Update UART driver API (#14839)

* Add uart_puts() and uart_gets()

* Add some docs

* Rework API

* Formatting

* Update docs/uart_driver.md

Co-authored-by: Sergey Vlasov <sigprof@gmail.com>

* Simplify a uart_write() loop

* Update platforms/avr/drivers/uart.c

Co-authored-by: Joel Challis <git@zvecr.com>

Co-authored-by: Sergey Vlasov <sigprof@gmail.com>
Co-authored-by: Joel Challis <git@zvecr.com>
This commit is contained in:
Ryan 2021-11-14 05:23:14 +11:00 committed by GitHub
parent 7e86c37962
commit 04b51e381e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 72 additions and 25 deletions

View file

@ -60,30 +60,56 @@ Initialize the UART driver. This function must be called only once, before any o
--- ---
### `void uart_putchar(uint8_t c)` ### `void uart_write(uint8_t data)`
Transmit a single byte. Transmit a single byte.
#### Arguments #### Arguments
- `uint8_t c` - `uint8_t data`
The byte (character) to send, from 0 to 255. The byte to write.
--- ---
### `uint8_t uart_getchar(void)` ### `uint8_t uart_read(void)`
Receive a single byte. Receive a single byte.
#### Return Value #### Return Value
The byte read from the receive buffer. The byte read from the receive buffer. This function will block if the buffer is empty (ie. no data to read).
---
### `void uart_transmit(const uint8_t *data, uint16_t length)`
Transmit multiple bytes.
#### Arguments
- `const uint8_t *data`
A pointer to the data to write from.
- `uint16_t length`
The number of bytes to write. Take care not to overrun the length of `data`.
---
### `void uart_receive(char *data, uint16_t length)`
Receive multiple bytes.
#### Arguments
- `uint8_t *data`
A pointer to the buffer to read into.
- `uint16_t length`
The number of bytes to read. Take care not to overrun the length of `data`.
--- ---
### `bool uart_available(void)` ### `bool uart_available(void)`
Return whether the receive buffer contains data. Call this function to determine if `uart_getchar()` will return meaningful data. Return whether the receive buffer contains data. Call this function to determine if `uart_read()` will return data immediately.
#### Return Value #### Return Value

View file

@ -27,7 +27,7 @@
# undef sendchar # undef sendchar
static int8_t capture_sendchar(uint8_t c) { static int8_t capture_sendchar(uint8_t c) {
// sendchar(c); // sendchar(c);
uart_putchar(c); uart_write(c);
return 0; return 0;
} }
#endif #endif

View file

@ -63,9 +63,7 @@ static void send_msg(uint16_t keycode, bool pressed) {
msg[IDX_PRESSED] = pressed; msg[IDX_PRESSED] = pressed;
msg[IDX_CHECKSUM] = chksum8(msg, UART_MSG_LEN-1); msg[IDX_CHECKSUM] = chksum8(msg, UART_MSG_LEN-1);
for (int i=0; i<UART_MSG_LEN; i++) { uart_transmit(msg, UART_MSG_LEN);
uart_putchar(msg[i]);
}
} }
static void print_message_buffer(void) { static void print_message_buffer(void) {
@ -103,7 +101,7 @@ static void process_uart(void) {
static void get_msg(void) { static void get_msg(void) {
while (uart_available()) { while (uart_available()) {
msg[msg_idx] = uart_getchar(); msg[msg_idx] = uart_read();
dprintf("idx: %u, recv: %u\n", msg_idx, msg[msg_idx]); dprintf("idx: %u, recv: %u\n", msg_idx, msg[msg_idx]);
if (msg_idx == 0 && (msg[msg_idx] != UART_PREAMBLE)) { if (msg_idx == 0 && (msg[msg_idx] != UART_PREAMBLE)) {
dprintf("Byte sync error!\n"); dprintf("Byte sync error!\n");

View file

@ -24,6 +24,5 @@ COMMON_VPATH += $(QUANTUM_PATH)
COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras
COMMON_VPATH += $(QUANTUM_PATH)/audio COMMON_VPATH += $(QUANTUM_PATH)/audio
COMMON_VPATH += $(QUANTUM_PATH)/process_keycode COMMON_VPATH += $(QUANTUM_PATH)/process_keycode
COMMON_VPATH += $(QUANTUM_PATH)/api
COMMON_VPATH += $(QUANTUM_PATH)/sequencer COMMON_VPATH += $(QUANTUM_PATH)/sequencer
COMMON_VPATH += $(DRIVER_PATH) COMMON_VPATH += $(DRIVER_PATH)

View file

@ -100,7 +100,7 @@ void uart_init(uint32_t baud) {
} }
// Transmit a byte // Transmit a byte
void uart_putchar(uint8_t c) { void uart_write(uint8_t data) {
uint8_t i; uint8_t i;
i = tx_buffer_head + 1; i = tx_buffer_head + 1;
@ -110,27 +110,39 @@ void uart_putchar(uint8_t c) {
while (tx_buffer_tail == i) while (tx_buffer_tail == i)
; // wait until space in buffer ; // wait until space in buffer
// cli(); // cli();
tx_buffer[i] = c; tx_buffer[i] = data;
tx_buffer_head = i; tx_buffer_head = i;
UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn); UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn);
// sei(); // sei();
} }
// Receive a byte // Receive a byte
uint8_t uart_getchar(void) { uint8_t uart_read(void) {
uint8_t c, i; uint8_t data, i;
while (rx_buffer_head == rx_buffer_tail) while (rx_buffer_head == rx_buffer_tail)
; // wait for character ; // wait for character
i = rx_buffer_tail + 1; i = rx_buffer_tail + 1;
if (i >= RX_BUFFER_SIZE) i = 0; if (i >= RX_BUFFER_SIZE) i = 0;
c = rx_buffer[i]; data = rx_buffer[i];
rx_buffer_tail = i; rx_buffer_tail = i;
return c; return data;
}
void uart_transmit(const uint8_t *data, uint16_t length) {
for (uint16_t i = 0; i < length; i++) {
uart_write(data[i]);
}
}
void uart_receive(uint8_t *data, uint16_t length) {
for (uint16_t i = 0; i < length; i++) {
data[i] = uart_read();
}
} }
// Return whether the number of bytes waiting in the receive buffer is nonzero. // Return whether the number of bytes waiting in the receive buffer is nonzero.
// Call this before uart_getchar() to check if it will need // Call this before uart_read() to check if it will need
// to wait for a byte to arrive. // to wait for a byte to arrive.
bool uart_available(void) { bool uart_available(void) {
uint8_t head, tail; uint8_t head, tail;

View file

@ -28,8 +28,12 @@
void uart_init(uint32_t baud); void uart_init(uint32_t baud);
void uart_putchar(uint8_t c); void uart_write(uint8_t data);
uint8_t uart_getchar(void); uint8_t uart_read(void);
void uart_transmit(const char *data, uint16_t length);
void uart_receive(char *data, uint16_t length);
bool uart_available(void); bool uart_available(void);

View file

@ -39,12 +39,16 @@ void uart_init(uint32_t baud) {
} }
} }
void uart_putchar(uint8_t c) { sdPut(&SERIAL_DRIVER, c); } void uart_write(uint8_t data) { sdPut(&SERIAL_DRIVER, c); }
uint8_t uart_getchar(void) { uint8_t uart_read(void) {
msg_t res = sdGet(&SERIAL_DRIVER); msg_t res = sdGet(&SERIAL_DRIVER);
return (uint8_t)res; 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); } bool uart_available(void) { return !sdGetWouldBlock(&SERIAL_DRIVER); }

View file

@ -70,8 +70,12 @@
void uart_init(uint32_t baud); void uart_init(uint32_t baud);
void uart_putchar(uint8_t c); void uart_write(uint8_t data);
uint8_t uart_getchar(void); uint8_t uart_read(void);
void uart_transmit(const uint8_t *data, uint16_t length);
void uart_receive(uint8_t *data, uint16_t length);
bool uart_available(void); bool uart_available(void);