Fix VFD communication at higher baud rates (> 9600). #184
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Sat, 19 Jan 2019 22:12:56 +0000 (14:12 -0800)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Sat, 19 Jan 2019 22:12:56 +0000 (14:12 -0800)
CHANGELOG.md
src/avr/src/modbus.c

index fb3d192478e6394477661e96cd3634fd766e5af4..a17211f0e505ff87130ca502937bed78f8d36edb 100644 (file)
@@ -6,6 +6,7 @@ Buildbotics CNC Controller Firmware Changelog
  - Fix bug where planner would not continue after optional pause (M1).
  - Fix lockup on invalid no move probe G38.x. #183
  - Fix zeroing homed axis after jog.
+ - Fix VFD communication at higher baud rates (> 9600). #184
 
 ## v0.4.4
  - Write version to log file.
index afdecb7448e9095597165cb797540829301e1da5..fe9a3a1c7d77e2d9be3aa1289c4dfacc2f10b17a 100644 (file)
@@ -74,6 +74,8 @@ static struct {
   uint8_t retry;
   uint8_t status;
   bool write_ready;
+  bool response_ready;
+  bool transmit_complete;
   bool busy;
 } state = {0};
 
@@ -102,17 +104,17 @@ static void _set_write(bool x) {SET_PIN(RS485_RW_PIN, x);}
 
 
 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);
 }
 
 
@@ -177,6 +179,9 @@ static void _notify(uint8_t func, uint8_t bytes, const uint8_t *data) {
 
 
 static void _handle_response() {
+  if (!state.response_ready) return;
+  state.response_ready = false;
+
   if (!_check_response()) return;
 
   state.last_write = 0;             // Clear timeout timer
@@ -205,8 +210,8 @@ ISR(RS485_DRE_vect) {
 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;
 }
 
 
@@ -221,7 +226,7 @@ ISR(RS485_RXC_vect) {
     _set_rxc_interrupt(false);
     _set_write(true); // Back to write mode
     state.bytes = 0;
-    _handle_response();
+    state.response_ready = true;
   }
 }
 
@@ -407,7 +412,14 @@ void modbus_write(uint16_t addr, uint16_t value, modbus_rw_cb_t cb) {
 
 
 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;