@@ -95,11 +95,53 @@ void co_pdo_pack (co_net_t * net, co_pdo_t * pdo)
95
95
}
96
96
}
97
97
98
+ static int co_mpdo_unpack (co_net_t * net , co_pdo_t * pdo )
99
+ {
100
+ bool is_dam = bitslice_get (& pdo -> frame , 7 , 1 );
101
+ uint8_t node = bitslice_get (& pdo -> frame , 0 , 7 );
102
+ uint16_t index = bitslice_get (& pdo -> frame , 8 , 16 );
103
+ uint8_t subindex = bitslice_get (& pdo -> frame , 24 , 8 );
104
+ uint32_t value = bitslice_get (& pdo -> frame , 32 , 32 );
105
+ const co_obj_t * obj ;
106
+ const co_entry_t * entry ;
107
+
108
+ if (is_dam )
109
+ {
110
+ if (node != 0 && node != net -> node )
111
+ return 0 ;
112
+
113
+ obj = co_obj_find (net , index );
114
+ if (obj == NULL )
115
+ return co_emcy_tx (net , 0x8230 , 0 , NULL );
116
+
117
+ entry = co_entry_find (net , obj , subindex );
118
+ if (entry == NULL || !(entry -> flags & OD_WRITE ))
119
+ return co_emcy_tx (net , 0x8230 , 0 , NULL );
120
+
121
+ if (co_od_set_value (net , obj , entry , subindex , value ))
122
+ return co_emcy_tx (net , 0x8230 , 0 , NULL );
123
+
124
+ } else {
125
+ /* TODO: Support SAM-MPDO Consumer using dispatcher list. */
126
+ }
127
+
128
+ return 0 ;
129
+ }
130
+
98
131
void co_pdo_unpack (co_net_t * net , co_pdo_t * pdo )
99
132
{
100
133
unsigned int ix ;
101
134
unsigned int offset = 0 ;
102
135
136
+ if (pdo -> number_of_mappings >= 0xFE )
137
+ {
138
+ /* TODO: Each MPDO frame contains the info whether it's SAM or DAM,
139
+ * so what difference does it make if the configuration here is 0xFE
140
+ * or 0xFF?? */
141
+ co_mpdo_unpack (net , pdo );
142
+ return ;
143
+ }
144
+
103
145
for (ix = 0 ; ix < pdo -> number_of_mappings ; ix ++ )
104
146
{
105
147
const co_entry_t * entry = pdo -> entries [ix ];
@@ -121,6 +163,13 @@ static uint32_t co_pdo_mapping_validate (co_pdo_t * pdo, uint8_t number_of_mappi
121
163
{
122
164
int ix ;
123
165
166
+ /* Check if MPDO */
167
+ if (number_of_mappings >= 0xFE )
168
+ {
169
+ pdo -> bitlength = 64 ;
170
+ return 0 ;
171
+ }
172
+
124
173
/* Mappings array bounds check */
125
174
if (number_of_mappings > MAX_PDO_ENTRIES )
126
175
return CO_SDO_ABORT_PDO_LENGTH ;
0 commit comments