ti/drv/uart: SCI bug fixes and UART test enhancements
[processor-sdk/pdk.git] / packages / ti / drv / uart / src / v3 / uartsci.c
1 /**
2  *   @file  uartsci.c
3  *
4  *   @brief
5  *      The file implements the UART Serial Communication Interface Driver
6  *      for the XWR14xx and XWR16xx. The file implements the driver to conform
7  *      to the MCPI standards.
8  *
9  *  \par
10  *  NOTE:
11  *      (C) Copyright 2016-2020 Texas Instruments, Inc.
12  *
13  *  Redistribution and use in source and binary forms, with or without
14  *  modification, are permitted provided that the following conditions
15  *  are met:
16  *
17  *    Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  *
20  *    Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the
23  *    distribution.
24  *
25  *    Neither the name of Texas Instruments Incorporated nor the names of
26  *    its contributors may be used to endorse or promote products derived
27  *    from this software without specific prior written permission.
28  *
29  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  */
42 /**************************************************************************
43  *************************** Include Files ********************************
44  **************************************************************************/
45 #include <stdint.h>
46 #include <string.h>
47 #include <ti/drv/uart/UART.h>
48 #include <ti/drv/uart/src/UART_osal.h>
49 #include <ti/drv/uart/src/UART_drv_log.h>
50 #include <ti/drv/uart/src/v3/uartsci.h>
51 #include <ti/csl/cslr_sci.h>
53 /**************************************************************************
54  ************************** Local Definitions *****************************
55  **************************************************************************/
57 /* Registered callback functions: */
58 static void         UartSci_close(UART_Handle handle);
59 static void         UartSci_init(UART_Handle handle);
60 static UART_Handle  UartSci_open(UART_Handle handle, const UART_Params *params);
61 static int32_t      UartSci_read(UART_Handle handle, void *buffer, size_t size);
62 static int32_t      UartSci_readPolling(UART_Handle handle, void *buffer, size_t size);
63 static void         UartSci_readCancel(UART_Handle handle);
64 static int32_t      UartSci_write(UART_Handle handle, const void *buffer, size_t size);
65 static int32_t      UartSci_writePolling(UART_Handle handle, const void* buffer, size_t size);
66 static void         UartSci_writeCancel(UART_Handle handle);
67 static int32_t      UartSci_control(UART_Handle handle, uint32_t cmd, void *arg);
68 static int32_t      UartSci_read2(UART_Handle handle, UART_Transaction *transaction);
69 static int32_t      UartSci_write2(UART_Handle handle, UART_Transaction *transaction);
71 /* Read/Write SCI Registers API: */
72 static void     UartSci_enableTxInterrupt (CSL_sciRegs* ptrSCIRegs);
73 static void     UartSci_disableTxInterrupt (CSL_sciRegs* ptrSCIRegs);
74 static uint32_t UartSci_isTxInterruptEnabled (const CSL_sciRegs* ptrSCIRegs);
75 static void     UartSci_enableRxInterrupt (CSL_sciRegs* ptrSCIRegs);
76 static void     UartSci_disableRxInterrupt (CSL_sciRegs* ptrSCIRegs);
77 static uint32_t UartSci_isRxInterruptEnabled (const CSL_sciRegs* ptrSCIRegs);
78 static uint32_t UartSci_isRxFree (const CSL_sciRegs* ptrSCIRegs);
79 static uint32_t UartSci_isTxFree (const CSL_sciRegs* ptrSCIRegs);
80 static uint32_t UartSci_isRxOverrun (const CSL_sciRegs* ptrSCIRegs);
81 static void     UartSci_clearRxOverrun (CSL_sciRegs* ptrSCIRegs);
82 static uint32_t UartSci_isParityError (const CSL_sciRegs* ptrSCIRegs);
83 static void     UartSci_clearParityError (CSL_sciRegs* ptrSCIRegs);
84 static uint32_t UartSci_isFramingError (const CSL_sciRegs* ptrSCIRegs);
85 static void     UartSci_clearFramingError (CSL_sciRegs* ptrSCIRegs);
86 static uint8_t  UartSci_getCh (const CSL_sciRegs* ptrSCIRegs);
87 static void     UartSci_putCh (CSL_sciRegs* ptrSCIRegs, uint8_t ch);
89 /* SCI Driver API: */
90 static void    UartSci_ISR (uintptr_t arg);
91 static int32_t UartSci_validateParams (const UART_Params* params, UartSci_HwCfg* ptrHwCfg);
92 static void    UartSci_writeChar(UartSci_Driver* ptrUartSciDriver, UartSci_HwCfg* ptrHwCfg);
93 static void    UartSci_readChar(UartSci_Driver* ptrUartSciDriver, UartSci_HwCfg* ptrHwCfg);
95 /**************************************************************************
96  ************************** Local Declarations ****************************
97  **************************************************************************/
99 /**
100  * @brief   Global Constant CR
101  */
102 static const uint8_t   CONST_CR =  (uint8_t)'\r';
104 /**
105  * @brief   Global Constant LF
106  */
107 static const uint8_t   CONST_LF =  (uint8_t)'\n';
109 /** @brief
110  *
111  *  Defines SCI frame format: number of stop bits
112  */
113 typedef uint32_t UARTSCI_FORMAT_STOPBIT;
114 #define UARTSCI_FORMAT_STOPBIT_ONE           ((uint32_t) 0U)
115 #define UARTSCI_FORMAT_STOPBIT_TWO           ((uint32_t) 1U)
117 /** @brief
118  *
119  *  Defines SCI frame format: partty type
120  */
121 typedef uint32_t UARTSCI_FORMAT_PARITY_TYPE;
122 #define UARTSCI_FORMAT_PARITY_NONE           ((uint32_t) 0U)
123 #define UARTSCI_FORMAT_PARITY_EVEN           ((uint32_t) 1U)
124 #define UARTSCI_FORMAT_PARITY_ODD            ((uint32_t) 2U)
126 /** @brief
127  *
128  *  Defines SCI frame format: character length in bits
129  */
130 typedef uint32_t UARTSCI_FORMAT_CHAR_LEN;
131 #define UARTSCI_FORMAT_CHAR_LEN_1           ((uint32_t) 0U)
132 #define UARTSCI_FORMAT_CHAR_LEN_2           ((uint32_t) 1U)
133 #define UARTSCI_FORMAT_CHAR_LEN_3           ((uint32_t) 2U)
134 #define UARTSCI_FORMAT_CHAR_LEN_4           ((uint32_t) 3U)
135 #define UARTSCI_FORMAT_CHAR_LEN_5           ((uint32_t) 4U)
136 #define UARTSCI_FORMAT_CHAR_LEN_6           ((uint32_t) 5U)
137 #define UARTSCI_FORMAT_CHAR_LEN_7           ((uint32_t) 6U)
138 #define UARTSCI_FORMAT_CHAR_LEN_8           ((uint32_t) 7U)
139 #define UARTSCI_FORMAT_CHAR_LEN_MAX         UARTSCI_FORMAT_CHAR_LEN_8
141 /** @brief
142  *
143  *  Defines SCI Timing mode
144  */
145 typedef uint32_t UARTSCI_TIMING_MODE;
146 #define UARTSCI_TIMING_MODE_SYNC            ((uint32_t) 0U)
147 #define UARTSCI_TIMING_MODE_ASYNC           ((uint32_t) 1U)
149 /** @brief
150  *
151  *  Defines SCI Clock mode
152  */
153 typedef uint32_t UARTSCI_CLOCK_MODE;
154 #define UARTSCI_CLOCK_MODE_EXTERNAL         ((uint32_t) 0U)
155 #define UARTSCI_CLOCK_MODE_INTERNAL         ((uint32_t) 1U)
157 /** @brief
158  *
159  *  Defines SCI Communication mode
160  */
161 typedef uint32_t UARTSCI_COMM_MODE;
162 #define UARTSCI_COMM_MODE_IDLE              ((uint32_t) 0U)
163 #define UARTSCI_COMM_MODE_ADDRESS           ((uint32_t) 1U)
165 /** @brief
166  *
167  *  Defines SCI interrupt indication
168  */
169 typedef uint32_t UARTSCI_INT_IND;
170 #define UARTSCI_INT_IND_BREAK               ((uint32_t) 1U)
171 #define UARTSCI_INT_IND_PE                  ((uint32_t) 2U)
172 #define UARTSCI_INT_IND_FE                  ((uint32_t) 3U)
173 #define UARTSCI_INT_IND_BREAK_DET_ERR       ((uint32_t) 4U)
174 #define UARTSCI_INT_IND_OE                  ((uint32_t) 5U)
175 #define UARTSCI_INT_IND_RX                  ((uint32_t) 6U)
176 #define UARTSCI_INT_IND_TX                  ((uint32_t) 7U)
178 /** @brief
179  *
180  *  Defines SCI interrupt contrl bitmap
181  */
182 #define UARTSCI_INT_BITMAP_BREAK           ((uint32_t) 0x01U)
183 #define UARTSCI_INT_BITMAP_WAKEUP          ((uint32_t) 0x02U)
184 #define UARTSCI_INT_BITMAP_TX              ((uint32_t) 0x04U)
185 #define UARTSCI_INT_BITMAP_RX              ((uint32_t) 0x08U)
186 #define UARTSCI_INT_BITMAP_PE              ((uint32_t) 0x10U)
187 #define UARTSCI_INT_BITMAP_OE              ((uint32_t) 0x20U)
188 #define UARTSCI_INT_BITMAP_FE              ((uint32_t) 0x30U)
190 /** @brief
191  *
192  *  Holds the SCI UART configuration info.
193  */
194 typedef struct UART_SCI_CONFI_s {
195     /**  Receive Enable */
196     uint32_t                    rxEn;
198     /**  Transmit Enable */
199     uint32_t                    txEn;
201     /**  Clock Mode internal or external
202      * @note: If an external clock source is selected, the internal baud rate
203      *        generator is bypassed. The maximum frequency allowed for external
204      *        clock is VCLK/16
205      */
206     UARTSCI_CLOCK_MODE          clkMode;
208     /** Timing mode: Asynchronous or Synchronous mode
209      */
210     UARTSCI_TIMING_MODE         timingMode;
212     /** Communication mode: idle-line or address-bit for multiprocessor operation
213      *  only
214      */
215     UARTSCI_COMM_MODE           commMode;
217     /** Number of stop bits: one or two */
218     UARTSCI_FORMAT_STOPBIT      stopBits;
220     /** Parity: none, even or odd */
221     UARTSCI_FORMAT_PARITY_TYPE  parityType;
223     /** Data length in bits */
224     UARTSCI_FORMAT_CHAR_LEN     charLen;
226     /** Baud rate */
227     uint32_t                    baudRate;
229     /** Input Clock Frequency */
230     uint32_t                    clockFrequency;
232     /** flag to indicate in loopback mode  */
233     uint32_t                    loopback;
235 } UART_SCI_CONFIG;
237 /**************************************************************************
238  ************************** Global Variables ******************************
239  **************************************************************************/
241 /**
242  * @brief   UART-SCI Driver Function Table
243  */
244 UART_FxnTable gUartSciFxnTable =
246     &UartSci_close,
247     &UartSci_control,
248     &UartSci_init,
249     &UartSci_open,
250     &UartSci_read,
251     &UartSci_readPolling,
252     &UartSci_readCancel,
253     &UartSci_write,
254     &UartSci_writePolling,
255     &UartSci_writeCancel,
256     &UartSci_read2,
257     &UartSci_write2,
258 };
260 /**************************************************************************
261  ************************* UART SCI Driver Functions **********************
262  **************************************************************************/
263 /**
264  *  @b Description
265  *  @n
266  *      Utility function which is used to enable the specific SCI
267  *      Instance by taking it out of reset
268  *
269  *  @param[in]  ptrSCIRegs
270  *      Point to the SCI Base
271  *
272  *  \ingroup UART_SCI_INTERNAL_FUNCTION
273  *
274  *  @retval
275  *      Not applicable
276  */
277 void UartSci_enable (CSL_sciRegs* ptrSCIRegs)
279     CSL_FINS(ptrSCIRegs->SCIGCR0, SCI_SCIGCR0_RESET, 1U);
282 /**
283  *  @b Description
284  *  @n
285  *      Utility function which is used to check if the specific SCI
286  *      Instance is enabled or not
287  *
288  *  @param[in]  ptrSCIRegs
289  *      Point to the SCI Base
290  *
291  *  \ingroup UART_SCI_INTERNAL_FUNCTION
292  *
293  *  @retval
294  *      1   -   SCI is enabled
295  *  @retval
296  *      0   -   SCI is disabled
297  */
298 uint32_t UartSci_isEnabled (const CSL_sciRegs* ptrSCIRegs)
300     return CSL_FEXT(ptrSCIRegs->SCIGCR0, SCI_SCIGCR0_RESET);
303 /**
304  *  @b Description
305  *  @n
306  *      Utility function which is used to disable the specific SCI
307  *      Instance by putting it into reset state
308  *
309  *  @param[in]  ptrSCIRegs
310  *      Point to the SCI Base
311  *
312  *  \ingroup UART_SCI_INTERNAL_FUNCTION
313  *
314  *  @retval
315  *      Not applicable
316  */
317 void UartSci_disable (CSL_sciRegs* ptrSCIRegs)
319     CSL_FINS(ptrSCIRegs->SCIGCR0, SCI_SCIGCR0_RESET, 0U);
322 /**
323  *  @b Description
324  *  @n
325  *      Utility function which is used to put the specific SCI
326  *      Instance into software reset for configuration
327  *
328  *  @param[in]  ptrSCIRegs
329  *      Point to the SCI Base
330  *
331  *  \ingroup UART_SCI_INTERNAL_FUNCTION
332  *
333  *  @retval
334  *      Not applicable
335  */
336 void UartSci_enableSwReset (CSL_sciRegs* ptrSCIRegs)
338     CSL_FINS(ptrSCIRegs->SCIGCR1, SCI_SCIGCR1_SW_NRESET, 0U);
341 /**
342  *  @b Description
343  *  @n
344  *      Utility function which is used to check if the specific SCI
345  *      Instance is at Software Reset state
346  *
347  *  @param[in]  ptrSCIRegs
348  *      Point to the SCI Base
349  *
350  *  \ingroup UART_SCI_INTERNAL_FUNCTION
351  *
352  *  @retval
353  *      1   -   SCI is at software reset
354  *  @retval
355  *      0   -   SCI is operational
356  */
357 uint32_t UartSci_isSwReset (const CSL_sciRegs* ptrSCIRegs)
359     return (CSL_FEXT(ptrSCIRegs->SCIGCR1, SCI_SCIGCR1_SW_NRESET)?0U:1U);
362 /**
363  *  @b Description
364  *  @n
365  *      Utility function which is used to take the specific SCI
366  *      instance out of software reset for normal operation
367  *
368  *  @param[in]  ptrSCIRegs
369  *      Point to the SCI Base
370  *
371  *  \ingroup UART_SCI_INTERNAL_FUNCTION
372  *
373  *  @retval
374  *      Not applicable
375  */
376 void UartSci_disableSwReset (CSL_sciRegs* ptrSCIRegs)
378     CSL_FINS(ptrSCIRegs->SCIGCR1, SCI_SCIGCR1_SW_NRESET, 1U);
381 /**
382  *  @b Description
383  *  @n
384  *      Utility function which is used to disable all interrupts
385  *      for the specific SCI Instance
386  *
387  *  @param[in]  ptrSCIRegs
388  *      Point to the SCI Base
389  *
390  *  \ingroup UART_SCI_INTERNAL_FUNCTION
391  *
392  *  @retval
393  *      Not applicable
394  */
395 void UartSci_disableAllInterrupts (CSL_sciRegs* ptrSCIRegs)
397     CSL_REG_WR(&ptrSCIRegs->SCICLEARINT, 0xFFFFFFFFU);
400 /**
401  *  @b Description
402  *  @n
403  *      Utility function which is used to configure the specific SCI
404  *      Instance to its desired operation modes
405  *
406  *  @param[in]  ptrSCIRegs
407  *      Point to the SCI Base
408  *  @param[in]  ptrSCIConfig
409  *      Point to the Configuartion structure
410  *
411  *  \ingroup UART_SCI_INTERNAL_FUNCTION
412  *
413  *  @retval
414  *   <b> Return Value </b>
415  *   @n   0 = success
416  *   @n  -1 = bad state or bad parameters
417  *
418  *   <b> Pre Condition </b>
419  *   @n  SCI should be at software reset state.
420  */
421 int32_t UartSci_config (CSL_sciRegs* ptrSCIRegs, UART_SCI_CONFIG* ptrSCIConfig)
423     uint32_t resetVal;
424     uint32_t val32 = 0;
425     int32_t retVal = 0;
426     uint32_t divisionFactor = 1U;
428     resetVal = UartSci_isSwReset(ptrSCIRegs);
429     if (resetVal == 0)
430     {
431         retVal = -1;
432     }
433     else
434     {
435         if (ptrSCIConfig->txEn)
436         {
437             val32 |= CSL_FMK (SCI_SCIGCR1_TXENA, 1U);
438             CSL_FINS(ptrSCIRegs->SCIPIO0, SCI_SCIPIO0_TX_FUNC, 1U);
439         }
441         if (ptrSCIConfig->rxEn)
442         {
443             val32 |= CSL_FMK (SCI_SCIGCR1_RXENA, 1U);
444             CSL_FINS(ptrSCIRegs->SCIPIO0, SCI_SCIPIO0_RX_FUNC, 1U);
445         }
447         if (ptrSCIConfig->clkMode == UARTSCI_CLOCK_MODE_INTERNAL)
448         {
449             val32 |= CSL_FMK (SCI_SCIGCR1_CLOCK, 1U);
450             CSL_FINS(ptrSCIRegs->SCIPIO0, SCI_SCIPIO0_CLK_FUNC, 1U);
451         }
453         if (ptrSCIConfig->timingMode == UARTSCI_TIMING_MODE_ASYNC)
454         {
455             val32 |= CSL_FMK (SCI_SCIGCR1_TIMING_MODE, 1U);
456             divisionFactor = 16U;
457         }
459         if (ptrSCIConfig->commMode == UARTSCI_COMM_MODE_ADDRESS)
460         {
461             val32 |= CSL_FMK (SCI_SCIGCR1_COMM_MODE, 1U);
462         }
464         if (ptrSCIConfig->stopBits == UARTSCI_FORMAT_STOPBIT_TWO)
465         {
466             val32 |= CSL_FMK (SCI_SCIGCR1_STOP, 1U);
467         }
469         if (ptrSCIConfig->parityType == UARTSCI_FORMAT_PARITY_EVEN)
470         {
471             val32 |= CSL_FMK (SCI_SCIGCR1_PARITY_ENA, 1U) |
472                      CSL_FMK (SCI_SCIGCR1_PARITY, 1U);
473         }
474         else if (ptrSCIConfig->parityType == UARTSCI_FORMAT_PARITY_ODD)
475         {
476             val32 |= CSL_FMK (SCI_SCIGCR1_PARITY_ENA, 1U);
477         }
479         CSL_REG_WR(&ptrSCIRegs->SCIGCR1, val32);
481         if(ptrSCIConfig->charLen > UARTSCI_FORMAT_CHAR_LEN_MAX)
482         {
483             retVal = -1;
484         }
485         else
486         {
487             CSL_REG_WR(&ptrSCIRegs->SCICHAR, CSL_FMK(SCI_SCICHAR_CHAR, ptrSCIConfig->charLen));
488         }
490         /* Calculate the baud value to generate the desired baud rate */
491         if (ptrSCIConfig->baudRate == 0U)
492         {
493             val32 = ptrSCIConfig->clockFrequency/32U;
494         }
495         else
496         {
497             val32 = ptrSCIConfig->clockFrequency/(ptrSCIConfig->baudRate * divisionFactor) - 1U;
498         }
499         CSL_REG_WR(&ptrSCIRegs->SCIBAUD, val32);
501         if (ptrSCIConfig->loopback)
502         {
503             /* Enable Loopback: */
504             CSL_FINS(ptrSCIRegs->SCIGCR1, SCI_SCIGCR1_LOOP_BACK , 1U);
505         }
506     }
508     return(retVal);
511 /**
512  *  @b Description
513  *  @n
514  *      Utility function which is used to enable multiple interrupt
515  *      for the specific SCI Instance
516  *
517  *  @param[in]  ptrSCIRegs
518  *      Point to the SCI Base
519  *  @param[in]  intBitMap
520  *      Intrrupts to be enabled
521  *
522  *  \ingroup UART_SCI_INTERNAL_FUNCTION
523  *
524  *  @retval
525  *      Not applicable
526  */
527 void UartSci_enableInterrupts (CSL_sciRegs* ptrSCIRegs, uint32_t intBitMap)
529     uint32_t val32 = 0;
531     if(intBitMap & UARTSCI_INT_BITMAP_BREAK)
532     {
533         val32 |= CSL_FMK(SCI_SCISETINT_SET_BRKDT_INT, 1U);
534     }
536     if(intBitMap & UARTSCI_INT_BITMAP_WAKEUP)
537     {
538         val32 |= CSL_FMK(SCI_SCISETINT_SET_WAKEUP_INT, 1U);
539     }
541     if(intBitMap & UARTSCI_INT_BITMAP_TX)
542     {
543         val32 |= CSL_FMK(SCI_SCISETINT_SET_TX_INT, 1U);
544     }
546     if(intBitMap & UARTSCI_INT_BITMAP_RX)
547     {
548         val32 |= CSL_FMK(SCI_SCISETINT_SET_RX_INT, 1U);
549     }
551     if(intBitMap & UARTSCI_INT_BITMAP_PE)
552     {
553         val32 |= CSL_FMK(SCI_SCISETINT_SET_PE_INT, 1U);
554     }
556     if(intBitMap & UARTSCI_INT_BITMAP_OE)
557     {
558         val32 |= CSL_FMK(SCI_SCISETINT_SET_OE_INT, 1U);
559     }
561     if(intBitMap & UARTSCI_INT_BITMAP_FE)
562     {
563         val32 |= CSL_FMK(SCI_SCISETINT_SET_FE_INT, 1U);
564     }
566     CSL_REG_WR(&ptrSCIRegs->SCISETINT, val32);
569 /**
570  *  @b Description
571  *  @n
572  *      Utility function which is used to disable multiple interrupt
573  *      for the specific SCI Instance
574  *
575  *  @param[in]  ptrSCIRegs
576  *      Point to the SCI Base
577  *  @param[in]  intBitMap
578  *      Intrrupts to be enabled
579  *
580  *  \ingroup UART_SCI_INTERNAL_FUNCTION
581  *
582  *  @retval
583  *      Not applicable
584  */
585 void UartSci_disableInterrupts (CSL_sciRegs* ptrSCIRegs, uint32_t intBitMap)
587     uint32_t val32 = 0;
589     if(intBitMap & UARTSCI_INT_BITMAP_BREAK)
590     {
591         val32 |= CSL_FMK(SCI_SCICLEARINT_CLR_BRKDT_INT, 1U);
592     }
594     if(intBitMap & UARTSCI_INT_BITMAP_WAKEUP)
595     {
596         val32 |= CSL_FMK(SCI_SCICLEARINT_CLR_WAKEUP_INT, 1U);
597     }
599     if(intBitMap & UARTSCI_INT_BITMAP_TX)
600     {
601         val32 |= CSL_FMK(SCI_SCICLEARINT_CLR_TX_INT, 1U);
602     }
604     if(intBitMap & UARTSCI_INT_BITMAP_RX)
605     {
606         val32 |= CSL_FMK(SCI_SCICLEARINT_CLR_RX_INT, 1U);
607     }
609     if(intBitMap & UARTSCI_INT_BITMAP_PE)
610     {
611         val32 |= CSL_FMK(SCI_SCICLEARINT_CLR_PE_INT, 1U);
612     }
614     if(intBitMap & UARTSCI_INT_BITMAP_OE)
615     {
616         val32 |= CSL_FMK(SCI_SCICLEARINT_CLR_OE_INT, 1U);
617     }
619     if(intBitMap & UARTSCI_INT_BITMAP_FE)
620     {
621         val32 |= CSL_FMK(SCI_SCICLEARINT_CLR_FE_INT, 1U);
622     }
624     CSL_REG_WR(&ptrSCIRegs->SCICLEARINT, val32);
627 /**
628  *  @b Description
629  *  @n
630  *      Utility function which is used to set multiple interrupt
631  *      levels from int0 to int1 for the specific SCI Instance
632  *
633  *  @param[in]  ptrSCIRegs
634  *      Point to the SCI Base
635  *  @param[in]  intBitMap
636  *      Intrrupts to be enabled
637  *
638  *  \ingroup UART_SCI_INTERNAL_FUNCTION
639  *
640  *  @retval
641  *      Not applicable
642  */
643 void UartSci_setInterruptLevels (CSL_sciRegs* ptrSCIRegs, uint32_t intBitMap)
645     uint32_t val32 = 0;
647     if(intBitMap & UARTSCI_INT_BITMAP_BREAK)
648     {
649         val32 |= CSL_FMK(SCI_SCISETINTLVL_SET_BRKDT_INT_LVL, 1U);
650     }
652     if(intBitMap & UARTSCI_INT_BITMAP_WAKEUP)
653     {
654         val32 |= CSL_FMK(SCI_SCISETINTLVL_SET_WAKEUP_INT_LVL, 1U);
655     }
657     if(intBitMap & UARTSCI_INT_BITMAP_TX)
658     {
659         val32 |= CSL_FMK(SCI_SCISETINTLVL_SET_TX_INT_LVL, 1U);
660     }
662     if(intBitMap & UARTSCI_INT_BITMAP_RX)
663     {
664         val32 |= CSL_FMK(SCI_SCISETINTLVL_SET_RX_INT_LVL, 1U);
665     }
667     if(intBitMap & UARTSCI_INT_BITMAP_PE)
668     {
669         val32 |= CSL_FMK(SCI_SCISETINTLVL_SET_PE_INT_LVL, 1U);
670     }
672     if(intBitMap & UARTSCI_INT_BITMAP_OE)
673     {
674         val32 |= CSL_FMK(SCI_SCISETINTLVL_SET_OE_INT_LVL, 1U);
675     }
677     if(intBitMap & UARTSCI_INT_BITMAP_FE)
678     {
679         val32 |= CSL_FMK(SCI_SCISETINTLVL_SET_FE_INT_LVL, 1U);
680     }
682     CSL_REG_WR(&ptrSCIRegs->SCISETINTLVL, val32);
685 /**
686  *  @b Description
687  *  @n
688  *      Utility function which is used to clear multiple interrupt
689  *      levels back from int1 to int0 for the specific SCI Instance
690  *
691  *  @param[in]  ptrSCIRegs
692  *      Point to the SCI Base
693  *  @param[in]  intBitMap
694  *      Intrrupts to be enabled
695  *
696  *  \ingroup UART_SCI_INTERNAL_FUNCTION
697  *
698  *  @retval
699  *      Not applicable
700  */
701 void UartSci_clearInterruptLevels (CSL_sciRegs* ptrSCIRegs, uint32_t intBitMap)
703     uint32_t val32 = 0;
705     if(intBitMap & UARTSCI_INT_BITMAP_BREAK)
706     {
707         val32 |= CSL_FMK(SCI_SCICLEARINTLVL_CLR_BRKDT_INT_LVL, 1U);
708     }
710     if(intBitMap & UARTSCI_INT_BITMAP_WAKEUP)
711     {
712         val32 |= CSL_FMK(SCI_SCICLEARINTLVL_CLR_WAKEUP_INT_LVL, 1U);
713     }
715     if(intBitMap & UARTSCI_INT_BITMAP_TX)
716     {
717         val32 |= CSL_FMK(SCI_SCICLEARINTLVL_CLR_TX_INT_LVL, 1U);
718     }
720     if(intBitMap & UARTSCI_INT_BITMAP_RX)
721     {
722         val32 |= CSL_FMK(SCI_SCICLEARINTLVL_CLR_RX_INT_LVL, 1U);
723     }
725     if(intBitMap & UARTSCI_INT_BITMAP_PE)
726     {
727         val32 |= CSL_FMK(SCI_SCICLEARINTLVL_CLR_PE_INT_LVL, 1U);
728     }
730     if(intBitMap & UARTSCI_INT_BITMAP_OE)
731     {
732         val32 |= CSL_FMK(SCI_SCICLEARINTLVL_CLR_OE_INT_LVL, 1U);
733     }
735     if(intBitMap & UARTSCI_INT_BITMAP_FE)
736     {
737         val32 |= CSL_FMK(SCI_SCICLEARINTLVL_CLR_FE_INT_LVL, 1U);
738     }
740     CSL_REG_WR(&ptrSCIRegs->SCICLEARINTLVL, val32);
743 /**
744  *  @b Description
745  *  @n
746  *      Utility function which is used to clear all interrupt
747  *      levels back to int0 for the specific SCI Instance
748  *
749  *  @param[in]  ptrSCIRegs
750  *      Point to the SCI Base
751  *
752  *  \ingroup UART_SCI_INTERNAL_FUNCTION
753  *
754  *  @retval
755  *      Not applicable
756  */
757 void UartSci_clearAllInterruptLevels (CSL_sciRegs* ptrSCIRegs)
759     CSL_REG_WR(&ptrSCIRegs->SCICLEARINTLVL, 0xFFFFFFFFU);
761 /**
762  *  @b Description
763  *  @n
764  *      Utility function which is used to enable/disable loopback mode
765  *      for the specific SCI Instance
766  *
767  *  @param[in]  ptrSCIRegs
768  *      Point to the SCI Base
769  *  @param[in]  enable
770  *      0/1: disable/enable loopback
771  *
772  *  \ingroup UART_SCI_INTERNAL_FUNCTION
773  *
774  *  @retval
775  *      Not applicable
776  */
777 void UartSci_loopbackControl (CSL_sciRegs* ptrSCIRegs, uint32_t enable)
779     uint32_t resetVal = UartSci_isSwReset(ptrSCIRegs);
781     if (resetVal == 1U)
782     {
783         UartSci_enableSwReset(ptrSCIRegs);
784     }
786     if (enable == 1U)
787     {
788         CSL_FINS(ptrSCIRegs->SCIGCR1, SCI_SCIGCR1_LOOP_BACK , 1U);
789     }
790     else
791     {
792         CSL_FINS(ptrSCIRegs->SCIGCR1, SCI_SCIGCR1_LOOP_BACK , 0U);
793     }
795     if (resetVal == 1U)
796     {
797         UartSci_disableSwReset(ptrSCIRegs);
798     }
801 /**
802  *  @b Description
803  *  @n
804  *      Utility function which is used to enable the transmit interrupt
805  *      for the specific SCI Instance
806  *
807  *  @param[in]  ptrSCIRegs
808  *      Point to the SCI Base
809  *
810  *  \ingroup UART_SCI_INTERNAL_FUNCTION
811  *
812  *  @retval
813  *      Not applicable
814  */
815 static void UartSci_enableTxInterrupt (CSL_sciRegs* ptrSCIRegs)
817     CSL_FINS(ptrSCIRegs->SCISETINT, SCI_SCISETINT_SET_TX_INT, 1U);
820 /**
821  *  @b Description
822  *  @n
823  *      Utility function which is used to check if the transmit interrupt
824  *      for the specific SCI Instance is enabled or not
825  *
826  *  @param[in]  ptrSCIRegs
827  *      Point to the SCI Base
828  *
829  *  \ingroup UART_SCI_INTERNAL_FUNCTION
830  *
831  *  @retval
832  *      1   -   Interrupt is enabled
833  *  @retval
834  *      0   -   Interrupt is disabled
835  */
836 static uint32_t UartSci_isTxInterruptEnabled (const CSL_sciRegs* ptrSCIRegs)
838     return CSL_FEXT(ptrSCIRegs->SCISETINT, SCI_SCISETINT_SET_TX_INT);
841 /**
842  *  @b Description
843  *  @n
844  *      Utility function which is used to enable the transmit DMA
845  *      functionality for the specific SCI Instance
846  *
847  *  @param[in]  ptrSCIRegs
848  *      Point to the SCI Base
849  *
850  *  \ingroup UART_SCI_INTERNAL_FUNCTION
851  *
852  *  @retval
853  *      Not applicable
854  */
855 void UartSci_enableTxDMA (CSL_sciRegs* ptrSCIRegs)
857     /* Enable Transmit DMA */
858     CSL_FINS(ptrSCIRegs->SCISETINT, SCI_SCISETINT_SET_TX_DMA, 1U);
861 /**
862  *  @b Description
863  *  @n
864  *      Utility function which is used to disable the transmit DMA
865  *      functionality for the specific SCI Instance
866  *
867  *  @param[in]  ptrSCIRegs
868  *      Point to the SCI Base
869  *
870  *  \ingroup UART_SCI_INTERNAL_FUNCTION
871  *
872  *  @retval
873  *      Not applicable
874  */
875 void UartSci_disableTxDMA (CSL_sciRegs* ptrSCIRegs)
877     /* Disable the Transmit DMA */
878     CSL_REG_WR(&ptrSCIRegs->SCICLEARINT, CSL_FMK(SCI_SCICLEARINT_CLR_TX_DMA, 1U));
881 /**
882  *  @b Description
883  *  @n
884  *      Utility function which is used to disable the transmit interrupt
885  *      for the specific SCI Instance
886  *
887  *  @param[in]  ptrSCIRegs
888  *      Point to the SCI Base
889  *
890  *  \ingroup UART_SCI_INTERNAL_FUNCTION
891  *
892  *  @retval
893  *      Not applicable
894  */
895 static void UartSci_disableTxInterrupt (CSL_sciRegs* ptrSCIRegs)
897     CSL_REG_WR(&ptrSCIRegs->SCICLEARINT, CSL_FMK(SCI_SCICLEARINT_CLR_TX_INT, 1U));
900 /**
901  *  @b Description
902  *  @n
903  *      Utility function which is used to enable the receive interrupt
904  *      for the specific SCI Instance
905  *
906  *  @param[in]  ptrSCIRegs
907  *      Point to the SCI Base
908  *
909  *  \ingroup UART_SCI_INTERNAL_FUNCTION
910  *
911  *  @retval
912  *      Not applicable
913  */
914 static void UartSci_enableRxInterrupt (CSL_sciRegs* ptrSCIRegs)
916     CSL_FINS(ptrSCIRegs->SCISETINT, SCI_SCISETINT_SET_RX_INT, 1U);
919 /**
920  *  @b Description
921  *  @n
922  *      Utility function which is used to check if the transmit interrupt
923  *      for the specific SCI Instance is enabled or not
924  *
925  *  @param[in]  ptrSCIRegs
926  *      Point to the SCI Base
927  *
928  *  \ingroup UART_SCI_INTERNAL_FUNCTION
929  *
930  *  @retval
931  *      1   -   Interrupt is enabled
932  *  @retval
933  *      0   -   Interrupt is disabled
934  */
935 static uint32_t UartSci_isRxInterruptEnabled (const CSL_sciRegs* ptrSCIRegs)
937     return CSL_FEXT(ptrSCIRegs->SCISETINT, SCI_SCISETINT_SET_RX_INT);
940 /**
941  *  @b Description
942  *  @n
943  *      Utility function which is used to disable the receive interrupt
944  *      for the specific SCI Instance
945  *
946  *  @param[in]  ptrSCIRegs
947  *      Point to the SCI Base
948  *
949  *  \ingroup UART_SCI_INTERNAL_FUNCTION
950  *
951  *  @retval
952  *      Not applicable
953  */
954 static void UartSci_disableRxInterrupt (CSL_sciRegs* ptrSCIRegs)
956     CSL_REG_WR(&ptrSCIRegs->SCICLEARINT,
957                CSL_FMK(SCI_SCICLEARINT_CLR_RX_INT, 1U));
960 /**
961  *  @b Description
962  *  @n
963  *      Utility function which is used to enable the receive DMA
964  *      functionality for the specific SCI Instance
965  *
966  *  @param[in]  ptrSCIRegs
967  *      Point to the SCI Base
968  *
969  *  \ingroup UART_SCI_INTERNAL_FUNCTION
970  *
971  *  @retval
972  *      Not applicable
973  */
974 void UartSci_enableRxDMA (CSL_sciRegs* ptrSCIRegs)
976     /* Enable the Rx DMA All and Rx DMA */
977     CSL_FINS(ptrSCIRegs->SCISETINT, SCI_SCISETINT_SET_RX_DMA_ALL, 1U);
978     CSL_FINS(ptrSCIRegs->SCISETINT, SCI_SCISETINT_SET_RX_DMA, 1U);
981 /**
982  *  @b Description
983  *  @n
984  *      Utility function which is used to disable the receive DMA
985  *      functionality for the specific SCI Instance
986  *
987  *  @param[in]  ptrSCIRegs
988  *      Point to the SCI Base
989  *
990  *  \ingroup UART_SCI_INTERNAL_FUNCTION
991  *
992  *  @retval
993  *      Not applicable
994  */
995 void UartSci_disableRxDMA (CSL_sciRegs* ptrSCIRegs)
997     /* Disable the Rx DMA All and Rx DMA */
998     CSL_REG_WR(&ptrSCIRegs->SCICLEARINT, CSL_FMK(SCI_SCICLEARINT_CLR_RX_DMA_ALL, 1U));
999     CSL_REG_WR(&ptrSCIRegs->SCICLEARINT, CSL_FMK(SCI_SCICLEARINT_CLR_RX_DMA, 1U));
1002 /**
1003  *  @b Description
1004  *  @n
1005  *      Utility function which is used to determine if the SCI receiver
1006  *      has been overrun or not?
1007  *
1008  *  @param[in]  ptrSCIRegs
1009  *      Point to the SCI Base
1010  *
1011  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1012  *
1013  *  @retval
1014  *      1   -   Receiver overrun has been detected
1015  *  @retval
1016  *      0   -   Receiver overrun not detected
1017  */
1018 static uint32_t UartSci_isRxOverrun (const CSL_sciRegs* ptrSCIRegs)
1020     return CSL_FEXT(ptrSCIRegs->SCIFLR, SCI_SCIFLR_OE);
1023 /**
1024  *  @b Description
1025  *  @n
1026  *      Utility function which is used to clear the SCI receiver.
1027  *
1028  *  @param[in]  ptrSCIRegs
1029  *      Point to the SCI Base
1030  *
1031  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1032  *
1033  *  @retval
1034  *      Not applicable
1035  */
1036 static void UartSci_clearRxOverrun (CSL_sciRegs* ptrSCIRegs)
1038     /* Write a 1 to the Overrun bit will clear the status of the overrun */
1039     CSL_REG_WR(&ptrSCIRegs->SCIFLR, CSL_FMK(SCI_SCIFLR_OE, 1U));
1042 /**
1043  *  @b Description
1044  *  @n
1045  *      Utility function which is used to determine if there is a
1046  *      framing error or not?
1047  *
1048  *  @param[in]  ptrSCIRegs
1049  *      Point to the SCI Base
1050  *
1051  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1052  *
1053  *  @retval
1054  *      1   -   Framing error has been detected
1055  *  @retval
1056  *      0   -   Framing error has not been detected
1057  */
1058 static uint32_t UartSci_isFramingError (const CSL_sciRegs* ptrSCIRegs)
1060     return CSL_FEXT(ptrSCIRegs->SCIFLR, SCI_SCIFLR_FE);
1063 /**
1064  *  @b Description
1065  *  @n
1066  *      Utility function which is used to clear the framing error
1067  *
1068  *  @param[in]  ptrSCIRegs
1069  *      Point to the SCI Base
1070  *
1071  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1072  *
1073  *  @retval
1074  *      Not applicable
1075  */
1076 static void UartSci_clearFramingError (CSL_sciRegs* ptrSCIRegs)
1078     /* Write a 1 to the Overrun bit will clear the status of the overrun */
1079     CSL_REG_WR(&ptrSCIRegs->SCIFLR, CSL_FMK(SCI_SCIFLR_FE, 1U));
1082 /**
1083  *  @b Description
1084  *  @n
1085  *      Utility function which is used to determine if there is a
1086  *      parity error or not?
1087  *
1088  *  @param[in]  ptrSCIRegs
1089  *      Point to the SCI Base
1090  *
1091  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1092  *
1093  *  @retval
1094  *      1   -   Parity error has been detected
1095  *  @retval
1096  *      0   -   Parity error has not been detected
1097  */
1098 static uint32_t UartSci_isParityError (const CSL_sciRegs* ptrSCIRegs)
1100     return CSL_FEXT(ptrSCIRegs->SCIFLR, SCI_SCIFLR_PE);
1103 /**
1104  *  @b Description
1105  *  @n
1106  *      Utility function which is used to clear the parity error
1107  *
1108  *  @param[in]  ptrSCIRegs
1109  *      Point to the SCI Base
1110  *
1111  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1112  *
1113  *  @retval
1114  *      Not applicable
1115  */
1116 static void UartSci_clearParityError (CSL_sciRegs* ptrSCIRegs)
1118     /* Write a 1 to the Parity Error bit will clear the status */
1119     CSL_REG_WR(&ptrSCIRegs->SCIFLR, CSL_FMK(SCI_SCIFLR_PE, 1U));
1122 /**
1123  *  @b Description
1124  *  @n
1125  *      Utility function which is used to determine if the SCI receiver
1126  *      is free or not.
1127  *
1128  *  @param[in]  ptrSCIRegs
1129  *      Point to the SCI Base
1130  *
1131  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1132  *
1133  *  @retval
1134  *      1   -   Receiver is free
1135  *  @retval
1136  *      0   -   Receiver is not free
1137  */
1138 static uint32_t UartSci_isRxFree (const CSL_sciRegs* ptrSCIRegs)
1140     return CSL_FEXT(ptrSCIRegs->SCIFLR, SCI_SCIFLR_RXRDY);
1143 /**
1144  *  @b Description
1145  *  @n
1146  *      Utility function which is used to determine if the SCI transmitter
1147  *      is free or not.
1148  *
1149  *  @param[in]  ptrSCIRegs
1150  *      Point to the SCI Base
1151  *
1152  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1153  *
1154  *  @retval
1155  *      1   -   Transmitter is free
1156  *  @retval
1157  *      0   -   Transmitter is not free
1158  */
1159 static uint32_t UartSci_isTxFree (const CSL_sciRegs* ptrSCIRegs)
1161     return CSL_FEXT(ptrSCIRegs->SCIFLR, SCI_SCIFLR_TXRDY);
1164 /**
1165  *  @b Description
1166  *  @n
1167  *      Utility function which is used to determine if the SCI transmitter
1168  *      is empty, i.e. there is no data transmission in progress
1169  *
1170  *  @param[in]  ptrSCIRegs
1171  *      Point to the SCI Base
1172  *
1173  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1174  *
1175  *  @retval
1176  *      1   -   Transmitter is empty
1177  *  @retval
1178  *      0   -   Transmitter is not empty
1179  */
1180 static uint32_t UartSci_isTxEmpty (const CSL_sciRegs* ptrSCIRegs)
1182     return CSL_FEXT(ptrSCIRegs->SCIFLR, SCI_SCIFLR_TX_EMPTY);
1185 /**
1186  *  @b Description
1187  *  @n
1188  *      Utility function which is used to put a character
1189  *
1190  *  @param[in]  ptrSCIRegs
1191  *      Point to the SCI Base
1192  *  @param[in]  ch
1193  *      Character to be placed
1194  *
1195  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1196  *
1197  *  @retval
1198  *      Not applicable
1199  */
1201 static void UartSci_putCh (CSL_sciRegs* ptrSCIRegs, uint8_t ch)
1203     CSL_FINS(ptrSCIRegs->SCITD, SCI_SCITD_TD, ch);
1206 /**
1207  *  @b Description
1208  *  @n
1209  *      Utility function which is used to get a character
1210  *
1211  *  @param[in]  ptrSCIRegs
1212  *      Point to the SCI Base
1213  *
1214  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1215  *
1216  *  @retval
1217  *      Character which is read from the SCI Register
1218  */
1219 static uint8_t UartSci_getCh (const CSL_sciRegs* ptrSCIRegs)
1221     return (uint8_t)CSL_FEXT(ptrSCIRegs->SCIRD, SCI_SCIRD_RD);
1224 extern uint64_t TimerP_getTimeInUsecs(void);
1226 /**
1227  *  @b Description
1228  *  @n
1229  *      Utility function of delay in micro-second
1230  *
1231  *  @param[in]  nTicks
1232  *      dealy ticks in us
1233  *
1234  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1235  *
1236  *  @retval
1237  *      None
1238  */
1239 static void Uartsci_usDelay(uint64_t nTicks)
1241     uint64_t start, end;
1243     start = TimerP_getTimeInUsecs();
1245     /* Every 32 cycle increment is 1ms */
1246     do {
1247         end = TimerP_getTimeInUsecs();
1248     } while ((end - start) <= nTicks);
1251 /**
1252  *  @b Description
1253  *  @n
1254  *      The function is used to write the character from the write buffer
1255  *      on the UART.
1256  *
1257  *  @param[in]  handle
1258  *      Handle to the UART Driver
1259  *  @param[in]  isRx
1260  *      true: receive operation
1261  *      false: transmit operation
1262  *
1263  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1264  *
1265  *  @retval
1266  *      Not applicable
1267  */
1268 void UartSci_callback (UART_Handle handle, bool isRx)
1270     UART_Config*        ptrUARTConfig;
1271     UartSci_Driver*     ptrUartSciDriver;
1273     /* Get the UART Configuration: */
1274     ptrUARTConfig = (UART_Config*)handle;
1276     /* Get the UART Driver Instance: */
1277     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
1279     /* Call back to application */
1280     if (isRx)
1281     {
1282         if (ptrUartSciDriver->params.readMode == UART_MODE_CALLBACK)
1283         {
1284              ptrUartSciDriver->params.readCallback(handle,
1285                                                    (void *)ptrUartSciDriver->ptrReadBuffer,
1286                                                    ptrUartSciDriver->readCount);
1287         }
1288         else
1289         {
1290             (void)UART_osalPostLock(ptrUartSciDriver->readSem);
1291         }
1292     }
1293     else
1294     {
1295         if ( ptrUartSciDriver->params.writeMode == UART_MODE_CALLBACK)
1296         {
1297              ptrUartSciDriver->params.writeCallback(handle,
1298                                                     (void *)(ptrUartSciDriver->ptrWriteBuffer),
1299                                                     ptrUartSciDriver->writeCount);
1300         }
1301         else
1302         {
1303             (void)UART_osalPostLock( ptrUartSciDriver->writeSem);
1304         }
1305     }
1309 /**
1310  *  @b Description
1311  *  @n
1312  *      The function is used to write the character from the write buffer
1313  *      on the UART.
1314  *
1315  *  @param[in]  ptrUartSciDriver
1316  *      Pointer to the UART Driver Instance
1317  *  @param[in]  ptrHwCfg
1318  *      Pointer to the UART Driver Hardware configuration
1319  *
1320  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1321  *
1322  *  @retval
1323  *      Not applicable
1324  */
1325 static void UartSci_writeChar
1327     UartSci_Driver*   ptrUartSciDriver,
1328     UartSci_HwCfg*    ptrHwCfg
1331     /* Is the UART Driver operating in TEXT/BINARY Mode? */
1332     if (ptrUartSciDriver->params.writeDataMode == UART_DATA_TEXT)
1333     {
1334         /* TEXT Mode: */
1335         if (ptrUartSciDriver->writeCR)
1336         {
1337             /* Write the return character */
1338             UartSci_putCh (ptrHwCfg->ptrSCIRegs, CONST_CR);
1340             /* Write size is incremented an additional time on the detection of '\n'
1341              * So we decrement it back again here. */
1342             ptrUartSciDriver->writeSize--;
1343             ptrUartSciDriver->writeCount++;
1344             ptrUartSciDriver->writeCR = 0;
1345         }
1346         else
1347         {
1348             /* Add a return if next character is a newline. */
1349             if (*(char *)ptrUartSciDriver->ptrWriteBuffer == CONST_LF)
1350             {
1351                ptrUartSciDriver->writeSize++;
1352                ptrUartSciDriver->writeCR = 1;
1353             }
1355             /* Write the character to the transmit buffer: */
1356             UartSci_putCh (ptrHwCfg->ptrSCIRegs, *(uint8_t*)ptrUartSciDriver->ptrWriteBuffer);
1358             /* Move to the next character */
1359             ptrUartSciDriver->ptrWriteBuffer = (uint8_t *)ptrUartSciDriver->ptrWriteBuffer + 1;
1360             ptrUartSciDriver->writeSize--;
1361             ptrUartSciDriver->writeCount++;
1362         }
1363     }
1364     else
1365     {
1366         /* Binary Mode: */
1367         UartSci_putCh (ptrHwCfg->ptrSCIRegs, *(uint8_t *)ptrUartSciDriver->ptrWriteBuffer);
1369         /* Move to the next character */
1370         ptrUartSciDriver->ptrWriteBuffer = (uint8_t *)ptrUartSciDriver->ptrWriteBuffer + 1;
1371         ptrUartSciDriver->writeSize--;
1372         ptrUartSciDriver->writeCount++;
1373     }
1376 /**
1377  *  @b Description
1378  *  @n
1379  *      The function is used to read the character and place this into the
1380  *      read buffer.
1381  *
1382  *  @param[in]  ptrUartSciDriver
1383  *      Pointer to the UART Driver Instance
1384  *  @param[in]  ptrHwCfg
1385  *      Pointer to the UART Driver Hardware configuration
1386  *
1387  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1388  *
1389  *  @retval
1390  *      Not applicable
1391  */
1392 static void UartSci_readChar
1394     UartSci_Driver* ptrUartSciDriver,
1395     UartSci_HwCfg*  ptrHwCfg
1398     uint8_t readIn;
1400     /* Read the char: */
1401     readIn = UartSci_getCh (ptrHwCfg->ptrSCIRegs) >> ptrUartSciDriver->shiftJustification;
1403     /* Is the UART Driver operating in TEXT/BINARY Mode? */
1404     if (ptrUartSciDriver->params.readDataMode == UART_DATA_TEXT)
1405     {
1406         /* TEXT Mode: */
1407         if (readIn == CONST_CR)
1408         {
1409             /* Do we need to echo character? */
1410             if (ptrUartSciDriver->params.readEcho)
1411             {
1412                 /* YES: Loop around and wait until TX is ready */
1413                 while (1)
1414                 {
1415                     if (UartSci_isTxFree(ptrHwCfg->ptrSCIRegs) == 1U)
1416                     {
1417                         UartSci_putCh (ptrHwCfg->ptrSCIRegs, CONST_CR);
1418                         break;
1419                     }
1420                 }
1421             }
1422             readIn = CONST_LF;
1423         }
1424     }
1426     /* Do we need to echo character? */
1427     if (ptrUartSciDriver->params.readEcho)
1428     {
1429         /* YES: Loop around and wait until TX is ready */
1430         while (1)
1431         {
1432             if (UartSci_isTxFree(ptrHwCfg->ptrSCIRegs) == 1U)
1433             {
1434                 UartSci_putCh (ptrHwCfg->ptrSCIRegs, readIn);
1435                 break;
1436             }
1437         }
1438     }
1440     /* Place the character into the receive buffer and increment the various counters */
1441     *(uint8_t *)ptrUartSciDriver->ptrReadBuffer = readIn;
1442     ptrUartSciDriver->ptrReadBuffer = (uint8_t *)ptrUartSciDriver->ptrReadBuffer + 1;
1443     ptrUartSciDriver->readCount++;
1444     ptrUartSciDriver->readSize--;
1446     /* Is the read complete? */
1447     if ((ptrUartSciDriver->params.readReturnMode == UART_RETURN_NEWLINE) && (readIn == CONST_LF))
1448     {
1449         /* YES: In return mode; NEWLINE we can stop the reception operation when we receive
1450          * a new line character. */
1451         ptrUartSciDriver->readSize = 0;
1452     }
1455 /**
1456  *  @b Description
1457  *  @n
1458  *      The function is the registered ISR for the UART SCI Driver.
1459  *
1460  *  @param[in]  arg
1461  *      Argument which is registered with the OS while registering
1462  *      the ISR
1463  *
1464  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1465  *
1466  *  @retval
1467  *      Not applicable
1468  */
1469 static void UartSci_ISR (uintptr_t arg)
1471     UART_Config*        ptrUARTConfig;
1472     UartSci_Driver*     ptrUartSciDriver;
1473     UartSci_HwCfg*      ptrHwCfg;
1475     /* Get the UART Configuration: */
1476     ptrUARTConfig = (UART_Config*)arg;
1478     /* Get the UART Driver Instance: */
1479     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
1481     /* Get the hardware configuration: */
1482     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
1484     /* Increment the total number of interrupts received. */
1485     ptrUartSciDriver->stats.totalInterrupts++;
1487     /* Are receive interrupts enabled? Only then do we handle them in the ISR context. */
1488     if (UartSci_isRxInterruptEnabled (ptrHwCfg->ptrSCIRegs) == 1U)
1489     {
1490         /* Increment the total number of receive interrupts: */
1491         ptrUartSciDriver->stats.numRxInterrupts++;
1493         /* Is there a Rx Interrupt? */
1494         if (UartSci_isRxFree(ptrHwCfg->ptrSCIRegs) == 1U)
1495         {
1496             /* YES: Do we have a valid data buffer where we need to place the data? */
1497             if (ptrUartSciDriver->readSize > 0)
1498             {
1499                 /* Read the character: */
1500                 UartSci_readChar (ptrUartSciDriver, ptrHwCfg);
1502                 /* Sanity Check: The read size can never be negative */
1503                 UART_osalAssert (ptrUartSciDriver->readSize >= 0);
1505                 /* Are we done with the read buffer ? */
1506                 if (ptrUartSciDriver->readSize == 0)
1507                 {
1508                     /* Disable RX interrupt until we do a new read */
1509                     UartSci_disableRxInterrupt(ptrHwCfg->ptrSCIRegs);
1510                     UartSci_callback((UART_Handle)arg, true);
1511                 }
1512             }
1513             else
1514             {
1515                 /* We received a character but there was no application provided buffer. We
1516                  * cannot keep this. */
1517                 ptrUartSciDriver->stats.numDummyRead++;
1519                 /* Dummy read and drop the received character */
1520                 UartSci_getCh (ptrHwCfg->ptrSCIRegs);
1521             }
1522         }
1523     }
1525     /* Are transmit interrupts enabled? Only then do we handle them in the ISR context. */
1526     if (UartSci_isTxInterruptEnabled (ptrHwCfg->ptrSCIRegs) == 1U)
1527     {
1528         /* Increment the total number of transmit interrupts: */
1529         ptrUartSciDriver->stats.numTxInterrupts++;
1531         /* Is there a Tx Interrupt? */
1532         if (UartSci_isTxFree(ptrHwCfg->ptrSCIRegs) == 1U)
1533         {
1534             /* YES: Is there any data which needs to be written? */
1535             if (ptrUartSciDriver->writeSize > 0)
1536             {
1537                 /* Write the character: */
1538                 UartSci_writeChar (ptrUartSciDriver, ptrHwCfg);
1540                 /* Sanity Check: The write size can never be negative */
1541                 UART_osalAssert (ptrUartSciDriver->writeSize >= 0);
1543                 /* Are we done with the write buffer ? */
1544                 if (ptrUartSciDriver->writeSize <= 0)
1545                 {
1546                     /* Disable TX interrupt until we do a new write */
1547                     UartSci_disableTxInterrupt(ptrHwCfg->ptrSCIRegs);
1548                     UartSci_callback((UART_Handle)arg, false);
1549                 }
1550             }
1551         }
1552     }
1554     /* Is there an overrun error? */
1555     if (UartSci_isRxOverrun(ptrHwCfg->ptrSCIRegs) == 1U)
1556     {
1557         /* Increment the number of overrun counter: */
1558         ptrUartSciDriver->stats.numRxOverrunInterrupts++;
1560         /* Clear the overrun status: */
1561         UartSci_clearRxOverrun (ptrHwCfg->ptrSCIRegs);
1562     }
1564     /* Is there a framing error? */
1565     if (UartSci_isFramingError(ptrHwCfg->ptrSCIRegs) == 1U)
1566     {
1567         /* Increment the stats: */
1568         ptrUartSciDriver->stats.numFramingErrors++;
1570         /* Clear the framing error: */
1571         UartSci_clearFramingError (ptrHwCfg->ptrSCIRegs);
1572     }
1574     /* Is there a parity error? */
1575     if (UartSci_isParityError(ptrHwCfg->ptrSCIRegs) == 1U)
1576     {
1577         /* Increment the stats: */
1578         ptrUartSciDriver->stats.numParityError++;
1580         /* Clear the parity error: */
1581         UartSci_clearParityError (ptrHwCfg->ptrSCIRegs);
1582     }
1583     return;
1586 /**
1587  *  @b Description
1588  *  @n
1589  *      The function is the registered callback function which is invoked when
1590  *      the data is to be read from the UART Driver. This function implements
1591  *      a semaphore blocking operation if the UART driver instance is configured
1592  *      to operate in BLOCKING mode.
1593  *
1594  *  @param[in]  handle
1595  *      Handle to the UART Driver
1596  *  @param[in]  buffer
1597  *      Pointer to the data buffer
1598  *  @param[in]  size
1599  *      Size of the data which needs to be read
1600  *
1601  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1602  *
1603  *  @retval
1604  *      Success     - Number of bytes which have been read
1605  *  @retval
1606  *      Error       - UART Error code
1607  */
1608 static int32_t UartSci_read(UART_Handle handle, void *buffer, size_t size)
1610     UART_Config*        ptrUARTConfig;
1611     UartSci_Driver*     ptrUartSciDriver;
1612     UartSci_HwCfg*      ptrHwCfg;
1613     uintptr_t           key;
1614     SemaphoreP_Status   status;
1615     int32_t             retVal = 0;
1617     /* Get the UART Configuration: */
1618     ptrUARTConfig = (UART_Config*)handle;
1620     /* Get the UART Driver Instance: */
1621     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
1623     /* Get the hardware configuration: */
1624     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
1626     /* Sanity Check: Validate the arguments */
1627     if ((size == 0U) || (buffer == NULL) || (ptrHwCfg->duplexity == UartSci_Duplexity_TX_ONLY))
1628     {
1629         /* Error: Invalid Arguments */
1630         retVal = UART_EINVAL;
1631         goto exit;
1632     }
1634     if(ptrHwCfg->swCfg.enableInterrupt)
1635     {
1636         /* Disable preemption while checking if the uart is in use. */
1637         key = UART_osalHardwareIntDisable();
1639         /* Is the UART in use? */
1640         if (ptrUartSciDriver->readSize != 0U)
1641         {
1642             /* YES: Restore the interrupts and report the error to the application. */
1643             UART_osalHardwareIntRestore(key);
1644             UART_drv_log1 ("UART:(%p) Could not read data, UART in use\n", ptrHwCfg->ptrSCIRegs);
1645             retVal = UART_EINUSE;
1646             goto exit;
1647         }
1649         /* Save the data to be read */
1650         ptrUartSciDriver->ptrReadBuffer = (uint8_t *)buffer;
1651         ptrUartSciDriver->readSize      = (int32_t)size;
1652         ptrUartSciDriver->readCount     = 0;
1654         /* Restore the interrupts: */
1655         UART_osalHardwareIntRestore(key);
1657 #ifdef UART_DMA_ENABLE
1658         /* Determine the DMA Mode for the Driver: */
1659         if (ptrUartSciDriver->isDMAEnabled == true)
1660         {
1661             /****************************************************************
1662             * DMA Mode: Initiate the Receive DMA
1663             ****************************************************************/
1664             retVal = ptrHwCfg->initiateRxDMAFxn (ptrUartSciDriver, (uint32_t)buffer, (uint32_t)size, false);
1665             if (retVal < 0)
1666             {
1667                 /* Error: Unable to initiate the receive DMA */
1668                 goto exit;
1669             }
1670         }
1671         else
1672 #endif
1673         {
1674             /****************************************************************
1675             * Normal Mode: Enable the receive interrupt
1676             ****************************************************************/
1677             UartSci_enableRxInterrupt (ptrHwCfg->ptrSCIRegs);
1678         }
1680         if (ptrUartSciDriver->params.readMode == UART_MODE_BLOCKING)
1681         {
1682             /* Block the callee; till the UART reads are complete */
1683             status = UART_osalPendLock (ptrUartSciDriver->readSem, ptrUartSciDriver->params.readTimeout);
1684             if (status == SemaphoreP_TIMEOUT)
1685             {
1686                 /* Reset the read size */
1687                 ptrUartSciDriver->readSize = 0;
1689                 /* Report the error condition: */
1690                 UART_drv_log2 ("UART:(%p) Read timed out %d bytes read\n",
1691                             ptrHwCfg->ptrSCIRegs, ptrUartSciDriver->readCount);
1692             }
1694             /* Setup the number of bytes which have been read */
1695             retVal = ptrUartSciDriver->readCount;
1696         }
1697         else
1698         {
1699             /*
1700              * for callback mode, immediately return SUCCESS,
1701              * once the transaction is done, callback function
1702              * will return the transaction status and actual
1703              * read count
1704              */
1705             retVal = UART_SUCCESS;
1706         }
1707     }
1708     else
1709     {
1710         retVal = UartSci_readPolling(handle, buffer, size);
1711     }
1713 exit:
1714     return retVal;
1717 /**
1718  *  @b Description
1719  *  @n
1720  *      The function is the registered callback function which is invoked when
1721  *      the data is to be read in polling mode from the UART Driver. The function
1722  *      will loop around till all the buffer is completely filled up or if the new
1723  *      line character is received.
1724  *
1725  *  @param[in]  handle
1726  *      Handle to the UART Driver
1727  *  @param[in]  buffer
1728  *      Pointer to the data buffer
1729  *  @param[in]  size
1730  *      Size of the data which needs to be read
1731  *
1732  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1733  *
1734  *  @retval
1735  *      Success     - Number of bytes which have been read
1736  *  @retval
1737  *      Error       - UART Error code
1738  */
1739 static int32_t UartSci_readPolling(UART_Handle handle, void *buffer, size_t size)
1741     UART_Config*        ptrUARTConfig;
1742     UartSci_Driver*     ptrUartSciDriver;
1743     UartSci_HwCfg*      ptrHwCfg;
1744     uintptr_t           key;
1745     int32_t             retVal;
1747     /* Get the UART Configuration: */
1748     ptrUARTConfig = (UART_Config*)handle;
1750     /* Get the UART Driver Instance: */
1751     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
1753     /* Get the hardware configuration: */
1754     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
1756     /* Sanity Check: Validate the arguments */
1757     if ((size == 0U) || (buffer == NULL) || (ptrHwCfg->duplexity == UartSci_Duplexity_TX_ONLY))
1758     {
1759         /* Error: Invalid Arguments */
1760         retVal = UART_EINVAL;
1761         goto exit;
1762     }
1764     /* Disable preemption while checking if the uart is in use. */
1765     key = UART_osalHardwareIntDisable();
1767     /* Is the UART in use? */
1768     if (ptrUartSciDriver->readSize != 0)
1769     {
1770         /* YES: Restore the interrupts */
1771         UART_osalHardwareIntRestore(key);
1773         /* Report the error to the application. */
1774         UART_drv_log1 ("UART:(%p) Could not read data, UART in use\n", ptrHwCfg->ptrSCIRegs);
1776         /* Setup the error code: */
1777         retVal = UART_EINUSE;
1778         goto exit;
1779     }
1781     /* Save the data to be read */
1782     ptrUartSciDriver->ptrReadBuffer = (uint8_t *)buffer;
1783     ptrUartSciDriver->readSize      = (int32_t)size;
1784     ptrUartSciDriver->readCount     = 0;
1786     /* Restore the interrupts: */
1787     UART_osalHardwareIntRestore(key);
1789 #ifdef UART_DMA_ENABLE
1790     /* Determine the DMA Mode for the Driver: */
1791     if (ptrUartSciDriver->isDMAEnabled == true)
1792     {
1793         /****************************************************************
1794          * DMA Mode: Initiate the Receive DMA
1795          ****************************************************************/
1796         retVal = ptrHwCfg->initiateRxDMAFxn (ptrUartSciDriver, (uint32_t)buffer, size, true);
1797         if (retVal < 0)
1798         {
1799             /* Error: Unable to initiate the receive DMA */
1800             goto exit;
1801         }
1802     }
1803     else
1804 #endif
1805     {
1806         /****************************************************************
1807          * Normal Mode: Read out all the data
1808          ****************************************************************/
1809         bool isWaitForever = (ptrUartSciDriver->params.readTimeout == UART_WAIT_FOREVER);
1810         uint64_t timeout = ptrUartSciDriver->params.readTimeout * 1000;
1812         while (ptrUartSciDriver->readSize > 0)
1813         {
1814             /* Is the receiver free? */
1815             if (UartSci_isRxFree(ptrHwCfg->ptrSCIRegs) == 1U)
1816             {
1817                 /* YES: Read out a character from the buffer. */
1818                 UartSci_readChar (ptrUartSciDriver, ptrHwCfg);
1819             }
1820             else if (timeout < 10)
1821             {
1822                 /* Debug Message: */
1823                 UART_drv_log2 ("Debug: UART(%p) readPolling timeout %d bytes have been read\n",
1824                                 ptrHwCfg->ptrSCIRegs, ptrUartSciDriver->readCount);
1825                 break;
1826             }
1827             else if (!isWaitForever)
1828             {
1829                 Uartsci_usDelay(10);
1830                 timeout -= 10;
1831             }
1832         }
1833     }
1835     /* Setup the number of bytes which have been read */
1836     retVal = ptrUartSciDriver->readCount;
1838 exit:
1839     return retVal;
1842 /**
1843  *  @b Diption
1844  *  @n
1845  *      function is the registered callback function which is invoked when
1846  *      a previous data read operation has to be cancelled.
1847  *
1848  *  @parn]  handle
1849  *      le to the UART Driver
1850  *
1851  *  \ing UART_SCI_INTERNAL_FUNCTION
1852  *
1853  *  @ret
1854  *      applicable
1855  */
1856 static void UartSci_readCancel(UART_Handle handle)
1858     UART_Config*        ptrUARTConfig;
1859     UartSci_Driver*     ptrUartSciDriver;
1860     UartSci_HwCfg*      ptrHwCfg;
1861     uintptr_t           key;
1863     /* Get the UART Configuration: */
1864     ptrUARTConfig = (UART_Config*)handle;
1866     /* Get the UART Driver Instance: */
1867     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
1869     /* Get the hardware configuration: */
1870     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
1872     /* Disable preemption while checking if the uart is in use. */
1873     key = UART_osalHardwareIntDisable();
1875     /* Is the UART in use? */
1876     if (ptrUartSciDriver->readSize == 0)
1877     {
1878         /* No: There is nothing to cancel */
1879         UART_osalHardwareIntRestore(key);
1880     }
1881     else
1882     {
1883         /* YES: Reset the read size to 0; this will stop the read operations */
1884         ptrUartSciDriver->readSize = 0;
1886         /* Determine the DMA Mode for the Driver: */
1887         if (ptrUartSciDriver->isDMAEnabled == true)
1888         {
1889             /****************************************************************
1890              * DMA Mode: Disable the Rx DMA
1891              ****************************************************************/
1892             UartSci_disableRxDMA (ptrHwCfg->ptrSCIRegs);
1893         }
1894         else
1895         {
1896             /****************************************************************
1897              * Normal Mode: Disable the Rx interrupt
1898              ****************************************************************/
1899             UartSci_disableRxInterrupt (ptrHwCfg->ptrSCIRegs);
1900         }
1902         /* Restore the interrupts: */
1903         UART_osalHardwareIntRestore(key);
1905         UartSci_callback(handle, true);
1907         /* Debug Message: */
1908         UART_drv_log2 ("Debug: UART(%p) read canceled %d bytes have been read\n",
1909                         ptrHwCfg->ptrSCIRegs, ptrUartSciDriver->readCount);
1910     }
1911     return;
1914 /**
1915  *  @b Description
1916  *  @n
1917  *      The function is the registered callback function which is invoked when
1918  *      the data is to be written to the UART Driver. This function implements
1919  *      a semaphore blocking operation if the UART driver instance is configured
1920  *      to operate in BLOCKING mode.
1921  *
1922  *  @param[in]  handle
1923  *      Handle to the UART Driver
1924  *  @param[in]  buffer
1925  *      Pointer to the data buffer
1926  *  @param[in]  size
1927  *      Size of the data to be written
1928  *
1929  *  \ingroup UART_SCI_INTERNAL_FUNCTION
1930  *
1931  *  @retval
1932  *      Success     - Number of bytes which have been transferred
1933  *  @retval
1934  *      Error       - UART Error code
1935  */
1936 static int32_t UartSci_write(UART_Handle handle, const void *buffer, size_t size)
1938     UART_Config*        ptrUARTConfig;
1939     UartSci_Driver*     ptrUartSciDriver;
1940     UartSci_HwCfg*      ptrHwCfg;
1941     SemaphoreP_Status   status;
1942     uintptr_t           key;
1943     int32_t             retVal = 0;
1945     /* Sanity Check: Validate the arguments */
1946     if ((size == 0U) || (buffer == NULL))
1947     {
1948         /* Error: Invalid Arguments */
1949         retVal = UART_EINVAL;
1950         goto exit;
1951     }
1953     /* Get the UART Configuration: */
1954     ptrUARTConfig = (UART_Config*)handle;
1956     /* Get the UART Driver Instance: */
1957     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
1959     /* Get the hardware configuration: */
1960     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
1962     if(ptrHwCfg->swCfg.enableInterrupt)
1963     {
1964         /* Disable preemption while checking if the uart is in use. */
1965         key = UART_osalHardwareIntDisable();
1967         /* Is the UART in use? */
1968         if (ptrUartSciDriver->writeSize != 0)
1969         {
1970             /* YES: Restore the interrupts */
1971             UART_osalHardwareIntRestore(key);
1973             /* Log the error to the application: */
1974             UART_drv_log1 ("UART:(%p) Could not write data, UART in use\n", (void *)ptrHwCfg->ptrSCIRegs);
1976             /* Setup the error code: */
1977             retVal = UART_EINUSE;
1978             goto exit;
1979         }
1981         /* NO: Save the data to be written */
1982         ptrUartSciDriver->ptrWriteBuffer = (uint8_t *)buffer;
1983         ptrUartSciDriver->writeSize      = (int32_t)size;
1984         ptrUartSciDriver->writeCount     = 0;
1986         /* Restore the interrupts: */
1987         UART_osalHardwareIntRestore(key);
1989 #ifdef UART_DMA_ENABLE
1990         /* Determine the DMA Mode for the Driver: */
1991         if (ptrUartSciDriver->isDMAEnabled == true)
1992         {
1993             /****************************************************************
1994             * DMA Mode: Initiate the transmit DMA
1995             ****************************************************************/
1996             retVal = ptrHwCfg->initiateTxDMAFxn (ptrUartSciDriver, (uint32_t)buffer, (uint32_t)size, false);
1997             if (retVal < 0)
1998             {
1999                 /* Error: Unable to initiate the transmit DMA */
2000                 goto exit;
2001             }
2002         }
2003         else
2004 #endif
2005         {
2006             /****************************************************************
2007             * Normal Mode: We always need to send out the first character
2008             * because the Transmit interrupt is only generated after the
2009             * first transfer from the TD to the TXSHF
2010             ****************************************************************/
2011             /* Wait for Tx Ready */
2012             while (UartSci_isTxFree(ptrHwCfg->ptrSCIRegs) == 0U) {};
2013             UartSci_writeChar(ptrUartSciDriver, ptrHwCfg);
2015             /* Do we have more data to send? */
2016             if (ptrUartSciDriver->writeSize == 0U)
2017             {
2018                 /* NO: This is the case where there is only 1 byte of data to be
2019                 * sent out. Setup the return value and we are done. */
2020                 retVal = ptrUartSciDriver->writeCount;
2021                 goto exit;
2022             }
2024             /* Enable the Transmit Interrupt: */
2025             UartSci_enableTxInterrupt (ptrHwCfg->ptrSCIRegs);
2026         }
2028         if (ptrUartSciDriver->params.writeMode == UART_MODE_BLOCKING)
2029         {
2030             /* Block the callee; till the UART writes are complete */
2031             status = UART_osalPendLock (ptrUartSciDriver->writeSem, ptrUartSciDriver->params.writeTimeout);
2032             if (status == SemaphoreP_TIMEOUT)
2033             {
2034                 /* Time out: Write has not been completed in the specified duration
2035                 * Disable the transmit interrupt */
2036                 UartSci_disableTxInterrupt (ptrHwCfg->ptrSCIRegs);
2038                 /* Reset the write size */
2039                 ptrUartSciDriver->writeSize = 0;
2041                 /* Report the error condition: */
2042                 UART_drv_log2 ("UART:(%p) Write timed out %d bytes written\n",
2043                                (void *)ptrHwCfg->ptrSCIRegs, ptrUartSciDriver->writeCount);
2044             }
2046             /* Return the number of bytes which have been sent out. */
2047             retVal = ptrUartSciDriver->writeCount;
2048         }
2049         else
2050         {
2051             /*
2052              * for callback mode, immediately return SUCCESS,
2053              * once the transaction is done, callback function
2054              * will return the transaction status and actual
2055              * write count
2056              */
2057             retVal = UART_SUCCESS;
2058         }
2059     }
2060     else
2061     {
2062         retVal = UartSci_writePolling(handle, buffer, size);
2063     }
2065 exit:
2066     return retVal;
2069 /**
2070  *  @b Description
2071  *  @n
2072  *      The function is the registered callback function which is invoked when
2073  *      the data is to be written to the UART Driver but this will poll the UART
2074  *      driver in a while loop and will only return once all the data has been
2075  *      sent out.
2076  *
2077  *  @param[in]  handle
2078  *      Handle to the UART Driver
2079  *  @param[in]  buffer
2080  *      Pointer to the data buffer
2081  *  @param[in]  size
2082  *      Size of the data to be written
2083  *
2084  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2085  *
2086  *  @retval
2087  *      Success     - Number of bytes which have been transferred
2088  *  @retval
2089  *      Error       - UART Error code
2090  */
2091 static int32_t UartSci_writePolling(UART_Handle handle, const void* buffer, size_t size)
2093     UART_Config*        ptrUARTConfig;
2094     UartSci_Driver*     ptrUartSciDriver;
2095     UartSci_HwCfg*      ptrHwCfg;
2096     uintptr_t           key;
2097     int32_t             retVal = 0;
2099     /* Sanity Check: Validate the arguments */
2100     if ((size == 0U) || (buffer == NULL))
2101     {
2102         /* Error: Invalid Arguments */
2103         retVal = UART_EINVAL;
2104         goto exit;
2105     }
2107     /* Get the UART Configuration: */
2108     ptrUARTConfig = (UART_Config*)handle;
2110     /* Get the UART Driver Instance: */
2111     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
2113     /* Get the hardware configuration: */
2114     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
2116     /* Disable preemption while checking if the uart is in use. */
2117     key = UART_osalHardwareIntDisable();
2119     /* Is the UART in use? */
2120     if (ptrUartSciDriver->writeSize != 0)
2121     {
2122         /* YES: Restore the interrupts and report the error to the application. */
2123         UART_osalHardwareIntRestore(key);
2124         UART_drv_log1 ("UART:(%p) Could not write data, UART in use\n", (void *)ptrHwCfg->ptrSCIRegs);
2126         /* Setup the error code: */
2127         retVal = UART_EINUSE;
2128         goto exit;
2129     }
2131     /* NO: Save the data to be written */
2132     ptrUartSciDriver->ptrWriteBuffer = (uint8_t*)buffer;
2133     ptrUartSciDriver->writeSize      = (int32_t)size;
2134     ptrUartSciDriver->writeCount     = 0U;
2136     /* Restore the interrupts: */
2137     UART_osalHardwareIntRestore(key);
2139 #ifdef UART_DMA_ENABLE
2140     /* Determine the DMA Mode for the Driver: */
2141     if (ptrUartSciDriver->isDMAEnabled == true)
2142     {
2143         /****************************************************************
2144          * DMA Mode: Initiate the transmit DMA
2145          ****************************************************************/
2146         retVal = ptrHwCfg->initiateTxDMAFxn (ptrUartSciDriver, (uint32_t)buffer, (uint32_t)size, true);
2147         if (retVal < 0)
2148         {
2149             /* Error: Unable to initiate the transmit DMA. The return value
2150              * is already setup with the error code. */
2151             goto exit;
2152         }
2153     }
2154     else
2155 #endif
2156     {
2157         /****************************************************************
2158          * Normal Mode: Write the data out one by one
2159          ****************************************************************/
2160         bool isWaitForever = (ptrUartSciDriver->params.writeTimeout == UART_WAIT_FOREVER);
2161         uint64_t timeout = ptrUartSciDriver->params.writeTimeout * 1000;
2163         /* Send out all the data: */
2164         while (ptrUartSciDriver->writeSize > 0)
2165         {
2166             /* Is the transmitter free? */
2167             if (UartSci_isTxFree(ptrHwCfg->ptrSCIRegs) == 1U)
2168             {
2169                 /* YES: Write out a character from the buffer. */
2170                 UartSci_writeChar (ptrUartSciDriver, ptrHwCfg);
2171             }
2172             else if (timeout < 10)
2173             {
2174                 /* Debug Message: */
2175                 UART_drv_log2 ("Debug: UART(%p) writePolling timeout %d bytes have been read\n",
2176                                 ptrHwCfg->ptrSCIRegs, ptrUartSciDriver->writeCount);
2177                 break;
2178             }
2179             else if (!isWaitForever)
2180             {
2181                 Uartsci_usDelay(10);
2182                 timeout -= 10;
2183             }
2184         }
2185     }
2187     /* Setup the number of bytes which have been written */
2188     retVal = ptrUartSciDriver->writeCount;
2190 exit:
2191     return retVal;
2194 /**
2195  *  @b Description
2196  *  @n
2197  *      The function is the registered callback function which is invoked
2198  *      when the UART Driver write operations are ben canceled.
2199  *
2200  *  @param[in]  handle
2201  *      Handle to the UART Driver
2202  *
2203  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2204  *
2205  *  @retval
2206  *      Not applicable
2207  */
2208 static void UartSci_writeCancel(UART_Handle handle)
2210     UART_Config*        ptrUARTConfig;
2211     UartSci_Driver*     ptrUartSciDriver;
2212     UartSci_HwCfg*      ptrHwCfg;
2213     uintptr_t           key;
2215     /* Get the UART Configuration: */
2216     ptrUARTConfig = (UART_Config*)handle;
2218     /* Get the UART Driver Instance: */
2219     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
2221     /* Get the hardware configuration: */
2222     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
2224     /* Disable preemption while checking if the uart is in use. */
2225     key = UART_osalHardwareIntDisable();
2227     /* Is the UART in use? */
2228     if (ptrUartSciDriver->writeSize == 0)
2229     {
2230         /* NO: Restore the interrupts and report the error to the application. */
2231         UART_osalHardwareIntRestore(key);
2232     }
2233     else
2234     {
2235         /* Set the write size to 0; this will prevent any more characters from being
2236          * transmitted. */
2237         ptrUartSciDriver->writeSize = 0;
2239         /* Determine the DMA Mode for the Driver: */
2240         if (ptrUartSciDriver->isDMAEnabled == true)
2241         {
2242             /* DMA Mode: Disable the Tx DMA */
2243             UartSci_disableTxDMA (ptrHwCfg->ptrSCIRegs);
2244         }
2245         else
2246         {
2247             /* Normal Mode: Disable the Tx interrupt: */
2248             UartSci_disableTxInterrupt (ptrHwCfg->ptrSCIRegs);
2249         }
2251         /* Restore the interrupts: */
2252         UART_osalHardwareIntRestore(key);
2254         /* We have cancelled the write operation. Invoke post-write operation */
2255         UartSci_callback(handle, false);
2257         /* Debug Message: */
2258         UART_drv_log2 ("Debug: UART(%p) write canceled %d bytes have been written\n",
2259                         (void *)ptrHwCfg->ptrSCIRegs, ptrUartSciDriver->writeCount);
2260     }
2261     return;
2264 /**
2265  *  @b Description
2266  *  @n
2267  *      The function is the registered callback function which is invoked when
2268  *      the UART Driver instance is being passed a control command.
2269  *
2270  *  @param[in]  handle
2271  *      Handle to the UART Driver
2272  *  @param[in]  cmd
2273  *      UART command
2274  *  @param[in]  arg
2275  *      Opaque handle to the argument
2276  *
2277  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2278  *
2279  *  @retval
2280  *      Success -   0
2281  *  @retval
2282  *      Error   -   UART Error code
2283  */
2284 static int32_t UartSci_control(UART_Handle handle, uint32_t cmd, void *arg)
2286     UART_Config*        ptrUARTConfig;
2287     UartSci_Driver*     ptrUartSciDriver;
2288     UartSci_HwCfg*      ptrHwCfg;
2289     int32_t             errCode;
2291     /* Initialize and setup the error code: */
2292     errCode = 0;
2294     /* Get the UART Configuration: */
2295     ptrUARTConfig = (UART_Config*)handle;
2297     /* Get the UART Driver Instance: */
2298     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
2300     /* Get the hardware configuration: */
2301     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
2303     /* Processing is done on the basis of the command: */
2304     switch (cmd)
2305     {
2306         case UART_CMD_LOOPBACK:
2307         {
2308             uint32_t*   loopback;
2310             /* Sanity Check: We need to ensure that a valid argument was passed */
2311             if (arg == NULL)
2312             {
2313                 /* Error: No valid argument was passed. */
2314                 errCode = UART_EINVAL;
2315             }
2316             else
2317             {
2318                 /* Get the loopback status from the argument */
2319                 loopback = (uint32_t*)arg;
2320                 UartSci_loopbackControl(ptrHwCfg->ptrSCIRegs, *loopback);
2322                 /*\r
2323                  * Silicon workaround: It has been identified that it will take a while
2324                  *                     for the loopback mode to take effect, therefore,
2325                  *                     introduce some delay here to avoid tx operation
2326                  *                     to be triggered prior to that.\r
2327                  */\r
2328                 if (*loopback)
2329                 {
2330                     UART_osalDelay(2);
2331                 }
2332             }
2333             break;
2334         }
2335         case UART_CMD_GET_STATS:
2336         {
2337             UART_Stats* ptrUARTStats;
2339             /* Sanity Check: We need to ensure that a valid argument was passed */
2340             if (arg == NULL)
2341             {
2342                 /* Error: No valid argument was passed. */
2343                 errCode = UART_EINVAL;
2344             }
2345             else
2346             {
2347                 /* Get the pointer to the UART statistics */
2348                 ptrUARTStats = (UART_Stats*)arg;
2350                 /* Copy over the UART statistics */
2351                 memcpy ((void*)ptrUARTStats, (void*)&ptrUartSciDriver->stats, sizeof(UART_Stats));
2352             }
2353             break;
2354         }
2355         default:
2356         {
2357             /* Error: Unsuported/Invalid command specified */
2358             errCode = UART_EINVAL;
2359             break;
2360         }
2361     }
2362     return errCode;
2365 /**
2366  *  @b Description
2367  *  @n
2368  *      The function is used to validate the arguments
2369  *
2370  *  @param[in]  params
2371  *      UART Parameters to be validated
2372  *  @param[in]  ptrHwCfg
2373  *      Pointer to the hardware configuration
2374  *
2375  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2376  *
2377  *  @retval
2378  *      Success -   0
2379  *  @retval
2380  *      Error   -   <0
2381  */
2382 static int32_t UartSci_validateParams (const UART_Params* params, UartSci_HwCfg* ptrHwCfg)
2384     int32_t retVal = 0;
2386     /* Sanity Check: The current implementation of the UART Driver currently only supports
2387      * NONE, ODD and EVEN Parity.  */
2388     if (params->parityType >= UART_PAR_ZERO)
2389     {
2390         retVal = -1;
2391     }
2393     /* Sanity Check: The current implementation of the UART Driver currently only supports
2394      * 5/6/7/8-bit data length.  */
2395     if (params->dataLength > UART_LEN_8)
2396     {
2397         retVal = -1;
2398     }
2400     /* Sanity Check: Ensure that the clock frequency is NON-Zero. */
2401     if ((params->baudRate == 0) || (ptrHwCfg->swCfg.clockFrequency == 0))
2402     {
2403         retVal = -1;
2404     }
2406     /* Sanity Check: Ensure the callback function is provided at callback mode. */
2407     if (((params->readMode == UART_MODE_CALLBACK) && (params->readCallback == NULL)) ||
2408         ((params->writeMode == UART_MODE_CALLBACK) && (params->writeCallback == NULL)))
2409     {
2410         retVal = -1;
2411     }
2413     return retVal;
2416 /**
2417  *  @b Description
2418  *  @n
2419  *      The function is the registered callback function which is invoked when
2420  *      the UART Driver instance is being opened with a specific application
2421  *      supplied arguments.
2422  *
2423  *  @param[in]  handle
2424  *      Handle to the UART Driver
2425  *  @param[in]  params
2426  *      UART Parameters with which the driver is being opened
2427  *
2428  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2429  *
2430  *  @retval
2431  *      Success -   Driver Handle
2432  *  @retval
2433  *      Error   -   NULL
2434  */
2435 static UART_Handle UartSci_open(UART_Handle handle, const UART_Params* params)
2437     UART_Config*             ptrUARTConfig;
2438     UartSci_Driver*          ptrUartSciDriver;
2439     SemaphoreP_Params        semParams;
2440     OsalRegisterIntrParams_t interruptRegParams;
2441     UartSci_HwCfg*           ptrHwCfg;
2442     UART_Handle              retHandle = NULL;
2443     CSL_sciRegs*             ptrSCIRegs;
2444     UART_SCI_CONFIG          sciConfig;
2445     uint32_t                 val32;
2446     int32_t                  ret;
2448     /* Get the UART Configuration: */
2449     ptrUARTConfig = (UART_Config*)handle;
2451     /* Get the hardware configuration: */
2452     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
2454     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
2456     /* Sanity Check: Validate the arguments */
2457     if (UartSci_validateParams(params, ptrHwCfg) < 0)
2458     {
2459         /* Error: Invalid arguments have been passed to the driver */
2460         UART_drv_log1 ("Debug: UART Driver (%p) Invalid arguments\n", (void *)ptrHwCfg->ptrSCIRegs);
2461         goto exit;
2462     }
2464     /* Initialize the memory: */
2465     memset ((void *)ptrUartSciDriver, 0, sizeof(UartSci_Driver));
2467     /* Copy over the UART Parameters */
2468     memcpy ((void*)&ptrUartSciDriver->params, (void *)params, sizeof(UART_Params));
2469     ptrUartSciDriver->handle = handle;
2471 #ifdef UART_DMA_ENABLE
2472     /* Open the DMA Block associated with the UART Instance */
2473     if (ptrHwCfg->openDMAFxn (ptrUartSciDriver, ptrHwCfg) < 0)
2474     {
2475         /* Error: Unable to open the DMA Block. */
2476         UART_drv_log1 ("Error: UART Driver (%p) Unable to open the DMA Block\n", (void *)ptrHwCfg->ptrSCIRegs);
2477         goto exit;
2478     }
2479 #endif
2481     /* Create a binary semaphore which is used to handle the Blocking operation. */
2482     UART_osalSemParamsInit(&semParams);
2483     semParams.mode             = SemaphoreP_Mode_BINARY;
2484     ptrUartSciDriver->writeSem = UART_osalCreateBlockingLock(0, &semParams);
2486     /* Create a binary semaphore which is used to handle the Blocking operation. */
2487     UART_osalSemParamsInit(&semParams);
2488     semParams.mode            = SemaphoreP_Mode_BINARY;
2489     ptrUartSciDriver->readSem = UART_osalCreateBlockingLock(0, &semParams);
2491     ptrSCIRegs = ptrHwCfg->ptrSCIRegs;
2492     /* Enable the SCI Module: */
2493     UartSci_enable(ptrSCIRegs);
2495     /* Put the SCI Module in Software Reset State: */
2496     UartSci_enableSwReset(ptrSCIRegs);
2498     /* Disable the interrupts: */
2499     UartSci_disableAllInterrupts (ptrSCIRegs);
2500     UartSci_clearAllInterruptLevels (ptrSCIRegs);
2502     /* Setup the SCI Global Control Register:
2503      *  - Receiver Enabled
2504      *  - Transmit Enabled
2505      *  - Internal Clock
2506      *  - Asynchronous Timing Mode
2507      *  - Idle-line Communication mode
2508      */
2509     sciConfig.rxEn = 1U;
2510     sciConfig.txEn = 1U;
2511     sciConfig.clkMode = UARTSCI_CLOCK_MODE_INTERNAL;
2512     sciConfig.timingMode = UARTSCI_TIMING_MODE_ASYNC;
2513     sciConfig.commMode = UARTSCI_COMM_MODE_IDLE;
2515     /* Setup the Stop Bits: */
2516     if (params->stopBits == UART_STOP_ONE)
2517     {
2518         sciConfig.stopBits = UARTSCI_FORMAT_STOPBIT_ONE;
2519     }
2520     else
2521     {
2522         sciConfig.stopBits = UARTSCI_FORMAT_STOPBIT_ONE;
2523     }
2525     /* Setup the Parity: */
2526     switch (params->parityType)
2527     {
2528         case UART_PAR_NONE:
2529         {
2530             sciConfig.parityType = UARTSCI_FORMAT_PARITY_NONE;
2531             break;
2532         }
2533         case UART_PAR_EVEN:
2534         {
2535             sciConfig.parityType = UARTSCI_FORMAT_PARITY_EVEN;
2536             break;
2537         }
2538         case UART_PAR_ODD:
2539         {
2540             sciConfig.parityType = UARTSCI_FORMAT_PARITY_ODD;
2541             break;
2542         }
2543         default:
2544         {
2545             /* Error: We have already verified the parameters. Control should never come here. */
2546             UART_osalAssert (0);
2547             break;
2548         }
2549     }
2551     /* Setup the Baud Rate: */
2552     sciConfig.clockFrequency = ptrHwCfg->swCfg.clockFrequency;
2553     sciConfig.baudRate = params->baudRate;
2555     /* Setup the data length control: */
2556     switch (params->dataLength)
2557     {
2558         case UART_LEN_5:
2559         {
2560             /* Data Length is 5 */
2561             sciConfig.charLen = UARTSCI_FORMAT_CHAR_LEN_5;
2562             ptrUartSciDriver->shiftJustification = 3U;
2563             break;
2564         }
2565         case UART_LEN_6:
2566         {
2567             /* Data Length is 6 */
2568             sciConfig.charLen = UARTSCI_FORMAT_CHAR_LEN_6;
2569             ptrUartSciDriver->shiftJustification = 2U;
2570             break;
2571         }
2572         case UART_LEN_7:
2573         {
2574             /* Data Length is 7 */
2575             sciConfig.charLen = UARTSCI_FORMAT_CHAR_LEN_7; 
2576             ptrUartSciDriver->shiftJustification = 1U;
2577             break;
2578         }
2579         case UART_LEN_8:
2580         {
2581             /* Data Length is 8 */
2582             sciConfig.charLen = UARTSCI_FORMAT_CHAR_LEN_8;
2583             ptrUartSciDriver->shiftJustification = 0U;
2584             break;
2585         }
2586         default:
2587         {
2588             /* Error: We have already verified the parameters. Control should never come here. */
2589             UART_osalAssert (0);
2590             break;
2591         }
2592     }
2594     if (ptrHwCfg->swCfg.loopback)
2595     {
2596         /* Enable Loopback: */
2597         sciConfig.loopback = 1U;
2598     }
2599     else
2600     {
2601         /* Disable Loopback: */
2602         sciConfig.loopback = 0U;
2603     }
2605     ret = UartSci_config (ptrSCIRegs, &sciConfig);
2606     if (ret < 0)
2607     {
2608         UART_drv_log1 ("Error: UART Driver configure error with ret = %d\n", ret);
2609         goto exit;
2610     }
2612     /* Enable the Interrupts:
2613      * - Framing Error
2614      * - Overrun Error
2615      * - Parity Error */
2616     val32 = UARTSCI_INT_BITMAP_FE |
2617             UARTSCI_INT_BITMAP_OE |
2618             UARTSCI_INT_BITMAP_PE;
2619     UartSci_enableInterrupts(ptrSCIRegs, val32);
2621     /* Register the Interrupt Handler: */
2622     if(ptrHwCfg->swCfg.enableInterrupt)
2623     {
2624         /* Construct Hwi object for this UART peripheral. */
2625         /* Initialize with defaults */
2626         Osal_RegisterInterrupt_initParams(&interruptRegParams);
2628          /* Populate the interrupt parameters */
2629         interruptRegParams.corepacConfig.arg=(uintptr_t)handle;
2630         interruptRegParams.corepacConfig.name=(char *)"UART";
2631         interruptRegParams.corepacConfig.isrRoutine=UartSci_ISR;
2632 #ifdef __TI_ARM_V7R4__
2633         interruptRegParams.corepacConfig.priority=0x8U;
2634         interruptRegParams.corepacConfig.intVecNum = (int32_t)(ptrHwCfg->interruptNum); /* Host Interrupt vector */
2635 #elif  defined(_TMS320C6X)
2636         interruptRegParams.corepacConfig.priority=0x20U;
2637         interruptRegParams.corepacConfig.corepacEventNum = (int32_t)(ptrHwCfg->interruptNum); /* Event going to INTC */
2638         interruptRegParams.corepacConfig.intVecNum = (int32_t)(OSAL_REGINT_INTVEC_EVENT_COMBINER); /* Host Interrupt vector */
2639 #endif
2641         /* Register interrupts */
2642         (void)UART_osalRegisterInterrupt(&interruptRegParams,&(ptrUartSciDriver->hwiHandle));
2644         if(ptrUartSciDriver->hwiHandle)
2645         {
2646             UART_drv_log2 ("Debug: UART Driver Registering HWI ISR [%p] for Interrupt %d\n",
2647                            ptrUartSciDriver->hwiHandle, ptrHwCfg->interruptNum);
2648         }
2649         else
2650         {
2651             goto exit;
2652         }
2653     }
2655     /* Start the SCI: */
2656     UartSci_disableSwReset (ptrSCIRegs);
2658     /*\r
2659      * Silicon workaround: It has been identified that it will take a while for the loopback mode
2660      *                     to take effect, therefore, introduce some delay here to avoid tx operation
2661      *                     to be triggered prior to that.\r
2662      */\r
2663     if (ptrHwCfg->swCfg.loopback)
2664     {
2665         UART_osalDelay(2);
2666     }
2668     /* Mark the driver to be operational */
2669     ptrUartSciDriver->status = UartSci_DriverStatus_OPERATIONAL;
2671     /* Debug Message: */
2672     UART_drv_log1 ("Debug: UART Driver %p opened\n", (void *)ptrHwCfg->ptrSCIRegs);
2674     /* Setup the return handle */
2675     retHandle = (UART_Handle)handle;
2677 exit:
2678     return retHandle;
2681 /**
2682  *  @b Description
2683  *  @n
2684  *      The function is the registered callback function which is invoked when
2685  *      the UART Driver instance is being closed
2686  *
2687  *  @param[in]  handle
2688  *      Handle to the UART Driver
2689  *
2690  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2691  *
2692  *  @retval
2693  *      Not applicable
2694  */
2695 static void UartSci_close(UART_Handle handle)
2697     UART_Config*        ptrUARTConfig;
2698     UartSci_Driver*     ptrUartSciDriver;
2699     UartSci_HwCfg*      ptrHwCfg;
2701     /* Get the UART Configuration: */
2702     ptrUARTConfig = (UART_Config*)handle;
2704     /* Get the UART Driver Instance: */
2705     ptrUartSciDriver = (UartSci_Driver*)ptrUARTConfig->object;
2707     /* Get the hardware configuration: */
2708     ptrHwCfg = (UartSci_HwCfg*)ptrUARTConfig->hwAttrs;
2710     /* Is the driver in use? */
2711     if (ptrUartSciDriver->status == UartSci_DriverStatus_UNINITIALIZED)
2712     {
2713         /* Error: UART has alreay been closed */
2714         UART_drv_log1 ("Error: UART Driver has already been closed\n", (void *)ptrHwCfg->ptrSCIRegs);
2715         goto exit;
2716     }
2718     /* Disable the interrupts: */
2719     UartSci_disableAllInterrupts(ptrHwCfg->ptrSCIRegs);
2721     /* Was the HWI registered?  */
2722     if (ptrUartSciDriver->hwiHandle)
2723     {
2724         /* YES: Delete and unregister the interrupt handler. */
2725         (void)UART_osalHardwareIntDestruct(ptrUartSciDriver->hwiHandle, (int32_t)(ptrHwCfg->interruptNum));
2726     }
2728     /*
2729      * Wait for the ongoing transmission to be completed.
2730      */
2731     while(!UartSci_isTxEmpty(ptrHwCfg->ptrSCIRegs)){};
2733     /* Was the UART Driver operating in Write Blocking mode? */
2734     if (ptrUartSciDriver->writeSem)
2735     {
2736         /* YES: Delete the write semaphore */
2737         UART_osalDeleteBlockingLock (ptrUartSciDriver->writeSem);
2738     }
2740     /* Was the UART Driver operating in Read Blocking mode? */
2741     if (ptrUartSciDriver->readSem)
2742     {
2743         /* YES: Delete the read semaphore */
2744         UART_osalDeleteBlockingLock (ptrUartSciDriver->readSem);
2745     }
2747 #ifdef UART_DMA_ENABLE
2748     /* Close the DMA block associated with the UART Instance */
2749     ptrHwCfg->closeDMAFxn (ptrUartSciDriver);
2750 #endif
2751     /* The driver is not in use: */
2752     ptrUartSciDriver->status = UartSci_DriverStatus_UNINITIALIZED;
2754 exit:
2755     return;
2758 /**
2759  *  @b Description
2760  *  @n
2761  *      The function is the registered callback function which is invoked when
2762  *      the UART drivers are initialized.
2763  *
2764  *  @param[in]  handle
2765  *      Handle to the UART Driver which is to be initialized.
2766  *
2767  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2768  *
2769  *  @retval
2770  *      Not applicable
2771  */
2772 static void
2773 UartSci_init(UART_Handle handle)
2775     return;
2778 /**
2779  *  @b Description
2780  *  @n
2781  *      The function is the registered callback function which is invoked when
2782  *      the UART driver invokes UART_read2() to receive data .
2783  *
2784  *  @param[in]  handle
2785  *      Handle to the UART Driver which is to be initialized.
2786  *
2787  *  @param[in/out] uartTrans
2788  *      A pointer to a UART_Transaction
2789  *
2790  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2791  *
2792  *  @return Returns UART_SUCCESS or UART_ERROR on an error.
2793  */
2794 static int32_t UartSci_read2(UART_Handle handle, UART_Transaction *transaction)
2796     return (UART_ENOTIMPL);
2799 /**
2800  *  @b Description
2801  *  @n
2802  *      The function is the registered callback function which is invoked when
2803  *      the UART driver invokes UART_write2() to transmit data .
2804  *
2805  *  @param[in]  handle
2806  *      Handle to the UART Driver which is to be initialized.
2807  *
2808  *  @param[in/out] uartTrans
2809  *      A pointer to a UART_Transaction
2810  *
2811  *  \ingroup UART_SCI_INTERNAL_FUNCTION
2812  *
2813  *  @return Returns UART_SUCCESS or UART_ERROR on an error.
2814  */
2815 static int32_t UartSci_write2(UART_Handle handle, UART_Transaction *transaction)
2817     return (UART_ENOTIMPL);