1 /******************************************************************************
2 * Filename: uart.c
3 * Revised: 2015-11-16 19:41:47 +0100 (Mon, 16 Nov 2015)
4 * Revision: 45094
5 *
6 * Description: Driver for the UART.
7 *
8 * Copyright (c) 2015, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 #include <driverlib/uart.h>
40
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #if !defined(DOXYGEN)
48 #undef UARTFIFOLevelGet
49 #define UARTFIFOLevelGet NOROM_UARTFIFOLevelGet
50 #undef UARTConfigSetExpClk
51 #define UARTConfigSetExpClk NOROM_UARTConfigSetExpClk
52 #undef UARTConfigGetExpClk
53 #define UARTConfigGetExpClk NOROM_UARTConfigGetExpClk
54 #undef UARTDisable
55 #define UARTDisable NOROM_UARTDisable
56 #undef UARTCharGetNonBlocking
57 #define UARTCharGetNonBlocking NOROM_UARTCharGetNonBlocking
58 #undef UARTCharGet
59 #define UARTCharGet NOROM_UARTCharGet
60 #undef UARTCharPutNonBlocking
61 #define UARTCharPutNonBlocking NOROM_UARTCharPutNonBlocking
62 #undef UARTCharPut
63 #define UARTCharPut NOROM_UARTCharPut
64 #undef UARTIntRegister
65 #define UARTIntRegister NOROM_UARTIntRegister
66 #undef UARTIntUnregister
67 #define UARTIntUnregister NOROM_UARTIntUnregister
68 #endif
69
70 //*****************************************************************************
71 //
72 //! Gets the FIFO level at which interrupts are generated
73 //
74 //*****************************************************************************
75 void
UARTFIFOLevelGet(uint32_t ui32Base,uint32_t * pui32TxLevel,uint32_t * pui32RxLevel)76 UARTFIFOLevelGet(uint32_t ui32Base, uint32_t *pui32TxLevel,
77 uint32_t *pui32RxLevel)
78 {
79 uint32_t ui32Temp;
80
81 //
82 // Check the arguments.
83 //
84 ASSERT(UARTBaseValid(ui32Base));
85
86 //
87 // Read the FIFO level register.
88 //
89 ui32Temp = HWREG(ui32Base + UART_O_IFLS);
90
91 //
92 // Extract the transmit and receive FIFO levels.
93 //
94 *pui32TxLevel = ui32Temp & UART_IFLS_TXSEL_M;
95 *pui32RxLevel = ui32Temp & UART_IFLS_RXSEL_M;
96 }
97
98 //*****************************************************************************
99 //
100 //! Sets the configuration of a UART
101 //
102 //*****************************************************************************
103 void
UARTConfigSetExpClk(uint32_t ui32Base,uint32_t ui32UARTClk,uint32_t ui32Baud,uint32_t ui32Config)104 UARTConfigSetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk,
105 uint32_t ui32Baud, uint32_t ui32Config)
106 {
107 uint32_t ui32Div;
108
109 //
110 // Check the arguments.
111 //
112 ASSERT(UARTBaseValid(ui32Base));
113 ASSERT(ui32Baud != 0);
114
115 //
116 // Stop the UART.
117 //
118 UARTDisable(ui32Base);
119
120 //
121 // Compute the fractional baud rate divider.
122 //
123 ui32Div = (((ui32UARTClk * 8) / ui32Baud) + 1) / 2;
124
125 //
126 // Set the baud rate.
127 //
128 HWREG(ui32Base + UART_O_IBRD) = ui32Div / 64;
129 HWREG(ui32Base + UART_O_FBRD) = ui32Div % 64;
130
131 //
132 // Set parity, data length, and number of stop bits.
133 //
134 HWREG(ui32Base + UART_O_LCRH) = ui32Config;
135 }
136
137 //*****************************************************************************
138 //
139 //! Gets the current configuration of a UART
140 //
141 //*****************************************************************************
142 void
UARTConfigGetExpClk(uint32_t ui32Base,uint32_t ui32UARTClk,uint32_t * pui32Baud,uint32_t * pui32Config)143 UARTConfigGetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk,
144 uint32_t *pui32Baud, uint32_t *pui32Config)
145 {
146 uint32_t ui32Int, ui32Frac;
147
148 //
149 // Check the arguments.
150 //
151 ASSERT(UARTBaseValid(ui32Base));
152
153 //
154 // Compute the baud rate.
155 //
156 ui32Int = HWREG(ui32Base + UART_O_IBRD);
157 ui32Frac = HWREG(ui32Base + UART_O_FBRD);
158 *pui32Baud = (ui32UARTClk * 4) / ((64 * ui32Int) + ui32Frac);
159
160 //
161 // Get the parity, data length, and number of stop bits.
162 //
163 *pui32Config = (HWREG(ui32Base + UART_O_LCRH) &
164 (UART_LCRH_SPS | UART_LCRH_WLEN_M | UART_LCRH_STP2 |
165 UART_LCRH_EPS | UART_LCRH_PEN));
166 }
167
168 //*****************************************************************************
169 //
170 //! Disables transmitting and receiving
171 //
172 //*****************************************************************************
173 void
UARTDisable(uint32_t ui32Base)174 UARTDisable(uint32_t ui32Base)
175 {
176
177 //
178 // Check the arguments.
179 //
180 ASSERT(UARTBaseValid(ui32Base));
181
182 //
183 // Wait for end of TX.
184 //
185 while(HWREG(ui32Base + UART_O_FR) & UART_FR_BUSY)
186 {
187 }
188
189 //
190 // Disable the FIFO.
191 //
192 HWREG(ui32Base + UART_O_LCRH) &= ~(UART_LCRH_FEN);
193
194 //
195 // Disable the UART.
196 //
197 HWREG(ui32Base + UART_O_CTL) &= ~(UART_CTL_UARTEN | UART_CTL_TXE |
198 UART_CTL_RXE);
199 }
200
201 //*****************************************************************************
202 //
203 //! Receives a character from the specified port
204 //
205 //*****************************************************************************
206 int32_t
UARTCharGetNonBlocking(uint32_t ui32Base)207 UARTCharGetNonBlocking(uint32_t ui32Base)
208 {
209 //
210 // Check the arguments.
211 //
212 ASSERT(UARTBaseValid(ui32Base));
213
214 //
215 // See if there are any characters in the receive FIFO.
216 //
217 if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE))
218 {
219 //
220 // Read and return the next character.
221 //
222 return(HWREG(ui32Base + UART_O_DR));
223 }
224 else
225 {
226 //
227 // There are no characters, so return a failure.
228 //
229 return(-1);
230 }
231 }
232
233 //*****************************************************************************
234 //
235 //! Waits for a character from the specified port
236 //
237 //*****************************************************************************
238 int32_t
UARTCharGet(uint32_t ui32Base)239 UARTCharGet(uint32_t ui32Base)
240 {
241 //
242 // Check the arguments.
243 //
244 ASSERT(UARTBaseValid(ui32Base));
245
246 //
247 // Wait until a char is available.
248 //
249 while(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE)
250 {
251 }
252
253 //
254 // Now get the character.
255 //
256 return(HWREG(ui32Base + UART_O_DR));
257 }
258
259 //*****************************************************************************
260 //
261 //! Sends a character to the specified port
262 //
263 //*****************************************************************************
264 bool
UARTCharPutNonBlocking(uint32_t ui32Base,uint8_t ui8Data)265 UARTCharPutNonBlocking(uint32_t ui32Base, uint8_t ui8Data)
266 {
267 //
268 // Check the arguments.
269 //
270 ASSERT(UARTBaseValid(ui32Base));
271
272 //
273 // See if there is space in the transmit FIFO.
274 //
275 if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF))
276 {
277 //
278 // Write this character to the transmit FIFO.
279 //
280 HWREG(ui32Base + UART_O_DR) = ui8Data;
281
282 //
283 // Success.
284 //
285 return(true);
286 }
287 else
288 {
289 //
290 // There is no space in the transmit FIFO, so return a failure.
291 //
292 return(false);
293 }
294 }
295
296 //*****************************************************************************
297 //
298 //! Waits to send a character from the specified port
299 //
300 //*****************************************************************************
301 void
UARTCharPut(uint32_t ui32Base,uint8_t ui8Data)302 UARTCharPut(uint32_t ui32Base, uint8_t ui8Data)
303 {
304 //
305 // Check the arguments.
306 //
307 ASSERT(UARTBaseValid(ui32Base));
308
309 //
310 // Wait until space is available.
311 //
312 while(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF)
313 {
314 }
315
316 //
317 // Send the char.
318 //
319 HWREG(ui32Base + UART_O_DR) = ui8Data;
320 }
321
322 //*****************************************************************************
323 //
324 //! Registers an interrupt handler for a UART interrupt
325 //
326 //*****************************************************************************
327 void
UARTIntRegister(uint32_t ui32Base,void (* pfnHandler)(void))328 UARTIntRegister(uint32_t ui32Base, void (*pfnHandler)(void))
329 {
330 //
331 // Check the arguments.
332 //
333 ASSERT(UARTBaseValid(ui32Base));
334
335 //
336 // Register the interrupt handler.
337 //
338 IntRegister(INT_UART0_COMB, pfnHandler);
339
340 //
341 // Enable the UART interrupt.
342 //
343 IntEnable(INT_UART0_COMB);
344 }
345
346 //*****************************************************************************
347 //
348 //! Unregisters an interrupt handler for a UART interrupt
349 //
350 //*****************************************************************************
351 void
UARTIntUnregister(uint32_t ui32Base)352 UARTIntUnregister(uint32_t ui32Base)
353 {
354 //
355 // Check the arguments.
356 //
357 ASSERT(UARTBaseValid(ui32Base));
358
359 //
360 // Disable the interrupt.
361 //
362 IntDisable(INT_UART0_COMB);
363
364 //
365 // Unregister the interrupt handler.
366 //
367 IntUnregister(INT_UART0_COMB);
368 }
369