1 /*
2  * @brief LPC15XX USART0/1/2 driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2013
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products.  This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #ifndef __UART_15XX_H_
33 #define __UART_15XX_H_
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 #include "ring_buffer.h"
40 
41 /** @defgroup UART_15XX CHIP: LPC15xx USART Driver (UARTS 0/1/2)
42  * @ingroup CHIP_15XX_Drivers
43  * @{
44  */
45 
46 /**
47  * @brief UART register block structure
48  */
49 typedef struct {
50 	__IO uint32_t  CFG;				/*!< Configuration register */
51 	__IO uint32_t  CTRL;			/*!< Control register */
52 	__IO uint32_t  STAT;			/*!< Status register */
53 	__IO uint32_t  INTENSET;		/*!< Interrupt Enable read and set register */
54 	__O  uint32_t  INTENCLR;		/*!< Interrupt Enable clear register */
55 	__I  uint32_t  RXDATA;			/*!< Receive Data register */
56 	__I  uint32_t  RXDATA_STAT;		/*!< Receive Data with status register */
57 	__IO uint32_t  TXDATA;			/*!< Transmit data register */
58 	__IO uint32_t  BRG;				/*!< Baud Rate Generator register */
59 	__IO uint32_t  INTSTAT;			/*!< Interrupt status register */
60 } LPC_USART_T;
61 
62 /**
63  * @brief UART CFG register definitions
64  */
65 #define UART_CFG_ENABLE         (0x01 << 0)
66 #define UART_CFG_DATALEN_7      (0x00 << 2)	/*!< UART 7 bit length mode */
67 #define UART_CFG_DATALEN_8      (0x01 << 2)	/*!< UART 8 bit length mode */
68 #define UART_CFG_DATALEN_9      (0x02 << 2)	/*!< UART 9 bit length mode */
69 #define UART_CFG_PARITY_NONE    (0x00 << 4)	/*!< No parity */
70 #define UART_CFG_PARITY_EVEN    (0x02 << 4)	/*!< Even parity */
71 #define UART_CFG_PARITY_ODD     (0x03 << 4)	/*!< Odd parity */
72 #define UART_CFG_STOPLEN_1      (0x00 << 6)	/*!< UART One Stop Bit Select */
73 #define UART_CFG_STOPLEN_2      (0x01 << 6)	/*!< UART Two Stop Bits Select */
74 #define UART_MODE_32K           (0x01 << 7)	/*!< Selects the 32 kHz clock from the RTC oscillator as the clock source to the BRG */
75 #define UART_CFG_CTSEN          (0x01 << 9)	/*!< CTS enable bit */
76 #define UART_CFG_SYNCEN         (0x01 << 11)	/*!< Synchronous mode enable bit */
77 #define UART_CFG_CLKPOL         (0x01 << 12)	/*!< Un_RXD rising edge sample enable bit */
78 #define UART_CFG_SYNCMST        (0x01 << 14)	/*!< Select master mode (synchronous mode) enable bit */
79 #define UART_CFG_LOOP           (0x01 << 15)	/*!< Loopback mode enable bit */
80 
81 /**
82  * @brief UART CTRL register definitions
83  */
84 #define UART_CTRL_TXBRKEN       (0x01 << 1)		/*!< Continuous break enable bit */
85 #define UART_CTRL_ADDRDET       (0x01 << 2)		/*!< Address detect mode enable bit */
86 #define UART_CTRL_TXDIS         (0x01 << 6)		/*!< Transmit disable bit */
87 #define UART_CTRL_CC            (0x01 << 8)		/*!< Continuous Clock mode enable bit */
88 #define UART_CTRL_CLRCC         (0x01 << 9)		/*!< Clear Continuous Clock bit */
89 
90 /**
91  * @brief UART STAT register definitions
92  */
93 #define UART_STAT_RXRDY         (0x01 << 0)			/*!< Receiver ready */
94 #define UART_STAT_RXIDLE        (0x01 << 1)			/*!< Receiver idle */
95 #define UART_STAT_TXRDY         (0x01 << 2)			/*!< Transmitter ready for data */
96 #define UART_STAT_TXIDLE        (0x01 << 3)			/*!< Transmitter idle */
97 #define UART_STAT_CTS           (0x01 << 4)			/*!< Status of CTS signal */
98 #define UART_STAT_DELTACTS      (0x01 << 5)			/*!< Change in CTS state */
99 #define UART_STAT_TXDISINT      (0x01 << 6)			/*!< Transmitter disabled */
100 #define UART_STAT_OVERRUNINT    (0x01 << 8)			/*!< Overrun Error interrupt flag. */
101 #define UART_STAT_RXBRK         (0x01 << 10)		/*!< Received break */
102 #define UART_STAT_DELTARXBRK    (0x01 << 11)		/*!< Change in receive break detection */
103 #define UART_STAT_START         (0x01 << 12)		/*!< Start detected */
104 #define UART_STAT_FRM_ERRINT    (0x01 << 13)		/*!< Framing Error interrupt flag */
105 #define UART_STAT_PAR_ERRINT    (0x01 << 14)		/*!< Parity Error interrupt flag */
106 #define UART_STAT_RXNOISEINT    (0x01 << 15)		/*!< Received Noise interrupt flag */
107 
108 /**
109  * @brief UART INTENSET/INTENCLR register definitions
110  */
111 #define UART_INTEN_RXRDY        (0x01 << 0)			/*!< Receive Ready interrupt */
112 #define UART_INTEN_TXRDY        (0x01 << 2)			/*!< Transmit Ready interrupt */
113 #define UART_INTEN_DELTACTS     (0x01 << 5)			/*!< Change in CTS state interrupt */
114 #define UART_INTEN_TXDIS        (0x01 << 6)			/*!< Transmitter disable interrupt */
115 #define UART_INTEN_OVERRUN      (0x01 << 8)			/*!< Overrun error interrupt */
116 #define UART_INTEN_DELTARXBRK   (0x01 << 11)		/*!< Change in receiver break detection interrupt */
117 #define UART_INTEN_START        (0x01 << 12)		/*!< Start detect interrupt */
118 #define UART_INTEN_FRAMERR      (0x01 << 13)		/*!< Frame error interrupt */
119 #define UART_INTEN_PARITYERR    (0x01 << 14)		/*!< Parity error interrupt */
120 #define UART_INTEN_RXNOISE      (0x01 << 15)		/*!< Received noise interrupt */
121 
122 /**
123  * @brief	Enable the UART
124  * @param	pUART		: Pointer to selected UARTx peripheral
125  * @return	Nothing
126  */
Chip_UART_Enable(LPC_USART_T * pUART)127 STATIC INLINE void Chip_UART_Enable(LPC_USART_T *pUART)
128 {
129 	pUART->CFG |= UART_CFG_ENABLE;
130 }
131 
132 /**
133  * @brief	Disable the UART
134  * @param	pUART	: Pointer to selected UARTx peripheral
135  * @return	Nothing
136  */
Chip_UART_Disable(LPC_USART_T * pUART)137 STATIC INLINE void Chip_UART_Disable(LPC_USART_T *pUART)
138 {
139 	pUART->CFG &= ~UART_CFG_ENABLE;
140 }
141 
142 /**
143  * @brief	Enable transmission on UART TxD pin
144  * @param	pUART	: Pointer to selected pUART peripheral
145  * @return Nothing
146  */
Chip_UART_TXEnable(LPC_USART_T * pUART)147 STATIC INLINE void Chip_UART_TXEnable(LPC_USART_T *pUART)
148 {
149 	pUART->CTRL &= ~UART_CTRL_TXDIS;
150 }
151 
152 /**
153  * @brief	Disable transmission on UART TxD pin
154  * @param	pUART	: Pointer to selected pUART peripheral
155  * @return Nothing
156  */
Chip_UART_TXDisable(LPC_USART_T * pUART)157 STATIC INLINE void Chip_UART_TXDisable(LPC_USART_T *pUART)
158 {
159 	pUART->CTRL |= UART_CTRL_TXDIS;
160 }
161 
162 /**
163  * @brief	Transmit a single data byte through the UART peripheral
164  * @param	pUART	: Pointer to selected UART peripheral
165  * @param	data	: Byte to transmit
166  * @return	Nothing
167  * @note	This function attempts to place a byte into the UART transmit
168  *			holding register regard regardless of UART state.
169  */
Chip_UART_SendByte(LPC_USART_T * pUART,uint8_t data)170 STATIC INLINE void Chip_UART_SendByte(LPC_USART_T *pUART, uint8_t data)
171 {
172 	pUART->TXDATA = (uint32_t) data;
173 }
174 
175 /**
176  * @brief	Read a single byte data from the UART peripheral
177  * @param	pUART	: Pointer to selected UART peripheral
178  * @return	A single byte of data read
179  * @note	This function reads a byte from the UART receive FIFO or
180  *			receive hold register regard regardless of UART state. The
181  *			FIFO status should be read first prior to using this function
182  */
Chip_UART_ReadByte(LPC_USART_T * pUART)183 STATIC INLINE uint32_t Chip_UART_ReadByte(LPC_USART_T *pUART)
184 {
185 	/* Strip off undefined reserved bits, keep 9 lower bits */
186 	return (uint32_t) (pUART->RXDATA & 0x000001FF);
187 }
188 
189 /**
190  * @brief	Enable UART interrupts
191  * @param	pUART	: Pointer to selected UART peripheral
192  * @param	intMask	: OR'ed Interrupts to enable
193  * @return	Nothing
194  * @note	Use an OR'ed value of UART_INTEN_* definitions with this function
195  *			to enable specific UART interrupts.
196  */
Chip_UART_IntEnable(LPC_USART_T * pUART,uint32_t intMask)197 STATIC INLINE void Chip_UART_IntEnable(LPC_USART_T *pUART, uint32_t intMask)
198 {
199 	pUART->INTENSET = intMask;
200 }
201 
202 /**
203  * @brief	Disable UART interrupts
204  * @param	pUART	: Pointer to selected UART peripheral
205  * @param	intMask	: OR'ed Interrupts to disable
206  * @return	Nothing
207  * @note	Use an OR'ed value of UART_INTEN_* definitions with this function
208  *			to disable specific UART interrupts.
209  */
Chip_UART_IntDisable(LPC_USART_T * pUART,uint32_t intMask)210 STATIC INLINE void Chip_UART_IntDisable(LPC_USART_T *pUART, uint32_t intMask)
211 {
212 	pUART->INTENCLR = intMask;
213 }
214 
215 /**
216  * @brief	Returns UART interrupts that are enabled
217  * @param	pUART	: Pointer to selected UART peripheral
218  * @return	Returns the enabled UART interrupts
219  * @note	Use an OR'ed value of UART_INTEN_* definitions with this function
220  *			to determine which interrupts are enabled. You can check
221  *			for multiple enabled bits if needed.
222  */
Chip_UART_GetIntsEnabled(LPC_USART_T * pUART)223 STATIC INLINE uint32_t Chip_UART_GetIntsEnabled(LPC_USART_T *pUART)
224 {
225 	return pUART->INTENSET;
226 }
227 
228 /**
229  * @brief	Get UART interrupt status
230  * @param	pUART	: The base of UART peripheral on the chip
231  * @return	The Interrupt status register of UART
232  * @note	Multiple interrupts may be pending. Mask the return value
233  *			with one or more UART_INTEN_* definitions to determine
234  *			pending interrupts.
235  */
Chip_UART_GetIntStatus(LPC_USART_T * pUART)236 STATIC INLINE uint32_t Chip_UART_GetIntStatus(LPC_USART_T *pUART)
237 {
238 	return pUART->INTSTAT;
239 }
240 
241 /**
242  * @brief	Configure data width, parity and stop bits
243  * @param	pUART	: Pointer to selected pUART peripheral
244  * @param	config	: UART configuration, OR'ed values of select UART_CFG_* defines
245  * @return	Nothing
246  * @note	Select OR'ed config options for the UART from the UART_CFG_PARITY_*,
247  *			UART_CFG_STOPLEN_*, and UART_CFG_DATALEN_* definitions. For example,
248  *			a configuration of 8 data bits, 1 stop bit, and even (enabled) parity would be
249  *			(UART_CFG_DATALEN_8 | UART_CFG_STOPLEN_1 | UART_CFG_PARITY_EVEN). Will not
250  *			alter other bits in the CFG register.
251  */
Chip_UART_ConfigData(LPC_USART_T * pUART,uint32_t config)252 STATIC INLINE void Chip_UART_ConfigData(LPC_USART_T *pUART, uint32_t config)
253 {
254 	uint32_t reg;
255 
256 	reg = pUART->CFG & ~((0x3 << 2) | (0x3 << 4) | (0x1 << 6));
257 	pUART->CFG = reg | config;
258 }
259 
260 /**
261  * @brief	Get the UART status register
262  * @param	pUART	: Pointer to selected UARTx peripheral
263  * @return	UART status register
264  * @note	Multiple statuses may be pending. Mask the return value
265  *			with one or more UART_STAT_* definitions to determine
266  *			statuses.
267  */
Chip_UART_GetStatus(LPC_USART_T * pUART)268 STATIC INLINE uint32_t Chip_UART_GetStatus(LPC_USART_T *pUART)
269 {
270 	return pUART->STAT;
271 }
272 
273 /**
274  * @brief	Clear the UART status register
275  * @param	pUART	: Pointer to selected UARTx peripheral
276  * @param	stsMask	: OR'ed statuses to disable
277  * @return	Nothing
278  * @note	Multiple interrupts may be pending. Mask the return value
279  *			with one or more UART_INTEN_* definitions to determine
280  *			pending interrupts.
281  */
Chip_UART_ClearStatus(LPC_USART_T * pUART,uint32_t stsMask)282 STATIC INLINE void Chip_UART_ClearStatus(LPC_USART_T *pUART, uint32_t stsMask)
283 {
284 	pUART->STAT = stsMask;
285 }
286 
287 /**
288  * @brief	Initialize the UART peripheral
289  * @param	pUART	: The base of UART peripheral on the chip
290  * @return	Nothing
291  */
292 void Chip_UART_Init(LPC_USART_T *pUART);
293 
294 /**
295  * @brief	Deinitialize the UART peripheral
296  * @param	pUART	: The base of UART peripheral on the chip
297  * @return	Nothing
298  */
299 void Chip_UART_DeInit(LPC_USART_T *pUART);
300 
301 /**
302  * @brief	Transmit a byte array through the UART peripheral (non-blocking)
303  * @param	pUART		: Pointer to selected UART peripheral
304  * @param	data		: Pointer to bytes to transmit
305  * @param	numBytes	: Number of bytes to transmit
306  * @return	The actual number of bytes placed into the FIFO
307  * @note	This function places data into the transmit FIFO until either
308  *			all the data is in the FIFO or the FIFO is full. This function
309  *			will not block in the FIFO is full. The actual number of bytes
310  *			placed into the FIFO is returned. This function ignores errors.
311  */
312 int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes);
313 
314 /**
315  * @brief	Read data through the UART peripheral (non-blocking)
316  * @param	pUART		: Pointer to selected UART peripheral
317  * @param	data		: Pointer to bytes array to fill
318  * @param	numBytes	: Size of the passed data array
319  * @return	The actual number of bytes read
320  * @note	This function reads data from the receive FIFO until either
321  *			all the data has been read or the passed buffer is completely full.
322  *			This function will not block. This function ignores errors.
323  */
324 int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes);
325 
326 /**
327  * @brief	Set baud rate for UART
328  * @param	pUART	: The base of UART peripheral on the chip
329  * @param	baudrate: Baud rate to be set
330  * @return	Nothing
331  */
332 void Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate);
333 
334 /**
335  * @brief	Set baud rate for UART using RTC32K oscillator
336  * @param	pUART	: The base of UART peripheral on the chip
337  * @param	baudrate: Baud rate to be set
338  * @return	Nothing
339  * @note	Since the baud rate is divided from the 32KHz oscillator,
340  *			this function should only be used with baud rates less
341  *			than or equal to 9600 baud. Don't expect any accuracy.
342  */
343 void Chip_UART_SetBaudWithRTC32K(LPC_USART_T *pUART, uint32_t baudrate);
344 
345 /**
346  * @brief	Transmit a byte array through the UART peripheral (blocking)
347  * @param	pUART		: Pointer to selected UART peripheral
348  * @param	data		: Pointer to data to transmit
349  * @param	numBytes	: Number of bytes to transmit
350  * @return	The number of bytes transmitted
351  * @note	This function will send or place all bytes into the transmit
352  *			FIFO. This function will block until the last bytes are in the FIFO.
353  */
354 int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes);
355 
356 /**
357  * @brief	Read data through the UART peripheral (blocking)
358  * @param	pUART		: Pointer to selected UART peripheral
359  * @param	data		: Pointer to data array to fill
360  * @param	numBytes	: Size of the passed data array
361  * @return	The size of the dat array
362  * @note	This function reads data from the receive FIFO until the passed
363  *			buffer is completely full. The function will block until full.
364  *			This function ignores errors.
365  */
366 int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes);
367 
368 /**
369  * @brief	UART receive-only interrupt handler for ring buffers
370  * @param	pUART	: Pointer to selected UART peripheral
371  * @param	pRB		: Pointer to ring buffer structure to use
372  * @return	Nothing
373  * @note	If ring buffer support is desired for the receive side
374  *			of data transfer, the UART interrupt should call this
375  *			function for a receive based interrupt status.
376  */
377 void Chip_UART_RXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB);
378 
379 /**
380  * @brief	UART transmit-only interrupt handler for ring buffers
381  * @param	pUART	: Pointer to selected UART peripheral
382  * @param	pRB		: Pointer to ring buffer structure to use
383  * @return	Nothing
384  * @note	If ring buffer support is desired for the transmit side
385  *			of data transfer, the UART interrupt should call this
386  *			function for a transmit based interrupt status.
387  */
388 void Chip_UART_TXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB);
389 
390 /**
391  * @brief	Populate a transmit ring buffer and start UART transmit
392  * @param	pUART	: Pointer to selected UART peripheral
393  * @param	pRB		: Pointer to ring buffer structure to use
394  * @param	data	: Pointer to buffer to move to ring buffer
395  * @param	count	: Number of bytes to move
396  * @return	The number of bytes placed into the ring buffer
397  * @note	Will move the data into the TX ring buffer and start the
398  *			transfer. If the number of bytes returned is less than the
399  *			number of bytes to send, the ring buffer is considered full.
400  */
401 uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int count);
402 
403 /**
404  * @brief	Copy data from a receive ring buffer
405  * @param	pUART	: Pointer to selected UART peripheral
406  * @param	pRB		: Pointer to ring buffer structure to use
407  * @param	data	: Pointer to buffer to fill from ring buffer
408  * @param	bytes	: Size of the passed buffer in bytes
409  * @return	The number of bytes placed into the ring buffer
410  * @note	Will move the data from the RX ring buffer up to the
411  *			the maximum passed buffer size. Returns 0 if there is
412  *			no data in the ring buffer.
413  */
414 int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes);
415 
416 /**
417  * @brief	UART receive/transmit interrupt handler for ring buffers
418  * @param	pUART	: Pointer to selected UART peripheral
419  * @param	pRXRB	: Pointer to transmit ring buffer
420  * @param	pTXRB	: Pointer to receive ring buffer
421  * @return	Nothing
422  * @note	This provides a basic implementation of the UART IRQ
423  *			handler for support of a ring buffer implementation for
424  *			transmit and receive.
425  */
426 void Chip_UART_IRQRBHandler(LPC_USART_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB);
427 
428 /**
429  * @}
430  */
431 
432 #ifdef __cplusplus
433 }
434 #endif
435 
436 #endif /* __UART_15XX_H_ */
437