Commit 125dbd02 authored by Claes's avatar Claes

Arduino, common read msg for Di,Ai, and common write for Do,Ao

parent 796a09f8
...@@ -51,13 +51,15 @@ int noMessageCnt = 0; ...@@ -51,13 +51,15 @@ int noMessageCnt = 0;
const int delayTime = 1; const int delayTime = 1;
const int debug = 0; const int debug = 0;
const int MSG_TYPE_WRITE = 1; const int MSG_TYPE_DOWRITE = 1;
const int MSG_TYPE_DIREAD = 2; const int MSG_TYPE_DIREAD = 2;
const int MSG_TYPE_AIREAD = 3; const int MSG_TYPE_AIREAD = 3;
const int MSG_TYPE_AOWRITE = 4; const int MSG_TYPE_AOWRITE = 4;
const int MSG_TYPE_CONFIGURE = 5; const int MSG_TYPE_CONFIGURE = 5;
const int MSG_TYPE_STATUS = 6; const int MSG_TYPE_STATUS = 6;
const int MSG_TYPE_DEBUG = 7; const int MSG_TYPE_DEBUG = 7;
const int MSG_TYPE_WRITEALL = 8;
const int MSG_TYPE_READALL = 9;
const int ARD__SUCCESS = 1; const int ARD__SUCCESS = 1;
const int ARD__DICONFIG = 2; const int ARD__DICONFIG = 2;
...@@ -159,7 +161,7 @@ void loop() ...@@ -159,7 +161,7 @@ void loop()
sizeErrorCnt = 0; sizeErrorCnt = 0;
noMessageCnt = 0; noMessageCnt = 0;
if ( msgType == MSG_TYPE_WRITE) { if ( msgType == MSG_TYPE_DOWRITE) {
// Write digital outputs // Write digital outputs
if ( msgSize == doSize) { if ( msgSize == doSize) {
...@@ -192,6 +194,30 @@ void loop() ...@@ -192,6 +194,30 @@ void loop()
sts = ARD__COMMERROR; sts = ARD__COMMERROR;
} }
} }
else if ( msgType == MSG_TYPE_WRITEALL) {
// Write digital outputs
if ( msgSize == doSize + aoCnt) {
for ( i = 0; i < doSize; i++) {
for ( j = 0; j < 8; j++) {
if ( ((1 << j) & doMask[i]) != 0) {
if ( ((1 << j) & msgData[i]) != 0)
digitalWrite( i * 8 + j, HIGH);
else
digitalWrite( i * 8 + j, LOW);
}
}
}
for ( i = 0; i < aoCnt; i++)
analogWrite( aoList[i], msgData[doSize + i]);
sts = ARD__SUCCESS;
}
else {
sts = ARD__COMMERROR;
}
}
else if ( msgType == MSG_TYPE_DIREAD) { else if ( msgType == MSG_TYPE_DIREAD) {
// Read Digital inputs // Read Digital inputs
smsg[0] = diSize + 3; smsg[0] = diSize + 3;
...@@ -221,6 +247,29 @@ void loop() ...@@ -221,6 +247,29 @@ void loop()
} }
Serial.write( amsg, amsg[0]); Serial.write( amsg, amsg[0]);
} }
else if ( msgType == MSG_TYPE_READALL) {
// Read Digital inputs
amsg[0] = diSize + aiCnt * 2 + 3;
amsg[1] = msgId;
amsg[2] = MSG_TYPE_READALL;
for ( i = 0; i < diSize; i++) {
amsg[i + 3] = 0;
for ( j = 0; j < 8; j++) {
if ( ((1 << j) & diMask[i]) != 0) {
val = digitalRead( i * 8 + j);
if ( val == HIGH)
amsg[i + 3] |= 1 << j;
}
}
}
for ( i = 0; i < aiCnt; i++) {
val = analogRead( aiList[i]);
amsg[diSize + i*2 + 3] = val / 256;
amsg[diSize + i*2 + 1 + 3] = val % 256;
}
Serial.write( amsg, amsg[0]);
}
else if ( msgType == MSG_TYPE_CONFIGURE) { else if ( msgType == MSG_TYPE_CONFIGURE) {
// Configure message // Configure message
int offs = 0; int offs = 0;
......
...@@ -34,6 +34,19 @@ ...@@ -34,6 +34,19 @@
#define AI_MAX_SIZE 4 #define AI_MAX_SIZE 4
#define AO_MAX_SIZE 4 #define AO_MAX_SIZE 4
typedef enum {
ard_eMsgType_No = 0,
ard_eMsgType_DoWrite = 1,
ard_eMsgType_DiRead = 2,
ard_eMsgType_AiRead = 3,
ard_eMsgType_AoWrite = 4,
ard_eMsgType_Configure = 5,
ard_eMsgType_Status = 6,
ard_eMsgType_Debug = 7,
ard_eMsgType_WriteAll = 8,
ard_eMsgType_ReadAll = 9
} ard_eMsgType;
typedef struct { typedef struct {
pwr_tTime ErrTime; pwr_tTime ErrTime;
int fd; int fd;
...@@ -50,6 +63,7 @@ typedef struct { ...@@ -50,6 +63,7 @@ typedef struct {
int IdCnt; int IdCnt;
int DiPollId; int DiPollId;
int DiPendingPoll; int DiPendingPoll;
ard_eMsgType PendingMsgType;
int AiIntervalCnt; int AiIntervalCnt;
int AoIntervalCnt; int AoIntervalCnt;
io_sChannel *DChanList[D_MAX_SIZE * 8]; io_sChannel *DChanList[D_MAX_SIZE * 8];
...@@ -83,16 +97,6 @@ static void logg( const char *str) ...@@ -83,16 +97,6 @@ static void logg( const char *str)
} }
#endif #endif
typedef enum {
ard_eMsgType_Write = 1,
ard_eMsgType_DiRead = 2,
ard_eMsgType_AiRead = 3,
ard_eMsgType_AoWrite = 4,
ard_eMsgType_Configure = 5,
ard_eMsgType_Status = 6,
ard_eMsgType_Debug = 7
} ard_eMsgType;
#define ARD__SUCCESS 1 #define ARD__SUCCESS 1
#define ARD__DICONFIG 2 #define ARD__DICONFIG 2
#define ARD__DOCONFIG 4 #define ARD__DOCONFIG 4
...@@ -153,18 +157,23 @@ static int receive( int fd, int id, ard_sMsg *rmsg, int size) ...@@ -153,18 +157,23 @@ static int receive( int fd, int id, ard_sMsg *rmsg, int size)
return ARD__NOMSG; return ARD__NOMSG;
} }
static int poll_di( ard_sMsg *msg, io_sLocal *local) static int poll( ard_sMsg *msg, io_sLocal *local, ard_eMsgType mtype)
{ {
int sts; int sts;
local->PendingMsgType = mtype;
if ( mtype == ard_eMsgType_No)
return 1;
msg->size = 3; msg->size = 3;
msg->id = local->IdCnt++; msg->id = local->IdCnt++;
msg->type = ard_eMsgType_DiRead; msg->type = mtype;
// logg( "Poll Di"); // logg( "Poll Di");
sts = write( local->fd, msg, msg->size); sts = write( local->fd, msg, msg->size);
local->DiPollId = msg->id; local->DiPollId = msg->id;
local->DiPendingPoll = 1; local->DiPendingPoll = 1;
local->PendingMsgType = mtype;
return sts; return sts;
} }
...@@ -437,29 +446,52 @@ static pwr_tStatus IoCardRead( io_tCtx ctx, ...@@ -437,29 +446,52 @@ static pwr_tStatus IoCardRead( io_tCtx ctx,
unsigned int m; unsigned int m;
pwr_tUInt32 error_count = op->ErrorCount; pwr_tUInt32 error_count = op->ErrorCount;
int sts; int sts;
int skip_ai;
ard_eMsgType mtype;
ard_sMsg msg;
if ( local->AiSize) {
skip_ai = 0;
if ( local->DiSize) { if ( op->AiScanInterval > 1) {
ard_sMsg msg, rmsg; skip_ai = local->AiIntervalCnt;
int sts;
int i, j;
unsigned char m;
local->AiIntervalCnt++;
if ( local->AiIntervalCnt >= op->AiScanInterval)
local->AiIntervalCnt = 0;
}
}
else
skip_ai = 1;
if ( !local->DiPendingPoll) if ( local->DiSize && skip_ai)
poll_di( &msg, local); mtype = ard_eMsgType_DiRead;
else if ( local->DiSize && !skip_ai)
mtype = ard_eMsgType_ReadAll;
else if ( !skip_ai)
mtype = ard_eMsgType_AiRead;
else
mtype = ard_eMsgType_No;
#if 0 if ( !local->DiPendingPoll)
msg.size = 3; poll( &msg, local, mtype);
msg.id = local->IdCnt++; else
msg.type = ard_eMsgType_DiRead; mtype = local->PendingMsgType;
// logg( "Poll Di"); local->DiPendingPoll = 0;
sts = write( local->fd, &msg, msg.size);
#endif
local->DiPendingPoll = 0;
sts = receive( local->fd, local->DiPollId, &rmsg, local->DiSize); if ( mtype == ard_eMsgType_ReadAll ) {
// Both Ai and Di
ard_sMsg rmsg;
int sts;
int i, j;
unsigned char m;
pwr_tInt32 ivalue;
pwr_tFloat32 actvalue;
sts = receive( local->fd, local->DiPollId, &rmsg, local->DiSize + local->AiNum * 2);
op->Status = sts; op->Status = sts;
if ( EVEN(sts)) { if ( EVEN(sts)) {
op->ErrorCount++; op->ErrorCount++;
...@@ -475,31 +507,74 @@ static pwr_tStatus IoCardRead( io_tCtx ctx, ...@@ -475,31 +507,74 @@ static pwr_tStatus IoCardRead( io_tCtx ctx,
} }
} }
} }
int ai_cnt = 0;
for ( i = 0; i < local->AiSize; i++) {
for ( j = 0; j < 8; j++) {
m = 1 << j;
if ( local->AiMask[i] & m) {
io_sChannel *chanp = local->AiChanList[i*8+j];
pwr_sClass_ChanAi *cop = (pwr_sClass_ChanAi *)chanp->cop;
pwr_sClass_Ai *sop = (pwr_sClass_Ai *)chanp->sop;
if ( cop->CalculateNewCoef)
// Request to calculate new coefficients
io_AiRangeToCoef( chanp);
ivalue = rmsg.data[local->DiSize + ai_cnt*2] * 256 +
rmsg.data[local->DiSize+ai_cnt*2 + 1];
io_ConvertAi( cop, ivalue, &actvalue);
// Filter
if ( sop->FilterType == 1 &&
sop->FilterAttribute[0] > 0 &&
sop->FilterAttribute[0] > ctx->ScanTime) {
actvalue = *(pwr_tFloat32 *)chanp->vbp + ctx->ScanTime / sop->FilterAttribute[0] *
(actvalue - *(pwr_tFloat32 *)chanp->vbp);
}
*(pwr_tFloat32 *)chanp->vbp = actvalue;
sop->SigValue = cop->SigValPolyCoef1 * ivalue + cop->SigValPolyCoef0;
sop->RawValue = ivalue;
ai_cnt++;
}
}
}
} }
else if ( mtype == ard_eMsgType_DiRead) {
// Only Di, no Ai
if ( local->AiSize) { ard_sMsg rmsg;
int skip_ai = 0; int sts;
int i, j;
unsigned char m;
if ( op->AiScanInterval > 1) { sts = receive( local->fd, local->DiPollId, &rmsg, local->DiSize);
skip_ai = local->AiIntervalCnt; op->Status = sts;
if ( EVEN(sts)) {
op->ErrorCount++;
}
else {
// printf( "Read: %u %u (%d)\n", rmsg.data[0], rmsg.data[1], sts);
local->AiIntervalCnt++; for ( i = 0; i < local->DiSize; i++) {
if ( local->AiIntervalCnt >= op->AiScanInterval) for ( j = 0; j < 8; j++) {
local->AiIntervalCnt = 0; m = 1 << j;
if ( local->DiMask[i] & m)
*(pwr_tBoolean *)local->DChanList[i*8+j]->vbp = ((rmsg.data[i] & m) != 0);
}
}
} }
}
else if ( mtype == ard_eMsgType_AiRead) {
// Only Ai, no Di
if ( !skip_ai) { if ( !skip_ai) {
ard_sMsg msg, rmsg; ard_sMsg rmsg;
pwr_tInt32 ivalue; pwr_tInt32 ivalue;
pwr_tFloat32 actvalue; pwr_tFloat32 actvalue;
msg.size = 3; sts = receive( local->fd, local->DiPollId, &rmsg, local->AiNum * 2);
msg.id = local->IdCnt++;
msg.type = ard_eMsgType_AiRead;
sts = write( local->fd, &msg, msg.size);
sts = receive( local->fd, msg.id, &rmsg, local->AiNum * 2);
if ( EVEN(sts)) { if ( EVEN(sts)) {
} }
else { else {
...@@ -563,13 +638,28 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx, ...@@ -563,13 +638,28 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
pwr_tUInt32 error_count = op->ErrorCount; pwr_tUInt32 error_count = op->ErrorCount;
ard_sMsg msg; ard_sMsg msg;
int sts; int sts;
int skip_ao;
if ( local->AoSize) {
skip_ao = 0;
if ( op->AoScanInterval > 1) {
skip_ao = local->AoIntervalCnt;
local->AoIntervalCnt++;
if ( local->AoIntervalCnt >= op->AoScanInterval)
local->AoIntervalCnt = 0;
}
}
else
skip_ao = 1;
if ( local->DoSize) { if ( local->DoSize && skip_ao) {
memset( &msg, 0, sizeof(msg)); memset( &msg, 0, sizeof(msg));
msg.size = local->DoSize + 3; msg.size = local->DoSize + 3;
msg.id = local->IdCnt++; msg.id = local->IdCnt++;
msg.type = ard_eMsgType_Write; msg.type = ard_eMsgType_DoWrite;
for ( i = 0; i < local->DoSize; i++) { for ( i = 0; i < local->DoSize; i++) {
for ( j = 0; j < 8; j++) { for ( j = 0; j < 8; j++) {
...@@ -584,18 +674,8 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx, ...@@ -584,18 +674,8 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
// logg( "Write Do"); // logg( "Write Do");
sts = write( local->fd, &msg, msg.size); sts = write( local->fd, &msg, msg.size);
} }
else if ( local->AoSize && !local->DoSize) {
if ( local->AoSize) {
int skip_ao = 0;
if ( op->AoScanInterval > 1) {
skip_ao = local->AoIntervalCnt;
local->AoIntervalCnt++;
if ( local->AoIntervalCnt >= op->AoScanInterval)
local->AoIntervalCnt = 0;
}
if ( !skip_ao) { if ( !skip_ao) {
ard_sMsg msg; ard_sMsg msg;
...@@ -639,7 +719,59 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx, ...@@ -639,7 +719,59 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
// logg( "Write Ao"); // logg( "Write Ao");
sts = write( local->fd, &msg, msg.size); sts = write( local->fd, &msg, msg.size);
} }
}
else if ( local->DoSize && !skip_ao) {
memset( &msg, 0, sizeof(msg));
msg.size = local->DoSize + local->AoNum + 3;
msg.id = local->IdCnt++;
msg.type = ard_eMsgType_WriteAll;
for ( i = 0; i < local->DoSize; i++) {
for ( j = 0; j < 8; j++) {
m = 1 << j;
if ( local->DoMask[i] & m) {
if ( *(pwr_tBoolean *)local->DChanList[i*8+j]->vbp)
msg.data[i] |= m;
}
}
}
int value;
int ao_cnt = 0;
for ( i = 0; i < local->AoSize; i++) {
for ( j = 0; j < 8; j++) {
m = 1 << j;
if ( local->AoMask[i] & m) {
io_sChannel *chanp = local->AoChanList[i*8+j];
pwr_sClass_ChanAo *cop = (pwr_sClass_ChanAo *)chanp->cop;
pwr_sClass_Ao *sop = (pwr_sClass_Ao *)chanp->sop;
if ( cop->CalculateNewCoef)
// Request to calculate new coefficients
io_AoRangeToCoef( chanp);
value = *(pwr_tFloat32 *)chanp->vbp * cop->OutPolyCoef1 +
cop->OutPolyCoef0 + 0.49;
if ( value < 0)
value = 0;
else if (value > 255)
value = 255;
msg.data[local->DoSize + ao_cnt] = value;
sop->SigValue = cop->SigValPolyCoef1 * *(pwr_tFloat32 *)chanp->vbp +
cop->SigValPolyCoef0;
sop->RawValue = value;
ao_cnt++;
}
}
}
// logg( "Write All");
sts = write( local->fd, &msg, msg.size);
} }
if ( op->ErrorCount >= op->ErrorSoftLimit && if ( op->ErrorCount >= op->ErrorSoftLimit &&
...@@ -652,11 +784,30 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx, ...@@ -652,11 +784,30 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
return IO__ERRDEVICE; return IO__ERRDEVICE;
} }
if ( local->DiSize && if ( op->Options & pwr_mArduino_OptionsMask_OptimizedDiPoll) {
op->Options & pwr_mArduino_OptionsMask_OptimizedDiPoll) {
ard_sMsg msg; ard_sMsg msg;
int skip_ai;
ard_eMsgType mtype;
poll_di( &msg, local); if ( local->AiSize) {
skip_ai = 0;
if ( op->AiScanInterval > 1)
skip_ai = local->AiIntervalCnt;
}
else
skip_ai = 1;
if ( local->DiSize && skip_ai)
mtype = ard_eMsgType_DiRead;
else if ( local->DiSize && !skip_ai)
mtype = ard_eMsgType_ReadAll;
else if ( !skip_ai)
mtype = ard_eMsgType_AiRead;
else
mtype = ard_eMsgType_No;
poll( &msg, local, mtype);
} }
return IO__SUCCESS; return IO__SUCCESS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment