-
Notifications
You must be signed in to change notification settings - Fork 0
/
SDO SVR STANDARD OBJECTS.ST
223 lines (212 loc) · 9.55 KB
/
SDO SVR STANDARD OBJECTS.ST
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
(* @NESTEDCOMMENTS := 'Yes' *)
(* @PATH := '\/SDO Server' *)
(* @OBJECTFLAGS := '0, 8' *)
(* @SYMFILEFLAGS := '2048' *)
FUNCTION_BLOCK FB_SDOSVR_STDOBJS
VAR_INPUT
SDOSVR_PROC : POINTER TO FB_SDOSVR_PROC;
DeviceType_Profile : WORD := 0; (* device profile this device supports, 0 indicates no predefined device (ex: 401 indicates input/output device profile DS401) *)
DeviceType_Features : WORD := 0; (* device profile features this device supports, or 16#FFFF to indicate a multi-profile device ??? *)
OBJ_DevName_String : POINTER TO STRING; (* Device name for 0x1008 *)
OBJ_HWVer_String : POINTER TO STRING; (* Hardware version for 0x1009 *)
OBJ_SWVer_String : POINTER TO STRING; (* Software version for 0x100A *)
HeartBeat_Prod_TM : TIME := t#1s; (* Producer Heartbeat time, 0x1017 *)
END_VAR
VAR
Dn_Buffer : ARRAY[0..3] OF BYTE; (* buffer for downloading of objects *)
(* Up_Buffer : ARRAY[0..3] OF BYTE; (* buffer for uploading of objects *) *)
END_VAR
(* @END_DECLARATION := '0' *)
IF SDOSVR_PROC <> 0 THEN
(* on call, SDO Processor should have a request dispatch, check if it matches any of our objects *)
CASE SDOSVR_PROC^.Request_RESULT OF
2:
(* Upload or READ requests *)
CASE SDOSVR_PROC^.Request_OBJ OF
16#1000:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSE
(* transfer device profile and features and submit to processor via expedited response *)
SDOSVR_PROC^.CANSDO_DATA[4] := WORD_TO_BYTE( DeviceType_Profile );
SDOSVR_PROC^.CANSDO_DATA[5] := WORD_TO_BYTE( SHR( DeviceType_Profile, 8 ) );
SDOSVR_PROC^.CANSDO_DATA[6] := WORD_TO_BYTE( DeviceType_Features );
SDOSVR_PROC^.CANSDO_DATA[7] := WORD_TO_BYTE( SHR( DeviceType_Features, 8 ) );
SDOSVR_PROC^.TX_EXP_UP_RESP( Response_BUFFER_LEN:=4 );
END_IF
16#1008:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSE
(* send device name string, if one is set *)
IF OBJ_DevName_String <> 0 THEN
SDOSVR_PROC^.DispatchResponse( Response_BUFFER_LEN:=LEN( OBJ_DevName_String^ ), Response_BUFFER_PTR:=OBJ_DevName_String );
END_IF
END_IF
16#1009:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSE
(* send hw version string, if one is set *)
IF OBJ_HWVer_String <> 0 THEN
SDOSVR_PROC^.DispatchResponse( Response_BUFFER_LEN:=LEN( OBJ_HWVer_String^ ), Response_BUFFER_PTR:=OBJ_HWVer_String );
END_IF
END_IF
16#100A:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSE
(* send sw version string, if one is set *)
IF OBJ_SWVer_String <> 0 THEN
SDOSVR_PROC^.DispatchResponse( Response_BUFFER_LEN:=LEN( OBJ_SWVer_String^ ), Response_BUFFER_PTR:=OBJ_SWVer_String );
END_IF
END_IF
16#1017:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSE
(* upload request, deposit in SDO processor buffer and submit expedited response *)
SDOSVR_PROC^.CANSDO_DATA[4] := DWORD_TO_BYTE( MIN( TIME_TO_DWORD( HeartBeat_Prod_TM ), 65535 ) AND 16#FF );
SDOSVR_PROC^.CANSDO_DATA[5] := DWORD_TO_BYTE( SHR( MIN( TIME_TO_DWORD( HeartBeat_Prod_TM ), 65535 ), 8 ) );
SDOSVR_PROC^.CANSDO_DATA[6] := SDOSVR_PROC^.CANSDO_DATA[7] := 0;
SDOSVR_PROC^.TX_EXP_UP_RESP( Response_BUFFER_LEN:=2 );
END_IF
END_CASE
3:
(* download (WRITE) request notification *)
CASE SDOSVR_PROC^.Request_OBJ OF
16#1000,
16#1008,
16#1009,
16#100A:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSE
(* client tried to download, object is read only *)
SDOSVR_PROC^.TX_ERR_R_ONLY();
END_IF
16#1017:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSE
(* download request, if length known, and not right, reject it, else accept it to our buffer *)
IF SEL( SDOSVR_PROC^.Request_LEN_KNOWN, SDOSVR_PROC^.Request_LEN >= 2, SDOSVR_PROC^.Request_LEN = 2 ) THEN
IF SDOSVR_PROC^.Request_EXP THEN
(* with request expedited we'll just handle it here *)
HeartBeat_Prod_TM := DWORD_TO_TIME( SHL( BYTE_TO_DWORD( SDOSVR_PROC^.CANSDO_DATA[5] ), 8 ) + SDOSVR_PROC^.CANSDO_DATA[4] );
SDOSVR_PROC^.TX_ACK_EXP_DN(); (* acknowledge the download request *)
ELSE
(* requester didn't expedite but the length seems within reason so allow the request to CONTINUE *)
SDOSVR_PROC^.DispatchResponse( Response_BUFFER_LEN:=2, Response_BUFFER_PTR:=ADR( Dn_Buffer ) );
END_IF
ELSE
SDOSVR_PROC^.TX_ERR_BAD_SIZE(); (* incorrect size for object *)
END_IF
END_IF
END_CASE
4:
(* download completion notification *)
CASE SDOSVR_PROC^.Request_OBJ OF
16#1017:
(* download completed, save value, if right number of bytes received, not overrunning our buffer *)
IF SDOSVR_PROC^.Request_LEN = 2 AND NOT SDOSVR_PROC^.Request_BUFFEROVERRUN THEN
(* convert from little endian to big endian and store in register *)
HeartBeat_Prod_TM := DWORD_TO_TIME( SHL( BYTE_TO_DWORD( Dn_Buffer[1] ), 8 ) + Dn_Buffer[0] );
ELSE
SDOSVR_PROC^.TX_ERR_BAD_SIZE(); (* incorrect size for object *)
END_IF
END_CASE
END_CASE
(* this is an alternate coding method ...
(* only process when RESULT is 2, 3 or 4 *)
IF MUX( SDOSVR_PROC^.Request_RESULT, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE ) THEN
CASE SDOSVR_PROC^.Request_OBJ OF
16#1000:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSIF SDOSVR_PROC^.Request_RESULT = 3 THEN
(* client tried to download, object is read only *)
SDOSVR_PROC^.TX_ERR_R_ONLY();
ELSE
(* transfer device profile and features and submit to processor via expedited response *)
SDOSVR_PROC^.CANSDO_DATA[4] := WORD_TO_BYTE( DeviceType_Profile );
SDOSVR_PROC^.CANSDO_DATA[5] := WORD_TO_BYTE( SHR( DeviceType_Profile, 8 ) );
SDOSVR_PROC^.CANSDO_DATA[6] := WORD_TO_BYTE( DeviceType_Features );
SDOSVR_PROC^.CANSDO_DATA[7] := WORD_TO_BYTE( SHR( DeviceType_Features, 8 ) );
SDOSVR_PROC^.TX_EXP_UP_RESP( Response_BUFFER_LEN:=4 );
END_IF
16#1008:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSIF SDOSVR_PROC^.Request_RESULT = 3 THEN
(* client tried to download, object is read only *)
SDOSVR_PROC^.TX_ERR_R_ONLY();
ELSIF OBJ_DevName_String <> 0 THEN
SDOSVR_PROC^.DispatchResponse( Response_BUFFER_LEN:=LEN( OBJ_DevName_String^ ), Response_BUFFER_PTR:=OBJ_DevName_String );
END_IF
16#1009:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSIF SDOSVR_PROC^.Request_RESULT = 3 THEN
(* client tried to download, object is read only *)
SDOSVR_PROC^.TX_ERR_R_ONLY();
ELSIF OBJ_HWVer_String <> 0 THEN
SDOSVR_PROC^.DispatchResponse( Response_BUFFER_LEN:=LEN( OBJ_HWVer_String^ ), Response_BUFFER_PTR:=OBJ_HWVer_String );
END_IF
16#100A:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSIF SDOSVR_PROC^.Request_RESULT = 3 THEN
(* client tried to download, object is read only *)
SDOSVR_PROC^.TX_ERR_R_ONLY();
ELSIF OBJ_SWVer_String <> 0 THEN
SDOSVR_PROC^.DispatchResponse( Response_BUFFER_LEN:=LEN( OBJ_SWVer_String^ ), Response_BUFFER_PTR:=OBJ_SWVer_String );
END_IF
16#1017:
IF SDOSVR_PROC^.Request_SIDX <> 0 THEN
(* object is wholly contained in SIDX 0 *)
SDOSVR_PROC^.TX_ERR_INV_SIDX();
ELSIF SDOSVR_PROC^.Request_RESULT = 3 THEN
(* download request, if length known, and not right, reject it, else accept it to our buffer *)
IF SEL( SDOSVR_PROC^.Request_LEN_KNOWN, SDOSVR_PROC^.Request_LEN >= 2, SDOSVR_PROC^.Request_LEN = 2 ) THEN
IF SDOSVR_PROC^.Request_EXP THEN
HeartBeat_Prod_TM := DWORD_TO_TIME( SHL( BYTE_TO_DWORD( SDOSVR_PROC^.CANSDO_DATA[5] ), 8 ) + SDOSVR_PROC^.CANSDO_DATA[4] );
SDOSVR_PROC^.TX_ACK_EXP_DN(); (* acknowledge the download request *)
ELSE
(* requester didn't expedite but the length seems within reason so allow the request to CONTINUE *)
SDOSVR_PROC^.DispatchResponse( Response_BUFFER_LEN:=2, Response_BUFFER_PTR:=ADR( Dn_Buffer ) );
END_IF
ELSE
SDOSVR_PROC^.TX_ERR_BAD_SIZE(); (* incorrect size for object *)
END_IF
ELSIF SDOSVR_PROC^.Request_RESULT = 4 THEN
(* download completed, save value, if right number of bytes received, not overrunning our buffer *)
IF SDOSVR_PROC^.Request_LEN = 2 AND NOT SDOSVR_PROC^.Request_BUFFEROVERRUN THEN
(* convert from little endian to big endian and store in register *)
HeartBeat_Prod_TM := DWORD_TO_TIME( SHL( BYTE_TO_DWORD( Dn_Buffer[1] ), 8 ) + Dn_Buffer[0] );
ELSE
SDOSVR_PROC^.TX_ERR_BAD_SIZE(); (* incorrect size for object *)
END_IF
ELSIF SDOSVR_PROC^.Request_RESULT = 2 THEN
(* upload request, deposit in SDO processor buffer and submit expedited response *)
SDOSVR_PROC^.CANSDO_DATA[4] := DWORD_TO_BYTE( MIN( TIME_TO_DWORD( HeartBeat_Prod_TM ), 65535 ) AND 16#FF );
SDOSVR_PROC^.CANSDO_DATA[5] := DWORD_TO_BYTE( SHR( MIN( TIME_TO_DWORD( HeartBeat_Prod_TM ), 65535 ), 8 ) );
SDOSVR_PROC^.CANSDO_DATA[6] := SDOSVR_PROC^.CANSDO_DATA[7] := 0;
SDOSVR_PROC^.TX_EXP_UP_RESP( Response_BUFFER_LEN:=2 );
END_IF
END_CASE
END_IF
*)
END_IF
END_FUNCTION_BLOCK