master/fsm_master.c
changeset 601 d6d951b766e3
parent 594 07dd2a7df66e
child 603 7f281d7372c6
equal deleted inserted replaced
600:b0660152f710 601:d6d951b766e3
   273 }
   273 }
   274 
   274 
   275 /*****************************************************************************/
   275 /*****************************************************************************/
   276 
   276 
   277 /**
   277 /**
       
   278  * Check for pending EEPROM write requests and process one.
       
   279  * \return non-zero, if an EEPROM write request is processed.
       
   280  */
       
   281 
       
   282 int ec_fsm_master_action_process_eeprom(
       
   283         ec_fsm_master_t *fsm /**< master state machine */
       
   284         )
       
   285 {
       
   286     ec_master_t *master = fsm->master;
       
   287     ec_eeprom_write_request_t *request;
       
   288     ec_slave_t *slave;
       
   289 
       
   290     down(&master->eeprom_sem);
       
   291     list_for_each_entry(request, &master->eeprom_requests, list) {
       
   292         list_del_init(&request->list); // dequeue
       
   293         up(&master->eeprom_sem);
       
   294 
       
   295         slave = request->slave;
       
   296         if (!slave->online || slave->error_flag) {
       
   297             EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
       
   298                     slave->ring_position);
       
   299             request->state = EC_EEPROM_REQ_ERROR;
       
   300             wake_up_interruptible(&master->eeprom_queue);
       
   301             down(&master->eeprom_sem);
       
   302             continue;
       
   303         }
       
   304 
       
   305         // found pending EEPROM write operation. execute it!
       
   306         EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
       
   307         fsm->eeprom_request = request;
       
   308         fsm->eeprom_index = 0;
       
   309         ec_fsm_sii_write(&fsm->fsm_sii, request->slave, request->offset,
       
   310                 request->words, EC_FSM_SII_NODE);
       
   311         fsm->state = ec_fsm_master_state_write_eeprom;
       
   312         fsm->state(fsm); // execute immediately
       
   313         return 1;
       
   314     }
       
   315 
       
   316     up(&master->eeprom_sem);
       
   317     return 0;
       
   318 }
       
   319 
       
   320 /*****************************************************************************/
       
   321 
       
   322 /**
   278    Master action: PROC_STATES.
   323    Master action: PROC_STATES.
   279    Processes the slave states.
   324    Processes the slave states.
   280 */
   325 */
   281 
   326 
   282 void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
   327 void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
   366             ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   411             ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   367             return;
   412             return;
   368         }
   413         }
   369 
   414 
   370         // check for pending EEPROM write operations.
   415         // check for pending EEPROM write operations.
   371         list_for_each_entry(slave, &master->slaves, list) {
   416         if (ec_fsm_master_action_process_eeprom(fsm))
   372             if (!slave->new_eeprom_data) continue;
   417             return; // EEPROM write request found
   373 
       
   374             if (!slave->online || slave->error_flag) {
       
   375                 kfree(slave->new_eeprom_data);
       
   376                 slave->new_eeprom_data = NULL;
       
   377                 EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
       
   378                        slave->ring_position);
       
   379                 continue;
       
   380             }
       
   381 
       
   382             // found pending EEPROM write operation. execute it!
       
   383             EC_INFO("Writing EEPROM of slave %i...\n", slave->ring_position);
       
   384             fsm->slave = slave;
       
   385             fsm->sii_offset = 0x0000;
       
   386             ec_fsm_sii_write(&fsm->fsm_sii, slave, fsm->sii_offset,
       
   387                              slave->new_eeprom_data, EC_FSM_SII_NODE);
       
   388             fsm->state = ec_fsm_master_state_write_eeprom;
       
   389             fsm->state(fsm); // execute immediately
       
   390             return;
       
   391         }
       
   392     }
   418     }
   393 
   419 
   394     fsm->state = ec_fsm_master_state_end;
   420     fsm->state = ec_fsm_master_state_end;
   395 }
   421 }
   396 
   422 
   749    Master state: WRITE EEPROM.
   775    Master state: WRITE EEPROM.
   750 */
   776 */
   751 
   777 
   752 void ec_fsm_master_state_write_eeprom(ec_fsm_master_t *fsm /**< master state machine */)
   778 void ec_fsm_master_state_write_eeprom(ec_fsm_master_t *fsm /**< master state machine */)
   753 {
   779 {
   754     ec_slave_t *slave = fsm->slave;
   780     ec_master_t *master = fsm->master;
       
   781     ec_eeprom_write_request_t *request = fsm->eeprom_request;
       
   782     ec_slave_t *slave = request->slave;
   755 
   783 
   756     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
   784     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
   757 
   785 
   758     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
   786     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
   759         fsm->slave->error_flag = 1;
   787         slave->error_flag = 1;
   760         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
   788         EC_ERR("Failed to write EEPROM contents to slave %i.\n",
   761                slave->ring_position);
   789                slave->ring_position);
   762         kfree(slave->new_eeprom_data);
   790         request->state = EC_EEPROM_REQ_ERROR;
   763         slave->new_eeprom_data = NULL;
   791         wake_up_interruptible(&master->eeprom_queue);
   764         fsm->state = ec_fsm_master_state_error;
   792         fsm->state = ec_fsm_master_state_error;
   765         return;
   793         return;
   766     }
   794     }
   767 
   795 
   768     fsm->sii_offset++;
   796     fsm->eeprom_index++;
   769     if (fsm->sii_offset < slave->new_eeprom_size) {
   797     if (fsm->eeprom_index < request->size) {
   770         ec_fsm_sii_write(&fsm->fsm_sii, slave, fsm->sii_offset,
   798         ec_fsm_sii_write(&fsm->fsm_sii, slave,
   771                          slave->new_eeprom_data + fsm->sii_offset,
   799                 request->offset + fsm->eeprom_index,
   772                          EC_FSM_SII_NODE);
   800                 request->words + fsm->eeprom_index,
       
   801                 EC_FSM_SII_NODE);
   773         ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
   802         ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
   774         return;
   803         return;
   775     }
   804     }
   776 
   805 
   777     // finished writing EEPROM
   806     // finished writing EEPROM
   778     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
   807     EC_INFO("Finished writing EEPROM of slave %i.\n", slave->ring_position);
   779     kfree(slave->new_eeprom_data);
   808     request->state = EC_EEPROM_REQ_COMPLETED;
   780     slave->new_eeprom_data = NULL;
   809     wake_up_interruptible(&master->eeprom_queue);
   781 
   810 
   782     // TODO: Evaluate new EEPROM contents!
   811     // TODO: Evaluate new EEPROM contents!
       
   812 
       
   813     // check for another EEPROM write request
       
   814     if (ec_fsm_master_action_process_eeprom(fsm))
       
   815         return; // processing another request
   783 
   816 
   784     // restart master state machine.
   817     // restart master state machine.
   785     fsm->state = ec_fsm_master_state_start;
   818     fsm->state = ec_fsm_master_state_start;
   786     fsm->state(fsm); // execute immediately
   819     fsm->state(fsm); // execute immediately
   787 }
   820 }