New group

Dependencies:   mbed

Fork of TAIST_modbus by Supachai Vorapojpisut

Committer:
nengzix
Date:
Tue Mar 20 12:08:50 2018 +0000
Revision:
29:c19cea6e2ec3
Parent:
26:e997527a78d7
add rs4b5 en

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vsupacha 0:f306cb0263a6 1 #include "mbed.h"
vsupacha 0:f306cb0263a6 2 #include "modbus.h"
vsupacha 0:f306cb0263a6 3
vsupacha 0:f306cb0263a6 4 uint8_t nodeId = 0;
vsupacha 0:f306cb0263a6 5 uint16_t regValue[ADDR_RANGE];
vsupacha 0:f306cb0263a6 6
vsupacha 0:f306cb0263a6 7 enum state {IDLE, RECEPTION, END} protState = IDLE;
vsupacha 0:f306cb0263a6 8
vsupacha 0:f306cb0263a6 9 int process_buffer(char *buf, uint8_t *frame)
vsupacha 0:f306cb0263a6 10 {
vsupacha 0:f306cb0263a6 11 int status = 0;
vsupacha 0:f306cb0263a6 12 uint8_t sum = 0;
vsupacha 0:f306cb0263a6 13 uint8_t lrc, i;
vsupacha 0:f306cb0263a6 14 char tmpbuf[] = {0, 0, 0};
vsupacha 0:f306cb0263a6 15
vsupacha 0:f306cb0263a6 16 if (strlen(buf) == 14) {
vsupacha 0:f306cb0263a6 17 for (i = 0; i < 6; i++) {
vsupacha 0:f306cb0263a6 18 tmpbuf[0] = buf[i*2];
vsupacha 0:f306cb0263a6 19 tmpbuf[1] = buf[i*2 + 1];
vsupacha 0:f306cb0263a6 20 frame[i] = strtoul(tmpbuf, NULL, 16);
vsupacha 0:f306cb0263a6 21 }
vsupacha 0:f306cb0263a6 22 tmpbuf[0] = buf[12]; tmpbuf[1] = buf[13];
vsupacha 0:f306cb0263a6 23 lrc = strtoul(tmpbuf, NULL, 16);
vsupacha 0:f306cb0263a6 24 for (i = 0; i < 6; i++) {
vsupacha 0:f306cb0263a6 25 sum += frame[i];
vsupacha 0:f306cb0263a6 26 }
vsupacha 24:0007712e84a8 27 sum = sum + lrc;
vsupacha 24:0007712e84a8 28 if (sum == 0) {
vsupacha 0:f306cb0263a6 29 status = 1;
vsupacha 0:f306cb0263a6 30 }
vsupacha 0:f306cb0263a6 31 }
vsupacha 0:f306cb0263a6 32
vsupacha 0:f306cb0263a6 33 return status;
vsupacha 0:f306cb0263a6 34 }
vsupacha 0:f306cb0263a6 35
vsupacha 0:f306cb0263a6 36 void modbus_init(uint8_t id)
vsupacha 0:f306cb0263a6 37 {
vsupacha 24:0007712e84a8 38 int i;
vsupacha 24:0007712e84a8 39
vsupacha 0:f306cb0263a6 40 nodeId = id;
vsupacha 24:0007712e84a8 41 for (i = 0; i < ADDR_RANGE; i++) {
vsupacha 24:0007712e84a8 42 regValue[i] = 0;
vsupacha 24:0007712e84a8 43 }
vsupacha 0:f306cb0263a6 44 }
vsupacha 0:f306cb0263a6 45
vsupacha 0:f306cb0263a6 46 uint16_t modbus_read(uint16_t offset)
vsupacha 24:0007712e84a8 47 {
vsupacha 0:f306cb0263a6 48 if (offset < ADDR_RANGE) {
nengzix 26:e997527a78d7 49 uint16_t tmp = regValue[offset];
nengzix 26:e997527a78d7 50 modbus_update(offset, 0x0000);
nengzix 26:e997527a78d7 51 return tmp;
nengzix 26:e997527a78d7 52
vsupacha 0:f306cb0263a6 53 }
vsupacha 24:0007712e84a8 54 return 0;
vsupacha 0:f306cb0263a6 55 }
vsupacha 0:f306cb0263a6 56
vsupacha 0:f306cb0263a6 57 uint16_t modbus_update(uint8_t offset, uint16_t val)
vsupacha 0:f306cb0263a6 58 {
vsupacha 0:f306cb0263a6 59 uint16_t tmp;
vsupacha 0:f306cb0263a6 60
vsupacha 0:f306cb0263a6 61 if (offset < ADDR_RANGE) {
vsupacha 0:f306cb0263a6 62 tmp = regValue[offset];
vsupacha 0:f306cb0263a6 63 regValue[offset] = val;
vsupacha 0:f306cb0263a6 64 return tmp;
vsupacha 0:f306cb0263a6 65 }
vsupacha 24:0007712e84a8 66 return 0;
vsupacha 24:0007712e84a8 67 }
vsupacha 24:0007712e84a8 68
vsupacha 24:0007712e84a8 69 uint8_t modbus_check(uint16_t offset, uint16_t count)
vsupacha 24:0007712e84a8 70 {
vsupacha 24:0007712e84a8 71 uint8_t reg_map = 0x00;
vsupacha 24:0007712e84a8 72 int i, j;
vsupacha 24:0007712e84a8 73
vsupacha 24:0007712e84a8 74 for (i = 0; i < ADDR_RANGE; i++) {
vsupacha 24:0007712e84a8 75 for (j = offset; j < (offset+count); j++) {
vsupacha 24:0007712e84a8 76 if (j == (ADDR_BASE + i)) {
vsupacha 24:0007712e84a8 77 reg_map |= (1 << i);
vsupacha 24:0007712e84a8 78 }
vsupacha 24:0007712e84a8 79 }
vsupacha 24:0007712e84a8 80 }
vsupacha 24:0007712e84a8 81
vsupacha 24:0007712e84a8 82 return reg_map;
vsupacha 0:f306cb0263a6 83 }
vsupacha 0:f306cb0263a6 84
vsupacha 0:f306cb0263a6 85 int modbus_parser(char ch, uint8_t *frame)
vsupacha 0:f306cb0263a6 86 {
vsupacha 0:f306cb0263a6 87 static char buf[514];
vsupacha 0:f306cb0263a6 88 static int idx = 0;
vsupacha 0:f306cb0263a6 89 static int status = 0;
vsupacha 0:f306cb0263a6 90
vsupacha 0:f306cb0263a6 91 switch(protState) {
vsupacha 0:f306cb0263a6 92 case IDLE:
vsupacha 0:f306cb0263a6 93 if (ch == ':') {
vsupacha 0:f306cb0263a6 94 protState = RECEPTION;
vsupacha 0:f306cb0263a6 95 idx = 0;
vsupacha 0:f306cb0263a6 96 status = 0;
vsupacha 0:f306cb0263a6 97 }
vsupacha 0:f306cb0263a6 98 break;
vsupacha 0:f306cb0263a6 99 case RECEPTION:
nengzix 26:e997527a78d7 100 //printf("%c", ch);
vsupacha 0:f306cb0263a6 101 if ((ch >= '0') && (ch <= '9')) {
vsupacha 0:f306cb0263a6 102 buf[idx++] = ch;
vsupacha 0:f306cb0263a6 103 } else if ((ch >= 'a') && (ch <= 'f')) {
vsupacha 0:f306cb0263a6 104 buf[idx++] = ch;
vsupacha 0:f306cb0263a6 105 } else if ((ch >= 'A') && (ch <= 'F')) {
vsupacha 0:f306cb0263a6 106 buf[idx++] = ch;
nengzix 29:c19cea6e2ec3 107 } else if (ch == '\r' and idx > 4) {
vsupacha 0:f306cb0263a6 108 buf[idx] = 0;
vsupacha 0:f306cb0263a6 109 protState = END;
vsupacha 0:f306cb0263a6 110 } else {
vsupacha 0:f306cb0263a6 111 protState = IDLE;
vsupacha 0:f306cb0263a6 112 }
vsupacha 0:f306cb0263a6 113 break;
vsupacha 0:f306cb0263a6 114 case END:
vsupacha 0:f306cb0263a6 115 if (ch == '\n') {
vsupacha 0:f306cb0263a6 116 if (process_buffer(buf, frame)) {
vsupacha 0:f306cb0263a6 117 if ((frame[0] == nodeId) && (frame[1] == FUNC_CODE)) {
vsupacha 0:f306cb0263a6 118 status = 1;
vsupacha 0:f306cb0263a6 119 }
vsupacha 0:f306cb0263a6 120 }
vsupacha 0:f306cb0263a6 121 }
vsupacha 0:f306cb0263a6 122 protState = IDLE;
vsupacha 0:f306cb0263a6 123 break;
vsupacha 0:f306cb0263a6 124 default:
vsupacha 0:f306cb0263a6 125 protState = IDLE;
vsupacha 0:f306cb0263a6 126 }
vsupacha 0:f306cb0263a6 127
vsupacha 0:f306cb0263a6 128 return status;
vsupacha 0:f306cb0263a6 129 }
vsupacha 24:0007712e84a8 130
vsupacha 24:0007712e84a8 131 uint8_t calc_lrc(uint8_t *frame, int count)
vsupacha 24:0007712e84a8 132 {
vsupacha 24:0007712e84a8 133 int8_t lrc = 0;
vsupacha 24:0007712e84a8 134 int i;
vsupacha 24:0007712e84a8 135
vsupacha 24:0007712e84a8 136 for (i = 0; i < count; i++) {
vsupacha 24:0007712e84a8 137 lrc += frame[i];
vsupacha 24:0007712e84a8 138 }
vsupacha 24:0007712e84a8 139 return -lrc;
vsupacha 24:0007712e84a8 140 }
vsupacha 24:0007712e84a8 141
nengzix 29:c19cea6e2ec3 142 void modbus_response(uint8_t reg_map, char *rttmp)
vsupacha 24:0007712e84a8 143 {
vsupacha 24:0007712e84a8 144 char fmt00[] = ":%02X%02X%02X\r\n";
vsupacha 24:0007712e84a8 145 char fmt01[] = ":%02X%02X%02X%02X%02X\r\n";
vsupacha 24:0007712e84a8 146 char fmt02[] = ":%02X%02X%02X%02X%02X\r\n";
vsupacha 24:0007712e84a8 147 char fmt03[] = ":%02X%02X%02X%02X%02X%02X%02X\r\n";
vsupacha 24:0007712e84a8 148 char *fmtstr;
vsupacha 24:0007712e84a8 149 uint8_t frame[ADDR_RANGE*2 + 3];
vsupacha 24:0007712e84a8 150 uint16_t tmp;
vsupacha 24:0007712e84a8 151
vsupacha 24:0007712e84a8 152 frame[0] = nodeId;
vsupacha 24:0007712e84a8 153 frame[1] = FUNC_CODE;
vsupacha 24:0007712e84a8 154 switch(reg_map) {
vsupacha 24:0007712e84a8 155 case 1:
vsupacha 24:0007712e84a8 156 tmp = modbus_read(0);
vsupacha 24:0007712e84a8 157 frame[2] = tmp >> 8;
vsupacha 24:0007712e84a8 158 frame[3] = tmp & 0xFF;
vsupacha 24:0007712e84a8 159 frame[4] = calc_lrc(frame, 4);
vsupacha 24:0007712e84a8 160 fmtstr = fmt01;
nengzix 29:c19cea6e2ec3 161 sprintf(rttmp, fmtstr, frame[0], frame[1], frame[2], frame[3], frame[4]);
nengzix 25:4d1450e7cb88 162 //printf("Response: %s", str);
nengzix 29:c19cea6e2ec3 163 //printf(str);
vsupacha 24:0007712e84a8 164 break;
vsupacha 24:0007712e84a8 165 case 2:
vsupacha 24:0007712e84a8 166 tmp = modbus_read(1);
vsupacha 24:0007712e84a8 167 frame[2] = tmp >> 8;
vsupacha 24:0007712e84a8 168 frame[3] = tmp & 0xFF;
vsupacha 24:0007712e84a8 169 frame[4] = calc_lrc(frame, 4);
vsupacha 24:0007712e84a8 170 fmtstr = fmt02;
nengzix 29:c19cea6e2ec3 171 sprintf(rttmp, fmtstr, frame[0], frame[1], frame[2], frame[3], frame[4]);
nengzix 26:e997527a78d7 172 //printf("Response: %s", str);
nengzix 29:c19cea6e2ec3 173 //printf(str);
vsupacha 24:0007712e84a8 174 break;
vsupacha 24:0007712e84a8 175 case 3:
vsupacha 24:0007712e84a8 176 tmp = modbus_read(0);
vsupacha 24:0007712e84a8 177 frame[2] = tmp >> 8;
vsupacha 24:0007712e84a8 178 frame[3] = tmp & 0xFF;
vsupacha 24:0007712e84a8 179 tmp = modbus_read(1);
vsupacha 24:0007712e84a8 180 frame[4] = tmp >> 8;
vsupacha 24:0007712e84a8 181 frame[5] = tmp & 0xFF;
vsupacha 24:0007712e84a8 182 frame[6] = calc_lrc(frame, 6);
vsupacha 24:0007712e84a8 183 fmtstr = fmt03;
nengzix 29:c19cea6e2ec3 184 sprintf(rttmp, fmtstr, frame[0], frame[1], frame[2], frame[3], frame[4], frame[5], frame[6]);
nengzix 26:e997527a78d7 185 //printf("Response: %s", str);
nengzix 29:c19cea6e2ec3 186 //printf(str);
vsupacha 24:0007712e84a8 187 break;
vsupacha 24:0007712e84a8 188 default:
vsupacha 24:0007712e84a8 189 fmtstr = fmt00;
vsupacha 24:0007712e84a8 190 frame[2] = calc_lrc(frame, 2);
nengzix 29:c19cea6e2ec3 191 sprintf(rttmp, fmtstr, frame[0], frame[1], frame[2]);
nengzix 25:4d1450e7cb88 192 //printf("Response: %s", str);
vsupacha 24:0007712e84a8 193 }
vsupacha 24:0007712e84a8 194 }