~ruther/qmk_firmware

04b51e381e2ff3f4c7aba662e1c817ce5daa931d — Ryan 3 years ago 7e86c37
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>
M docs/uart_driver.md => docs/uart_driver.md +32 -6
@@ 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.

#### Arguments

 - `uint8_t c`  
   The byte (character) to send, from 0 to 255.
 - `uint8_t data`  
   The byte to write.

---

### `uint8_t uart_getchar(void)`
### `uint8_t uart_read(void)`

Receive a single byte.

#### 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)`

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


M keyboards/mschwingen/modelm/modelm.c => keyboards/mschwingen/modelm/modelm.c +1 -1
@@ 27,7 27,7 @@
#    undef sendchar
static int8_t capture_sendchar(uint8_t c) {
    //  sendchar(c);
    uart_putchar(c);
    uart_write(c);
    return 0;
}
#endif

M keyboards/nullbitsco/common/remote_kb.c => keyboards/nullbitsco/common/remote_kb.c +2 -4
@@ 63,9 63,7 @@ static void send_msg(uint16_t keycode, bool pressed) {
  msg[IDX_PRESSED] = pressed;
  msg[IDX_CHECKSUM] = chksum8(msg, UART_MSG_LEN-1);

  for (int i=0; i<UART_MSG_LEN; i++) {
    uart_putchar(msg[i]);
  }
  uart_transmit(msg, UART_MSG_LEN);
}

static void print_message_buffer(void) {


@@ 103,7 101,7 @@ static void process_uart(void) {

static void get_msg(void) {
  while (uart_available()) {
    msg[msg_idx] = uart_getchar();
    msg[msg_idx] = uart_read();
    dprintf("idx: %u, recv: %u\n", msg_idx, msg[msg_idx]);
    if (msg_idx == 0 && (msg[msg_idx] != UART_PREAMBLE)) {
      dprintf("Byte sync error!\n");

M paths.mk => paths.mk +0 -1
@@ 24,6 24,5 @@ COMMON_VPATH += $(QUANTUM_PATH)
COMMON_VPATH += $(QUANTUM_PATH)/keymap_extras
COMMON_VPATH += $(QUANTUM_PATH)/audio
COMMON_VPATH += $(QUANTUM_PATH)/process_keycode
COMMON_VPATH += $(QUANTUM_PATH)/api
COMMON_VPATH += $(QUANTUM_PATH)/sequencer
COMMON_VPATH += $(DRIVER_PATH)

M platforms/avr/drivers/uart.c => platforms/avr/drivers/uart.c +19 -7
@@ 100,7 100,7 @@ void uart_init(uint32_t baud) {
}

// Transmit a byte
void uart_putchar(uint8_t c) {
void uart_write(uint8_t data) {
    uint8_t i;

    i = tx_buffer_head + 1;


@@ 110,27 110,39 @@ void uart_putchar(uint8_t c) {
    while (tx_buffer_tail == i)
        ;  // wait until space in buffer
    // cli();
    tx_buffer[i]   = c;
    tx_buffer[i]   = data;
    tx_buffer_head = i;
    UCSRnB         = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn);
    // sei();
}

// Receive a byte
uint8_t uart_getchar(void) {
    uint8_t c, i;
uint8_t uart_read(void) {
    uint8_t data, i;

    while (rx_buffer_head == rx_buffer_tail)
        ;  // wait for character
    i = rx_buffer_tail + 1;
    if (i >= RX_BUFFER_SIZE) i = 0;
    c              = rx_buffer[i];
    data           = rx_buffer[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.
// 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.
bool uart_available(void) {
    uint8_t head, tail;

M platforms/avr/drivers/uart.h => platforms/avr/drivers/uart.h +6 -2
@@ 28,8 28,12 @@

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);

M platforms/chibios/drivers/uart.c => platforms/chibios/drivers/uart.c +6 -2
@@ 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);

    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); }

M platforms/chibios/drivers/uart.h => platforms/chibios/drivers/uart.h +6 -2
@@ 70,8 70,12 @@

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);