diff options
Diffstat (limited to 'platforms/chibios/drivers/serial_usart.c')
-rw-r--r-- | platforms/chibios/drivers/serial_usart.c | 237 |
1 files changed, 0 insertions, 237 deletions
diff --git a/platforms/chibios/drivers/serial_usart.c b/platforms/chibios/drivers/serial_usart.c deleted file mode 100644 index 767ef8726f..0000000000 --- a/platforms/chibios/drivers/serial_usart.c +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2021 QMK -// Copyright 2022 Stefan Kerkmann -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "serial_usart.h" -#include "serial_protocol.h" -#include "synchronization_util.h" -#include "chibios_config.h" - -#if defined(SERIAL_USART_CONFIG) -static QMKSerialConfig serial_config = SERIAL_USART_CONFIG; -#elif defined(MCU_STM32) /* STM32 MCUs */ -static QMKSerialConfig serial_config = { -# if HAL_USE_SERIAL - .speed = (SERIAL_USART_SPEED), -# else - .baud = (SERIAL_USART_SPEED), -# endif - .cr1 = (SERIAL_USART_CR1), - .cr2 = (SERIAL_USART_CR2), -# if !defined(SERIAL_USART_FULL_DUPLEX) - .cr3 = ((SERIAL_USART_CR3) | USART_CR3_HDSEL) /* activate half-duplex mode */ -# else - .cr3 = (SERIAL_USART_CR3) -# endif -}; -#elif defined(MCU_RP) /* Raspberry Pi MCUs */ -/* USART in 8E2 config with RX and TX FIFOs enabled. */ -// clang-format off -static QMKSerialConfig serial_config = { - .baud = (SERIAL_USART_SPEED), - .UARTLCR_H = UART_UARTLCR_H_WLEN_8BITS | UART_UARTLCR_H_PEN | UART_UARTLCR_H_STP2 | UART_UARTLCR_H_FEN, - .UARTCR = 0U, - .UARTIFLS = UART_UARTIFLS_RXIFLSEL_1_8F | UART_UARTIFLS_TXIFLSEL_1_8E, - .UARTDMACR = 0U -}; -// clang-format on -#else -# error MCU Familiy not supported by default, supply your own serial_config by defining SERIAL_USART_CONFIG in your keyboard files. -#endif - -static QMKSerialDriver* serial_driver = (QMKSerialDriver*)&SERIAL_USART_DRIVER; - -#if HAL_USE_SERIAL - -/** - * @brief SERIAL Driver startup routine. - */ -static inline void usart_driver_start(void) { - sdStart(serial_driver, &serial_config); -} - -inline void serial_transport_driver_clear(void) { - osalSysLock(); - bool volatile queue_not_empty = !iqIsEmptyI(&serial_driver->iqueue); - osalSysUnlock(); - - while (queue_not_empty) { - osalSysLock(); - /* Hard reset the input queue. */ - iqResetI(&serial_driver->iqueue); - osalSysUnlock(); - /* Allow pending interrupts to preempt. - * Do not merge the lock/unlock blocks into one - * or the code will not work properly. - * The empty read adds a tiny amount of delay. */ - (void)queue_not_empty; - osalSysLock(); - queue_not_empty = !iqIsEmptyI(&serial_driver->iqueue); - osalSysUnlock(); - } -} - -#elif HAL_USE_SIO - -/** - * @brief SIO Driver startup routine. - */ -static inline void usart_driver_start(void) { - sioStart(serial_driver, &serial_config); -} - -inline void serial_transport_driver_clear(void) { - if (sioHasRXErrorsX(serial_driver)) { - sioGetAndClearErrors(serial_driver); - } - osalSysLock(); - while (!sioIsRXEmptyX(serial_driver)) { - (void)sioGetX(serial_driver); - } - osalSysUnlock(); -} - -#else - -# error Either the SERIAL or SIO driver has to be activated to use the usart driver for split keyboards. - -#endif - -inline bool serial_transport_send(const uint8_t* source, const size_t size) { - bool success = (size_t)chnWriteTimeout(serial_driver, source, size, TIME_MS2I(SERIAL_USART_TIMEOUT)) == size; - -#if !defined(SERIAL_USART_FULL_DUPLEX) - /* Half duplex fills the input queue with the data we wrote - just throw it away. */ - if (likely(success)) { - size_t bytes_left = size; -# if HAL_USE_SERIAL - /* The SERIAL driver uses large soft FIFOs that are filled from an IRQ - * context, so there is a delay between receiving the data and it - * becoming actually available, therefore we have to apply a timeout - * mechanism. Under the right circumstances (e.g. bad cables paired with - * high baud rates) less bytes can be present in the input queue as - * well. */ - uint8_t dump[64]; - - while (unlikely(bytes_left >= 64)) { - if (unlikely(!serial_transport_receive(dump, 64))) { - return false; - } - bytes_left -= 64; - } - - return serial_transport_receive(dump, bytes_left); -# else - /* The SIO driver directly accesses the hardware FIFOs of the USART - * peripheral. As these are limited in depth, the RX FIFO might have - * been overflowed by a large transaction that we just send. Therefore - * we attempt to read back all the data we send or until the FIFO runs - * empty in case it overflowed and data was truncated. */ - if (unlikely(sioSynchronizeTXEnd(serial_driver, TIME_MS2I(SERIAL_USART_TIMEOUT)) < MSG_OK)) { - return false; - } - - osalSysLock(); - while (bytes_left > 0 && !sioIsRXEmptyX(serial_driver)) { - (void)sioGetX(serial_driver); - bytes_left--; - } - osalSysUnlock(); -# endif - } -#endif - - return success; -} - -inline bool serial_transport_receive(uint8_t* destination, const size_t size) { - bool success = (size_t)chnReadTimeout(serial_driver, destination, size, TIME_MS2I(SERIAL_USART_TIMEOUT)) == size; - return success; -} - -inline bool serial_transport_receive_blocking(uint8_t* destination, const size_t size) { - bool success = (size_t)chnRead(serial_driver, destination, size) == size; - return success; -} - -#if !defined(SERIAL_USART_FULL_DUPLEX) - -/** - * @brief Initiate pins for USART peripheral. Half-duplex configuration. - */ -__attribute__((weak)) void usart_init(void) { -# if defined(MCU_STM32) /* STM32 MCUs */ -# if defined(USE_GPIOV1) - palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_OPENDRAIN); -# else - palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE(SERIAL_USART_TX_PAL_MODE) | PAL_OUTPUT_TYPE_OPENDRAIN); -# endif - -# if defined(USART_REMAP) - USART_REMAP; -# endif -# elif defined(MCU_RP) /* Raspberry Pi MCUs */ -# error Half-duplex with the SIO driver is not supported due to hardware limitations on the RP2040, switch to the PIO driver which has half-duplex support. -# else -# pragma message "usart_init: MCU Familiy not supported by default, please supply your own init code by implementing usart_init() in your keyboard files." -# endif -} - -#else - -/** - * @brief Initiate pins for USART peripheral. Full-duplex configuration. - */ -__attribute__((weak)) void usart_init(void) { -# if defined(MCU_STM32) /* STM32 MCUs */ -# if defined(USE_GPIOV1) - palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_PUSHPULL); - palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_INPUT); -# else - palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE(SERIAL_USART_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); - palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_ALTERNATE(SERIAL_USART_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); -# endif - -# if defined(USART_REMAP) - USART_REMAP; -# endif -# elif defined(MCU_RP) /* Raspberry Pi MCUs */ - palSetLineMode(SERIAL_USART_TX_PIN, PAL_MODE_ALTERNATE_UART); - palSetLineMode(SERIAL_USART_RX_PIN, PAL_MODE_ALTERNATE_UART); -# else -# pragma message "usart_init: MCU Familiy not supported by default, please supply your own init code by implementing usart_init() in your keyboard files." -# endif -} - -#endif - -/** - * @brief Overridable master specific initializations. - */ -__attribute__((weak, nonnull)) void usart_master_init(QMKSerialDriver** driver) { - (void)driver; - usart_init(); -} - -/** - * @brief Overridable slave specific initializations. - */ -__attribute__((weak, nonnull)) void usart_slave_init(QMKSerialDriver** driver) { - (void)driver; - usart_init(); -} - -void serial_transport_driver_slave_init(void) { - usart_slave_init(&serial_driver); - usart_driver_start(); -} - -void serial_transport_driver_master_init(void) { - usart_master_init(&serial_driver); - -#if defined(MCU_STM32) && defined(SERIAL_USART_PIN_SWAP) - serial_config.cr2 |= USART_CR2_SWAP; // master has swapped TX/RX pins -#endif - - usart_driver_start(); -} |