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