1 /****************************************************************************** |
1 /****************************************************************************** |
2 * |
2 * |
3 * $Id$ |
3 * $Id$ |
4 * |
4 * |
5 * Copyright (C) 2008 Olav Zarges, imc Messsysteme GmbH |
5 * Copyright (C) 2008 Olav Zarges, imc Messsysteme GmbH |
|
6 * 2013 Florian Pose <fp@igh-essen.com> |
6 * |
7 * |
7 * This file is part of the IgH EtherCAT Master. |
8 * This file is part of the IgH EtherCAT Master. |
8 * |
9 * |
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or |
10 * The IgH EtherCAT Master is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU General Public License version 2, as |
11 * modify it under the terms of the GNU General Public License version 2, as |
25 * EtherCAT technology and brand is only permitted in compliance with the |
26 * EtherCAT technology and brand is only permitted in compliance with the |
26 * industrial property and similar rights of Beckhoff Automation GmbH. |
27 * industrial property and similar rights of Beckhoff Automation GmbH. |
27 * |
28 * |
28 *****************************************************************************/ |
29 *****************************************************************************/ |
29 |
30 |
30 /** |
31 /** \file |
31 \file |
32 * EtherCAT FoE state machines. |
32 EtherCAT FoE state machines. |
33 */ |
33 */ |
|
34 |
34 |
35 /*****************************************************************************/ |
35 /*****************************************************************************/ |
36 |
36 |
37 #include "globals.h" |
37 #include "globals.h" |
38 #include "master.h" |
38 #include "master.h" |
207 ec_fsm_foe_t *fsm, /**< finite state machine */ |
207 ec_fsm_foe_t *fsm, /**< finite state machine */ |
208 ec_datagram_t *datagram /**< Datagram to use. */ |
208 ec_datagram_t *datagram /**< Datagram to use. */ |
209 ) |
209 ) |
210 { |
210 { |
211 #ifdef DEBUG_FOE |
211 #ifdef DEBUG_FOE |
212 printk("ec_fsm_foe_error()\n"); |
212 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
213 #endif |
213 #endif |
214 } |
214 } |
215 |
215 |
216 /*****************************************************************************/ |
216 /*****************************************************************************/ |
217 |
217 |
221 ec_fsm_foe_t *fsm, /**< finite state machine */ |
221 ec_fsm_foe_t *fsm, /**< finite state machine */ |
222 ec_datagram_t *datagram /**< Datagram to use. */ |
222 ec_datagram_t *datagram /**< Datagram to use. */ |
223 ) |
223 ) |
224 { |
224 { |
225 #ifdef DEBUG_FOE |
225 #ifdef DEBUG_FOE |
226 printk("ec_fsm_foe_end\n"); |
226 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
227 #endif |
227 #endif |
228 } |
228 } |
229 |
229 |
230 /*****************************************************************************/ |
230 /*****************************************************************************/ |
231 |
231 |
319 fsm->tx_current_size = 0; |
319 fsm->tx_current_size = 0; |
320 fsm->tx_packet_no = 0; |
320 fsm->tx_packet_no = 0; |
321 fsm->tx_last_packet = 0; |
321 fsm->tx_last_packet = 0; |
322 |
322 |
323 #ifdef DEBUG_FOE |
323 #ifdef DEBUG_FOE |
324 printk("ec_fsm_foe_write_start()\n"); |
324 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
325 #endif |
325 #endif |
326 |
326 |
327 if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) { |
327 if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) { |
328 ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR); |
328 ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR); |
329 EC_SLAVE_ERR(slave, "Slave does not support FoE!\n"); |
329 EC_SLAVE_ERR(slave, "Slave does not support FoE!\n"); |
348 ) |
348 ) |
349 { |
349 { |
350 ec_slave_t *slave = fsm->slave; |
350 ec_slave_t *slave = fsm->slave; |
351 |
351 |
352 #ifdef DEBUG_FOE |
352 #ifdef DEBUG_FOE |
353 printk("ec_fsm_foe_ack_check()\n"); |
353 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
354 #endif |
354 #endif |
355 |
355 |
356 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
356 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
357 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
357 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
358 EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: "); |
358 EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: "); |
403 uint8_t *data, mbox_prot; |
403 uint8_t *data, mbox_prot; |
404 uint8_t opCode; |
404 uint8_t opCode; |
405 size_t rec_size; |
405 size_t rec_size; |
406 |
406 |
407 #ifdef DEBUG_FOE |
407 #ifdef DEBUG_FOE |
408 printk("ec_fsm_foe_ack_read()\n"); |
408 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
409 #endif |
409 #endif |
410 |
410 |
411 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
411 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
412 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
412 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
413 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); |
413 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); |
480 ) |
480 ) |
481 { |
481 { |
482 ec_slave_t *slave = fsm->slave; |
482 ec_slave_t *slave = fsm->slave; |
483 |
483 |
484 #ifdef DEBUG_FOE |
484 #ifdef DEBUG_FOE |
485 printk("ec_foe_state_sent_wrq()\n"); |
485 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
486 #endif |
486 #endif |
487 |
487 |
488 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
488 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
489 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
489 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
490 EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: "); |
490 EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: "); |
521 ) |
521 ) |
522 { |
522 { |
523 ec_slave_t *slave = fsm->slave; |
523 ec_slave_t *slave = fsm->slave; |
524 |
524 |
525 #ifdef DEBUG_FOE |
525 #ifdef DEBUG_FOE |
526 printk("ec_fsm_foe_state_data_sent()\n"); |
526 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
527 #endif |
527 #endif |
528 |
528 |
529 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
529 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
530 ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR); |
530 ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR); |
531 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); |
531 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); |
618 ) |
618 ) |
619 { |
619 { |
620 ec_slave_t *slave = fsm->slave; |
620 ec_slave_t *slave = fsm->slave; |
621 |
621 |
622 #ifdef DEBUG_FOE |
622 #ifdef DEBUG_FOE |
623 printk("ec_foe_state_rrq_sent()\n"); |
623 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
624 #endif |
624 #endif |
625 |
625 |
626 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
626 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
627 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
627 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
628 EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: "); |
628 EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: "); |
660 fsm->rx_buffer_offset = 0; |
660 fsm->rx_buffer_offset = 0; |
661 fsm->rx_expected_packet_no = 1; |
661 fsm->rx_expected_packet_no = 1; |
662 fsm->rx_last_packet = 0; |
662 fsm->rx_last_packet = 0; |
663 |
663 |
664 #ifdef DEBUG_FOE |
664 #ifdef DEBUG_FOE |
665 printk("ec_fsm_foe_read_start()\n"); |
665 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
666 #endif |
666 #endif |
667 |
667 |
668 if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) { |
668 if (!(slave->sii.mailbox_protocols & EC_MBOX_FOE)) { |
669 ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR); |
669 ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR); |
670 EC_SLAVE_ERR(slave, "Slave does not support FoE!\n"); |
670 EC_SLAVE_ERR(slave, "Slave does not support FoE!\n"); |
689 ) |
689 ) |
690 { |
690 { |
691 ec_slave_t *slave = fsm->slave; |
691 ec_slave_t *slave = fsm->slave; |
692 |
692 |
693 #ifdef DEBUG_FOE |
693 #ifdef DEBUG_FOE |
694 printk("ec_fsm_foe_state_data_check()\n"); |
694 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
695 #endif |
695 #endif |
696 |
696 |
697 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
697 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
698 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
698 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
699 EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: "); |
699 EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: "); |
726 // Fetch response |
726 // Fetch response |
727 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. |
727 ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. |
728 |
728 |
729 fsm->retries = EC_FSM_RETRIES; |
729 fsm->retries = EC_FSM_RETRIES; |
730 fsm->state = ec_fsm_foe_state_data_read; |
730 fsm->state = ec_fsm_foe_state_data_read; |
731 |
|
732 } |
731 } |
733 |
732 |
734 /*****************************************************************************/ |
733 /*****************************************************************************/ |
735 |
734 |
736 /** Start reading data. |
735 /** Start reading data. |
744 uint8_t *data, opCode, packet_no, mbox_prot; |
743 uint8_t *data, opCode, packet_no, mbox_prot; |
745 |
744 |
746 ec_slave_t *slave = fsm->slave; |
745 ec_slave_t *slave = fsm->slave; |
747 |
746 |
748 #ifdef DEBUG_FOE |
747 #ifdef DEBUG_FOE |
749 printk("ec_fsm_foe_state_data_read()\n"); |
748 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
750 #endif |
749 #endif |
751 |
750 |
752 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
751 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
753 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
752 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
754 EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: "); |
753 EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: "); |
830 - EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset) |
829 - EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset) |
831 <= fsm->rx_buffer_size) { |
830 <= fsm->rx_buffer_size) { |
832 // either it was the last packet or a new packet will fit into the |
831 // either it was the last packet or a new packet will fit into the |
833 // delivered buffer |
832 // delivered buffer |
834 #ifdef DEBUG_FOE |
833 #ifdef DEBUG_FOE |
835 printk ("last_packet=true\n"); |
834 EC_SLAVE_DBG(fsm->slave, 0, "last_packet=true\n"); |
836 #endif |
835 #endif |
837 if (ec_foe_prepare_send_ack(fsm, datagram)) { |
836 if (ec_foe_prepare_send_ack(fsm, datagram)) { |
838 ec_foe_set_rx_error(fsm, FOE_RX_DATA_ACK_ERROR); |
837 ec_foe_set_rx_error(fsm, FOE_RX_DATA_ACK_ERROR); |
839 return; |
838 return; |
840 } |
839 } |
842 fsm->state = ec_fsm_foe_state_sent_ack; |
841 fsm->state = ec_fsm_foe_state_sent_ack; |
843 } |
842 } |
844 else { |
843 else { |
845 // no more data fits into the delivered buffer |
844 // no more data fits into the delivered buffer |
846 // ... wait for new read request |
845 // ... wait for new read request |
847 printk ("ERROR: data doesn't fit in receive buffer\n"); |
846 EC_SLAVE_ERR(slave, "Data do not fit in receive buffer!\n"); |
848 printk (" rx_buffer_size = %d\n", fsm->rx_buffer_size); |
847 printk(" rx_buffer_size = %d\n", fsm->rx_buffer_size); |
849 printk (" rx_buffer_offset= %d\n", fsm->rx_buffer_offset); |
848 printk("rx_buffer_offset = %d\n", fsm->rx_buffer_offset); |
850 printk (" rec_size = %zd\n", rec_size); |
849 printk(" rec_size = %zd\n", rec_size); |
851 printk (" rx_mailbox_size = %d\n", |
850 printk(" rx_mailbox_size = %d\n", slave->configured_rx_mailbox_size); |
852 slave->configured_rx_mailbox_size); |
851 printk(" rx_last_packet = %d\n", fsm->rx_last_packet); |
853 printk (" rx_last_packet = %d\n", fsm->rx_last_packet); |
|
854 fsm->request->result = FOE_READY; |
852 fsm->request->result = FOE_READY; |
855 } |
853 } |
856 } |
854 } |
857 |
855 |
858 /*****************************************************************************/ |
856 /*****************************************************************************/ |
865 ) |
863 ) |
866 { |
864 { |
867 ec_slave_t *slave = fsm->slave; |
865 ec_slave_t *slave = fsm->slave; |
868 |
866 |
869 #ifdef DEBUG_FOE |
867 #ifdef DEBUG_FOE |
870 printk("ec_foe_state_sent_ack()\n"); |
868 EC_SLAVE_DBG(fsm->slave, 0, "%s()\n", __func__); |
871 #endif |
869 #endif |
872 |
870 |
873 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
871 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
874 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
872 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
875 EC_SLAVE_ERR(slave, "Failed to send FoE ACK: "); |
873 EC_SLAVE_ERR(slave, "Failed to send FoE ACK: "); |