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 } |