| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
uart_13xx.c
Go to the documentation of this file.
1 /*
2 * @brief LPC13xx UART chip driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
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 #include "chip.h"
33
34 /*****************************************************************************
35 * Private types/enumerations/variables
36 ****************************************************************************/
37
38 /* Used for transmit interrupt monitoring */
39 STATIC bool txIntEnabled;
40
41 /*****************************************************************************
42 * Public types/enumerations/variables
43 ****************************************************************************/
44
45 /*****************************************************************************
46 * Private functions
47 ****************************************************************************/
48
49 /*****************************************************************************
50 * Public functions
51 ****************************************************************************/
52
53 /* Initializes the pUART peripheral */
54 void Chip_UART_Init(LPC_USART_T *pUART)
55 {
56 /* Enable clock to UART block */
57 Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_UART0);
58 Chip_Clock_SetUARTClockDiv(1);
59
60 IP_UART_Init(pUART);
61 }
62
63 /* De-initializes the pUART peripheral */
64 void Chip_UART_DeInit(LPC_USART_T *pUART)
65 {
66 IP_UART_DeInit(pUART);
67
68 /* Disable UART block */
69 Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_UART0);
70 }
71
72 /* Transmit a byte array through the UART peripheral (non-blocking) */
73 int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes)
74 {
75 int sent = 0;
76 uint8_t *p8 = (uint8_t *) data;
77
78 /* Send until the transmit FIFO is full or out of bytes */
79 while ((sent < numBytes) &&
80 ((IP_UART_ReadLineStatus(pUART) & UART_LSR_THRE) != 0)) {
81 IP_UART_SendByte(pUART, *p8);
82 p8++;
83 sent++;
84 }
85
86 return sent;
87 }
88
89 /* Transmit a byte array through the UART peripheral (blocking) */
90 int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes)
91 {
92 int pass, sent = 0;
93 uint8_t *p8 = (uint8_t *) data;
94
95 while (numBytes > 0) {
96 pass = Chip_UART_Send(pUART, p8, numBytes);
97 numBytes -= pass;
98 sent += pass;
99 p8 += pass;
100 }
101
102 return sent;
103 }
104
105 /* Read data through the UART peripheral (non-blocking) */
106 int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes)
107 {
108 int readBytes = 0;
109 uint8_t *p8 = (uint8_t *) data;
110
111 /* Send until the transmit FIFO is full or out of bytes */
112 while ((readBytes < numBytes) &&
113 ((IP_UART_ReadLineStatus(pUART) & UART_LSR_RDR) != 0)) {
114 *p8 = IP_UART_ReadByte(pUART);
115 p8++;
116 readBytes++;
117 }
118
119 return readBytes;
120 }
121
122 /* Read data through the UART peripheral (blocking) */
123 int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes)
124 {
125 int pass, readBytes = 0;
126 uint8_t *p8 = (uint8_t *) data;
127
128 while (readBytes < numBytes) {
129 pass = Chip_UART_Read(pUART, p8, numBytes);
130 numBytes -= pass;
131 readBytes += pass;
132 p8 += pass;
133 }
134
135 return readBytes;
136 }
137
138 /* Determines and sets best dividers to get a target bit rate */
139 uint32_t Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate)
140 {
141 uint32_t div, divh, divl, clkin;
142
143 /* Determine UART clock in rate without FDR */
144 clkin = Chip_Clock_GetMainClockRate();
145 div = clkin / (baudrate * 16);
146
147 /* High and low halves of the divider */
148 divh = div / 256;
149 divl = div - (divh * 256);
150
151 IP_UART_EnableDivisorAccess(pUART);
152 IP_UART_SetDivisorLatches(pUART, divl, divh);
153 IP_UART_DisableDivisorAccess(pUART);
154
155 /* Fractional FDR alreadt setup for 1 in UART init */
156
157 return clkin / div;
158 }
159
160 /* UART receive-only interrupt handler for ring buffers */
161 void Chip_UART_RXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB)
162 {
163 /* New data will be discarded if the buffer is not popped in time */
164 while (Chip_UART_ReadLineStatus(pUART) & UART_LSR_RDR) {
165 uint8_t ch = Chip_UART_ReadByte(pUART);
166 RingBuffer_Insert(pRB, &ch);
167 }
168 }
169
170 /* UART transmit-only interrupt handler for ring buffers */
171 void Chip_UART_TXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB)
172 {
173 uint8_t ch;
174
175 /* Fill FIFO until full or until TX ring buffer is empty */
176 while ((IP_UART_ReadLineStatus(pUART) & UART_LSR_THRE) != 0 &&
177 RingBuffer_Pop(pRB, &ch)) {
178 IP_UART_SendByte(pUART, ch);
179 }
180
181 /* Turn off interrupt if the ring buffer is empty */
182 if (RingBuffer_IsEmpty(pRB))
183 {
184 /* Shut down transmit */
185 Chip_UART_IntDisable(pUART, UART_IER_THREINT);
186 txIntEnabled = false;
187 }
188 }
189
190 /* Populate a transmit ring buffer and start UART transmit */
191 uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int bytes)
192 {
193 int ret;
194 uint8_t *p8 = (uint8_t *) data;
195
196 /* Fill transmit FIFO */
197 txIntEnabled = false;
198 ret = RingBuffer_InsertMult(pRB, p8, bytes);
199 bytes -= ret;
200 p8 += ret;
201 Chip_UART_TXIntHandlerRB(pUART, pRB);
202 txIntEnabled = true;
203
204 /* Enable Transmit FIFO interrupt to start transmit ring
205 buffer servicing */
206 Chip_UART_IntEnable(pUART, UART_IER_THREINT);
207
208 /* Do this till all bytes are queued */
209 while (bytes) {
210 /* A proper wait handler must be added here */
211 ret = RingBuffer_InsertMult(pRB, p8, bytes);
212 bytes -= ret;
213 p8 += ret;
214 }
215
216 return 0;
217 }
218
219 /* Copy data from a receive ring buffer */
220 int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes)
221 {
222 (void) pUART;
223
224 return RingBuffer_PopMult(pRB, (uint8_t *) data, bytes);
225 }
226
227 /* UART receive/transmit interrupt handler for ring buffers */
228 void Chip_UART_IRQRBHandler(LPC_USART_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB)
229 {
230 (void) pUART;
231
232 /* Handle transmit and receive interrupts using the ring
233 buffer handlers */
234 Chip_UART_RXIntHandlerRB(LPC_USART, pRXRB);
235
236 if (txIntEnabled) {
237 Chip_UART_TXIntHandlerRB(LPC_USART, pTXRB);
238 }
239 }