Commit 19f09f4e authored by Claes Sjofors's avatar Claes Sjofors

IO Ardino connect request, checksum and 16 bits ao

parent c6c0ff6a
......@@ -23,7 +23,7 @@ all : init copy lib
init :
copy : $(inc_dir)/libusbio.h $(inc_dir)/openSocket.h $(inc_dir)/setport.h $(inc_dir)/pwr_arduino_uno.pde
copy : $(inc_dir)/libusbio.h $(inc_dir)/openSocket.h $(inc_dir)/setport.h $(inc_dir)/pwr_arduino_uno.ino
lib :
......@@ -51,8 +51,8 @@ $(inc_dir)/setport.h : ../../setport.h
@ echo "Copying setport.h"
@ $(cp) $(cpflags) $(source) $(target)
$(inc_dir)/pwr_arduino_uno.pde : ../../pwr_arduino_uno.pde
@ echo "Copying pwr_arduino_uno.pde"
$(inc_dir)/pwr_arduino_uno.ino : ../../pwr_arduino_uno.ino
@ echo "Copying pwr_arduino_uno.ino"
@ $(cp) $(cpflags) $(source) $(target)
......
//
// Proview
// Copyright (C) 2010 SSAB Oxelösund AB.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 2 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the program, if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// Description:
// Sketch for Arduino USB board to communicate with Proview I/O
// object OtherIO:Arduino_Uno.
//
byte firmware[20] = "Proview 2012-02-29";
byte version_major = 2;
byte version_minor = 0;
byte msg = 0;
byte sts;
int val = 0;
byte amsg[50];
byte smsg[10];
byte diSize = 0;
byte doSize = 0;
byte aiSize = 0;
byte aoSize = 0;
byte diMask[10];
byte doMask[10];
byte aiMask[4];
byte aoMask[4];
int watchdogTime = 5000;
int status;
int i;
int j;
int aiList[32];
int aiCnt;
int aoList[32];
int aoCnt;
byte msgType;
byte msgId;
byte msgSize;
byte msgData[100];
byte rmsg[40];
int sizeErrorCnt = 0;
int noMessageCnt = 0;
const int delayTime = 1;
const int debug = 0;
const int MSG_TYPE_DOWRITE = 1;
const int MSG_TYPE_DIREAD = 2;
const int MSG_TYPE_AIREAD = 3;
const int MSG_TYPE_AOWRITE = 4;
const int MSG_TYPE_CONFIGURE = 5;
const int MSG_TYPE_STATUS = 6;
const int MSG_TYPE_DEBUG = 7;
const int MSG_TYPE_WRITEALL = 8;
const int MSG_TYPE_READALL = 9;
const int MSG_TYPE_CONNECTREQ = 10;
const int MSG_TYPE_CONNECTRES = 11;
const int ARD__SUCCESS = 1;
const int ARD__DICONFIG = 2;
const int ARD__DOCONFIG = 4;
const int ARD__AICONFIG = 6;
const int ARD__AOCONFIG = 8;
const int ARD__COMMERROR = 10;
const int ARD__MSGSIZE = 12;
const int ARD__NOMSG = 14;
const int ARD__CHECKSUM = 16;
void sendDebug( byte sts)
{
rmsg[0] = 4;
rmsg[1] = 0;
rmsg[2] = MSG_TYPE_DEBUG;
rmsg[3] = sts;
add_checksum( rmsg);
Serial.write( rmsg, rmsg[0]);
}
void add_checksum( byte *buf)
{
int i;
byte sum = 0;
buf[0]++;
for ( i = 0; i < buf[0] - 1; i++)
sum ^= buf[i];
buf[buf[0]-1] = sum;
}
int check_checksum( byte size, byte id, byte type, byte *buf)
{
int i;
unsigned char sum = 0;
sum ^= size;
sum ^= id;
sum ^= type;
for ( i = 0; i < size - 4; i++)
sum ^= buf[i];
if ( buf[size-1] == sum)
return 1;
return 0;
}
//
// Reset all outputs when communication communication is down
//
void resetOutput()
{
for ( i = 0; i < doSize; i++) {
for ( j = 0; j < 8; j++) {
if ( ((1 << j) & doMask[i]) != 0)
digitalWrite( i * 8 + j, LOW);
}
}
for ( i = 0; i < aoCnt; i++)
analogWrite( aoList[i], 0);
}
//
// Read a message from the serial port
//
int serialRead()
{
int num;
num = Serial.available();
if ( num == 0)
return ARD__NOMSG;
msgSize = Serial.peek();
if ( num < msgSize)
return ARD__MSGSIZE;
msgSize = Serial.read();
msgId = Serial.read();
msgType = Serial.read();
msgSize -= 3;
for ( int i = 0; i < msgSize; i++)
msgData[i] = Serial.read();
if ( !check_checksum( msgSize, msgId, msgType, msgData))
return ARD__CHECKSUM;
if ( debug) {
rmsg[0] = msgSize - 1 + 3;
rmsg[1] = msgId;
rmsg[2] = MSG_TYPE_DEBUG;
for ( int j = 0; j < msgSize-1; j++)
rmsg[j+3] = msgData[j];
add_checksum( rmsg);
Serial.write( rmsg, rmsg[0]);
}
return ARD__SUCCESS;
}
void setup()
{
// Start serial port at the configured baud rate
Serial.begin(9600);
Serial.flush();
}
void loop()
{
status = serialRead();
if ( status == ARD__NOMSG) {
if ( watchdogTime != 0) {
// Increment watchdog counter
noMessageCnt++;
if ( noMessageCnt * delayTime > watchdogTime)
resetOutput();
}
}
else if ( status == ARD__MSGSIZE) {
sizeErrorCnt++;
if ( sizeErrorCnt > 50) {
Serial.flush();
sizeErrorCnt = 0;
}
}
else if ( (status & 1) != 0) {
// A message is received
sizeErrorCnt = 0;
noMessageCnt = 0;
if ( msgType == MSG_TYPE_DOWRITE) {
// Write digital outputs
if ( msgSize == doSize) {
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);
}
}
}
sts = ARD__SUCCESS;
}
else {
sts = ARD__COMMERROR;
}
}
else if ( msgType == MSG_TYPE_AOWRITE) {
// Write analog outputs
if ( msgSize == aoCnt) {
for ( i = 0; i < aoCnt; i++)
analogWrite( aoList[i], msgData[i]);
sts = ARD__SUCCESS;
}
else {
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) {
// Read Digital inputs
smsg[0] = diSize + 3;
smsg[1] = msgId;
smsg[2] = MSG_TYPE_DIREAD;
for ( i = 0; i < diSize; i++) {
smsg[i + 3] = 0;
for ( j = 0; j < 8; j++) {
if ( ((1 << j) & diMask[i]) != 0) {
val = digitalRead( i * 8 + j);
if ( val == HIGH)
smsg[i + 3] |= 1 << j;
}
}
}
add_checksum( smsg);
Serial.write( smsg, smsg[0]);
}
else if ( msgType == MSG_TYPE_AIREAD) {
// Read analog inputs
amsg[0] = aiCnt * 2 + 3;
amsg[1] = msgId;
amsg[2] = MSG_TYPE_AIREAD;
for ( i = 0; i < aiCnt; i++) {
val = analogRead( aiList[i]);
amsg[i*2 + 3] = val / 256;
amsg[i*2 + 1 + 3] = val % 256;
}
add_checksum( amsg);
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;
}
add_checksum( amsg);
Serial.write( amsg, amsg[0]);
}
else if ( msgType == MSG_TYPE_CONFIGURE) {
// Configure message
int offs = 0;
sts = ARD__SUCCESS;
if ( debug) {
smsg[0] = msgSize + 3;
smsg[1] = msgId;
smsg[2] = MSG_TYPE_DEBUG;
for ( int j = 0; j < msgSize; j++)
smsg[j+3] = msgData[j];
add_checksum( smsg);
Serial.write( smsg, smsg[0]);
}
watchdogTime = msgData[offs++] * 100;
diSize = msgData[offs++];
if ( diSize > 10) {
diSize = 10;
sts = ARD__DICONFIG;
}
if ( sts & 1 != 0) {
for ( i = 0; i < diSize; i++)
diMask[i] = msgData[offs++];
}
if ( sts & 1 != 0) {
doSize = msgData[offs++];
if ( doSize > 10) {
doSize = 10;
sts = ARD__DOCONFIG;
}
}
if ( sts & 1 != 0) {
for ( i = 0; i < doSize; i++)
doMask[i] = msgData[offs++];
}
if ( sts & 1 != 0) {
aiSize = msgData[offs++];
if ( aiSize > 4) {
aiSize = 4;
sts = ARD__AICONFIG;
}
}
if ( sts & 1 != 0) {
for ( i = 0; i < aiSize; i++)
aiMask[i] = msgData[offs++];
}
if ( sts & 1 != 0) {
aoSize = msgData[offs++];
if ( aoSize > 4) {
aoSize = 4;
sts = ARD__AOCONFIG;
}
}
if ( sts & 1 != 0) {
for ( i = 0; i < aoSize; i++)
aoMask[i] = msgData[offs++];
}
if ( sts & 1 != 0) {
// Set Di pinmode
for ( i = 0; i < diSize; i++) {
for ( j = 0; j < 8; j++) {
if ( ((1 << j) & diMask[i]) != 0)
pinMode( i * 8 + j, INPUT);
}
}
// Set Do pinmode
for ( i = 0; i < doSize; i++) {
for ( j = 0; j < 8; j++) {
if ( ((1 << j) & doMask[i]) != 0)
pinMode( i * 8 + j, OUTPUT);
}
}
// Create list of configured Ai
aiCnt = 0;
for ( i = 0; i < aiSize; i++) {
for ( j = 0; j < 8; j++) {
if ( ((1 << j) & aiMask[i]) != 0) {
aiList[aiCnt] = i * 8 + j;
aiCnt++;
}
}
}
// Create list of configured Ao
aoCnt = 0;
for ( i = 0; i < aoSize; i++) {
for ( j = 0; j < 8; j++) {
if ( ((1 << j) & aoMask[i]) != 0) {
aoList[aoCnt] = i * 8 + j;
aoCnt++;
}
}
}
}
// Send configuration status
smsg[0] = 4;
smsg[1] = msgId;
smsg[2] = MSG_TYPE_STATUS;
smsg[3] = sts;
add_checksum( smsg);
Serial.write(smsg, smsg[0]);
}
else if ( msgType == MSG_TYPE_CONNECTREQ) {
// Connect reqeust
amsg[0] = 23 + 3;
amsg[1] = msgId;
amsg[2] = MSG_TYPE_CONNECTRES;
amsg[3] = ARD__SUCCESS;
amsg[4] = version_major;
amsg[5] = version_minor;
for ( i = 0; i < 20; i++)
amsg[i+6] = firmware[i];
add_checksum( amsg);
Serial.write( amsg, amsg[0]);
}
}
else {
// Return error status
smsg[0] = 4;
smsg[1] = msgId;
smsg[2] = MSG_TYPE_STATUS;
smsg[3] = status;
add_checksum( smsg);
Serial.write(smsg, smsg[0]);
}
delay(delayTime);
}
......@@ -72,7 +72,9 @@ typedef enum {
ard_eMsgType_Status = 6,
ard_eMsgType_Debug = 7,
ard_eMsgType_WriteAll = 8,
ard_eMsgType_ReadAll = 9
ard_eMsgType_ReadAll = 9,
ard_eMsgType_ConnectReq = 10,
ard_eMsgType_ConnectRes = 11
} ard_eMsgType;
typedef struct {
......@@ -96,6 +98,8 @@ typedef struct {
int AoIntervalCnt;
int Reconnect;
int ReconnectCnt;
int VersionMajor;
int VersionMinor;
io_sChannel *DChanList[D_MAX_SIZE * 8];
io_sChannel *AiChanList[AI_MAX_SIZE * 8];
io_sChannel *AoChanList[AO_MAX_SIZE * 8];
......@@ -125,6 +129,7 @@ static void logg( const char *str)
#define ARD__COMMERROR 10
#define ARD__MSGSIZE 12
#define ARD__NOMSG 14
#define ARD__CHECKSUM 16
typedef struct {
unsigned char size __attribute__ ((aligned(1)));
......@@ -133,15 +138,211 @@ typedef struct {
unsigned char data[100] __attribute__ ((aligned(1)));
} ard_sMsg;
static unsigned char checksum( unsigned char *buf, int len)
static void add_checksum( void *buf);
static int check_checksum( void *buf);
static int receive( int fd, int id, ard_sMsg *rmsg, int size, float tmo, pwr_sClass_Arduino_Uno *op);
static int open_device( io_sLocal *local, pwr_sClass_Arduino_Uno *op, io_sCard *cp)
{
struct termios tty_attributes;
int sts;
// Open device
local->fd = open( op->Device, O_RDWR | O_NDELAY | O_NOCTTY);
if ( local->fd == -1) {
errh_Error( "IO Init Card '%s', unable to open device %s", cp->Name, op->Device);
op->Status = pwr_eArduino_StatusEnum_NoSuchDevice;
return IO__INITFAIL;
}
tcgetattr( local->fd, &tty_attributes);
#if defined OS_LINUX
tty_attributes.c_cflag &= ~CBAUD; //maska bort all hastighet
#endif
switch( op->BaudRate) {
case 300:
tty_attributes.c_cflag |= B300;
break;
case 1200:
tty_attributes.c_cflag |= B1200;
break;
case 2400:
tty_attributes.c_cflag |= B2400;
break;
case 4800:
tty_attributes.c_cflag |= B4800;
break;
case 9600:
tty_attributes.c_cflag |= B9600;
break;
case 19200:
tty_attributes.c_cflag |= B19200;
break;
case 38400:
tty_attributes.c_cflag |= B38400;
break;
case 57600:
tty_attributes.c_cflag |= B57600;
break;
case 115200:
tty_attributes.c_cflag |= B115200;
break;
default:
tty_attributes.c_cflag |= B9600;
break;
}
tty_attributes.c_iflag &= ~(BRKINT | ICRNL | IMAXBEL);
tty_attributes.c_oflag &= ~(OPOST | ONLCR);
tty_attributes.c_lflag &= ~(ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE);
tty_attributes.c_cc[VMIN] = 1;
tty_attributes.c_cc[VTIME] = 0;
tty_attributes.c_cc[VEOF] = 1;
sts = tcsetattr( local->fd, TCSANOW, &tty_attributes);
if ( sts < 0) {
errh_Error( "IO Init Card '%s', unable to set baud rate on device %s", cp->Name, op->Device);
op->Status = pwr_eArduino_StatusEnum_DeviceSetupError;
return IO__INITFAIL;
}
tcflush( local->fd, TCIOFLUSH);
return IO__SUCCESS;
}
static int send_configuration( io_sLocal *local, pwr_sClass_Arduino_Uno *op, io_sCard *cp)
{
unsigned char wdg;
int i;
int sts;
// Configure Watchdog
if ( op->WatchdogTime == 0)
wdg = 0;
else if ( op->WatchdogTime > 255)
wdg = 255;
else {
wdg = op->WatchdogTime * 10;
if ( wdg < 1)
wdg = 1;
}
// Send config message
ard_sMsg msg, rmsg;
int offs = 0;
msg.size = 3;
msg.id = local->IdCnt++;
msg.type = ard_eMsgType_Configure;
msg.data[offs++] = wdg;
msg.data[offs++] = local->DiSize;
for ( i = 0; i < local->DiSize; i++)
msg.data[offs++] = local->DiMask[i];
msg.data[offs++] = local->DoSize;
for ( i = 0; i < local->DoSize; i++)
msg.data[offs++] = local->DoMask[i];
msg.data[offs++] = local->AiSize;
for ( i = 0; i < local->AiSize; i++)
msg.data[offs++] = local->AiMask[i];
msg.data[offs++] = local->AoSize;
for ( i = 0; i < local->AoSize; i++)
msg.data[offs++] = local->AoMask[i];
msg.size += offs;
printf( "Config (size=%d, id= %d): ", offs, msg.id);
for ( i = 0; i < offs; i++)
printf( "%u ", msg.data[i]);
printf( "\n");
sleep(5);
if ( op->Options & pwr_mArduino_OptionsMask_Checksum)
add_checksum( &msg);
sts = write( local->fd, &msg, msg.size);
sts = receive( local->fd, msg.id, &rmsg, 1, op->Timeout, op);
if ( sts & 1) {
op->Status = rmsg.data[0];
}
else {
errh_Error( "IO Init Card '%s', config error: %d", cp->Name, sts);
op->Status = sts;
if ( sts == pwr_eArduino_StatusEnum_NoMessage)
sts = pwr_eArduino_StatusEnum_ConnectionTimeout;
return IO__INITFAIL;
printf( "Config read error %d\n", sts);
}
return IO__SUCCESS;
}
static int send_connect_request( io_sLocal *local, pwr_sClass_Arduino_Uno *op, io_sCard *cp)
{
int sts;
// Send connect request
ard_sMsg msg, rmsg;
msg.size = 3;
msg.id = local->IdCnt++;
msg.type = ard_eMsgType_ConnectReq;
if ( op->Options & pwr_mArduino_OptionsMask_Checksum)
add_checksum( &msg);
sts = write( local->fd, &msg, msg.size);
sts = receive( local->fd, msg.id, &rmsg, 21, op->Timeout, op);
if ( sts & 1) {
if ( rmsg.type != ard_eMsgType_ConnectRes)
return IO__INITFAIL;
op->Status = rmsg.data[0];
local->VersionMajor = rmsg.data[1];
local->VersionMinor = rmsg.data[2];
snprintf( op->FirmwareVersion, sizeof(op->FirmwareVersion), "V%d.%d %s",
local->VersionMajor, local->VersionMinor, (char *)&rmsg.data[3]);
}
else {
return IO__INITFAIL;
}
return IO__SUCCESS;
}
static void add_checksum( void *buf)
{
int i;
unsigned char sum = 0;
unsigned char *b = (unsigned char *)buf;
b[0]++;
for ( i = 0; i < b[0] - 1; i++)
sum ^= b[i];
b[b[0]-1] = sum;
}
static int check_checksum( void *buf)
{
int i;
unsigned char sum = 0;
unsigned char *b = (unsigned char *)buf;
for ( i = 0; i < len; i++)
sum ^= buf[i];
for ( i = 0; i < b[0] - 1; i++)
sum ^= b[i];
return sum;
if ( b[b[0]-1] == sum)
return 1;
return 0;
}
static void get_tv(struct timeval *tv, float t)
......@@ -156,7 +357,7 @@ static void get_tv(struct timeval *tv, float t)
}
}
static int receive( int fd, int id, ard_sMsg *rmsg, int size, float tmo)
static int receive( int fd, int id, ard_sMsg *rmsg, int size, float tmo, pwr_sClass_Arduino_Uno *op)
{
fd_set rfd;
struct timeval tv;
......@@ -164,6 +365,9 @@ static int receive( int fd, int id, ard_sMsg *rmsg, int size, float tmo)
int msize;
int ret;
if ( op->Options & pwr_mArduino_OptionsMask_Checksum)
size++;
FD_ZERO(&rfd);
FD_SET(fd, &rfd);
while ( 1) {
......@@ -200,14 +404,21 @@ static int receive( int fd, int id, ard_sMsg *rmsg, int size, float tmo)
printf( "\n");
}
else {
if ( rmsg->size == size + 3 && rmsg->id == id)
if ( rmsg->size == size + 3 && rmsg->id == id) {
if ( op->Options & pwr_mArduino_OptionsMask_Checksum) {
if ( !check_checksum( rmsg))
return ARD__CHECKSUM;
rmsg->size--;
}
return ARD__SUCCESS;
}
}
}
return ARD__NOMSG;
}
static int apoll( ard_sMsg *msg, io_sLocal *local, ard_eMsgType mtype)
static int apoll( ard_sMsg *msg, io_sLocal *local, ard_eMsgType mtype, pwr_sClass_Arduino_Uno *op)
{
int sts;
......@@ -220,6 +431,9 @@ static int apoll( ard_sMsg *msg, io_sLocal *local, ard_eMsgType mtype)
msg->type = mtype;
// logg( "Poll Di");
if ( op->Options & pwr_mArduino_OptionsMask_Checksum)
add_checksum( msg);
sts = write( local->fd, msg, msg->size);
local->DiPollId = msg->id;
local->DiPendingPoll = 1;
......@@ -238,8 +452,6 @@ static pwr_tStatus IoCardInit( io_tCtx ctx,
unsigned int number, number_byte, number_bit;
pwr_tStatus sts;
int i;
unsigned char wdg;
struct termios tty_attributes;
// fp = fopen( "/home/claes/ard.log", "w"); // Test
......@@ -350,127 +562,17 @@ static pwr_tStatus IoCardInit( io_tCtx ctx,
}
}
// Configure Watchdog
if ( op->WatchdogTime == 0)
wdg = 0;
else if ( op->WatchdogTime > 255)
wdg = 255;
else {
wdg = op->WatchdogTime * 10;
if ( wdg < 1)
wdg = 1;
}
sts = open_device( local, op, cp);
if ( EVEN(sts)) return sts;
// Open device
local->fd = open( op->Device, O_RDWR | O_NDELAY | O_NOCTTY);
if ( local->fd == -1) {
errh_Error( "IO Init Card '%s', unable to open device %s", cp->Name, op->Device);
op->Status = pwr_eArduino_StatusEnum_NoSuchDevice;
return IO__INITFAIL;
}
tcgetattr( local->fd, &tty_attributes);
#if defined OS_LINUX
tty_attributes.c_cflag &= ~CBAUD; //maska bort all hastighet
#endif
switch( op->BaudRate) {
case 300:
tty_attributes.c_cflag |= B300;
break;
case 1200:
tty_attributes.c_cflag |= B1200;
break;
case 2400:
tty_attributes.c_cflag |= B2400;
break;
case 4800:
tty_attributes.c_cflag |= B4800;
break;
case 9600:
tty_attributes.c_cflag |= B9600;
break;
case 19200:
tty_attributes.c_cflag |= B19200;
break;
case 38400:
tty_attributes.c_cflag |= B38400;
break;
case 57600:
tty_attributes.c_cflag |= B57600;
break;
case 115200:
tty_attributes.c_cflag |= B115200;
break;
default:
tty_attributes.c_cflag |= B9600;
break;
}
tty_attributes.c_iflag &= ~(BRKINT | ICRNL | IMAXBEL);
tty_attributes.c_oflag &= ~(OPOST | ONLCR);
tty_attributes.c_lflag &= ~(ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE);
tty_attributes.c_cc[VMIN] = 1;
tty_attributes.c_cc[VTIME] = 0;
tty_attributes.c_cc[VEOF] = 1;
sts = tcsetattr( local->fd, TCSANOW, &tty_attributes);
if ( sts < 0) {
errh_Error( "IO Init Card '%s', unable to set baud rate on device %s", cp->Name, op->Device);
op->Status = pwr_eArduino_StatusEnum_DeviceSetupError;
return IO__INITFAIL;
}
tcflush( local->fd, TCIOFLUSH);
// Send config message
ard_sMsg msg, rmsg;
int offs = 0;
msg.size = 3;
msg.id = local->IdCnt++;
msg.type = ard_eMsgType_Configure;
msg.data[offs++] = wdg;
msg.data[offs++] = local->DiSize;
for ( i = 0; i < local->DiSize; i++)
msg.data[offs++] = local->DiMask[i];
msg.data[offs++] = local->DoSize;
for ( i = 0; i < local->DoSize; i++)
msg.data[offs++] = local->DoMask[i];
msg.data[offs++] = local->AiSize;
for ( i = 0; i < local->AiSize; i++)
msg.data[offs++] = local->AiMask[i];
msg.data[offs++] = local->AoSize;
for ( i = 0; i < local->AoSize; i++)
msg.data[offs++] = local->AoMask[i];
msg.size += offs;
printf( "Config (size=%d, id= %d): ", offs, msg.id);
for ( i = 0; i < offs; i++)
printf( "%u ", msg.data[i]);
printf( "\n");
sleep(5);
sts = write( local->fd, &msg, msg.size);
sts = receive( local->fd, msg.id, &rmsg, 1, op->Timeout);
if ( sts & 1) {
op->Status = rmsg.data[0];
}
else {
errh_Error( "IO Init Card '%s', config error: %d", cp->Name, sts);
op->Status = sts;
if ( sts == pwr_eArduino_StatusEnum_NoMessage)
sts = pwr_eArduino_StatusEnum_ConnectionTimeout;
return IO__INITFAIL;
printf( "Config read error %d\n", sts);
if ( op->Options & pwr_mArduino_OptionsMask_ConnectionRequest) {
sts = send_connect_request( local, op, cp);
if ( EVEN(sts)) return sts;
}
sts = send_configuration( local, op, cp);
if ( EVEN(sts)) return sts;
errh_Info( "Init of Arduino card '%s'", cp->Name);
return IO__SUCCESS;
......@@ -534,7 +636,7 @@ static pwr_tStatus IoCardRead( io_tCtx ctx,
mtype = ard_eMsgType_No;
if ( !local->DiPendingPoll)
apoll( &msg, local, mtype);
apoll( &msg, local, mtype, op);
else
mtype = local->PendingMsgType;
......@@ -552,7 +654,7 @@ static pwr_tStatus IoCardRead( io_tCtx ctx,
sts = receive( local->fd, local->DiPollId, &rmsg, local->DiSize + local->AiNum * 2,
op->Timeout);
op->Timeout, op);
op->Status = sts;
if ( EVEN(sts)) {
op->ErrorCount++;
......@@ -617,7 +719,7 @@ static pwr_tStatus IoCardRead( io_tCtx ctx,
int i, j;
unsigned char m;
sts = receive( local->fd, local->DiPollId, &rmsg, local->DiSize, op->Timeout);
sts = receive( local->fd, local->DiPollId, &rmsg, local->DiSize, op->Timeout, op);
op->Status = sts;
if ( EVEN(sts)) {
op->ErrorCount++;
......@@ -647,7 +749,7 @@ static pwr_tStatus IoCardRead( io_tCtx ctx,
pwr_tInt32 ivalue;
pwr_tFloat32 actvalue;
sts = receive( local->fd, local->DiPollId, &rmsg, local->AiNum * 2, op->Timeout);
sts = receive( local->fd, local->DiPollId, &rmsg, local->AiNum * 2, op->Timeout, op);
if ( EVEN(sts)) {
}
else {
......@@ -771,6 +873,9 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
// logg( "Write Do");
if ( op->Options & pwr_mArduino_OptionsMask_Checksum)
add_checksum( &msg);
sts = write( local->fd, &msg, msg.size);
}
else if ( local->AoSize && !local->DoSize) {
......@@ -780,7 +885,10 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
int value;
memset( &msg, 0, sizeof(msg));
msg.size = local->AoNum + 3;
if ( op->Options & pwr_mArduino_OptionsMask_Ao16Bit)
msg.size = local->AoNum + 3;
else
msg.size = local->AoNum * 2 + 3;
msg.id = local->IdCnt++;
msg.type = ard_eMsgType_AoWrite;
......@@ -805,12 +913,23 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
value = *(pwr_tFloat32 *)chanp->vbp * cop->OutPolyCoef1 +
cop->OutPolyCoef0 + 0.49;
if ( value < 0)
value = 0;
else if (value > 255)
value = 255;
if ( op->Options & pwr_mArduino_OptionsMask_Ao16Bit) {
if ( value < 0)
value = 0;
else if (value > 65535)
value = 65535;
msg.data[ao_cnt] = value;
msg.data[ao_cnt * 2] = value / 256;
msg.data[ao_cnt * 2 + 1] = value % 256;
}
else {
if ( value < 0)
value = 0;
else if (value > 255)
value = 255;
msg.data[ao_cnt] = value;
}
sop->SigValue = cop->SigValPolyCoef1 * *(pwr_tFloat32 *)chanp->vbp +
cop->SigValPolyCoef0;
......@@ -820,12 +939,19 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
}
}
// logg( "Write Ao");
if ( op->Options & pwr_mArduino_OptionsMask_Checksum)
add_checksum( &msg);
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;
if ( op->Options & pwr_mArduino_OptionsMask_Ao16Bit)
msg.size = local->DoSize + local->AoNum * 2 + 3;
else
msg.size = local->DoSize + local->AoNum + 3;
msg.id = local->IdCnt++;
msg.type = ard_eMsgType_WriteAll;
......@@ -872,12 +998,29 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
value = *(pwr_tFloat32 *)chanp->vbp * cop->OutPolyCoef1 +
cop->OutPolyCoef0 + 0.49;
if ( op->Options & pwr_mArduino_OptionsMask_Ao16Bit) {
if ( value < 0)
value = 0;
else if (value > 65535)
value = 65535;
msg.data[local->DoSize + ao_cnt * 2] = value / 256;
msg.data[local->DoSize + ao_cnt * 2 + 1] = value % 256;
}
else {
if ( value < 0)
value = 0;
else if (value > 255)
value = 255;
msg.data[local->DoSize + ao_cnt] = value;
}
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;
......@@ -887,6 +1030,10 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
}
}
// logg( "Write All");
if ( op->Options & pwr_mArduino_OptionsMask_Checksum)
add_checksum( &msg);
sts = write( local->fd, &msg, msg.size);
}
......@@ -930,7 +1077,7 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
else
mtype = ard_eMsgType_No;
apoll( &msg, local, mtype);
apoll( &msg, local, mtype, op);
}
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