master/fsm.c
changeset 308 d50b139c8601
parent 306 45886de3db87
child 309 42e69cf31495
equal deleted inserted replaced
307:ffec9aae50a5 308:d50b139c8601
    52 void ec_fsm_master_rewrite_addresses(ec_fsm_t *);
    52 void ec_fsm_master_rewrite_addresses(ec_fsm_t *);
    53 void ec_fsm_master_configure_slave(ec_fsm_t *);
    53 void ec_fsm_master_configure_slave(ec_fsm_t *);
    54 void ec_fsm_master_scan_slaves(ec_fsm_t *);
    54 void ec_fsm_master_scan_slaves(ec_fsm_t *);
    55 void ec_fsm_master_write_eeprom(ec_fsm_t *);
    55 void ec_fsm_master_write_eeprom(ec_fsm_t *);
    56 
    56 
    57 void ec_fsm_slave_start_reading(ec_fsm_t *);
    57 void ec_fsm_slavescan_start(ec_fsm_t *);
    58 void ec_fsm_slave_read_state(ec_fsm_t *);
    58 void ec_fsm_slavescan_state(ec_fsm_t *);
    59 void ec_fsm_slave_read_base(ec_fsm_t *);
    59 void ec_fsm_slavescan_base(ec_fsm_t *);
    60 void ec_fsm_slave_read_dl(ec_fsm_t *);
    60 void ec_fsm_slavescan_datalink(ec_fsm_t *);
    61 void ec_fsm_slave_eeprom_size(ec_fsm_t *);
    61 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *);
    62 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *);
    62 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *);
    63 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *);
    63 void ec_fsm_slavescan_eeprom_data2(ec_fsm_t *);
    64 void ec_fsm_slave_end(ec_fsm_t *);
    64 void ec_fsm_slavescan_end(ec_fsm_t *);
    65 
    65 
    66 void ec_fsm_slave_conf(ec_fsm_t *);
    66 void ec_fsm_slaveconf_start(ec_fsm_t *);
    67 void ec_fsm_slave_sync(ec_fsm_t *);
    67 void ec_fsm_slaveconf_sync(ec_fsm_t *);
    68 void ec_fsm_slave_preop(ec_fsm_t *);
    68 void ec_fsm_slaveconf_preop(ec_fsm_t *);
    69 void ec_fsm_slave_fmmu(ec_fsm_t *);
    69 void ec_fsm_slaveconf_fmmu(ec_fsm_t *);
    70 void ec_fsm_slave_saveop(ec_fsm_t *);
    70 void ec_fsm_slaveconf_saveop(ec_fsm_t *);
    71 void ec_fsm_slave_op(ec_fsm_t *);
    71 void ec_fsm_slaveconf_op(ec_fsm_t *);
    72 void ec_fsm_slave_op2(ec_fsm_t *);
    72 void ec_fsm_slaveconf_op2(ec_fsm_t *);
       
    73 void ec_fsm_slaveconf_end(ec_fsm_t *);
    73 
    74 
    74 void ec_fsm_sii_start_reading(ec_fsm_t *);
    75 void ec_fsm_sii_start_reading(ec_fsm_t *);
    75 void ec_fsm_sii_read_check(ec_fsm_t *);
    76 void ec_fsm_sii_read_check(ec_fsm_t *);
    76 void ec_fsm_sii_read_fetch(ec_fsm_t *);
    77 void ec_fsm_sii_read_fetch(ec_fsm_t *);
    77 void ec_fsm_sii_start_writing(ec_fsm_t *);
    78 void ec_fsm_sii_start_writing(ec_fsm_t *);
   260             list_add_tail(&slave->list, &master->slaves);
   261             list_add_tail(&slave->list, &master->slaves);
   261         }
   262         }
   262 
   263 
   263         // begin scanning of slaves
   264         // begin scanning of slaves
   264         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   265         fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   265         fsm->slave_state = ec_fsm_slave_start_reading;
   266         fsm->slave_state = ec_fsm_slavescan_start;
   266         fsm->master_state = ec_fsm_master_scan_slaves;
   267         fsm->master_state = ec_fsm_master_scan_slaves;
   267         fsm->master_state(fsm); // execute immediately
   268         fsm->master_state(fsm); // execute immediately
   268         return;
   269         return;
   269     }
   270     }
   270 
   271 
   301         printk(" to ");
   302         printk(" to ");
   302         ec_print_states(slave->requested_state);
   303         ec_print_states(slave->requested_state);
   303         printk(".\n");
   304         printk(".\n");
   304 
   305 
   305         fsm->slave = slave;
   306         fsm->slave = slave;
   306         fsm->slave_state = ec_fsm_slave_conf;
   307         fsm->slave_state = ec_fsm_slaveconf_start;
   307         fsm->change_new = EC_SLAVE_STATE_INIT;
   308         fsm->change_new = EC_SLAVE_STATE_INIT;
   308         fsm->change_state = ec_fsm_change_start;
   309         fsm->change_state = ec_fsm_change_start;
   309         fsm->master_state = ec_fsm_master_configure_slave;
   310         fsm->master_state = ec_fsm_master_configure_slave;
   310         fsm->master_state(fsm); // execute immediately
   311         fsm->master_state(fsm); // execute immediately
   311         return;
   312         return;
   605     uint16_t reverse_coupler_index, current_coupler_index;
   606     uint16_t reverse_coupler_index, current_coupler_index;
   606     ec_slave_ident_t *ident;
   607     ec_slave_ident_t *ident;
   607 
   608 
   608     fsm->slave_state(fsm); // execute slave state machine
   609     fsm->slave_state(fsm); // execute slave state machine
   609 
   610 
   610     if (fsm->slave_state != ec_fsm_slave_end) return;
   611     if (fsm->slave_state != ec_fsm_slavescan_end) return;
   611 
   612 
   612     // have all slaves been fetched?
   613     // have all slaves been fetched?
   613     if (slave->list.next == &master->slaves) {
   614     if (slave->list.next == &master->slaves) {
   614         EC_INFO("Bus scanning completed.\n");
   615         EC_INFO("Bus scanning completed.\n");
   615 
   616 
   680         return;
   681         return;
   681     }
   682     }
   682 
   683 
   683     // process next slave
   684     // process next slave
   684     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   685     fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list);
   685     fsm->slave_state = ec_fsm_slave_start_reading;
   686     fsm->slave_state = ec_fsm_slavescan_start;
   686     fsm->slave_state(fsm); // execute immediately
   687     fsm->slave_state(fsm); // execute immediately
   687 }
   688 }
   688 
   689 
   689 /*****************************************************************************/
   690 /*****************************************************************************/
   690 
   691 
   696 void ec_fsm_master_configure_slave(ec_fsm_t *fsm
   697 void ec_fsm_master_configure_slave(ec_fsm_t *fsm
   697                                    /**< finite state machine */
   698                                    /**< finite state machine */
   698                                    )
   699                                    )
   699 {
   700 {
   700     fsm->slave_state(fsm); // execute slave's state machine
   701     fsm->slave_state(fsm); // execute slave's state machine
   701     if (fsm->slave_state != ec_fsm_slave_end) return;
   702     if (fsm->slave_state != ec_fsm_slaveconf_end) return;
   702 
   703 
   703     ec_fsm_master_action_process_states(fsm);
   704     ec_fsm_master_action_process_states(fsm);
   704 }
   705 }
   705 
   706 
   706 /*****************************************************************************/
   707 /*****************************************************************************/
   740     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
   741     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
   741     kfree(slave->new_eeprom_data);
   742     kfree(slave->new_eeprom_data);
   742     slave->new_eeprom_data = NULL;
   743     slave->new_eeprom_data = NULL;
   743 
   744 
   744     // restart master state machine.
   745     // restart master state machine.
   745     fsm->master_state = ec_fsm_master_start; // TODO: Scan slaves!
   746     fsm->master_state = ec_fsm_master_start; // TODO: Evaluate new contents!
   746     fsm->master_state(fsm); // execute immediately
   747     fsm->master_state(fsm); // execute immediately
   747     return;
   748     return;
   748 }
   749 }
   749 
   750 
   750 /******************************************************************************
   751 /******************************************************************************
   751  *  slave state machine
   752  *  slave scan sub state machine
   752  *****************************************************************************/
   753  *****************************************************************************/
   753 
   754 
   754 /**
   755 /**
   755    Slave state: START_READING.
   756    Slave state: START_READING.
   756    First state of the slave state machine. Writes the station address to the
   757    First state of the slave state machine. Writes the station address to the
   757    slave, according to its ring position.
   758    slave, according to its ring position.
   758 */
   759 */
   759 
   760 
   760 void ec_fsm_slave_start_reading(ec_fsm_t *fsm /**< finite state machine */)
   761 void ec_fsm_slavescan_start(ec_fsm_t *fsm /**< finite state machine */)
   761 {
   762 {
   762     ec_datagram_t *datagram = &fsm->datagram;
   763     ec_datagram_t *datagram = &fsm->datagram;
   763 
   764 
   764     // write station address
   765     // write station address
   765     ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
   766     ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2);
   766     EC_WRITE_U16(datagram->data, fsm->slave->station_address);
   767     EC_WRITE_U16(datagram->data, fsm->slave->station_address);
   767     ec_master_queue_datagram(fsm->master, datagram);
   768     ec_master_queue_datagram(fsm->master, datagram);
   768     fsm->slave_state = ec_fsm_slave_read_state;
   769     fsm->slave_state = ec_fsm_slavescan_state;
   769 }
   770 }
   770 
   771 
   771 /*****************************************************************************/
   772 /*****************************************************************************/
   772 
   773 
   773 /**
   774 /**
   774    Slave state: READ_STATUS.
   775    Slave state: READ_STATUS.
   775 */
   776 */
   776 
   777 
   777 void ec_fsm_slave_read_state(ec_fsm_t *fsm /**< finite state machine */)
   778 void ec_fsm_slavescan_state(ec_fsm_t *fsm /**< finite state machine */)
   778 {
   779 {
   779     ec_datagram_t *datagram = &fsm->datagram;
   780     ec_datagram_t *datagram = &fsm->datagram;
   780 
   781 
   781     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   782     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   782         fsm->slave->error_flag = 1;
   783         fsm->slave->error_flag = 1;
   783         fsm->slave_state = ec_fsm_slave_end;
   784         fsm->slave_state = ec_fsm_slavescan_end;
   784         EC_ERR("Failed to write station address of slave %i.\n",
   785         EC_ERR("Failed to write station address of slave %i.\n",
   785                fsm->slave->ring_position);
   786                fsm->slave->ring_position);
   786         return;
   787         return;
   787     }
   788     }
   788 
   789 
   789     // Read AL state
   790     // Read AL state
   790     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2);
   791     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2);
   791     ec_master_queue_datagram(fsm->master, datagram);
   792     ec_master_queue_datagram(fsm->master, datagram);
   792     fsm->slave_state = ec_fsm_slave_read_base;
   793     fsm->slave_state = ec_fsm_slavescan_base;
   793 }
   794 }
   794 
   795 
   795 /*****************************************************************************/
   796 /*****************************************************************************/
   796 
   797 
   797 /**
   798 /**
   798    Slave state: READ_BASE.
   799    Slave state: READ_BASE.
   799 */
   800 */
   800 
   801 
   801 void ec_fsm_slave_read_base(ec_fsm_t *fsm /**< finite state machine */)
   802 void ec_fsm_slavescan_base(ec_fsm_t *fsm /**< finite state machine */)
   802 {
   803 {
   803     ec_datagram_t *datagram = &fsm->datagram;
   804     ec_datagram_t *datagram = &fsm->datagram;
   804     ec_slave_t *slave = fsm->slave;
   805     ec_slave_t *slave = fsm->slave;
   805 
   806 
   806     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   807     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   807         fsm->slave->error_flag = 1;
   808         fsm->slave->error_flag = 1;
   808         fsm->slave_state = ec_fsm_slave_end;
   809         fsm->slave_state = ec_fsm_slavescan_end;
   809         EC_ERR("Failed to read AL state of slave %i.\n",
   810         EC_ERR("Failed to read AL state of slave %i.\n",
   810                fsm->slave->ring_position);
   811                fsm->slave->ring_position);
   811         return;
   812         return;
   812     }
   813     }
   813 
   814 
   819     }
   820     }
   820 
   821 
   821     // read base data
   822     // read base data
   822     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6);
   823     ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6);
   823     ec_master_queue_datagram(fsm->master, datagram);
   824     ec_master_queue_datagram(fsm->master, datagram);
   824     fsm->slave_state = ec_fsm_slave_read_dl;
   825     fsm->slave_state = ec_fsm_slavescan_datalink;
   825 }
   826 }
   826 
   827 
   827 /*****************************************************************************/
   828 /*****************************************************************************/
   828 
   829 
   829 /**
   830 /**
   830    Slave state: READ_DL.
   831    Slave state: READ_DL.
   831 */
   832 */
   832 
   833 
   833 void ec_fsm_slave_read_dl(ec_fsm_t *fsm /**< finite state machine */)
   834 void ec_fsm_slavescan_datalink(ec_fsm_t *fsm /**< finite state machine */)
   834 {
   835 {
   835     ec_datagram_t *datagram = &fsm->datagram;
   836     ec_datagram_t *datagram = &fsm->datagram;
   836     ec_slave_t *slave = fsm->slave;
   837     ec_slave_t *slave = fsm->slave;
   837 
   838 
   838     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   839     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   839         fsm->slave->error_flag = 1;
   840         fsm->slave->error_flag = 1;
   840         fsm->slave_state = ec_fsm_slave_end;
   841         fsm->slave_state = ec_fsm_slavescan_end;
   841         EC_ERR("Failed to read base data of slave %i.\n",
   842         EC_ERR("Failed to read base data of slave %i.\n",
   842                slave->ring_position);
   843                slave->ring_position);
   843         return;
   844         return;
   844     }
   845     }
   845 
   846 
   853         slave->base_fmmu_count = EC_MAX_FMMUS;
   854         slave->base_fmmu_count = EC_MAX_FMMUS;
   854 
   855 
   855     // read data link status
   856     // read data link status
   856     ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2);
   857     ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2);
   857     ec_master_queue_datagram(slave->master, datagram);
   858     ec_master_queue_datagram(slave->master, datagram);
   858     fsm->slave_state = ec_fsm_slave_eeprom_size;
   859     fsm->slave_state = ec_fsm_slavescan_eeprom_size;
   859 }
   860 }
   860 
   861 
   861 /*****************************************************************************/
   862 /*****************************************************************************/
   862 
   863 
   863 /**
   864 /**
   864    Slave state: EEPROM_SIZE.
   865    Slave state: EEPROM_SIZE.
   865    Read the actual size of the EEPROM to allocate the EEPROM image.
   866    Read the actual size of the EEPROM to allocate the EEPROM image.
   866 */
   867 */
   867 
   868 
   868 void ec_fsm_slave_eeprom_size(ec_fsm_t *fsm /**< finite state machine */)
   869 void ec_fsm_slavescan_eeprom_size(ec_fsm_t *fsm /**< finite state machine */)
   869 {
   870 {
   870     ec_datagram_t *datagram = &fsm->datagram;
   871     ec_datagram_t *datagram = &fsm->datagram;
   871     ec_slave_t *slave = fsm->slave;
   872     ec_slave_t *slave = fsm->slave;
   872     uint16_t dl_status;
   873     uint16_t dl_status;
   873     unsigned int i;
   874     unsigned int i;
   874 
   875 
   875     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   876     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
   876         fsm->slave->error_flag = 1;
   877         fsm->slave->error_flag = 1;
   877         fsm->slave_state = ec_fsm_slave_end;
   878         fsm->slave_state = ec_fsm_slavescan_end;
   878         EC_ERR("Failed to read DL status of slave %i.\n",
   879         EC_ERR("Failed to read DL status of slave %i.\n",
   879                slave->ring_position);
   880                slave->ring_position);
   880         return;
   881         return;
   881     }
   882     }
   882 
   883 
   890     // Start fetching EEPROM size
   891     // Start fetching EEPROM size
   891 
   892 
   892     fsm->sii_offset = 0x0040; // first category header
   893     fsm->sii_offset = 0x0040; // first category header
   893     fsm->sii_mode = 1;
   894     fsm->sii_mode = 1;
   894     fsm->sii_state = ec_fsm_sii_start_reading;
   895     fsm->sii_state = ec_fsm_sii_start_reading;
   895     fsm->slave_state = ec_fsm_slave_fetch_eeprom;
   896     fsm->slave_state = ec_fsm_slavescan_eeprom_data;
   896     fsm->slave_state(fsm); // execute state immediately
   897     fsm->slave_state(fsm); // execute state immediately
   897 }
   898 }
   898 
   899 
   899 /*****************************************************************************/
   900 /*****************************************************************************/
   900 
   901 
   901 /**
   902 /**
   902    Slave state: FETCH_EEPROM.
   903    Slave state: FETCH_EEPROM.
   903 */
   904 */
   904 
   905 
   905 void ec_fsm_slave_fetch_eeprom(ec_fsm_t *fsm /**< finite state machine */)
   906 void ec_fsm_slavescan_eeprom_data(ec_fsm_t *fsm /**< finite state machine */)
   906 {
   907 {
   907     ec_slave_t *slave = fsm->slave;
   908     ec_slave_t *slave = fsm->slave;
   908     uint16_t cat_type, cat_size;
   909     uint16_t cat_type, cat_size;
   909 
   910 
   910     // execute SII state machine
   911     // execute SII state machine
   911     fsm->sii_state(fsm);
   912     fsm->sii_state(fsm);
   912 
   913 
   913     if (fsm->sii_state == ec_fsm_sii_error) {
   914     if (fsm->sii_state == ec_fsm_sii_error) {
   914         fsm->slave->error_flag = 1;
   915         fsm->slave->error_flag = 1;
   915         fsm->slave_state = ec_fsm_slave_end;
   916         fsm->slave_state = ec_fsm_slavescan_end;
   916         EC_ERR("Failed to read EEPROM size of slave %i.\n",
   917         EC_ERR("Failed to read EEPROM size of slave %i.\n",
   917                slave->ring_position);
   918                slave->ring_position);
   918         return;
   919         return;
   919     }
   920     }
   920 
   921 
   939     }
   940     }
   940 
   941 
   941     if (!(slave->eeprom_data =
   942     if (!(slave->eeprom_data =
   942           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
   943           (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
   943         fsm->slave->error_flag = 1;
   944         fsm->slave->error_flag = 1;
   944         fsm->slave_state = ec_fsm_slave_end;
   945         fsm->slave_state = ec_fsm_slavescan_end;
   945         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
   946         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
   946                slave->ring_position);
   947                slave->ring_position);
   947         return;
   948         return;
   948     }
   949     }
   949 
   950 
   950     // Start fetching EEPROM contents
   951     // Start fetching EEPROM contents
   951 
   952 
   952     fsm->sii_offset = 0x0000;
   953     fsm->sii_offset = 0x0000;
   953     fsm->sii_mode = 1;
   954     fsm->sii_mode = 1;
   954     fsm->sii_state = ec_fsm_sii_start_reading;
   955     fsm->sii_state = ec_fsm_sii_start_reading;
   955     fsm->slave_state = ec_fsm_slave_fetch_eeprom2;
   956     fsm->slave_state = ec_fsm_slavescan_eeprom_data2;
   956     fsm->slave_state(fsm); // execute state immediately
   957     fsm->slave_state(fsm); // execute state immediately
   957 }
   958 }
   958 
   959 
   959 /*****************************************************************************/
   960 /*****************************************************************************/
   960 
   961 
   961 /**
   962 /**
   962    Slave state: FETCH_EEPROM2.
   963    Slave state: FETCH_EEPROM2.
   963 */
   964 */
   964 
   965 
   965 void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *fsm /**< finite state machine */)
   966 void ec_fsm_slavescan_eeprom_data2(ec_fsm_t *fsm /**< finite state machine */)
   966 {
   967 {
   967     ec_slave_t *slave = fsm->slave;
   968     ec_slave_t *slave = fsm->slave;
   968     uint16_t *cat_word, cat_type, cat_size;
   969     uint16_t *cat_word, cat_type, cat_size;
   969 
   970 
   970     // execute SII state machine
   971     // execute SII state machine
   971     fsm->sii_state(fsm);
   972     fsm->sii_state(fsm);
   972 
   973 
   973     if (fsm->sii_state == ec_fsm_sii_error) {
   974     if (fsm->sii_state == ec_fsm_sii_error) {
   974         fsm->slave->error_flag = 1;
   975         fsm->slave->error_flag = 1;
   975         fsm->slave_state = ec_fsm_slave_end;
   976         fsm->slave_state = ec_fsm_slavescan_end;
   976         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
   977         EC_ERR("Failed to fetch EEPROM contents of slave %i.\n",
   977                slave->ring_position);
   978                slave->ring_position);
   978         return;
   979         return;
   979     }
   980     }
   980 
   981 
  1060         cat_word += cat_size + 2;
  1061         cat_word += cat_size + 2;
  1061     }
  1062     }
  1062 
  1063 
  1063 end:
  1064 end:
  1064     fsm->slave->error_flag = 1;
  1065     fsm->slave->error_flag = 1;
  1065     fsm->slave_state = ec_fsm_slave_end;
  1066     fsm->slave_state = ec_fsm_slavescan_end;
  1066 }
  1067 }
  1067 
  1068 
  1068 /*****************************************************************************/
  1069 /*****************************************************************************/
       
  1070 
       
  1071 /**
       
  1072    Slave state: END.
       
  1073    End state of the slave state machine.
       
  1074 */
       
  1075 
       
  1076 void ec_fsm_slavescan_end(ec_fsm_t *fsm /**< finite state machine */)
       
  1077 {
       
  1078 }
       
  1079 
       
  1080 /******************************************************************************
       
  1081  *  slave configuration sub state machine
       
  1082  *****************************************************************************/
  1069 
  1083 
  1070 /**
  1084 /**
  1071    Slave state: CONF.
  1085    Slave state: CONF.
  1072 */
  1086 */
  1073 
  1087 
  1074 void ec_fsm_slave_conf(ec_fsm_t *fsm /**< finite state machine */)
  1088 void ec_fsm_slaveconf_start(ec_fsm_t *fsm /**< finite state machine */)
  1075 {
  1089 {
  1076     ec_slave_t *slave = fsm->slave;
  1090     ec_slave_t *slave = fsm->slave;
  1077     ec_master_t *master = fsm->master;
  1091     ec_master_t *master = fsm->master;
  1078     ec_datagram_t *datagram = &fsm->datagram;
  1092     ec_datagram_t *datagram = &fsm->datagram;
  1079 
  1093 
  1080     fsm->change_state(fsm); // execute state change state machine
  1094     fsm->change_state(fsm); // execute state change state machine
  1081 
  1095 
  1082     if (fsm->change_state == ec_fsm_change_error) {
  1096     if (fsm->change_state == ec_fsm_change_error) {
  1083         slave->error_flag = 1;
  1097         slave->error_flag = 1;
  1084         fsm->slave_state = ec_fsm_slave_end;
  1098         fsm->slave_state = ec_fsm_slaveconf_end;
  1085         return;
  1099         return;
  1086     }
  1100     }
  1087 
  1101 
  1088     if (fsm->change_state != ec_fsm_change_end) return;
  1102     if (fsm->change_state != ec_fsm_change_end) return;
  1089 
  1103 
  1090     // slave is now in INIT
  1104     // slave is now in INIT
  1091     if (slave->current_state == slave->requested_state) {
  1105     if (slave->current_state == slave->requested_state) {
  1092         fsm->slave_state = ec_fsm_slave_end; // successful
  1106         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1093         return;
  1107         return;
  1094     }
  1108     }
  1095 
  1109 
  1096     // check for slave registration
  1110     // check for slave registration
  1097     if (!slave->type) {
  1111     if (!slave->type) {
  1100 
  1114 
  1101     // check and reset CRC fault counters
  1115     // check and reset CRC fault counters
  1102     //ec_slave_check_crc(slave);
  1116     //ec_slave_check_crc(slave);
  1103 
  1117 
  1104     if (!slave->base_fmmu_count) { // no fmmus
  1118     if (!slave->base_fmmu_count) { // no fmmus
  1105         fsm->slave_state = ec_fsm_slave_sync;
  1119         fsm->slave_state = ec_fsm_slaveconf_sync;
  1106         fsm->slave_state(fsm); // execute immediately
  1120         fsm->slave_state(fsm); // execute immediately
  1107         return;
  1121         return;
  1108     }
  1122     }
  1109 
  1123 
  1110     // reset FMMUs
  1124     // reset FMMUs
  1111     ec_datagram_npwr(datagram, slave->station_address, 0x0600,
  1125     ec_datagram_npwr(datagram, slave->station_address, 0x0600,
  1112                      EC_FMMU_SIZE * slave->base_fmmu_count);
  1126                      EC_FMMU_SIZE * slave->base_fmmu_count);
  1113     memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
  1127     memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count);
  1114     ec_master_queue_datagram(master, datagram);
  1128     ec_master_queue_datagram(master, datagram);
  1115     fsm->slave_state = ec_fsm_slave_sync;
  1129     fsm->slave_state = ec_fsm_slaveconf_sync;
  1116 }
  1130 }
  1117 
  1131 
  1118 /*****************************************************************************/
  1132 /*****************************************************************************/
  1119 
  1133 
  1120 /**
  1134 /**
  1121    Slave state: SYNC.
  1135    Slave state: SYNC.
  1122    Configure sync managers.
  1136    Configure sync managers.
  1123 */
  1137 */
  1124 
  1138 
  1125 void ec_fsm_slave_sync(ec_fsm_t *fsm /**< finite state machine */)
  1139 void ec_fsm_slaveconf_sync(ec_fsm_t *fsm /**< finite state machine */)
  1126 {
  1140 {
  1127     ec_datagram_t *datagram = &fsm->datagram;
  1141     ec_datagram_t *datagram = &fsm->datagram;
  1128     ec_slave_t *slave = fsm->slave;
  1142     ec_slave_t *slave = fsm->slave;
  1129     unsigned int j;
  1143     unsigned int j;
  1130     const ec_sync_t *sync;
  1144     const ec_sync_t *sync;
  1131     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
  1145     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
  1132 
  1146 
  1133     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1147     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1134         slave->error_flag = 1;
  1148         slave->error_flag = 1;
  1135         fsm->slave_state = ec_fsm_slave_end;
  1149         fsm->slave_state = ec_fsm_slaveconf_end;
  1136         EC_ERR("Failed to reset FMMUs of slave %i.\n",
  1150         EC_ERR("Failed to reset FMMUs of slave %i.\n",
  1137                slave->ring_position);
  1151                slave->ring_position);
  1138         return;
  1152         return;
  1139     }
  1153     }
  1140 
  1154 
  1141     if (!slave->base_sync_count) { // no sync managers
  1155     if (!slave->base_sync_count) { // no sync managers
  1142         fsm->slave_state = ec_fsm_slave_preop;
  1156         fsm->slave_state = ec_fsm_slaveconf_preop;
  1143         fsm->slave_state(fsm); // execute immediately
  1157         fsm->slave_state(fsm); // execute immediately
  1144         return;
  1158         return;
  1145     }
  1159     }
  1146 
  1160 
  1147     // configure sync managers
  1161     // configure sync managers
  1153     // does the slave supply sync manager configurations in its EEPROM?
  1167     // does the slave supply sync manager configurations in its EEPROM?
  1154     if (!list_empty(&slave->eeprom_syncs)) {
  1168     if (!list_empty(&slave->eeprom_syncs)) {
  1155         list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
  1169         list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
  1156             if (eeprom_sync->index >= slave->base_sync_count) {
  1170             if (eeprom_sync->index >= slave->base_sync_count) {
  1157                 fsm->slave->error_flag = 1;
  1171                 fsm->slave->error_flag = 1;
  1158                 fsm->slave_state = ec_fsm_slave_end;
  1172                 fsm->slave_state = ec_fsm_slaveconf_end;
  1159                 EC_ERR("Invalid sync manager configuration found!");
  1173                 EC_ERR("Invalid sync manager configuration found!");
  1160                 return;
  1174                 return;
  1161             }
  1175             }
  1162             ec_eeprom_sync_config(eeprom_sync, slave,
  1176             ec_eeprom_sync_config(eeprom_sync, slave,
  1163                                   datagram->data + EC_SYNC_SIZE
  1177                                   datagram->data + EC_SYNC_SIZE
  1195         EC_INFO("Mailbox configured for unknown slave %i\n",
  1209         EC_INFO("Mailbox configured for unknown slave %i\n",
  1196                 slave->ring_position);
  1210                 slave->ring_position);
  1197     }
  1211     }
  1198 
  1212 
  1199     ec_master_queue_datagram(fsm->master, datagram);
  1213     ec_master_queue_datagram(fsm->master, datagram);
  1200     fsm->slave_state = ec_fsm_slave_preop;
  1214     fsm->slave_state = ec_fsm_slaveconf_preop;
  1201 }
  1215 }
  1202 
  1216 
  1203 /*****************************************************************************/
  1217 /*****************************************************************************/
  1204 
  1218 
  1205 /**
  1219 /**
  1206    Slave state: PREOP.
  1220    Slave state: PREOP.
  1207    Change slave state to PREOP.
  1221    Change slave state to PREOP.
  1208 */
  1222 */
  1209 
  1223 
  1210 void ec_fsm_slave_preop(ec_fsm_t *fsm /**< finite state machine */)
  1224 void ec_fsm_slaveconf_preop(ec_fsm_t *fsm /**< finite state machine */)
  1211 {
  1225 {
  1212     ec_datagram_t *datagram = &fsm->datagram;
  1226     ec_datagram_t *datagram = &fsm->datagram;
  1213     ec_slave_t *slave = fsm->slave;
  1227     ec_slave_t *slave = fsm->slave;
  1214 
  1228 
  1215     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1229     if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) {
  1216         slave->error_flag = 1;
  1230         slave->error_flag = 1;
  1217         fsm->slave_state = ec_fsm_slave_end;
  1231         fsm->slave_state = ec_fsm_slaveconf_end;
  1218         EC_ERR("Failed to set sync managers on slave %i.\n",
  1232         EC_ERR("Failed to set sync managers on slave %i.\n",
  1219                slave->ring_position);
  1233                slave->ring_position);
  1220         return;
  1234         return;
  1221     }
  1235     }
  1222 
  1236 
  1223     fsm->change_new = EC_SLAVE_STATE_PREOP;
  1237     fsm->change_new = EC_SLAVE_STATE_PREOP;
  1224     fsm->change_state = ec_fsm_change_start;
  1238     fsm->change_state = ec_fsm_change_start;
  1225     fsm->slave_state = ec_fsm_slave_fmmu;
  1239     fsm->slave_state = ec_fsm_slaveconf_fmmu;
  1226     fsm->change_state(fsm); // execute immediately
  1240     fsm->change_state(fsm); // execute immediately
  1227 }
  1241 }
  1228 
  1242 
  1229 /*****************************************************************************/
  1243 /*****************************************************************************/
  1230 
  1244 
  1231 /**
  1245 /**
  1232    Slave state: FMMU.
  1246    Slave state: FMMU.
  1233    Configure FMMUs.
  1247    Configure FMMUs.
  1234 */
  1248 */
  1235 
  1249 
  1236 void ec_fsm_slave_fmmu(ec_fsm_t *fsm /**< finite state machine */)
  1250 void ec_fsm_slaveconf_fmmu(ec_fsm_t *fsm /**< finite state machine */)
  1237 {
  1251 {
  1238     ec_slave_t *slave = fsm->slave;
  1252     ec_slave_t *slave = fsm->slave;
  1239     ec_master_t *master = fsm->master;
  1253     ec_master_t *master = fsm->master;
  1240     ec_datagram_t *datagram = &fsm->datagram;
  1254     ec_datagram_t *datagram = &fsm->datagram;
  1241     unsigned int j;
  1255     unsigned int j;
  1242 
  1256 
  1243     fsm->change_state(fsm); // execute state change state machine
  1257     fsm->change_state(fsm); // execute state change state machine
  1244 
  1258 
  1245     if (fsm->change_state == ec_fsm_change_error) {
  1259     if (fsm->change_state == ec_fsm_change_error) {
  1246         slave->error_flag = 1;
  1260         slave->error_flag = 1;
  1247         fsm->slave_state = ec_fsm_slave_end;
  1261         fsm->slave_state = ec_fsm_slaveconf_end;
  1248         return;
  1262         return;
  1249     }
  1263     }
  1250 
  1264 
  1251     if (fsm->change_state != ec_fsm_change_end) return;
  1265     if (fsm->change_state != ec_fsm_change_end) return;
  1252 
  1266 
  1253     // slave is now in PREOP
  1267     // slave is now in PREOP
  1254     if (slave->current_state == slave->requested_state) {
  1268     if (slave->current_state == slave->requested_state) {
  1255         fsm->slave_state = ec_fsm_slave_end; // successful
  1269         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1256         return;
  1270         return;
  1257     }
  1271     }
  1258 
  1272 
  1259     // stop activation here for slaves without type
  1273     // stop activation here for slaves without type
  1260     if (!slave->type) {
  1274     if (!slave->type) {
  1261         fsm->slave_state = ec_fsm_slave_end; // successful
  1275         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1262         return;
  1276         return;
  1263     }
  1277     }
  1264 
  1278 
  1265     if (!slave->base_fmmu_count) {
  1279     if (!slave->base_fmmu_count) {
  1266         fsm->slave_state = ec_fsm_slave_saveop;
  1280         fsm->slave_state = ec_fsm_slaveconf_saveop;
  1267         fsm->slave_state(fsm); // execute immediately
  1281         fsm->slave_state(fsm); // execute immediately
  1268         return;
  1282         return;
  1269     }
  1283     }
  1270 
  1284 
  1271     // configure FMMUs
  1285     // configure FMMUs
  1276         ec_fmmu_config(&slave->fmmus[j], slave,
  1290         ec_fmmu_config(&slave->fmmus[j], slave,
  1277                        datagram->data + EC_FMMU_SIZE * j);
  1291                        datagram->data + EC_FMMU_SIZE * j);
  1278     }
  1292     }
  1279 
  1293 
  1280     ec_master_queue_datagram(master, datagram);
  1294     ec_master_queue_datagram(master, datagram);
  1281     fsm->slave_state = ec_fsm_slave_saveop;
  1295     fsm->slave_state = ec_fsm_slaveconf_saveop;
  1282 }
  1296 }
  1283 
  1297 
  1284 /*****************************************************************************/
  1298 /*****************************************************************************/
  1285 
  1299 
  1286 /**
  1300 /**
  1287    Slave state: SAVEOP.
  1301    Slave state: SAVEOP.
  1288    Set slave state to SAVEOP.
  1302    Set slave state to SAVEOP.
  1289 */
  1303 */
  1290 
  1304 
  1291 void ec_fsm_slave_saveop(ec_fsm_t *fsm /**< finite state machine */)
  1305 void ec_fsm_slaveconf_saveop(ec_fsm_t *fsm /**< finite state machine */)
  1292 {
  1306 {
  1293     ec_datagram_t *datagram = &fsm->datagram;
  1307     ec_datagram_t *datagram = &fsm->datagram;
  1294 
  1308 
  1295     if (fsm->slave->base_fmmu_count && (datagram->state != EC_CMD_RECEIVED ||
  1309     if (fsm->slave->base_fmmu_count && (datagram->state != EC_CMD_RECEIVED ||
  1296                                         datagram->working_counter != 1)) {
  1310                                         datagram->working_counter != 1)) {
  1297         fsm->slave->error_flag = 1;
  1311         fsm->slave->error_flag = 1;
  1298         fsm->slave_state = ec_fsm_slave_end;
  1312         fsm->slave_state = ec_fsm_slaveconf_end;
  1299         EC_ERR("Failed to set FMMUs on slave %i.\n",
  1313         EC_ERR("Failed to set FMMUs on slave %i.\n",
  1300                fsm->slave->ring_position);
  1314                fsm->slave->ring_position);
  1301         return;
  1315         return;
  1302     }
  1316     }
  1303 
  1317 
  1304     // set state to SAVEOP
  1318     // set state to SAVEOP
  1305     fsm->slave_state = ec_fsm_slave_op;
  1319     fsm->slave_state = ec_fsm_slaveconf_op;
  1306     fsm->change_new = EC_SLAVE_STATE_SAVEOP;
  1320     fsm->change_new = EC_SLAVE_STATE_SAVEOP;
  1307     fsm->change_state = ec_fsm_change_start;
  1321     fsm->change_state = ec_fsm_change_start;
  1308     fsm->change_state(fsm); // execute immediately
  1322     fsm->change_state(fsm); // execute immediately
  1309 }
  1323 }
  1310 
  1324 
  1313 /**
  1327 /**
  1314    Slave state: OP.
  1328    Slave state: OP.
  1315    Set slave state to OP.
  1329    Set slave state to OP.
  1316 */
  1330 */
  1317 
  1331 
  1318 void ec_fsm_slave_op(ec_fsm_t *fsm /**< finite state machine */)
  1332 void ec_fsm_slaveconf_op(ec_fsm_t *fsm /**< finite state machine */)
  1319 {
  1333 {
  1320     fsm->change_state(fsm); // execute state change state machine
  1334     fsm->change_state(fsm); // execute state change state machine
  1321 
  1335 
  1322     if (fsm->change_state == ec_fsm_change_error) {
  1336     if (fsm->change_state == ec_fsm_change_error) {
  1323         fsm->slave->error_flag = 1;
  1337         fsm->slave->error_flag = 1;
  1324         fsm->slave_state = ec_fsm_slave_end;
  1338         fsm->slave_state = ec_fsm_slaveconf_end;
  1325         return;
  1339         return;
  1326     }
  1340     }
  1327 
  1341 
  1328     if (fsm->change_state != ec_fsm_change_end) return;
  1342     if (fsm->change_state != ec_fsm_change_end) return;
  1329 
  1343 
  1330     // slave is now in SAVEOP
  1344     // slave is now in SAVEOP
  1331     if (fsm->slave->current_state == fsm->slave->requested_state) {
  1345     if (fsm->slave->current_state == fsm->slave->requested_state) {
  1332         fsm->slave_state = ec_fsm_slave_end; // successful
  1346         fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1333         return;
  1347         return;
  1334     }
  1348     }
  1335 
  1349 
  1336     // set state to OP
  1350     // set state to OP
  1337     fsm->slave_state = ec_fsm_slave_op2;
  1351     fsm->slave_state = ec_fsm_slaveconf_op2;
  1338     fsm->change_new = EC_SLAVE_STATE_OP;
  1352     fsm->change_new = EC_SLAVE_STATE_OP;
  1339     fsm->change_state = ec_fsm_change_start;
  1353     fsm->change_state = ec_fsm_change_start;
  1340     fsm->change_state(fsm); // execute immediately
  1354     fsm->change_state(fsm); // execute immediately
  1341 }
  1355 }
  1342 
  1356 
  1345 /**
  1359 /**
  1346    Slave state: OP2
  1360    Slave state: OP2
  1347    Executes the change state machine, until the OP state is set.
  1361    Executes the change state machine, until the OP state is set.
  1348 */
  1362 */
  1349 
  1363 
  1350 void ec_fsm_slave_op2(ec_fsm_t *fsm /**< finite state machine */)
  1364 void ec_fsm_slaveconf_op2(ec_fsm_t *fsm /**< finite state machine */)
  1351 {
  1365 {
  1352     fsm->change_state(fsm); // execute state change state machine
  1366     fsm->change_state(fsm); // execute state change state machine
  1353 
  1367 
  1354     if (fsm->change_state == ec_fsm_change_error) {
  1368     if (fsm->change_state == ec_fsm_change_error) {
  1355         fsm->slave->error_flag = 1;
  1369         fsm->slave->error_flag = 1;
  1356         fsm->slave_state = ec_fsm_slave_end;
  1370         fsm->slave_state = ec_fsm_slaveconf_end;
  1357         return;
  1371         return;
  1358     }
  1372     }
  1359 
  1373 
  1360     if (fsm->change_state != ec_fsm_change_end) return;
  1374     if (fsm->change_state != ec_fsm_change_end) return;
  1361 
  1375 
  1362     // slave is now in OP
  1376     // slave is now in OP
  1363     fsm->slave_state = ec_fsm_slave_end; // successful
  1377     fsm->slave_state = ec_fsm_slaveconf_end; // successful
  1364 }
  1378 }
  1365 
  1379 
  1366 /*****************************************************************************/
  1380 /*****************************************************************************/
  1367 
  1381 
  1368 /**
  1382 /**
  1369    Slave state: END.
  1383    Slave state: END.
  1370    End state of the slave state machine.
  1384    End state of the slave state machine.
  1371 */
  1385 */
  1372 
  1386 
  1373 void ec_fsm_slave_end(ec_fsm_t *fsm /**< finite state machine */)
  1387 void ec_fsm_slaveconf_end(ec_fsm_t *fsm /**< finite state machine */)
  1374 {
  1388 {
  1375 }
  1389 }
  1376 
  1390 
  1377 /******************************************************************************
  1391 /******************************************************************************
  1378  *  SII state machine
  1392  *  SII sub state machine
  1379  *****************************************************************************/
  1393  *****************************************************************************/
  1380 
  1394 
  1381 /**
  1395 /**
  1382    SII state: START_READING.
  1396    SII state: START_READING.
  1383    Starts reading the slave information interface.
  1397    Starts reading the slave information interface.
  1590 void ec_fsm_sii_error(ec_fsm_t *fsm /**< finite state machine */)
  1604 void ec_fsm_sii_error(ec_fsm_t *fsm /**< finite state machine */)
  1591 {
  1605 {
  1592 }
  1606 }
  1593 
  1607 
  1594 /******************************************************************************
  1608 /******************************************************************************
  1595  *  state change state machine
  1609  *  state change sub state machine
  1596  *****************************************************************************/
  1610  *****************************************************************************/
  1597 
  1611 
  1598 /**
  1612 /**
  1599    Change state: START.
  1613    Change state: START.
  1600 */
  1614 */