From: Joseph Coffland Date: Sat, 24 Mar 2018 01:33:08 +0000 (-0700) Subject: Continuing work on huanyang/modbus split X-Git-Url: https://git.buildbotics.com/?a=commitdiff_plain;h=63497326fecde34085732cee2b937589961c32ba;p=bbctrl-firmware Continuing work on huanyang/modbus split --- diff --git a/src/avr/src/huanyang.c b/src/avr/src/huanyang.c index 87d47a6..6d96abc 100644 --- a/src/avr/src/huanyang.c +++ b/src/avr/src/huanyang.c @@ -53,30 +53,19 @@ // See VFD manual pg56 3.1.3 typedef enum { - HUANYANG_FUNC_READ = 1, // Use hy_addr_t - HUANYANG_FUNC_WRITE, // ? - HUANYANG_CTRL_WRITE, // Use hy_ctrl_state_t - HUANYANG_CTRL_READ, // Use hy_ctrl_addr_t - HUANYANG_FREQ_WRITE, // Write frequency as uint16_t + HUANYANG_FUNC_READ = 1, // [len=1][hy_addr_t] + HUANYANG_FUNC_WRITE, // [len=3][hy_addr_t][data] + HUANYANG_CTRL_WRITE, // [len=1][hy_ctrl_state_t] + HUANYANG_CTRL_READ, // [len=1][hy_ctrl_addr_t] + HUANYANG_FREQ_WRITE, // [len=2][freq] HUANYANG_RESERVED_1, HUANYANG_RESERVED_2, HUANYANG_LOOP_TEST, } hy_func_t; -// See VFD manual pg57 3.1.3.d -typedef enum { - HUANYANG_TARGET_FREQ, - HUANYANG_ACTUAL_FREQ, - HUANYANG_ACTUAL_CURRENT, - HUANYANG_ACTUAL_RPM, - HUANYANG_DCV, - HUANYANG_ACV, - HUANYANG_CONT, - HUANYANG_TEMPERATURE, -} hy_ctrl_addr_t; - - +// Sent in HUANYANG_CTRL_WRITE +// See VFD manual pg57 3.1.3.c typedef enum { HUANYANG_RUN = 1 << 0, HUANYANG_FORWARD = 1 << 1, @@ -85,10 +74,12 @@ typedef enum { HUANYANG_REV_FWD = 1 << 4, HUANYANG_JOG = 1 << 5, HUANYANG_JOG_FORWARD = 1 << 6, - HUANYANG_JOG_REVERSE = 1 << 1, + HUANYANG_JOG_REVERSE = 1 << 7, } hy_ctrl_state_t; +// Returned by HUANYANG_CTRL_WRITE +// See VFD manual pg57 3.1.3.c typedef enum { HUANYANG_STATUS_RUN = 1 << 0, HUANYANG_STATUS_JOG = 1 << 1, @@ -101,6 +92,20 @@ typedef enum { } hy_ctrl_status_t; +// Sent in HUANYANG_CTRL_READ +// See VFD manual pg57 3.1.3.d +typedef enum { + HUANYANG_TARGET_FREQ, + HUANYANG_ACTUAL_FREQ, + HUANYANG_ACTUAL_CURRENT, + HUANYANG_ACTUAL_RPM, + HUANYANG_DCV, + HUANYANG_ACV, + HUANYANG_COUNTER, + HUANYANG_TEMPERATURE, +} hy_ctrl_addr_t; + + static struct { uint8_t id; @@ -127,6 +132,15 @@ static struct { } hy = {1}; // Default ID +static void _func_read(hy_addr_t addr) { + hy.func = HUANYANG_FUNC_READ; + hy.bytes = 2; + hy.response = 4; + hy.data[0] = 1; + hy.data[1] = addr; +} + + static void _ctrl_write(hy_ctrl_state_t state) { hy.func = HUANYANG_CTRL_WRITE; hy.bytes = 2; @@ -148,24 +162,13 @@ static void _ctrl_read(hy_ctrl_addr_t addr) { static void _freq_write(uint16_t freq) { hy.func = HUANYANG_FREQ_WRITE; hy.bytes = 3; - hy.response = 2; + hy.response = 3; hy.data[0] = 2; hy.data[1] = freq >> 8; hy.data[2] = freq; } -static void _func_read(uint16_t addr) { - hy.func = HUANYANG_FUNC_READ; - hy.bytes = 4; - hy.response = 4; - hy.data[0] = 3; - hy.data[1] = addr; - hy.data[2] = addr >> 8; - hy.data[3] = 0; -} - - static void _func_read_response(hy_addr_t addr, uint16_t value) { switch (addr) { case HY_PD005_MAX_FREQUENCY: hy.max_freq = value * 0.01; break; @@ -194,18 +197,16 @@ static uint16_t _read_word(const uint8_t *data) { static void _handle_response(hy_func_t func, const uint8_t *data) { switch (func) { - case HUANYANG_FUNC_READ: { - _func_read_response((hy_addr_t)_read_word(data), _read_word(data + 2)); + case HUANYANG_FUNC_READ: + _func_read_response((hy_addr_t)*data, _read_word(data + 1)); break; - } case HUANYANG_FUNC_WRITE: break; - case HUANYANG_CTRL_WRITE: hy.status = _read_word(data); break; + case HUANYANG_CTRL_WRITE: hy.status = *data; break; - case HUANYANG_CTRL_READ: { - _ctrl_read_response((hy_ctrl_addr_t)_read_word(data), _read_word(data + 2)); + case HUANYANG_CTRL_READ: + _ctrl_read_response((hy_ctrl_addr_t)*data, _read_word(data + 1)); break; - } case HUANYANG_FREQ_WRITE: break; default: break; @@ -235,7 +236,9 @@ static void _reset(bool halt) { static void _modbus_cb(uint8_t slave, uint8_t func, uint8_t bytes, const uint8_t *data) { - if (data && bytes == *data + 1) { + if (!data) _reset(true); + + else if (bytes == *data + 1) { _handle_response((hy_func_t)func, data + 1); if (func == HUANYANG_CTRL_WRITE && hy.shutdown) { diff --git a/src/avr/src/modbus.c b/src/avr/src/modbus.c index 6e3bee1..1d76f51 100644 --- a/src/avr/src/modbus.c +++ b/src/avr/src/modbus.c @@ -29,6 +29,7 @@ #include "usart.h" #include "status.h" #include "rtc.h" +#include "util.h" #include "config.h" #include @@ -55,7 +56,7 @@ static struct { uint8_t retry; bool connected; bool busy; -} mb = {true, USART_BAUD_9600}; +} mb = {false, USART_BAUD_9600}; static uint16_t _crc16(const uint8_t *buffer, unsigned length) { @@ -103,8 +104,14 @@ static bool _check_response() { mb.response[mb.response_length - 2]; if (computed != expected) { - STATUS_WARNING(STAT_OK, "modbus: invalid CRC, expected=0x%04u got=0x%04u", - expected, computed); + char sent[mb.command_length * 2 + 1]; + char response[mb.response_length * 2 + 1]; + format_hex_buf(sent, mb.command, mb.command_length); + format_hex_buf(response, mb.response, mb.response_length); + + STATUS_WARNING(STAT_OK, "modbus: invalid CRC, expected=0x%04x got=0x%04x " + "sent=0x%s received=0x%s", + expected, computed, sent, response); return false; } @@ -210,6 +217,12 @@ static void _retry() { _set_rxc_interrupt(false); _set_dre_interrupt(true); + // Try changing pin polarity + if (mb.retry == MODBUS_RETRIES) { + PINCTRL_PIN(RS485_RO_PIN) ^= PORT_INVEN_bm; + PINCTRL_PIN(RS485_DI_PIN) ^= PORT_INVEN_bm; + } + if (mb.debug) STATUS_DEBUG("modbus: retry %d", mb.retry); } @@ -217,12 +230,14 @@ static void _retry() { static void _timeout() { if (mb.debug) STATUS_DEBUG("modbus: timedout"); - // Try changing pin polarity - PINCTRL_PIN(RS485_RO_PIN) ^= PORT_INVEN_bm; - PINCTRL_PIN(RS485_DI_PIN) ^= PORT_INVEN_bm; + modbus_cb_t cb = mb.receive_cb; + uint8_t id = mb.command[0]; + uint8_t func = mb.command[1]; - mb.retry = -1; - _retry(); + _reset(); + + // Notify caller + if (cb) cb(id, func, 0, 0); } @@ -290,28 +305,22 @@ void modbus_func(uint8_t slave, uint8_t func, uint8_t send, const uint8_t *data, void modbus_rtc_callback() { - if (mb.last && rtc_expired(mb.last + MODBUS_TIMEOUT)) { - if (mb.debug && mb.bytes) { - const uint8_t buf_len = 8 * 2 + 1; - char sent[buf_len]; - char received[buf_len]; - - uint8_t i; - for (i = 0; i < mb.command_length; i++) - sprintf(sent + i * 2, "%02x", mb.command[i]); - sent[i * 2] = 0; - - for (i = 0; i < mb.bytes; i++) - sprintf(received + i * 2, "%02x", mb.response[i]); - received[i * 2] = 0; - - STATUS_DEBUG("modbus: sent 0x%s received 0x%s expected %u bytes", - sent, received, mb.response_length); - } - - if (mb.retry < MODBUS_RETRIES) _retry(); - else _timeout(); + if (!mb.last || !rtc_expired(mb.last + MODBUS_TIMEOUT)) return; + + if (mb.debug && mb.bytes) { + const uint8_t buf_len = 8 * 2 + 1; + char sent[buf_len]; + char received[buf_len]; + + format_hex_buf(sent, mb.command, mb.command_length); + format_hex_buf(received, mb.response, mb.bytes); + + STATUS_DEBUG("modbus: sent 0x%s received 0x%s expected %u bytes", + sent, received, mb.response_length); } + + if (mb.retry < 2 * MODBUS_RETRIES) _retry(); + else _timeout(); } diff --git a/src/avr/src/util.c b/src/avr/src/util.c index 1a60669..61137fe 100644 --- a/src/avr/src/util.c +++ b/src/avr/src/util.c @@ -29,6 +29,7 @@ #include "base64.h" +#include #include #include #include @@ -81,3 +82,14 @@ stat_t decode_axes(char **cmd, float axes[AXES]) { return STAT_OK; } + + +// Assumes the caller provide format buffer length is @param len * 2 + 1. +void format_hex_buf(char *buf, const uint8_t *data, unsigned len) { + uint8_t i; + + for (i = 0; i < len; i++) + sprintf(buf + i * 2, "%02x", data[i]); + + buf[i * 2] = 0; +} diff --git a/src/avr/src/util.h b/src/avr/src/util.h index 1a4ea42..300fb1a 100644 --- a/src/avr/src/util.h +++ b/src/avr/src/util.h @@ -68,6 +68,7 @@ inline static bool fp_TRUE(float a) {return !fp_ZERO(a);} int8_t decode_hex_nibble(char c); bool decode_float(char **s, float *f); stat_t decode_axes(char **cmd, float axes[AXES]); +void format_hex_buf(char *buf, const uint8_t *data, unsigned len); // Constants #define MM_PER_INCH 25.4