master/fsm_master.c
branchstable-1.5
changeset 2453 d461b1f07296
parent 2448 41dc9a4a0f76
child 2456 a9bbc44584e0
equal deleted inserted replaced
2452:abc1d1caead7 2453:d461b1f07296
    84     fsm->master = master;
    84     fsm->master = master;
    85     fsm->datagram = datagram;
    85     fsm->datagram = datagram;
    86     fsm->state = ec_fsm_master_state_start;
    86     fsm->state = ec_fsm_master_state_start;
    87     fsm->idle = 0;
    87     fsm->idle = 0;
    88     fsm->dev_idx = EC_DEVICE_MAIN;
    88     fsm->dev_idx = EC_DEVICE_MAIN;
    89     for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
    89     for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
       
    90             dev_idx++) {
    90         fsm->link_state[dev_idx] = 0;
    91         fsm->link_state[dev_idx] = 0;
    91         fsm->slaves_responding[dev_idx] = 0;
    92         fsm->slaves_responding[dev_idx] = 0;
    92         fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN;
    93         fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN;
    93     }
    94     }
    94     fsm->rescan_required = 0;
    95     fsm->rescan_required = 0;
   207     if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
   208     if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
   208         fsm->rescan_required = 1;
   209         fsm->rescan_required = 1;
   209         fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter;
   210         fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter;
   210         EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n",
   211         EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n",
   211                 fsm->slaves_responding[fsm->dev_idx],
   212                 fsm->slaves_responding[fsm->dev_idx],
   212                 ec_device_names[fsm->dev_idx]);
   213                 ec_device_names[fsm->dev_idx != 0]);
   213     }
   214     }
   214 
   215 
   215     if (fsm->link_state[fsm->dev_idx] &&
   216     if (fsm->link_state[fsm->dev_idx] &&
   216             !master->devices[fsm->dev_idx].link_state) {
   217             !master->devices[fsm->dev_idx].link_state) {
   217         ec_device_index_t dev_idx;
   218         ec_device_index_t dev_idx;
   218 
   219 
   219         EC_MASTER_DBG(master, 1, "Master state machine detected "
   220         EC_MASTER_DBG(master, 1, "Master state machine detected "
   220                 "link down on %s device. Clearing slave list.\n",
   221                 "link down on %s device. Clearing slave list.\n",
   221                 ec_device_names[fsm->dev_idx]);
   222                 ec_device_names[fsm->dev_idx != 0]);
   222 
   223 
   223 #ifdef EC_EOE
   224 #ifdef EC_EOE
   224         ec_master_eoe_stop(master);
   225         ec_master_eoe_stop(master);
   225         ec_master_clear_eoe_handlers(master);
   226         ec_master_clear_eoe_handlers(master);
   226 #endif
   227 #endif
   227         ec_master_clear_slaves(master);
   228         ec_master_clear_slaves(master);
   228 
   229 
   229         for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) {
   230         for (dev_idx = EC_DEVICE_MAIN;
       
   231                 dev_idx < ec_master_num_devices(master); dev_idx++) {
   230             fsm->slave_states[dev_idx] = 0x00;
   232             fsm->slave_states[dev_idx] = 0x00;
   231             fsm->slaves_responding[dev_idx] = 0; /* Reset to trigger rescan on
   233             fsm->slaves_responding[dev_idx] = 0; /* Reset to trigger rescan on
   232                                                     next link up. */
   234                                                     next link up. */
   233         }
   235         }
   234     }
   236     }
   241             // slave states changed
   243             // slave states changed
   242             char state_str[EC_STATE_STRING_SIZE];
   244             char state_str[EC_STATE_STRING_SIZE];
   243             fsm->slave_states[fsm->dev_idx] = states;
   245             fsm->slave_states[fsm->dev_idx] = states;
   244             ec_state_string(states, state_str, 1);
   246             ec_state_string(states, state_str, 1);
   245             EC_MASTER_INFO(master, "Slave states on %s device: %s.\n",
   247             EC_MASTER_INFO(master, "Slave states on %s device: %s.\n",
   246                     ec_device_names[fsm->dev_idx], state_str);
   248                     ec_device_names[fsm->dev_idx != 0], state_str);
   247         }
   249         }
   248     } else {
   250     } else {
   249         fsm->slave_states[fsm->dev_idx] = 0x00;
   251         fsm->slave_states[fsm->dev_idx] = 0x00;
   250     }
   252     }
   251 
   253 
   252     fsm->dev_idx++;
   254     fsm->dev_idx++;
   253     if (fsm->dev_idx < EC_NUM_DEVICES) {
   255     if (fsm->dev_idx < ec_master_num_devices(master)) {
   254         // check number of responding slaves on next device
   256         // check number of responding slaves on next device
   255         fsm->state = ec_fsm_master_state_start;
   257         fsm->state = ec_fsm_master_state_start;
   256         fsm->state(fsm); // execute immediately
   258         fsm->state(fsm); // execute immediately
   257         return;
   259         return;
   258     }
   260     }
   277             ec_master_eoe_stop(master);
   279             ec_master_eoe_stop(master);
   278             ec_master_clear_eoe_handlers(master);
   280             ec_master_clear_eoe_handlers(master);
   279 #endif
   281 #endif
   280             ec_master_clear_slaves(master);
   282             ec_master_clear_slaves(master);
   281 
   283 
   282             for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES;
   284             for (dev_idx = EC_DEVICE_MAIN;
   283                     dev_idx++) {
   285                     dev_idx < ec_master_num_devices(master); dev_idx++) {
   284                 count += fsm->slaves_responding[dev_idx];
   286                 count += fsm->slaves_responding[dev_idx];
   285             }
   287             }
   286 
   288 
   287             if (!count) {
   289             if (!count) {
   288                 // no slaves present -> finish state machine.
   290                 // no slaves present -> finish state machine.
   706     }
   708     }
   707 
   709 
   708     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   710     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   709         EC_MASTER_ERR(master, "Failed to receive address"
   711         EC_MASTER_ERR(master, "Failed to receive address"
   710                 " clearing datagram on %s link: ",
   712                 " clearing datagram on %s link: ",
   711                 ec_device_names[fsm->dev_idx]);
   713                 ec_device_names[fsm->dev_idx != 0]);
   712         ec_datagram_print_state(datagram);
   714         ec_datagram_print_state(datagram);
   713         master->scan_busy = 0;
   715         master->scan_busy = 0;
   714         wake_up_interruptible(&master->scan_queue);
   716         wake_up_interruptible(&master->scan_queue);
   715         ec_fsm_master_restart(fsm);
   717         ec_fsm_master_restart(fsm);
   716         return;
   718         return;
   717     }
   719     }
   718 
   720 
   719     if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
   721     if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) {
   720         EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:"
   722         EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:"
   721                 " Cleared %u of %u",
   723                 " Cleared %u of %u",
   722                 ec_device_names[fsm->dev_idx], datagram->working_counter,
   724                 ec_device_names[fsm->dev_idx != 0], datagram->working_counter,
   723                 fsm->slaves_responding[fsm->dev_idx]);
   725                 fsm->slaves_responding[fsm->dev_idx]);
   724     }
   726     }
   725 
   727 
   726     EC_MASTER_DBG(master, 1, "Sending broadcast-write"
   728     EC_MASTER_DBG(master, 1, "Sending broadcast-write"
   727             " to measure transmission delays on %s link.\n",
   729             " to measure transmission delays on %s link.\n",
   728             ec_device_names[fsm->dev_idx]);
   730             ec_device_names[fsm->dev_idx != 0]);
   729 
   731 
   730     ec_datagram_bwr(datagram, 0x0900, 1);
   732     ec_datagram_bwr(datagram, 0x0900, 1);
   731     ec_datagram_zero(datagram);
   733     ec_datagram_zero(datagram);
   732     fsm->datagram->device_index = fsm->dev_idx;
   734     fsm->datagram->device_index = fsm->dev_idx;
   733     fsm->retries = EC_FSM_RETRIES;
   735     fsm->retries = EC_FSM_RETRIES;
   748     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   750     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   749         return;
   751         return;
   750 
   752 
   751     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   753     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   752         EC_MASTER_ERR(master, "Failed to receive delay measuring datagram"
   754         EC_MASTER_ERR(master, "Failed to receive delay measuring datagram"
   753                 " on %s link: ", ec_device_names[fsm->dev_idx]);
   755                 " on %s link: ", ec_device_names[fsm->dev_idx != 0]);
   754         ec_datagram_print_state(datagram);
   756         ec_datagram_print_state(datagram);
   755         master->scan_busy = 0;
   757         master->scan_busy = 0;
   756         wake_up_interruptible(&master->scan_queue);
   758         wake_up_interruptible(&master->scan_queue);
   757         ec_fsm_master_restart(fsm);
   759         ec_fsm_master_restart(fsm);
   758         return;
   760         return;
   759     }
   761     }
   760 
   762 
   761     EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring"
   763     EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring"
   762             " on %s link.\n",
   764             " on %s link.\n",
   763             datagram->working_counter, ec_device_names[fsm->dev_idx]);
   765             datagram->working_counter, ec_device_names[fsm->dev_idx != 0]);
   764 
   766 
   765     do {
   767     do {
   766         fsm->dev_idx++;
   768         fsm->dev_idx++;
   767     } while (fsm->dev_idx < EC_NUM_DEVICES &&
   769     } while (fsm->dev_idx < ec_master_num_devices(master) &&
   768             !fsm->slaves_responding[fsm->dev_idx]);
   770             !fsm->slaves_responding[fsm->dev_idx]);
   769     if (fsm->dev_idx < EC_NUM_DEVICES) {
   771     if (fsm->dev_idx < ec_master_num_devices(master)) {
   770         ec_fsm_master_enter_clear_addresses(fsm);
   772         ec_fsm_master_enter_clear_addresses(fsm);
   771         return;
   773         return;
   772     }
   774     }
   773 
   775 
   774     EC_MASTER_INFO(master, "Scanning bus.\n");
   776     EC_MASTER_INFO(master, "Scanning bus.\n");
   775 
   777 
   776     // begin scanning of slaves
   778     // begin scanning of slaves
   777     fsm->slave = master->slaves;
   779     fsm->slave = master->slaves;
   778     EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
   780     EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
   779             fsm->slave->ring_position,
   781             fsm->slave->ring_position,
   780             ec_device_names[fsm->slave->device_index]);
   782             ec_device_names[fsm->slave->device_index != 0]);
   781     fsm->state = ec_fsm_master_state_scan_slave;
   783     fsm->state = ec_fsm_master_state_scan_slave;
   782     ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave);
   784     ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave);
   783     ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
   785     ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
   784     fsm->datagram->device_index = fsm->slave->device_index;
   786     fsm->datagram->device_index = fsm->slave->device_index;
   785 }
   787 }
   821     // another slave to fetch?
   823     // another slave to fetch?
   822     fsm->slave++;
   824     fsm->slave++;
   823     if (fsm->slave < master->slaves + master->slave_count) {
   825     if (fsm->slave < master->slaves + master->slave_count) {
   824         EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
   826         EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n",
   825                 fsm->slave->ring_position,
   827                 fsm->slave->ring_position,
   826                 ec_device_names[fsm->slave->device_index]);
   828                 ec_device_names[fsm->slave->device_index != 0]);
   827         ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave);
   829         ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave);
   828         ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
   830         ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately
   829         fsm->datagram->device_index = fsm->slave->device_index;
   831         fsm->datagram->device_index = fsm->slave->device_index;
   830         return;
   832         return;
   831     }
   833     }