master/fsm_foe.c
changeset 1336 e27b37e80a99
parent 1335 09c6fce1ae45
child 1337 0253c74d0940
equal deleted inserted replaced
1335:09c6fce1ae45 1336:e27b37e80a99
     1 /******************************************************************************
     1 /******************************************************************************
     2  *
     2  *
     3  *  $Id:$
     3  *  $Id$
     4  *
     4  *
     5  *  Copyright (C) 2008  Olav Zarges, imc Meßsysteme GmbH
     5  *  Copyright (C) 2008  Olav Zarges, imc Meßsysteme GmbH
     6  *
     6  *
     7  *  This file is part of the IgH EtherCAT Master.
     7  *  This file is part of the IgH EtherCAT Master.
     8  *
     8  *
    50  */
    50  */
    51 #define EC_FSM_FOE_TIMEOUT 3000
    51 #define EC_FSM_FOE_TIMEOUT 3000
    52 
    52 
    53 #define EC_MBOX_TYPE_FILEACCESS 0x04
    53 #define EC_MBOX_TYPE_FILEACCESS 0x04
    54 
    54 
       
    55 #define myDEBUG
       
    56 
    55 /*****************************************************************************/
    57 /*****************************************************************************/
    56 
    58 
    57 int		ec_foe_prepare_data_send( ec_fsm_foe_t * );
    59 int		ec_foe_prepare_data_send( ec_fsm_foe_t * );
    58 int		ec_foe_prepare_wrq_send( ec_fsm_foe_t * );
    60 int		ec_foe_prepare_wrq_send( ec_fsm_foe_t * );
    59 int		ec_foe_prepare_rrq_send( ec_fsm_foe_t * );
    61 int		ec_foe_prepare_rrq_send( ec_fsm_foe_t * );
   186 // uint8_t	reserved
   188 // uint8_t	reserved
   187 // uint8_t	Type:4
   189 // uint8_t	Type:4
   188 // uint8_t	Counter:4
   190 // uint8_t	Counter:4
   189 
   191 
   190 #define	EC_FOE_HEADER_SIZE		6
   192 #define	EC_FOE_HEADER_SIZE		6
   191 // uint8_t	OpMode
   193 // uint8_t	OpCode
   192 // uint8_t	reserved
   194 // uint8_t	reserved
   193 // uint32_t	PacketNo, Password, ErrorCode
   195 // uint32_t	PacketNo, Password, ErrorCode
   194 
   196 
   195 enum {
   197 enum {
   196 	EC_FOE_OPMODE_RRQ  = 1,
   198 	EC_FOE_OPCODE_RRQ  = 1,
   197 	EC_FOE_OPMODE_WRQ  = 2,
   199 	EC_FOE_OPCODE_WRQ  = 2,
   198 	EC_FOE_OPMODE_DATA = 3,
   200 	EC_FOE_OPCODE_DATA = 3,
   199 	EC_FOE_OPMODE_ACK  = 4,
   201 	EC_FOE_OPCODE_ACK  = 4,
   200 	EC_FOE_OPMODE_ERR  = 5,
   202 	EC_FOE_OPCODE_ERR  = 5,
   201 	EC_FOE_OPMODE_BUSY = 6
   203 	EC_FOE_OPCODE_BUSY = 6
   202 } ec_foe_opmode_t;
   204 } ec_foe_opcode_t;
   203 
   205 
   204 /*****************************************************************************/
   206 /*****************************************************************************/
   205 /**
   207 /**
   206    Sends a file or the next fragment.
   208    Sends a file or the next fragment.
   207 */
   209 */
   222 
   224 
   223     if (!(data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
   225     if (!(data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
   224     		EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE)))
   226     		EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE)))
   225         return -1;
   227         return -1;
   226 
   228 
   227     EC_WRITE_U8 ( data, EC_FOE_OPMODE_DATA ); 		// OpMode = DataBlock req.
   229     EC_WRITE_U8 ( data, EC_FOE_OPCODE_DATA ); 		// OpCode = DataBlock req.
   228     EC_WRITE_U32( data + 2, fsm->tx_packet_no );	// PacketNo, Password
   230     EC_WRITE_U32( data + 2, fsm->tx_packet_no );	// PacketNo, Password
   229 
   231 
   230     memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
   232     memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
   231 
   233 
   232     fsm->tx_current_size = current_size;
   234     fsm->tx_current_size = current_size;
   252 
   254 
   253     if (!(data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
   255     if (!(data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
   254     		EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE)))
   256     		EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE)))
   255         return -1;
   257         return -1;
   256 
   258 
   257     EC_WRITE_U16( data, EC_FOE_OPMODE_WRQ); // fsm write request
   259     EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
   258     EC_WRITE_U32( data + 2, fsm->tx_packet_no );
   260     EC_WRITE_U32( data + 2, fsm->tx_packet_no );
   259 
   261 
   260     memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);
   262     memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);
   261 
   263 
   262     return 0;
   264     return 0;
   373 void ec_fsm_foe_state_ack_read( ec_fsm_foe_t *fsm ) {
   375 void ec_fsm_foe_state_ack_read( ec_fsm_foe_t *fsm ) {
   374 
   376 
   375     ec_datagram_t *datagram = fsm->datagram;
   377     ec_datagram_t *datagram = fsm->datagram;
   376     ec_slave_t *slave = fsm->slave;
   378     ec_slave_t *slave = fsm->slave;
   377     uint8_t *data, mbox_prot;
   379     uint8_t *data, mbox_prot;
   378     uint16_t opMode;
   380     uint8_t opCode;
   379     size_t rec_size;
   381     size_t rec_size;
   380 
   382 
   381 #ifdef	myDEBUG
   383 #ifdef	myDEBUG
   382 	printk("ec_fsm_foe_ack_read()\n");
   384 	printk("ec_fsm_foe_ack_read()\n");
   383 #endif
   385 #endif
   406     	ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
   408     	ec_foe_set_tx_error(fsm, FOE_MBOX_PROT_ERROR);
   407         EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot);
   409         EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot);
   408         return;
   410         return;
   409     }
   411     }
   410 
   412 
   411     opMode = EC_READ_U16(data);
   413     opCode = EC_READ_U8(data);
   412 
   414 
   413     if ( opMode == EC_FOE_OPMODE_BUSY ) {
   415     if (opCode == EC_FOE_OPCODE_BUSY) {
   414     	// slave ist noch nicht bereit
   416     	// slave ist noch nicht bereit
   415         if (ec_foe_prepare_data_send(fsm)) {
   417         if (ec_foe_prepare_data_send(fsm)) {
   416         	ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   418         	ec_foe_set_tx_error(fsm, FOE_PROT_ERROR);
   417             EC_ERR("Slave is busy.\n");
   419             EC_ERR("Slave is busy.\n");
   418         	return;
   420         	return;
   419         }
   421         }
   420         fsm->state = ec_fsm_foe_state_data_sent;
   422         fsm->state = ec_fsm_foe_state_data_sent;
   421         return;
   423         return;
   422     }
   424     }
   423 
   425 
   424     if ( opMode == EC_FOE_OPMODE_ACK ) {
   426     if (opCode == EC_FOE_OPCODE_ACK) {
   425         fsm->tx_packet_no++;
   427         fsm->tx_packet_no++;
   426         fsm->tx_buffer_offset += fsm->tx_current_size;
   428         fsm->tx_buffer_offset += fsm->tx_current_size;
   427 
   429 
   428         if (fsm->tx_last_packet) {
   430         if (fsm->tx_last_packet) {
   429         	fsm->state = ec_fsm_foe_end;
   431         	fsm->state = ec_fsm_foe_end;
   528 
   530 
   529     if (!(data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
   531     if (!(data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
   530     		EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE)))
   532     		EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE)))
   531         return -1;
   533         return -1;
   532 
   534 
   533     EC_WRITE_U16( data, EC_FOE_OPMODE_RRQ); // fsm read request
   535     EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
   534     EC_WRITE_U32( data + 2, 0 );
   536     EC_WRITE_U32(data + 2, 0x00000000); // no passwd
   535 
       
   536     memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
   537     memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);
       
   538 
       
   539     if (fsm->slave->master->debug_level) {
       
   540         EC_DBG("FoE Read Request:\n");
       
   541         ec_print_data(data, current_size + EC_FOE_HEADER_SIZE);
       
   542     }
   537 
   543 
   538     return 0;
   544     return 0;
   539 }
   545 }
   540 
   546 
   541 
   547 
   546 
   552 
   547     if (!(data = ec_slave_mbox_prepare_send(foe->slave, foe->datagram,
   553     if (!(data = ec_slave_mbox_prepare_send(foe->slave, foe->datagram,
   548     		EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE)))
   554     		EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE)))
   549         return -1;
   555         return -1;
   550 
   556 
   551     EC_WRITE_U16( data, EC_FOE_OPMODE_ACK);
   557     EC_WRITE_U16( data, EC_FOE_OPCODE_ACK);
   552     EC_WRITE_U32( data + 2, foe->rx_expected_packet_no  );
   558     EC_WRITE_U32( data + 2, foe->rx_expected_packet_no  );
   553 
   559 
   554     return 0;
   560     return 0;
   555 }
   561 }
   556 
   562 
   696 
   702 
   697 /*****************************************************************************/
   703 /*****************************************************************************/
   698 
   704 
   699 void ec_fsm_foe_state_data_read ( ec_fsm_foe_t *fsm ) {
   705 void ec_fsm_foe_state_data_read ( ec_fsm_foe_t *fsm ) {
   700     size_t 	rec_size;
   706     size_t 	rec_size;
   701     uint8_t *data, opMode, packet_no, mbox_prot;
   707     uint8_t *data, opCode, packet_no, mbox_prot;
   702 
   708 
   703     ec_datagram_t *datagram = fsm->datagram;
   709     ec_datagram_t *datagram = fsm->datagram;
   704     ec_slave_t *slave = fsm->slave;
   710     ec_slave_t *slave = fsm->slave;
   705 
   711 
   706 #ifdef	myDEBUG
   712 #ifdef	myDEBUG
   707 	printk("ec_fsm_foe_state_data_read()\n");
   713 	printk("ec_fsm_foe_state_data_read()\n");
   708 #endif
   714 #endif
       
   715 
   709     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   716     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   710     	ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   717     	ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR);
   711         EC_ERR("Failed to receive FoE DATA READ datagram for"
   718         EC_ERR("Failed to receive FoE DATA READ datagram for"
   712                " slave %u (datagram state %u).\n",
   719                " slave %u (datagram state %u).\n",
   713                slave->ring_position, datagram->state);
   720                slave->ring_position, datagram->state);
   731         EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot);
   738         EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot);
   732         ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
   739         ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
   733         return;
   740         return;
   734     }
   741     }
   735 
   742 
   736     opMode = EC_READ_U16(data);
   743     opCode = EC_READ_U8(data);
   737 
   744 
   738     if (opMode == EC_FOE_OPMODE_BUSY) {
   745     if (opCode == EC_FOE_OPCODE_BUSY) {
   739         if (ec_foe_prepare_send_ack(fsm)) {
   746         if (ec_foe_prepare_send_ack(fsm)) {
   740             ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
   747             ec_foe_set_rx_error(fsm, FOE_PROT_ERROR);
   741         }
   748         }
   742         return;
   749         return;
   743     }
   750     }
   744 
   751 
   745     if (opMode != EC_FOE_OPMODE_DATA) {
   752     if (opCode == EC_FOE_OPCODE_ERR) {
   746         ec_foe_set_rx_error(fsm, FOE_OPMODE_ERROR);
   753         fsm->request->error_code = EC_READ_U32(data + 2);
       
   754         EC_ERR("Received FoE Error Request (code %08x) on slave %u.\n",
       
   755                 fsm->request->error_code, slave->ring_position);
       
   756         if (rec_size > 6) {
       
   757             uint8_t text[1024];
       
   758             strncpy(text, data + 6, min(rec_size - 6, sizeof(text)));
       
   759             EC_ERR("FoE Error Text: %s\n", text);
       
   760         }
       
   761         ec_foe_set_rx_error(fsm, FOE_OPCODE_ERROR);
       
   762         return;
       
   763     }
       
   764 
       
   765     if (opCode != EC_FOE_OPCODE_DATA) {
       
   766         EC_ERR("Received OPCODE %x, expected %x on slave %u.\n",
       
   767                 opCode, EC_FOE_OPCODE_DATA, slave->ring_position);
       
   768         fsm->request->error_code = 0x00000000;
       
   769         ec_foe_set_rx_error(fsm, FOE_OPCODE_ERROR);
   747         return;
   770         return;
   748     }
   771     }
   749 
   772 
   750     packet_no = EC_READ_U16(data + 2);
   773     packet_no = EC_READ_U16(data + 2);
   751     if (packet_no != fsm->rx_expected_packet_no) {
   774     if (packet_no != fsm->rx_expected_packet_no) {
       
   775         EC_ERR("Received unexpected packet number on slave %u.\n",
       
   776                 slave->ring_position);
   752         ec_foe_set_rx_error(fsm, FOE_PACKETNO_ERROR);
   777         ec_foe_set_rx_error(fsm, FOE_PACKETNO_ERROR);
   753         return;
   778         return;
   754     }
   779     }
   755 
   780 
   756     rec_size -= EC_FOE_HEADER_SIZE;
   781     rec_size -= EC_FOE_HEADER_SIZE;
   757 
   782 
   758     if ( fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size ) {
   783     if (fsm->rx_buffer_size >= fsm->rx_buffer_offset + rec_size) {
   759         memcpy ( fsm->rx_buffer + fsm->rx_buffer_offset, data + EC_FOE_HEADER_SIZE, rec_size );
   784         memcpy(fsm->rx_buffer + fsm->rx_buffer_offset,
       
   785                 data + EC_FOE_HEADER_SIZE, rec_size);
   760         fsm->rx_buffer_offset += rec_size;
   786         fsm->rx_buffer_offset += rec_size;
   761     }
   787     }
   762 
   788 
   763     fsm->rx_last_packet = (rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE != fsm->slave->sii.rx_mailbox_size);
   789     fsm->rx_last_packet =
       
   790         (rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE
       
   791          != fsm->slave->sii.rx_mailbox_size);
   764 
   792 
   765     if (fsm->rx_last_packet ||
   793     if (fsm->rx_last_packet ||
   766     	slave->sii.rx_mailbox_size - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE  + fsm->rx_buffer_offset <= fsm->rx_buffer_size) {
   794     	(slave->sii.rx_mailbox_size - EC_MBOX_HEADER_SIZE
       
   795          - EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset) <= fsm->rx_buffer_size) {
   767     	// either it was the last packet or a new packet will fit into the delivered buffer
   796     	// either it was the last packet or a new packet will fit into the delivered buffer
   768 #ifdef	myDEBUG
   797 #ifdef	myDEBUG
   769     	printk ("last_packet=true\n");
   798     	printk ("last_packet=true\n");
   770 #endif
   799 #endif
   771 	    if (ec_foe_prepare_send_ack(fsm)) {
   800 	    if (ec_foe_prepare_send_ack(fsm)) {
   774 	    }
   803 	    }
   775 
   804 
   776 	    fsm->state = ec_fsm_foe_state_sent_ack;
   805 	    fsm->state = ec_fsm_foe_state_sent_ack;
   777     }
   806     }
   778     else {
   807     else {
   779     	// no more data fits into the deliverd buffer
   808     	// no more data fits into the delivered buffer
   780     	// ... wait for new read request (an den Treiber)
   809     	// ... wait for new read request
   781     	printk ("ERROR: data doesn't fit in receive buffer\n");
   810     	printk ("ERROR: data doesn't fit in receive buffer\n");
   782     	printk ("       rx_buffer_size  = %d\n", fsm->rx_buffer_size);
   811     	printk ("       rx_buffer_size  = %d\n", fsm->rx_buffer_size);
   783     	printk ("       rx_buffer_offset= %d\n", fsm->rx_buffer_offset);
   812     	printk ("       rx_buffer_offset= %d\n", fsm->rx_buffer_offset);
   784     	printk ("       rec_size        = %d\n", rec_size);
   813     	printk ("       rec_size        = %d\n", rec_size);
   785     	printk ("       rx_mailbox_size = %d\n", slave->sii.rx_mailbox_size);
   814     	printk ("       rx_mailbox_size = %d\n", slave->sii.rx_mailbox_size);
   786     	printk ("       rx_last_packet  = %d\n", fsm->rx_last_packet);
   815     	printk ("       rx_last_packet  = %d\n", fsm->rx_last_packet);
   787 //    	fsm->state = ec_fsm_state_wait_next_read;
   816 //    	fsm->state = ec_fsm_state_wait_next_read;
   788     	fsm->request->abort_code = FOE_READY;
   817     	fsm->request->result = FOE_READY;
   789     }
   818     }
   790 }
   819 }
   791 
   820 
   792 /*****************************************************************************/
   821 /*****************************************************************************/
   793 
   822 
   832     }
   861     }
   833 }
   862 }
   834 
   863 
   835 /*****************************************************************************/
   864 /*****************************************************************************/
   836 
   865 
   837 void ec_foe_set_tx_error( ec_fsm_foe_t *fsm, uint32_t errorcode ) {
   866 void ec_foe_set_tx_error(ec_fsm_foe_t *fsm, uint32_t errorcode)
       
   867 {
   838 	fsm->tx_errors++;
   868 	fsm->tx_errors++;
   839 	fsm->request->abort_code = errorcode;
   869 	fsm->request->result = errorcode;
   840 	fsm->state = ec_fsm_foe_error;
   870 	fsm->state = ec_fsm_foe_error;
   841 }
   871 }
   842 
   872 
   843 /*****************************************************************************/
   873 /*****************************************************************************/
   844 
   874 
   845 void ec_foe_set_rx_error( ec_fsm_foe_t *fsm, uint32_t errorcode ) {
   875 void ec_foe_set_rx_error(ec_fsm_foe_t *fsm, uint32_t errorcode)
       
   876 {
   846 	fsm->rx_errors++;
   877 	fsm->rx_errors++;
   847 	fsm->request->abort_code = errorcode;
   878 	fsm->request->result = errorcode;
   848 	fsm->state = ec_fsm_foe_error;
   879 	fsm->state = ec_fsm_foe_error;
   849 }
   880 }
   850 
   881 
   851 /*****************************************************************************/
   882 /*****************************************************************************/