1 /*
2  * Copyright (c) 2015-2019, 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       UARTCC32XX.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/UART.h>
40  *  #include <ti/drivers/uart/UARTCC32XX.h>
41  *  @endcode
42  *
43  *  Refer to @ref UART.h for a complete description of APIs & example of use.
44  *
45  *  # Device Specific Pin Mode Macros #
46  *  This header file contains pin mode definitions used to specify the
47  *  UART TX and RX pin assignment in the UARTCC32XX_HWAttrsV1 structure.
48  *  Please refer to the CC32XX Techincal Reference Manual for details on pin
49  *  multiplexing.
50  *
51  *  # Flow Control #
52  *  To enable Flow Control, the RTS and CTS pins must be assigned in the
53  *  ::UARTCC32XX_HWAttrsV1.
54  *
55  *  ============================================================================
56  */
57 
58 #ifndef ti_drivers_uart_UARTCC32XX__include
59 #define ti_drivers_uart_UARTCC32XX__include
60 
61 #include <stdint.h>
62 #include <stdbool.h>
63 
64 #include <ti/drivers/dpl/ClockP.h>
65 #include <ti/drivers/dpl/HwiP.h>
66 #include <ti/drivers/dpl/SemaphoreP.h>
67 #include <ti/drivers/Power.h>
68 #include <ti/drivers/power/PowerCC32XX.h>
69 #include <ti/drivers/UART.h>
70 #include <ti/drivers/utils/RingBuf.h>
71 
72 #ifdef __cplusplus
73 extern "C" {
74 #endif
75 
76 /*!
77  * @brief Indicates a pin is not being used
78  *
79  *  If hardware flow control is not being used, the UART CTS and RTS
80  *  pins should be set to UARTCC32XX_PIN_UNASSIGNED.
81  */
82 #define UARTCC32XX_PIN_UNASSIGNED   0xFFF
83 
84 /*
85  *  The bits in the pin mode macros are as follows:
86  *  The lower 8 bits of the macro refer to the pin, offset by 1, to match
87  *  driverlib pin defines.  For example, UARTCC32XX_PIN_01_UART1_TX & 0xff = 0,
88  *  which equals PIN_01 in driverlib pin.h.  By matching the PIN_xx defines in
89  *  driverlib pin.h, we can pass the pin directly to the driverlib functions.
90  *  The upper 8 bits of the macro correspond to the pin mux confg mode
91  *  value for the pin to operate in the UART mode.  For example, pin 1 is
92  *  configured with mode 7 to operate as UART1 TX.
93  */
94 #define UARTCC32XX_PIN_01_UART1_TX  0x700 /*!< PIN 1 is used for UART1 TX */
95 #define UARTCC32XX_PIN_02_UART1_RX  0x701 /*!< PIN 2 is used for UART1 RX */
96 #define UARTCC32XX_PIN_03_UART0_TX  0x702 /*!< PIN 3 is used for UART0 TX */
97 #define UARTCC32XX_PIN_04_UART0_RX  0x703 /*!< PIN 4 is used for UART0 RX */
98 #define UARTCC32XX_PIN_07_UART1_TX  0x506 /*!< PIN 7 is used for UART1 TX */
99 #define UARTCC32XX_PIN_08_UART1_RX  0x507 /*!< PIN 8 is used for UART1 RX */
100 #define UARTCC32XX_PIN_16_UART1_TX  0x20F /*!< PIN 16 is used for UART1 TX */
101 #define UARTCC32XX_PIN_17_UART1_RX  0x210 /*!< PIN 17 is used for UART1 RX */
102 #define UARTCC32XX_PIN_45_UART0_RX  0x92C /*!< PIN 45 is used for UART0 RX */
103 #define UARTCC32XX_PIN_45_UART1_RX  0x22C /*!< PIN 45 is used for UART1 RX */
104 #define UARTCC32XX_PIN_53_UART0_TX  0x934 /*!< PIN 53 is used for UART0 TX */
105 #define UARTCC32XX_PIN_55_UART0_TX  0x336 /*!< PIN 55 is used for UART0 TX */
106 #define UARTCC32XX_PIN_55_UART1_TX  0x636 /*!< PIN 55 is used for UART1 TX */
107 #define UARTCC32XX_PIN_57_UART0_RX  0x338 /*!< PIN 57 is used for UART0 RX */
108 #define UARTCC32XX_PIN_57_UART1_RX  0x638 /*!< PIN 57 is used for UART1 RX */
109 #define UARTCC32XX_PIN_58_UART1_TX  0x639 /*!< PIN 58 is used for UART1 TX */
110 #define UARTCC32XX_PIN_59_UART1_RX  0x63A /*!< PIN 59 is used for UART1 RX */
111 #define UARTCC32XX_PIN_62_UART0_TX  0xB3D /*!< PIN 62 is used for UART0 TX */
112 
113 /*
114  *  Flow control pins.
115  */
116 #define UARTCC32XX_PIN_50_UART0_CTS  0xC31 /*!< PIN 50 is used for UART0 CTS */
117 #define UARTCC32XX_PIN_50_UART0_RTS  0x331 /*!< PIN 50 is used for UART0 RTS */
118 #define UARTCC32XX_PIN_50_UART1_RTS  0xA31 /*!< PIN 50 is used for UART1 RTS */
119 #define UARTCC32XX_PIN_52_UART0_RTS  0x633 /*!< PIN 52 is used for UART0 RTS */
120 #define UARTCC32XX_PIN_61_UART0_RTS  0x53C /*!< PIN 61 is used for UART0 RTS */
121 #define UARTCC32XX_PIN_61_UART0_CTS  0x63C /*!< PIN 61 is used for UART0 CTS */
122 #define UARTCC32XX_PIN_61_UART1_CTS  0x33C /*!< PIN 61 is used for UART1 CTS */
123 #define UARTCC32XX_PIN_62_UART0_RTS  0xA3D /*!< PIN 62 is used for UART0 RTS */
124 #define UARTCC32XX_PIN_62_UART1_RTS  0x33D /*!< PIN 62 is used for UART1 RTS */
125 
126 /*!
127  * @brief No hardware flow control
128  */
129 #define UARTCC32XX_FLOWCTRL_NONE 0
130 
131 /*!
132  * @brief Hardware flow control
133  */
134 #define UARTCC32XX_FLOWCTRL_HARDWARE 1
135 
136 /**
137  *  @addtogroup UART_STATUS
138  *  UARTCC32XX_STATUS_* macros are command codes only defined in the
139  *  UARTCC32XX.h driver implementation and need to:
140  *  @code
141  *  #include <ti/drivers/uart/UARTCC32XX.h>
142  *  @endcode
143  *  @{
144  */
145 
146 /* Add UARTCC32XX_STATUS_* macros here */
147 
148 /** @}*/
149 
150 /**
151  *  @addtogroup UART_CMD
152  *  UARTCC32XX_CMD_* macros are command codes only defined in the
153  *  UARTCC32XX.h driver implementation and need to:
154  *  @code
155  *  #include <ti/drivers/uart/UARTCC32XX.h>
156  *  @endcode
157  *  @{
158  */
159 
160 /*!
161  * @brief Command used by UART_control to determines
162  * whether the UART transmitter is busy or not
163  *
164  * With this command code, @b arg is a pointer to a @c bool.
165  * @b *arg contains @c true if the UART is transmitting,
166  * else @c false if all transmissions are complete.
167  */
168 #define UARTCC32XX_CMD_IS_BUSY                  (UART_CMD_RESERVED + 0)
169 
170 
171 /*!
172  * @brief Command used by UART_control to determines
173  * if there are any characters in the receive FIFO
174  *
175  * With this command code, @b arg is a pointer to a @c bool.
176  * @b *arg contains @c true if there is data in the receive FIFO,
177  * or @c false if there is no data in the receive FIFO.
178  */
179 #define UARTCC32XX_CMD_IS_RX_DATA_AVAILABLE     (UART_CMD_RESERVED + 1)
180 
181 
182 /*!
183  * @brief Command used by UART_control to determines
184  * if there is any space in the transmit FIFO
185  *
186  * With this command code, @b arg is a pointer to a @c bool.
187  * @b *arg contains @c true if there is space available in the transmit FIFO,
188  * or @c false if there is no space available in the transmit FIFO.
189  */
190 #define UARTCC32XX_CMD_IS_TX_SPACE_AVAILABLE    (UART_CMD_RESERVED + 2)
191 
192 
193 /** @}*/
194 
195 /* UART function table pointer */
196 extern const UART_FxnTable UARTCC32XX_fxnTable;
197 
198 /*!
199  *  @brief Complement set of read functions to be used by the UART ISR and
200  *         UARTCC32XX_read(). Internal use only.
201  *
202  *  These functions are solely intended for the UARTCC32XX driver, and should
203  *  not be used by the application.
204  *  The UARTCC32XX_FxnSet is a pair of complement functions that are design to
205  *  operate with one another in a task context and in an ISR context. The
206  *  readTaskFxn is called by UARTCC32XX_read() to drain a circular buffer,
207  *  whereas the readIsrFxn is used by the UARTCC32XX_hwiIntFxn to fill up the
208  *  circular buffer.
209  *
210  *  readTaskFxn:    Function called by UART read
211  *                  These variables are set and avilalable for use to the
212  *                  readTaskFxn.
213  *                  object->readBuf = buffer; //Pointer to a user buffer
214  *                  object->readSize = size;  //Desired no. of bytes to read
215  *                  object->readCount = size; //Remaining no. of bytes to read
216  *
217  *  readIsrFxn:     The required ISR counterpart to readTaskFxn
218  */
219 typedef struct {
220     bool (*readIsrFxn)  (UART_Handle handle);
221     int  (*readTaskFxn) (UART_Handle handle);
222 } UARTCC32XX_FxnSet;
223 
224 /*!
225  *  @brief      The definition of an optional callback function used by the UART
226  *              driver to notify the application when a receive error (FIFO overrun,
227  *              parity error, etc) occurs.
228  *
229  *  @param      UART_Handle             UART_Handle
230  *
231  *  @param      error                   The current value of the receive
232  *                                      status register.  Please refer to the
233  *                                      device data sheet to interpret this
234  *                                      value.
235  */
236 typedef void (*UARTCC32XX_ErrorCallback) (UART_Handle handle, uint32_t error);
237 
238 /*!
239  *  @brief      UARTCC32XX Hardware attributes
240  *
241  *  The fields, baseAddr, intNum, and flowControl, are used by driverlib
242  *  APIs and therefore must be populated by
243  *  driverlib macro definitions. For CC32XXWare these definitions are found in:
244  *      - inc/hw_memmap.h
245  *      - inc/hw_ints.h
246  *      - driverlib/uart.h
247  *
248  *  intPriority is the UART peripheral's interrupt priority, as defined by the
249  *  underlying OS.  It is passed unmodified to the underlying OS's interrupt
250  *  handler creation code, so you need to refer to the OS documentation
251  *  for usage.  For example, for SYS/BIOS applications, refer to the
252  *  ti.sysbios.family.arm.m3.Hwi documentation for SYS/BIOS usage of
253  *  interrupt priorities.  If the driver uses the ti.dpl interface
254  *  instead of making OS calls directly, then the HwiP port handles the
255  *  interrupt priority in an OS specific way.  In the case of the SYS/BIOS
256  *  port, intPriority is passed unmodified to Hwi_create().
257  *
258  *  A sample structure is shown below:
259  *  @code
260  *  unsigned char uartCC32XXRingBuffer[2][32];
261  *
262  *  const UARTCC32XX_HWAttrsV1 uartCC32XXHWAttrs[] = {
263  *      {
264  *          .baseAddr = UARTA0_BASE,
265  *          .intNum = INT_UARTA0,
266  *          .intPriority = (~0),
267  *          .flowControl = UARTCC32XX_FLOWCTRL_NONE,
268  *          .ringBufPtr  = uartCC32XXRingBuffer[0],
269  *          .ringBufSize = sizeof(uartCC32XXRingBuffer[0]),
270  *          .rxPin = UARTCC32XX_PIN_57_UART0_RX,
271  *          .txPin = UARTCC32XX_PIN_55_UART0_TX,
272  *          .rtsPin = UARTCC32XX_PIN_UNASSIGNED,
273  *          .ctsPin = UARTCC32XX_PIN_UNASSIGNED,
274  *          .errorFxn = NULL
275  *      },
276  *      {
277  *          .baseAddr = UARTA1_BASE,
278  *          .intNum = INT_UARTA1,
279  *          .intPriority = (~0),
280  *          .flowControl = UARTCC32XX_FLOWCTRL_HARDWARE,
281  *          .ringBufPtr  = uartCC32XXRingBuffer[1],
282  *          .ringBufSize = sizeof(uartCC32XXRingBuffer[1]),
283  *          .rxPin = UARTCC32XX_PIN_08_UART1_RX,
284  *          .txPin = UARTCC32XX_PIN_07_UART1_TX,
285  *          .rtsPin = UARTCC32XX_PIN_50_UART1_RTS,
286  *          .ctsPin = UARTCC32XX_PIN_61_UART1_CTS,
287  *          .errorFxn = NULL
288  *      },
289  *  };
290  *  @endcode
291  */
292 typedef struct {
293     /*! UART Peripheral's base address */
294     unsigned int    baseAddr;
295     /*! UART Peripheral's interrupt vector */
296     unsigned int    intNum;
297     /*! UART Peripheral's interrupt priority */
298     unsigned int    intPriority;
299     /*! Hardware flow control setting defined by driverlib */
300     uint32_t        flowControl;
301     /*! Pointer to an application ring buffer */
302     unsigned char  *ringBufPtr;
303     /*! Size of ringBufPtr */
304     size_t          ringBufSize;
305     /*! UART RX pin assignment */
306     uint16_t        rxPin;
307     /*! UART TX pin assignment */
308     uint16_t        txPin;
309     /*! UART clear to send (CTS) pin assignment */
310     uint16_t        ctsPin;
311     /*! UART request to send (RTS) pin assignment */
312     uint16_t        rtsPin;
313     /*! Application error function to be called on receive errors */
314     UARTCC32XX_ErrorCallback errorFxn;
315 } UARTCC32XX_HWAttrsV1;
316 
317 /*!
318  *  @brief      UARTCC32XX Object
319  *
320  *  The application must not access any member variables of this structure!
321  */
322 typedef struct {
323     /* UART state variable */
324     struct {
325         bool             opened:1;         /* Has the obj been opened */
326         UART_Mode        readMode:1;       /* Mode for all read calls */
327         UART_Mode        writeMode:1;      /* Mode for all write calls */
328         UART_DataMode    readDataMode:1;   /* Type of data being read */
329         UART_DataMode    writeDataMode:1;  /* Type of data being written */
330         UART_ReturnMode  readReturnMode:1; /* Receive return mode */
331         UART_Echo        readEcho:1;       /* Echo received data back */
332         /*
333          * Flag to determine if a timeout has occurred when the user called
334          * UART_read(). This flag is set by the timeoutClk clock object.
335          */
336         bool             bufTimeout:1;
337         /*
338          * Flag to determine when an ISR needs to perform a callback; in both
339          * UART_MODE_BLOCKING or UART_MODE_CALLBACK
340          */
341         bool             callCallback:1;
342         /*
343          * Flag to determine if the ISR is in control draining the ring buffer
344          * when in UART_MODE_CALLBACK
345          */
346         bool             drainByISR:1;
347         /* Flag to keep the state of the read Power constraints */
348         bool             rxEnabled:1;
349         /* Flag to keep the state of the write Power constraints */
350         bool             txEnabled:1;
351 
352         /* Flags to prevent recursion in read callback mode */
353         bool             inReadCallback:1;
354         volatile bool    readCallbackPending:1;
355     } state;
356 
357     HwiP_Handle          hwiHandle;        /* Hwi handle for interrupts */
358     ClockP_Handle        timeoutClk;       /* Clock object to for timeouts */
359     uint32_t             baudRate;         /* Baud rate for UART */
360     UART_LEN             dataLength;       /* Data length for UART */
361     UART_STOP            stopBits;         /* Stop bits for UART */
362     UART_PAR             parityType;       /* Parity bit type for UART */
363 
364     /* UART read variables */
365     RingBuf_Object       ringBuffer;       /* local circular buffer object */
366     /* A complement pair of read functions for both the ISR and UART_read() */
367     UARTCC32XX_FxnSet    readFxns;
368     unsigned char       *readBuf;          /* Buffer data pointer */
369     size_t               readSize;         /* Desired number of bytes to read */
370     size_t               readCount;        /* Number of bytes left to read */
371     SemaphoreP_Handle    readSem;          /* UART read semaphore */
372     unsigned int         readTimeout;      /* Timeout for read semaphore */
373     UART_Callback        readCallback;     /* Pointer to read callback */
374 
375     /* UART write variables */
376     const unsigned char *writeBuf;         /* Buffer data pointer */
377     size_t               writeSize;        /* Desired number of bytes to write*/
378     size_t               writeCount;       /* Number of bytes left to write */
379     SemaphoreP_Handle    writeSem;         /* UART write semaphore*/
380     unsigned int         writeTimeout;     /* Timeout for write semaphore */
381     UART_Callback        writeCallback;    /* Pointer to write callback */
382 
383     /* For Power management */
384     Power_NotifyObj       postNotify;      /* LPDS wake-up notify object */
385     unsigned int          powerMgrId;      /* Determined from base address */
386     PowerCC32XX_ParkState prevParkTX;      /* Previous park state TX pin */
387     uint16_t              txPin;           /* TX pin ID */
388     PowerCC32XX_ParkState prevParkRTS;     /* Previous park state of RTS pin */
389     uint16_t              rtsPin;           /* RTS pin ID */
390 } UARTCC32XX_Object, *UARTCC32XX_Handle;
391 
392 #ifdef __cplusplus
393 }
394 #endif
395 
396 #endif /* ti_drivers_uart_UARTCC32XX__include */
397