]> sigrok.org Git - libsigrok.git/blobdiff - src/modbus/modbus_serial_rtu.c
crc: Factor out CRC16 implementation from Modbus
[libsigrok.git] / src / modbus / modbus_serial_rtu.c
index 4b15d241fcdf14c1b35a761b60d4814b0b429008..8d6978b1e0bf114f23ee578f329e2653f3161f8b 100644 (file)
@@ -26,6 +26,8 @@
 
 #define LOG_PREFIX "modbus_serial"
 
+#ifdef HAVE_SERIAL_COMM
+
 #define BUFFER_SIZE 1024
 
 struct modbus_serial_rtu {
@@ -79,27 +81,6 @@ static int modbus_serial_rtu_source_remove(struct sr_session *session,
        return serial_source_remove(session, serial);
 }
 
-static uint16_t modbus_serial_rtu_crc(uint16_t crc,
-               const uint8_t *buffer, int len)
-{
-       int i;
-
-       if (!buffer || len < 0)
-               return crc;
-
-       while (len--) {
-               crc ^= *buffer++;
-               for (i = 0; i < 8; i++) {
-                       int carry = crc & 1;
-                       crc >>= 1;
-                       if (carry)
-                               crc ^= 0xA001;
-               }
-       }
-
-       return crc;
-}
-
 static int modbus_serial_rtu_send(void *priv,
                const uint8_t *buffer, int buffer_size)
 {
@@ -111,18 +92,18 @@ static int modbus_serial_rtu_send(void *priv,
 
        result = serial_write_blocking(serial, &slave_addr, sizeof(slave_addr), 0);
        if (result < 0)
-               return result;
+               return SR_ERR;
 
        result = serial_write_blocking(serial, buffer, buffer_size, 0);
        if (result < 0)
-               return result;
+               return SR_ERR;
 
-       crc = modbus_serial_rtu_crc(0xFFFF, &slave_addr, sizeof(slave_addr));
-       crc = modbus_serial_rtu_crc(crc, buffer, buffer_size);
+       crc = sr_crc16(SR_CRC16_DEFAULT_INIT, &slave_addr, sizeof(slave_addr));
+       crc = sr_crc16(crc, buffer, buffer_size);
 
        result = serial_write_blocking(serial, &crc, sizeof(crc), 0);
        if (result < 0)
-               return result;
+               return SR_ERR;
 
        return SR_OK;
 }
@@ -135,14 +116,14 @@ static int modbus_serial_rtu_read_begin(void *priv, uint8_t *function_code)
 
        ret = serial_read_blocking(modbus->serial, &slave_addr, 1, 500);
        if (ret != 1 || slave_addr != modbus->slave_addr)
-               return ret;
+               return SR_ERR;
 
        ret = serial_read_blocking(modbus->serial, function_code, 1, 100);
        if (ret != 1)
-               return ret;
+               return SR_ERR;
 
-       modbus->crc = modbus_serial_rtu_crc(0xFFFF, &slave_addr, sizeof(slave_addr));
-       modbus->crc = modbus_serial_rtu_crc(modbus->crc, function_code, 1);
+       modbus->crc = sr_crc16(SR_CRC16_DEFAULT_INIT, &slave_addr, sizeof(slave_addr));
+       modbus->crc = sr_crc16(modbus->crc, function_code, 1);
 
        return SR_OK;
 }
@@ -155,7 +136,7 @@ static int modbus_serial_rtu_read_data(void *priv, uint8_t *buf, int maxlen)
        ret = serial_read_nonblocking(modbus->serial, buf, maxlen);
        if (ret < 0)
                return ret;
-       modbus->crc = modbus_serial_rtu_crc(modbus->crc, buf, ret);
+       modbus->crc = sr_crc16(modbus->crc, buf, ret);
        return ret;
 }
 
@@ -167,7 +148,7 @@ static int modbus_serial_rtu_read_end(void *priv)
 
        ret = serial_read_blocking(modbus->serial, &crc, sizeof(crc), 100);
        if (ret != 2)
-               return ret;
+               return SR_ERR;
 
        if (crc != modbus->crc) {
                sr_err("CRC error (0x%04X vs 0x%04X).", crc, modbus->crc);
@@ -207,3 +188,5 @@ SR_PRIV const struct sr_modbus_dev_inst modbus_serial_rtu_dev = {
        .close         = modbus_serial_rtu_close,
        .free          = modbus_serial_rtu_free,
 };
+
+#endif