181 |
181 |
182 /** |
182 /** |
183 Starts to download an Sdo to a slave. |
183 Starts to download an Sdo to a slave. |
184 */ |
184 */ |
185 |
185 |
186 void ec_fsm_coe_download(ec_fsm_coe_t *fsm, /**< finite state machine */ |
186 void ec_fsm_coe_download( |
187 ec_slave_t *slave, /**< EtherCAT slave */ |
187 ec_fsm_coe_t *fsm, /**< State machine. */ |
188 ec_sdo_data_t *sdodata /**< Sdo data object */ |
188 ec_slave_t *slave, /**< EtherCAT slave. */ |
189 ) |
189 ec_sdo_request_t *request /**< Sdo request. */ |
|
190 ) |
190 { |
191 { |
191 fsm->slave = slave; |
192 fsm->slave = slave; |
192 fsm->sdodata = sdodata; |
193 fsm->request = request; |
193 fsm->state = ec_fsm_coe_down_start; |
194 fsm->state = ec_fsm_coe_down_start; |
194 } |
195 } |
195 |
196 |
196 /*****************************************************************************/ |
197 /*****************************************************************************/ |
197 |
198 |
952 |
953 |
953 void ec_fsm_coe_down_start(ec_fsm_coe_t *fsm /**< finite state machine */) |
954 void ec_fsm_coe_down_start(ec_fsm_coe_t *fsm /**< finite state machine */) |
954 { |
955 { |
955 ec_datagram_t *datagram = fsm->datagram; |
956 ec_datagram_t *datagram = fsm->datagram; |
956 ec_slave_t *slave = fsm->slave; |
957 ec_slave_t *slave = fsm->slave; |
957 ec_sdo_data_t *sdodata = fsm->sdodata; |
958 ec_sdo_request_t *request = fsm->request; |
958 uint8_t *data; |
959 uint8_t *data; |
959 |
960 |
960 if (fsm->slave->master->debug_level) |
961 if (fsm->slave->master->debug_level) |
961 EC_DBG("Downloading Sdo 0x%04X:%i to slave %i.\n", |
962 EC_DBG("Downloading Sdo 0x%04X:%i to slave %i.\n", |
962 sdodata->index, sdodata->subindex, slave->ring_position); |
963 request->index, request->subindex, slave->ring_position); |
963 |
964 |
964 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { |
965 if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { |
965 EC_ERR("Slave %u does not support CoE!\n", slave->ring_position); |
966 EC_ERR("Slave %u does not support CoE!\n", slave->ring_position); |
966 fsm->state = ec_fsm_coe_error; |
967 fsm->state = ec_fsm_coe_error; |
967 return; |
968 return; |
968 } |
969 } |
969 |
970 |
970 if (slave->sii.rx_mailbox_size < 6 + 10 + sdodata->size) { |
971 if (slave->sii.rx_mailbox_size < 6 + 10 + request->data_size) { |
971 EC_ERR("Sdo fragmenting not supported yet!\n"); |
972 EC_ERR("Sdo fragmenting not supported yet!\n"); |
972 fsm->state = ec_fsm_coe_error; |
973 fsm->state = ec_fsm_coe_error; |
973 return; |
974 return; |
974 } |
975 } |
975 |
976 |
976 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, |
977 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, |
977 sdodata->size + 10))) { |
978 request->data_size + 10))) { |
978 fsm->state = ec_fsm_coe_error; |
979 fsm->state = ec_fsm_coe_error; |
979 return; |
980 return; |
980 } |
981 } |
981 |
982 |
982 EC_WRITE_U16(data, 0x2 << 12); // Sdo request |
983 EC_WRITE_U16(data, 0x2 << 12); // Sdo request |
983 EC_WRITE_U8 (data + 2, (0x1 // size specified |
984 EC_WRITE_U8 (data + 2, (0x1 // size specified |
984 | 0x1 << 5)); // Download request |
985 | 0x1 << 5)); // Download request |
985 EC_WRITE_U16(data + 3, sdodata->index); |
986 EC_WRITE_U16(data + 3, request->index); |
986 EC_WRITE_U8 (data + 5, sdodata->subindex); |
987 EC_WRITE_U8 (data + 5, request->subindex); |
987 EC_WRITE_U32(data + 6, sdodata->size); |
988 EC_WRITE_U32(data + 6, request->data_size); |
988 memcpy(data + 10, sdodata->data, sdodata->size); |
989 memcpy(data + 10, request->data, request->data_size); |
989 |
990 |
990 fsm->retries = EC_FSM_RETRIES; |
991 fsm->retries = EC_FSM_RETRIES; |
991 fsm->state = ec_fsm_coe_down_request; |
992 fsm->state = ec_fsm_coe_down_request; |
992 } |
993 } |
993 |
994 |
1090 { |
1091 { |
1091 ec_datagram_t *datagram = fsm->datagram; |
1092 ec_datagram_t *datagram = fsm->datagram; |
1092 ec_slave_t *slave = fsm->slave; |
1093 ec_slave_t *slave = fsm->slave; |
1093 uint8_t *data, mbox_prot; |
1094 uint8_t *data, mbox_prot; |
1094 size_t rec_size; |
1095 size_t rec_size; |
1095 ec_sdo_data_t *sdodata = fsm->sdodata; |
1096 ec_sdo_request_t *request = fsm->request; |
1096 |
1097 |
1097 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1098 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
1098 return; // FIXME: request again? |
1099 return; // FIXME: request again? |
1099 |
1100 |
1100 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1101 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1134 |
1135 |
1135 if (EC_READ_U16(data) >> 12 == 0x2 && // Sdo request |
1136 if (EC_READ_U16(data) >> 12 == 0x2 && // Sdo request |
1136 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request |
1137 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request |
1137 fsm->state = ec_fsm_coe_error; |
1138 fsm->state = ec_fsm_coe_error; |
1138 EC_ERR("Sdo download 0x%04X:%X (%i bytes) aborted on slave %i.\n", |
1139 EC_ERR("Sdo download 0x%04X:%X (%i bytes) aborted on slave %i.\n", |
1139 sdodata->index, sdodata->subindex, sdodata->size, |
1140 request->index, request->subindex, request->data_size, |
1140 slave->ring_position); |
1141 slave->ring_position); |
1141 if (rec_size < 10) { |
1142 if (rec_size < 10) { |
1142 EC_ERR("Incomplete Abort command:\n"); |
1143 EC_ERR("Incomplete Abort command:\n"); |
1143 ec_print_data(data, rec_size); |
1144 ec_print_data(data, rec_size); |
1144 } |
1145 } |
1147 return; |
1148 return; |
1148 } |
1149 } |
1149 |
1150 |
1150 if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response |
1151 if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response |
1151 EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response |
1152 EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response |
1152 EC_READ_U16(data + 3) != sdodata->index || // index |
1153 EC_READ_U16(data + 3) != request->index || // index |
1153 EC_READ_U8 (data + 5) != sdodata->subindex) { // subindex |
1154 EC_READ_U8 (data + 5) != request->subindex) { // subindex |
1154 fsm->state = ec_fsm_coe_error; |
1155 fsm->state = ec_fsm_coe_error; |
1155 EC_ERR("Sdo download 0x%04X:%X (%i bytes) failed:\n", |
1156 EC_ERR("Sdo download 0x%04X:%X (%i bytes) failed:\n", |
1156 sdodata->index, sdodata->subindex, sdodata->size); |
1157 request->index, request->subindex, request->data_size); |
1157 EC_ERR("Invalid Sdo download response at slave %i!\n", |
1158 EC_ERR("Invalid Sdo download response at slave %i!\n", |
1158 slave->ring_position); |
1159 slave->ring_position); |
1159 ec_print_data(data, rec_size); |
1160 ec_print_data(data, rec_size); |
1160 return; |
1161 return; |
1161 } |
1162 } |
1412 ec_print_data(data, rec_size); |
1407 ec_print_data(data, rec_size); |
1413 fsm->state = ec_fsm_coe_error; |
1408 fsm->state = ec_fsm_coe_error; |
1414 return; |
1409 return; |
1415 } |
1410 } |
1416 |
1411 |
1417 if (!(request->data = (uint8_t *) |
1412 if (ec_sdo_request_copy_data(request, data + 6, complete_size)) { |
1418 kmalloc(complete_size + 1, GFP_ATOMIC))) { |
1413 fsm->state = ec_fsm_coe_error; |
1419 EC_ERR("Failed to allocate %i bytes of Sdo data!\n", |
1414 return; |
1420 complete_size); |
1415 } |
1421 fsm->state = ec_fsm_coe_error; |
|
1422 return; |
|
1423 } |
|
1424 request->data[complete_size] = 0x00; // just to be sure... |
|
1425 |
|
1426 memcpy(request->data, data + 6, complete_size); |
|
1427 request->size = complete_size; |
|
1428 |
|
1429 } else { // normal |
1416 } else { // normal |
1430 if (rec_size < 10) { |
1417 if (rec_size < 10) { |
1431 EC_ERR("Received currupted Sdo normal upload" |
1418 EC_ERR("Received currupted Sdo normal upload" |
1432 " response (only %u bytes)!\n", rec_size); |
1419 " response (only %u bytes)!\n", rec_size); |
1433 ec_print_data(data, rec_size); |
1420 ec_print_data(data, rec_size); |
1456 ec_print_data(data, rec_size); |
1443 ec_print_data(data, rec_size); |
1457 fsm->state = ec_fsm_coe_error; |
1444 fsm->state = ec_fsm_coe_error; |
1458 return; |
1445 return; |
1459 } |
1446 } |
1460 |
1447 |
1461 if (!(request->data = (uint8_t *) |
1448 if (ec_sdo_request_alloc(request, complete_size)) { |
1462 kmalloc(complete_size + 1, GFP_ATOMIC))) { |
1449 fsm->state = ec_fsm_coe_error; |
1463 EC_ERR("Failed to allocate %i bytes of Sdo data!\n", |
1450 return; |
1464 complete_size); |
1451 } |
1465 fsm->state = ec_fsm_coe_error; |
1452 |
1466 return; |
1453 if (ec_sdo_request_copy_data(request, data + 10, data_size)) { |
1467 } |
1454 fsm->state = ec_fsm_coe_error; |
1468 request->data[complete_size] = 0x00; // just to be sure... |
1455 return; |
1469 |
1456 } |
1470 memcpy(request->data, data + 10, data_size); |
1457 |
1471 request->size = complete_size; |
|
1472 fsm->toggle = 0; |
1458 fsm->toggle = 0; |
1473 |
1459 |
1474 if (data_size < complete_size) { |
1460 if (data_size < complete_size) { |
1475 EC_WARN("Sdo data incomplete (%i / %i).\n", |
1461 EC_WARN("Sdo data incomplete (%i / %i).\n", |
1476 data_size, complete_size); |
1462 data_size, complete_size); |
1675 EC_WARN("Sdo segment data invalid (%i / %i)" |
1662 EC_WARN("Sdo segment data invalid (%i / %i)" |
1676 " - Fragmenting not implemented.\n", |
1663 " - Fragmenting not implemented.\n", |
1677 data_size, seg_size); |
1664 data_size, seg_size); |
1678 } |
1665 } |
1679 |
1666 |
1680 memcpy(request->data + request->size, data + 10, data_size); |
1667 memcpy(request->data + request->data_size, data + 10, data_size); |
1681 request->size += data_size; |
1668 request->data_size += data_size; |
1682 |
1669 |
1683 if (!last_segment) { |
1670 if (!last_segment) { |
1684 fsm->toggle = !fsm->toggle; |
1671 fsm->toggle = !fsm->toggle; |
1685 |
1672 |
1686 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 3))) { |
1673 if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 3))) { |