# HG changeset patch # User Florian Pose # Date 1204045100 0 # Node ID ded9519c8d6e686cf62210712fb4c1400729379f # Parent d83d92e1a91947f70223477048731f7cad3c933d Reading of Pdo mapping via CoE during scan. diff -r d83d92e1a919 -r ded9519c8d6e NEWS --- a/NEWS Tue Feb 26 13:20:32 2008 +0000 +++ b/NEWS Tue Feb 26 16:58:20 2008 +0000 @@ -41,7 +41,10 @@ be reached by specifying an explicit Pdo mapping and registering those Pdo entries. * Pdo configuration is now supported. +* Current Pdo mapping/configuration is now read during bus scan, without + using the Sdo dictionary. * Added 8139too driver for kernel 2.6.22, thanks to Erwin Burgstaller. +* Added 8139too driver for kernel 2.6.23, thanks to Richard Hacker. * Added e1000 driver for kernel 2.6.22. * Added support for slaves that do not support the LRW datagram type. Separate domains have to be used for inputs and output. diff -r d83d92e1a919 -r ded9519c8d6e TODO --- a/TODO Tue Feb 26 13:20:32 2008 +0000 +++ b/TODO Tue Feb 26 16:58:20 2008 +0000 @@ -8,7 +8,6 @@ Version 1.4.0: -* Read PDO mapping via CoE during bus scan. * Realtime interface changes: - SDO access. * Mailbox handler @@ -18,9 +17,8 @@ * Remove ecdb.h and let lsec output PDO information 'cut-and-pastable' for applications. * SDO write access in sysfs. +* Distributed clocks. * Update documentation. -* Distributed clocks. -* Safety-over-EtherCAT Future issues: @@ -29,6 +27,8 @@ to replace lsec. - Step 2: Move kernel threads to user space daemon with a TCP interface replacing the cdev. +* Mailbox gateway. +* Slave-to-slave communication. * Redundancy with 2 network adapters. * Interface/buffers for asynchronous domain IO. diff -r d83d92e1a919 -r ded9519c8d6e documentation/graphs/fsm_master.dot --- a/documentation/graphs/fsm_master.dot Tue Feb 26 13:20:32 2008 +0000 +++ b/documentation/graphs/fsm_master.dot Tue Feb 26 16:58:20 2008 +0000 @@ -26,16 +26,16 @@ action_configure -> configure_slave + action_process_states -> action_configure + action_process_states -> action_process_sdo + action_process_states -> sdodict + action_process_states -> action_process_eeprom + action_process_states -> end + action_next_slave_state -> read_states action_next_slave_state -> validate_vendor action_next_slave_state -> action_process_states - action_process_states -> action_configure - action_process_states -> action_process_sdo - action_process_states -> action_process_eeprom - action_process_states -> sdodict - action_process_states -> end - //read_states -> error read_states -> action_next_slave_state read_states -> acknowledge @@ -50,8 +50,8 @@ action_addresses -> rewrite_addresses //validate_product -> error + validate_product -> action_addresses validate_product -> validate_vendor - validate_product -> action_addresses //rewrite_addresses -> error rewrite_addresses -> end @@ -67,6 +67,7 @@ configure_slave -> end //write_eeprom -> error + write_eeprom -> action_process_eeprom write_eeprom -> end //sdodict -> error diff -r d83d92e1a919 -r ded9519c8d6e master/canopen.c --- a/master/canopen.c Tue Feb 26 13:20:32 2008 +0000 +++ b/master/canopen.c Tue Feb 26 16:58:20 2008 +0000 @@ -416,7 +416,8 @@ off_t off = 0; ec_sdo_request_t request; - ec_sdo_request_init_read(&request, entry); + ec_sdo_request_init_read(&request, entry->sdo->slave, + entry->sdo->index, entry->subindex); // schedule request. down(&master->sdo_sem); @@ -479,11 +480,16 @@ Sdo request constructor. */ -void ec_sdo_request_init_read(ec_sdo_request_t *req, /**< Sdo request */ - ec_sdo_entry_t *entry /**< Sdo entry */ - ) -{ - req->entry = entry; +void ec_sdo_request_init_read( + ec_sdo_request_t *req, /**< Sdo request */ + ec_slave_t *slave, /**< Slave owning the Sdo. */ + uint16_t index, /**< Sdo index. */ + uint8_t subindex /**< Sdo subindex. */ + ) +{ + req->slave = slave; + req->index = index; + req->subindex = subindex; req->data = NULL; req->size = 0; req->state = EC_REQUEST_QUEUED; diff -r d83d92e1a919 -r ded9519c8d6e master/canopen.h --- a/master/canopen.h Tue Feb 26 13:20:32 2008 +0000 +++ b/master/canopen.h Tue Feb 26 16:58:20 2008 +0000 @@ -49,12 +49,9 @@ /*****************************************************************************/ -/** - CANopen Sdo. -*/ - -struct ec_sdo -{ +/** CANopen Sdo. + */ +struct ec_sdo { struct kobject kobj; /**< kobject */ struct list_head list; /**< list item */ ec_slave_t *slave; /**< parent slave */ @@ -67,12 +64,9 @@ /*****************************************************************************/ -/** - CANopen Sdo entry. -*/ - -typedef struct -{ +/** CANopen Sdo entry. + */ +typedef struct { struct kobject kobj; /**< kobject */ struct list_head list; /**< list item */ ec_sdo_t *sdo; /**< parent Sdo */ @@ -80,17 +74,13 @@ uint16_t data_type; /**< entry data type */ uint16_t bit_length; /**< entry length in bit */ char *description; /**< entry description */ -} -ec_sdo_entry_t; +} ec_sdo_entry_t; /*****************************************************************************/ -/** - CANopen Sdo configuration data. -*/ - -typedef struct -{ +/** CANopen Sdo configuration data. + */ +typedef struct { struct list_head list; /**< list item */ uint16_t index; /**< Sdo index */ uint8_t subindex; /**< Sdo subindex */ @@ -105,15 +95,15 @@ CANopen Sdo request. */ -typedef struct -{ +typedef struct { struct list_head list; /**< list item */ - ec_sdo_entry_t *entry; /**< Sdo entry */ + ec_slave_t *slave; /**< Slave owning the Sdo. */ + uint16_t index; /**< Sdo index. */ + uint8_t subindex; /**< Sdo subindex. */ uint8_t *data; /**< pointer to Sdo data */ size_t size; /**< size of Sdo data */ ec_request_state_t state; /**< Sdo request state */ -} -ec_sdo_request_t; +} ec_sdo_request_t; /*****************************************************************************/ @@ -124,7 +114,8 @@ int ec_sdo_entry_init(ec_sdo_entry_t *, uint8_t, ec_sdo_t *); void ec_sdo_entry_destroy(ec_sdo_entry_t *); -void ec_sdo_request_init_read(ec_sdo_request_t *, ec_sdo_entry_t *); +void ec_sdo_request_init_read(ec_sdo_request_t *, ec_slave_t *, uint16_t, + uint8_t); void ec_sdo_request_clear(ec_sdo_request_t *); /*****************************************************************************/ diff -r d83d92e1a919 -r ded9519c8d6e master/fsm_coe.c --- a/master/fsm_coe.c Tue Feb 26 13:20:32 2008 +0000 +++ b/master/fsm_coe.c Tue Feb 26 16:58:20 2008 +0000 @@ -1175,12 +1175,11 @@ ec_slave_t *slave = fsm->slave; ec_master_t *master = slave->master; ec_sdo_request_t *request = fsm->request; - ec_sdo_entry_t *entry = request->entry; uint8_t *data; if (master->debug_level) EC_DBG("Uploading Sdo 0x%04X:%i from slave %i.\n", - entry->sdo->index, entry->subindex, slave->ring_position); + request->index, request->subindex, slave->ring_position); if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)) { EC_ERR("Slave %u does not support CoE!\n", slave->ring_position); @@ -1195,8 +1194,8 @@ EC_WRITE_U16(data, 0x2 << 12); // Sdo request EC_WRITE_U8 (data + 2, 0x2 << 5); // initiate upload request - EC_WRITE_U16(data + 3, entry->sdo->index); - EC_WRITE_U8 (data + 5, entry->subindex); + EC_WRITE_U16(data + 3, request->index); + EC_WRITE_U8 (data + 5, request->subindex); memset(data + 6, 0x00, 4); if (master->debug_level) { @@ -1311,7 +1310,6 @@ uint8_t *data, mbox_prot; size_t rec_size, data_size; ec_sdo_request_t *request = fsm->request; - ec_sdo_entry_t *entry = request->entry; uint32_t complete_size; unsigned int expedited, size_specified; @@ -1361,7 +1359,7 @@ if (EC_READ_U16(data) >> 12 == 0x2 && // Sdo request EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request EC_ERR("Sdo upload 0x%04X:%X aborted on slave %i.\n", - entry->sdo->index, entry->subindex, slave->ring_position); + request->index, request->subindex, slave->ring_position); if (rec_size >= 10) ec_canopen_abort_msg(EC_READ_U32(data + 6)); else @@ -1390,9 +1388,10 @@ if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response - EC_READ_U16(data + 3) != entry->sdo->index || // index - EC_READ_U8 (data + 5) != entry->subindex) { // subindex - EC_ERR("Sdo upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex); + EC_READ_U16(data + 3) != request->index || // index + EC_READ_U8 (data + 5) != request->subindex) { // subindex + EC_ERR("Sdo upload 0x%04X:%X failed:\n", + request->index, request->subindex); EC_ERR("Invalid Sdo upload response at slave %i!\n", slave->ring_position); ec_print_data(data, rec_size); @@ -1438,9 +1437,10 @@ if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response - EC_READ_U16(data + 3) != entry->sdo->index || // index - EC_READ_U8 (data + 5) != entry->subindex) { // subindex - EC_ERR("Sdo upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex); + EC_READ_U16(data + 3) != request->index || // index + EC_READ_U8 (data + 5) != request->subindex) { // subindex + EC_ERR("Sdo upload 0x%04X:%X failed:\n", + request->index, request->subindex); EC_ERR("Invalid Sdo upload response at slave %i!\n", slave->ring_position); ec_print_data(data, rec_size); @@ -1602,7 +1602,6 @@ uint8_t *data, mbox_prot; size_t rec_size, data_size; ec_sdo_request_t *request = fsm->request; - ec_sdo_entry_t *entry = request->entry; uint32_t seg_size; unsigned int last_segment; @@ -1652,7 +1651,7 @@ if (EC_READ_U16(data) >> 12 == 0x2 && // Sdo request EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request EC_ERR("Sdo upload 0x%04X:%X aborted on slave %i.\n", - entry->sdo->index, entry->subindex, slave->ring_position); + request->index, request->subindex, slave->ring_position); ec_canopen_abort_msg(EC_READ_U32(data + 6)); fsm->state = ec_fsm_coe_error; return; @@ -1660,7 +1659,7 @@ if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response EC_READ_U8 (data + 2) >> 5 != 0x0) { // upload segment response - EC_ERR("Sdo upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex); + EC_ERR("Sdo upload 0x%04X:%X failed:\n", request->index, request->subindex); EC_ERR("Invalid Sdo upload segment response at slave %i!\n", slave->ring_position); ec_print_data(data, rec_size); diff -r d83d92e1a919 -r ded9519c8d6e master/fsm_coe_map.c --- a/master/fsm_coe_map.c Tue Feb 26 13:20:32 2008 +0000 +++ b/master/fsm_coe_map.c Tue Feb 26 16:58:20 2008 +0000 @@ -55,7 +55,7 @@ void ec_fsm_coe_map_state_end(ec_fsm_coe_map_t *); void ec_fsm_coe_map_state_error(ec_fsm_coe_map_t *); -void ec_fsm_coe_map_action_next_sync(ec_fsm_coe_map_t *); +void ec_fsm_coe_map_action_next_dir(ec_fsm_coe_map_t *); void ec_fsm_coe_map_action_next_pdo(ec_fsm_coe_map_t *); void ec_fsm_coe_map_action_next_pdo_entry(ec_fsm_coe_map_t *); @@ -140,49 +140,56 @@ ec_fsm_coe_map_t *fsm /**< finite state machine */ ) { - // read mapping of first sync manager - fsm->sync_index = 0; - ec_fsm_coe_map_action_next_sync(fsm); -} - -/*****************************************************************************/ - -/** - * Read mapping of next sync manager. - */ - -void ec_fsm_coe_map_action_next_sync( + // read mapping for first direction + fsm->dir = (ec_direction_t) -1; // next is EC_DIR_OUTPUT + ec_fsm_coe_map_action_next_dir(fsm); +} + +/*****************************************************************************/ + +/** + * Read mapping of next direction manager. + */ + +void ec_fsm_coe_map_action_next_dir( ec_fsm_coe_map_t *fsm /**< finite state machine */ ) { ec_slave_t *slave = fsm->slave; - ec_sdo_entry_t *entry; - - for (; fsm->sync_index < slave->sii_sync_count; fsm->sync_index++) { - if (!(fsm->sync_sdo = ec_slave_get_sdo(slave, 0x1C10 + fsm->sync_index))) + + fsm->dir++; + + if (slave->master->debug_level) + EC_DBG("Processing dir %u of slave %u.\n", + fsm->dir, slave->ring_position); + + for (; fsm->dir <= EC_DIR_INPUT; fsm->dir++) { + + if (!(fsm->sync = ec_slave_get_pdo_sync(slave, fsm->dir))) { + if (slave->master->debug_level) + EC_DBG("No sync manager for direction %u!\n", fsm->dir); continue; + } + + fsm->sync_sdo_index = 0x1C10 + fsm->sync->index; if (slave->master->debug_level) EC_DBG("Reading Pdo mapping of sync manager %u of slave %u.\n", - fsm->sync_index, slave->ring_position); + fsm->sync->index, slave->ring_position); ec_pdo_mapping_clear_pdos(&fsm->mapping); - if (!(entry = ec_sdo_get_entry(fsm->sync_sdo, 0))) { - EC_ERR("Sdo 0x%04X has no subindex 0 on slave %u.\n", - fsm->sync_sdo->index, - fsm->slave->ring_position); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - ec_sdo_request_init_read(&fsm->request, entry); + ec_sdo_request_init_read(&fsm->request, slave, fsm->sync_sdo_index, 0); fsm->state = ec_fsm_coe_map_state_pdo_count; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately return; } + if (slave->master->debug_level) + EC_DBG("Reading of Pdo mapping finished for slave %u.\n", + slave->ring_position); + fsm->state = ec_fsm_coe_map_state_end; } @@ -225,41 +232,27 @@ ec_fsm_coe_map_t *fsm /**< finite state machine */ ) { - ec_sdo_entry_t *entry; - if (fsm->sync_subindex <= fsm->sync_subindices) { - if (!(entry = ec_sdo_get_entry(fsm->sync_sdo, - fsm->sync_subindex))) { - EC_ERR("Sdo 0x%04X has no subindex %u on slave %u.\n", - fsm->sync_sdo->index, - fsm->sync_subindex, - fsm->slave->ring_position); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - ec_sdo_request_init_read(&fsm->request, entry); + ec_sdo_request_init_read(&fsm->request, fsm->slave, + fsm->sync_sdo_index, fsm->sync_subindex); fsm->state = ec_fsm_coe_map_state_pdo; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately return; } - { - ec_sync_t *sync = fsm->slave->sii_syncs + fsm->sync_index; - - if (ec_pdo_mapping_copy(&sync->mapping, &fsm->mapping)) { - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - sync->mapping_source = EC_SYNC_MAPPING_COE; - ec_pdo_mapping_clear_pdos(&fsm->mapping); - - // next sync manager - fsm->sync_index++; - ec_fsm_coe_map_action_next_sync(fsm); - } + // finished reading Pdo mapping/configuration + + if (ec_pdo_mapping_copy(&fsm->sync->mapping, &fsm->mapping)) { + fsm->state = ec_fsm_coe_map_state_error; + return; + } + + fsm->sync->mapping_source = EC_SYNC_MAPPING_COE; + ec_pdo_mapping_clear_pdos(&fsm->mapping); + + // next direction + ec_fsm_coe_map_action_next_dir(fsm); } /*****************************************************************************/ @@ -281,58 +274,26 @@ return; } - { - ec_sdo_entry_t *entry; - - if (!(fsm->pdo = (ec_pdo_t *) - kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) { - EC_ERR("Failed to allocate Pdo.\n"); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - ec_pdo_init(fsm->pdo); - fsm->pdo->index = EC_READ_U16(fsm->request.data); - fsm->pdo->dir = - ec_sync_direction(fsm->slave->sii_syncs + fsm->sync_index); - - if (fsm->slave->master->debug_level) - EC_DBG(" Pdo 0x%04X.\n", fsm->pdo->index); - - if (!(fsm->pdo_sdo = ec_slave_get_sdo(fsm->slave, fsm->pdo->index))) { - EC_ERR("Slave %u has no Sdo 0x%04X.\n", - fsm->slave->ring_position, fsm->pdo->index); - ec_pdo_clear(fsm->pdo); - kfree(fsm->pdo); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - if (ec_pdo_set_name(fsm->pdo, fsm->pdo_sdo->name)) { - ec_pdo_clear(fsm->pdo); - kfree(fsm->pdo); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - if (!(entry = ec_sdo_get_entry(fsm->pdo_sdo, 0))) { - EC_ERR("Sdo 0x%04X has no subindex 0 on slave %u.\n", - fsm->pdo_sdo->index, - fsm->slave->ring_position); - ec_pdo_clear(fsm->pdo); - kfree(fsm->pdo); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos); - - ec_sdo_request_init_read(&fsm->request, entry); - fsm->state = ec_fsm_coe_map_state_pdo_entry_count; - ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); - ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately - return; - } + if (!(fsm->pdo = (ec_pdo_t *) + kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate Pdo.\n"); + fsm->state = ec_fsm_coe_map_state_error; + return; + } + + ec_pdo_init(fsm->pdo); + fsm->pdo->index = EC_READ_U16(fsm->request.data); + fsm->pdo->dir = ec_sync_direction(fsm->sync); + + if (fsm->slave->master->debug_level) + EC_DBG(" Pdo 0x%04X.\n", fsm->pdo->index); + + list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos); + + ec_sdo_request_init_read(&fsm->request, fsm->slave, fsm->pdo->index, 0); + fsm->state = ec_fsm_coe_map_state_pdo_entry_count; + ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); + ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately } /*****************************************************************************/ @@ -374,19 +335,9 @@ ec_fsm_coe_map_t *fsm /**< finite state machine */ ) { - ec_sdo_entry_t *entry; - if (fsm->pdo_subindex <= fsm->pdo_subindices) { - if (!(entry = ec_sdo_get_entry(fsm->pdo_sdo, - fsm->pdo_subindex))) { - EC_ERR("Sdo 0x%04X has no subindex %u on slave %u.\n", - fsm->pdo_sdo->index, fsm->pdo_subindex, - fsm->slave->ring_position); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - ec_sdo_request_init_read(&fsm->request, entry); + ec_sdo_request_init_read(&fsm->request, fsm->slave, + fsm->pdo->index, fsm->pdo_subindex); fsm->state = ec_fsm_coe_map_state_pdo_entry; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately @@ -419,8 +370,6 @@ { uint32_t pdo_entry_info; - ec_sdo_t *sdo; - ec_sdo_entry_t *entry; ec_pdo_entry_t *pdo_entry; pdo_entry_info = EC_READ_U32(fsm->request.data); @@ -438,49 +387,12 @@ pdo_entry->bit_length = pdo_entry_info & 0xFF; if (!pdo_entry->index && !pdo_entry->subindex) { - // we have a gap in the Pdo, next Pdo entry - if (fsm->slave->master->debug_level) { - EC_DBG(" Pdo entry gap: %u bit.\n", - pdo_entry->bit_length); - } - if (ec_pdo_entry_set_name(pdo_entry, "Gap")) { ec_pdo_entry_clear(pdo_entry); kfree(pdo_entry); fsm->state = ec_fsm_coe_map_state_error; return; } - - list_add_tail(&pdo_entry->list, &fsm->pdo->entries); - fsm->pdo_subindex++; - ec_fsm_coe_map_action_next_pdo_entry(fsm); - return; - } - - if (!(sdo = ec_slave_get_sdo(fsm->slave, pdo_entry->index))) { - EC_ERR("Slave %u has no Sdo 0x%04X.\n", - fsm->slave->ring_position, pdo_entry->index); - ec_pdo_entry_clear(pdo_entry); - kfree(pdo_entry); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - if (!(entry = ec_sdo_get_entry(sdo, pdo_entry->subindex))) { - EC_ERR("Slave %u has no Sdo entry 0x%04X:%u.\n", - fsm->slave->ring_position, pdo_entry->index, - pdo_entry->subindex); - ec_pdo_entry_clear(pdo_entry); - kfree(pdo_entry); - fsm->state = ec_fsm_coe_map_state_error; - return; - } - - if (ec_pdo_entry_set_name(pdo_entry, entry->description)) { - ec_pdo_entry_clear(pdo_entry); - kfree(pdo_entry); - fsm->state = ec_fsm_coe_map_state_error; - return; } if (fsm->slave->master->debug_level) { @@ -489,9 +401,8 @@ pdo_entry->bit_length); } + // next Pdo entry list_add_tail(&pdo_entry->list, &fsm->pdo->entries); - - // next Pdo entry fsm->pdo_subindex++; ec_fsm_coe_map_action_next_pdo_entry(fsm); } diff -r d83d92e1a919 -r ded9519c8d6e master/fsm_coe_map.h --- a/master/fsm_coe_map.h Tue Feb 26 13:20:32 2008 +0000 +++ b/master/fsm_coe_map.h Tue Feb 26 16:58:20 2008 +0000 @@ -61,8 +61,9 @@ ec_slave_t *slave; /**< EtherCAT slave */ ec_sdo_request_t request; /**< Sdo request */ - unsigned int sync_index; /**< index of the current sync manager */ - ec_sdo_t *sync_sdo; /**< pointer to the sync managers mapping Sdo */ + ec_direction_t dir; /**< index of the current sync manager */ + ec_sync_t *sync; /**< Pdo sync manager. */ + uint16_t sync_sdo_index; /**< Index of the mapping Sdo. */ uint8_t sync_subindices; /**< number of mapped Pdos */ uint16_t sync_subindex; /**< current subindex in mapping Sdo */ diff -r d83d92e1a919 -r ded9519c8d6e master/fsm_master.c --- a/master/fsm_master.c Tue Feb 26 13:20:32 2008 +0000 +++ b/master/fsm_master.c Tue Feb 26 16:58:20 2008 +0000 @@ -60,7 +60,6 @@ void ec_fsm_master_state_scan_slaves(ec_fsm_master_t *); void ec_fsm_master_state_write_eeprom(ec_fsm_master_t *); void ec_fsm_master_state_sdodict(ec_fsm_master_t *); -void ec_fsm_master_state_pdomap(ec_fsm_master_t *); void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); void ec_fsm_master_state_end(ec_fsm_master_t *); void ec_fsm_master_state_error(ec_fsm_master_t *); @@ -88,7 +87,8 @@ // init sub-state-machines ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram); - ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram); + ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram, + &fsm->fsm_slave_config, &fsm->fsm_coe_map); ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram); ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram); @@ -387,7 +387,7 @@ request->state = EC_REQUEST_IN_PROGRESS; up(&master->sdo_sem); - slave = request->entry->sdo->slave; + slave = request->slave; if (slave->current_state == EC_SLAVE_STATE_INIT || slave->online_state == EC_SLAVE_OFFLINE || slave->error_flag) { @@ -526,29 +526,6 @@ return; } - // check, if slaves have their Pdo mapping to be read. - list_for_each_entry(slave, &master->slaves, list) { - if (!(slave->sii_mailbox_protocols & EC_MBOX_COE) - || slave->pdo_mapping_fetched - || !slave->sdo_dictionary_fetched - || slave->current_state == EC_SLAVE_STATE_INIT - || slave->online_state == EC_SLAVE_OFFLINE) continue; - - if (master->debug_level) { - EC_DBG("Fetching Pdo mapping from slave %i via CoE.\n", - slave->ring_position); - } - - slave->pdo_mapping_fetched = 1; - - // start fetching Pdo mapping - fsm->idle = 0; - fsm->state = ec_fsm_master_state_pdomap; - ec_fsm_coe_map_start(&fsm->fsm_coe_map, slave); - ec_fsm_coe_map_exec(&fsm->fsm_coe_map); // execute immediately - return; - } - // check for pending EEPROM write operations. if (ec_fsm_master_action_process_eeprom(fsm)) return; // EEPROM write request found @@ -1039,28 +1016,7 @@ /*****************************************************************************/ /** - * Scan the Pdo mapping of a slave. - */ - -void ec_fsm_master_state_pdomap( - ec_fsm_master_t *fsm /**< master state machine */ - ) -{ - if (ec_fsm_coe_map_exec(&fsm->fsm_coe_map)) return; - - if (!ec_fsm_coe_map_success(&fsm->fsm_coe_map)) { - fsm->state = ec_fsm_master_state_error; - return; - } - - // fetching of Pdo mapping finished - fsm->state = ec_fsm_master_state_end; -} - -/*****************************************************************************/ - -/** - Master state: Sdo REQUEST. + Master state: SDO REQUEST. */ void ec_fsm_master_state_sdo_request(ec_fsm_master_t *fsm /**< master state machine */) diff -r d83d92e1a919 -r ded9519c8d6e master/fsm_slave_scan.c --- a/master/fsm_slave_scan.c Tue Feb 26 13:20:32 2008 +0000 +++ b/master/fsm_slave_scan.c Tue Feb 26 16:58:20 2008 +0000 @@ -54,19 +54,31 @@ void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_eeprom_size(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_eeprom_data(ec_fsm_slave_scan_t *); +void ec_fsm_slave_scan_state_preop(ec_fsm_slave_scan_t *); +void ec_fsm_slave_scan_state_pdos(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *); +void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *); +void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *); + /*****************************************************************************/ /** Constructor. */ -void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *fsm, /**< slave state machine */ - ec_datagram_t *datagram /**< datagram structure to use */ +void ec_fsm_slave_scan_init( + ec_fsm_slave_scan_t *fsm, /**< Slave scanning state machine. */ + ec_datagram_t *datagram, /**< Datagram to use. */ + ec_fsm_slave_config_t *fsm_slave_config, /**< Slave configuration + state machine to use. */ + ec_fsm_coe_map_t *fsm_coe_map /**< Pdo mapping state machine to use. + */ ) { fsm->datagram = datagram; + fsm->fsm_slave_config = fsm_slave_config; + fsm->fsm_coe_map = fsm_coe_map; // init sub state machines ec_fsm_sii_init(&fsm->fsm_sii, fsm->datagram); @@ -556,7 +568,11 @@ } } - fsm->state = ec_fsm_slave_scan_state_end; + if (slave->sii_mailbox_protocols & EC_MBOX_COE) { + ec_fsm_slave_scan_enter_preop(fsm); + } else { + fsm->state = ec_fsm_slave_scan_state_end; + } return; end: @@ -565,6 +581,82 @@ fsm->state = ec_fsm_slave_scan_state_error; } +/*****************************************************************************/ + +void ec_fsm_slave_scan_enter_preop( + ec_fsm_slave_scan_t *fsm /**< slave state machine */ + ) +{ + ec_slave_t *slave = fsm->slave; + + if ((slave->current_state & EC_SLAVE_STATE_MASK) < EC_SLAVE_STATE_PREOP) { + if (slave->master->debug_level) + EC_DBG("Slave %u is not in the state to do mailbox com, setting" + " to PREOP.\n", slave->ring_position); + fsm->state = ec_fsm_slave_scan_state_preop; + ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); + ec_fsm_slave_config_start(fsm->fsm_slave_config, slave); + ec_fsm_slave_config_exec(fsm->fsm_slave_config); + } else { + ec_fsm_slave_scan_enter_pdos(fsm); + } +} + +/*****************************************************************************/ + +/** Slave scan state: PREOP. + */ +void ec_fsm_slave_scan_state_preop( + ec_fsm_slave_scan_t *fsm /**< slave state machine */ + ) +{ + if (ec_fsm_slave_config_exec(fsm->fsm_slave_config)) + return; + + if (!ec_fsm_slave_config_success(fsm->fsm_slave_config)) { + fsm->state = ec_fsm_slave_scan_state_error; + return; + } + + ec_fsm_slave_scan_enter_pdos(fsm); +} + +/*****************************************************************************/ + +void ec_fsm_slave_scan_enter_pdos( + ec_fsm_slave_scan_t *fsm /**< slave state machine */ + ) +{ + ec_slave_t *slave = fsm->slave; + + if (slave->master->debug_level) + EC_DBG("Scanning Pdo mapping/configuration of slave %u.\n", + slave->ring_position); + fsm->state = ec_fsm_slave_scan_state_pdos; + ec_fsm_coe_map_start(fsm->fsm_coe_map, slave); + ec_fsm_coe_map_exec(fsm->fsm_coe_map); // execute immediately +} + +/*****************************************************************************/ + +/** Slave scan state: PDOS. + */ +void ec_fsm_slave_scan_state_pdos( + ec_fsm_slave_scan_t *fsm /**< slave state machine */ + ) +{ + if (ec_fsm_coe_map_exec(fsm->fsm_coe_map)) + return; + + if (!ec_fsm_coe_map_success(fsm->fsm_coe_map)) { + fsm->state = ec_fsm_slave_scan_state_error; + return; + } + + // fetching of Pdo mapping finished + fsm->state = ec_fsm_slave_scan_state_end; +} + /****************************************************************************** * Common state functions *****************************************************************************/ diff -r d83d92e1a919 -r ded9519c8d6e master/fsm_slave_scan.h --- a/master/fsm_slave_scan.h Tue Feb 26 13:20:32 2008 +0000 +++ b/master/fsm_slave_scan.h Tue Feb 26 16:58:20 2008 +0000 @@ -49,6 +49,7 @@ #include "fsm_sii.h" #include "fsm_change.h" #include "fsm_coe.h" +#include "fsm_coe_map.h" #include "fsm_pdo_mapping.h" #include "fsm_pdo_config.h" @@ -63,6 +64,9 @@ { ec_slave_t *slave; /**< Slave the FSM runs on. */ ec_datagram_t *datagram; /**< Datagram used in the state machine. */ + ec_fsm_slave_config_t *fsm_slave_config; /**< Slave configuration state + machine to use. */ + ec_fsm_coe_map_t *fsm_coe_map; /**< Pdo mapping state machine to use. */ unsigned int retries; /**< Retries on datagram timeout. */ void (*state)(ec_fsm_slave_scan_t *); /**< State function. */ @@ -73,7 +77,8 @@ /*****************************************************************************/ -void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *, ec_datagram_t *); +void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *, ec_datagram_t *, + ec_fsm_slave_config_t *, ec_fsm_coe_map_t *); void ec_fsm_slave_scan_clear(ec_fsm_slave_scan_t *); void ec_fsm_slave_scan_start(ec_fsm_slave_scan_t *, ec_slave_t *); diff -r d83d92e1a919 -r ded9519c8d6e master/slave.c --- a/master/slave.c Tue Feb 26 13:20:32 2008 +0000 +++ b/master/slave.c Tue Feb 26 16:58:20 2008 +0000 @@ -154,7 +154,6 @@ INIT_LIST_HEAD(&slave->sdo_dictionary); slave->sdo_dictionary_fetched = 0; - slave->pdo_mapping_fetched = 0; slave->jiffies_preop = 0; for (i = 0; i < 4; i++) { diff -r d83d92e1a919 -r ded9519c8d6e master/slave.h --- a/master/slave.h Tue Feb 26 13:20:32 2008 +0000 +++ b/master/slave.h Tue Feb 26 16:58:20 2008 +0000 @@ -53,6 +53,15 @@ /*****************************************************************************/ +/** Slave state mask. + * + * Apply this mask to a slave state byte to get the slave state without + * the error flag. + */ +#define EC_SLAVE_STATE_MASK 0x0F + +/*****************************************************************************/ + /** State of an EtherCAT slave. */ typedef enum { @@ -156,8 +165,6 @@ struct list_head sdo_dictionary; /**< Sdo dictionary list */ uint8_t sdo_dictionary_fetched; /**< dictionary has been fetched */ unsigned long jiffies_preop; /**< time, the slave went to PREOP */ - - uint8_t pdo_mapping_fetched; /**< Pdo mapping has been fetched */ }; /*****************************************************************************/