Modbus serial assignment

Dependencies:   mbed

Fork of TAIST_modbus by Supachai Vorapojpisut

Revision:
0:f306cb0263a6
Child:
1:b50d9b988d1e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modbus.cpp	Wed Mar 14 06:17:48 2018 +0000
@@ -0,0 +1,103 @@
+#include "mbed.h"
+#include "modbus.h"
+
+uint8_t nodeId = 0;
+uint16_t regValue[ADDR_RANGE];
+
+enum state {IDLE, RECEPTION, END} protState = IDLE;
+
+int process_buffer(char *buf, uint8_t *frame)
+{
+    int status = 0;
+    uint8_t sum = 0;
+    uint8_t lrc, i;
+    char tmpbuf[] = {0, 0, 0};
+    
+    if (strlen(buf) == 14) {
+        for (i = 0; i < 6; i++) {
+            tmpbuf[0] = buf[i*2];
+            tmpbuf[1] = buf[i*2 + 1]; 
+            frame[i] = strtoul(tmpbuf, NULL, 16);
+        }
+        tmpbuf[0] = buf[12]; tmpbuf[1] = buf[13]; 
+        lrc = strtoul(tmpbuf, NULL, 16);
+        for (i = 0; i < 6; i++) {
+            sum += frame[i];
+        }
+        if ((sum + lrc) == 0) {
+            status = 1;
+        }
+    }
+    
+    return status;    
+}
+
+void modbus_init(uint8_t id)
+{
+    nodeId = id;
+}
+
+uint16_t modbus_read(uint16_t offset)
+{
+    if (offset < ADDR_RANGE) {
+        return regValue[offset];
+    } 
+    return 0xFFFF;
+}
+
+uint16_t modbus_update(uint8_t offset, uint16_t val)
+{
+    uint16_t tmp;
+    
+    if (offset < ADDR_RANGE) {
+        tmp = regValue[offset];
+        regValue[offset] = val;
+        return tmp;
+    } 
+    return 0xFFFF;
+}
+
+int modbus_parser(char ch, uint8_t *frame)
+{
+    static char buf[514];
+    static int idx = 0;
+    static int status = 0;
+    
+    switch(protState) {
+        case IDLE:
+            if (ch == ':') {
+                protState = RECEPTION;
+                idx = 0;
+                status = 0;
+            }
+            break;
+        case RECEPTION:
+            if ((ch >= '0') && (ch <= '9')) {
+                buf[idx++] = ch;
+            } else if ((ch >= 'a') && (ch <= 'f')) {
+                buf[idx++] = ch;
+            } else if ((ch >= 'A') && (ch <= 'F')) {
+                buf[idx++] = ch;
+            } else if (ch == '\r') {
+                buf[idx] = 0;
+                protState = END;
+            } else {
+                protState = IDLE;
+            }
+            break;
+        case END:
+            if (ch == '\n') {
+                if (process_buffer(buf, frame)) {
+                    if ((frame[0] == nodeId) && (frame[1] == FUNC_CODE)) {
+                        status = 1;
+                    }
+                }
+            } 
+            protState = IDLE;
+            break;
+        default:
+            protState = IDLE;
+    }
+    
+    return status;
+}