Commit 2d6699e8 authored by Ivan Tyagov's avatar Ivan Tyagov

Fixup mod io

See merge request nexedi/osie!40
parents 4e53f19d 0a02dd20
// global relay state
// global relay state - XXX: use a list rather than individual variables
uint8_t I2C_0_RELAYS_STATE = 0; // state of 4 relays at I2C slave 0
uint8_t I2C_1_RELAYS_STATE = 0; // state of 4 relays at I2C slave 1
......@@ -8,8 +8,11 @@ static char *DEFAULT_I2C_0_ADDR = "0x58";
// the list of attached I2C slaves
const int DEFAULT_I2C_SLAVE_ADDR = 0x58;
// XXX:code assumes only 8 I2C slaves but it can be up to 127
int I2C_SLAVE_ADDR_LIST[] = {0, 0, 0, 0, 0, 0, 0, 0};
// the current architecture of LIME2 supports up to 127 MOD-IO I2C slaves
int I2C_SLAVE_ADDR_LIST[127] = {0};
// the number of physical relays
int DEFAULT_RELAY_COUNT = 4;
// the block device at host machine
static char *DEFAULT_I2C_BLOCK_DEVICE_NAME = "/dev/i2c-1";
......@@ -173,7 +176,6 @@ static int getAnalogInputStateAIN(int i2c_addr, int **analog_input, uint8_t read
}
// step 3: write command over I2c
//__u8 read_reg = 0x30; /* Device register to access */
char read_buf[10];
read_buf[0] = read_reg;
if (write(file, read_buf, 1) != 1)
......
......@@ -66,138 +66,32 @@ static void addVariable(UA_Server *server)
/*
* Create all variables representing MOD-IO's relays
*/
int i,n;;
int length = getI2CSlaveListLength();
if (length >= 1)
{
// IC2-0
addIntegerVariableNode(server, "i2c0.relay0", "I2C0 / Relay 0");
addIntegerVariableNode(server, "i2c0.relay1", "I2C0 / Relay 1");
addIntegerVariableNode(server, "i2c0.relay2", "I2C0 / Relay 2");
addIntegerVariableNode(server, "i2c0.relay3", "I2C0 / Relay 3");
addBooleanVariableReadNode(server, "i2c0.in0", "I2C0 / Digital Input 0");
addBooleanVariableReadNode(server, "i2c0.in1", "I2C0 / Digital Input 1");
addBooleanVariableReadNode(server, "i2c0.in2", "I2C0 / Digital Input 2");
addBooleanVariableReadNode(server, "i2c0.in3", "I2C0 / Digital Input 3");
addUIntegerVariableReadNode(server, "i2c0.ain0", "I2C0 / Analog Input 0");
addUIntegerVariableReadNode(server, "i2c0.ain1", "I2C0 / Analog Input 1");
addUIntegerVariableReadNode(server, "i2c0.ain2", "I2C0 / Analog Input 2");
addUIntegerVariableReadNode(server, "i2c0.ain3", "I2C0 / Analog Input 3");
}
if (length >= 2)
{
// IC2-1
addIntegerVariableNode(server, "i2c1.relay0", "I2C1 / Relay 0");
addIntegerVariableNode(server, "i2c1.relay1", "I2C1 / Relay 1");
addIntegerVariableNode(server, "i2c1.relay2", "I2C1 / Relay 2");
addIntegerVariableNode(server, "i2c1.relay3", "I2C1 / Relay 3");
addBooleanVariableReadNode(server, "i2c1.in0", "I2C1 / Digital Input 0");
addBooleanVariableReadNode(server, "i2c1.in1", "I2C1 / Digital Input 1");
addBooleanVariableReadNode(server, "i2c1.in2", "I2C1 / Digital Input 2");
addBooleanVariableReadNode(server, "i2c1.in3", "I2C1 / Digital Input 3");
addUIntegerVariableReadNode(server, "i2c1.ain0", "I2C1 / Analog Input 0");
addUIntegerVariableReadNode(server, "i2c1.ain1", "I2C1 / Analog Input 1");
addUIntegerVariableReadNode(server, "i2c1.ain2", "I2C1 / Analog Input 2");
addUIntegerVariableReadNode(server, "i2c1.ain3", "I2C1 / Analog Input 3");
}
if (length >= 3)
{
// IC2-2
addIntegerVariableNode(server, "i2c2.relay0", "I2C2 / Relay 0");
addIntegerVariableNode(server, "i2c2.relay1", "I2C2 / Relay 1");
addIntegerVariableNode(server, "i2c2.relay2", "I2C2 / Relay 2");
addIntegerVariableNode(server, "i2c2.relay3", "I2C2 / Relay 3");
addBooleanVariableReadNode(server, "i2c2.in0", "I2C2 / Digital Input 0");
addBooleanVariableReadNode(server, "i2c2.in1", "I2C2 / Digital Input 1");
addBooleanVariableReadNode(server, "i2c2.in2", "I2C2 / Digital Input 2");
addBooleanVariableReadNode(server, "i2c2.in3", "I2C2 / Digital Input 3");
addUIntegerVariableReadNode(server, "i2c2.ain0", "I2C2 / Analog Input 0");
addUIntegerVariableReadNode(server, "i2c2.ain1", "I2C2 / Analog Input 1");
addUIntegerVariableReadNode(server, "i2c2.ain2", "I2C2 / Analog Input 2");
addUIntegerVariableReadNode(server, "i2c2.ain3", "I2C2 / Analog Input 3");
}
if (length >= 4)
{
// IC2-3
addIntegerVariableNode(server, "i2c3.relay0", "I2C3 / Relay 0");
addIntegerVariableNode(server, "i2c3.relay1", "I2C3 / Relay 1");
addIntegerVariableNode(server, "i2c3.relay2", "I2C3 / Relay 2");
addIntegerVariableNode(server, "i2c3.relay3", "I2C3 / Relay 3");
addBooleanVariableReadNode(server, "i2c3.in0", "I2C3 / Digital Input 0");
addBooleanVariableReadNode(server, "i2c3.in1", "I2C3 / Digital Input 1");
addBooleanVariableReadNode(server, "i2c3.in2", "I2C3 / Digital Input 2");
addBooleanVariableReadNode(server, "i2c3.in3", "I2C3 / Digital Input 3");
addUIntegerVariableReadNode(server, "i2c3.ain0", "I2C3 / Analog Input 0");
addUIntegerVariableReadNode(server, "i2c3.ain1", "I2C3 / Analog Input 1");
addUIntegerVariableReadNode(server, "i2c3.ain2", "I2C3 / Analog Input 2");
addUIntegerVariableReadNode(server, "i2c3.ain3", "I2C3 / Analog Input 3");
}
if (length >= 5)
{
// IC2-4
addIntegerVariableNode(server, "i2c4.relay0", "I2C4 / Relay 0");
addIntegerVariableNode(server, "i2c4.relay1", "I2C4 / Relay 1");
addIntegerVariableNode(server, "i2c4.relay2", "I2C4 / Relay 2");
addIntegerVariableNode(server, "i2c4.relay3", "I2C4 / Relay 3");
addBooleanVariableReadNode(server, "i2c4.in0", "I2C4 / Digital Input 0");
addBooleanVariableReadNode(server, "i2c4.in1", "I2C4 / Digital Input 1");
addBooleanVariableReadNode(server, "i2c4.in2", "I2C4 / Digital Input 2");
addBooleanVariableReadNode(server, "i2c4.in3", "I2C4 / Digital Input 3");
addUIntegerVariableReadNode(server, "i2c4.ain0", "I2C4 / Analog Input 0");
addUIntegerVariableReadNode(server, "i2c4.ain1", "I2C4 / Analog Input 1");
addUIntegerVariableReadNode(server, "i2c4.ain2", "I2C4 / Analog Input 2");
addUIntegerVariableReadNode(server, "i2c4.ain3", "I2C4 / Analog Input 3");
}
if (length >= 6)
{
// IC2-5
addIntegerVariableNode(server, "i2c5.relay0", "I2C5 / Relay 0");
addIntegerVariableNode(server, "i2c5.relay1", "I2C5 / Relay 1");
addIntegerVariableNode(server, "i2c5.relay2", "I2C5 / Relay 2");
addIntegerVariableNode(server, "i2c5.relay3", "I2C5 / Relay 3");
addBooleanVariableReadNode(server, "i2c5.in0", "I2C5 / Digital Input 0");
addBooleanVariableReadNode(server, "i2c5.in1", "I2C5 / Digital Input 1");
addBooleanVariableReadNode(server, "i2c5.in2", "I2C5 / Digital Input 2");
addBooleanVariableReadNode(server, "i2c5.in3", "I2C5 / Digital Input 3");
addUIntegerVariableReadNode(server, "i2c5.ain0", "I2C5 / Analog Input 0");
addUIntegerVariableReadNode(server, "i2c5.ain1", "I2C5 / Analog Input 1");
addUIntegerVariableReadNode(server, "i2c5.ain2", "I2C5 / Analog Input 2");
addUIntegerVariableReadNode(server, "i2c5.ain3", "I2C5 / Analog Input 3");
}
if (length >= 7)
{
// IC2-6
addIntegerVariableNode(server, "i2c6.relay0", "I2C6 / Relay 0");
addIntegerVariableNode(server, "i2c6.relay1", "I2C6 / Relay 1");
addIntegerVariableNode(server, "i2c6.relay2", "I2C6 / Relay 2");
addIntegerVariableNode(server, "i2c6.relay3", "I2C6 / Relay 3");
addBooleanVariableReadNode(server, "i2c6.in0", "I2C6 / Digital Input 0");
addBooleanVariableReadNode(server, "i2c6.in1", "I2C6 / Digital Input 1");
addBooleanVariableReadNode(server, "i2c6.in2", "I2C6 / Digital Input 2");
addBooleanVariableReadNode(server, "i2c6.in3", "I2C6 / Digital Input 3");
addUIntegerVariableReadNode(server, "i2c6.ain0", "I2C6 / Analog Input 0");
addUIntegerVariableReadNode(server, "i2c6.ain1", "I2C6 / Analog Input 1");
addUIntegerVariableReadNode(server, "i2c6.ain2", "I2C6 / Analog Input 2");
addUIntegerVariableReadNode(server, "i2c6.ain3", "I2C6 / Analog Input 3");
}
if (length >= 8)
{
// IC2-7
addIntegerVariableNode(server, "i2c7.relay0", "I2C7 / Relay 0");
addIntegerVariableNode(server, "i2c7.relay1", "I2C7 / Relay 1");
addIntegerVariableNode(server, "i2c7.relay2", "I2C7 / Relay 2");
addIntegerVariableNode(server, "i2c7.relay3", "I2C7 / Relay 3");
addBooleanVariableReadNode(server, "i2c7.in0", "I2C7 / Digital Input 0");
addBooleanVariableReadNode(server, "i2c7.in1", "I2C7 / Digital Input 1");
addBooleanVariableReadNode(server, "i2c7.in2", "I2C7 / Digital Input 2");
addBooleanVariableReadNode(server, "i2c7.in3", "I2C7 / Digital Input 3");
addUIntegerVariableReadNode(server, "i2c7.ain0", "I2C7 / Analog Input 0");
addUIntegerVariableReadNode(server, "i2c7.ain1", "I2C7 / Analog Input 1");
addUIntegerVariableReadNode(server, "i2c7.ain2", "I2C7 / Analog Input 2");
addUIntegerVariableReadNode(server, "i2c7.ain3", "I2C7 / Analog Input 3");
}
}
/* Connect to variables to physical relays
char *node_id = malloc(sizeof(char) * 10);
char *node_title = malloc(sizeof(char) * 30);
for (i = 0; i < length; i++)
{
for (n = 0; n < DEFAULT_RELAY_COUNT; n++)
{
// add relay nodes
sprintf(node_id, "i2c%d.relay%d", i, n);
sprintf(node_title, "I2C%d / Relay %d", i, n);
addIntegerVariableNode(server, node_id, node_title);
// add digital in
sprintf(node_id, "i2c%d.in%d", i, n);
sprintf(node_title, "I2C%d / Digital Input %d", i, n);
addBooleanVariableReadNode(server, node_id, node_title);
// add analog in
sprintf(node_id, "i2c%d.ain%d", i, n);
sprintf(node_title, "I2C%d / Analog Input %d", i, n);
addUIntegerVariableReadNode(server, node_id, node_title);
}
}
}
/* Connect to variables to physical relays, analog and digital inputs.
*
*/
static void beforeReadTime(UA_Server *server,
......@@ -556,53 +450,45 @@ static void afterWriteTime(UA_Server *server,
// nothing to do as not yet needed.
}
// XXX: having afterWriteTime{0..3} is not needed and maybe with introspection of context we can
// write only one callback function
static void afterWriteTimeI2C0_0(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
if (data->value.type == &UA_TYPES[UA_TYPES_INT32])
{
static void setI2CSlaveRelayState(int addr,
int relay_number,
uint8_t *global_relays_state,
const UA_DataValue *data){
/*
* A generic handler function for setting relay state.
*/
if (data->value.type == &UA_TYPES[UA_TYPES_INT32]){
UA_Int32 hrValue = *(UA_Int32 *)data->value.data;
// used only for debuging with logical analyzer
if (CURRENT_GPIO_MODE == 2) setGPIO();
if (CURRENT_GPIO_MODE == 2)
setGPIO();
int addr = I2C_SLAVE_ADDR_LIST[0];
if (hrValue > 0)
{
I2C_0_RELAYS_STATE |= 1UL << 0;
setRelayState(I2C_0_RELAYS_STATE, addr);
if (hrValue > 0){
*global_relays_state |= 1UL << relay_number;
setRelayState(*global_relays_state, addr);
}
else
{
I2C_0_RELAYS_STATE &= ~(1UL << 0);
setRelayState(I2C_0_RELAYS_STATE, addr);
else{
*global_relays_state &= ~(1UL << relay_number);
setRelayState(*global_relays_state, addr);
}
}
}
// I2C0
static void afterWriteTimeI2C0_0(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
setI2CSlaveRelayState(I2C_SLAVE_ADDR_LIST[0], 0, &I2C_0_RELAYS_STATE, data);
}
static void afterWriteTimeI2C0_1(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
if (data->value.type == &UA_TYPES[UA_TYPES_INT32])
{
UA_Int32 hrValue = *(UA_Int32 *)data->value.data;
int addr = I2C_SLAVE_ADDR_LIST[0];
if (hrValue > 0)
{
I2C_0_RELAYS_STATE |= 1UL << 1;
setRelayState(I2C_0_RELAYS_STATE, addr);
}
else
{
I2C_0_RELAYS_STATE &= ~(1UL << 1);
setRelayState(I2C_0_RELAYS_STATE, addr);
}
}
setI2CSlaveRelayState(I2C_SLAVE_ADDR_LIST[0], 1, &I2C_0_RELAYS_STATE, data);
}
static void afterWriteTimeI2C0_2(UA_Server *server,
......@@ -610,21 +496,7 @@ static void afterWriteTimeI2C0_2(UA_Server *server,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
if (data->value.type == &UA_TYPES[UA_TYPES_INT32])
{
UA_Int32 hrValue = *(UA_Int32 *)data->value.data;
int addr = I2C_SLAVE_ADDR_LIST[0];
if (hrValue > 0)
{
I2C_0_RELAYS_STATE |= 1UL << 2;
setRelayState(I2C_0_RELAYS_STATE, addr);
}
else
{
I2C_0_RELAYS_STATE &= ~(1UL << 2);
setRelayState(I2C_0_RELAYS_STATE, addr);
}
}
setI2CSlaveRelayState(I2C_SLAVE_ADDR_LIST[0], 2, &I2C_0_RELAYS_STATE, data);
}
static void afterWriteTimeI2C0_3(UA_Server *server,
......@@ -632,21 +504,7 @@ static void afterWriteTimeI2C0_3(UA_Server *server,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
if (data->value.type == &UA_TYPES[UA_TYPES_INT32])
{
UA_Int32 hrValue = *(UA_Int32 *)data->value.data;
int addr = I2C_SLAVE_ADDR_LIST[0];
if (hrValue > 0)
{
I2C_0_RELAYS_STATE |= 1UL << 3;
setRelayState(I2C_0_RELAYS_STATE, addr);
}
else
{
I2C_0_RELAYS_STATE &= ~(1UL << 3);
setRelayState(I2C_0_RELAYS_STATE, addr);
}
}
setI2CSlaveRelayState(I2C_SLAVE_ADDR_LIST[0], 3, &I2C_0_RELAYS_STATE, data);
}
// I2C1
......@@ -655,21 +513,7 @@ static void afterWriteTimeI2C1_0(UA_Server *server,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
if (data->value.type == &UA_TYPES[UA_TYPES_INT32])
{
UA_Int32 hrValue = *(UA_Int32 *)data->value.data;
int addr = I2C_SLAVE_ADDR_LIST[1];
if (hrValue > 0)
{
I2C_1_RELAYS_STATE |= 1UL << 0;
setRelayState(I2C_1_RELAYS_STATE, addr);
}
else
{
I2C_1_RELAYS_STATE &= ~(1UL << 0);
setRelayState(I2C_1_RELAYS_STATE, addr);
}
}
setI2CSlaveRelayState(I2C_SLAVE_ADDR_LIST[1], 0, &I2C_1_RELAYS_STATE, data);
}
static void afterWriteTimeI2C1_1(UA_Server *server,
......@@ -677,21 +521,7 @@ static void afterWriteTimeI2C1_1(UA_Server *server,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
if (data->value.type == &UA_TYPES[UA_TYPES_INT32])
{
UA_Int32 hrValue = *(UA_Int32 *)data->value.data;
int addr = I2C_SLAVE_ADDR_LIST[1];
if (hrValue > 0)
{
I2C_1_RELAYS_STATE |= 1UL << 1;
setRelayState(I2C_1_RELAYS_STATE, addr);
}
else
{
I2C_1_RELAYS_STATE &= ~(1UL << 1);
setRelayState(I2C_1_RELAYS_STATE, addr);
}
}
setI2CSlaveRelayState(I2C_SLAVE_ADDR_LIST[1], 1, &I2C_1_RELAYS_STATE, data);
}
static void afterWriteTimeI2C1_2(UA_Server *server,
......@@ -699,21 +529,7 @@ static void afterWriteTimeI2C1_2(UA_Server *server,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
if (data->value.type == &UA_TYPES[UA_TYPES_INT32])
{
UA_Int32 hrValue = *(UA_Int32 *)data->value.data;
int addr = I2C_SLAVE_ADDR_LIST[1];
if (hrValue > 0)
{
I2C_1_RELAYS_STATE |= 1UL << 2;
setRelayState(I2C_1_RELAYS_STATE, addr);
}
else
{
I2C_1_RELAYS_STATE &= ~(1UL << 2);
setRelayState(I2C_1_RELAYS_STATE, addr);
}
}
setI2CSlaveRelayState(I2C_SLAVE_ADDR_LIST[1], 2, &I2C_1_RELAYS_STATE, data);
}
static void afterWriteTimeI2C1_3(UA_Server *server,
......@@ -721,21 +537,7 @@ static void afterWriteTimeI2C1_3(UA_Server *server,
const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data)
{
if (data->value.type == &UA_TYPES[UA_TYPES_INT32])
{
UA_Int32 hrValue = *(UA_Int32 *)data->value.data;
int addr = I2C_SLAVE_ADDR_LIST[1];
if (hrValue > 0)
{
I2C_1_RELAYS_STATE |= 1UL << 3;
setRelayState(I2C_1_RELAYS_STATE, addr);
}
else
{
I2C_1_RELAYS_STATE &= ~(1UL << 3);
setRelayState(I2C_1_RELAYS_STATE, addr);
}
}
setI2CSlaveRelayState(I2C_SLAVE_ADDR_LIST[1], 3, &I2C_1_RELAYS_STATE, data);
}
static void addValueCallbackToCurrentTimeVariable(UA_Server *server)
......
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