X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=firmware%2Fmodbus.c;h=b726280f9922f9de4abea11a702e0a69ba58af0f;hb=d8f201d671212ce6ea71de49e852776e5f03f4e7;hp=00a9370a05bdaa872ce14b38f95de35d194d275b;hpb=6146a1caafd449cae4ce08134d763137424300c6;p=openparking.git diff --git a/firmware/modbus.c b/firmware/modbus.c index 00a9370..b726280 100644 --- a/firmware/modbus.c +++ b/firmware/modbus.c @@ -28,7 +28,7 @@ typedef uint8_t bufptr_t; #endif static volatile bufptr_t buf_len, tx_ptr; -static volatile uint8_t buffer[BUFSIZE], transmitting;; +static volatile uint8_t buffer[BUFSIZE], transmitting; static volatile uint16_t last_rx; #ifndef mb_unit_id static uint8_t mb_unit_id; @@ -169,18 +169,10 @@ uint8_t modbus_poll() if (transmitting) return 0; - if (buf_len == 0) // nothing received yet - return 0; - if (get_clock() - last_rx < REQ_TIMEOUT) // still receiving return 0; - if (buf_len < 4) { // too short - buf_len = 0; - return 0; - } - - if (buffer[0] != mb_unit_id) { // not for myself + if (buf_len < 4) { // too short (or not for us) buf_len = 0; return 0; } @@ -207,14 +199,14 @@ uint8_t modbus_poll() switch (buffer[1]) { // function case 3: - if (packet_len == 5) + if (packet_len == 6) rv = read_holding_regs( get_word(buffer, 2), get_word(buffer, 4) ); break; case 6: - if (packet_len == 5) + if (packet_len == 6) rv = write_single_reg( get_word(buffer, 2), get_word(buffer, 4) @@ -241,16 +233,28 @@ uint8_t modbus_poll() ISR(USART_RX_vect) { uint8_t rx_byte = UDR0; + clock_t now = get_clock(); + + if (transmitting) // how did we get here? discard it + goto out; - if (transmitting) // discard it - return; + if (buf_len && buffer[0] != mb_unit_id) // not for us + goto out; - buffer[buf_len] = rx_byte; + if (buf_len == BUFSIZE) { // overrun - discard the packet + buffer[0] = 0xFF; + buf_len = 1; + goto out; + } - if (buf_len + 1 < BUFSIZE) // ignore overruns - buf_len++; + if (now - last_rx >= REQ_TIMEOUT) { // new packet; start over + buf_len = 0; + } - last_rx = get_clock(); + // TODO: we can probably calculate the CRC here as well + buffer[buf_len++] = rx_byte; +out: + last_rx = now; } ISR(USART_TX_vect) @@ -263,7 +267,8 @@ ISR(USART_TX_vect) ISR(USART_UDRE_vect) { - if (tx_ptr+1 >= buf_len) { + if (tx_ptr >= buf_len) { + UCSR0A |= _BV(TXC0); // clear the pending TXC flag UCSR0B |= _BV(TXCIE0); // enable xmit complete irq UCSR0B &= ~_BV(UDRIE0); // disable ourselves } else {