1 /*
2  * Copyright (c) 2017, Linaro Ltd
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT ti_msp432p4xx_uart
8 
9 /* See www.ti.com/lit/pdf/slau356f, Chapter 22, for MSP432P4XX UART info. */
10 
11 /* include driverlib/gpio.h (from the msp432p4xx SDK) before Z's uart.h so
12  * that the definition of BIT is not overridden */
13 #include <driverlib/gpio.h>
14 
15 #include <drivers/uart.h>
16 
17 /* Driverlib includes */
18 #include <driverlib/rom.h>
19 #include <driverlib/rom_map.h>
20 #include <driverlib/uart.h>
21 
22 struct uart_msp432p4xx_dev_data_t {
23 	/* UART config structure */
24 	eUSCI_UART_Config uartConfig;
25 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
26 	uart_irq_callback_user_data_t cb; /**< Callback function pointer */
27 	void *cb_data;  /**< Callback function arg */
28 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
29 };
30 
31 #define DEV_CFG(dev) \
32 	((const struct uart_device_config * const)(dev)->config)
33 #define DEV_DATA(dev) \
34 	((struct uart_msp432p4xx_dev_data_t * const)(dev)->data)
35 
36 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
37 static void uart_msp432p4xx_isr(const struct device *dev);
38 #endif
39 
40 static const struct uart_device_config uart_msp432p4xx_dev_cfg_0 = {
41 	.base = (void *)DT_INST_REG_ADDR(0),
42 	.sys_clk_freq = DT_INST_PROP_BY_PHANDLE(0, clocks, clock_frequency),
43 };
44 
45 static struct uart_msp432p4xx_dev_data_t uart_msp432p4xx_dev_data_0 = {
46 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
47 	.cb = NULL,
48 #endif
49 };
50 
baudrate_set(eUSCI_UART_Config * config,uint32_t baudrate)51 static int baudrate_set(eUSCI_UART_Config *config, uint32_t baudrate)
52 {
53 	uint16_t prescalar;
54 	uint8_t first_mod_reg, second_mod_reg;
55 
56 	switch (baudrate) {
57 	case 1200:
58 		prescalar = 2500U;
59 		first_mod_reg = 0U;
60 		second_mod_reg = 0U;
61 		break;
62 	case 2400:
63 		prescalar = 1250U;
64 		first_mod_reg = 0U;
65 		second_mod_reg = 0U;
66 		break;
67 	case 4800:
68 		prescalar = 625U;
69 		first_mod_reg = 0U;
70 		second_mod_reg = 0U;
71 		break;
72 	case 9600:
73 		prescalar = 312U;
74 		first_mod_reg = 8U;
75 		second_mod_reg = 0U;
76 		break;
77 	case 19200:
78 		prescalar = 156U;
79 		first_mod_reg = 4U;
80 		second_mod_reg = 0U;
81 		break;
82 	case 38400:
83 		prescalar = 78U;
84 		first_mod_reg = 2U;
85 		second_mod_reg = 0U;
86 		break;
87 	case 57600:
88 		prescalar = 52U;
89 		first_mod_reg = 1U;
90 		second_mod_reg = 37U;
91 		break;
92 	case 115200:
93 		prescalar = 26U;
94 		first_mod_reg = 0U;
95 		second_mod_reg = 111U;
96 		break;
97 	case 230400:
98 		prescalar = 13U;
99 		first_mod_reg = 0U;
100 		second_mod_reg = 37U;
101 		break;
102 	case 460800:
103 		prescalar = 6U;
104 		first_mod_reg = 8U;
105 		second_mod_reg = 32U;
106 		break;
107 	default:
108 		return -EINVAL;
109 	}
110 
111 	config->clockPrescalar = prescalar;
112 	config->firstModReg = first_mod_reg;
113 	config->secondModReg = second_mod_reg;
114 
115 	return 0;
116 }
117 
uart_msp432p4xx_init(const struct device * dev)118 static int uart_msp432p4xx_init(const struct device *dev)
119 {
120 	int err;
121 	const struct uart_device_config *config = DEV_CFG(dev);
122 	eUSCI_UART_Config UartConfig;
123 
124 	/* Select P1.2 and P1.3 in UART mode */
125 	MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
126 		(GPIO_PIN2 | GPIO_PIN3), GPIO_PRIMARY_MODULE_FUNCTION);
127 
128 	UartConfig.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
129 	UartConfig.parity = EUSCI_A_UART_NO_PARITY;
130 	UartConfig.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
131 	UartConfig.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
132 	UartConfig.uartMode = EUSCI_A_UART_MODE;
133 	UartConfig.overSampling = EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
134 
135 	/* Baud rate settings calculated for 48MHz */
136 	err = baudrate_set(&UartConfig, DT_INST_PROP(0, current_speed));
137 	if (err) {
138 		return err;
139 	}
140 	/* Configure UART Module */
141 	MAP_UART_initModule((unsigned long)config->base, &UartConfig);
142 
143 	/* Enable UART module */
144 	MAP_UART_enableModule((unsigned long)config->base);
145 
146 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
147 	IRQ_CONNECT(DT_INST_IRQN(0),
148 			DT_INST_IRQ(0, priority),
149 			uart_msp432p4xx_isr, DEVICE_DT_INST_GET(0),
150 			0);
151 	irq_enable(DT_INST_IRQN(0));
152 
153 #endif
154 	return 0;
155 }
156 
uart_msp432p4xx_poll_in(const struct device * dev,unsigned char * c)157 static int uart_msp432p4xx_poll_in(const struct device *dev, unsigned char *c)
158 {
159 	const struct uart_device_config *config = DEV_CFG(dev);
160 
161 	*c = MAP_UART_receiveData((unsigned long)config->base);
162 
163 	return 0;
164 }
165 
uart_msp432p4xx_poll_out(const struct device * dev,unsigned char c)166 static void uart_msp432p4xx_poll_out(const struct device *dev,
167 				     unsigned char c)
168 {
169 	const struct uart_device_config *config = DEV_CFG(dev);
170 
171 	MAP_UART_transmitData((unsigned long)config->base, c);
172 }
173 
174 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_msp432p4xx_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)175 static int uart_msp432p4xx_fifo_fill(const struct device *dev,
176 						const uint8_t *tx_data, int size)
177 {
178 	const struct uart_device_config *config = DEV_CFG(dev);
179 	unsigned int num_tx = 0U;
180 
181 	while ((size - num_tx) > 0) {
182 		MAP_UART_transmitData((unsigned long)config->base,
183 							tx_data[num_tx]);
184 		if (MAP_UART_getInterruptStatus((unsigned long)config->base,
185 			EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG)) {
186 			num_tx++;
187 		} else {
188 			break;
189 		}
190 	}
191 
192 	return (int)num_tx;
193 }
194 
uart_msp432p4xx_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)195 static int uart_msp432p4xx_fifo_read(const struct device *dev,
196 							uint8_t *rx_data,
197 							const int size)
198 {
199 	const struct uart_device_config *config = DEV_CFG(dev);
200 	unsigned int num_rx = 0U;
201 
202 	while (((size - num_rx) > 0) &&
203 		MAP_UART_getInterruptStatus((unsigned long)config->base,
204 					EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)) {
205 
206 		rx_data[num_rx++] =
207 			MAP_UART_receiveData((unsigned long)config->base);
208 	}
209 
210 	return num_rx;
211 }
212 
uart_msp432p4xx_irq_tx_enable(const struct device * dev)213 static void uart_msp432p4xx_irq_tx_enable(const struct device *dev)
214 {
215 	const struct uart_device_config *config = DEV_CFG(dev);
216 
217 	MAP_UART_enableInterrupt((unsigned long)config->base,
218 					EUSCI_A_UART_TRANSMIT_INTERRUPT);
219 }
220 
uart_msp432p4xx_irq_tx_disable(const struct device * dev)221 static void uart_msp432p4xx_irq_tx_disable(const struct device *dev)
222 {
223 	const struct uart_device_config *config = DEV_CFG(dev);
224 
225 	MAP_UART_disableInterrupt((unsigned long)config->base,
226 					EUSCI_A_UART_TRANSMIT_INTERRUPT);
227 }
228 
uart_msp432p4xx_irq_tx_ready(const struct device * dev)229 static int uart_msp432p4xx_irq_tx_ready(const struct device *dev)
230 {
231 	const struct uart_device_config *config = DEV_CFG(dev);
232 	unsigned int int_status;
233 
234 	int_status =  MAP_UART_getInterruptStatus((unsigned long)config->base,
235 					EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG);
236 
237 	return (int_status & EUSCI_A_IE_TXIE);
238 }
239 
uart_msp432p4xx_irq_rx_enable(const struct device * dev)240 static void uart_msp432p4xx_irq_rx_enable(const struct device *dev)
241 {
242 	const struct uart_device_config *config = DEV_CFG(dev);
243 
244 	MAP_UART_enableInterrupt((unsigned long)config->base,
245 				EUSCI_A_UART_RECEIVE_INTERRUPT);
246 }
247 
uart_msp432p4xx_irq_rx_disable(const struct device * dev)248 static void uart_msp432p4xx_irq_rx_disable(const struct device *dev)
249 {
250 	const struct uart_device_config *config = DEV_CFG(dev);
251 
252 	MAP_UART_disableInterrupt((unsigned long)config->base,
253 				EUSCI_A_UART_RECEIVE_INTERRUPT);
254 }
255 
uart_msp432p4xx_irq_tx_complete(const struct device * dev)256 static int uart_msp432p4xx_irq_tx_complete(const struct device *dev)
257 {
258 	const struct uart_device_config *config = DEV_CFG(dev);
259 
260 	return MAP_UART_getInterruptStatus((unsigned long)config->base,
261 				EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG);
262 }
263 
uart_msp432p4xx_irq_rx_ready(const struct device * dev)264 static int uart_msp432p4xx_irq_rx_ready(const struct device *dev)
265 {
266 	const struct uart_device_config *config = DEV_CFG(dev);
267 	unsigned int int_status;
268 
269 	int_status = MAP_UART_getInterruptStatus((unsigned long)config->base,
270 					EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG);
271 
272 	return (int_status & EUSCI_A_IE_RXIE);
273 }
274 
uart_msp432p4xx_irq_err_enable(const struct device * dev)275 static void uart_msp432p4xx_irq_err_enable(const struct device *dev)
276 {
277 	/* Not yet used in zephyr */
278 }
279 
uart_msp432p4xx_irq_err_disable(const struct device * dev)280 static void uart_msp432p4xx_irq_err_disable(const struct device *dev)
281 {
282 	/* Not yet used in zephyr */
283 }
284 
uart_msp432p4xx_irq_is_pending(const struct device * dev)285 static int uart_msp432p4xx_irq_is_pending(const struct device *dev)
286 {
287 	const struct uart_device_config *config = DEV_CFG(dev);
288 	unsigned int int_status;
289 
290 	int_status = MAP_UART_getEnabledInterruptStatus(
291 						(unsigned long)config->base);
292 
293 	return (int_status & (EUSCI_A_IE_TXIE | EUSCI_A_IE_RXIE));
294 }
295 
uart_msp432p4xx_irq_update(const struct device * dev)296 static int uart_msp432p4xx_irq_update(const struct device *dev)
297 {
298 	return 1;
299 }
300 
uart_msp432p4xx_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)301 static void uart_msp432p4xx_irq_callback_set(const struct device *dev,
302 					     uart_irq_callback_user_data_t cb,
303 					     void *cb_data)
304 {
305 	struct uart_msp432p4xx_dev_data_t * const dev_data = DEV_DATA(dev);
306 
307 	dev_data->cb = cb;
308 	dev_data->cb_data = cb_data;
309 }
310 
311 /**
312  * @brief Interrupt service routine.
313  *
314  * This simply calls the callback function, if one exists.
315  *
316  * @param arg Argument to ISR.
317  *
318  * @return N/A
319  */
uart_msp432p4xx_isr(const struct device * dev)320 static void uart_msp432p4xx_isr(const struct device *dev)
321 {
322 	const struct uart_device_config *config = DEV_CFG(dev);
323 	struct uart_msp432p4xx_dev_data_t * const dev_data = DEV_DATA(dev);
324 	unsigned int int_status;
325 
326 	int_status = MAP_UART_getEnabledInterruptStatus(
327 						(unsigned long)config->base);
328 
329 	if (dev_data->cb) {
330 		dev_data->cb(dev, dev_data->cb_data);
331 	}
332 	/*
333 	 * Clear interrupts only after cb called, as Zephyr UART clients expect
334 	 * to check interrupt status during the callback.
335 	 */
336 	MAP_UART_disableInterrupt((unsigned long)config->base, int_status);
337 }
338 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
339 
340 static const struct uart_driver_api uart_msp432p4xx_driver_api = {
341 	.poll_in = uart_msp432p4xx_poll_in,
342 	.poll_out = uart_msp432p4xx_poll_out,
343 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
344 	.fifo_fill	  = uart_msp432p4xx_fifo_fill,
345 	.fifo_read	  = uart_msp432p4xx_fifo_read,
346 	.irq_tx_enable	  = uart_msp432p4xx_irq_tx_enable,
347 	.irq_tx_disable	  = uart_msp432p4xx_irq_tx_disable,
348 	.irq_tx_ready	  = uart_msp432p4xx_irq_tx_ready,
349 	.irq_rx_enable	  = uart_msp432p4xx_irq_rx_enable,
350 	.irq_rx_disable	  = uart_msp432p4xx_irq_rx_disable,
351 	.irq_tx_complete  = uart_msp432p4xx_irq_tx_complete,
352 	.irq_rx_ready	  = uart_msp432p4xx_irq_rx_ready,
353 	.irq_err_enable	  = uart_msp432p4xx_irq_err_enable,
354 	.irq_err_disable  = uart_msp432p4xx_irq_err_disable,
355 	.irq_is_pending	  = uart_msp432p4xx_irq_is_pending,
356 	.irq_update	  = uart_msp432p4xx_irq_update,
357 	.irq_callback_set = uart_msp432p4xx_irq_callback_set,
358 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
359 };
360 
361 DEVICE_DT_INST_DEFINE(0,
362 			uart_msp432p4xx_init, NULL,
363 			&uart_msp432p4xx_dev_data_0,
364 			&uart_msp432p4xx_dev_cfg_0,
365 			PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY,
366 			(void *)&uart_msp432p4xx_driver_api);
367