Inclusion of MOD IO digital input reading functions

Test: Program is tested locally with laptop.

        modified:   server.c
parent db52601f
...@@ -144,11 +144,9 @@ static int setRelayState(int command, int i2c_addr) { ...@@ -144,11 +144,9 @@ static int setRelayState(int command, int i2c_addr) {
// step 3: write command over I2c // step 3: write command over I2c
__u8 reg = 0x10; /* Device register to access */ __u8 reg = 0x10; /* Device register to access */
__s32 res;
char buf[10]; char buf[10];
buf[0] = reg; buf[0] = reg;
buf[1] = command; //0x00 -all off, 0x0F - all 4 on buf[1] = command; //0x00 -all off, 0x0F - all 4 on
buf[2] = 0x65; // seems irrelevant the value
if (write(file, buf, 3) != 3) { if (write(file, buf, 3) != 3) {
/* ERROR HANDLING: i2c transaction failed */ /* ERROR HANDLING: i2c transaction failed */
printf("Error writing to i2c slave (0x%x).\n", i2c_addr); printf("Error writing to i2c slave (0x%x).\n", i2c_addr);
...@@ -156,6 +154,51 @@ static int setRelayState(int command, int i2c_addr) { ...@@ -156,6 +154,51 @@ static int setRelayState(int command, int i2c_addr) {
close(file); close(file);
} }
static int getDigitalInputState( int i2c_addr, char **digital_input) {
/*
* get digital input state over I2C
*/
int file;
char filename[20];
if(I2C_VIRTUAL_MODE){
// we're in a virtual mode, likely on x86 platform or without I2C support
// simply do nothing
return 0;
}
// step 1: open device
file = open(I2C_BLOCK_DEVICE_NAME, O_RDWR);
if (file < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */
printf("Error opening i2c device (0x%x).\n", i2c_addr);
exit(1);
}
// step 2: address the slave by its address
if (ioctl(file, I2C_SLAVE, i2c_addr) < 0) {
/* ERROR HANDLING; you can check errno to see what went wrong */
printf("Error addressing i2c slave (0x%x).\n", i2c_addr);
exit(1);
}
// step 3: write command over I2c
__u8 read_reg = 0x20; /* Device register to access */
char read_buf[2];
read_buf[0] = read_reg;
if (write(file, read_buf, 1) != 1) {
/* ERROR HANDLING: i2c transaction failed */
printf("Error writing to i2c slave (0x%x).\n", i2c_addr);
}
if (read(file, read_buf, 1) != 1) {
/* ERROR HANDLING: i2c transaction failed */
printf("Error reading digital input from i2c slave (0x%x).\n", i2c_addr);
} else {
/* read_buf[0] contains the read byte */
*digital_input=&read_buf[0];
}
close(file);
}
void addIntegerVariableNode(UA_Server *server, char *node_id, char *node_description) { void addIntegerVariableNode(UA_Server *server, char *node_id, char *node_description) {
UA_Int32 myInteger = 0; UA_Int32 myInteger = 0;
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
...@@ -175,6 +218,25 @@ void addIntegerVariableNode(UA_Server *server, char *node_id, char *node_descrip ...@@ -175,6 +218,25 @@ void addIntegerVariableNode(UA_Server *server, char *node_id, char *node_descrip
} }
void addIntegerVariableReadNode(UA_Server *server, char *node_id, char *node_description) {
UA_Int32 myInteger = 0;
UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
UA_VariableAttributes attr0 = UA_VariableAttributes_default;
UA_Variant_setScalar(&attr0.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);
attr0.description = UA_LOCALIZEDTEXT("en-US", node_description);
attr0.displayName = UA_LOCALIZEDTEXT("en-US", node_description);
attr0.dataType = UA_TYPES[UA_TYPES_INT32].typeId;
attr0.accessLevel = UA_ACCESSLEVELMASK_READ;
UA_NodeId myIntegerNodeId0 = UA_NODEID_STRING(1, node_id);
UA_QualifiedName myIntegerName0 = UA_QUALIFIEDNAME(1, node_description);
UA_Server_addVariableNode(server, myIntegerNodeId0, parentNodeId,
parentReferenceNodeId, myIntegerName0,
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), attr0, NULL, NULL);
}
static void addVariable(UA_Server *server) { static void addVariable(UA_Server *server) {
/* /*
* Create all variables representing MOD-IO's relays * Create all variables representing MOD-IO's relays
...@@ -186,6 +248,10 @@ static void addVariable(UA_Server *server) { ...@@ -186,6 +248,10 @@ static void addVariable(UA_Server *server) {
addIntegerVariableNode(server, "i2c0.relay1", "I2C0 / Relay 1"); addIntegerVariableNode(server, "i2c0.relay1", "I2C0 / Relay 1");
addIntegerVariableNode(server, "i2c0.relay2", "I2C0 / Relay 2"); addIntegerVariableNode(server, "i2c0.relay2", "I2C0 / Relay 2");
addIntegerVariableNode(server, "i2c0.relay3", "I2C0 / Relay 3"); addIntegerVariableNode(server, "i2c0.relay3", "I2C0 / Relay 3");
addIntegerVariableReadNode(server, "i2c0.in0", "I2C0 / Digital Input 0");
addIntegerVariableReadNode(server, "i2c0.in1", "I2C0 / Digital Input 1");
addIntegerVariableReadNode(server, "i2c0.in2", "I2C0 / Digital Input 2");
addIntegerVariableReadNode(server, "i2c0.in3", "I2C0 / Digital Input 3");
} }
if (length>=2) { if (length>=2) {
// IC2-1 // IC2-1
...@@ -193,6 +259,10 @@ static void addVariable(UA_Server *server) { ...@@ -193,6 +259,10 @@ static void addVariable(UA_Server *server) {
addIntegerVariableNode(server, "i2c1.relay1", "I2C1 / Relay 1"); addIntegerVariableNode(server, "i2c1.relay1", "I2C1 / Relay 1");
addIntegerVariableNode(server, "i2c1.relay2", "I2C1 / Relay 2"); addIntegerVariableNode(server, "i2c1.relay2", "I2C1 / Relay 2");
addIntegerVariableNode(server, "i2c1.relay3", "I2C1 / Relay 3"); addIntegerVariableNode(server, "i2c1.relay3", "I2C1 / Relay 3");
addIntegerVariableReadNode(server, "i2c1.in0", "I2C1 / Digital Input 0");
addIntegerVariableReadNode(server, "i2c1.in1", "I2C1 / Digital Input 1");
addIntegerVariableReadNode(server, "i2c1.in2", "I2C1 / Digital Input 2");
addIntegerVariableReadNode(server, "i2c1.in3", "I2C1 / Digital Input 3");
} }
} }
...@@ -203,7 +273,156 @@ static void beforeReadTime(UA_Server *server, ...@@ -203,7 +273,156 @@ static void beforeReadTime(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext, const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) { const UA_NumericRange *range, const UA_DataValue *data) {
// nothing to do as not yet needed.
}
static void beforeReadTimeI2C0In0(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
int addr = I2C_SLAVE_ADDR_LIST[0];
char *data_input=0;
getDigitalInputState( addr, &data_input);
if ((*data_input) & (1UL << 0)){
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 1;
}
} else {
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 0;
}
}
}
static void beforeReadTimeI2C0In1(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
int addr = I2C_SLAVE_ADDR_LIST[0];
char *data_input=0;
getDigitalInputState( addr, &data_input);
if ((*data_input) & (1UL << 1)){
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 1;
}
} else {
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 0;
}
}
}
static void beforeReadTimeI2C0In2(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
int addr = I2C_SLAVE_ADDR_LIST[0];
char *data_input=0;
getDigitalInputState( addr, &data_input);
if ((*data_input) & (1UL << 2)){
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 1;
}
} else {
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 0;
}
}
}
static void beforeReadTimeI2C0In3(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
int addr = I2C_SLAVE_ADDR_LIST[0];
char *data_input=0;
getDigitalInputState( addr, &data_input);
if ((*data_input) & (1UL << 3)){
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 1;
}
} else {
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 0;
}
}
}
static void beforeReadTimeI2C1In0(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
int addr = I2C_SLAVE_ADDR_LIST[0];
char *data_input=0;
getDigitalInputState( addr, &data_input);
if ((*data_input) & (1UL << 0)){
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 1;
}
} else {
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 0;
}
}
}
static void beforeReadTimeI2C1In1(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
int addr = I2C_SLAVE_ADDR_LIST[0];
char *data_input=0;
getDigitalInputState( addr, &data_input);
if ((*data_input) & (1UL << 1)){
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 1;
}
} else {
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 0;
}
}
}
static void beforeReadTimeI2C1In2(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
int addr = I2C_SLAVE_ADDR_LIST[0];
char *data_input=0;
getDigitalInputState( addr, &data_input);
if ((*data_input) & (1UL << 2)){
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 1;
}
} else {
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 0;
}
}
}
static void beforeReadTimeI2C1In3(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeid, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
int addr = I2C_SLAVE_ADDR_LIST[0];
char *data_input=0;
getDigitalInputState( addr, &data_input);
if ((*data_input) & (1UL << 3)){
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 1;
}
} else {
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]) {
*(UA_Int32 *)data->value.data = 0;
}
}
}
static void afterWriteTime(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) {
// nothing to do as not yet needed.
} }
// XXX: having afterWriteTime{0..3} is not needed and maybe with introspection of context we can // XXX: having afterWriteTime{0..3} is not needed and maybe with introspection of context we can
...@@ -386,35 +605,91 @@ static void addValueCallbackToCurrentTimeVariable(UA_Server *server) { ...@@ -386,35 +605,91 @@ static void addValueCallbackToCurrentTimeVariable(UA_Server *server) {
callback3.onWrite = afterWriteTimeI2C0_3; callback3.onWrite = afterWriteTimeI2C0_3;
UA_Server_setVariableNode_valueCallback(server, currentNodeId3, callback3); UA_Server_setVariableNode_valueCallback(server, currentNodeId3, callback3);
// Digital input 0
UA_NodeId currentNodeId4 = UA_NODEID_STRING(1, "i2c0.in0");
UA_ValueCallback callback4;
callback4.onRead = beforeReadTimeI2C0In0;
callback4.onWrite = afterWriteTime;
UA_Server_setVariableNode_valueCallback(server, currentNodeId4, callback4);
// Digital input 1
UA_NodeId currentNodeId5 = UA_NODEID_STRING(1, "i2c0.in1");
UA_ValueCallback callback5;
callback5.onRead = beforeReadTimeI2C0In1;
callback5.onWrite = afterWriteTime;
UA_Server_setVariableNode_valueCallback(server, currentNodeId5, callback5);
// Digital input 2
UA_NodeId currentNodeId6 = UA_NODEID_STRING(1, "i2c0.in2");
UA_ValueCallback callback6;
callback6.onRead = beforeReadTimeI2C0In2;
callback6.onWrite = afterWriteTime;
UA_Server_setVariableNode_valueCallback(server, currentNodeId6, callback6);
// Digital input 3
UA_NodeId currentNodeId7 = UA_NODEID_STRING(1, "i2c0.in3");
UA_ValueCallback callback7;
callback7.onRead = beforeReadTimeI2C0In3;
callback7.onWrite = afterWriteTime;
UA_Server_setVariableNode_valueCallback(server, currentNodeId7, callback7);
if(length > 1){ if(length > 1){
// I2C1 // I2C1
// relay 0 // relay 0
UA_NodeId currentNodeId4 = UA_NODEID_STRING(1, "i2c1.relay0"); UA_NodeId currentNodeId8 = UA_NODEID_STRING(1, "i2c1.relay0");
UA_ValueCallback callback4; UA_ValueCallback callback8;
callback4.onRead = beforeReadTime; callback8.onRead = beforeReadTime;
callback4.onWrite = afterWriteTimeI2C1_0; callback8.onWrite = afterWriteTimeI2C1_0;
UA_Server_setVariableNode_valueCallback(server, currentNodeId4, callback4); UA_Server_setVariableNode_valueCallback(server, currentNodeId8, callback8);
// relay 1 // relay 1
UA_NodeId currentNodeId5 = UA_NODEID_STRING(1, "i2c1.relay1"); UA_NodeId currentNodeId9 = UA_NODEID_STRING(1, "i2c1.relay1");
UA_ValueCallback callback5; UA_ValueCallback callback9;
callback5.onRead = beforeReadTime; callback9.onRead = beforeReadTime;
callback5.onWrite = afterWriteTimeI2C1_1; callback9.onWrite = afterWriteTimeI2C1_1;
UA_Server_setVariableNode_valueCallback(server, currentNodeId5, callback5); UA_Server_setVariableNode_valueCallback(server, currentNodeId9, callback9);
// relay 2 // relay 2
UA_NodeId currentNodeId6 = UA_NODEID_STRING(1, "i2c1.relay2"); UA_NodeId currentNodeId10 = UA_NODEID_STRING(1, "i2c1.relay2");
UA_ValueCallback callback6; UA_ValueCallback callback10;
callback6.onRead = beforeReadTime; callback10.onRead = beforeReadTime;
callback6.onWrite = afterWriteTimeI2C1_2; callback10.onWrite = afterWriteTimeI2C1_2;
UA_Server_setVariableNode_valueCallback(server, currentNodeId6, callback6); UA_Server_setVariableNode_valueCallback(server, currentNodeId6, callback10);
// relay 2 // relay 2
UA_NodeId currentNodeId7 = UA_NODEID_STRING(1, "i2c1.relay3"); UA_NodeId currentNodeId11 = UA_NODEID_STRING(1, "i2c1.relay3");
UA_ValueCallback callback7; UA_ValueCallback callback11;
callback7.onRead = beforeReadTime; callback11.onRead = beforeReadTime;
callback7.onWrite = afterWriteTimeI2C1_3; callback11.onWrite = afterWriteTimeI2C1_3;
UA_Server_setVariableNode_valueCallback(server, currentNodeId7, callback7); UA_Server_setVariableNode_valueCallback(server, currentNodeId11, callback11);
// Digital input 0
UA_NodeId currentNodeId12 = UA_NODEID_STRING(1, "i2c1.in0");
UA_ValueCallback callback12;
callback12.onRead = beforeReadTimeI2C1In0;
callback12.onWrite = afterWriteTime;
UA_Server_setVariableNode_valueCallback(server, currentNodeId12, callback12);
// Digital input 1
UA_NodeId currentNodeId13 = UA_NODEID_STRING(1, "i2c1.in1");
UA_ValueCallback callback13;
callback13.onRead = beforeReadTimeI2C1In1;
callback13.onWrite = afterWriteTime;
UA_Server_setVariableNode_valueCallback(server, currentNodeId13, callback13);
// Digital input 2
UA_NodeId currentNodeId14 = UA_NODEID_STRING(1, "i2c1.in2");
UA_ValueCallback callback14;
callback14.onRead = beforeReadTimeI2C1In2;
callback14.onWrite = afterWriteTime;
UA_Server_setVariableNode_valueCallback(server, currentNodeId14, callback14);
// Digital input 3
UA_NodeId currentNodeId15 = UA_NODEID_STRING(1, "i2c1.in3");
UA_ValueCallback callback15;
callback15.onRead = beforeReadTimeI2C1In3;
callback15.onWrite = afterWriteTime;
UA_Server_setVariableNode_valueCallback(server, currentNodeId15, callback15);
} }
} }
......
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