/* * Copyright (c) 2025 Texas Instruments * Copyright (c) 2025 Linumiz * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT ti_mspm0_uart /* Zephyr includes */ #include #include #include #include #include #include /* Driverlib includes */ #include struct uart_mspm0_config { UART_Regs *regs; uint32_t current_speed; const struct mspm0_sys_clock *clock_subsys; const struct pinctrl_dev_config *pinctrl; }; struct uart_mspm0_data { /* UART clock structure */ DL_UART_Main_ClockConfig uart_clockconfig; /* UART config structure */ DL_UART_Main_Config uart_config; }; static int uart_mspm0_init(const struct device *dev) { const struct uart_mspm0_config *config = dev->config; struct uart_mspm0_data *data = dev->data; const struct device *clk_dev = DEVICE_DT_GET(DT_NODELABEL(ckm)); uint32_t clock_rate; int ret; /* Reset power */ DL_UART_Main_reset(config->regs); DL_UART_Main_enablePower(config->regs); delay_cycles(CONFIG_MSPM0_PERIPH_STARTUP_DELAY); /* Init UART pins */ ret = pinctrl_apply_state(config->pinctrl, PINCTRL_STATE_DEFAULT); if (ret < 0) { return ret; } /* Set UART configs */ DL_UART_Main_setClockConfig(config->regs, &data->uart_clockconfig); DL_UART_Main_init(config->regs, &data->uart_config); /* * Configure baud rate by setting oversampling and baud rate divisor * from the device tree data current-speed */ ret = clock_control_get_rate(clk_dev, (struct mspm0_sys_clock *)config->clock_subsys, &clock_rate); if (ret < 0) { return ret; } DL_UART_Main_configBaudRate(config->regs, clock_rate, config->current_speed); /* Enable UART */ DL_UART_Main_enable(config->regs); return 0; } static int uart_mspm0_poll_in(const struct device *dev, unsigned char *c) { const struct uart_mspm0_config *config = dev->config; if (DL_UART_Main_receiveDataCheck(config->regs, c) == false) { return -1; } return 0; } static void uart_mspm0_poll_out(const struct device *dev, unsigned char c) { const struct uart_mspm0_config *config = dev->config; DL_UART_Main_transmitDataBlocking(config->regs, c); } static DEVICE_API(uart, uart_mspm0_driver_api) = { .poll_in = uart_mspm0_poll_in, .poll_out = uart_mspm0_poll_out, }; #define MSPM0_MAIN_CLK_DIV(n) CONCAT(DL_UART_MAIN_CLOCK_DIVIDE_RATIO_, DT_INST_PROP(n, clk_div)) #define MSPM0_UART_INIT_FN(index) \ \ PINCTRL_DT_INST_DEFINE(index); \ \ static const struct mspm0_sys_clock mspm0_uart_sys_clock##index = \ MSPM0_CLOCK_SUBSYS_FN(index); \ \ static const struct uart_mspm0_config uart_mspm0_cfg_##index = { \ .regs = (UART_Regs *)DT_INST_REG_ADDR(index), \ .current_speed = DT_INST_PROP(index, current_speed), \ .pinctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \ .clock_subsys = &mspm0_uart_sys_clock##index, \ }; \ \ static struct uart_mspm0_data uart_mspm0_data_##index = { \ .uart_clockconfig = { \ .clockSel = MSPM0_CLOCK_PERIPH_REG_MASK(DT_INST_CLOCKS_CELL(index, clk)), \ .divideRatio = MSPM0_MAIN_CLK_DIV(index), \ }, \ .uart_config = {.mode = DL_UART_MAIN_MODE_NORMAL, \ .direction = DL_UART_MAIN_DIRECTION_TX_RX, \ .flowControl = (DT_INST_PROP(index, hw_flow_control) \ ? DL_UART_MAIN_FLOW_CONTROL_RTS_CTS \ : DL_UART_MAIN_FLOW_CONTROL_NONE), \ .parity = DL_UART_MAIN_PARITY_NONE, \ .wordLength = DL_UART_MAIN_WORD_LENGTH_8_BITS, \ .stopBits = DL_UART_MAIN_STOP_BITS_ONE, \ }, \ }; \ \ DEVICE_DT_INST_DEFINE(index, &uart_mspm0_init, NULL, &uart_mspm0_data_##index, \ &uart_mspm0_cfg_##index, PRE_KERNEL_1, \ CONFIG_SERIAL_INIT_PRIORITY, &uart_mspm0_driver_api); DT_INST_FOREACH_STATUS_OKAY(MSPM0_UART_INIT_FN)