master/slave.c
changeset 114 e4b4b5a85e75
parent 113 a3dbd6bc8fce
child 118 dc71ce4cc641
equal deleted inserted replaced
113:a3dbd6bc8fce 114:e4b4b5a85e75
    32     slave->base_build = 0;
    32     slave->base_build = 0;
    33     slave->base_fmmu_count = 0;
    33     slave->base_fmmu_count = 0;
    34     slave->base_sync_count = 0;
    34     slave->base_sync_count = 0;
    35     slave->ring_position = 0;
    35     slave->ring_position = 0;
    36     slave->station_address = 0;
    36     slave->station_address = 0;
       
    37     slave->sii_alias = 0;
    37     slave->sii_vendor_id = 0;
    38     slave->sii_vendor_id = 0;
    38     slave->sii_product_code = 0;
    39     slave->sii_product_code = 0;
    39     slave->sii_revision_number = 0;
    40     slave->sii_revision_number = 0;
    40     slave->sii_serial_number = 0;
    41     slave->sii_serial_number = 0;
    41     slave->type = NULL;
    42     slave->type = NULL;
    82 
    83 
    83     if (slave->base_fmmu_count > EC_MAX_FMMUS)
    84     if (slave->base_fmmu_count > EC_MAX_FMMUS)
    84         slave->base_fmmu_count = EC_MAX_FMMUS;
    85         slave->base_fmmu_count = EC_MAX_FMMUS;
    85 
    86 
    86     // Read identification from "Slave Information Interface" (SII)
    87     // Read identification from "Slave Information Interface" (SII)
       
    88 
       
    89     if (unlikely(ec_slave_sii_read(slave, 0x0004,
       
    90                                    (uint32_t *) &slave->sii_alias))) {
       
    91         EC_ERR("Could not read SII alias!\n");
       
    92         return -1;
       
    93     }
    87 
    94 
    88     if (unlikely(ec_slave_sii_read(slave, 0x0008, &slave->sii_vendor_id))) {
    95     if (unlikely(ec_slave_sii_read(slave, 0x0008, &slave->sii_vendor_id))) {
    89         EC_ERR("Could not read SII vendor id!\n");
    96         EC_ERR("Could not read SII vendor id!\n");
    90         return -1;
    97         return -1;
    91     }
    98     }
   132     uint8_t data[10];
   139     uint8_t data[10];
   133     cycles_t start, end, timeout;
   140     cycles_t start, end, timeout;
   134 
   141 
   135     // Initiate read operation
   142     // Initiate read operation
   136 
   143 
   137     EC_WRITE_U8 (data,     0x00);
   144     EC_WRITE_U8 (data,     0x00); // read-only access
   138     EC_WRITE_U8 (data + 1, 0x01);
   145     EC_WRITE_U8 (data + 1, 0x01); // request read operation
   139     EC_WRITE_U16(data + 2, offset);
   146     EC_WRITE_U32(data + 2, offset);
   140     EC_WRITE_U16(data + 4, 0x0000);
       
   141 
   147 
   142     ec_command_init_npwr(&command, slave->station_address, 0x502, 6, data);
   148     ec_command_init_npwr(&command, slave->station_address, 0x502, 6, data);
   143     if (unlikely(ec_master_simple_io(slave->master, &command))) {
   149     if (unlikely(ec_master_simple_io(slave->master, &command))) {
   144         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   150         EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
   145         return -1;
   151         return -1;
   164         }
   170         }
   165 
   171 
   166         end = get_cycles();
   172         end = get_cycles();
   167 
   173 
   168         if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
   174         if (likely((EC_READ_U8(command.data + 1) & 0x81) == 0)) {
   169             memcpy(target, command.data + 6, 4);
   175             *target = EC_READ_U32(command.data + 6);
   170             return 0;
   176             return 0;
   171         }
   177         }
   172 
   178 
   173         if (unlikely((end - start) >= timeout)) {
   179         if (unlikely((end - start) >= timeout)) {
   174             EC_ERR("SSI-read. Slave %i timed out!\n", slave->ring_position);
   180             EC_ERR("SSI-read. Slave %i timed out!\n", slave->ring_position);
       
   181             return -1;
       
   182         }
       
   183     }
       
   184 }
       
   185 
       
   186 /*****************************************************************************/
       
   187 
       
   188 /**
       
   189    Schreibt Daten in das Slave-Information-Interface
       
   190    eines EtherCAT-Slaves.
       
   191 
       
   192    \return 0 bei Erfolg, sonst < 0
       
   193 */
       
   194 
       
   195 int ec_slave_sii_write(ec_slave_t *slave,
       
   196                        /**< EtherCAT-Slave */
       
   197                        uint16_t offset,
       
   198                        /**< Adresse des zu lesenden SII-Registers */
       
   199                        uint16_t value
       
   200                        /**< Zu schreibender Wert */
       
   201                        )
       
   202 {
       
   203     ec_command_t command;
       
   204     uint8_t data[8];
       
   205     cycles_t start, end, timeout;
       
   206 
       
   207     EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n",
       
   208             slave->ring_position, offset, value);
       
   209 
       
   210     // Initiate write operation
       
   211 
       
   212     EC_WRITE_U8 (data,     0x01); // enable write access
       
   213     EC_WRITE_U8 (data + 1, 0x02); // request write operation
       
   214     EC_WRITE_U32(data + 2, offset);
       
   215     EC_WRITE_U16(data + 6, value);
       
   216 
       
   217     ec_command_init_npwr(&command, slave->station_address, 0x502, 8, data);
       
   218     if (unlikely(ec_master_simple_io(slave->master, &command))) {
       
   219         EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
       
   220         return -1;
       
   221     }
       
   222 
       
   223     // Der Slave legt die Informationen des Slave-Information-Interface
       
   224     // in das Datenregister und löscht daraufhin ein Busy-Bit. Solange
       
   225     // den Status auslesen, bis das Bit weg ist.
       
   226 
       
   227     start = get_cycles();
       
   228     timeout = cpu_khz; // 1ms
       
   229 
       
   230     while (1)
       
   231     {
       
   232         udelay(10);
       
   233 
       
   234         ec_command_init_nprd(&command, slave->station_address, 0x502, 2);
       
   235         if (unlikely(ec_master_simple_io(slave->master, &command))) {
       
   236             EC_ERR("Getting SII-write status failed on slave %i!\n",
       
   237                    slave->ring_position);
       
   238             return -1;
       
   239         }
       
   240 
       
   241         end = get_cycles();
       
   242 
       
   243         if (likely((EC_READ_U8(command.data + 1) & 0x82) == 0)) {
       
   244             if (EC_READ_U8(command.data + 1) & 0x40) {
       
   245                 EC_ERR("SII-write failed!\n");
       
   246                 return -1;
       
   247             }
       
   248             else {
       
   249                 EC_INFO("SII-write succeeded!\n");
       
   250                 return 0;
       
   251             }
       
   252         }
       
   253 
       
   254         if (unlikely((end - start) >= timeout)) {
       
   255             EC_ERR("SSI-write: Slave %i timed out!\n", slave->ring_position);
   175             return -1;
   256             return -1;
   176         }
   257         }
   177     }
   258     }
   178 }
   259 }
   179 
   260 
   375             slave->base_type, slave->base_revision, slave->base_build);
   456             slave->base_type, slave->base_revision, slave->base_build);
   376     EC_INFO("    Supported FMMUs: %i, Sync managers: %i\n",
   457     EC_INFO("    Supported FMMUs: %i, Sync managers: %i\n",
   377             slave->base_fmmu_count, slave->base_sync_count);
   458             slave->base_fmmu_count, slave->base_sync_count);
   378 
   459 
   379     EC_INFO("  Slave information interface:\n");
   460     EC_INFO("  Slave information interface:\n");
       
   461     EC_INFO("    Configured station alias: 0x%04X (%i)\n", slave->sii_alias,
       
   462             slave->sii_alias);
   380     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   463     EC_INFO("    Vendor-ID: 0x%08X, Product code: 0x%08X\n",
   381             slave->sii_vendor_id, slave->sii_product_code);
   464             slave->sii_vendor_id, slave->sii_product_code);
   382     EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
   465     EC_INFO("    Revision number: 0x%08X, Serial number: 0x%08X\n",
   383             slave->sii_revision_number, slave->sii_serial_number);
   466             slave->sii_revision_number, slave->sii_serial_number);
   384 }
   467 }
   427 /* Emacs-Konfiguration
   510 /* Emacs-Konfiguration
   428 ;;; Local Variables: ***
   511 ;;; Local Variables: ***
   429 ;;; c-basic-offset:4 ***
   512 ;;; c-basic-offset:4 ***
   430 ;;; End: ***
   513 ;;; End: ***
   431 */
   514 */
       
   515