diff --git a/keyboards/anne_pro/anne_pro_lighting.c b/keyboards/anne_pro/anne_pro_lighting.c index 3fffab12b7..f983143ef2 100644 --- a/keyboards/anne_pro/anne_pro_lighting.c +++ b/keyboards/anne_pro/anne_pro_lighting.c @@ -32,16 +32,9 @@ static uart_tx_ringbuf_t led_uart_ringbuf = { .tail = 0, }; -/* Should the main loop try a transmission, used when transmission finishes - to send any data that might have been added to the buffer while the - transmission was in progress. -*/ -static volatile bool led_uart_try_transmission = false; - /* Handler for finsihed LED UART transmissions */ static void led_uart_txend(UARTDriver *uart) { uart_tx_ringbuf_finish_transmission(&led_uart_ringbuf); - led_uart_try_transmission = true; } /* LED UART configuration */ @@ -97,14 +90,14 @@ void anne_pro_lighting_update_dynamic(keyrecord_t *record) { /* Send the keystate to the LED controller */ uart_tx_ringbuf_write(&led_uart_ringbuf, 12, keystate); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); } } /* Update lighting, should be called every matrix scan */ void anne_pro_lighting_update(void) { - if (led_uart_try_transmission) { + if (!uart_tx_ringbuf_empty(&led_uart_ringbuf)) { uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); - led_uart_try_transmission = false; } } @@ -120,12 +113,14 @@ void anne_pro_lighting_toggle(void) { /* Turn the lighting on */ void anne_pro_lighting_on(void) { uart_tx_ringbuf_write(&led_uart_ringbuf, 3, "\x09\x01\x01"); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); leds_enabled = true; } /* Turn the lighting off */ void anne_pro_lighting_off(void) { uart_tx_ringbuf_write(&led_uart_ringbuf, 4, "\x09\x02\x01\x00"); + uart_tx_ringbuf_start_transmission(&led_uart_ringbuf); leds_enabled = false; } diff --git a/keyboards/anne_pro/rules.mk b/keyboards/anne_pro/rules.mk index 6c537567e6..41d7ee92fb 100644 --- a/keyboards/anne_pro/rules.mk +++ b/keyboards/anne_pro/rules.mk @@ -24,7 +24,7 @@ ARMV = 7 DFU_ARGS = -d 0483:df11 -a 0 -s 0x08004000 # Extra source files -SRC += anne_pro_lighting.c +SRC += uart_tx_ringbuf.c anne_pro_lighting.c # Build Options # comment out to disable the options. diff --git a/keyboards/anne_pro/uart_tx_ringbuf.c b/keyboards/anne_pro/uart_tx_ringbuf.c new file mode 100644 index 0000000000..1a27a54347 --- /dev/null +++ b/keyboards/anne_pro/uart_tx_ringbuf.c @@ -0,0 +1,89 @@ +/* Copyright 2019 Michiel Visser + * + * 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 2 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 . + */ + +#include "uart_tx_ringbuf.h" +#include "hal.h" + +int uart_tx_ringbuf_elements(uart_tx_ringbuf_t *ringbuf) { + return ringbuf->head - ringbuf->tail; +} + +int uart_tx_ringbuf_space(uart_tx_ringbuf_t *ringbuf) { + return ringbuf->size - uart_tx_ringbuf_elements(ringbuf); +} + +bool uart_tx_ringbuf_empty(uart_tx_ringbuf_t *ringbuf) { + return uart_tx_ringbuf_elements(ringbuf) == 0; +} + +bool uart_tx_ringbuf_full(uart_tx_ringbuf_t *ringbuf) { + return uart_tx_ringbuf_elements(ringbuf) == ringbuf->size; +} + +void uart_tx_ringbuf_start_transmission(uart_tx_ringbuf_t *ringbuf) { + /* Do not start transmission when one is already in progress */ + if (ringbuf->sending_elements != 0) return; + + size_t elements = uart_tx_ringbuf_elements(ringbuf); + /* Do not start transmission when ringbuffer is empty */ + if (elements == 0) return; + + /* Get the offset of the first and last item */ + size_t first_offset = (ringbuf->tail & (ringbuf->size - 1)); + + /* Determine if this wraps around the end of the buffer */ + if (first_offset + elements >= ringbuf->size) { + /* If so only send until the end of the buffer */ + elements = ringbuf->size - first_offset; + } + + /* Send the selected elements */ + ringbuf->sending_elements = elements; + uartStartSend(ringbuf->uart, elements, ringbuf->buf + first_offset); +} + +void uart_tx_ringbuf_finish_transmission(uart_tx_ringbuf_t *ringbuf) { + /* Update the tail of the ringbuffer */ + ringbuf->tail += ringbuf->sending_elements; + /* Clear the sending elements */ + ringbuf->sending_elements = 0; +} + +bool uart_tx_ringbuf_put(uart_tx_ringbuf_t *ringbuf, uint8_t c) { + /* If the ringbuffer is full, ignore the request */ + if (uart_tx_ringbuf_full(ringbuf)) return false; + + /* Put the character into the ringbuffer */ + size_t head_offset = (ringbuf->head & (ringbuf->size - 1)); + ringbuf->buf[head_offset] = c; + ringbuf->head++; + + return true; +} + +bool uart_tx_ringbuf_write(uart_tx_ringbuf_t *ringbuf, size_t count, void *data) { + /* If there is not enough space, ignore the request */ + if (uart_tx_ringbuf_space(ringbuf) < count) return false; + + for (int i = 0; i < count; i++) { + /* Put the character into the ringbuffer */ + size_t head_offset = (ringbuf->head & (ringbuf->size - 1)); + ringbuf->buf[head_offset] = ((uint8_t *) data)[i]; + ringbuf->head++; + } + + return true; +} diff --git a/keyboards/anne_pro/uart_tx_ringbuf.h b/keyboards/anne_pro/uart_tx_ringbuf.h index abdb37f0d6..fa20156ed9 100644 --- a/keyboards/anne_pro/uart_tx_ringbuf.h +++ b/keyboards/anne_pro/uart_tx_ringbuf.h @@ -26,77 +26,11 @@ typedef struct { volatile size_t tail; } uart_tx_ringbuf_t; -int uart_tx_ringbuf_elements(uart_tx_ringbuf_t *ringbuf) { - return ringbuf->head - ringbuf->tail; -} - -int uart_tx_ringbuf_space(uart_tx_ringbuf_t *ringbuf) { - return ringbuf->size - uart_tx_ringbuf_elements(ringbuf); -} - -bool uart_tx_ringbuf_empty(uart_tx_ringbuf_t *ringbuf) { - return uart_tx_ringbuf_elements(ringbuf) == 0; -} - -bool uart_tx_ringbuf_full(uart_tx_ringbuf_t *ringbuf) { - return uart_tx_ringbuf_elements(ringbuf) == ringbuf->size; -} - -void uart_tx_ringbuf_start_transmission(uart_tx_ringbuf_t *ringbuf) { - /* Do not start transmission when one is already in progress */ - if (ringbuf->sending_elements != 0) return; - - size_t elements = uart_tx_ringbuf_elements(ringbuf); - /* Do not start transmission when ringbuffer is empty */ - if (elements == 0) return; - - /* Get the offset of the first and last item */ - size_t first_offset = (ringbuf->tail & (ringbuf->size - 1)); - - /* Determine if this wraps around the end of the buffer */ - if (first_offset + elements >= ringbuf->size) { - /* If so only send until the end of the buffer */ - elements = ringbuf->size - first_offset; - } - - /* Send the selected elements */ - ringbuf->sending_elements = elements; - uartStartSend(ringbuf->uart, elements, ringbuf->buf + first_offset); -} - -void uart_tx_ringbuf_finish_transmission(uart_tx_ringbuf_t *ringbuf) { - /* Update the tail of the ringbuffer */ - ringbuf->tail += ringbuf->sending_elements; - /* Clear the sending elements */ - ringbuf->sending_elements = 0; -} - -bool uart_tx_ringbuf_put(uart_tx_ringbuf_t *ringbuf, uint8_t c) { - /* If the ringbuffer is full, ignore the request */ - if (uart_tx_ringbuf_full(ringbuf)) return false; - - /* Put the character into the ringbuffer */ - size_t head_offset = (ringbuf->head & (ringbuf->size - 1)); - ringbuf->buf[head_offset] = c; - ringbuf->head++; - - /* Try to start the transmission immediately */ - uart_tx_ringbuf_start_transmission(ringbuf); - return true; -} - -bool uart_tx_ringbuf_write(uart_tx_ringbuf_t *ringbuf, size_t count, void *data) { - /* If there is not enough space, ignore the request */ - if (uart_tx_ringbuf_space(ringbuf) < count) return false; - - for (int i = 0; i < count; i++) { - /* Put the character into the ringbuffer */ - size_t head_offset = (ringbuf->head & (ringbuf->size - 1)); - ringbuf->buf[head_offset] = ((uint8_t *) data)[i]; - ringbuf->head++; - } - - /* Try to start the transmission immediately */ - uart_tx_ringbuf_start_transmission(ringbuf); - return true; -} +int uart_tx_ringbuf_elements(uart_tx_ringbuf_t *ringbuf); +int uart_tx_ringbuf_space(uart_tx_ringbuf_t *ringbuf); +bool uart_tx_ringbuf_empty(uart_tx_ringbuf_t *ringbuf); +bool uart_tx_ringbuf_full(uart_tx_ringbuf_t *ringbuf); +void uart_tx_ringbuf_start_transmission(uart_tx_ringbuf_t *ringbuf); +void uart_tx_ringbuf_finish_transmission(uart_tx_ringbuf_t *ringbuf); +bool uart_tx_ringbuf_put(uart_tx_ringbuf_t *ringbuf, uint8_t c); +bool uart_tx_ringbuf_write(uart_tx_ringbuf_t *ringbuf, size_t count, void *data);