@@ -95,11 +95,53 @@ void co_pdo_pack (co_net_t * net, co_pdo_t * pdo)
9595 }
9696}
9797
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+
98131void co_pdo_unpack (co_net_t * net , co_pdo_t * pdo )
99132{
100133 unsigned int ix ;
101134 unsigned int offset = 0 ;
102135
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+
103145 for (ix = 0 ; ix < pdo -> number_of_mappings ; ix ++ )
104146 {
105147 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
121163{
122164 int ix ;
123165
166+ /* Check if MPDO */
167+ if (number_of_mappings >= 0xFE )
168+ {
169+ pdo -> bitlength = 64 ;
170+ return 0 ;
171+ }
172+
124173 /* Mappings array bounds check */
125174 if (number_of_mappings > MAX_PDO_ENTRIES )
126175 return CO_SDO_ABORT_PDO_LENGTH ;
0 commit comments