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:
@@ -5,10 +5,11 @@
|
||||
#include <ascon.h>
|
||||
#include <ascon.i>
|
||||
#include <dynstring.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static int dbgprintf(char* fmtstr, ...);
|
||||
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
|
||||
* TODO: clean me up
|
||||
@@ -20,6 +21,7 @@ int ModbusWriteStart(Ascon *a) {
|
||||
char temp[32];
|
||||
char* endp = NULL;
|
||||
int idx = 6;
|
||||
bool do_float = false;
|
||||
temp[0] = 0; /* transaction id */
|
||||
temp[1] = 0;
|
||||
temp[2] = 0; /* protocol id */
|
||||
@@ -38,16 +40,22 @@ int ModbusWriteStart(Ascon *a) {
|
||||
temp[idx++] = dev;
|
||||
buff = endp + 1;
|
||||
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);
|
||||
a->state = AsconIdle;
|
||||
AsconError(a, "Bad command id", 0);
|
||||
return 0;
|
||||
}
|
||||
if (cmd > 1000) {
|
||||
cmd %= 1000;
|
||||
do_float = true;
|
||||
} else {
|
||||
do_float = false;
|
||||
}
|
||||
temp[idx++] = cmd;
|
||||
buff = endp + 1;
|
||||
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);
|
||||
a->state = AsconIdle;
|
||||
AsconError(a, "Bad register id", 0);
|
||||
@@ -56,9 +64,27 @@ int ModbusWriteStart(Ascon *a) {
|
||||
temp[idx++] = (reg >> 8) & 0xFF;
|
||||
temp[idx++] = reg & 0xFF;
|
||||
temp[idx++] = 0; /* word count msbyte */
|
||||
if (do_float)
|
||||
temp[idx++] = 2; /* word count lsbyte */
|
||||
else
|
||||
temp[idx++] = 1; /* word count lsbyte */
|
||||
if (cmd == 16) { /* write registers */
|
||||
buff = endp + 1;
|
||||
if (do_float) {
|
||||
union { unsigned char v[4]; float val; } u;
|
||||
u.val = strtof(buff, &endp);
|
||||
if (endp == buff) {
|
||||
dbgprintf("modbus-er: Bad value: %f from %s\n", u.val, buff);
|
||||
a->state = AsconIdle;
|
||||
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) {
|
||||
@@ -71,6 +97,7 @@ int ModbusWriteStart(Ascon *a) {
|
||||
temp[idx++] = (val >> 8) & 0xFF;
|
||||
temp[idx++] = val & 0xFF;
|
||||
}
|
||||
}
|
||||
len = idx - 6;
|
||||
temp[4] = len >> 8; /* length msbyte */
|
||||
temp[5] = len & 0xFF; /* length lsbyte */
|
||||
@@ -109,8 +136,19 @@ int ModbusReading(Ascon *a) {
|
||||
if (cp[7] == 3 && cp[8] == 2) {
|
||||
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) {
|
||||
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) {
|
||||
rlen = snprintf(temp, 64, "ASCERR:%02x:%d", cp[7], cp[8]);
|
||||
|
||||
Reference in New Issue
Block a user