Add Floating point read/write commands

r3029 | dcl | 2010-11-12 14:56:28 +1100 (Fri, 12 Nov 2010) | 1 line
This commit is contained in:
Douglas Clowes
2010-11-12 14:56:28 +11:00
parent 2e0780f2b1
commit 2e658ff4a9

View File

@@ -5,10 +5,11 @@
#include <ascon.h> #include <ascon.h>
#include <ascon.i> #include <ascon.i>
#include <dynstring.h> #include <dynstring.h>
#include <stdbool.h>
static int dbgprintf(char* fmtstr, ...); static int dbgprintf(char* fmtstr, ...);
static int dbgprintx(const char* msg, const unsigned char* cp, int blen); static int dbgprintx(const char* msg, const unsigned char* cp, int blen);
static unsigned int debug_modbus = 0; static unsigned int debug_modbus = 1;
/** @brief encode modbus request /** @brief encode modbus request
* TODO: clean me up * TODO: clean me up
@@ -20,6 +21,7 @@ int ModbusWriteStart(Ascon *a) {
char temp[32]; char temp[32];
char* endp = NULL; char* endp = NULL;
int idx = 6; int idx = 6;
bool do_float = false;
temp[0] = 0; /* transaction id */ temp[0] = 0; /* transaction id */
temp[1] = 0; temp[1] = 0;
temp[2] = 0; /* protocol id */ temp[2] = 0; /* protocol id */
@@ -38,16 +40,22 @@ int ModbusWriteStart(Ascon *a) {
temp[idx++] = dev; temp[idx++] = dev;
buff = endp + 1; buff = endp + 1;
cmd = strtoul(buff, &endp, 10); cmd = strtoul(buff, &endp, 10);
if (endp == buff || (cmd != 3 && cmd != 16)) { /* read/write registers */ if (endp == buff || (cmd != 3 && cmd != 16 && cmd != 1003 && cmd != 1016)) { /* read/write registers */
dbgprintf("modbus-er: Bad command id: %d from %s\n", cmd, buff); dbgprintf("modbus-er: Bad command id: %d from %s\n", cmd, buff);
a->state = AsconIdle; a->state = AsconIdle;
AsconError(a, "Bad command id", 0); AsconError(a, "Bad command id", 0);
return 0; return 0;
} }
if (cmd > 1000) {
cmd %= 1000;
do_float = true;
} else {
do_float = false;
}
temp[idx++] = cmd; temp[idx++] = cmd;
buff = endp + 1; buff = endp + 1;
reg = strtoul(buff, &endp, 10); reg = strtoul(buff, &endp, 10);
if (endp == buff || reg < 1 || reg > 65535) { if (endp == buff || reg > 65535) {
dbgprintf("modbus-er: Bad register id: %d from %s\n", reg, buff); dbgprintf("modbus-er: Bad register id: %d from %s\n", reg, buff);
a->state = AsconIdle; a->state = AsconIdle;
AsconError(a, "Bad register id", 0); AsconError(a, "Bad register id", 0);
@@ -56,20 +64,39 @@ int ModbusWriteStart(Ascon *a) {
temp[idx++] = (reg >> 8) & 0xFF; temp[idx++] = (reg >> 8) & 0xFF;
temp[idx++] = reg & 0xFF; temp[idx++] = reg & 0xFF;
temp[idx++] = 0; /* word count msbyte */ temp[idx++] = 0; /* word count msbyte */
temp[idx++] = 1; /* word count lsbyte */ if (do_float)
temp[idx++] = 2; /* word count lsbyte */
else
temp[idx++] = 1; /* word count lsbyte */
if (cmd == 16) { /* write registers */ if (cmd == 16) { /* write registers */
buff = endp + 1; buff = endp + 1;
unsigned int val; if (do_float) {
val = strtoul(buff, &endp, 10); union { unsigned char v[4]; float val; } u;
if (endp == buff || val > 65535) { u.val = strtof(buff, &endp);
dbgprintf("modbus-er: Bad value: %d from %s\n", val, buff); if (endp == buff) {
a->state = AsconIdle; dbgprintf("modbus-er: Bad value: %f from %s\n", u.val, buff);
AsconError(a, "Bad value", 0); a->state = AsconIdle;
return 0; AsconError(a, "Bad value", 0);
return 0;
}
temp[idx++] = 4; /* byte count */
temp[idx++] = u.v[1];
temp[idx++] = u.v[0];
temp[idx++] = u.v[3];
temp[idx++] = u.v[2];
} else {
unsigned int val;
val = strtoul(buff, &endp, 10);
if (endp == buff || val > 65535) {
dbgprintf("modbus-er: Bad value: %d from %s\n", val, buff);
a->state = AsconIdle;
AsconError(a, "Bad value", 0);
return 0;
}
temp[idx++] = 2; /* byte count */
temp[idx++] = (val >> 8) & 0xFF;
temp[idx++] = val & 0xFF;
} }
temp[idx++] = 2; /* byte count */
temp[idx++] = (val >> 8) & 0xFF;
temp[idx++] = val & 0xFF;
} }
len = idx - 6; len = idx - 6;
temp[4] = len >> 8; /* length msbyte */ temp[4] = len >> 8; /* length msbyte */
@@ -109,8 +136,19 @@ int ModbusReading(Ascon *a) {
if (cp[7] == 3 && cp[8] == 2) { if (cp[7] == 3 && cp[8] == 2) {
rlen = snprintf(temp, 64, "%d", (((unsigned int)cp[9]) << 8) + (unsigned int)cp[10]); rlen = snprintf(temp, 64, "%d", (((unsigned int)cp[9]) << 8) + (unsigned int)cp[10]);
} }
else if (cp[7] == 3 && cp[8] == 4) {
union { unsigned char v[4]; float val; } u;
u.v[1] = cp[9];
u.v[0] = cp[10];
u.v[3] = cp[11];
u.v[2] = cp[12];
rlen = snprintf(temp, 64, "%g", u.val);
}
else if (cp[7] == 16 && cp[11] == 1) { else if (cp[7] == 16 && cp[11] == 1) {
rlen = snprintf(temp, 64, "OK"); rlen = snprintf(temp, 64, "OK int");
}
else if (cp[7] == 16 && cp[11] == 2) {
rlen = snprintf(temp, 64, "OK float");
} }
else if (((unsigned int)cp[7]) == 0x83) { else if (((unsigned int)cp[7]) == 0x83) {
rlen = snprintf(temp, 64, "ASCERR:%02x:%d", cp[7], cp[8]); rlen = snprintf(temp, 64, "ASCERR:%02x:%d", cp[7], cp[8]);