lhakpa dorji
/
TAIST_modbus_Assignment
Modbus serial assignment
Fork of TAIST_modbus by
Diff: modbus.cpp
- Revision:
- 0:f306cb0263a6
- Child:
- 1:b50d9b988d1e
diff -r 000000000000 -r f306cb0263a6 modbus.cpp --- /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; +}