summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2021-01-27 17:42:49 +1100
committerGitHub <noreply@github.com>2021-01-27 17:42:49 +1100
commit30b46fad5764b54ab4d47e9c4024f8030e1bf1a7 (patch)
tree9a9aa60158edf5adea802e33ee2db2ba4164145a
parentbe897cbc2f9d542dfcc98c8e06aeb04179cc484c (diff)
UART driver refactor (#11637)
-rw-r--r--docs/_summary.md1
-rw-r--r--docs/uart_driver.md90
-rw-r--r--drivers/avr/uart.c (renamed from tmk_core/common/uart.c)42
-rw-r--r--drivers/avr/uart.h34
-rw-r--r--drivers/chibios/uart.c59
-rw-r--r--drivers/chibios/uart.h77
-rw-r--r--keyboards/mschwingen/modelm/rules.mk2
-rw-r--r--keyboards/nullbitsco/nibble/remote_kb.c1
-rw-r--r--keyboards/nullbitsco/nibble/remote_kb.h1
-rw-r--r--keyboards/nullbitsco/nibble/rules.mk7
-rw-r--r--platforms/chibios/QMK_PROTON_C/configs/mcuconf.h4
-rw-r--r--tmk_core/common/uart.h8
12 files changed, 287 insertions, 39 deletions
diff --git a/docs/_summary.md b/docs/_summary.md
index 9bc0b193a7..526caf926f 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -138,6 +138,7 @@
* [WS2812 Driver](ws2812_driver.md)
* [EEPROM Driver](eeprom_driver.md)
* ['serial' Driver](serial_driver.md)
+ * [UART Driver](uart_driver.md)
* [GPIO Controls](internals_gpio_control.md)
* [Keyboard Guidelines](hardware_keyboard_guidelines.md)
diff --git a/docs/uart_driver.md b/docs/uart_driver.md
new file mode 100644
index 0000000000..4d1716975f
--- /dev/null
+++ b/docs/uart_driver.md
@@ -0,0 +1,90 @@
+# UART Driver
+
+The UART drivers used in QMK have a set of common functions to allow portability between MCUs.
+
+Currently, this driver does not support enabling hardware flow control (the `RTS` and `CTS` pins) if available, but may do so in future.
+
+## AVR Configuration
+
+No special setup is required - just connect the `RX` and `TX` pins of your UART device to the opposite pins on the MCU:
+
+|MCU |`TX`|`RX`|`CTS`|`RTS`|
+|-------------|----|----|-----|-----|
+|ATmega16/32U2|`D3`|`D2`|`D7` |`D6` |
+|ATmega16/32U4|`D3`|`D2`|`D5` |`B7` |
+|AT90USB64/128|`D3`|`D2`|*n/a*|*n/a*|
+|ATmega32A |`D1`|`D0`|*n/a*|*n/a*|
+|ATmega328/P |`D1`|`D0`|*n/a*|*n/a*|
+
+## ChibiOS/ARM Configuration
+
+You'll need to determine which pins can be used for UART -- as an example, STM32 parts generally have multiple UART peripherals, labeled USART1, USART2, USART3 etc.
+
+To enable UART, modify your board's `halconf.h` to enable the serial driver:
+
+```c
+#define HAL_USE_SERIAL TRUE
+```
+
+Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example:
+
+```c
+#undef STM32_SERIAL_USE_USART2
+#define STM32_SERIAL_USE_USART2 TRUE
+```
+
+Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303.
+
+|`config.h` override |Description |Default Value|
+|--------------------------|---------------------------------------------------------------|-------------|
+|`#define SERIAL_DRIVER` |USART peripheral to use - USART1 -> `SD1`, USART2 -> `SD2` etc.|`SD1` |
+|`#define SD1_TX_PIN` |The pin to use for TX |`A9` |
+|`#define SD1_TX_PAL_MODE` |The alternate function mode for TX |`7` |
+|`#define SD1_RX_PIN` |The pin to use for RX |`A10` |
+|`#define SD1_RX_PAL_MODE` |The alternate function mode for RX |`7` |
+|`#define SD1_CTS_PIN` |The pin to use for CTS |`A11` |
+|`#define SD1_CTS_PAL_MODE`|The alternate function mode for CTS |`7` |
+|`#define SD1_RTS_PIN` |The pin to use for RTS |`A12` |
+|`#define SD1_RTS_PAL_MODE`|The alternate function mode for RTS |`7` |
+
+## Functions
+
+### `void uart_init(uint32_t baud)`
+
+Initialize the UART driver. This function must be called only once, before any of the below functions can be called.
+
+#### Arguments
+
+ - `uint32_t 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_putchar(uint8_t c)`
+
+Transmit a single byte.
+
+#### Arguments
+
+ - `uint8_t c`
+ The byte (character) to send, from 0 to 255.
+
+---
+
+### `uint8_t uart_getchar(void)`
+
+Receive a single byte.
+
+#### Return Value
+
+The byte read from the receive buffer.
+
+---
+
+### `bool uart_available(void)`
+
+Return whether the receive buffer contains data. Call this function to determine if `uart_getchar()` will return meaningful data.
+
+#### Return Value
+
+`true` if the receive buffer length is non-zero.
diff --git a/tmk_core/common/uart.c b/drivers/avr/uart.c
index 150e256c8f..e866a9e4f8 100644
--- a/tmk_core/common/uart.c
+++ b/drivers/avr/uart.c
@@ -1,5 +1,3 @@
-// TODO: Teensy support(ATMega32u4/AT90USB128)
-// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
/* UART Example for Teensy USB Development Board
* http://www.pjrc.com/teensy/
* Copyright (c) 2009 PJRC.COM, LLC
@@ -31,22 +29,7 @@
#include "uart.h"
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
-# define UDRn UDR0
-# define UBRRnL UBRR0L
-# define UCSRnA UCSR0A
-# define UCSRnB UCSR0B
-# define UCSRnC UCSR0C
-# define U2Xn U2X0
-# define RXENn RXEN0
-# define TXENn TXEN0
-# define RXCIEn RXCIE0
-# define UCSZn1 UCSZ01
-# define UCSZn0 UCSZ00
-# define UDRIEn UDRIE0
-# define USARTn_UDRE_vect USART_UDRE_vect
-# define USARTn_RX_vect USART_RX_vect
-#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
+#if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
# define UDRn UDR1
# define UBRRnL UBRR1L
# define UCSRnA UCSR1A
@@ -76,6 +59,21 @@
# define UDRIEn UDRIE
# define USARTn_UDRE_vect USART_UDRE_vect
# define USARTn_RX_vect USART_RX_vect
+#elif defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
+# define UDRn UDR0
+# define UBRRnL UBRR0L
+# define UCSRnA UCSR0A
+# define UCSRnB UCSR0B
+# define UCSRnC UCSR0C
+# define U2Xn U2X0
+# define RXENn RXEN0
+# define TXENn TXEN0
+# define RXCIEn RXCIE0
+# define UCSZn1 UCSZ01
+# define UCSZn0 UCSZ00
+# define UDRIEn UDRIE0
+# define USARTn_UDRE_vect USART_UDRE_vect
+# define USARTn_RX_vect USART_RX_vect
#endif
// These buffers may be any size from 2 to 256 bytes.
@@ -131,16 +129,16 @@ uint8_t uart_getchar(void) {
return c;
}
-// Return the number of bytes waiting in the receive buffer.
+// Return whether the number of bytes waiting in the receive buffer is nonzero.
// Call this before uart_getchar() to check if it will need
// to wait for a byte to arrive.
-uint8_t uart_available(void) {
+bool uart_available(void) {
uint8_t head, tail;
head = rx_buffer_head;
tail = rx_buffer_tail;
- if (head >= tail) return head - tail;
- return RX_BUFFER_SIZE + head - tail;
+ if (head >= tail) return (head - tail) > 0;
+ return (RX_BUFFER_SIZE + head - tail) > 0;
}
// Transmit Interrupt
diff --git a/drivers/avr/uart.h b/drivers/avr/uart.h
new file mode 100644
index 0000000000..d5ec563db2
--- /dev/null
+++ b/drivers/avr/uart.h
@@ -0,0 +1,34 @@
+/* UART Example for Teensy USB Development Board
+ * http://www.pjrc.com/teensy/
+ * Copyright (c) 2009 PJRC.COM, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+void uart_init(uint32_t baud);
+
+void uart_putchar(uint8_t c);
+
+uint8_t uart_getchar(void);
+
+bool uart_available(void);
diff --git a/drivers/chibios/uart.c b/drivers/chibios/uart.c
new file mode 100644
index 0000000000..6e94899b9d
--- /dev/null
+++ b/drivers/chibios/uart.c
@@ -0,0 +1,59 @@
+/* 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"
+
+#include "quantum.h"
+
+static SerialConfig serialConfig = {
+ SERIAL_DEFAULT_BITRATE,
+ SD1_CR1,
+ SD1_CR2,
+ SD1_CR3
+};
+
+void uart_init(uint32_t baud) {
+ static bool is_initialised = false;
+
+ if (!is_initialised) {
+ is_initialised = true;
+
+ serialConfig.speed = baud;
+
+#if defined(USE_GPIOV1)
+ palSetLineMode(SD1_TX_PIN, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
+ palSetLineMode(SD1_RX_PIN, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
+#else
+ palSetLineMode(SD1_TX_PIN, PAL_MODE_ALTERNATE(SD1_TX_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
+ palSetLineMode(SD1_RX_PIN, PAL_MODE_ALTERNATE(SD1_RX_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
+#endif
+ sdStart(&SERIAL_DRIVER, &serialConfig);
+ }
+}
+
+void uart_putchar(uint8_t c) {
+ sdPut(&SERIAL_DRIVER, c);
+}
+
+uint8_t uart_getchar(void) {
+ msg_t res = sdGet(&SERIAL_DRIVER);
+
+ return (uint8_t)res;
+}
+
+bool uart_available(void) {
+ return !sdGetWouldBlock(&SERIAL_DRIVER);
+}
diff --git a/drivers/chibios/uart.h b/drivers/chibios/uart.h
new file mode 100644
index 0000000000..b4e20e9fd3
--- /dev/null
+++ b/drivers/chibios/uart.h
@@ -0,0 +1,77 @@
+/* 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/>.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <hal.h>
+
+#ifndef SERIAL_DRIVER
+# define SERIAL_DRIVER SD1
+#endif
+
+#ifndef SD1_TX_PIN
+# define SD1_TX_PIN A9
+#endif
+
+#ifndef SD1_TX_PAL_MODE
+# define SD1_TX_PAL_MODE 7
+#endif
+
+#ifndef SD1_RX_PIN
+# define SD1_RX_PIN A10
+#endif
+
+#ifndef SD1_RX_PAL_MODE
+# define SD1_RX_PAL_MODE 7
+#endif
+
+#ifndef SD1_CTS_PIN
+# define SD1_CTS_PIN A11
+#endif
+
+#ifndef SD1_CTS_PAL_MODE
+# define SD1_CTS_PAL_MODE 7
+#endif
+
+#ifndef SD1_RTS_PIN
+# define SD1_RTS_PIN A12
+#endif
+
+#ifndef SD1_RTS_PAL_MODE
+# define SD1_RTS_PAL_MODE 7
+#endif
+
+#ifndef SD1_CR1
+# define SD1_CR1 0
+#endif
+
+#ifndef SD1_CR2
+# define SD1_CR2 0
+#endif
+
+#ifndef SD1_CR3
+# define SD1_CR3 0
+#endif
+
+void uart_init(uint32_t baud);
+
+void uart_putchar(uint8_t c);
+
+uint8_t uart_getchar(void);
+
+bool uart_available(void);
diff --git a/keyboards/mschwingen/modelm/rules.mk b/keyboards/mschwingen/modelm/rules.mk
index f3af26eeeb..6775dfa203 100644
--- a/keyboards/mschwingen/modelm/rules.mk
+++ b/keyboards/mschwingen/modelm/rules.mk
@@ -29,7 +29,7 @@ DYNAMIC_MACRO_ENABLE = yes
UART_DEBUG = no
SRC += matrix.c
-QUANTUM_LIB_SRC += $(COMMON_DIR)/uart.c \
+QUANTUM_LIB_SRC += uart.c \
spi_master.c
OPT_DEFS += -DSLEEP_LED_ENABLE # we need our own sleep callbacks to turn of WS2812 LEDs
diff --git a/keyboards/nullbitsco/nibble/remote_kb.c b/keyboards/nullbitsco/nibble/remote_kb.c
index 2e36f5f22e..7a914993f3 100644
--- a/keyboards/nullbitsco/nibble/remote_kb.c
+++ b/keyboards/nullbitsco/nibble/remote_kb.c
@@ -27,6 +27,7 @@ This will require a new communication protocol, as the current one is limited.
*/
#include "remote_kb.h"
+#include "uart.h"
uint8_t
msg[UART_MSG_LEN],
diff --git a/keyboards/nullbitsco/nibble/remote_kb.h b/keyboards/nullbitsco/nibble/remote_kb.h
index e2b24655b5..f4b5c43f5d 100644
--- a/keyboards/nullbitsco/nibble/remote_kb.h
+++ b/keyboards/nullbitsco/nibble/remote_kb.h
@@ -16,7 +16,6 @@
#pragma once
#include "quantum.h"
-#include "tmk_core/common/uart.h"
#define SERIAL_UART_BAUD 153600 //low error rate for 32u4 @ 16MHz
diff --git a/keyboards/nullbitsco/nibble/rules.mk b/keyboards/nullbitsco/nibble/rules.mk
index 683e290866..9340214027 100644
--- a/keyboards/nullbitsco/nibble/rules.mk
+++ b/keyboards/nullbitsco/nibble/rules.mk
@@ -1,9 +1,6 @@
# MCU name
MCU = atmega32u4
-# Interrupt driven control endpoint task(+60)
-OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
-
# Bootloader selection
BOOTLOADER = atmel-dfu
@@ -31,5 +28,5 @@ CUSTOM_MATRIX = lite # Lite custom matrix
SRC += matrix.c \
bitc_led.c \
big_led.c \
- remote_kb.c \
- tmk_core/common/uart.c
+ remote_kb.c
+QUANTUM_LIB_SRC += uart.c
diff --git a/platforms/chibios/QMK_PROTON_C/configs/mcuconf.h b/platforms/chibios/QMK_PROTON_C/configs/mcuconf.h
index ac2d9a1eed..4d7b586c08 100644
--- a/platforms/chibios/QMK_PROTON_C/configs/mcuconf.h
+++ b/platforms/chibios/QMK_PROTON_C/configs/mcuconf.h
@@ -212,8 +212,8 @@
/*
* SERIAL driver system settings.
*/
-#define STM32_SERIAL_USE_USART1 FALSE
-#define STM32_SERIAL_USE_USART2 TRUE
+#define STM32_SERIAL_USE_USART1 TRUE
+#define STM32_SERIAL_USE_USART2 FALSE
#define STM32_SERIAL_USE_USART3 FALSE
#define STM32_SERIAL_USE_UART4 FALSE
#define STM32_SERIAL_USE_UART5 FALSE
diff --git a/tmk_core/common/uart.h b/tmk_core/common/uart.h
deleted file mode 100644
index ea247b17b8..0000000000
--- a/tmk_core/common/uart.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-void uart_init(uint32_t baud);
-void uart_putchar(uint8_t c);
-uint8_t uart_getchar(void);
-uint8_t uart_available(void);