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