uint8_t retry;
uint8_t status;
bool write_ready;
+ bool response_ready;
+ bool transmit_complete;
bool busy;
} state = {0};
static void _set_dre_interrupt(bool enable) {
- INTLVL_ENABLE(RS485_PORT.CTRLA, USART_DRE, LO, enable);
+ INTLVL_ENABLE(RS485_PORT.CTRLA, USART_DRE, MED, enable);
}
static void _set_txc_interrupt(bool enable) {
- INTLVL_ENABLE(RS485_PORT.CTRLA, USART_TXC, LO, enable);
+ INTLVL_ENABLE(RS485_PORT.CTRLA, USART_TXC, MED, enable);
}
static void _set_rxc_interrupt(bool enable) {
- INTLVL_ENABLE(RS485_PORT.CTRLA, USART_RXC, LO, enable);
+ INTLVL_ENABLE(RS485_PORT.CTRLA, USART_RXC, MED, enable);
}
static void _handle_response() {
+ if (!state.response_ready) return;
+ state.response_ready = false;
+
if (!_check_response()) return;
state.last_write = 0; // Clear timeout timer
ISR(RS485_TXC_vect) {
_set_txc_interrupt(false);
_set_rxc_interrupt(true);
- _set_write(false); // Switch to read mode
- state.last_write = rtc_get_time(); // Set timeout timer
+ _set_write(false); // Switch to read mode
+ state.transmit_complete = true;
}
_set_rxc_interrupt(false);
_set_write(true); // Back to write mode
state.bytes = 0;
- _handle_response();
+ state.response_ready = true;
}
}
void modbus_rtc_callback() {
+ if (state.transmit_complete) {
+ state.last_write = rtc_get_time();
+ state.transmit_complete = false;
+ }
+
+ _handle_response();
_start_write();
+
if (!state.last_write || !rtc_expired(state.last_write + MODBUS_TIMEOUT))
return;
state.last_write = 0;