1 /**************************************************************************/
4 @author K. Townsend (microBuilder.eu)
10 Generic code for UART-based communication. Incoming text is stored
11 in a FIFO Queue for safer processing.
13 @section Example: Sending text via UART
16 #include "core/cpu/cpu.h"
17 #include "core/uart/uart.h"
19 #define UARTBUFFERSIZE 5
24 uint8_t uartBuffer[UARTBUFFERSIZE] = { 'T', 'e', 's', 't', '\n' };
26 // Send contents of uartBuffer
27 uartSend((uint8_t *)uartBuffer, UARTBUFFERSIZE);
30 @section Example: Reading from UART
34 #include "core/cpu/cpu.h"
35 #include "core/uart/uart.h"
40 // Get a reference to the UART control block
41 uart_pcb_t *pcb = uartGetPCB();
43 // Read any text available in the queue
44 while (uartRxBufferDataPending())
46 // Read the first available character
47 uint8_t c = uartRxBufferRead();
49 // read out the data in the buffer and echo it back to the host.
65 Software License Agreement (BSD License)
67 Copyright (c) 2010, microBuilder SARL
70 Redistribution and use in source and binary forms, with or without
71 modification, are permitted provided that the following conditions are met:
72 1. Redistributions of source code must retain the above copyright
73 notice, this list of conditions and the following disclaimer.
74 2. Redistributions in binary form must reproduce the above copyright
75 notice, this list of conditions and the following disclaimer in the
76 documentation and/or other materials provided with the distribution.
77 3. Neither the name of the copyright holders nor the
78 names of its contributors may be used to endorse or promote products
79 derived from this software without specific prior written permission.
81 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
82 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
83 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
85 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
86 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92 /**************************************************************************/
98 #ifdef CFG_INTERFACE_UART
99 #include "core/cmd/cmd.h"
102 /**************************************************************************/
104 UART protocol control block, which is used to safely access the
105 RX FIFO buffer from elsewhere in the code. This should be accessed
106 through 'uartGetPCB()'.
108 /**************************************************************************/
109 static uart_pcb_t pcb
;
111 /**************************************************************************/
113 IRQ to handle incoming data, etc.
115 /**************************************************************************/
116 void UART_IRQHandler(void)
118 uint8_t IIRValue
, LSRValue
;
119 uint8_t Dummy
= Dummy
;
121 IIRValue
= UART_U0IIR
;
122 IIRValue
&= ~(UART_U0IIR_IntStatus_MASK
); /* skip pending bit in IIR */
123 IIRValue
&= UART_U0IIR_IntId_MASK
; /* check bit 1~3, interrupt identification */
125 // 1.) Check receiver line status
126 if (IIRValue
== UART_U0IIR_IntId_RLS
)
128 LSRValue
= UART_U0LSR
;
130 if (LSRValue
& (UART_U0LSR_OE
| UART_U0LSR_PE
| UART_U0LSR_FE
| UART_U0LSR_RXFE
| UART_U0LSR_BI
))
132 /* There are errors or break interrupt */
133 /* Read LSR will clear the interrupt */
134 pcb
.status
= LSRValue
;
135 Dummy
= UART_U0RBR
; /* Dummy read on RX to clear interrupt, then bail out */
138 // No error and receive data is ready
139 if (LSRValue
& UART_U0LSR_RDR_DATA
)
141 /* If no error on RLS, normal ready, save into the data buffer. */
142 /* Note: read RBR will clear the interrupt */
143 uartRxBufferWrite(UART_U0RBR
);
147 // 2.) Check receive data available
148 else if (IIRValue
== UART_U0IIR_IntId_RDA
)
150 // Add incoming text to UART buffer
151 uartRxBufferWrite(UART_U0RBR
);
154 // 3.) Check character timeout indicator
155 else if (IIRValue
== UART_U0IIR_IntId_CTI
)
157 /* Bit 9 as the CTI error */
161 // 4.) Check THRE (transmit holding register empty)
162 else if (IIRValue
== UART_U0IIR_IntId_THRE
)
164 /* Check status in the LSR to see if valid data in U0THR or not */
165 LSRValue
= UART_U0LSR
;
166 if (LSRValue
& UART_U0LSR_THRE
)
168 pcb
.pending_tx_data
= 0;
172 pcb
.pending_tx_data
= 1;
178 /**************************************************************************/
180 @brief Get a pointer to the UART's protocol control block, which can
181 be used to control the RX FIFO buffer and check whether UART
182 has already been initialised or not.
187 // Make sure that UART is initialised
188 uart_pcb_t *pcb = uartGetPCB();
189 if (!pcb->initialised)
191 uartInit(CFG_UART_BAUDRATE);
196 /**************************************************************************/
197 uart_pcb_t
*uartGetPCB()
202 /**************************************************************************/
204 @brief Initialises UART at the specified baud rate.
207 The baud rate to use when configuring the UART.
209 /**************************************************************************/
210 void uartInit(uint32_t baudrate
)
215 NVIC_DisableIRQ(UART_IRQn
);
217 // Clear protocol control blocks
218 memset(&pcb
, 0, sizeof(uart_pcb_t
));
219 pcb
.pending_tx_data
= 0;
222 /* Set 1.6 UART RXD */
223 IOCON_PIO1_6
&= ~IOCON_PIO1_6_FUNC_MASK
;
224 IOCON_PIO1_6
|= IOCON_PIO1_6_FUNC_UART_RXD
;
226 /* Set 1.7 UART TXD */
227 IOCON_PIO1_7
&= ~IOCON_PIO1_7_FUNC_MASK
;
228 IOCON_PIO1_7
|= IOCON_PIO1_7_FUNC_UART_TXD
;
230 /* Enable UART clock */
231 SCB_SYSAHBCLKCTRL
|= (SCB_SYSAHBCLKCTRL_UART
);
232 SCB_UARTCLKDIV
= SCB_UARTCLKDIV_DIV1
; /* divided by 1 */
234 /* 8 bits, no Parity, 1 Stop bit */
235 UART_U0LCR
= (UART_U0LCR_Word_Length_Select_8Chars
|
236 UART_U0LCR_Stop_Bit_Select_1Bits
|
237 UART_U0LCR_Parity_Disabled
|
238 UART_U0LCR_Parity_Select_OddParity
|
239 UART_U0LCR_Break_Control_Disabled
|
240 UART_U0LCR_Divisor_Latch_Access_Enabled
);
243 regVal
= SCB_UARTCLKDIV
;
244 fDiv
= (((CFG_CPU_CCLK
* SCB_SYSAHBCLKDIV
)/regVal
)/16)/baudrate
;
246 UART_U0DLM
= fDiv
/ 256;
247 UART_U0DLL
= fDiv
% 256;
249 /* Set DLAB back to 0 */
250 UART_U0LCR
= (UART_U0LCR_Word_Length_Select_8Chars
|
251 UART_U0LCR_Stop_Bit_Select_1Bits
|
252 UART_U0LCR_Parity_Disabled
|
253 UART_U0LCR_Parity_Select_OddParity
|
254 UART_U0LCR_Break_Control_Disabled
|
255 UART_U0LCR_Divisor_Latch_Access_Disabled
);
257 /* Enable and reset TX and RX FIFO. */
258 UART_U0FCR
= (UART_U0FCR_FIFO_Enabled
|
259 UART_U0FCR_Rx_FIFO_Reset
|
260 UART_U0FCR_Tx_FIFO_Reset
);
262 /* Read to clear the line status. */
265 /* Ensure a clean start, no data in either TX or RX FIFO. */
266 while (( UART_U0LSR
& (UART_U0LSR_THRE
|UART_U0LSR_TEMT
)) != (UART_U0LSR_THRE
|UART_U0LSR_TEMT
) );
267 while ( UART_U0LSR
& UART_U0LSR_RDR_DATA
)
269 /* Dump data from RX FIFO */
273 /* Set the initialised flag in the protocol control block */
275 pcb
.baudrate
= baudrate
;
277 /* Enable the UART Interrupt */
278 NVIC_EnableIRQ(UART_IRQn
);
279 UART_U0IER
= UART_U0IER_RBR_Interrupt_Enabled
| UART_U0IER_RLS_Interrupt_Enabled
;
284 /**************************************************************************/
286 @brief Sends the contents of supplied text buffer over UART.
289 Pointer to the text buffer
291 The size of the text buffer
296 // Set 5-character text buffer
297 uint8_t uartBuffer[5] = { 'T', 'e', 's', 't', '\n' };
298 // Send contents of uartBuffer
299 uartSend((uint8_t *)uartBuffer, 5);
303 /**************************************************************************/
304 void uartSend (uint8_t *bufferPtr
, uint32_t length
)
308 /* THRE status, contain valid data */
309 while ( !(UART_U0LSR
& UART_U0LSR_THRE
) );
310 UART_U0THR
= *bufferPtr
;
319 /**************************************************************************/
321 @brief Sends a single byte over UART.
329 // Send 0xFF over UART
331 // Send 'B' over UART (note single quotes)
336 /**************************************************************************/
337 void uartSendByte (uint8_t byte
)
339 /* THRE status, contain valid data */
340 while ( !(UART_U0LSR
& UART_U0LSR_THRE
) );