Skip to content

Commit f236a56

Browse files
ssekar15kartben
authored andcommitted
drivers: serial: Add initial support TI MSPM0 UART
Add initial support for TI MSPM0 UART with basic poll-in and poll-out functionality. Signed-off-by: Saravanan Sekar <[email protected]> Signed-off-by: Jackson Farley <[email protected]>
1 parent ff3ec74 commit f236a56

File tree

5 files changed

+184
-0
lines changed

5 files changed

+184
-0
lines changed

drivers/serial/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_MCUX_LPSCI uart_mcux_lpsci.c)
5353
zephyr_library_sources_ifdef(CONFIG_UART_MCUX_LPUART uart_mcux_lpuart.c)
5454
zephyr_library_sources_ifdef(CONFIG_UART_MIV uart_miv.c)
5555
zephyr_library_sources_ifdef(CONFIG_UART_MSP432P4XX uart_msp432p4xx.c)
56+
zephyr_library_sources_ifdef(CONFIG_UART_MSPM0 uart_mspm0.c)
5657
zephyr_library_sources_ifdef(CONFIG_UART_NEORV32 uart_neorv32.c)
5758
zephyr_library_sources_ifdef(CONFIG_UART_NPCX uart_npcx.c)
5859
zephyr_library_sources_ifdef(CONFIG_UART_NRFX_UART uart_nrfx_uart.c)

drivers/serial/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ rsource "Kconfig.mcux_lpuart"
196196
rsource "Kconfig.mec5"
197197
rsource "Kconfig.miv"
198198
rsource "Kconfig.msp432p4xx"
199+
rsource "Kconfig.mspm0"
199200
rsource "Kconfig.native_pty"
200201
rsource "Kconfig.native_tty"
201202
rsource "Kconfig.neorv32"

drivers/serial/Kconfig.mspm0

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# Copyright (c) 2025 Texas Instruments
3+
# Copyright (c) 2025 Linumiz
4+
5+
config UART_MSPM0
6+
bool "MSPM0 UART driver"
7+
default y
8+
depends on DT_HAS_TI_MSPM0_UART_ENABLED
9+
select SERIAL_HAS_DRIVER
10+
select USE_MSPM0_DL_UART
11+
select PINCTRL
12+
help
13+
This option enables the TI MSPM0 UART driver.

drivers/serial/uart_mspm0.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Copyright (c) 2025 Texas Instruments
3+
* Copyright (c) 2025 Linumiz
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#define DT_DRV_COMPAT ti_mspm0_uart
9+
10+
/* Zephyr includes */
11+
#include <zephyr/kernel.h>
12+
#include <zephyr/drivers/clock_control.h>
13+
#include <zephyr/drivers/clock_control/mspm0_clock_control.h>
14+
#include <zephyr/drivers/pinctrl.h>
15+
#include <zephyr/drivers/uart.h>
16+
#include <zephyr/irq.h>
17+
18+
/* Driverlib includes */
19+
#include <ti/driverlib/dl_uart_main.h>
20+
21+
struct uart_mspm0_config {
22+
UART_Regs *regs;
23+
uint32_t current_speed;
24+
const struct mspm0_sys_clock *clock_subsys;
25+
const struct pinctrl_dev_config *pinctrl;
26+
};
27+
28+
struct uart_mspm0_data {
29+
/* UART clock structure */
30+
DL_UART_Main_ClockConfig uart_clockconfig;
31+
/* UART config structure */
32+
DL_UART_Main_Config uart_config;
33+
};
34+
35+
static int uart_mspm0_init(const struct device *dev)
36+
{
37+
const struct uart_mspm0_config *config = dev->config;
38+
struct uart_mspm0_data *data = dev->data;
39+
const struct device *clk_dev = DEVICE_DT_GET(DT_NODELABEL(ckm));
40+
uint32_t clock_rate;
41+
int ret;
42+
43+
/* Reset power */
44+
DL_UART_Main_reset(config->regs);
45+
DL_UART_Main_enablePower(config->regs);
46+
delay_cycles(CONFIG_MSPM0_PERIPH_STARTUP_DELAY);
47+
48+
/* Init UART pins */
49+
ret = pinctrl_apply_state(config->pinctrl, PINCTRL_STATE_DEFAULT);
50+
if (ret < 0) {
51+
return ret;
52+
}
53+
54+
/* Set UART configs */
55+
DL_UART_Main_setClockConfig(config->regs,
56+
&data->uart_clockconfig);
57+
DL_UART_Main_init(config->regs, &data->uart_config);
58+
59+
/*
60+
* Configure baud rate by setting oversampling and baud rate divisor
61+
* from the device tree data current-speed
62+
*/
63+
ret = clock_control_get_rate(clk_dev,
64+
(struct mspm0_sys_clock *)config->clock_subsys,
65+
&clock_rate);
66+
if (ret < 0) {
67+
return ret;
68+
}
69+
70+
DL_UART_Main_configBaudRate(config->regs,
71+
clock_rate,
72+
config->current_speed);
73+
74+
/* Enable UART */
75+
DL_UART_Main_enable(config->regs);
76+
77+
return 0;
78+
}
79+
80+
static int uart_mspm0_poll_in(const struct device *dev, unsigned char *c)
81+
{
82+
const struct uart_mspm0_config *config = dev->config;
83+
84+
if (DL_UART_Main_receiveDataCheck(config->regs, c) == false) {
85+
return -1;
86+
}
87+
88+
return 0;
89+
}
90+
91+
static void uart_mspm0_poll_out(const struct device *dev, unsigned char c)
92+
{
93+
const struct uart_mspm0_config *config = dev->config;
94+
95+
DL_UART_Main_transmitDataBlocking(config->regs, c);
96+
}
97+
98+
static const struct uart_driver_api uart_mspm0_driver_api = {
99+
.poll_in = uart_mspm0_poll_in,
100+
.poll_out = uart_mspm0_poll_out,
101+
};
102+
103+
#define MSPM0_MAIN_CLK_DIV(n) CONCAT(DL_UART_MAIN_CLOCK_DIVIDE_RATIO_, DT_INST_PROP(n, clk_div))
104+
105+
#define MSPM0_UART_INIT_FN(index) \
106+
\
107+
PINCTRL_DT_INST_DEFINE(index); \
108+
\
109+
static const struct mspm0_sys_clock mspm0_uart_sys_clock##index = \
110+
MSPM0_CLOCK_SUBSYS_FN(index); \
111+
\
112+
static const struct uart_mspm0_config uart_mspm0_cfg_##index = { \
113+
.regs = (UART_Regs *)DT_INST_REG_ADDR(index), \
114+
.current_speed = DT_INST_PROP(index, current_speed), \
115+
.pinctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
116+
.clock_subsys = &mspm0_uart_sys_clock##index, \
117+
}; \
118+
\
119+
static struct uart_mspm0_data uart_mspm0_data_##index = { \
120+
.uart_clockconfig = { \
121+
.clockSel = MSPM0_CLOCK_PERIPH_REG_MASK(DT_INST_CLOCKS_CELL(index, clk)), \
122+
.divideRatio = MSPM0_MAIN_CLK_DIV(index), \
123+
}, \
124+
.uart_config = {.mode = DL_UART_MAIN_MODE_NORMAL, \
125+
.direction = DL_UART_MAIN_DIRECTION_TX_RX, \
126+
.flowControl = (DT_INST_PROP(index, hw_flow_control) \
127+
? DL_UART_MAIN_FLOW_CONTROL_RTS_CTS \
128+
: DL_UART_MAIN_FLOW_CONTROL_NONE), \
129+
.parity = DL_UART_MAIN_PARITY_NONE, \
130+
.wordLength = DL_UART_MAIN_WORD_LENGTH_8_BITS, \
131+
.stopBits = DL_UART_MAIN_STOP_BITS_ONE, \
132+
}, \
133+
}; \
134+
\
135+
DEVICE_DT_INST_DEFINE(index, &uart_mspm0_init, NULL, &uart_mspm0_data_##index, \
136+
&uart_mspm0_cfg_##index, PRE_KERNEL_1, \
137+
CONFIG_SERIAL_INIT_PRIORITY, &uart_mspm0_driver_api);
138+
139+
DT_INST_FOREACH_STATUS_OKAY(MSPM0_UART_INIT_FN)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
description: TI MSPM0 UART
2+
3+
compatible: "ti,mspm0-uart"
4+
5+
include: [uart-controller.yaml, pinctrl-device.yaml, base.yaml]
6+
7+
properties:
8+
reg:
9+
required: true
10+
11+
pinctrl-0:
12+
required: true
13+
14+
pinctrl-names:
15+
required: true
16+
17+
clk-div:
18+
type: int
19+
default: 1
20+
enum:
21+
- 1
22+
- 2
23+
- 3
24+
- 4
25+
- 5
26+
- 6
27+
- 7
28+
- 8
29+
description: |
30+
Clock divider selction value.

0 commit comments

Comments
 (0)