1 /***************************************************************************//**
2 * \file cy_lin.c
3 * \version 1.1
4 *
5 * \brief
6 * Provides an API declaration of the LIN driver
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2020-2021, Cypress Semiconductor Corporation. All rights reserved.
11 * You may use this file only in accordance with the license, terms, conditions,
12 * disclaimers, and limitations in the end user license agreement accompanying
13 * the software package with which this file was provided.
14 *******************************************************************************/
15 #include "cy_device.h"
16 #if defined (CY_IP_MXLIN)
17 /*****************************************************************************/
18 /* Include files                                                             */
19 /*****************************************************************************/
20 #include "cy_lin.h"
21 
22 /*****************************************************************************/
23 /* Local pre-processor symbols/macros ('#define')                            */
24 /*****************************************************************************/
25 
26 
27 /*****************************************************************************/
28 /* Global variable definitions (declared in header file with 'extern')       */
29 /*****************************************************************************/
30 
31 
32 /*****************************************************************************/
33 /* Local type definitions ('typedef')                                        */
34 /*****************************************************************************/
35 
36 
37 /*****************************************************************************/
38 /* Local variable definitions ('static')                                     */
39 /*****************************************************************************/
40 
41 
42 /*****************************************************************************/
43 /* Local function prototypes ('static')                                      */
44 /*****************************************************************************/
45 
46 /*****************************************************************************/
47 /* Function implementation - global ('extern') and local ('static')          */
48 /*****************************************************************************/
49 /**
50  *****************************************************************************
51  ** Cy_LIN_DeInit
52  ** DeInitialization of a LIN module.
53  ** This Function deinitializes the selected LIN channel.
54  *****************************************************************************/
Cy_LIN_DeInit(LIN_CH_Type * base)55 cy_en_lin_status_t Cy_LIN_DeInit( LIN_CH_Type* base )
56 {
57     cy_en_lin_status_t status = CY_LIN_SUCCESS;
58 
59     /* Check if pointers are valid */
60     if ( NULL == base )
61     {
62         return CY_LIN_BAD_PARAM;
63     }
64 
65     /* Disable the LIN Channel and set the values to default. */
66     LIN_CH_CTL0(base) = LIN_CH_CTL0_DEFAULT;
67 
68     /* Clear the data registers */
69     LIN_CH_DATA0(base) = 0UL;
70     LIN_CH_DATA0(base) = 0UL;
71 
72     /* Clear the PID filed */
73     LIN_CH_PID_CHECKSUM(base) &= ~(LIN_CH_PID_CHECKSUM_PID_Msk);
74 
75     return status;
76 }
77 
78 /**
79  *****************************************************************************
80  ** Cy_LIN_Init
81  ** Initialization of a LIN module.
82  ** This function initializes the LIN according the Options setup in the
83  ** passed Config Struct. Several Checkings are done before that and an error
84  ** is returned if invalid Modes are requested.
85  *****************************************************************************/
Cy_LIN_Init(LIN_CH_Type * base,const cy_stc_lin_config_t * pstcConfig)86 cy_en_lin_status_t Cy_LIN_Init( LIN_CH_Type* base, const cy_stc_lin_config_t *pstcConfig)
87 {
88     cy_en_lin_status_t status = CY_LIN_SUCCESS;
89 
90     /* Check if pointers are valid */
91     if ( ( NULL == base  )     ||
92          ( NULL == pstcConfig ) )
93     {
94         status = CY_LIN_BAD_PARAM;
95     }
96     else if (pstcConfig->masterMode &&
97              ((LIN_MASTER_BREAK_FILED_LENGTH_MIN > pstcConfig->breakFieldLength) ||
98               (LIN_BREAK_WAKEUP_LENGTH_BITS_MAX < pstcConfig->breakFieldLength)))
99     {
100         status = CY_LIN_BAD_PARAM;
101     }
102     else if (LIN_BREAK_WAKEUP_LENGTH_BITS_MAX < pstcConfig->breakFieldLength)
103     {
104         status = CY_LIN_BAD_PARAM;
105     }
106     else
107     {
108         LIN_CH_CTL0(base) =  (_VAL2FLD(LIN_CH_CTL0_STOP_BITS, pstcConfig->stopBit) | \
109                               _VAL2FLD(LIN_CH_CTL0_AUTO_EN,  pstcConfig->linTransceiverAutoEnable) | \
110                               _VAL2FLD(LIN_CH_CTL0_BREAK_DELIMITER_LENGTH, pstcConfig->breakDelimiterLength) | \
111                               _VAL2FLD(LIN_CH_CTL0_BREAK_WAKEUP_LENGTH, (((uint32_t)pstcConfig->breakFieldLength) - 1U)) | \
112                               _VAL2FLD(LIN_CH_CTL0_MODE, LIN_CH_CTL0_MODE_DEFAULT) | \
113                               _VAL2FLD(LIN_CH_CTL0_BIT_ERROR_IGNORE, LIN_CH_CTL0_BIT_ERROR_IGNORE_DEFAULT) | \
114                               _VAL2FLD(LIN_CH_CTL0_PARITY, LIN_CH_CTL0_PARITY_DEFAULT) | \
115                               _VAL2FLD(LIN_CH_CTL0_PARITY_EN, LIN_CH_CTL0_PARITY_EN_DEFAULT) | \
116                               _VAL2FLD(LIN_CH_CTL0_FILTER_EN, pstcConfig->filterEnable) | \
117                               _VAL2FLD(LIN_CH_CTL0_ENABLED, 1U));
118 
119     }
120 
121     return status;
122 }
123 
124 /**
125  *****************************************************************************
126  ** Cy_LIN_ReadData.
127  ** Read response data.
128  *****************************************************************************/
Cy_LIN_ReadData(LIN_CH_Type * base,uint8_t * data)129 cy_en_lin_status_t Cy_LIN_ReadData( LIN_CH_Type* base, uint8_t  *data )
130 {
131     cy_en_lin_status_t status = CY_LIN_SUCCESS;
132     uint8_t cnt;
133     uint8_t length;
134     uint8_t data0[4];
135     uint8_t data1[4];
136 
137     /* Check if pointers are valid */
138     if( ( NULL == base )           ||
139         ( NULL == data ))
140     {
141         status = CY_LIN_BAD_PARAM;
142     }
143     /* Check if the response is received successfully */
144     else if( ( 0U == _FLD2VAL(LIN_CH_CMD_TX_RESPONSE, LIN_CH_CMD(base)))  &&
145              ( 0u == _FLD2VAL(LIN_CH_STATUS_RX_BUSY, LIN_CH_STATUS(base))))
146     {
147         length = (uint8_t)(_FLD2VAL(LIN_CH_CTL1_DATA_NR, LIN_CH_CTL1(base)) + 1U);
148         /* Copy the data in to u8Data array */
149         data0[0] = (uint8_t)_FLD2VAL(LIN_CH_DATA0_DATA1, LIN_CH_DATA0(base));
150         data0[1] = (uint8_t)_FLD2VAL(LIN_CH_DATA0_DATA2, LIN_CH_DATA0(base));
151         data0[2] = (uint8_t)_FLD2VAL(LIN_CH_DATA0_DATA3, LIN_CH_DATA0(base));
152         data0[3] = (uint8_t)_FLD2VAL(LIN_CH_DATA0_DATA4, LIN_CH_DATA0(base));
153         data1[0] = (uint8_t)_FLD2VAL(LIN_CH_DATA1_DATA5, LIN_CH_DATA1(base));
154         data1[1] = (uint8_t)_FLD2VAL(LIN_CH_DATA1_DATA6, LIN_CH_DATA1(base));
155         data1[2] = (uint8_t)_FLD2VAL(LIN_CH_DATA1_DATA7, LIN_CH_DATA1(base));
156         data1[3] = (uint8_t)_FLD2VAL(LIN_CH_DATA1_DATA8, LIN_CH_DATA1(base));
157         for ( cnt = 0; cnt < length; cnt++ )
158         {
159             if( 4U > cnt )
160             {
161                 data[cnt] = data0[cnt];
162             }
163             else
164             {
165                 data[cnt] = data1[cnt - 4U];
166             }
167         }
168     }
169     else
170     {
171         status = CY_LIN_BUSY;
172     }
173 
174     return status;
175 }
176 
177 /**
178  *****************************************************************************
179  ** Cy_LIN_WriteData
180  ** Write response data.
181  *****************************************************************************/
Cy_LIN_WriteData(LIN_CH_Type * base,const uint8_t * data,uint8_t dataLength)182 cy_en_lin_status_t Cy_LIN_WriteData( LIN_CH_Type* base, const uint8_t *data,
183                                   uint8_t dataLength )
184 {
185     cy_en_lin_status_t status = CY_LIN_SUCCESS;
186     uint8_t data0[4U] = { 0 };
187     uint8_t data1[4U] = { 0 };
188     uint8_t cnt;
189 
190     /* Check if NULL pointer */
191     if( ( NULL == base ) ||
192         ( NULL == data ) )
193     {
194         status = CY_LIN_BAD_PARAM;
195     }
196     /* Check if data length is valid */
197     else if( LIN_DATA_LENGTH_MAX < dataLength )
198     {
199         status = CY_LIN_BAD_PARAM;
200     }
201     /* Check if the bus is free */
202     else if( 0U == _FLD2VAL(LIN_CH_STATUS_TX_BUSY, LIN_CH_STATUS(base)) )
203     {
204         /* Write data in to the temp variables */
205         for( cnt = 0U; cnt < dataLength; cnt++ )
206         {
207             if( 4u > cnt )
208             {
209                 data0[cnt] = data[cnt];
210             }
211             else
212             {
213                 data1[cnt - 4u] = data[cnt];
214             }
215         }
216         /* Write data to HW FIFO */
217         LIN_CH_DATA0(base) =   (_VAL2FLD(LIN_CH_DATA0_DATA1, data0[0]) | \
218                                 _VAL2FLD(LIN_CH_DATA0_DATA2, data0[1]) | \
219                                 _VAL2FLD(LIN_CH_DATA0_DATA3, data0[2]) | \
220                                 _VAL2FLD(LIN_CH_DATA0_DATA4, data0[3]));
221         LIN_CH_DATA1(base) =   (_VAL2FLD(LIN_CH_DATA1_DATA5, data1[0]) | \
222                                 _VAL2FLD(LIN_CH_DATA1_DATA6, data1[1]) | \
223                                 _VAL2FLD(LIN_CH_DATA1_DATA7, data1[2]) | \
224                                 _VAL2FLD(LIN_CH_DATA1_DATA8, data1[3]));
225     }
226     else
227     {
228         status = CY_LIN_BUSY;
229         /* A requested operation could not be completed */
230     }
231 
232     return status;
233 }
234 
235 /**
236  *****************************************************************************
237  ** Cy_LIN_Enable
238  ** Enable LIN channel.
239  *****************************************************************************/
Cy_LIN_Enable(LIN_CH_Type * base)240 cy_en_lin_status_t Cy_LIN_Enable(LIN_CH_Type* base)
241 {
242     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
243 
244     if (NULL == base)
245     {
246         ret = CY_LIN_BAD_PARAM;
247     }
248     else
249     {
250         LIN_CH_CTL0(base) |= _VAL2FLD(LIN_CH_CTL0_ENABLED, 1U);
251     }
252 
253     return ret;
254 }
255 
256 /**
257  *****************************************************************************
258  ** Cy_LIN_Disable
259  ** Disable LIN channel.
260  *****************************************************************************/
Cy_LIN_Disable(LIN_CH_Type * base)261 cy_en_lin_status_t Cy_LIN_Disable(LIN_CH_Type* base)
262 {
263     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
264 
265     if (NULL == base)
266     {
267         ret = CY_LIN_BAD_PARAM;
268     }
269     else
270     {
271         LIN_CH_CTL0(base) &= ~(LIN_CH_CTL0_ENABLED_Msk);
272     }
273 
274     return ret;
275 }
276 
277 /**
278  *****************************************************************************
279  **  Cy_LIN_SetBreakWakeupFieldLength
280  **  Setup LIN break/wakeup field length.
281  **  Normally this I/F is used for detection of the wakeup pulse.
282  *****************************************************************************/
Cy_LIN_SetBreakWakeupFieldLength(LIN_CH_Type * base,uint8_t length)283 cy_en_lin_status_t Cy_LIN_SetBreakWakeupFieldLength(LIN_CH_Type* base, uint8_t length)
284 {
285     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
286 
287     if (NULL == base)
288     {
289         ret = CY_LIN_BAD_PARAM;
290     }
291     else if (LIN_BREAK_WAKEUP_LENGTH_BITS_MAX < length)
292     {
293         ret = CY_LIN_BAD_PARAM;
294     }
295     else
296     {
297         LIN_CH_CTL0(base) |= _VAL2FLD(LIN_CH_CTL0_BREAK_WAKEUP_LENGTH, (((uint32_t)length) - 1U));
298     }
299 
300     return ret;
301 }
302 
303 /**
304  *****************************************************************************
305  ** Cy_LIN_SetChecksumType
306  ** Setup LIN checksum type setting
307  *****************************************************************************/
Cy_LIN_SetChecksumType(LIN_CH_Type * base,cy_en_lin_checksum_type_t type)308 cy_en_lin_status_t Cy_LIN_SetChecksumType(LIN_CH_Type* base, cy_en_lin_checksum_type_t type)
309 {
310     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
311 
312     if (NULL == base)
313     {
314         ret = CY_LIN_BAD_PARAM;
315     }
316     else
317     {
318         LIN_CH_CTL1(base) |= _VAL2FLD(LIN_CH_CTL1_CHECKSUM_ENHANCED, type);
319     }
320     return ret;
321 }
322 
323 /**
324  *****************************************************************************
325  ** Cy_LIN_SetDataLength
326  ** Setup LIN response field data length
327  *****************************************************************************/
Cy_LIN_SetDataLength(LIN_CH_Type * base,uint8_t length)328 cy_en_lin_status_t Cy_LIN_SetDataLength(LIN_CH_Type* base, uint8_t length)
329 {
330     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
331 
332     if ((NULL == base) ||
333         (length > LIN_DATA_LENGTH_MAX) ||
334         (length < LIN_DATA_LENGTH_MIN))
335     {
336         ret = CY_LIN_BAD_PARAM;
337     }
338     else
339     {
340         LIN_CH_CTL1(base) |= _VAL2FLD(LIN_CH_CTL1_DATA_NR, (((uint32_t)length) - 1U));
341     }
342     return ret;
343 }
344 
345 /**
346  *****************************************************************************
347  ** Cy_LIN_SetCmd
348  ** Setup LIN operation command
349  *****************************************************************************/
Cy_LIN_SetCmd(LIN_CH_Type * base,uint32_t command)350 cy_en_lin_status_t Cy_LIN_SetCmd(LIN_CH_Type* base, uint32_t command)
351 {
352     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
353 
354     if (NULL == base)
355     {
356         ret = CY_LIN_BAD_PARAM;
357     }
358     /* The command cannot have both TX_HEADER and RX_HEADER master set's TX_HEADER and slave sets RX_HEADER.
359        If the Command is a wakeup command then TX_HEADER, RX_HEADER, TX_RESPONSE and RX_RESPONSE are not valid.
360     */
361     else if (((command & (LIN_CH_CMD_TX_HEADER_Msk | LIN_CH_CMD_RX_HEADER_Msk))
362                 == (LIN_CH_CMD_TX_HEADER_Msk | LIN_CH_CMD_RX_HEADER_Msk))   ||
363             (((command & LIN_CH_CMD_TX_WAKEUP_Msk) != 0UL) &&
364              ((command & (LIN_CH_CMD_TX_HEADER_Msk |
365                           LIN_CH_CMD_TX_RESPONSE_Msk |
366                           LIN_CH_CMD_RX_HEADER_Msk |
367                           LIN_CH_CMD_RX_RESPONSE_Msk)) != 0UL)))
368     {
369         ret = CY_LIN_BAD_PARAM;
370     }
371     /* If software has already set the command and it is not complete then the channel must be busy processing the command.
372        before setting the command make sure that hardware has already set the bit to 0 for the above cases.
373     */
374     else if (((_FLD2VAL(LIN_CH_CMD_TX_HEADER, LIN_CH_CMD(base)) != 0UL) && (command & LIN_CH_CMD_RX_HEADER_Msk) != 0UL) ||
375              ((_FLD2VAL(LIN_CH_CMD_RX_HEADER, LIN_CH_CMD(base)) != 0UL) && (command & LIN_CH_CMD_TX_HEADER_Msk) != 0UL) ||
376              ((_FLD2VAL(LIN_CH_CMD_TX_WAKEUP, LIN_CH_CMD(base)) != 0UL) &&
377                             ((command & (LIN_CH_CMD_TX_HEADER_Msk |
378                                          LIN_CH_CMD_TX_RESPONSE_Msk |
379                                          LIN_CH_CMD_RX_HEADER_Msk |
380                                          LIN_CH_CMD_RX_RESPONSE_Msk)) != 0UL)))
381     {
382         ret = CY_LIN_BUSY;
383     }
384     else
385     {
386         LIN_CH_CMD(base) = command;
387     }
388 
389     return ret;
390 }
391 
392 /**
393  *****************************************************************************
394  ** Cy_LIN_SetHeader
395  ** Setup LIN header for master tx header operation
396  *****************************************************************************/
Cy_LIN_SetHeader(LIN_CH_Type * base,uint8_t id)397 cy_en_lin_status_t Cy_LIN_SetHeader(LIN_CH_Type* base, uint8_t id)
398 {
399     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
400     uint8_t tempPID;
401     uint8_t parity_P1, parity_P0;
402 
403     if ((NULL == base) ||
404         (LIN_ID_MAX < id))
405     {
406         ret = CY_LIN_BAD_PARAM;
407     }
408     else
409     {
410         /* Calculate the Parity bits P0 & P1
411            Parity is calculated as per the formula given
412              - P[1] = ! (ID[5] ^ ID[4] ^ ID[3] ^ ID[1])
413              - P[0] = (ID[4] ^ ID[2] ^ ID[1] ^ ID[0])
414         */
415         parity_P0 = ((id) ^ (id>>1u) ^
416                      (id>>2u) ^ (id>>4u)) & 0x01u;
417         parity_P1 = (~((id>>1u) ^ (id>>3u) ^
418                        (id>>4u) ^ (id>>5u))) & 0x01u;
419         /* Assign the Parity bits and the header values in to the tempPID */
420         tempPID = id | ((uint8_t) parity_P0<<6u) | ((uint8_t) parity_P1<<7u);
421         /* Write the TempID value in to the TX_HEADER register */
422         LIN_CH_PID_CHECKSUM(base) = _VAL2FLD(LIN_CH_PID_CHECKSUM_PID, tempPID);
423     }
424 
425     return ret;
426 }
427 
428 /**
429  *****************************************************************************
430  ** Cy_LIN_GetHeader
431  ** Return received LIN header
432  *****************************************************************************/
Cy_LIN_GetHeader(LIN_CH_Type * base,uint8_t * id,uint8_t * parity)433 cy_en_lin_status_t Cy_LIN_GetHeader(LIN_CH_Type* base, uint8_t *id, uint8_t *parity)
434 {
435     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
436 
437     if ((NULL == base) ||
438         (NULL == id)      ||
439         (NULL == parity))
440     {
441         ret = CY_LIN_BAD_PARAM;
442     }
443     else
444     {
445         /* Store received ID and parity bits */
446         uint8_t temp = (uint8_t)_FLD2VAL(LIN_CH_PID_CHECKSUM_PID, LIN_CH_PID_CHECKSUM(base));
447         *parity = (temp >> 6u);
448         *id = (temp & LIN_ID_MAX);
449     }
450 
451     return ret;
452 }
453 
454 /**
455  *****************************************************************************
456  ** Cy_LIN_SetInterruptMask
457  ** Setup interrupt source to be accepted.
458  *****************************************************************************/
Cy_LIN_SetInterruptMask(LIN_CH_Type * base,uint32_t mask)459 cy_en_lin_status_t Cy_LIN_SetInterruptMask(LIN_CH_Type* base, uint32_t mask)
460 {
461     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
462 
463     if (NULL == base)
464     {
465         ret = CY_LIN_BAD_PARAM;
466     }
467     else
468     {
469         LIN_CH_INTR_MASK(base)  = mask;
470     }
471 
472     return ret;
473 }
474 
475 /**
476  *****************************************************************************
477  ** Cy_LIN_GetInterruptMask
478  ** Return interrupt mask setting.
479  *****************************************************************************/
Cy_LIN_GetInterruptMask(LIN_CH_Type * base,uint32_t * mask)480 cy_en_lin_status_t Cy_LIN_GetInterruptMask(LIN_CH_Type* base, uint32_t *mask)
481 {
482     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
483 
484     if ((NULL == base) ||
485         (NULL == mask))
486     {
487         ret = CY_LIN_BAD_PARAM;
488     }
489     else
490     {
491         *mask = LIN_CH_INTR_MASK(base);
492     }
493 
494     return ret;
495 }
496 
497 /**
498  *****************************************************************************
499  ** Cy_LIN_GetInterruptMaskedStatus
500  ** Return interrupt masked status.
501  *****************************************************************************/
Cy_LIN_GetInterruptMaskedStatus(LIN_CH_Type * base,uint32_t * status)502 cy_en_lin_status_t Cy_LIN_GetInterruptMaskedStatus(LIN_CH_Type* base, uint32_t *status)
503 {
504     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
505 
506     if ((NULL == base) ||
507         (NULL == status))
508     {
509         ret = CY_LIN_BAD_PARAM;
510     }
511     else
512     {
513         *status = LIN_CH_INTR_MASKED(base);
514     }
515 
516     return ret;
517 }
518 
519 /**
520  *****************************************************************************
521  ** Cy_LIN_GetInterruptStatus
522  ** Return interrupt raw status.
523  *****************************************************************************/
Cy_LIN_GetInterruptStatus(LIN_CH_Type * base,uint32_t * status)524 cy_en_lin_status_t Cy_LIN_GetInterruptStatus(LIN_CH_Type* base, uint32_t *status)
525 {
526 
527     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
528 
529     if ((NULL == base) ||
530         (NULL == status))
531     {
532         ret = CY_LIN_BAD_PARAM;
533     }
534     else
535     {
536         *status = LIN_CH_INTR(base) ;
537     }
538 
539     return ret;
540 }
541 
542 /**
543  *****************************************************************************
544  ** Cy_LIN_ClearInterrupt
545  ** Clear interrupt status.
546  *****************************************************************************/
Cy_LIN_ClearInterrupt(LIN_CH_Type * base,uint32_t mask)547 cy_en_lin_status_t Cy_LIN_ClearInterrupt(LIN_CH_Type* base, uint32_t mask)
548 {
549     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
550 
551     if (NULL == base)
552     {
553         ret = CY_LIN_BAD_PARAM;
554     }
555     else
556     {
557         LIN_CH_INTR(base) = mask;
558     }
559 
560     return ret;
561 }
562 
563 /**
564  *****************************************************************************
565  ** Cy_LIN_GetStatus
566  ** Return LIN module status
567  *****************************************************************************/
Cy_LIN_GetStatus(LIN_CH_Type * base,uint32_t * status)568 cy_en_lin_status_t Cy_LIN_GetStatus(LIN_CH_Type* base, uint32_t *status)
569 {
570     cy_en_lin_status_t ret = CY_LIN_SUCCESS;
571 
572     if ((NULL == base) ||
573         (NULL == status))
574     {
575         ret = CY_LIN_BAD_PARAM;
576     }
577     else
578     {
579         *status = LIN_CH_STATUS(base);
580     }
581 
582     return ret;
583 }
584 
585 /**
586  *****************************************************************************
587  ** Cy_LIN_EnOut_Enable
588  ** Enables LIN channel 'en' out
589  *****************************************************************************/
Cy_LIN_EnOut_Enable(LIN_CH_Type * base)590 cy_en_lin_status_t Cy_LIN_EnOut_Enable(LIN_CH_Type* base)
591 {
592     if (NULL == base)
593     {
594         return CY_LIN_BAD_PARAM;
595     }
596     /* check if auto enabled is set or not */
597     bool auto_enable = (_FLD2VAL(LIN_CH_CTL0_AUTO_EN, LIN_CH_CTL0(base)) != 0UL) ? true : false;
598     if(!auto_enable)
599     {
600         /* Enable EN out  */
601         LIN_CH_TX_RX_STATUS(base) |= _VAL2FLD(LIN_CH_TX_RX_STATUS_EN_OUT, 1U);
602     }
603     return CY_LIN_SUCCESS;
604 }
605 
606 /**
607  *****************************************************************************
608  ** Cy_LIN_EnOut_Disable
609  ** Disables LIN channel 'en' out
610  *****************************************************************************/
Cy_LIN_EnOut_Disable(LIN_CH_Type * base)611 cy_en_lin_status_t Cy_LIN_EnOut_Disable(LIN_CH_Type* base)
612 {
613     if (NULL == base)
614     {
615         return CY_LIN_BAD_PARAM;
616     }
617     /* check if auto enabled is set or not */
618     bool auto_enable = (_FLD2VAL(LIN_CH_CTL0_AUTO_EN, LIN_CH_CTL0(base)) != 0UL) ? true : false;
619     if(!auto_enable)
620     {
621         /* Disable EN out  */
622         LIN_CH_TX_RX_STATUS(base) &= ~LIN_CH_TX_RX_STATUS_EN_OUT_Msk;
623     }
624     return CY_LIN_SUCCESS;
625 }
626 
627 /**
628  *****************************************************************************
629  ** Cy_LIN_TestMode_Enable
630  ** Enables LIN Test mode
631  *****************************************************************************/
Cy_LIN_TestMode_Enable(LIN_Type * base,const cy_stc_lin_test_config_t * lin_test_config)632 cy_en_lin_status_t Cy_LIN_TestMode_Enable(LIN_Type* base, const cy_stc_lin_test_config_t* lin_test_config)
633 {
634     if (NULL == base || NULL == lin_test_config)
635     {
636         return CY_LIN_BAD_PARAM;
637     }
638     CY_ASSERT_L3(CY_LIN_IS_TEST_CTL_CH_IDX_VALID(lin_test_config->chidx));
639     /* Enable Test mode and set test configuration  */
640     LIN_TEST_CTL(base) = (_VAL2FLD(LIN_TEST_CTL_CH_IDX, lin_test_config->chidx) |\
641                           _VAL2FLD(LIN_TEST_CTL_MODE, lin_test_config->mode)    |\
642                           _VAL2FLD(LIN_TEST_CTL_ENABLED, 1U));
643 
644     return CY_LIN_SUCCESS;
645 }
646 
647 /**
648  *****************************************************************************
649  ** Cy_LIN_TestMode_Disable
650  ** Disables LIN Test mode
651  *****************************************************************************/
Cy_LIN_TestMode_Disable(LIN_Type * base)652 cy_en_lin_status_t Cy_LIN_TestMode_Disable(LIN_Type* base)
653 {
654     if (NULL == base)
655     {
656         return CY_LIN_BAD_PARAM;
657     }
658     /* Disable Test mode  */
659     LIN_TEST_CTL(base) &= ~LIN_TEST_CTL_ENABLED_Msk;
660     return CY_LIN_SUCCESS;
661 }
662 
663 /**
664  *****************************************************************************
665  ** Cy_LIN_ErrCtl_Enable
666  ** Enables LIN Err Ctl in Test mode
667  *****************************************************************************/
Cy_LIN_ErrCtl_Enable(LIN_Type * base,cy_stc_lin_test_error_config_t * test_error_config)668 cy_en_lin_status_t Cy_LIN_ErrCtl_Enable(LIN_Type* base, cy_stc_lin_test_error_config_t* test_error_config)
669 {
670     if (NULL == base)
671     {
672         return CY_LIN_BAD_PARAM;
673     }
674 
675     /* LIN est Error CTL setting  */
676     CY_ASSERT_L3(CY_LIN_IS_TEST_CTL_CH_IDX_VALID(test_error_config->chidx));
677 
678     LIN_ERROR_CTL(base) = (_VAL2FLD(LIN_ERROR_CTL_CH_IDX, test_error_config->chidx) |\
679                            _VAL2FLD(LIN_ERROR_CTL_TX_SYNC_ERROR, test_error_config->txsync_error)             |\
680                            _VAL2FLD(LIN_ERROR_CTL_TX_SYNC_STOP_ERROR, test_error_config->txsyncStop_error)    |\
681                            _VAL2FLD(LIN_ERROR_CTL_TX_PARITY_ERROR, test_error_config->txParity_error)         |\
682                            _VAL2FLD(LIN_ERROR_CTL_TX_PID_STOP_ERROR, test_error_config->txPIDStop_error)      |\
683                            _VAL2FLD(LIN_ERROR_CTL_TX_DATA_STOP_ERROR, test_error_config->txDataStop_error)    |\
684                            _VAL2FLD(LIN_ERROR_CTL_TX_CHECKSUM_ERROR, test_error_config->txChecksum_error)     |\
685                            _VAL2FLD(LIN_ERROR_CTL_TX_CHECKSUM_STOP_ERROR, test_error_config->txChecksumStop_error) |\
686                            _VAL2FLD(LIN_ERROR_CTL_ENABLED, 1U));
687 
688     return CY_LIN_SUCCESS;
689 }
690 
691 /**
692  *****************************************************************************
693  ** Cy_LIN_ErrCtl_Disable
694  ** Disables LIN Error Ctl in Test mode
695  *****************************************************************************/
Cy_LIN_ErrCtl_Disable(LIN_Type * base)696 cy_en_lin_status_t Cy_LIN_ErrCtl_Disable(LIN_Type* base)
697 {
698     if (NULL == base)
699     {
700         return CY_LIN_BAD_PARAM;
701     }
702     /* Disable Test Error Control mode  */
703     LIN_ERROR_CTL(base) &= ~LIN_ERROR_CTL_ENABLED_Msk;
704     return CY_LIN_SUCCESS;
705 }
706 
707 #endif /* CY_IP_MXLIN */
708 /*****************************************************************************/
709 /* EOF (not truncated)                                                       */
710 /*****************************************************************************/
711