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