1 /*
2 * Copyright 2021-2022 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 /**
7 * @file Linflexd_Uart_Ip.c
8 * @defgroup linflexd_uart_ip Linflexd UART IPL
9 * @addtogroup linflexd_uart_ip Linflexd UART IPL
10 * @{
11 */
12
13 #ifdef __cplusplus
14 extern "C"{
15 #endif
16
17 /*==================================================================================================
18 * INCLUDE FILES
19 * 1) system and project includes
20 * 2) needed interfaces from external units
21 * 3) internal and external interfaces from this unit
22 ==================================================================================================*/
23
24 #include "Linflexd_Uart_Ip.h"
25 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
26 #include "Dma_Ip.h"
27 #endif
28
29 #ifdef LINFLEXD_UART_IP_DEV_ERROR_DETECT
30 #if (LINFLEXD_UART_IP_DEV_ERROR_DETECT == STD_ON)
31 #include "Devassert.h"
32 #endif /* (STD_ON == LINFLEXD_UART_IP_DEV_ERROR_DETECT) */
33 #endif /* ifdef LINFLEXD_UART_IP_DEV_ERROR_DETECT */
34
35 #if (STD_ON == LINFLEXD_UART_IP_SET_USER_ACCESS_ALLOWED_AVAILABLE)
36 #define USER_MODE_REG_PROT_ENABLED (STD_ON)
37 #include "RegLockMacros.h"
38 #endif
39 /*==================================================================================================
40 * SOURCE FILE VERSION INFORMATION
41 ==================================================================================================*/
42
43 #define LINFLEXD_UART_IP_VENDOR_ID_C 43
44 #define LINFLEXD_UART_IP_AR_RELEASE_MAJOR_VERSION_C 4
45 #define LINFLEXD_UART_IP_AR_RELEASE_MINOR_VERSION_C 7
46 #define LINFLEXD_UART_IP_AR_RELEASE_REVISION_VERSION_C 0
47 #define LINFLEXD_UART_IP_SW_MAJOR_VERSION_C 0
48 #define LINFLEXD_UART_IP_SW_MINOR_VERSION_C 9
49 #define LINFLEXD_UART_IP_SW_PATCH_VERSION_C 0
50
51 /*==================================================================================================
52 * FILE VERSION CHECKS
53 ==================================================================================================*/
54 /* Checks against Linflexd_Uart_Ip.h */
55 #if (LINFLEXD_UART_IP_VENDOR_ID_C != LINFLEXD_UART_IP_VENDOR_ID)
56 #error "Linflexd_Uart_Ip.c and Linflexd_Uart_Ip.h have different vendor ids"
57 #endif
58 #if ((LINFLEXD_UART_IP_AR_RELEASE_MAJOR_VERSION_C != LINFLEXD_UART_IP_AR_RELEASE_MAJOR_VERSION) || \
59 (LINFLEXD_UART_IP_AR_RELEASE_MINOR_VERSION_C != LINFLEXD_UART_IP_AR_RELEASE_MINOR_VERSION) || \
60 (LINFLEXD_UART_IP_AR_RELEASE_REVISION_VERSION_C != LINFLEXD_UART_IP_AR_RELEASE_REVISION_VERSION))
61 #error "AUTOSAR Version Numbers of Linflexd_Uart_Ip.c and Linflexd_Uart_Ip.h are different"
62 #endif
63 #if ((LINFLEXD_UART_IP_SW_MAJOR_VERSION_C != LINFLEXD_UART_IP_SW_MAJOR_VERSION) || \
64 (LINFLEXD_UART_IP_SW_MINOR_VERSION_C != LINFLEXD_UART_IP_SW_MINOR_VERSION) || \
65 (LINFLEXD_UART_IP_SW_PATCH_VERSION_C != LINFLEXD_UART_IP_SW_PATCH_VERSION))
66 #error "Software Version Numbers of Linflexd_Uart_Ip.c and Linflexd_Uart_Ip.h are different"
67 #endif
68
69 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
70 /* Checks against Dma_Ip.h */
71 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
72 #if ((LINFLEXD_UART_IP_AR_RELEASE_MAJOR_VERSION_C != DMA_IP_AR_RELEASE_MAJOR_VERSION) || \
73 (LINFLEXD_UART_IP_AR_RELEASE_MINOR_VERSION_C != DMA_IP_AR_RELEASE_MINOR_VERSION))
74 #error "AutoSar Version Numbers of Linflexd_Uart_Ip.c and Dma_Ip.h are different"
75 #endif
76 #endif
77
78 /* Checks against RegLockMacros.h */
79 #if (STD_ON == LINFLEXD_UART_IP_SET_USER_ACCESS_ALLOWED_AVAILABLE)
80 #if ((LINFLEXD_UART_IP_AR_RELEASE_MAJOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MAJOR_VERSION) || \
81 (LINFLEXD_UART_IP_AR_RELEASE_MINOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MINOR_VERSION))
82 #error "AutoSar Version Numbers of Linflexd_Uart_Ip.c and RegLockMacros.h are different"
83 #endif
84 #endif
85
86 /* Checks against Devassert.h */
87 #ifdef LINFLEXD_UART_IP_DEV_ERROR_DETECT
88 #if (LINFLEXD_UART_IP_DEV_ERROR_DETECT == STD_ON)
89 #if ((LINFLEXD_UART_IP_AR_RELEASE_MAJOR_VERSION_C != DEVASSERT_AR_RELEASE_MAJOR_VERSION) || \
90 (LINFLEXD_UART_IP_AR_RELEASE_MINOR_VERSION_C != DEVASSERT_AR_RELEASE_MINOR_VERSION))
91 #error "AutoSar Version Numbers of Linflexd_Uart_Ip.c and Devassert.h are different"
92 #endif
93 #endif /* (STD_ON == LINFLEXD_UART_IP_DEV_ERROR_DETECT) */
94 #endif /* idfef LINFLEXD_UART_IP_DEV_ERROR_DETECT */
95 #endif
96 /*==================================================================================================
97 * LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
98 ==================================================================================================*/
99
100 /*==================================================================================================
101 * LOCAL MACROS
102 ==================================================================================================*/
103
104 #ifdef LINFLEXD_UART_IP_DEV_ERROR_DETECT
105 #if (LINFLEXD_UART_IP_DEV_ERROR_DETECT == STD_ON)
106 #define LINFLEXD_UART_IP_DEV_ASSERT(x) DevAssert(x)
107 #else
108 #define LINFLEXD_UART_IP_DEV_ASSERT(x) (void)(x)
109 #endif
110 #endif
111
112 /* @brief Address of the least significant byte or word in a 32-bit register (depends on endianness) */
113 #define LINFLEXD_UART_IP_LSBW_ADDR(reg) ((uint32)(&(reg)))
114
115 /*==================================================================================================
116 * LOCAL CONSTANTS
117 ==================================================================================================*/
118
119 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
120 #define LINFLEXD_UART_IP_DMA_CONFIG_LIST_DIMENSION (10U)
121 #define LINFLEXD_UART_DMA_LEAST_CONFIG_LIST_DIMENSION (2U)
122 #endif
123
124 /*==================================================================================================
125 * LOCAL VARIABLES
126 ==================================================================================================*/
127 #define UART_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
128 #include "Uart_MemMap.h"
129
130 /** @brief Array of UART driver runtime state structures */
131 VAR_SEC_NOCACHE(Linflexd_Uart_Ip_apStateStructure) Linflexd_Uart_Ip_StateStructureType Linflexd_Uart_Ip_apStateStructure[LINFLEXD_UART_IP_NUMBER_OF_INSTANCES];
132
133 #define UART_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
134 #include "Uart_MemMap.h"
135
136 #define UART_START_SEC_VAR_CLEARED_UNSPECIFIED
137 #include "Uart_MemMap.h"
138
139 /** @brief User config structure. */
140 static const Linflexd_Uart_Ip_UserConfigType* Linflexd_Uart_Ip_apUserConfig[LINFLEXD_INSTANCE_COUNT];
141
142 #define UART_STOP_SEC_VAR_CLEARED_UNSPECIFIED
143 #include "Uart_MemMap.h"
144
145 #define UART_START_SEC_VAR_CLEARED_UNSPECIFIED
146 #include "Uart_MemMap.h"
147
148 /** @brief Array of pointers to UART driver runtime state structures */
149 static Linflexd_Uart_Ip_StateStructureType* Linflexd_Uart_Ip_apStateStructuresArray[LINFLEXD_INSTANCE_COUNT];
150
151 #define UART_STOP_SEC_VAR_CLEARED_UNSPECIFIED
152 #include "Uart_MemMap.h"
153
154 #define UART_START_SEC_CONST_UNSPECIFIED
155 #include "Uart_MemMap.h"
156
157 /** @brief Table of base addresses for LINFLEXD instances. */
158 static LINFLEXD_Type* const Linflexd_Uart_Ip_apBases[LINFLEXD_INSTANCE_COUNT] = IP_LINFLEXD_BASE_PTRS;
159
160 #define UART_STOP_SEC_CONST_UNSPECIFIED
161 #include "Uart_MemMap.h"
162
163 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
164 #define UART_START_SEC_CONST_BOOLEAN
165 #include "Uart_MemMap.h"
166
167 /** @brief Table storing DMA capabilities for LINFLEXD instances. */
168 static const boolean Linflexd_Uart_Ip_InstHasDma[LINFLEXD_INSTANCE_COUNT] = LINFLEXD_UART_IP_INST_HAS_DMA;
169
170 #define UART_STOP_SEC_CONST_BOOLEAN
171 #include "Uart_MemMap.h"
172 #endif
173
174 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
175 #define UART_START_SEC_CONST_BOOLEAN
176 #include "Uart_MemMap.h"
177
178 /** @brief Table storing timeout interrupt capabilities for LINFLEXD instances. */
179 static const boolean Linflexd_Uart_Ip_InstHasTimeoutInterruptEnabled[LINFLEXD_INSTANCE_COUNT] = LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT_PER_INSTANCE;
180
181 #define UART_STOP_SEC_CONST_BOOLEAN
182 #include "Uart_MemMap.h"
183 #endif
184
185 #if (LINFLEXD_UART_IP_ENABLE_INTERNAL_LOOPBACK == STD_ON)
186 #define UART_START_SEC_CONST_BOOLEAN
187 #include "Uart_MemMap.h"
188
189 /** @brief Table storing internal loopback capabilities for LINFLEXD instances. */
190 static const boolean Linflexd_Uart_Ip_InstHasLoopbackEnabled[LINFLEXD_INSTANCE_COUNT] = LINFLEXD_UART_IP_ENABLE_INTERNAL_LOOPBACK_PER_INSTANCE;
191
192 #define UART_STOP_SEC_CONST_BOOLEAN
193 #include "Uart_MemMap.h"
194 #endif
195 /*==================================================================================================
196 * GLOBAL CONSTANTS
197 ==================================================================================================*/
198
199 /*==================================================================================================
200 * GLOBAL VARIABLES
201 ==================================================================================================*/
202
203 /*==================================================================================================
204 * LOCAL FUNCTION PROTOTYPES
205 ==================================================================================================*/
206
207 /*==================================================================================================
208 * LOCAL FUNCTIONS
209 ==================================================================================================*/
210 #define UART_START_SEC_CODE
211 #include "Uart_MemMap.h"
212
213 static Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_StartSendUsingInterrupts(const uint8 Instance,
214 const uint8 * TxBuff,
215 const uint32 TxSize);
216 static Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_StartReceiveUsingInterrupts(const uint8 Instance,
217 uint8 * RxBuff,
218 const uint32 RxSize);
219 static void Linflexd_Uart_Ip_CompleteSendUsingInterrupts(const uint8 Instance);
220 static void Linflexd_Uart_Ip_CompleteReceiveUsingInterrupts(const uint8 Instance);
221 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
222 static Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_StartSendUsingDma(const uint8 Instance,
223 const uint8 * TxBuff,
224 const uint32 TxSize);
225 static Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_StartReceiveUsingDma(const uint8 Instance,
226 uint8 * RxBuff,
227 const uint32 RxSize);
228 static void Linflexd_Uart_Ip_FlushRxFifo(const LINFLEXD_Type *Base,const Linflexd_Uart_Ip_WordLengthType WordLength);
229 #endif
230 static void Linflexd_Uart_Ip_PutData(const uint8 Instance);
231 static void Linflexd_Uart_Ip_GetData(const uint8 Instance);
232 static void Linflexd_Uart_Ip_SetWordLength(const uint8 Instance);
233 static void Linflexd_Uart_Ip_SetUp_Init(const uint8 Instance);
234 static void Linflexd_Uart_Ip_SetUp_Receiver(const uint8 Instance);
235 static void Linflexd_Uart_Ip_UpdateReceiver(const uint8 Instance, uint32 * StartTime, uint32 * ElapsedTicks, uint32 TimeoutTicks);
236 static void Linflexd_Uart_Ip_GetRemainingBytes(const uint8 Instance, uint32 * BytesRemaining, Linflexd_Uart_Ip_DataDirectionType Direction);
237 #if (STD_ON == LINFLEXD_UART_IP_SET_USER_ACCESS_ALLOWED_AVAILABLE)
238 void Linflexd_Uart_Ip_SetUserAccess(const uint8 Instance);
239 static void Linflexd_Uart_Ip_SetUserAccessAllowed(const uint8 Instance);
240 #endif /* LINFLEXD_UART_IP_SET_USER_ACCESS_ALLOWED_AVAILABLE */
241
242 /*==================================================================================================
243 * GLOBAL FUNCTIONS
244 ==================================================================================================*/
245
246 /* implements Linflexd_Uart_Ip_SetBaudrate_Activity*/
Linflexd_Uart_Ip_SetBaudrate(const uint8 Instance,const Linflexd_Uart_Ip_BaudrateType DesiredBaudRate,const uint32 ClockFrequency)247 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_SetBaudrate(const uint8 Instance,
248 const Linflexd_Uart_Ip_BaudrateType DesiredBaudRate,
249 const uint32 ClockFrequency)
250 {
251
252 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
253
254 LINFLEXD_Type * Base;
255 float32 Prescaler;
256 float32 Fraction;
257 float32 Numerator;
258 uint32 Mantissa;
259 uint32 FractionDenominator;
260 uint32 StartTime;
261 uint32 TimeoutTicks;
262 uint32 ElapsedTicks = 0;
263 boolean ResetIdle = FALSE;
264 boolean IsReturn = FALSE;
265 Linflexd_Uart_Ip_StateStructureType * UartState;
266 Linflexd_Uart_Ip_StatusType Status = LINFLEXD_UART_IP_STATUS_ERROR;
267 uint8 FractionNumerator;
268
269 Base = Linflexd_Uart_Ip_apBases[Instance];
270 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
271
272 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
273
274 if ((TRUE == UartState->IsTxBusy) || (TRUE == UartState->IsRxBusy))
275 {
276 Status = LINFLEXD_UART_IP_STATUS_BUSY;
277 }
278 else
279 {
280 /* Compute the values for baud rate divider Mantissa and Fraction */
281 Prescaler = (float32)ClockFrequency / ((float32)DesiredBaudRate * (float32)DEFAULT_OSR);
282 Mantissa = (uint32)Prescaler;
283 Fraction = Prescaler - (float32)Mantissa;
284 FractionDenominator = ((uint32)1U << (uint32)BAUDRATE_FRACTION_WIDTH);
285 Numerator = ((float32)Fraction * (float32)FractionDenominator) + (float32)0.5F;
286 FractionNumerator = (uint8)(Numerator);
287
288 if (FractionNumerator == FractionDenominator)
289 {
290 FractionNumerator = 0;
291 Mantissa++;
292 }
293
294 if (Linflexd_Uart_Ip_GetLinState(Base) != LINFLEXD_STATE_INIT_MODE)
295 {
296 /* Request init mode and wait until the mode entry is complete */
297 Linflexd_Uart_Ip_EnterInitMode(Base);
298
299 Linflexd_Uart_Ip_StartTimeout(&StartTime, &TimeoutTicks, (uint32)LINFLEXD_UART_IP_TIMEOUT_VALUE_US, LINFLEXD_UART_IP_TIMEOUT_TYPE);
300
301 while (!Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE) &&
302 (Linflexd_Uart_Ip_GetLinState(Base) != LINFLEXD_STATE_INIT_MODE)) {}
303
304 /* Init mode error */
305 if (Linflexd_Uart_Ip_GetLinState(Base) != LINFLEXD_STATE_INIT_MODE)
306 {
307 Status = LINFLEXD_UART_IP_STATUS_ERROR;
308 IsReturn = TRUE;
309 }
310 else
311 {
312 ResetIdle = TRUE;
313 }
314 }
315 if (!IsReturn)
316 {
317 /* Write the computed values to registers */
318 Linflexd_Uart_Ip_SetIntegerBaudRate(Base, Mantissa);
319 Linflexd_Uart_Ip_SetFractionalBaudRate(Base, FractionNumerator);
320
321 if (TRUE == ResetIdle)
322 {
323 /* Enter normal mode */
324 Linflexd_Uart_Ip_EnterNormalMode(Base);
325 }
326 /* Save current baudrate value */
327 UartState->Baudrate = (uint32)DesiredBaudRate;
328 Status = LINFLEXD_UART_IP_STATUS_SUCCESS;
329 }
330 }
331 return Status;
332 }
333
334 /*FUNCTION**********************************************************************
335 *
336 * Function Name : Linflexd_Uart_Ip_GetBaudrate
337 * Description : This function retrieves the baud rate for UART communication.
338 *
339 *END**************************************************************************/
340 /* implements Linflexd_Uart_Ip_GetBaudrate_Activity*/
Linflexd_Uart_Ip_GetBaudrate(const uint8 Instance,uint32 * ConfiguredBaudRate)341 void Linflexd_Uart_Ip_GetBaudrate(const uint8 Instance, uint32 * ConfiguredBaudRate)
342 {
343 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
344 LINFLEXD_UART_IP_DEV_ASSERT(ConfiguredBaudRate != NULL_PTR);
345
346 const Linflexd_Uart_Ip_StateStructureType *UartStatePtr;
347 UartStatePtr = Linflexd_Uart_Ip_apStateStructuresArray[Instance];
348
349 LINFLEXD_UART_IP_DEV_ASSERT(UartStatePtr != NULL_PTR);
350
351 *ConfiguredBaudRate = UartStatePtr->Baudrate;
352 }
353
354 /*FUNCTION**********************************************************************
355 *
356 * Function Name : Linflexd_Uart_Ip_Init
357 * Description : This function initializes a LINFLEXD instance for UART
358 * operation.
359 * This function will initialize the run-time state structure to keep track of
360 * the on-going transfers, initialize the module to user defined settings and
361 * default settings, enable the module-level interrupt to the core, and enable
362 * the UART module transmitter and receiver.
363 *
364 *END**************************************************************************/
365 /* implements Linflexd_Uart_Ip_Init_Activity*/
Linflexd_Uart_Ip_Init(const uint8 Instance,const Linflexd_Uart_Ip_UserConfigType * UserConfig)366 void Linflexd_Uart_Ip_Init(const uint8 Instance, const Linflexd_Uart_Ip_UserConfigType * UserConfig)
367 {
368 uint32 Index;
369 uint32 StartTime;
370 uint32 TimeoutTicks;
371 uint32 ElapsedTicks = 0;
372 uint8 *ClearStructPtr;
373
374 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
375 LINFLEXD_UART_IP_DEV_ASSERT(NULL_PTR == Linflexd_Uart_Ip_apStateStructuresArray[Instance]);
376 LINFLEXD_UART_IP_DEV_ASSERT(UserConfig != NULL_PTR);
377 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
378 /* Check if an instance with no DMA support is configured in DMA mode */
379 LINFLEXD_UART_IP_DEV_ASSERT((UserConfig->TransferType != LINFLEXD_UART_IP_USING_DMA) || Linflexd_Uart_Ip_InstHasDma[Instance]);
380 #endif
381 LINFLEXD_Type * Base = Linflexd_Uart_Ip_apBases[Instance];
382 Linflexd_Uart_Ip_apStateStructuresArray[Instance] = UserConfig->StateStruct;
383
384 Linflexd_Uart_Ip_StateStructureType *UartStatePtr = Linflexd_Uart_Ip_apStateStructuresArray[Instance];
385 Linflexd_Uart_Ip_apUserConfig[Instance] = UserConfig;
386 ClearStructPtr = (uint8 *)UartStatePtr;
387
388 /* Clear the state struct for this Instance. */
389 for (Index = 0; Index < sizeof(Linflexd_Uart_Ip_StateStructureType); Index++)
390 {
391 ClearStructPtr[Index] = 0U;
392 }
393 #if (STD_ON == LINFLEXD_UART_IP_SET_USER_ACCESS_ALLOWED_AVAILABLE)
394 Linflexd_Uart_Ip_SetUserAccessAllowed(Instance);
395 #endif
396 /* Request init mode and wait until the mode entry is complete */
397 Linflexd_Uart_Ip_EnterInitMode(Base);
398
399 UartStatePtr->IsDriverInitialized = FALSE;
400
401 Linflexd_Uart_Ip_StartTimeout(&StartTime, &TimeoutTicks, (uint32)LINFLEXD_UART_IP_TIMEOUT_VALUE_US, LINFLEXD_UART_IP_TIMEOUT_TYPE);
402 while (!Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE) &&
403 (Linflexd_Uart_Ip_GetLinState(Base) != LINFLEXD_STATE_INIT_MODE)) {}
404
405 if (LINFLEXD_STATE_INIT_MODE == Linflexd_Uart_Ip_GetLinState(Base))
406 {
407 UartStatePtr->IsDriverInitialized = TRUE;
408 }
409
410 /* Set up UART mode, baud rate, word length, parity, stop bits count and enable FIFO. */
411 Linflexd_Uart_Ip_SetUp_Init(Instance);
412
413 /* Enter normal mode */
414 Linflexd_Uart_Ip_EnterNormalMode(Base);
415
416 Linflexd_Uart_Ip_SetTransmitterState(Base, FALSE);
417 Linflexd_Uart_Ip_SetReceiverState(Base, FALSE);
418
419 /* initialize last driver operation status */
420 UartStatePtr->TransmitStatus = LINFLEXD_UART_IP_STATUS_SUCCESS;
421 UartStatePtr->ReceiveStatus = LINFLEXD_UART_IP_STATUS_SUCCESS;
422 }
423
424
425 /*FUNCTION**********************************************************************
426 *
427 * Function Name : Linflexd_Uart_Ip_Deinit
428 * Description : This function shuts down the UART by disabling interrupts and
429 * transmitter/receiver.
430 *
431 *END**************************************************************************/
432 /* implements Linflexd_Uart_Ip_Deinit_Activity */
Linflexd_Uart_Ip_Deinit(const uint8 Instance)433 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_Deinit(const uint8 Instance)
434 {
435 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
436
437 LINFLEXD_Type * Base;
438 Linflexd_Uart_Ip_StatusType RetVal;
439 const Linflexd_Uart_Ip_StateStructureType * UartState;
440 uint32 StartTime;
441 uint32 TimeoutTicks;
442 uint32 ElapsedTicks = 0;
443
444 Base = Linflexd_Uart_Ip_apBases[Instance];
445 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
446
447 Linflexd_Uart_Ip_StartTimeout(&StartTime, &TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_VALUE_US, LINFLEXD_UART_IP_TIMEOUT_TYPE);
448 /* Wait until the data is completely shifted out of shift register */
449 while ((UartState->IsTxBusy || UartState->IsRxBusy) && \
450 !Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
451 {}
452 /* Disable Tx data register empty and transmission complete interrupt */
453 if (Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
454 {
455 RetVal = LINFLEXD_UART_IP_STATUS_ERROR;
456 }
457 else
458 {
459 /* Calling Linflexd_Uart_Ip_Deinit shall disable the transmitter and reciever. */
460 /* Disable transmission complete interrupt */
461 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_TRANSMITTED_INT, FALSE);
462 /* Disable receive data full interrupt. */
463 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_RECEPTION_COMPLETE_INT, FALSE);
464
465 /* Calling Linflexd_Uart_Ip_Deinit shall disable error interrupts (rx overrun and framing error).*/
466 /* Disable error interrupts */
467 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_FRAME_ERROR_INT, FALSE);
468 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_BUFFER_OVERRUN_INT, FALSE);
469 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
470 if (Linflexd_Uart_Ip_InstHasTimeoutInterruptEnabled[Instance])
471 {
472 /* Disable timeout interrupt */
473 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_TIMEOUT_INT, FALSE);
474 }
475 #endif
476
477 /* Clear the saved pointer to the state structure */
478 Linflexd_Uart_Ip_apStateStructuresArray[Instance] = NULL_PTR;
479
480 RetVal = LINFLEXD_UART_IP_STATUS_SUCCESS;
481 }
482 return RetVal;
483 }
484
485 /*FUNCTION**********************************************************************
486 *
487 * Function Name : Linflexd_Uart_Ip_SetTxBuffer
488 * Description : Sets the driver internal reference to the tx buffer.
489 * Can be called from the tx callback to provide a different
490 * buffer for continuous transmission.
491 *
492 *END**************************************************************************/
493 /* implements Linflexd_Uart_Ip_SetTxBuffer_Activity */
Linflexd_Uart_Ip_SetTxBuffer(const uint8 Instance,const uint8 * TxBuff,const uint32 TxSize)494 void Linflexd_Uart_Ip_SetTxBuffer(const uint8 Instance,
495 const uint8 * TxBuff,
496 const uint32 TxSize)
497 {
498 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
499 LINFLEXD_UART_IP_DEV_ASSERT(TxBuff != NULL_PTR);
500 LINFLEXD_UART_IP_DEV_ASSERT(TxSize > 0U);
501
502 Linflexd_Uart_Ip_StateStructureType * UartState;
503
504 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
505
506 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
507
508 UartState->TxBuff = TxBuff;
509 UartState->TxSize = TxSize;
510
511 }
512
513 /*FUNCTION**********************************************************************
514 *
515 * Function Name : Linflexd_Uart_Ip_SetRxBuffer
516 * Description : Sets the driver internal reference to the rx buffer.
517 * Can be called from the rx callback to provide a different
518 * buffer for continuous reception.
519 *
520 *END**************************************************************************/
521 /* implements Linflexd_Uart_Ip_SetRxBuffer_Activity */
Linflexd_Uart_Ip_SetRxBuffer(const uint8 Instance,uint8 * RxBuff,const uint32 RxSize)522 void Linflexd_Uart_Ip_SetRxBuffer(const uint8 Instance,
523 uint8 * RxBuff,
524 const uint32 RxSize)
525 {
526 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
527 LINFLEXD_UART_IP_DEV_ASSERT(RxBuff != NULL_PTR);
528 LINFLEXD_UART_IP_DEV_ASSERT(RxSize > 0U);
529
530 Linflexd_Uart_Ip_StateStructureType * UartState;
531
532 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
533
534 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
535
536 UartState->RxBuff = RxBuff;
537 UartState->RxSize = RxSize;
538
539 }
540
541 /*FUNCTION**********************************************************************
542 *
543 * Function Name : Linflexd_Uart_Ip_PutData
544 * Description : Write data to the buffer register, according to configured
545 * word length.
546 * This is not a public API as it is called from other driver functions.
547 *
548 *END**************************************************************************/
Linflexd_Uart_Ip_PutData(const uint8 Instance)549 static void Linflexd_Uart_Ip_PutData(const uint8 Instance)
550 {
551 Linflexd_Uart_Ip_StateStructureType * UartState;
552 LINFLEXD_Type * Base;
553 const Linflexd_Uart_Ip_UserConfigType *UartUserCfg;
554 Base = Linflexd_Uart_Ip_apBases[Instance];
555
556 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
557 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
558
559 if ((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength))
560 {
561 uint8 Data = *(UartState->TxBuff);
562 /* Update the state structure */
563 ++UartState->TxBuff;
564 --UartState->TxSize;
565 /* Transmit the Data */
566 Linflexd_Uart_Ip_SetTxDataBuffer1Byte(Base, Data);
567 }
568 else
569 {
570 /* Transmit the Data and update state structure */
571 if (1U == UartState->TxSize)
572 {
573 uint16 Data = (uint16)(*UartState->TxBuff);
574 ++UartState->TxBuff;
575 --UartState->TxSize;
576 Linflexd_Uart_Ip_SetTxDataBuffer2Bytes(Base, Data);
577 }
578 else
579 {
580 uint16 Data = *((const uint16*)UartState->TxBuff);
581 /* Move the pointer twice */
582 ++UartState->TxBuff;
583 ++UartState->TxBuff;
584 UartState->TxSize -= 2U;
585 Linflexd_Uart_Ip_SetTxDataBuffer2Bytes(Base, Data);
586 }
587 }
588 }
589
590 /*FUNCTION**********************************************************************
591 *
592 * Function Name : Linflexd_Uart_Ip_CompleteSendUsingInterrupts
593 * Description : Finish up a transmit by completing the process of sending
594 * Data and disabling the interrupt.
595 * This is not a public API as it is called from other driver functions.
596 *
597 *END**************************************************************************/
Linflexd_Uart_Ip_CompleteSendUsingInterrupts(const uint8 Instance)598 static void Linflexd_Uart_Ip_CompleteSendUsingInterrupts(const uint8 Instance)
599 {
600 Linflexd_Uart_Ip_StateStructureType * UartState;
601 LINFLEXD_Type * Base;
602 uint32 StartTime;
603 uint32 TimeoutTicks = 0;
604 uint32 ElapsedTicks = 0;
605
606 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
607 Base = Linflexd_Uart_Ip_apBases[Instance];
608
609 /* Disable transmission complete interrupt */
610 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_TRANSMITTED_INT, FALSE);
611 /* In Abort case, the transmission need to stop instantly */
612 /* In case the Abort function is called when the last byte is transmited
613 checking the Data Transmission Complete flag in the while function will result in Timeout Error
614 so the TxSize needs to be greater than zero. */
615 if ((LINFLEXD_UART_IP_STATUS_ABORTED == UartState->TransmitStatus) && (UartState->TxSize > 0U))
616 {
617 Linflexd_Uart_Ip_StartTimeout(&StartTime, &TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_VALUE_US, LINFLEXD_UART_IP_TIMEOUT_TYPE);
618 /* Wait until the data is completely shifted out of shift register */
619 while (!Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG) && \
620 !Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
621 {}
622 if (Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
623 {
624 /* In case timeout occur */
625 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_TIMEOUT;
626 }
627 /* Clear data transmission completed flag */
628 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG);
629 }
630 /* Disable the transmitter */
631 Linflexd_Uart_Ip_SetTransmitterState(Base, FALSE);
632
633 /* Update the information of the module driver state */
634 UartState->IsTxBusy = FALSE;
635
636 /* If the current transmission hasn't been aborted, update the status */
637 if (LINFLEXD_UART_IP_STATUS_BUSY == UartState->TransmitStatus)
638 {
639 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_SUCCESS;
640 }
641 }
642
643 /*FUNCTION**********************************************************************
644 *
645 * Function Name : Linflexd_Uart_Ip_CompleteReceiveUsingInterrupts
646 * Description : Finish up a receive by completing the process of receiving data
647 * and disabling the interrupt.
648 * This is not a public API as it is called from other driver functions.
649 *
650 *END**************************************************************************/
Linflexd_Uart_Ip_CompleteReceiveUsingInterrupts(const uint8 Instance)651 static void Linflexd_Uart_Ip_CompleteReceiveUsingInterrupts(const uint8 Instance)
652 {
653 Linflexd_Uart_Ip_StateStructureType * UartState;
654 LINFLEXD_Type * Base;
655 uint32 StartTime;
656 uint32 TimeoutTicks;
657 uint32 ElapsedTicks = 0;
658
659 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
660 Base = Linflexd_Uart_Ip_apBases[Instance];
661
662 /* Disable receive data full interrupt. */
663 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_RECEPTION_COMPLETE_INT, FALSE);
664
665 /* Disable error interrupts */
666 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_FRAME_ERROR_INT, FALSE);
667 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_BUFFER_OVERRUN_INT, FALSE);
668 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
669 if (Linflexd_Uart_Ip_InstHasTimeoutInterruptEnabled[Instance])
670 {
671 /* Disable timeout interrupt */
672 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_TIMEOUT_INT, FALSE);
673 }
674 #endif
675 /* In Abort case, the transmission need to stop instantly */
676 /* In case the Abort function is called when the last byte is received
677 checking the Data Reception Complete flag in the while function will result in Timeout Error
678 so the RxSize needs to be greater than zero. */
679 if ((LINFLEXD_UART_IP_STATUS_ABORTED == UartState->ReceiveStatus) && (UartState->RxSize > 0U))
680 {
681 Linflexd_Uart_Ip_StartTimeout(&StartTime, &TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_VALUE_US, LINFLEXD_UART_IP_TIMEOUT_TYPE);
682 /* Wait until the data is completely received */
683 while (!Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG) && \
684 !Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
685 {}
686
687 if (Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
688 {
689 /* In case timeout occur */
690 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_TIMEOUT;
691 }
692 /* Read dummy to get all data remaning */
693 Linflexd_Uart_Ip_GetData(Instance);
694 /* Clear data reception completed flag */
695 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG);
696 }
697 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
698 if (LINFLEXD_UART_IP_STATUS_RX_IDLE_STATE != UartState->ReceiveStatus)
699 #endif
700 {
701 /* Disable the receiver */
702 Linflexd_Uart_Ip_SetReceiverState(Base, FALSE);
703 }
704
705 /* Update the information of the module driver state */
706 UartState->IsRxBusy = FALSE;
707
708 /* If the current reception hasn't been aborted and no error occurred, update the status */
709 if (LINFLEXD_UART_IP_STATUS_BUSY == UartState->ReceiveStatus)
710 {
711 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_SUCCESS;
712 }
713 }
714
715 /*FUNCTION**********************************************************************
716 *
717 * Function Name : Linflexd_Uart_Ip_SyncSend
718 * Description : Send out multiple bytes of data using polling method.
719 *
720 *END**************************************************************************/
721 /* implements Linflexd_Uart_Ip_SyncSend_Activity */
Linflexd_Uart_Ip_SyncSend(const uint8 Instance,const uint8 * TxBuff,const uint32 TxSize,const uint32 Timeout)722 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_SyncSend(const uint8 Instance,
723 const uint8 *TxBuff,
724 const uint32 TxSize,
725 const uint32 Timeout)
726 {
727
728 /* Check the validity of the parameters */
729 LINFLEXD_UART_IP_DEV_ASSERT(TxSize > 0U);
730 LINFLEXD_UART_IP_DEV_ASSERT(TxBuff != NULL_PTR);
731 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
732
733 Linflexd_Uart_Ip_StateStructureType * UartState;
734 LINFLEXD_Type * Base;
735 uint32 StartTime;
736 uint32 TimeoutTicks;
737 uint32 ElapsedTicks = 0;
738 Linflexd_Uart_Ip_StatusType Status = LINFLEXD_UART_IP_STATUS_TIMEOUT;
739 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
740 Base = Linflexd_Uart_Ip_apBases[Instance];
741
742 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
743
744 SchM_Enter_Uart_UART_EXCLUSIVE_AREA_03();
745 /* Check driver is not busy transmitting data from a previous asynchronous call */
746 if (UartState->IsTxBusy)
747 {
748 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_03();
749 Status = LINFLEXD_UART_IP_STATUS_BUSY;
750 }
751 else
752 {
753 /* Initialize the module driver state structure */
754 UartState->IsTxBusy = TRUE;
755 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_03();
756 UartState->TxBuff = TxBuff;
757 UartState->TxSize = TxSize;
758
759 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_BUSY;
760
761 /* The interrupts shall be disabled when the Linflexd_Uart_Ip_SyncReceive and Linflexd_Uart_Ip_SyncSend are called. */
762 /* Disble transmission complete interrupt */
763 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_TRANSMITTED_INT, FALSE);
764 /* Disable receive data full interrupt. */
765 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_RECEPTION_COMPLETE_INT, FALSE);
766
767 /* Disable error interrupts */
768 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_FRAME_ERROR_INT, FALSE);
769 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_BUFFER_OVERRUN_INT, FALSE);
770
771 /* Enable the transmitter */
772 Linflexd_Uart_Ip_SetTransmitterState(Base, TRUE);
773
774 Linflexd_Uart_Ip_StartTimeout(&StartTime, &TimeoutTicks, Timeout, LINFLEXD_UART_IP_TIMEOUT_TYPE);
775
776 while ((UartState->TxSize > 0U) && !Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
777 {
778 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG);
779 Linflexd_Uart_Ip_PutData(Instance);
780 /* Wait until data transmited flag is set or timeout occurs if there is an error during transmission */
781 while (!Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG) && \
782 !Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
783 {}
784 }
785 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG);
786
787 /* Disable the transmitter */
788 Linflexd_Uart_Ip_SetTransmitterState(Base, FALSE);
789
790 /* Check if Timeout occur */
791 if (UartState->TxSize > 0U)
792 {
793 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_TIMEOUT;
794 }else /* The transmit process is complete */
795 {
796 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_SUCCESS;
797 }
798 UartState->IsTxBusy = FALSE;
799 Status = UartState->TransmitStatus;
800 }
801 return Status;
802 }
803
804
805 /*FUNCTION**********************************************************************
806 *
807 * Function Name : Linflexd_Uart_Ip_GetData
808 * Description : Read data from the buffer register, according to configured
809 * word length.
810 * This is not a public API as it is called from other driver functions.
811 *
812 *END**************************************************************************/
Linflexd_Uart_Ip_GetData(const uint8 Instance)813 static void Linflexd_Uart_Ip_GetData(const uint8 Instance)
814 {
815 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
816 Linflexd_Uart_Ip_StateStructureType * UartState;
817 const LINFLEXD_Type * Base;
818
819 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
820 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
821 Base = Linflexd_Uart_Ip_apBases[Instance];
822
823
824 if ((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength))
825 {
826 /* Get the data */
827 *(UartState->RxBuff) = Linflexd_Uart_Ip_GetRxDataBuffer1Byte(Base);
828 /* Update the state structure */
829 ++UartState->RxBuff;
830 --UartState->RxSize;
831 }
832 else
833 {
834 /* Get the data and update state structure */
835 if (1U == UartState->RxSize)
836 {
837 *(UartState->RxBuff) = (uint8)(Linflexd_Uart_Ip_GetRxDataBuffer2Bytes(Base));
838 ++UartState->RxBuff;
839 --UartState->RxSize;
840 }
841 else
842 {
843 *((uint16*)(UartState->RxBuff)) = Linflexd_Uart_Ip_GetRxDataBuffer2Bytes(Base);
844 /* Move the pointer twice */
845 ++UartState->RxBuff;
846 ++UartState->RxBuff;
847 UartState->RxSize -= 2U;
848 }
849 }
850 }
851
852 /*FUNCTION**********************************************************************
853 *
854 * Function Name : Linflexd_Uart_Ip_SyncReceive
855 * Description : Retrieves data from the LINFLEXD module in UART mode with
856 * polling method.
857 *
858 *END**************************************************************************/
859 /* implements Linflexd_Uart_Ip_SyncReceive_Activity*/
Linflexd_Uart_Ip_SyncReceive(const uint8 Instance,uint8 * RxBuff,const uint32 RxSize,const uint32 Timeout)860 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_SyncReceive(const uint8 Instance,
861 uint8 * RxBuff,
862 const uint32 RxSize,
863 const uint32 Timeout)
864 {
865 /* Check the validity of the parameters */
866 LINFLEXD_UART_IP_DEV_ASSERT(RxSize > 0U);
867 LINFLEXD_UART_IP_DEV_ASSERT(RxBuff != NULL_PTR);
868 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
869
870 Linflexd_Uart_Ip_StateStructureType * UartState;
871 LINFLEXD_Type * Base;
872 uint32 StartTime;
873 uint32 TimeoutTicks;
874 uint32 ElapsedTicks = 0;
875 Linflexd_Uart_Ip_StatusType Status = LINFLEXD_UART_IP_STATUS_TIMEOUT;
876
877 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
878 Base = Linflexd_Uart_Ip_apBases[Instance];
879
880 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
881
882 SchM_Enter_Uart_UART_EXCLUSIVE_AREA_06();
883 /* Check driver is not busy transmitting data from a previous asynchronous call */
884 if (UartState->IsRxBusy)
885 {
886 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_06();
887 Status = LINFLEXD_UART_IP_STATUS_BUSY;
888 }
889 else
890 {
891 /* Initialize the module driver state structure */
892 UartState->IsRxBusy = TRUE;
893 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_06();
894 UartState->RxBuff = RxBuff;
895 UartState->RxSize = RxSize;
896 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_BUSY;
897
898 /*The interrupts shall be disabled when the Linflexd_Uart_Ip_SyncReceive and Linflexd_Uart_Ip_SyncSend are called.*/
899 Linflexd_Uart_Ip_SetUp_Receiver(Instance);
900
901 Linflexd_Uart_Ip_StartTimeout(&StartTime, &TimeoutTicks, Timeout, LINFLEXD_UART_IP_TIMEOUT_TYPE);
902
903 /* Update status and clear the flag according to the error occurred */
904 Linflexd_Uart_Ip_UpdateReceiver(Instance, &StartTime, &ElapsedTicks, TimeoutTicks);
905
906 /* Check if Timeout occur */
907 if (Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
908 {
909 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_TIMEOUT;
910 }
911
912 if (LINFLEXD_UART_IP_STATUS_BUSY == UartState->ReceiveStatus)
913 {
914 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_SUCCESS;
915 }
916
917 /* Disable the receiver */
918 Linflexd_Uart_Ip_SetReceiverState(Base, FALSE);
919 UartState->IsRxBusy = FALSE;
920 Status = UartState->ReceiveStatus;
921 }
922 return Status;
923 }
924
925
926 /*FUNCTION**********************************************************************
927 *
928 * Function Name : Linflexd_Uart_Ip_AbortReceivingData
929 * Description : Terminates a non-blocking receive early.
930 *
931 *END**************************************************************************/
932 /* implements Linflexd_Uart_Ip_AbortReceivingData_Activity*/
Linflexd_Uart_Ip_AbortReceivingData(const uint8 Instance)933 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_AbortReceivingData(const uint8 Instance)
934 {
935 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
936
937 Linflexd_Uart_Ip_StateStructureType * UartState;
938 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
939
940 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
941 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
942 Linflexd_Uart_Ip_StatusType Status = LINFLEXD_UART_IP_STATUS_SUCCESS;
943
944 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
945 LINFLEXD_UART_IP_DEV_ASSERT(UartUserCfg != NULL_PTR);
946
947 /* Check if a transfer is running. */
948 if (!UartState->IsRxBusy)
949 {
950 Status = LINFLEXD_UART_IP_STATUS_SUCCESS;
951 }
952 else
953 {
954 /* Update the rx status */
955 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_ABORTED;
956
957 /* Stop the running transfer. */
958 if (LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
959 {
960 Linflexd_Uart_Ip_CompleteReceiveUsingInterrupts(Instance);
961 }
962 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
963 else
964 {
965 /* Release the DMA channel */
966 (void)Dma_Ip_SetLogicChannelCommand(UartUserCfg->RxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
967 Linflexd_Uart_Ip_CompleteReceiveUsingDma(Instance);
968 }
969 #endif
970 }
971 if (LINFLEXD_UART_IP_STATUS_TIMEOUT == UartState->ReceiveStatus)
972 {
973 Status = LINFLEXD_UART_IP_STATUS_ERROR;
974 }
975 return Status;
976 }
977
978 /*FUNCTION**********************************************************************
979 *
980 * Function Name : Linflexd_Uart_Ip_AbortSendingData
981 * Description : This function terminates an non-blocking UART transmission
982 * early. During a non-blocking UART transmission, the user has the option to
983 * terminate the transmission early if the transmission is still in progress.
984 *
985 *END**************************************************************************/
986 /* implements Linflexd_Uart_Ip_AbortSendingData_Activity */
Linflexd_Uart_Ip_AbortSendingData(const uint8 Instance)987 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_AbortSendingData(const uint8 Instance)
988 {
989 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
990
991 Linflexd_Uart_Ip_StateStructureType * UartState;
992 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
993
994 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
995 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
996 Linflexd_Uart_Ip_StatusType Status = LINFLEXD_UART_IP_STATUS_SUCCESS;
997
998 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
999 LINFLEXD_UART_IP_DEV_ASSERT(UartUserCfg != NULL_PTR);
1000
1001 /* Check if a transfer is running. */
1002 if (!UartState->IsTxBusy)
1003 {
1004 Status = LINFLEXD_UART_IP_STATUS_SUCCESS;
1005 }
1006 else
1007 {
1008 /* Update the tx status */
1009 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_ABORTED;
1010
1011 /* Stop the running transfer. */
1012 if (LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
1013 {
1014 Linflexd_Uart_Ip_CompleteSendUsingInterrupts(Instance);
1015 }
1016 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
1017 else
1018 {
1019 /* Release the DMA channel */
1020 Linflexd_Uart_Ip_CompleteSendUsingDma(Instance);
1021 (void)Dma_Ip_SetLogicChannelCommand(UartUserCfg->TxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
1022 }
1023 #endif
1024 }
1025 if (LINFLEXD_UART_IP_STATUS_TIMEOUT == UartState->TransmitStatus)
1026 {
1027 Status = LINFLEXD_UART_IP_STATUS_ERROR;
1028 }
1029 return Status;
1030 }
1031
1032 /*FUNCTION**********************************************************************
1033 *
1034 * Function Name : Linflexd_Uart_Ip_StartReceiveUsingInterrupts
1035 * Description : Initiate (start) a receive by beginning the process of
1036 * receiving data and enabling the interrupt.
1037 * This is not a public API as it is called from other driver functions.
1038 *
1039 *END**************************************************************************/
Linflexd_Uart_Ip_StartReceiveUsingInterrupts(const uint8 Instance,uint8 * RxBuff,const uint32 RxSize)1040 static Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_StartReceiveUsingInterrupts(const uint8 Instance,
1041 uint8 * RxBuff,
1042 const uint32 RxSize)
1043 {
1044 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
1045 LINFLEXD_UART_IP_DEV_ASSERT(RxBuff != NULL_PTR);
1046
1047 Linflexd_Uart_Ip_StateStructureType * UartState;
1048 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
1049 LINFLEXD_Type * Base;
1050
1051 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1052 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1053 Base = Linflexd_Uart_Ip_apBases[Instance];
1054 Linflexd_Uart_Ip_StatusType Status = LINFLEXD_UART_IP_STATUS_ERROR;
1055
1056 SchM_Enter_Uart_UART_EXCLUSIVE_AREA_07();
1057 /* Check it's not busy receiving data from a previous function call */
1058 if ((UartState->IsRxBusy) && (UartUserCfg->Callback != NULL_PTR))
1059 {
1060 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_07();
1061 Status = LINFLEXD_UART_IP_STATUS_BUSY;
1062 }
1063 else
1064 {
1065 /* Initialize the module driver state struct to indicate transfer in progress
1066 * and with the buffer and byte count data. */
1067 UartState->IsRxBusy = TRUE;
1068 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_07();
1069 UartState->RxBuff = RxBuff;
1070 LINFLEXD_UART_IP_DEV_ASSERT(RxSize > 0U);
1071 UartState->RxSize = RxSize;
1072 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_BUSY;
1073
1074 /* Clear the flag */
1075 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG);
1076 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_MESSAGE_BUFFER_FULL_FLAG);
1077 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_FRAME_ERROR_FLAG);
1078 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_BUFFER_OVERRUN_FLAG);
1079
1080 /* Enable the receiver */
1081 Linflexd_Uart_Ip_SetReceiverState(Base, TRUE);
1082
1083 /* Enable receive data full interrupt */
1084 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_RECEPTION_COMPLETE_INT, TRUE);
1085 Status = LINFLEXD_UART_IP_STATUS_SUCCESS;
1086 }
1087 return Status;
1088 }
1089
1090 /*FUNCTION**********************************************************************
1091 *
1092 * Function Name : Linflexd_Uart_Ip_GetReceiveStatus
1093 * Description : This function returns whether the previous UART receive is
1094 * complete. When performing a non-blocking receive, the user can call this
1095 * function to ascertain the state of the current receive progress: in progress
1096 * or complete. In addition, if the receive is still in progress, the user can
1097 * obtain the number of words that have not yet been received.
1098 *
1099 *END**************************************************************************/
1100 /* implements Linflexd_Uart_Ip_GetReceiveStatus_Activity */
Linflexd_Uart_Ip_GetReceiveStatus(const uint8 Instance,uint32 * BytesRemaining)1101 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_GetReceiveStatus(const uint8 Instance, uint32 * BytesRemaining)
1102 {
1103 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
1104
1105 const Linflexd_Uart_Ip_StateStructureType * UartState;
1106 const Linflexd_Uart_Ip_UserConfigType *UartUserCfg;
1107 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1108 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1109
1110 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
1111 LINFLEXD_UART_IP_DEV_ASSERT(UartUserCfg != NULL_PTR);
1112
1113 if (BytesRemaining != NULL_PTR)
1114 {
1115 if (UartState->IsRxBusy)
1116 {
1117 Linflexd_Uart_Ip_GetRemainingBytes(Instance, BytesRemaining, LINFLEXD_UART_IP_RECEIVE);
1118 }
1119 else
1120 {
1121 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
1122 if (LINFLEXD_UART_IP_STATUS_RX_IDLE_STATE == UartState->ReceiveStatus)
1123 {
1124 Linflexd_Uart_Ip_GetRemainingBytes(Instance, BytesRemaining, LINFLEXD_UART_IP_RECEIVE);
1125 }
1126 else
1127 #endif
1128 {
1129 *BytesRemaining = 0;
1130 }
1131 }
1132 }
1133
1134 return UartState->ReceiveStatus;
1135 }
1136
1137 /*FUNCTION**********************************************************************
1138 *
1139 * Function Name : Linflexd_Uart_Ip_GetTransmitStatus
1140 * Description : This function returns whether the previous UART transmit has
1141 * finished. When performing non-blocking transmit, the user can call this
1142 * function to ascertain the state of the current transmission:
1143 * in progress (or busy) or complete (success). In addition, if the transmission
1144 * is still in progress, the user can obtain the number of words that have been
1145 * currently transferred.
1146 *
1147 *END**************************************************************************/
1148 /* implements Linflexd_Uart_Ip_GetTransmitStatus_Activity */
Linflexd_Uart_Ip_GetTransmitStatus(const uint8 Instance,uint32 * BytesRemaining)1149 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_GetTransmitStatus(const uint8 Instance, uint32 * BytesRemaining)
1150 {
1151 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
1152
1153 const Linflexd_Uart_Ip_StateStructureType * UartState;
1154 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
1155 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1156 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1157
1158 LINFLEXD_UART_IP_DEV_ASSERT(UartState != NULL_PTR);
1159 LINFLEXD_UART_IP_DEV_ASSERT(UartUserCfg != NULL_PTR);
1160
1161 if (BytesRemaining != NULL_PTR)
1162 {
1163 /* Fill in the number of bytes yet to be transferred and update the return value if needed */
1164 if (UartState->IsTxBusy)
1165 {
1166 Linflexd_Uart_Ip_GetRemainingBytes(Instance, BytesRemaining, LINFLEXD_UART_IP_SEND);
1167 }
1168 else
1169 {
1170 *BytesRemaining = 0;
1171 }
1172 }
1173 return UartState->TransmitStatus;
1174 }
1175
1176 /*FUNCTION**********************************************************************
1177 *
1178 * Function Name : Linflexd_Uart_Ip_AsyncReceive
1179 * Description : Retrieves data from the LINFLEXD module in UART mode with
1180 * non-blocking method.
1181 *
1182 *END**************************************************************************/
1183 /* implements Linflexd_Uart_Ip_AsyncReceive_Activity*/
Linflexd_Uart_Ip_AsyncReceive(const uint8 Instance,uint8 * RxBuff,const uint32 RxSize)1184 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_AsyncReceive(const uint8 Instance,
1185 uint8 * RxBuff,
1186 const uint32 RxSize)
1187 {
1188 LINFLEXD_UART_IP_DEV_ASSERT(RxBuff != NULL_PTR);
1189 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
1190 LINFLEXD_Type * Base;
1191 Linflexd_Uart_Ip_StatusType RetVal = LINFLEXD_UART_IP_STATUS_ERROR;
1192 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
1193
1194 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1195 Base = Linflexd_Uart_Ip_apBases[Instance];
1196
1197 LINFLEXD_UART_IP_DEV_ASSERT(UartUserCfg != NULL_PTR);
1198
1199 /* Enable error interrupts */
1200 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_FRAME_ERROR_INT, TRUE);
1201 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_BUFFER_OVERRUN_INT, TRUE);
1202
1203 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
1204 if (Linflexd_Uart_Ip_InstHasTimeoutInterruptEnabled[Instance])
1205 {
1206 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_TIMEOUT_INT, TRUE);
1207 }
1208 #endif
1209
1210 if (LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
1211 {
1212 /* Start the transmission process using interrupts */
1213 RetVal = Linflexd_Uart_Ip_StartReceiveUsingInterrupts(Instance, RxBuff, RxSize);
1214 }
1215 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
1216 else
1217 {
1218 /* Start the transmission process using DMA */
1219 RetVal = Linflexd_Uart_Ip_StartReceiveUsingDma(Instance, RxBuff, RxSize);
1220 }
1221 #endif
1222 return RetVal;
1223 }
1224
1225
1226 /*FUNCTION**********************************************************************
1227 *
1228 * Function Name : Linflexd_Uart_Ip_StartSendUsingInterrupts
1229 * Description : Initiate (start) a transmit by beginning the process of
1230 * sending data and enabling the interrupt.
1231 * This is not a public API as it is called from other driver functions.
1232 *
1233 *END**************************************************************************/
Linflexd_Uart_Ip_StartSendUsingInterrupts(const uint8 Instance,const uint8 * TxBuff,const uint32 TxSize)1234 static Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_StartSendUsingInterrupts(const uint8 Instance,
1235 const uint8 * TxBuff,
1236 const uint32 TxSize)
1237 {
1238 LINFLEXD_Type * Base;
1239 Linflexd_Uart_Ip_StateStructureType * UartState;
1240 Linflexd_Uart_Ip_StatusType Status = LINFLEXD_UART_IP_STATUS_ERROR;
1241 Base = Linflexd_Uart_Ip_apBases[Instance];
1242 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1243
1244 SchM_Enter_Uart_UART_EXCLUSIVE_AREA_04();
1245 /* Check it's not busy transmitting data from a previous function call */
1246 if (UartState->IsTxBusy)
1247 {
1248 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_04();
1249 Status = LINFLEXD_UART_IP_STATUS_BUSY;
1250 }
1251 else
1252 {
1253 /* Initialize the module driver state structure */
1254 UartState->IsTxBusy = TRUE;
1255 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_04();
1256 UartState->TxBuff = TxBuff;
1257
1258 LINFLEXD_UART_IP_DEV_ASSERT(TxSize > 0U);
1259 UartState->TxSize = TxSize;
1260
1261 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_BUSY;
1262
1263 /* Enable the transmitter */
1264 Linflexd_Uart_Ip_SetTransmitterState(Base, TRUE);
1265
1266 /* Clear the tx empty flag to make sure the transmission of the first byte
1267 * doesn't occur right after enabling the tx interrupt
1268 */
1269 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG);
1270
1271 /* Enable transmission complete interrupt */
1272 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_TRANSMITTED_INT, TRUE);
1273
1274 /* Transmit the first word */
1275 Linflexd_Uart_Ip_PutData(Instance);
1276 Status = LINFLEXD_UART_IP_STATUS_SUCCESS;
1277 }
1278 return Status;
1279 }
1280
1281 /*FUNCTION**********************************************************************
1282 *
1283 * Function Name : Linflexd_Uart_Ip_AsyncSend
1284 * Description : This function sends data using LINFLEXD module in UART mode
1285 * with non-blocking method.
1286 *
1287 *END**************************************************************************/
1288 /* implements Linflexd_Uart_Ip_AsyncSend_Activity */
Linflexd_Uart_Ip_AsyncSend(const uint8 Instance,const uint8 * TxBuff,const uint32 TxSize)1289 Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_AsyncSend(const uint8 Instance,
1290 const uint8 * TxBuff,
1291 const uint32 TxSize)
1292 {
1293 LINFLEXD_UART_IP_DEV_ASSERT(TxBuff != NULL_PTR);
1294 LINFLEXD_UART_IP_DEV_ASSERT(Instance < LINFLEXD_INSTANCE_COUNT);
1295
1296 Linflexd_Uart_Ip_StatusType RetVal = LINFLEXD_UART_IP_STATUS_ERROR;
1297 const Linflexd_Uart_Ip_UserConfigType *UartUserCfg;
1298
1299 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1300
1301 LINFLEXD_UART_IP_DEV_ASSERT(UartUserCfg != NULL_PTR);
1302 LINFLEXD_UART_IP_DEV_ASSERT((LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType) ||
1303 (LINFLEXD_UART_IP_USING_DMA == UartUserCfg->TransferType));
1304
1305 if (LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
1306 {
1307 /* Start the transmission process using interrupts */
1308 RetVal = Linflexd_Uart_Ip_StartSendUsingInterrupts(Instance, TxBuff, TxSize);
1309 }
1310 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
1311 else
1312 {
1313 /* Start the transmission process using DMA */
1314 RetVal = Linflexd_Uart_Ip_StartSendUsingDma(Instance, TxBuff, TxSize);
1315 }
1316 #endif
1317 /* Start the transmission process */
1318 return RetVal;
1319 }
1320
1321 /*FUNCTION**********************************************************************
1322 *
1323 * Function Name : Linflexd_Uart_Ip_RxIRQHandler
1324 * Description : Rx interrupt handler for UART.
1325 * This handler uses the rx buffer stored in the state structure to receive
1326 * data. This is not a public API as it is called by IRQ whenever an interrupt
1327 * occurs.
1328 *
1329 *END**************************************************************************/
Linflexd_Uart_Ip_RxIRQHandler(uint8 Instance)1330 static void Linflexd_Uart_Ip_RxIRQHandler(uint8 Instance)
1331 {
1332 const Linflexd_Uart_Ip_StateStructureType * UartState;
1333 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
1334 LINFLEXD_Type * Base;
1335
1336 Base = Linflexd_Uart_Ip_apBases[Instance];
1337 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1338 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1339
1340 if (UartState != NULL_PTR)
1341 {
1342 if ((UartState->IsDriverInitialized) && (UartState->IsRxBusy))
1343 {
1344
1345 /* Retrieve the data */
1346 Linflexd_Uart_Ip_GetData(Instance);
1347
1348 /* Clear the flags */
1349 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG);
1350 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_MESSAGE_BUFFER_FULL_FLAG);
1351
1352 /* Check if this was the last byte in the current buffer */
1353 if (0U == UartState->RxSize)
1354 {
1355 /* Invoke the callback when the buffer is finished;
1356 * Application can provide another buffer inside the callback by calling Linflexd_Uart_Ip_SetRxBuffer */
1357 if (UartUserCfg->Callback != NULL_PTR)
1358 {
1359 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_RX_FULL, UartUserCfg->CallbackParam);
1360 }
1361 }
1362
1363 /* Finish reception if this was the last byte received */
1364 if (0U == UartState->RxSize)
1365 {
1366 /* Complete transfer (disable rx logic) */
1367 Linflexd_Uart_Ip_CompleteReceiveUsingInterrupts(Instance);
1368
1369 /* Invoke callback if there is one */
1370 if (UartUserCfg->Callback != NULL_PTR)
1371 {
1372 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_END_TRANSFER, UartUserCfg->CallbackParam);
1373 }
1374 }
1375 }
1376 /* Case of spurious interrupt when driver had an error in initialization */
1377 else
1378 {
1379 /* Clear the flags */
1380 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG);
1381 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_MESSAGE_BUFFER_FULL_FLAG);
1382 }
1383 }
1384 /* Case of spurious interrupt when driver is not at all initialized*/
1385 else
1386 {
1387 /* Clear the flags */
1388 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG);
1389 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_MESSAGE_BUFFER_FULL_FLAG);
1390 }
1391 }
1392
1393 /*FUNCTION**********************************************************************
1394 *
1395 * Function Name : Linflexd_Uart_Ip_TxIRQHandler
1396 * Description : Tx interrupt handler for UART.
1397 * This handler uses the tx buffer stored in the state structure to transmit
1398 * data. This is not a public API as it is called by IRQ whenever an interrupt
1399 * occurs.
1400 *
1401 *END**************************************************************************/
Linflexd_Uart_Ip_TxIRQHandler(uint8 Instance)1402 static void Linflexd_Uart_Ip_TxIRQHandler(uint8 Instance)
1403 {
1404 const Linflexd_Uart_Ip_StateStructureType * UartState;
1405 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
1406 LINFLEXD_Type * Base;
1407
1408 Base = Linflexd_Uart_Ip_apBases[Instance];
1409 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1410 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1411
1412 if (UartState != NULL_PTR)
1413 {
1414 if ((UartState->IsDriverInitialized) && (UartState->IsTxBusy))
1415 {
1416 /* Check if there are any more bytes to send */
1417 if (UartState->TxSize > 0U)
1418 {
1419 /* Clear the flag */
1420 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG);
1421
1422 /* Send data */
1423 Linflexd_Uart_Ip_PutData(Instance);
1424 }
1425 else
1426 {
1427 /* Invoke the callback when the buffer is finished;
1428 * Application can provide another buffer inside the callback by calling Linflexd_Uart_Ip_SetTxBuffer */
1429 if (UartUserCfg->Callback != NULL_PTR)
1430 {
1431 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_TX_EMPTY, UartUserCfg->CallbackParam);
1432 }
1433
1434 /* If there is no more data to send, complete the transmission */
1435 if (0U == UartState->TxSize)
1436 {
1437 Linflexd_Uart_Ip_CompleteSendUsingInterrupts(Instance);
1438
1439 /* Call the callback to notify application that the transfer is complete */
1440 if (UartUserCfg->Callback != NULL_PTR)
1441 {
1442 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_END_TRANSFER, UartUserCfg->CallbackParam);
1443 }
1444
1445 /* Clear the flag */
1446 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG);
1447 }
1448 }
1449 }
1450 /* Case of spurious interrupt when driver had an error in initialization */
1451 else
1452 {
1453 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG);
1454 }
1455 }
1456 /* Case of spurious interrupt when driver is not at all initialized*/
1457 else
1458 {
1459 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG);
1460 }
1461 }
1462
1463 /*FUNCTION**********************************************************************
1464 *
1465 * Function Name : Linflexd_Uart_Ip_ErrIRQHandler
1466 * Description : Error interrupt handler for UART.
1467 * This handler calls the user callback to treat error conditions.
1468 *
1469 *END**************************************************************************/
Linflexd_Uart_Ip_ErrIRQHandler(uint8 Instance)1470 static void Linflexd_Uart_Ip_ErrIRQHandler(uint8 Instance)
1471 {
1472 Linflexd_Uart_Ip_StateStructureType * UartState;
1473 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
1474 LINFLEXD_Type * Base;
1475
1476 Base = Linflexd_Uart_Ip_apBases[Instance];
1477 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1478 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1479
1480 if (UartState != NULL_PTR)
1481 {
1482 if (UartState->IsDriverInitialized)
1483 {
1484 /* Update the receive status according to the error occurred */
1485 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_BUFFER_OVERRUN_FLAG))
1486 {
1487 /* Update the status */
1488 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_RX_OVERRUN;
1489 /* The read dummy data not apply for DMA
1490 because reading the BDRM register in this mode IPS operation result will returns IPS transfer error status*/
1491 if(LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
1492 {
1493 /* Read dummy to take the byte that caused the overrun error and shifts it to the buffer */
1494 Linflexd_Uart_Ip_GetData(Instance);
1495 }
1496 /* Clear the flag */
1497 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_BUFFER_OVERRUN_FLAG);
1498 }
1499 else if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_FRAME_ERROR_FLAG))
1500 {
1501 /* Update the status */
1502 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_FRAMING_ERROR;
1503 /* The read dummy data not apply for DMA
1504 because reading the BDRM register in this mode IPS operation result will returns IPS transfer error status*/
1505 if(LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
1506 {
1507 /* Read dummy to take the byte that caused the framing error and shifts it to the buffer */
1508 Linflexd_Uart_Ip_GetData(Instance);
1509 }
1510 /* Clear the flag */
1511 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_FRAME_ERROR_FLAG);
1512 }
1513 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
1514 else if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_TIMEOUT_INTERRUPT_FLAG))
1515 {
1516 /* Disable the receiver to stop timer counter */
1517 Linflexd_Uart_Ip_SetReceiverState(Base, FALSE);
1518 /* Update the status */
1519 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_RX_IDLE_STATE;
1520 /* Clear Timeout Interrupt Error flag */
1521 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_TIMEOUT_INTERRUPT_FLAG);
1522 /* Reset Reset Value to default */
1523 Linflexd_Uart_Ip_SetPresetValue(Base, 0xFFF);
1524 }
1525 #endif
1526 else
1527 {
1528 /* This branch should never be reached - avoid MISRA violations */
1529 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_ERROR;
1530 }
1531
1532 /* Terminate the current reception */
1533 if (LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
1534 {
1535 Linflexd_Uart_Ip_CompleteReceiveUsingInterrupts(Instance);
1536 }
1537 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
1538 else
1539 {
1540 /* Release the DMA channel */
1541 (void)Dma_Ip_SetLogicChannelCommand(UartUserCfg->RxDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
1542 Linflexd_Uart_Ip_CompleteReceiveUsingDma(Instance);
1543 }
1544 #endif
1545
1546 /* Invoke the callback, if any */
1547 if (UartUserCfg->Callback != NULL_PTR)
1548 {
1549 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
1550 if (LINFLEXD_UART_IP_STATUS_RX_IDLE_STATE == UartState->ReceiveStatus)
1551 {
1552 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_IDLE_STATE, UartUserCfg->CallbackParam);
1553 }
1554 else
1555 #endif
1556 {
1557 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_ERROR, UartUserCfg->CallbackParam);
1558 }
1559 }
1560 }
1561 /* Case of spurious interrupt when driver had an error in initialization */
1562 else
1563 {
1564 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_BUFFER_OVERRUN_FLAG);
1565 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_FRAME_ERROR_FLAG);
1566 }
1567 }
1568 /* Case of spurious interrupt when driver is not at all initialized*/
1569 else
1570 {
1571 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_BUFFER_OVERRUN_FLAG);
1572 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_FRAME_ERROR_FLAG);
1573 }
1574 }
1575
1576 /*FUNCTION**********************************************************************
1577 *
1578 * Function Name : Linflexd_Uart_Ip_IRQHandler
1579 * Description : Interrupt handler for UART.
1580 * This handler uses the buffers stored in the state structure to transfer
1581 * data. This is not a public API as it is called by IRQ whenever an interrupt
1582 * occurs.
1583 *
1584 *END**************************************************************************/
1585 /* implements Linflexd_Uart_Ip_IRQHandler_Activity*/
Linflexd_Uart_Ip_IRQHandler(uint8 Instance)1586 void Linflexd_Uart_Ip_IRQHandler(uint8 Instance)
1587 {
1588 const LINFLEXD_Type * Base;
1589
1590 Base = Linflexd_Uart_Ip_apBases[Instance];
1591
1592 /* Handle receive data full interrupt */
1593 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG))
1594 {
1595 if (Linflexd_Uart_Ip_IsInterruptEnabled(Base, LINFLEXD_DATA_RECEPTION_COMPLETE_INT))
1596 {
1597 Linflexd_Uart_Ip_RxIRQHandler(Instance);
1598 }
1599 else
1600 {
1601 /* CPR_RTD_00664.uart Spurious interrupt*/
1602 /* Do nothing - Return immediately */
1603 }
1604 }
1605
1606 /* Handle transmitter data register empty interrupt */
1607 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_DATA_TRANSMITTED_FLAG))
1608 {
1609 if (Linflexd_Uart_Ip_IsInterruptEnabled(Base, LINFLEXD_DATA_TRANSMITTED_INT))
1610 {
1611 Linflexd_Uart_Ip_TxIRQHandler(Instance);
1612 }
1613 else
1614 {
1615 /* CPR_RTD_00664.uart Spurious interrupt*/
1616 /* Do nothing - Return immediately */
1617 }
1618 }
1619
1620 /* Handle the error interrupts if no rx/tx interrupt was triggered */
1621 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_FRAME_ERROR_FLAG))
1622 {
1623 if (Linflexd_Uart_Ip_IsInterruptEnabled(Base, LINFLEXD_FRAME_ERROR_INT))
1624 {
1625 Linflexd_Uart_Ip_ErrIRQHandler(Instance);
1626 }
1627 else
1628 {
1629 /* CPR_RTD_00664.uart Spurious interrupt*/
1630 /* Do nothing - Return immediately */
1631 }
1632 }
1633
1634 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_BUFFER_OVERRUN_FLAG))
1635 {
1636 if (Linflexd_Uart_Ip_IsInterruptEnabled(Base, LINFLEXD_BUFFER_OVERRUN_INT))
1637 {
1638 Linflexd_Uart_Ip_ErrIRQHandler(Instance);
1639 }
1640 else
1641 {
1642 /* CPR_RTD_00664.uart Spurious interrupt*/
1643 /* Do nothing - Return immediately */
1644 }
1645 }
1646 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
1647 /* Handle the error interrupts if timeout error */
1648 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_TIMEOUT_INTERRUPT_FLAG))
1649 {
1650 /* This checking also ensures that the feature is activated for the current instance
1651 * because the Interrupt can be enabled only in this case.
1652 */
1653 if (Linflexd_Uart_Ip_IsInterruptEnabled(Base, LINFLEXD_TIMEOUT_INT))
1654 {
1655 Linflexd_Uart_Ip_ErrIRQHandler(Instance);
1656 }
1657 else
1658 {
1659 /* CPR_RTD_00664.uart Spurious interrupt*/
1660 /* Do nothing - Return immediately */
1661 }
1662 }
1663 #endif
1664 }
1665
1666 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
1667 /*FUNCTION**********************************************************************
1668 *
1669 * Function Name : Linflexd_Uart_Ip_StartSendUsingDma
1670 * Description : Initiate (start) a transmit by beginning the process of
1671 * sending data using DMA transfers.
1672 * This is not a public API as it is called from other driver functions.
1673 *
1674 *END**************************************************************************/
Linflexd_Uart_Ip_StartSendUsingDma(const uint8 Instance,const uint8 * TxBuff,const uint32 TxSize)1675 static Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_StartSendUsingDma(const uint8 Instance,
1676 const uint8 * TxBuff,
1677 const uint32 TxSize)
1678 {
1679 LINFLEXD_Type * Base;
1680 Linflexd_Uart_Ip_StatusType RetVal;
1681 Linflexd_Uart_Ip_StateStructureType * UartState;
1682 const Linflexd_Uart_Ip_UserConfigType *UartUserCfg;
1683 Dma_Ip_LogicChannelTransferListType DmaTransferList[LINFLEXD_UART_IP_DMA_CONFIG_LIST_DIMENSION];
1684 Dma_Ip_ReturnType DmaReturnStatus;
1685
1686 Base = Linflexd_Uart_Ip_apBases[Instance];
1687 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1688 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1689
1690 SchM_Enter_Uart_UART_EXCLUSIVE_AREA_05();
1691 /* Check it's not busy transmitting data from a previous function call */
1692 if(!UartState->IsTxBusy)
1693 {
1694 /* Update state structure */
1695 UartState->IsTxBusy = TRUE;
1696 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_05();
1697 UartState->TxBuff = TxBuff;
1698
1699 /* Check the validity of the parameters */
1700 LINFLEXD_UART_IP_DEV_ASSERT(TxSize > 0U);
1701 if (!((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength)))
1702 {
1703 /* The size of the buffer should be an even number for DMA transfers with 15/16 bits word length */
1704 LINFLEXD_UART_IP_DEV_ASSERT(0U == (TxSize & 1U));
1705 }
1706 UartState->TxSize = 0U;
1707 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_BUSY;
1708
1709 /* Set up parameters for Dma_Ip_LogicChannelTransferListType */
1710 DmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
1711 DmaTransferList[0].Value = (uint32)TxBuff;
1712 DmaTransferList[1].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
1713 DmaTransferList[1].Value = LINFLEXD_UART_IP_LSBW_ADDR(Base->BDRL);
1714 DmaTransferList[2].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
1715 DmaTransferList[3].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
1716 DmaTransferList[3].Value = 0;
1717 DmaTransferList[4].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
1718 DmaTransferList[5].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
1719 DmaTransferList[6].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
1720 DmaTransferList[7].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
1721 if ((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength))
1722 {
1723 DmaTransferList[2].Value = 1;
1724 DmaTransferList[4].Value = TxSize;
1725 DmaTransferList[5].Value = 1;
1726 DmaTransferList[6].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
1727 DmaTransferList[7].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
1728 }
1729 else
1730 {
1731 DmaTransferList[2].Value = 2;
1732 DmaTransferList[4].Value = TxSize/(uint32)2;
1733 DmaTransferList[5].Value = 2;
1734 DmaTransferList[6].Value = DMA_IP_TRANSFER_SIZE_2_BYTE;
1735 DmaTransferList[7].Value = DMA_IP_TRANSFER_SIZE_2_BYTE;
1736 }
1737
1738 DmaTransferList[8].Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT;
1739 DmaTransferList[8].Value = 1;
1740 DmaTransferList[9].Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST;
1741 DmaTransferList[9].Value = 1;
1742
1743 /* Configure the transfer control descriptor for the DMA channel */
1744 DmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(UartUserCfg->TxDMAChannel, DmaTransferList, LINFLEXD_UART_IP_DMA_CONFIG_LIST_DIMENSION);
1745 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
1746
1747 /* Start the DMA channel */
1748 DmaReturnStatus = Dma_Ip_SetLogicChannelCommand(UartUserCfg->TxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
1749 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
1750 /* Enable the transmitter */
1751 Linflexd_Uart_Ip_SetTransmitterState(Base, TRUE);
1752
1753 /* Enable tx DMA requests for the current instance */
1754 Linflexd_Uart_Ip_SetDmaTxEnable(Base, TRUE);
1755
1756 RetVal = LINFLEXD_UART_IP_STATUS_SUCCESS;
1757 }
1758 else
1759 {
1760 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_05();
1761 RetVal = LINFLEXD_UART_IP_STATUS_BUSY;
1762 }
1763
1764 return RetVal;
1765 }
1766
1767 /*FUNCTION**********************************************************************
1768 *
1769 * Function Name : Linflexd_Uart_Ip_StartReceiveUsingDma
1770 * Description : Initiate (start) a receive by beginning the process of
1771 * receiving data using DMA transfers.
1772 * This is not a public API as it is called from other driver functions.
1773 *
1774 *END**************************************************************************/
Linflexd_Uart_Ip_StartReceiveUsingDma(const uint8 Instance,uint8 * RxBuff,const uint32 RxSize)1775 static Linflexd_Uart_Ip_StatusType Linflexd_Uart_Ip_StartReceiveUsingDma(const uint8 Instance,
1776 uint8 * RxBuff,
1777 const uint32 RxSize)
1778 {
1779 LINFLEXD_Type * Base;
1780 Linflexd_Uart_Ip_StatusType RetVal;
1781 Linflexd_Uart_Ip_StateStructureType * UartState;
1782 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
1783 Dma_Ip_LogicChannelTransferListType DmaTransferList[LINFLEXD_UART_IP_DMA_CONFIG_LIST_DIMENSION];
1784 Dma_Ip_ReturnType DmaReturnStatus;
1785
1786 Base = Linflexd_Uart_Ip_apBases[Instance];
1787 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1788 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1789
1790
1791 SchM_Enter_Uart_UART_EXCLUSIVE_AREA_08();
1792 /* Check it's not busy transmitting data from a previous function call */
1793 if (!UartState->IsRxBusy)
1794 {
1795 /* Update the state structure */
1796 UartState->IsRxBusy = TRUE;
1797 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_08();
1798
1799 LINFLEXD_UART_IP_DEV_ASSERT(RxSize > 0U);
1800 if (!((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength)))
1801 {
1802 /* The size of the buffer should be an even number for DMA transfers with 15/16 bits word length */
1803 LINFLEXD_UART_IP_DEV_ASSERT(0U == (RxSize & 1U));
1804 }
1805 UartState->RxBuff = RxBuff;
1806 UartState->RxSize = 0U;
1807 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_BUSY;
1808
1809 /* Set up parameters for Dma_Ip_LogicChannelTransferListType */
1810 DmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
1811 DmaTransferList[0].Value = LINFLEXD_UART_IP_LSBW_ADDR(Base->BDRM);
1812 DmaTransferList[1].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
1813 DmaTransferList[1].Value = (uint32)RxBuff;
1814 DmaTransferList[2].Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET;
1815 DmaTransferList[2].Value = 0;
1816 DmaTransferList[3].Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET;
1817 DmaTransferList[4].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
1818 DmaTransferList[5].Param = DMA_IP_CH_SET_MINORLOOP_SIZE;
1819 DmaTransferList[6].Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE;
1820 DmaTransferList[7].Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE;
1821 if ((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength))
1822 {
1823 DmaTransferList[3].Value = 1;
1824 DmaTransferList[4].Value = RxSize;
1825 DmaTransferList[5].Value = 1;
1826 DmaTransferList[6].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
1827 DmaTransferList[7].Value = DMA_IP_TRANSFER_SIZE_1_BYTE;
1828 }
1829 else
1830 {
1831 DmaTransferList[3].Value = 2;
1832 DmaTransferList[4].Value = RxSize/(uint32)2;
1833 DmaTransferList[5].Value = 2;
1834 DmaTransferList[6].Value = DMA_IP_TRANSFER_SIZE_2_BYTE;
1835 DmaTransferList[7].Value = DMA_IP_TRANSFER_SIZE_2_BYTE;
1836 }
1837 DmaTransferList[8].Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT;
1838 DmaTransferList[8].Value = 1;
1839 DmaTransferList[9].Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST;
1840 DmaTransferList[9].Value = 1;
1841
1842 /* Configure the transfer control descriptor for the DMA channel */
1843 DmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(UartUserCfg->RxDMAChannel, DmaTransferList, LINFLEXD_UART_IP_DMA_CONFIG_LIST_DIMENSION);
1844 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
1845
1846 /* Start the DMA channel */
1847 DmaReturnStatus = Dma_Ip_SetLogicChannelCommand(UartUserCfg->RxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
1848
1849 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
1850 /* Flush the rx FIFO to discard any junk data received while the driver was idle */
1851 Linflexd_Uart_Ip_FlushRxFifo(Base, UartUserCfg->WordLength);
1852
1853 /* Enable the receiver */
1854 Linflexd_Uart_Ip_SetReceiverState(Base, TRUE);
1855
1856 /* Enable rx DMA requests for the current instance */
1857 Linflexd_Uart_Ip_SetDmaRxEnable(Base, TRUE);
1858
1859 RetVal = LINFLEXD_UART_IP_STATUS_SUCCESS;
1860 }
1861 else
1862 {
1863 SchM_Exit_Uart_UART_EXCLUSIVE_AREA_08();
1864 RetVal = LINFLEXD_UART_IP_STATUS_BUSY;
1865 }
1866
1867 return RetVal;
1868 }
1869
1870 /*FUNCTION**********************************************************************
1871 *
1872 * Function Name : Linflexd_Uart_Ip_CompleteSendUsingDma
1873 * Description : Finish up a transmit by completing the process of sending
1874 * data and disabling the DMA requests. This is a callback for DMA major loop
1875 * completion, so it must match the DMA callback signature.
1876 *
1877 *END**************************************************************************/
Linflexd_Uart_Ip_CompleteSendUsingDma(uint8 Instance)1878 void Linflexd_Uart_Ip_CompleteSendUsingDma(uint8 Instance)
1879 {
1880 LINFLEXD_Type * Base;
1881 Linflexd_Uart_Ip_StateStructureType * UartState;
1882 const Linflexd_Uart_Ip_UserConfigType *UartUserCfg;
1883 Dma_Ip_LogicChannelTransferListType DmaTransferList[LINFLEXD_UART_DMA_LEAST_CONFIG_LIST_DIMENSION];
1884 Dma_Ip_ReturnType DmaReturnStatus;
1885 Dma_Ip_LogicChannelStatusType DmaStatus;
1886
1887 Base = Linflexd_Uart_Ip_apBases[Instance];
1888 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
1889 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
1890
1891 /* Get Dma Ip Logic Channel Status */
1892 (void)Dma_Ip_GetLogicChannelStatus(UartUserCfg->TxDMAChannel, &DmaStatus);
1893 if (DMA_IP_CH_ERROR_STATE == DmaStatus.ChStateValue)
1894 {
1895 /* Reset the Dma Channel Error status. */
1896 DmaReturnStatus = Dma_Ip_SetLogicChannelCommand(UartUserCfg->TxDMAChannel, DMA_IP_CH_CLEAR_ERROR);
1897
1898 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
1899 /* Update transmit status */
1900 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_DMA_ERROR;
1901 /* Invoke callback if there is one */
1902 if (UartUserCfg->Callback != NULL_PTR)
1903 {
1904 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_ERROR, UartUserCfg->CallbackParam);
1905 }
1906 }
1907
1908 /* Invoke the callback when the buffer is finished;
1909 * Application can provide another buffer inside the callback by calling Linflexd_Uart_Ip_SetTxBuffer */
1910 if (LINFLEXD_UART_IP_STATUS_BUSY == UartState->TransmitStatus)
1911 {
1912 if (UartUserCfg->Callback != NULL_PTR)
1913 {
1914 /* Pass the state structure as parameter for internal information retrieval */
1915 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_TX_EMPTY, UartUserCfg->CallbackParam);
1916 }
1917 }
1918
1919 /* If the callback has updated the tx buffer, update the DMA descriptor to continue the transfer;
1920 * otherwise, stop the current transfer.
1921 */
1922 if (UartState->TxSize > 0U)
1923 {
1924 /* Set up parameters for Dma_Ip_LogicChannelTransferListType */
1925 DmaTransferList[0].Param = DMA_IP_CH_SET_SOURCE_ADDRESS;
1926 DmaTransferList[1].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
1927 /* Update tx size and major loop count parameters for Dma_Ip_LogicChannelTransferListType */
1928 DmaTransferList[0].Value = (uint32)(UartState->TxBuff);
1929 if (!((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength)))
1930 {
1931 /* The size of the buffer should be an even number for DMA transfers with 15/16 bits word length */
1932 LINFLEXD_UART_IP_DEV_ASSERT(0U == (UartState->TxSize & 1U));
1933 }
1934 if ((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength))
1935 {
1936 DmaTransferList[1].Value = UartState->TxSize;
1937 }
1938 else
1939 {
1940 DmaTransferList[1].Value = (UartState->TxSize)/(uint32)2;
1941 }
1942
1943 /* Re-configure the transfer control descriptor for the DMA channel */
1944 DmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(UartUserCfg->TxDMAChannel, DmaTransferList, LINFLEXD_UART_DMA_LEAST_CONFIG_LIST_DIMENSION);
1945 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
1946
1947 /* Now that this tx is set up, clear remaining bytes count */
1948 UartState->TxSize = 0U;
1949
1950 /* Re-start the channel */
1951 DmaReturnStatus = Dma_Ip_SetLogicChannelCommand(UartUserCfg->TxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
1952 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
1953 }
1954 else
1955 {
1956 /* Disable the transmitter */
1957 Linflexd_Uart_Ip_SetTransmitterState(Base, FALSE);
1958
1959 /* Disable tx DMA requests for the current instance */
1960 Linflexd_Uart_Ip_SetDmaTxEnable(Base, FALSE);
1961
1962 /* Update the busy flag */
1963 UartState->IsTxBusy = FALSE;
1964
1965 /* If the current reception hasn't been aborted, update the status */
1966 if (LINFLEXD_UART_IP_STATUS_BUSY == UartState->TransmitStatus)
1967 {
1968 UartState->TransmitStatus = LINFLEXD_UART_IP_STATUS_SUCCESS;
1969 /* Call the callback to notify application that the transfer is complete */
1970 if (UartUserCfg->Callback != NULL_PTR)
1971 {
1972 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_END_TRANSFER, UartUserCfg->CallbackParam);
1973 }
1974 }
1975 }
1976 }
1977
1978
1979 /*FUNCTION**********************************************************************
1980 *
1981 * Function Name : Linflexd_Uart_Ip_CompleteReceiveUsingDma
1982 * Description : Finish up a receive by completing the process of receiving data
1983 * and disabling the DMA requests. This is a callback for DMA major loop
1984 * completion, so it must match the DMA callback signature.
1985 *
1986 *END**************************************************************************/
Linflexd_Uart_Ip_CompleteReceiveUsingDma(uint8 Instance)1987 void Linflexd_Uart_Ip_CompleteReceiveUsingDma(uint8 Instance)
1988 {
1989 LINFLEXD_Type * Base;
1990 Linflexd_Uart_Ip_StateStructureType * UartState;
1991 const Linflexd_Uart_Ip_UserConfigType *UartUserCfg;
1992 Dma_Ip_LogicChannelTransferListType DmaTransferList[LINFLEXD_UART_DMA_LEAST_CONFIG_LIST_DIMENSION];
1993 Dma_Ip_ReturnType DmaReturnStatus;
1994 Dma_Ip_LogicChannelStatusType DmaStatus;
1995 uint32 StartTime;
1996 uint32 TimeoutTicks;
1997 uint32 ElapsedTicks = 0;
1998
1999 Base = Linflexd_Uart_Ip_apBases[Instance];
2000 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
2001 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
2002
2003 /* Get Dma Ip Logic Channel Status */
2004 (void)Dma_Ip_GetLogicChannelStatus(UartUserCfg->RxDMAChannel, &DmaStatus);
2005
2006 if (DMA_IP_CH_ERROR_STATE == DmaStatus.ChStateValue)
2007 {
2008 /* Reset the Dma Channel Error status. */
2009 DmaReturnStatus = Dma_Ip_SetLogicChannelCommand(UartUserCfg->RxDMAChannel, DMA_IP_CH_CLEAR_ERROR);
2010
2011 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
2012 /* Update transmit status */
2013 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_DMA_ERROR;
2014 /* Invoke callback if there is one */
2015 if (UartUserCfg->Callback != NULL_PTR)
2016 {
2017 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_ERROR, UartUserCfg->CallbackParam);
2018 }
2019 }
2020
2021 /* Invoke the callback when the buffer is finished */
2022 if (LINFLEXD_UART_IP_STATUS_BUSY == UartState->ReceiveStatus)
2023 {
2024 /* Application can provide another buffer inside the callback by calling Linflexd_Uart_Ip_SetRxBuffer */
2025 if (UartUserCfg->Callback != NULL_PTR)
2026 {
2027 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_RX_FULL, UartUserCfg->CallbackParam);
2028 }
2029 }
2030
2031 /* If the callback has updated the rx buffer, update the DMA descriptor to continue the transfer;
2032 * otherwise, stop the current transfer.
2033 */
2034 if (UartState->RxSize > 0U)
2035 {
2036 /* Set up parameters for Dma_Ip_LogicChannelTransferListType */
2037 DmaTransferList[0].Param = DMA_IP_CH_SET_DESTINATION_ADDRESS;
2038 DmaTransferList[1].Param = DMA_IP_CH_SET_MAJORLOOP_COUNT;
2039 DmaTransferList[0].Value = (uint32)(UartState->RxBuff);
2040 if ((LINFLEXD_UART_IP_7_BITS == UartUserCfg->WordLength) || (LINFLEXD_UART_IP_8_BITS == UartUserCfg->WordLength))
2041 {
2042 DmaTransferList[1].Value = UartState->RxSize;
2043 }
2044 else
2045 {
2046 DmaTransferList[1].Value = (UartState->RxSize)/(uint32)2;
2047 }
2048 /* Re-configure the transfer control descriptor for the DMA channel */
2049 DmaReturnStatus = Dma_Ip_SetLogicChannelTransferList(UartUserCfg->RxDMAChannel, DmaTransferList, LINFLEXD_UART_DMA_LEAST_CONFIG_LIST_DIMENSION);
2050 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
2051 /* Now that this rx is set up, clear remaining bytes count */
2052 UartState->RxSize = 0U;
2053 /* Re-start the channel */
2054 DmaReturnStatus = Dma_Ip_SetLogicChannelCommand(UartUserCfg->RxDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
2055 LINFLEXD_UART_IP_DEV_ASSERT(DMA_IP_STATUS_SUCCESS == DmaReturnStatus);
2056 }
2057 else
2058 {
2059 /* Disable rx DMA requests for the current instance */
2060 Linflexd_Uart_Ip_SetDmaRxEnable(Base, FALSE);
2061
2062 /* In Abort case, the transmission need to stop instantly */
2063 if (LINFLEXD_UART_IP_STATUS_ABORTED == UartState->ReceiveStatus)
2064 {
2065 /* Wait until the last transmission complete */
2066 Linflexd_Uart_Ip_StartTimeout(&StartTime, &TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_VALUE_US, LINFLEXD_UART_IP_TIMEOUT_TYPE);
2067 while (!Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG) && \
2068 !Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
2069 {}
2070 if (Linflexd_Uart_Ip_CheckTimeout(&StartTime, &ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
2071 {
2072 /* In case timeout occur */
2073 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_TIMEOUT;
2074 }
2075 }
2076 /* Disable the receiver */
2077 Linflexd_Uart_Ip_SetReceiverState(Base, FALSE);
2078
2079 /* Update the information of the module driver state */
2080 UartState->IsRxBusy = FALSE;
2081
2082 /* If the current reception hasn't been aborted, update the status and call the callback */
2083 if (LINFLEXD_UART_IP_STATUS_BUSY == UartState->ReceiveStatus)
2084 {
2085 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_SUCCESS;
2086
2087 /* Call the callback to notify application that the transfer is complete */
2088 if (UartUserCfg->Callback != NULL_PTR)
2089 {
2090 UartUserCfg->Callback(Instance, LINFLEXD_UART_IP_EVENT_END_TRANSFER, UartUserCfg->CallbackParam);
2091 }
2092 }
2093 /* Disable error interrupts */
2094 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_FRAME_ERROR_INT, FALSE);
2095 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_BUFFER_OVERRUN_INT, FALSE);
2096 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
2097 if (Linflexd_Uart_Ip_InstHasTimeoutInterruptEnabled[Instance])
2098 {
2099 /* Disable timeout interrupt */
2100 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_TIMEOUT_INT, FALSE);
2101 }
2102 #endif
2103 }
2104 }
2105
2106 /*FUNCTION**********************************************************************
2107 *
2108 * Function Name : Linflexd_Uart_Ip_FlushRxFifo
2109 * Description : Flushes the rx FIFO.
2110 * This is not a public API as it is called from other driver functions.
2111 *
2112 *END**************************************************************************/
Linflexd_Uart_Ip_FlushRxFifo(const LINFLEXD_Type * Base,const Linflexd_Uart_Ip_WordLengthType WordLength)2113 static void Linflexd_Uart_Ip_FlushRxFifo(const LINFLEXD_Type *Base,const Linflexd_Uart_Ip_WordLengthType WordLength)
2114 {
2115 uint16 DummyData;
2116
2117 if ((LINFLEXD_UART_IP_7_BITS == WordLength) || (LINFLEXD_UART_IP_8_BITS == WordLength))
2118 {
2119 volatile const uint8 *FifoBase;
2120
2121 /* Get the address of the FIFO */
2122 FifoBase = (volatile const uint8 *)(&(Base->BDRM));
2123 #ifdef CORE_BIG_ENDIAN
2124 FifoBase = &FifoBase[3];
2125 #endif
2126
2127 /* Four dummy reads, to flush the FIFO contents */
2128 DummyData = (uint16)(*FifoBase);
2129 DummyData = (uint16)(*FifoBase);
2130 DummyData = (uint16)(*FifoBase);
2131 DummyData = (uint16)(*FifoBase);
2132 (void)DummyData;
2133 }
2134 else
2135 {
2136 volatile const uint16 *u16FifoBase;
2137
2138 /* Get the address of the FIFO */
2139 u16FifoBase = (volatile const uint16 *)(&(Base->BDRM));
2140 #ifdef CORE_BIG_ENDIAN
2141 u16FifoBase = &u16FifoBase[1];
2142 #endif
2143
2144 /* Four dummy reads, to flush the FIFO contents */
2145 DummyData = *u16FifoBase;
2146 DummyData = *u16FifoBase;
2147 DummyData = *u16FifoBase;
2148 DummyData = *u16FifoBase;
2149 (void)DummyData;
2150 }
2151 }
2152 #endif
2153
2154 /*FUNCTION**********************************************************************
2155 *
2156 * Function Name : Linflexd_Uart_Ip_SetUp_Init
2157 * Description : Set up Linflexd Uart to Init Privileged.
2158 * This is not a public API as it is called from other driver functions.
2159 *
2160 *END**************************************************************************/
Linflexd_Uart_Ip_SetUp_Init(const uint8 Instance)2161 static void Linflexd_Uart_Ip_SetUp_Init(const uint8 Instance)
2162 {
2163 const Linflexd_Uart_Ip_UserConfigType * UartUserCfg;
2164 LINFLEXD_Type * Base = Linflexd_Uart_Ip_apBases[Instance];
2165 Linflexd_Uart_Ip_StateStructureType * UartStatePtr;
2166 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
2167 UartStatePtr = Linflexd_Uart_Ip_apStateStructuresArray[Instance];
2168
2169 /* Set UART mode */
2170 Linflexd_Uart_Ip_SetMode(Base, LINFLEXD_UART_MODE);
2171
2172 /* Set the baud rate */
2173 Linflexd_Uart_Ip_SetIntegerBaudRate(Base, UartUserCfg->BaudRateMantissa);
2174 Linflexd_Uart_Ip_SetFractionalBaudRate(Base, UartUserCfg->BaudRateFractionalDivisor);
2175
2176 UartStatePtr->Baudrate = UartUserCfg->BaudRate;
2177
2178 #if (LINFLEXD_UART_IP_ENABLE_INTERNAL_LOOPBACK == STD_ON)
2179 if (Linflexd_Uart_Ip_InstHasLoopbackEnabled[Instance])
2180 {
2181 Base->LINCR1 |= LINFLEXD_LINCR1_LBKM(1);
2182 }
2183 #endif
2184
2185 #if (LINFLEXD_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
2186 if (Linflexd_Uart_Ip_InstHasTimeoutInterruptEnabled[Instance])
2187 {
2188 Linflexd_Uart_Ip_EnableTimerReset(Base, TRUE);
2189 Linflexd_Uart_Ip_EnableMonitorIdleState(Base, TRUE);
2190 Linflexd_Uart_Ip_SetPresetValue(Base, (uint16)UartUserCfg->WordLength + 2U);
2191 }
2192 #endif
2193
2194 /* Set word length */
2195 Linflexd_Uart_Ip_SetWordLength(Instance);
2196
2197 /* Set parity */
2198 if (UartUserCfg->ParityCheck)
2199 {
2200 Linflexd_Uart_Ip_SetParityControl(Base, TRUE);
2201 Linflexd_Uart_Ip_SetParityType(Base, UartUserCfg->ParityType);
2202 }
2203 else
2204 {
2205 Linflexd_Uart_Ip_SetParityControl(Base, FALSE);
2206 }
2207
2208 /* Set stop bits count */
2209 Linflexd_Uart_Ip_SetRxStopBitsCount(Base, UartUserCfg->StopBitsCount);
2210 Linflexd_Uart_Ip_SetTxStopBitsCount(Base, UartUserCfg->StopBitsCount, TRUE);
2211
2212 /* Enable FIFO for DMA based communication, or buffer mode for interrupt based communication */
2213 if (LINFLEXD_UART_IP_USING_DMA == UartUserCfg->TransferType)
2214 {
2215 Linflexd_Uart_Ip_SetTxMode(Base, LINFLEXD_UART_RXTX_FIFO_MODE);
2216 Linflexd_Uart_Ip_SetRxMode(Base, LINFLEXD_UART_RXTX_FIFO_MODE);
2217 }
2218 else
2219 {
2220 Linflexd_Uart_Ip_SetTxMode(Base, LINFLEXD_UART_RXTX_BUFFER_MODE);
2221 Linflexd_Uart_Ip_SetRxMode(Base, LINFLEXD_UART_RXTX_BUFFER_MODE);
2222 }
2223 }
2224
2225 /*FUNCTION**********************************************************************
2226 *
2227 * Function Name : Linflexd_Uart_Ip_SetWordLength
2228 * Description : Set up word length for Linflexd Uart.
2229 * This is not a public API as it is called from other driver functions.
2230 *
2231 *END**************************************************************************/
Linflexd_Uart_Ip_SetWordLength(const uint8 Instance)2232 static void Linflexd_Uart_Ip_SetWordLength(const uint8 Instance)
2233 {
2234 const Linflexd_Uart_Ip_UserConfigType *UartUserCfg;
2235 LINFLEXD_Type * Base = Linflexd_Uart_Ip_apBases[Instance];
2236
2237 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
2238 Linflexd_Uart_Ip_SetUartWordLength(Base, UartUserCfg->WordLength);
2239 Linflexd_Uart_Ip_SetTxDataFieldLength(Base, (uint8)((uint8)UartUserCfg->WordLength >> 1U));
2240 Linflexd_Uart_Ip_SetRxDataFieldLength(Base, (uint8)((uint8)UartUserCfg->WordLength >> 1U));
2241 }
2242 /*FUNCTION**********************************************************************
2243 *
2244 * Function Name : Linflexd_Uart_Ip_UpdateReceiver
2245 * Description : Update status and clear the flag according to the error occurred.
2246 * This is not a public API as it is called from other driver functions.
2247 *
2248 *END**************************************************************************/
Linflexd_Uart_Ip_UpdateReceiver(const uint8 Instance,uint32 * StartTime,uint32 * ElapsedTicks,uint32 TimeoutTicks)2249 static void Linflexd_Uart_Ip_UpdateReceiver(const uint8 Instance, uint32 * StartTime, uint32 * ElapsedTicks, uint32 TimeoutTicks)
2250 {
2251 LINFLEXD_Type * Base;
2252 Linflexd_Uart_Ip_StateStructureType * UartState;
2253 Base = Linflexd_Uart_Ip_apBases[Instance];
2254 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
2255 boolean IsError = FALSE;
2256
2257 /* To be updated with timeout when aProach is defined*/
2258 while ((UartState->RxSize > 0U) && !Linflexd_Uart_Ip_CheckTimeout(StartTime, ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
2259 {
2260 /* Wait until data reception flag is set or timeout occurs if there is an error during reception */
2261 while (!Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG) && \
2262 !Linflexd_Uart_Ip_CheckTimeout(StartTime, ElapsedTicks, TimeoutTicks, LINFLEXD_UART_IP_TIMEOUT_TYPE))
2263 {}
2264 /* Update the receive status according to the error occurred */
2265 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_BUFFER_OVERRUN_FLAG))
2266 {
2267 /* Update the status */
2268 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_RX_OVERRUN;
2269 /* Clear the flag */
2270 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_BUFFER_OVERRUN_FLAG);
2271 IsError = TRUE;
2272 }
2273 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_FRAME_ERROR_FLAG))
2274 {
2275 /* Update the status */
2276 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_FRAMING_ERROR;
2277 /* Clear the flag */
2278 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_FRAME_ERROR_FLAG);
2279 IsError = TRUE;
2280 }
2281 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_PARITY_ERROR_FLAG))
2282 {
2283 /* Update the status */
2284 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_PARITY_ERROR;
2285 /* Clear the flag */
2286 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_PARITY_ERROR_FLAG);
2287 IsError = TRUE;
2288 }
2289 if (Linflexd_Uart_Ip_GetStatusFlag(Base, LINFLEXD_UART_NOISE_FLAG))
2290 {
2291 /* Update the status */
2292 UartState->ReceiveStatus = LINFLEXD_UART_IP_STATUS_NOISE_ERROR;
2293 /* Clear the flag */
2294 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_NOISE_FLAG);
2295 IsError = TRUE;
2296 }
2297
2298 if (!IsError)
2299 {
2300 /* Retrieve the data */
2301 Linflexd_Uart_Ip_GetData(Instance);
2302 /* Clear the flags */
2303 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_DATA_RECEPTION_COMPLETE_FLAG);
2304 Linflexd_Uart_Ip_ClearStatusFlag(Base, LINFLEXD_UART_MESSAGE_BUFFER_FULL_FLAG);
2305 }
2306 else
2307 {
2308 break;
2309 }
2310 }
2311 }
2312
2313 /*FUNCTION**********************************************************************
2314 *
2315 * Function Name : Linflexd_Uart_Ip_SetUp_Receiver
2316 * Description : Disble transmission complete interrupt, Disable receive data full interrupt.
2317 and Disable error interrupts to Enable the receiver.
2318 * This is not a public API as it is called from other driver functions.
2319 *
2320 *END**************************************************************************/
Linflexd_Uart_Ip_SetUp_Receiver(const uint8 Instance)2321 static void Linflexd_Uart_Ip_SetUp_Receiver(const uint8 Instance)
2322 {
2323 LINFLEXD_Type * Base;
2324 Base = Linflexd_Uart_Ip_apBases[Instance];
2325
2326 /* Disble transmission complete interrupt */
2327 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_TRANSMITTED_INT, FALSE);
2328 /* Disable receive data full interrupt. */
2329 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_DATA_RECEPTION_COMPLETE_INT, FALSE);
2330 /* Disable error interrupts */
2331 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_FRAME_ERROR_INT, FALSE);
2332 Linflexd_Uart_Ip_SetInterruptMode(Base, LINFLEXD_BUFFER_OVERRUN_INT, FALSE);
2333
2334 /* Enable the receiver */
2335 Linflexd_Uart_Ip_SetReceiverState(Base, TRUE);
2336 }
2337
2338 /*FUNCTION**********************************************************************
2339 *
2340 * Function Name : Linflexd_Uart_Ip_GetRemainingBytes
2341 * Description : Get the Remaining Bytes
2342 * This is not a public API as it is called from other driver functions.
2343 *
2344 *END**************************************************************************/
Linflexd_Uart_Ip_GetRemainingBytes(const uint8 Instance,uint32 * BytesRemaining,Linflexd_Uart_Ip_DataDirectionType Direction)2345 static void Linflexd_Uart_Ip_GetRemainingBytes(const uint8 Instance, uint32 * BytesRemaining, Linflexd_Uart_Ip_DataDirectionType Direction)
2346 {
2347 const Linflexd_Uart_Ip_UserConfigType *UartUserCfg;
2348 const Linflexd_Uart_Ip_StateStructureType * UartState;
2349 UartUserCfg = Linflexd_Uart_Ip_apUserConfig[Instance];
2350 UartState = (Linflexd_Uart_Ip_StateStructureType *)Linflexd_Uart_Ip_apStateStructuresArray[Instance];
2351 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
2352 const Dma_Ip_LogicChannelInfoParamType DmaLogicChnParam = DMA_IP_CH_GET_CURRENT_ITER_COUNT;
2353 #endif
2354
2355 /* Fill in the number of bytes yet to be received or transferred and update the return value if needed */
2356 if (LINFLEXD_UART_IP_USING_INTERRUPTS == UartUserCfg->TransferType)
2357 {
2358 /* In interrupt-based communication, the remaining bytes are retrieved
2359 * from the state structure
2360 */
2361 if (LINFLEXD_UART_IP_RECEIVE == Direction)
2362 {
2363 *BytesRemaining = UartState->RxSize;
2364 }
2365 else
2366 {
2367 *BytesRemaining = UartState->TxSize;
2368 }
2369 }
2370 #if (LINFLEXD_UART_IP_HAS_DMA_ENABLED == STD_ON)
2371 else
2372 {
2373 /* In DMA-based communication, the remaining bytes are retrieved
2374 * from the current DMA major loop count
2375 */
2376 if (LINFLEXD_UART_IP_RECEIVE == Direction)
2377 {
2378 (void)Dma_Ip_GetLogicChannelParam(UartUserCfg->RxDMAChannel, DmaLogicChnParam, BytesRemaining);
2379 }
2380 else
2381 {
2382 (void)Dma_Ip_GetLogicChannelParam(UartUserCfg->TxDMAChannel, DmaLogicChnParam, BytesRemaining);
2383 }
2384 }
2385 #endif
2386 }
2387
2388 #if (STD_ON == LINFLEXD_UART_IP_SET_USER_ACCESS_ALLOWED_AVAILABLE)
2389 /**
2390 * @brief This function will set UAA bit in REG_PROT for UART unit
2391 */
Linflexd_Uart_Ip_SetUserAccess(const uint8 Instance)2392 void Linflexd_Uart_Ip_SetUserAccess(const uint8 Instance)
2393 {
2394 LINFLEXD_Type * Base;
2395 Base = Linflexd_Uart_Ip_apBases[Instance];
2396
2397 SET_USER_ACCESS_ALLOWED((uint32)Base, LINFLEX_PROT_MEM_U32);
2398 }
2399
2400 /**
2401 * @brief This function will enable writing all UART registers under protection in User mode by configuring REG_PROT
2402 */
Linflexd_Uart_Ip_SetUserAccessAllowed(const uint8 Instance)2403 static void Linflexd_Uart_Ip_SetUserAccessAllowed(const uint8 Instance)
2404 {
2405 OsIf_Trusted_Call1param(Linflexd_Uart_Ip_SetUserAccess, Instance);
2406 }
2407 #endif /* LINFLEXD_UART_IP_SET_USER_ACCESS_ALLOWED_AVAILABLE */
2408
2409 #define UART_STOP_SEC_CODE
2410 #include "Uart_MemMap.h"
2411
2412 #ifdef __cplusplus
2413 }
2414 #endif
2415
2416 /** @} */
2417