1 /*
2 * @brief UART interrupt example with ring buffers
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 #include "board.h"
33 #include "string.h"
34
35 /*****************************************************************************
36 * Private types/enumerations/variables
37 ****************************************************************************/
38
39 /* Enable this define to use integer clocking instead of the fractional baud
40 rate generator */
41 #define USE_INTEGER_CLOCK
42
43 /* Transmit and receive ring buffers */
44 STATIC RINGBUFF_T txring, rxring;
45
46 /* Ring buffer size */
47 #define UART_RB_SIZE 64
48
49 /* Set the default UART, IRQ number, and IRQ handler name */
50 #if defined(BOARD_NXP_LPCXPRESSO_1549)
51 #define LPC_USART LPC_USART0
52 #define LPC_IRQNUM UART0_IRQn
53 #define LPC_UARTHNDLR UART0_IRQHandler
54
55 #else
56 /* Configure your own UART pin muxing here if needed */
57 #error "No UART setup defined"
58 #endif
59
60 /* Default baudrate for testing */
61 #define UART_TEST_DEFAULT_BAUDRATE 115200
62
63 /* Transmit and receive buffers */
64 static uint8_t rxbuff[UART_RB_SIZE], txbuff[UART_RB_SIZE];
65
66 const char inst1[] = "LPC15xx UART example using ring buffers\r\n";
67 const char inst2[] = "Press a key to echo it back or ESC to quit\r\n";
68
69 /*****************************************************************************
70 * Public types/enumerations/variables
71 ****************************************************************************/
72
73 /*****************************************************************************
74 * Private functions
75 ****************************************************************************/
76
77 /* UART Pin mux function - note that SystemInit() may already setup your
78 pin muxing at system startup */
Init_UART_PinMux(void)79 static void Init_UART_PinMux(void)
80 {
81 #if defined(BOARD_NXP_LPCXPRESSO_1549)
82 /* UART signals on pins PIO0_13 (FUNC0, U0_TXD) and PIO0_18 (FUNC0, U0_RXD) */
83 Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 13, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN));
84 Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 18, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN));
85
86 /* UART signal muxing via SWM */
87 Chip_SWM_MovablePortPinAssign(SWM_UART0_RXD_I, 0, 13);
88 Chip_SWM_MovablePortPinAssign(SWM_UART0_TXD_O, 0, 18);
89
90 #else
91 #warning "No UART nmuxing defined for this example"
92 #endif
93 }
94
95 /*****************************************************************************
96 * Public functions
97 ****************************************************************************/
98
99 /**
100 * @brief UART interrupt handler using ring buffers
101 * @return Nothing
102 */
LPC_UARTHNDLR(void)103 void LPC_UARTHNDLR(void)
104 {
105 /* Want to handle any errors? Do it here. */
106
107 /* Use default ring buffer handler. Override this with your own
108 code if you need more capability. */
109 Chip_UART_IRQRBHandler(LPC_USART, &rxring, &txring);
110 }
111
112 /**
113 * @brief Main UART program body
114 * @return Always returns 1
115 */
main(void)116 int main(void)
117 {
118 uint8_t key;
119 int bytes;
120
121 SystemCoreClockUpdate();
122 Board_Init();
123 Init_UART_PinMux();
124 Board_LED_Set(0, false);
125
126 /* Before setting up the UART, the global UART clock for USARTS 1-4
127 must first be setup. This requires setting the UART divider and
128 the UART base clock rate to 16x the maximum UART rate for all
129 UARTs. */
130 #if defined(USE_INTEGER_CLOCK)
131 /* Use main clock rate as base for UART baud rate divider */
132 Chip_Clock_SetUARTBaseClockRate(Chip_Clock_GetMainClockRate(), false);
133
134 #else
135 /* Use 128x expected UART baud rate for fractional baud mode. */
136 Chip_Clock_SetUARTBaseClockRate((115200 * 128), true);
137 #endif
138
139 /* Setup UART */
140 Chip_UART_Init(LPC_USART);
141 Chip_UART_ConfigData(LPC_USART, UART_CFG_DATALEN_8 | UART_CFG_PARITY_NONE | UART_CFG_STOPLEN_1);
142 Chip_UART_SetBaud(LPC_USART, UART_TEST_DEFAULT_BAUDRATE);
143 /* Optional for low clock rates only: Chip_UART_SetBaudWithRTC32K(LPC_USART, 300); */
144 Chip_UART_Enable(LPC_USART);
145 Chip_UART_TXEnable(LPC_USART);
146
147 /* Before using the ring buffers, initialize them using the ring
148 buffer init function */
149 RingBuffer_Init(&rxring, rxbuff, 1, UART_RB_SIZE);
150 RingBuffer_Init(&txring, txbuff, 1, UART_RB_SIZE);
151
152 /* Enable receive data and line status interrupt */
153 Chip_UART_IntEnable(LPC_USART, UART_INTEN_RXRDY);
154 Chip_UART_IntDisable(LPC_USART, UART_INTEN_TXRDY); /* May not be needed */
155
156 /* Enable UART interrupt */
157 NVIC_EnableIRQ(LPC_IRQNUM);
158
159 /* Initial message sent using blocking method to prevent ring
160 buffer overflow */
161 Chip_UART_SendBlocking(LPC_USART, inst1, sizeof(inst1) - 1);
162 Chip_UART_SendRB(LPC_USART, &txring, inst2, sizeof(inst2) - 1);
163
164 /* Poll the receive ring buffer for the ESC (ASCII 27) key */
165 key = 0;
166 while (key != 27) {
167 bytes = Chip_UART_ReadRB(LPC_USART, &rxring, &key, 1);
168 if (bytes > 0) {
169 /* Wrap value back around */
170 if (Chip_UART_SendRB(LPC_USART, &txring, (const uint8_t *) &key, 1) != 1) {
171 Board_LED_Toggle(0);/* Toggle LED if the TX FIFO is full */
172 }
173 }
174 }
175
176 /* DeInitialize UART peripheral */
177 NVIC_DisableIRQ(LPC_IRQNUM);
178 Chip_UART_DeInit(LPC_USART);
179
180 return 1;
181 }
182