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