Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
osie
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nikola Balog
osie
Commits
c6c28acc
Commit
c6c28acc
authored
Jan 31, 2022
by
Balakrishna Balakrishna
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Inclusion of MOD IO digital input reading functions
Test: Program is tested locally with laptop. modified: server.c
parent
db52601f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
298 additions
and
23 deletions
+298
-23
coupler/opc-ua-server/server.c
coupler/opc-ua-server/server.c
+298
-23
No files found.
coupler/opc-ua-server/server.c
View file @
c6c28acc
...
...
@@ -144,11 +144,9 @@ static int setRelayState(int command, int i2c_addr) {
// step 3: write command over I2c
__u8
reg
=
0x10
;
/* Device register to access */
__s32
res
;
char
buf
[
10
];
buf
[
0
]
=
reg
;
buf
[
1
]
=
command
;
//0x00 -all off, 0x0F - all 4 on
buf
[
2
]
=
0x65
;
// seems irrelevant the value
if
(
write
(
file
,
buf
,
3
)
!=
3
)
{
/* ERROR HANDLING: i2c transaction failed */
printf
(
"Error writing to i2c slave (0x%x).
\n
"
,
i2c_addr
);
...
...
@@ -156,6 +154,51 @@ static int setRelayState(int command, int i2c_addr) {
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
)
{
UA_Int32
myInteger
=
0
;
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
}
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
)
{
/*
* Create all variables representing MOD-IO's relays
...
...
@@ -186,6 +248,10 @@ static void addVariable(UA_Server *server) {
addIntegerVariableNode
(
server
,
"i2c0.relay1"
,
"I2C0 / Relay 1"
);
addIntegerVariableNode
(
server
,
"i2c0.relay2"
,
"I2C0 / Relay 2"
);
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
)
{
// IC2-1
...
...
@@ -193,6 +259,10 @@ static void addVariable(UA_Server *server) {
addIntegerVariableNode
(
server
,
"i2c1.relay1"
,
"I2C1 / Relay 1"
);
addIntegerVariableNode
(
server
,
"i2c1.relay2"
,
"I2C1 / Relay 2"
);
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,
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.
}
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
...
...
@@ -386,35 +605,91 @@ static void addValueCallbackToCurrentTimeVariable(UA_Server *server) {
callback3
.
onWrite
=
afterWriteTimeI2C0_3
;
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
){
// I2C1
// relay 0
UA_NodeId
currentNodeId
4
=
UA_NODEID_STRING
(
1
,
"i2c1.relay0"
);
UA_ValueCallback
callback
4
;
callback
4
.
onRead
=
beforeReadTime
;
callback
4
.
onWrite
=
afterWriteTimeI2C1_0
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId
4
,
callback4
);
UA_NodeId
currentNodeId
8
=
UA_NODEID_STRING
(
1
,
"i2c1.relay0"
);
UA_ValueCallback
callback
8
;
callback
8
.
onRead
=
beforeReadTime
;
callback
8
.
onWrite
=
afterWriteTimeI2C1_0
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId
8
,
callback8
);
// relay 1
UA_NodeId
currentNodeId
5
=
UA_NODEID_STRING
(
1
,
"i2c1.relay1"
);
UA_ValueCallback
callback
5
;
callback
5
.
onRead
=
beforeReadTime
;
callback
5
.
onWrite
=
afterWriteTimeI2C1_1
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId
5
,
callback5
);
UA_NodeId
currentNodeId
9
=
UA_NODEID_STRING
(
1
,
"i2c1.relay1"
);
UA_ValueCallback
callback
9
;
callback
9
.
onRead
=
beforeReadTime
;
callback
9
.
onWrite
=
afterWriteTimeI2C1_1
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId
9
,
callback9
);
// relay 2
UA_NodeId
currentNodeId
6
=
UA_NODEID_STRING
(
1
,
"i2c1.relay2"
);
UA_ValueCallback
callback
6
;
callback
6
.
onRead
=
beforeReadTime
;
callback
6
.
onWrite
=
afterWriteTimeI2C1_2
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId6
,
callback
6
);
UA_NodeId
currentNodeId
10
=
UA_NODEID_STRING
(
1
,
"i2c1.relay2"
);
UA_ValueCallback
callback
10
;
callback
10
.
onRead
=
beforeReadTime
;
callback
10
.
onWrite
=
afterWriteTimeI2C1_2
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId6
,
callback
10
);
// relay 2
UA_NodeId
currentNodeId7
=
UA_NODEID_STRING
(
1
,
"i2c1.relay3"
);
UA_ValueCallback
callback7
;
callback7
.
onRead
=
beforeReadTime
;
callback7
.
onWrite
=
afterWriteTimeI2C1_3
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId7
,
callback7
);
UA_NodeId
currentNodeId11
=
UA_NODEID_STRING
(
1
,
"i2c1.relay3"
);
UA_ValueCallback
callback11
;
callback11
.
onRead
=
beforeReadTime
;
callback11
.
onWrite
=
afterWriteTimeI2C1_3
;
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
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment