Skip to content

Commit 0ac278b

Browse files
committed
drivers: serial: rpi_pico: added functions for runtime uart configuration
Added functions for runtime uart configuartion for raspberry pico Signed-off-by: Akos Melczer <[email protected]>
1 parent 1629a2f commit 0ac278b

File tree

1 file changed

+96
-6
lines changed

1 file changed

+96
-6
lines changed

drivers/serial/uart_rpi_pico.c

+96-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <zephyr/drivers/reset.h>
1010
#include <zephyr/drivers/pinctrl.h>
1111
#include <zephyr/irq.h>
12+
#include <string.h>
1213

1314
/* pico-sdk includes */
1415
#include <hardware/uart.h>
@@ -26,7 +27,7 @@ struct uart_rpi_config {
2627
};
2728

2829
struct uart_rpi_data {
29-
uint32_t baudrate;
30+
struct uart_config uart_config;
3031
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
3132
uart_irq_callback_user_data_t irq_cb;
3233
void *irq_cb_data;
@@ -64,7 +65,8 @@ static int uart_rpi_init(const struct device *dev)
6465
uart_inst_t * const uart_inst = config->uart_dev;
6566
uart_hw_t * const uart_hw = config->uart_regs;
6667
struct uart_rpi_data * const data = dev->data;
67-
int ret, baudrate;
68+
uint baudrate;
69+
int ret;
6870

6971
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
7072
if (ret < 0) {
@@ -75,12 +77,27 @@ static int uart_rpi_init(const struct device *dev)
7577
* uart_init() may be replaced by register based API once rpi-pico platform
7678
* has a clock controller driver
7779
*/
78-
baudrate = uart_init(uart_inst, data->baudrate);
80+
baudrate = uart_init(uart_inst, data->uart_config.baudrate);
7981
/* Check if baudrate adjustment returned by 'uart_init' function is a positive value */
80-
if (baudrate <= 0) {
82+
if (baudrate == 0) {
8183
return -EINVAL;
8284
}
83-
85+
/*
86+
* initialize uart_config with hardware reset values
87+
* https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#tab-registerlist_uart page:431
88+
* data bits set default to 8 instaed of hardware reset 5 to increase compatibility.
89+
*/
90+
data->uart_config = (struct uart_config){
91+
.baudrate = baudrate,
92+
.data_bits = UART_CFG_DATA_BITS_8,
93+
.flow_ctrl = UART_CFG_FLOW_CTRL_NONE,
94+
.parity = UART_CFG_PARITY_NONE,
95+
.stop_bits = UART_CFG_STOP_BITS_1
96+
};
97+
uart_set_format(uart_inst,
98+
data->uart_config.data_bits,
99+
data->uart_config.stop_bits,
100+
data->uart_config.parity);
84101
hw_clear_bits(&uart_hw->lcr_h, UART_UARTLCR_H_FEN_BITS);
85102
uart_hw->dr = 0U;
86103

@@ -91,6 +108,75 @@ static int uart_rpi_init(const struct device *dev)
91108
return 0;
92109
}
93110

111+
static int uart_rpi_config_get(const struct device *dev, struct uart_config *cfg)
112+
{
113+
struct uart_rpi_data *data = dev->data;
114+
115+
memcpy(cfg, &data->uart_config, sizeof(struct uart_config));
116+
return 0;
117+
}
118+
119+
static int uart_rpi_configure(const struct device *dev, const struct uart_config *cfg)
120+
{
121+
const struct uart_rpi_config *config = dev->config;
122+
uart_inst_t * const uart_inst = config->uart_dev;
123+
struct uart_rpi_data *data = dev->data;
124+
uart_parity_t parity = 0;
125+
uint data_bits = 0;
126+
uint stop_bits = 0;
127+
uint baudrate = 0;
128+
129+
switch (cfg->data_bits) {
130+
case UART_CFG_DATA_BITS_5:
131+
data_bits = 5;
132+
break;
133+
case UART_CFG_DATA_BITS_6:
134+
data_bits = 6;
135+
break;
136+
case UART_CFG_DATA_BITS_7:
137+
data_bits = 7;
138+
break;
139+
case UART_CFG_DATA_BITS_8:
140+
data_bits = 8;
141+
break;
142+
default:
143+
return -EINVAL;
144+
}
145+
146+
switch (cfg->stop_bits) {
147+
case UART_CFG_STOP_BITS_1:
148+
stop_bits = 1;
149+
break;
150+
case UART_CFG_STOP_BITS_2:
151+
stop_bits = 2;
152+
break;
153+
default:
154+
return -EINVAL;
155+
}
156+
157+
switch (cfg->parity) {
158+
case UART_CFG_PARITY_NONE:
159+
parity = UART_PARITY_NONE;
160+
break;
161+
case UART_CFG_PARITY_EVEN:
162+
parity = UART_PARITY_EVEN;
163+
break;
164+
case UART_CFG_PARITY_ODD:
165+
parity = UART_PARITY_ODD;
166+
break;
167+
default:
168+
return -EINVAL;
169+
}
170+
171+
baudrate = uart_set_baudrate(uart_inst, cfg->baudrate);
172+
if (baudrate == 0) {
173+
return -EINVAL;
174+
}
175+
uart_set_format(uart_inst, data_bits, stop_bits, parity);
176+
data->uart_config = *cfg;
177+
return 0;
178+
}
179+
94180
static int uart_rpi_err_check(const struct device *dev)
95181
{
96182
const struct uart_rpi_config * const config = dev->config;
@@ -264,6 +350,10 @@ static const struct uart_driver_api uart_rpi_driver_api = {
264350
.poll_in = uart_rpi_poll_in,
265351
.poll_out = uart_rpi_poll_out,
266352
.err_check = uart_rpi_err_check,
353+
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
354+
.configure = uart_rpi_configure,
355+
.config_get = uart_rpi_config_get,
356+
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
267357
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
268358
.fifo_fill = uart_rpi_fifo_fill,
269359
.fifo_read = uart_rpi_fifo_read,
@@ -310,7 +400,7 @@ static const struct uart_driver_api uart_rpi_driver_api = {
310400
}; \
311401
\
312402
static struct uart_rpi_data uart##idx##_rpi_data = { \
313-
.baudrate = DT_INST_PROP(idx, current_speed), \
403+
.uart_config.baudrate = DT_INST_PROP(idx, current_speed), \
314404
}; \
315405
\
316406
DEVICE_DT_INST_DEFINE(idx, &uart_rpi_init, \

0 commit comments

Comments
 (0)