mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-28 09:58:23 +08:00
[uart] use buffer write function for ChibiOS uart driver (#3491)
This way is about 10 times faster than using a for loop with single byte put function.
This commit is contained in:
committed by
GitHub
parent
06c0b2f4ed
commit
b91239f7b5
@@ -86,8 +86,7 @@ UNUSED static void handle_uart_rx(struct uart_periph *p)
|
|||||||
UNUSED static void handle_uart_tx(struct uart_periph *p)
|
UNUSED static void handle_uart_tx(struct uart_periph *p)
|
||||||
{
|
{
|
||||||
// check if more data to send
|
// check if more data to send
|
||||||
// TODO send by block with sdWrite (be careful with circular buffer)
|
// send by block with sdWrite if possible: not compatible with soft flow control
|
||||||
// not compatible with soft flow control
|
|
||||||
struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
|
struct SerialInit *init_struct = (struct SerialInit *)(p->init_struct);
|
||||||
chSemWait(init_struct->tx_sem);
|
chSemWait(init_struct->tx_sem);
|
||||||
p->tx_running = true;
|
p->tx_running = true;
|
||||||
@@ -97,18 +96,27 @@ UNUSED static void handle_uart_tx(struct uart_periph *p)
|
|||||||
// wait for CTS line to be set to send next byte
|
// wait for CTS line to be set to send next byte
|
||||||
while (gpio_get(init_struct->cts_port, init_struct->cts_pin) == 1) ;
|
while (gpio_get(init_struct->cts_port, init_struct->cts_pin) == 1) ;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
uint8_t data = p->tx_buf[p->tx_extract_idx];
|
uint8_t data = p->tx_buf[p->tx_extract_idx];
|
||||||
sdPut((SerialDriver *)p->reg_addr, data);
|
sdPut((SerialDriver *)p->reg_addr, data);
|
||||||
chMtxLock(init_struct->tx_mtx);
|
chMtxLock(init_struct->tx_mtx);
|
||||||
p->tx_extract_idx++;
|
p->tx_extract_idx++;
|
||||||
p->tx_extract_idx %= UART_TX_BUFFER_SIZE;
|
p->tx_extract_idx %= UART_TX_BUFFER_SIZE;
|
||||||
chMtxUnlock(init_struct->tx_mtx);
|
chMtxUnlock(init_struct->tx_mtx);
|
||||||
#if USE_UART_SOFT_FLOW_CONTROL
|
|
||||||
if (init_struct->cts_port != 0) {
|
if (init_struct->cts_port != 0) {
|
||||||
// wait for physical transfer to be completed
|
// wait for physical transfer to be completed
|
||||||
while ((((SerialDriver *)p->reg_addr)->usart->SR & USART_SR_TC) == 0) ;
|
while ((((SerialDriver *)p->reg_addr)->usart->SR & USART_SR_TC) == 0) ;
|
||||||
}
|
}
|
||||||
|
#else // normal operation without soft flow control
|
||||||
|
chMtxLock(init_struct->tx_mtx);
|
||||||
|
if (p->tx_insert_idx > p->tx_extract_idx) {
|
||||||
|
sdWrite((SerialDriver *)p->reg_addr, &p->tx_buf[p->tx_extract_idx], p->tx_insert_idx - p->tx_extract_idx);
|
||||||
|
} else {
|
||||||
|
// wrapping circular buffer
|
||||||
|
sdWrite((SerialDriver *)p->reg_addr, &p->tx_buf[p->tx_extract_idx], UART_TX_BUFFER_SIZE - p->tx_extract_idx);
|
||||||
|
sdWrite((SerialDriver *)p->reg_addr, &p->tx_buf[0], p->tx_insert_idx);
|
||||||
|
}
|
||||||
|
p->tx_extract_idx = p->tx_insert_idx;
|
||||||
|
chMtxUnlock(init_struct->tx_mtx);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
p->tx_running = false;
|
p->tx_running = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user