diff -r a3dbd6bc8fce -r e4b4b5a85e75 master/slave.c --- a/master/slave.c Mon Mar 20 13:36:10 2006 +0000 +++ b/master/slave.c Mon Mar 20 15:28:25 2006 +0000 @@ -34,6 +34,7 @@ slave->base_sync_count = 0; slave->ring_position = 0; slave->station_address = 0; + slave->sii_alias = 0; slave->sii_vendor_id = 0; slave->sii_product_code = 0; slave->sii_revision_number = 0; @@ -85,6 +86,12 @@ // Read identification from "Slave Information Interface" (SII) + if (unlikely(ec_slave_sii_read(slave, 0x0004, + (uint32_t *) &slave->sii_alias))) { + EC_ERR("Could not read SII alias!\n"); + return -1; + } + if (unlikely(ec_slave_sii_read(slave, 0x0008, &slave->sii_vendor_id))) { EC_ERR("Could not read SII vendor id!\n"); return -1; @@ -134,10 +141,9 @@ // Initiate read operation - EC_WRITE_U8 (data, 0x00); - EC_WRITE_U8 (data + 1, 0x01); - EC_WRITE_U16(data + 2, offset); - EC_WRITE_U16(data + 4, 0x0000); + EC_WRITE_U8 (data, 0x00); // read-only access + EC_WRITE_U8 (data + 1, 0x01); // request read operation + EC_WRITE_U32(data + 2, offset); ec_command_init_npwr(&command, slave->station_address, 0x502, 6, data); if (unlikely(ec_master_simple_io(slave->master, &command))) { @@ -166,7 +172,7 @@ end = get_cycles(); if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) { - memcpy(target, command.data + 6, 4); + *target = EC_READ_U32(command.data + 6); return 0; } @@ -180,6 +186,81 @@ /*****************************************************************************/ /** + Schreibt Daten in das Slave-Information-Interface + eines EtherCAT-Slaves. + + \return 0 bei Erfolg, sonst < 0 +*/ + +int ec_slave_sii_write(ec_slave_t *slave, + /**< EtherCAT-Slave */ + uint16_t offset, + /**< Adresse des zu lesenden SII-Registers */ + uint16_t value + /**< Zu schreibender Wert */ + ) +{ + ec_command_t command; + uint8_t data[8]; + cycles_t start, end, timeout; + + EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n", + slave->ring_position, offset, value); + + // Initiate write operation + + EC_WRITE_U8 (data, 0x01); // enable write access + EC_WRITE_U8 (data + 1, 0x02); // request write operation + EC_WRITE_U32(data + 2, offset); + EC_WRITE_U16(data + 6, value); + + ec_command_init_npwr(&command, slave->station_address, 0x502, 8, data); + if (unlikely(ec_master_simple_io(slave->master, &command))) { + EC_ERR("SII-write failed on slave %i!\n", slave->ring_position); + return -1; + } + + // Der Slave legt die Informationen des Slave-Information-Interface + // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange + // den Status auslesen, bis das Bit weg ist. + + start = get_cycles(); + timeout = cpu_khz; // 1ms + + while (1) + { + udelay(10); + + ec_command_init_nprd(&command, slave->station_address, 0x502, 2); + if (unlikely(ec_master_simple_io(slave->master, &command))) { + EC_ERR("Getting SII-write status failed on slave %i!\n", + slave->ring_position); + return -1; + } + + end = get_cycles(); + + if (likely((EC_READ_U8(command.data + 1) & 0x82) == 0)) { + if (EC_READ_U8(command.data + 1) & 0x40) { + EC_ERR("SII-write failed!\n"); + return -1; + } + else { + EC_INFO("SII-write succeeded!\n"); + return 0; + } + } + + if (unlikely((end - start) >= timeout)) { + EC_ERR("SSI-write: Slave %i timed out!\n", slave->ring_position); + return -1; + } + } +} + +/*****************************************************************************/ + +/** Bestätigt einen Fehler beim Zustandswechsel. \todo Funktioniert noch nicht... @@ -377,6 +458,8 @@ slave->base_fmmu_count, slave->base_sync_count); EC_INFO(" Slave information interface:\n"); + EC_INFO(" Configured station alias: 0x%04X (%i)\n", slave->sii_alias, + slave->sii_alias); EC_INFO(" Vendor-ID: 0x%08X, Product code: 0x%08X\n", slave->sii_vendor_id, slave->sii_product_code); EC_INFO(" Revision number: 0x%08X, Serial number: 0x%08X\n", @@ -429,3 +512,4 @@ ;;; c-basic-offset:4 *** ;;; End: *** */ +