diff options
author | Stefan Kerkmann <karlk90@pm.me> | 2024-02-20 11:34:24 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-20 11:34:24 +0100 |
commit | 61fa6949fbb537f54d48a4fc0218ff2b6873e940 (patch) | |
tree | 400f8f4920888097c0e22c68cb5fa742b0e340c8 /platforms/chibios/drivers | |
parent | 865a8f42a6128dfc09a24fe749b0d78d8c69b70e (diff) |
[Core] Allow ChibiOS `SIO` driver for `UART` driver (#22839)
* onekey: stm32f3_disco: add usart pins and activate peripheral
Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
* chibios: uart: change SD1 prefix to UART
Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
* chibios: uart: add SIO driver and RP2040 compatibility
Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
* Update platforms/chibios/drivers/uart.h
Co-authored-by: Joel Challis <git@zvecr.com>
---------
Signed-off-by: Stefan Kerkmann <karlk90@pm.me>
Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
Co-authored-by: Joel Challis <git@zvecr.com>
Diffstat (limited to 'platforms/chibios/drivers')
-rw-r--r-- | platforms/chibios/drivers/uart.c | 70 | ||||
-rw-r--r-- | platforms/chibios/drivers/uart.h | 194 | ||||
-rw-r--r-- | platforms/chibios/drivers/uart_serial.c | 65 | ||||
-rw-r--r-- | platforms/chibios/drivers/uart_sio.c | 77 |
4 files changed, 281 insertions, 125 deletions
diff --git a/platforms/chibios/drivers/uart.c b/platforms/chibios/drivers/uart.c deleted file mode 100644 index 39a59dd445..0000000000 --- a/platforms/chibios/drivers/uart.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright 2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -#include "uart.h" - -#if defined(MCU_KINETIS) -static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE}; -#elif defined(WB32F3G71xx) || defined(WB32FQ95xx) -static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE, SD1_WRDLEN, SD1_STPBIT, SD1_PARITY, SD1_ATFLCT}; -#else -static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE, SD1_CR1, SD1_CR2, SD1_CR3}; -#endif - -void uart_init(uint32_t baud) { - static bool is_initialised = false; - - if (!is_initialised) { - is_initialised = true; - -#if defined(MCU_KINETIS) - serialConfig.sc_speed = baud; -#else - serialConfig.speed = baud; -#endif - -#if defined(USE_GPIOV1) - palSetLineMode(SD1_TX_PIN, SD1_TX_PAL_MODE); - palSetLineMode(SD1_RX_PIN, SD1_RX_PAL_MODE); -#else - palSetLineMode(SD1_TX_PIN, PAL_MODE_ALTERNATE(SD1_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); - palSetLineMode(SD1_RX_PIN, PAL_MODE_ALTERNATE(SD1_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); -#endif - sdStart(&SERIAL_DRIVER, &serialConfig); - } -} - -void uart_write(uint8_t data) { - sdPut(&SERIAL_DRIVER, data); -} - -uint8_t uart_read(void) { - msg_t res = sdGet(&SERIAL_DRIVER); - - return (uint8_t)res; -} - -void uart_transmit(const uint8_t *data, uint16_t length) { - sdWrite(&SERIAL_DRIVER, data, length); -} - -void uart_receive(uint8_t *data, uint16_t length) { - sdRead(&SERIAL_DRIVER, data, length); -} - -bool uart_available(void) { - return !sdGetWouldBlock(&SERIAL_DRIVER); -} diff --git a/platforms/chibios/drivers/uart.h b/platforms/chibios/drivers/uart.h index 16983072ce..c1945575f1 100644 --- a/platforms/chibios/drivers/uart.h +++ b/platforms/chibios/drivers/uart.h @@ -1,18 +1,7 @@ -/* Copyright 2021 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ +// Copyright 2024 Stefan Kerkmann +// Copyright 2021 QMK +// Copyright 2024 Stefan Kerkmann +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -24,93 +13,188 @@ #include "gpio.h" #include "chibios_config.h" -#ifndef SERIAL_DRIVER -# define SERIAL_DRIVER SD1 +// ======== DEPRECATED DEFINES - DO NOT USE ======== +#ifdef SERIAL_DRIVER +# define UART_DRIVER SERIAL_DRIVER +#endif +#ifdef SD1_TX_PIN +# define UART_TX_PIN SD1_TX_PIN +#endif +#ifdef SD1_RX_PIN +# define UART_RX_PIN SD1_RX_PIN +#endif +#ifdef SD1_CTS_PIN +# define UART_CTS_PIN SD1_CTS_PIN +#endif +#ifdef SD1_RTS_PIN +# define UART_RTS_PIN SD1_RTS_PIN +#endif +#ifdef SD1_TX_PAL_MODE +# define UART_TX_PAL_MODE SD1_TX_PAL_MODE +#endif +#ifdef SD1_RX_PAL_MODE +# define UART_RX_PAL_MODE SD1_RX_PAL_MODE +#endif +#ifdef SD1_CTS_PAL_MODE +# define UART_RTS_PAL_MODE SD1_CTS_PAL_MODE +#endif +#ifdef SD1_RTS_PAL_MODE +# define UART_TX_PAL_MODE SD1_RTS_PAL_MODE +#endif +#ifdef SD1_CR1 +# define UART_CR1 SD1_CR1 +#endif +#ifdef SD1_CR2 +# define UART_CR2 SD1_CR2 +#endif +#ifdef SD1_CR3 +# define UART_CR3 SD1_CR3 +#endif +#ifdef SD1_WRDLEN +# define UART_WRDLEN SD1_WRDLEN +#endif +#ifdef SD1_STPBIT +# define UART_STPBIT SD1_STPBIT +#endif +#ifdef SD1_PARITY +# define UART_PARITY SD1_PARITY +#endif +#ifdef SD1_ATFLCT +# define UART_ATFLCT SD1_ATFLCT +#endif +// ======== + +#ifndef UART_DRIVER +# if (HAL_USE_SERIAL == TRUE) +# define UART_DRIVER SD1 +# elif (HAL_USE_SIO == TRUE) +# define UART_DRIVER SIOD1 +# endif #endif -#ifndef SD1_TX_PIN -# define SD1_TX_PIN A9 +#ifndef UART_TX_PIN +# define UART_TX_PIN A9 #endif -#ifndef SD1_RX_PIN -# define SD1_RX_PIN A10 +#ifndef UART_RX_PIN +# define UART_RX_PIN A10 #endif -#ifndef SD1_CTS_PIN -# define SD1_CTS_PIN A11 +#ifndef UART_CTS_PIN +# define UART_CTS_PIN A11 #endif -#ifndef SD1_RTS_PIN -# define SD1_RTS_PIN A12 +#ifndef UART_RTS_PIN +# define UART_RTS_PIN A12 #endif #ifdef USE_GPIOV1 -# ifndef SD1_TX_PAL_MODE -# define SD1_TX_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL +# ifndef UART_TX_PAL_MODE +# define UART_TX_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL # endif -# ifndef SD1_RX_PAL_MODE -# define SD1_RX_PAL_MODE PAL_MODE_INPUT +# ifndef UART_RX_PAL_MODE +# define UART_RX_PAL_MODE PAL_MODE_INPUT # endif -# ifndef SD1_CTS_PAL_MODE -# define SD1_CTS_PAL_MODE PAL_MODE_INPUT +# ifndef UART_CTS_PAL_MODE +# define UART_CTS_PAL_MODE PAL_MODE_INPUT # endif -# ifndef SD1_RTS_PAL_MODE -# define SD1_RTS_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL +# ifndef UART_RTS_PAL_MODE +# define UART_RTS_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL # endif #else -# ifndef SD1_TX_PAL_MODE -# define SD1_TX_PAL_MODE 7 +# ifndef UART_TX_PAL_MODE +# define UART_TX_PAL_MODE 7 # endif -# ifndef SD1_RX_PAL_MODE -# define SD1_RX_PAL_MODE 7 +# ifndef UART_RX_PAL_MODE +# define UART_RX_PAL_MODE 7 # endif -# ifndef SD1_CTS_PAL_MODE -# define SD1_CTS_PAL_MODE 7 +# ifndef UART_CTS_PAL_MODE +# define UART_CTS_PAL_MODE 7 # endif -# ifndef SD1_RTS_PAL_MODE -# define SD1_RTS_PAL_MODE 7 +# ifndef UART_RTS_PAL_MODE +# define UART_RTS_PAL_MODE 7 # endif #endif -#ifndef SD1_CR1 -# define SD1_CR1 0 +#ifndef UART_CR1 +# define UART_CR1 0 #endif -#ifndef SD1_CR2 -# define SD1_CR2 0 +#ifndef UART_CR2 +# define UART_CR2 0 #endif -#ifndef SD1_CR3 -# define SD1_CR3 0 +#ifndef UART_CR3 +# define UART_CR3 0 #endif -#ifndef SD1_WRDLEN -# define SD1_WRDLEN 3 +#ifndef UART_WRDLEN +# define UART_WRDLEN 3 #endif -#ifndef SD1_STPBIT -# define SD1_STPBIT 0 +#ifndef UART_STPBIT +# define UART_STPBIT 0 #endif -#ifndef SD1_PARITY -# define SD1_PARITY 0 +#ifndef UART_PARITY +# define UART_PARITY 0 #endif -#ifndef SD1_ATFLCT -# define SD1_ATFLCT 0 +#ifndef UART_ATFLCT +# define UART_ATFLCT 0 #endif +/** + * @brief Initialize the UART driver. This function must be called only once, + * before any of the below functions can be called. + * + * @param baud The baud rate to transmit and receive at. This may depend on the + * device you are communicating with. Common values are 1200, 2400, 4800, 9600, + * 19200, 38400, 57600, and 115200. + */ void uart_init(uint32_t baud); +/** + * @brief Transmit a single byte. + * + * @param data The byte to transmit. + */ void uart_write(uint8_t data); +/** + * @brief Receive a single byte. + * + * @return uint8_t The byte read from the receive buffer. This function will + * block if the buffer is empty (ie. no data to read). + */ uint8_t uart_read(void); +/** + * @brief Transmit multiple bytes. + * + * @param data A pointer to the data to write from. + * @param length The number of bytes to write. Take care not to overrun the + * length of `data`. + */ void uart_transmit(const uint8_t *data, uint16_t length); +/** + * @brief Receive multiple bytes. + * + * @param data A pointer to the buffer to read into. + * @param length The number of bytes to read. Take care not to overrun the + * length of `data`. + */ void uart_receive(uint8_t *data, uint16_t length); +/** + * @brief Return whether the receive buffer contains data. Call this function + * to determine if `uart_read()` will return data immediately. + * + * @return true If there is data available to read. + * @return false If there is no data available to read. + */ bool uart_available(void); diff --git a/platforms/chibios/drivers/uart_serial.c b/platforms/chibios/drivers/uart_serial.c new file mode 100644 index 0000000000..6aff4eae47 --- /dev/null +++ b/platforms/chibios/drivers/uart_serial.c @@ -0,0 +1,65 @@ +// Copyright 2024 Stefan Kerkmann (@KarlK90) +// Copyright 2021 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "uart.h" + +#if defined(MCU_KINETIS) +static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE}; +#elif defined(WB32F3G71xx) || defined(WB32FQ95xx) +static SerialConfig serialConfig = { + SERIAL_DEFAULT_BITRATE, UART_WRDLEN, UART_STPBIT, UART_PARITY, UART_ATFLCT, +}; +#else +static SerialConfig serialConfig = { + SERIAL_DEFAULT_BITRATE, + UART_CR1, + UART_CR2, + UART_CR3, +}; +#endif + +void uart_init(uint32_t baud) { + static bool is_initialised = false; + + if (is_initialised) { + return; + } + is_initialised = true; + +#if defined(MCU_KINETIS) + serialConfig.sc_speed = baud; +#else + serialConfig.speed = baud; +#endif + +#if defined(USE_GPIOV1) + palSetLineMode(UART_TX_PIN, UART_TX_PAL_MODE); + palSetLineMode(UART_RX_PIN, UART_RX_PAL_MODE); +#else + palSetLineMode(UART_TX_PIN, PAL_MODE_ALTERNATE(UART_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); + palSetLineMode(UART_RX_PIN, PAL_MODE_ALTERNATE(UART_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); +#endif + + sdStart(&UART_DRIVER, &serialConfig); +} + +void uart_write(uint8_t data) { + sdPut(&UART_DRIVER, data); +} + +uint8_t uart_read(void) { + return (uint8_t)sdGet(&UART_DRIVER); +} + +void uart_transmit(const uint8_t *data, uint16_t length) { + sdWrite(&UART_DRIVER, data, length); +} + +void uart_receive(uint8_t *data, uint16_t length) { + sdRead(&UART_DRIVER, data, length); +} + +bool uart_available(void) { + return !sdGetWouldBlock(&UART_DRIVER); +} diff --git a/platforms/chibios/drivers/uart_sio.c b/platforms/chibios/drivers/uart_sio.c new file mode 100644 index 0000000000..ebf51ae5a8 --- /dev/null +++ b/platforms/chibios/drivers/uart_sio.c @@ -0,0 +1,77 @@ +// Copyright 2024 Stefan Kerkmann (@KarlK90) +// Copyright 2021 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "uart.h" + +#if defined(MCU_RP) +// 38400 baud, 8 data bits, 1 stop bit, no parity, no flow control +static SIOConfig sioConfig = { + .baud = SIO_DEFAULT_BITRATE, + .UARTLCR_H = (UART_UARTLCR_H_WLEN_8BITS | UART_UARTLCR_H_FEN), + .UARTCR = 0U, + .UARTIFLS = (UART_UARTIFLS_RXIFLSEL_1_8F | UART_UARTIFLS_TXIFLSEL_1_8E), + .UARTDMACR = 0U, +}; +#else +static SIOConfig sioConfig = { + .baud = SIO_DEFAULT_BITRATE, +# if defined(MCU_STM32) && defined(CHIBIOS_HAL_USARTv3) + .presc = USART_PRESC1, +# endif + .cr1 = UART_CR1, + .cr2 = UART_CR2, + .cr3 = UART_CR3, +}; +#endif + +void uart_init(uint32_t baud) { + static bool is_initialised = false; + + if (is_initialised) { + return; + } + is_initialised = true; + + sioConfig.baud = baud; + +#if defined(USE_GPIOV1) + palSetLineMode(UART_TX_PIN, UART_TX_PAL_MODE); + palSetLineMode(UART_RX_PIN, UART_RX_PAL_MODE); +#else + palSetLineMode(UART_TX_PIN, PAL_MODE_ALTERNATE(UART_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); + palSetLineMode(UART_RX_PIN, PAL_MODE_ALTERNATE(UART_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); +#endif + + sioStart(&UART_DRIVER, &sioConfig); +} + +void uart_write(uint8_t data) { + chnPutTimeout(&UART_DRIVER, data, TIME_INFINITE); +} + +uint8_t uart_read(void) { + msg_t result = chnGetTimeout(&UART_DRIVER, TIME_INFINITE); + + if (sioHasRXErrorsX(&UART_DRIVER)) { + sioGetAndClearErrors(&UART_DRIVER); + } + + return (uint8_t)result; +} + +void uart_transmit(const uint8_t *data, uint16_t length) { + chnWrite(&UART_DRIVER, data, length); +} + +void uart_receive(uint8_t *data, uint16_t length) { + chnRead(&UART_DRIVER, data, length); + + if (sioHasRXErrorsX(&UART_DRIVER)) { + sioGetAndClearErrors(&UART_DRIVER); + } +} + +bool uart_available() { + return !sioIsRXEmptyX(&UART_DRIVER); +} |