uart_sio.c (3142B)
1 // Copyright 2024 Stefan Kerkmann (@KarlK90) 2 // Copyright 2021 QMK 3 // SPDX-License-Identifier: GPL-2.0-or-later 4 5 #include "uart.h" 6 #include "gpio.h" 7 #include "chibios_config.h" 8 #include <hal.h> 9 10 #ifndef UART_DRIVER 11 # define UART_DRIVER SIOD1 12 #endif 13 14 #ifndef UART_TX_PIN 15 # define UART_TX_PIN A9 16 #endif 17 18 #ifndef UART_TX_PAL_MODE 19 # ifdef USE_GPIOV1 20 # define UART_TX_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL 21 # else 22 # define UART_TX_PAL_MODE 7 23 # endif 24 #endif 25 26 #ifndef UART_RX_PIN 27 # define UART_RX_PIN A10 28 #endif 29 30 #ifndef UART_RX_PAL_MODE 31 # ifdef USE_GPIOV1 32 # define UART_RX_PAL_MODE PAL_MODE_INPUT 33 # else 34 # define UART_RX_PAL_MODE 7 35 # endif 36 #endif 37 38 #ifndef UART_CTS_PIN 39 # define UART_CTS_PIN A11 40 #endif 41 42 #ifndef UART_CTS_PAL_MODE 43 # ifdef USE_GPIOV1 44 # define UART_CTS_PAL_MODE PAL_MODE_INPUT 45 # else 46 # define UART_CTS_PAL_MODE 7 47 # endif 48 #endif 49 50 #ifndef UART_RTS_PIN 51 # define UART_RTS_PIN A12 52 #endif 53 54 #ifndef UART_RTS_PAL_MODE 55 # ifdef USE_GPIOV1 56 # define UART_RTS_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL 57 # else 58 # define UART_RTS_PAL_MODE 7 59 # endif 60 #endif 61 62 #ifndef UART_CR1 63 # define UART_CR1 0 64 #endif 65 66 #ifndef UART_CR2 67 # define UART_CR2 0 68 #endif 69 70 #ifndef UART_CR3 71 # define UART_CR3 0 72 #endif 73 74 #if defined(MCU_RP) 75 // 38400 baud, 8 data bits, 1 stop bit, no parity, no flow control 76 static SIOConfig sioConfig = { 77 .baud = SIO_DEFAULT_BITRATE, 78 .UARTLCR_H = (UART_UARTLCR_H_WLEN_8BITS | UART_UARTLCR_H_FEN), 79 .UARTCR = 0U, 80 .UARTIFLS = (UART_UARTIFLS_RXIFLSEL_1_8F | UART_UARTIFLS_TXIFLSEL_1_8E), 81 .UARTDMACR = 0U, 82 }; 83 #else 84 static SIOConfig sioConfig = { 85 .baud = SIO_DEFAULT_BITRATE, 86 # if defined(MCU_STM32) && defined(USE_USARTV3) 87 .presc = USART_PRESC1, 88 # endif 89 .cr1 = UART_CR1, 90 .cr2 = UART_CR2, 91 .cr3 = UART_CR3, 92 }; 93 #endif 94 95 void uart_init(uint32_t baud) { 96 static bool is_initialised = false; 97 98 if (is_initialised) { 99 return; 100 } 101 is_initialised = true; 102 103 sioConfig.baud = baud; 104 105 #if defined(USE_GPIOV1) 106 palSetLineMode(UART_TX_PIN, UART_TX_PAL_MODE); 107 palSetLineMode(UART_RX_PIN, UART_RX_PAL_MODE); 108 #else 109 palSetLineMode(UART_TX_PIN, PAL_MODE_ALTERNATE(UART_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); 110 palSetLineMode(UART_RX_PIN, PAL_MODE_ALTERNATE(UART_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST); 111 #endif 112 113 sioStart(&UART_DRIVER, &sioConfig); 114 } 115 116 void uart_write(uint8_t data) { 117 chnPutTimeout(&UART_DRIVER, data, TIME_INFINITE); 118 } 119 120 uint8_t uart_read(void) { 121 msg_t result = chnGetTimeout(&UART_DRIVER, TIME_INFINITE); 122 123 if (sioHasRXErrorsX(&UART_DRIVER)) { 124 sioGetAndClearErrors(&UART_DRIVER); 125 } 126 127 return (uint8_t)result; 128 } 129 130 void uart_transmit(const uint8_t *data, uint16_t length) { 131 chnWrite(&UART_DRIVER, data, length); 132 } 133 134 void uart_receive(uint8_t *data, uint16_t length) { 135 chnRead(&UART_DRIVER, data, length); 136 137 if (sioHasRXErrorsX(&UART_DRIVER)) { 138 sioGetAndClearErrors(&UART_DRIVER); 139 } 140 } 141 142 bool uart_available() { 143 return !sioIsRXEmptyX(&UART_DRIVER); 144 }