1 /*
2  * Copyright (c) 2020, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ============================================================================
33  *  @file       UART2CC32XX.h
34  *
35  *  @brief      UART driver implementation for a CC32XX UART controller
36  *
37  *  The UART header file should be included in an application as follows:
38  *  @code
39  *  #include <ti/drivers/UART2.h>
40  *  #include <ti/drivers/uart2/UART2CC32XX.h>
41  *  @endcode
42  *
43  *  Refer to @ref UART2.h for a complete description of APIs and examples
44  *  of use.
45  *
46  *  ============================================================================
47  */
48 
49 #ifndef ti_drivers_uart2_UART2CC32XX__include
50 #define ti_drivers_uart2_UART2CC32XX__include
51 
52 #include <stddef.h>
53 #include <stdint.h>
54 #include <stdbool.h>
55 
56 #include <ti/drivers/dpl/HwiP.h>
57 #include <ti/drivers/dpl/SemaphoreP.h>
58 #include <ti/drivers/power/PowerCC32XX.h>
59 #include <ti/drivers/UART2.h>
60 #include <ti/drivers/dma/UDMACC32XX.h>
61 #include <ti/drivers/Power.h>
62 
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66 
67 /*!
68  * @brief Indicates a pin is not being used
69  *
70  *  If hardware flow control is not being used, the UART CTS and RTS
71  *  pins should be set to UART2CC32XX_PIN_UNASSIGNED.
72  */
73 #define UART2CC32XX_PIN_UNASSIGNED   0xFFF
74 
75 /*!
76  * @brief Indicates a DMA channel is not being used
77  *
78  *  If DMA is not being used, the UART rxDmaChannel and txDmaChannel
79  *  should be set to UART2CC32XX_DMACH_UNASSIGNED.
80  */
81 #define UART2CC32XX_DMACH_UNASSIGNED 0xFF
82 
83 /*
84  *  The bits in the pin mode macros are as follows:
85  *  The lower 8 bits of the macro refer to the pin, offset by 1, to match
86  *  driverlib pin defines.  For example, UART2CC32XX_PIN_01_UART1_TX & 0xff = 0,
87  *  which equals PIN_01 in driverlib pin.h.  By matching the PIN_xx defines in
88  *  driverlib pin.h, we can pass the pin directly to the driverlib functions.
89  *  The upper 8 bits of the macro correspond to the pin mux confg mode
90  *  value for the pin to operate in the UART mode.  For example, pin 1 is
91  *  configured with mode 7 to operate as UART1 TX.
92  */
93 #define UART2CC32XX_PIN_01_UART1_TX  0x700 /*!< PIN 1 is used for UART1 TX */
94 #define UART2CC32XX_PIN_02_UART1_RX  0x701 /*!< PIN 2 is used for UART1 RX */
95 #define UART2CC32XX_PIN_03_UART0_TX  0x702 /*!< PIN 3 is used for UART0 TX */
96 #define UART2CC32XX_PIN_04_UART0_RX  0x703 /*!< PIN 4 is used for UART0 RX */
97 #define UART2CC32XX_PIN_07_UART1_TX  0x506 /*!< PIN 7 is used for UART1 TX */
98 #define UART2CC32XX_PIN_08_UART1_RX  0x507 /*!< PIN 8 is used for UART1 RX */
99 #define UART2CC32XX_PIN_16_UART1_TX  0x20F /*!< PIN 16 is used for UART1 TX */
100 #define UART2CC32XX_PIN_17_UART1_RX  0x210 /*!< PIN 17 is used for UART1 RX */
101 #define UART2CC32XX_PIN_45_UART0_RX  0x92C /*!< PIN 45 is used for UART0 RX */
102 #define UART2CC32XX_PIN_45_UART1_RX  0x22C /*!< PIN 45 is used for UART1 RX */
103 #define UART2CC32XX_PIN_53_UART0_TX  0x934 /*!< PIN 53 is used for UART0 TX */
104 #define UART2CC32XX_PIN_55_UART0_TX  0x336 /*!< PIN 55 is used for UART0 TX */
105 #define UART2CC32XX_PIN_55_UART1_TX  0x636 /*!< PIN 55 is used for UART1 TX */
106 #define UART2CC32XX_PIN_57_UART0_RX  0x338 /*!< PIN 57 is used for UART0 RX */
107 #define UART2CC32XX_PIN_57_UART1_RX  0x638 /*!< PIN 57 is used for UART1 RX */
108 #define UART2CC32XX_PIN_58_UART1_TX  0x639 /*!< PIN 58 is used for UART1 TX */
109 #define UART2CC32XX_PIN_59_UART1_RX  0x63A /*!< PIN 59 is used for UART1 RX */
110 #define UART2CC32XX_PIN_62_UART0_TX  0xB3D /*!< PIN 62 is used for UART0 TX */
111 
112 /*
113  *  Flow control pins.
114  */
115 #define UART2CC32XX_PIN_50_UART0_CTS  0xC31 /*!< PIN 50 is used for UART0 CTS */
116 #define UART2CC32XX_PIN_50_UART0_RTS  0x331 /*!< PIN 50 is used for UART0 RTS */
117 #define UART2CC32XX_PIN_50_UART1_RTS  0xA31 /*!< PIN 50 is used for UART1 RTS */
118 #define UART2CC32XX_PIN_52_UART0_RTS  0x633 /*!< PIN 52 is used for UART0 RTS */
119 #define UART2CC32XX_PIN_61_UART0_RTS  0x53C /*!< PIN 61 is used for UART0 RTS */
120 #define UART2CC32XX_PIN_61_UART0_CTS  0x63C /*!< PIN 61 is used for UART0 CTS */
121 #define UART2CC32XX_PIN_61_UART1_CTS  0x33C /*!< PIN 61 is used for UART1 CTS */
122 #define UART2CC32XX_PIN_62_UART0_RTS  0xA3D /*!< PIN 62 is used for UART0 RTS */
123 #define UART2CC32XX_PIN_62_UART1_RTS  0x33D /*!< PIN 62 is used for UART1 RTS */
124 
125 /*!
126  * @brief No hardware flow control
127  */
128 #define UART2CC32XX_FLOWCTRL_NONE 0
129 
130 /*!
131  * @brief Hardware flow control
132  */
133 #define UART2CC32XX_FLOWCTRL_HARDWARE 1
134 
135 /*!
136  *  @brief    UART TX/RX interrupt FIFO threshold select
137  *
138  *  Defined FIFO thresholds for generation of both TX interrupt and RX
139  *  interrupt.  If the RX and TX FIFO and thresholds are not set in the
140  *  HwAttrs, the RX interrupt FIFO threshold is set to 1/8 full, and the
141  *  TX interrupt FIFO threshold is set to 1/8 full.
142  */
143 typedef enum {
144     UART2CC32XX_FIFO_THRESHOLD_1_8 = 0,     /*!< FIFO threshold of 1/8 full */
145     UART2CC32XX_FIFO_THRESHOLD_2_8 = 1,     /*!< FIFO threshold of 2/8 full */
146     UART2CC32XX_FIFO_THRESHOLD_4_8 = 2,     /*!< FIFO threshold of 4/8 full */
147     UART2CC32XX_FIFO_THRESHOLD_6_8 = 3,     /*!< FIFO threshold of 6/8 full */
148     UART2CC32XX_FIFO_THRESHOLD_7_8 = 4      /*!< FIFO threshold of 7/8 full */
149 } UART2CC32XX_FifoThreshold;
150 
151 /* UART2CC32XX functions */
152 extern void UART2CC32XX_close(UART2_Handle handle);
153 extern UART2_Handle UART2CC32XX_open(uint_least8_t, UART2_Params *params);
154 extern int_fast16_t UART2CC32XX_read(UART2_Handle handle, void *buffer,
155         size_t size, size_t *bytesRead, uint32_t timeout);
156 extern void UART2CC32XX_readCancel(UART2_Handle handle);
157 extern int_fast16_t UART2CC32XX_write(UART2_Handle handle,
158         const void *buffer, size_t size, size_t *bytesWritten,
159         uint32_t timeout);
160 extern void UART2CC32XX_writeCancel(UART2_Handle handle);
161 extern void UART2CC32XX_flushRx(UART2_Handle handle);
162 
163 /* UART2 function table pointer */
164 extern const UART2_FxnTable UART2CC32XX_fxnTable;
165 
166 /*!
167  *  @brief      UART2CC32XX Hardware attributes
168  *
169  *  The fields, baseAddr and intNum are used by driverlib
170  *  APIs and therefore must be populated by
171  *  driverlib macro definitions. These definitions are found under the
172  *  device family in:
173  *      - inc/hw_memmap.h
174  *      - inc/hw_ints.h
175  *      - driverlib/uart.h
176  *
177  *  intPriority is the UART peripheral's interrupt priority, as defined by the
178  *  underlying OS.  It is passed unmodified to the underlying OS's interrupt
179  *  handler creation code, so you need to refer to the OS documentation
180  *  for usage.  For example, for SYS/BIOS applications, refer to the
181  *  ti.sysbios.family.arm.m3.Hwi documentation for SYS/BIOS usage of
182  *  interrupt priorities.  If the driver uses the ti.dpl interface
183  *  instead of making OS calls directly, then the HwiP port handles the
184  *  interrupt priority in an OS specific way.  In the case of the SYS/BIOS
185  *  port, intPriority is passed unmodified to Hwi_create().
186  *  The CC32XX uses three of the priority bits, meaning ~0 has the same
187  *  effect as (7 << 5).
188  *
189  *        (7 << 5) will apply the lowest priority.
190  *        (1 << 5) will apply the highest priority.
191  *
192  *  Setting the priority to 0 is not supported by this driver.  HWI's with
193  *  priority 0 ignore the HWI dispatcher to support zero-latency interrupts,
194  *  thus invalidating the critical sections in this driver.
195  *
196  *  A sample structure is shown below:
197  *  @code
198  *  const UART2CC32XX_HWAttrs UART2CC32XXHWAttrs[] = {
199  *      {
200  *          .baseAddr     = UARTA0_BASE,
201  *          .intNum       = INT_UARTA0,
202  *          .intPriority  = (~0),
203  *          .flowControl  = UART2CC32XX_FLOWCTRL_NONE,
204  *          .rxPin        = UART2CC32XX_PIN_57_UART0_RX,
205  *          .txPin        = UART2CC32XX_PIN_55_UART0_TX,
206  *          .ctsPin       = UART2CC32XX_PIN_UNASSIGNED,
207  *          .rtsPin       = UART2CC32XX_PIN_UNASSIGNED,
208  *          .txIntFifoThr = UART2CC32XX_FIFO_THRESHOLD_1_8,
209  *          .rxIntFifoThr = UART2CC32XX_FIFO_THRESHOLD_4_8,
210  *          .rxDmaChannel = UDMA_CH8_UARTA0_RX,
211  *          .txDmaChannel = UDMA_CH9_UARTA0_TX,
212  *      },
213  *      {
214  *          .baseAddr     = UARTA1_BASE,
215  *          .intNum       = INT_UARTA1,
216  *          .intPriority  = (~0),
217  *          .flowControl  = UART2CC32XX_FLOWCTRL_NONE,
218  *          .rxPin        = UART2CC32XX_PIN_08_UART1_RX,
219  *          .txPin        = UART2CC32XX_PIN_07_UART1_TX,
220  *          .ctsPin       = UART2CC32XX_PIN_UNASSIGNED,
221  *          .rtsPin       = UART2CC32XX_PIN_UNASSIGNED,
222  *          .txIntFifoThr = UART2CC32XX_FIFO_THRESHOLD_1_8,
223  *          .rxIntFifoThr = UART2CC32XX_FIFO_THRESHOLD_4_8,
224  *          .rxDmaChannel = UDMA_CH10_UARTA1_RX,
225  *          .txDmaChannel = UDMA_CH11_UARTA1_TX,
226  *      },
227  *  };
228  *  @endcode
229  *
230  *  To enable flow control, the .ctsPin and/or .rtsPin must be assigned.
231  *  In addition, .flowControl must be set to UART2CC32XX_FLOWCTL_HARDWARE.
232  */
233 typedef struct {
234     /*! UART Peripheral's base address */
235     uint32_t        baseAddr;
236     /*! UART Peripheral's interrupt vector */
237     int             intNum;
238     /*! UART Peripheral's interrupt priority */
239     uint8_t         intPriority;
240     /*! Hardware flow control setting */
241     uint32_t        flowControl;
242     /*! UART RX pin assignment */
243     uint32_t         rxPin;
244     /*! UART TX pin assignment */
245     uint32_t         txPin;
246     /*! UART clear to send (CTS) pin assignment */
247     uint32_t         ctsPin;
248     /*! UART request to send (RTS) pin assignment */
249     uint32_t         rtsPin;
250     /*! UART TX interrupt FIFO threshold select */
251     UART2CC32XX_FifoThreshold txIntFifoThr;
252     /*! UART RX interrupt FIFO threshold select */
253     UART2CC32XX_FifoThreshold rxIntFifoThr;
254     /*! uDMA channel for RX data */
255     uint32_t  rxDmaChannel;
256     /*! uDMA channel for TX data */
257     uint32_t  txDmaChannel;
258 } UART2CC32XX_HWAttrs;
259 
260 /*!
261  *  @brief      UART2CC32XX Object
262  *
263  *  The application must not access any member variables of this structure!
264  */
265 typedef struct {
266     /* UART2 state variable */
267     struct {
268         bool             opened:1;         /* Has the obj been opened */
269         UART2_Mode       readMode;         /* Mode for read calls */
270         UART2_Mode       writeMode;        /* Mode for write calls */
271         UART2_ReadReturnMode readReturnMode:1; /* RX return mode (partial/full) */
272         bool             txEnabled:1;      /* Flag to show ongoing transmit */
273     } state;
274 
275     HwiP_Handle          hwi;              /* Hwi object for interrupts */
276     uint32_t             baudRate;         /* Baud rate for UART */
277     UART2_DataLen        dataLength;       /* Data length for UART */
278     UART2_StopBits       stopBits;         /* Stop bits for UART */
279     UART2_Parity         parityType;       /* Parity bit type for UART */
280     int32_t              rxStatus;         /* RX status */
281     int32_t              txStatus;         /* TX status */
282     void                *userArg;          /* User supplied arg for callbacks */
283     UDMACC32XX_Handle    udmaHandle;       /* For setting power dependency */
284 
285     /* UART read variables */
286     unsigned char       *readBuf;          /* Buffer data pointer */
287     size_t               readSize;         /* Number of bytes to read */
288     uint32_t             nReadTransfers;   /* Number of DMA transfers needed */
289     size_t               readCount;        /* Number of bytes left to read */
290     size_t               rxSize;           /* # of bytes to read in DMA xfer */
291     size_t               bytesRead;        /* Number of bytes read */
292     SemaphoreP_Handle    readSem;          /* UART read semaphore */
293     UART2_Callback       readCallback;     /* Pointer to read callback */
294 
295     /* UART write variables */
296     const unsigned char *writeBuf;         /* Buffer data pointer */
297     size_t               writeSize;        /* Number of bytes to write*/
298     uint32_t             nWriteTransfers;  /* Number of DMA transfers needed */
299     size_t               writeCount;       /* Number of bytes left to write */
300     size_t               txSize;           /* # of bytes to write with DMA */
301     size_t               bytesWritten;     /* Number of bytes written */
302     SemaphoreP_Handle    writeSem;         /* UART write semaphore*/
303     UART2_Callback       writeCallback;    /* Pointer to write callback */
304 
305     /* For Power management */
306     Power_NotifyObj       postNotify;
307     unsigned int          powerMgrId;      /* Determined from base address */
308     PowerCC32XX_ParkState prevParkTX;      /* Previous park state TX pin */
309     uint16_t              txPin;           /* TX pin ID */
310     PowerCC32XX_ParkState prevParkRTS;     /* Previous park state of RTS pin */
311     uint16_t              rtsPin;          /* RTS pin ID */
312 } UART2CC32XX_Object, *UART2CC32XX_Handle;
313 
314 #ifdef __cplusplus
315 }
316 #endif
317 
318 #endif /* ti_drivers_uart2_UART2CC32XX__include */
319