From db62b021ea5b82e91eaacb345ad81439a4cb41dc Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Sat, 23 May 2015 00:13:07 +0200 Subject: [PATCH] Use TX end IRQ instead of busy wait --- firmware/modbus.c | 10 +++++++--- firmware/rs485.c | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/firmware/modbus.c b/firmware/modbus.c index 0c238c2..2b2a255 100644 --- a/firmware/modbus.c +++ b/firmware/modbus.c @@ -43,7 +43,6 @@ static uint8_t mb_unit_id; #define UART_BAUD 9600 #define UBRR_VAL ((F_CPU + 8UL * UART_BAUD) / (16UL*UART_BAUD) - 1) -#define wait_one_byte() _delay_us(10*1000000/UART_BAUD) /* * According to Wikipedia, it is indeed 28 bits = 3.5 bytes without @@ -267,14 +266,19 @@ ISR(USART_RX_vect) } } +ISR(USART_TX_vect) +{ + UCSR0B &= ~_BV(TXCIE0); // disable further IRQs + ctl_pin_off(); +} + ISR(USART_UDRE_vect) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { if (tx_head == tx_tail) { + UCSR0B |= _BV(TXCIE0); // enable xmit complete irq UCSR0B &= ~_BV(UDRIE0); tx_tail = tx_head = 0; - wait_one_byte(); // FIXME: too long busy-wait - ctl_pin_off(); } else { UDR0 = txbuf[tx_tail]; tx_tail = bufptr_inc(tx_tail); diff --git a/firmware/rs485.c b/firmware/rs485.c index 6d16a2a..7aec92c 100644 --- a/firmware/rs485.c +++ b/firmware/rs485.c @@ -34,7 +34,6 @@ static volatile char rxbuf[BUFSIZE], txbuf[BUFSIZE]; #define UART_BAUD 9600 #define UBRR_VAL ((F_CPU + 8UL * UART_BAUD) / (16UL*UART_BAUD) - 1) -#define wait_one_byte() _delay_us(10*1000000/UART_BAUD) void rs485_init() { @@ -99,13 +98,18 @@ ISR(USART_RX_vect) sei(); } +ISR(USART_TX_vect) +{ + UCSR0B &= ~_BV(TXCIE0); // disable further IRQs + ctl_pin_off(); +} + ISR(USART_UDRE_vect) { cli(); if (tx_head == tx_tail) { + UCSR0B |= _BV(TXCIE0); // enable xmit complete irq UCSR0B &= ~_BV(UDRIE0); - wait_one_byte(); - ctl_pin_off(); } else { UDR0 = txbuf[tx_tail]; tx_tail = bufptr_inc(tx_tail); -- 2.43.0