master/fsm_slave.c
changeset 742 03d2fe3d4a93
parent 738 880c6153101f
child 744 b83392e8cd66
equal deleted inserted replaced
741:aece53f82df3 742:03d2fe3d4a93
   429     if (!(slave->eeprom_data =
   429     if (!(slave->eeprom_data =
   430                 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
   430                 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) {
   431         slave->eeprom_size = 0;
   431         slave->eeprom_size = 0;
   432         slave->error_flag = 1;
   432         slave->error_flag = 1;
   433         fsm->state = ec_fsm_slave_state_error;
   433         fsm->state = ec_fsm_slave_state_error;
   434         EC_ERR("Failed to allocate EEPROM data on slave %i.\n",
   434         EC_ERR("Failed to allocate EEPROM data for slave %u.\n",
   435                slave->ring_position);
   435                slave->ring_position);
   436         return;
   436         return;
   437     }
   437     }
   438 
   438 
   439     // Start fetching EEPROM contents
   439     // Start fetching EEPROM contents
   451 */
   451 */
   452 
   452 
   453 void ec_fsm_slave_scan_state_eeprom_data(ec_fsm_slave_t *fsm /**< slave state machine */)
   453 void ec_fsm_slave_scan_state_eeprom_data(ec_fsm_slave_t *fsm /**< slave state machine */)
   454 {
   454 {
   455     ec_slave_t *slave = fsm->slave;
   455     ec_slave_t *slave = fsm->slave;
   456     uint16_t *cat_word, cat_type, cat_size;
   456     uint16_t *cat_word, cat_type, cat_size, eeprom_word_size = slave->eeprom_size / 2;
   457 
   457 
   458     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
   458     if (ec_fsm_sii_exec(&fsm->fsm_sii)) return;
   459 
   459 
   460     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
   460     if (!ec_fsm_sii_success(&fsm->fsm_sii)) {
   461         fsm->slave->error_flag = 1;
   461         fsm->slave->error_flag = 1;
   465         return;
   465         return;
   466     }
   466     }
   467 
   467 
   468     // 2 words fetched
   468     // 2 words fetched
   469 
   469 
   470     if (fsm->sii_offset + 2 <= slave->eeprom_size / 2) { // 2 words fit
   470     if (fsm->sii_offset + 2 <= eeprom_word_size) { // 2 words fit
   471         memcpy(slave->eeprom_data + fsm->sii_offset * 2,
   471         memcpy(slave->eeprom_data + fsm->sii_offset * 2,
   472                fsm->fsm_sii.value, 4);
   472                fsm->fsm_sii.value, 4);
   473     }
   473     }
   474     else { // copy the last word
   474     else { // copy the last word
   475         memcpy(slave->eeprom_data + fsm->sii_offset * 2,
   475         memcpy(slave->eeprom_data + fsm->sii_offset * 2,
   476                fsm->fsm_sii.value, 2);
   476                fsm->fsm_sii.value, 2);
   477     }
   477     }
   478 
   478 
   479     if (fsm->sii_offset + 2 < slave->eeprom_size / 2) {
   479     if (fsm->sii_offset + 2 < eeprom_word_size) {
   480         // fetch the next 2 words
   480         // fetch the next 2 words
   481         fsm->sii_offset += 2;
   481         fsm->sii_offset += 2;
   482         ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
   482         ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset,
   483                         EC_FSM_SII_NODE);
   483                         EC_FSM_SII_NODE);
   484         ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
   484         ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately
   506     slave->sii_tx_mailbox_size =
   506     slave->sii_tx_mailbox_size =
   507         EC_READ_U16(slave->eeprom_data + 2 * 0x001B);
   507         EC_READ_U16(slave->eeprom_data + 2 * 0x001B);
   508     slave->sii_mailbox_protocols =
   508     slave->sii_mailbox_protocols =
   509         EC_READ_U16(slave->eeprom_data + 2 * 0x001C);
   509         EC_READ_U16(slave->eeprom_data + 2 * 0x001C);
   510 
   510 
       
   511     if (eeprom_word_size < EC_FIRST_EEPROM_CATEGORY_OFFSET + 1) {
       
   512         EC_ERR("Unexpected end of EEPROM data in slave %u.\n",
       
   513                 slave->ring_position);
       
   514         goto end;
       
   515     }
       
   516 
   511     // evaluate category data
   517     // evaluate category data
   512     cat_word = (uint16_t *) slave->eeprom_data + EC_FIRST_EEPROM_CATEGORY_OFFSET;
   518     cat_word =
       
   519         (uint16_t *) slave->eeprom_data + EC_FIRST_EEPROM_CATEGORY_OFFSET;
   513     while (EC_READ_U16(cat_word) != 0xFFFF) {
   520     while (EC_READ_U16(cat_word) != 0xFFFF) {
       
   521 
       
   522         // type and size words must fit
       
   523         if (cat_word + 2 - (uint16_t *) slave->eeprom_data
       
   524                 > eeprom_word_size) {
       
   525             EC_ERR("Unexpected end of EEPROM data in slave %u.\n",
       
   526                     slave->ring_position);
       
   527             goto end;
       
   528         }
       
   529 
   514         cat_type = EC_READ_U16(cat_word) & 0x7FFF;
   530         cat_type = EC_READ_U16(cat_word) & 0x7FFF;
   515         cat_size = EC_READ_U16(cat_word + 1);
   531         cat_size = EC_READ_U16(cat_word + 1);
       
   532         cat_word += 2;
       
   533 
       
   534         if (cat_word + cat_size - (uint16_t *) slave->eeprom_data
       
   535                 > eeprom_word_size) {
       
   536             EC_WARN("Unexpected end of EEPROM data in slave %u.\n",
       
   537                     slave->ring_position);
       
   538             goto end;
       
   539         }
   516 
   540 
   517         switch (cat_type) {
   541         switch (cat_type) {
   518             case 0x000A:
   542             case 0x000A:
   519                 if (ec_slave_fetch_sii_strings(
   543                 if (ec_slave_fetch_sii_strings(slave, (uint8_t *) cat_word,
   520                             slave, (uint8_t *) (cat_word + 2)))
   544                             cat_size * 2))
   521                     goto end;
   545                     goto end;
   522                 break;
   546                 break;
   523             case 0x001E:
   547             case 0x001E:
   524                 ec_slave_fetch_sii_general(
   548                 if (ec_slave_fetch_sii_general(slave, (uint8_t *) cat_word,
   525                         slave, (uint8_t *) (cat_word + 2));
   549                             cat_size * 2))
       
   550                     goto end;
   526                 break;
   551                 break;
   527             case 0x0028:
   552             case 0x0028:
   528                 break;
   553                 break;
   529             case 0x0029:
   554             case 0x0029:
   530                 if (ec_slave_fetch_sii_syncs(
   555                 if (ec_slave_fetch_sii_syncs(slave, (uint8_t *) cat_word,
   531                             slave, (uint8_t *) (cat_word + 2), cat_size))
   556                             cat_size * 2))
   532                     goto end;
   557                     goto end;
   533                 break;
   558                 break;
   534             case 0x0032:
   559             case 0x0032:
   535                 if (ec_slave_fetch_sii_pdos(
   560                 if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
   536                             slave, (uint8_t *) (cat_word + 2),
   561                             cat_size * 2, EC_TX_PDO))
   537                             cat_size, EC_TX_PDO))
       
   538                     goto end;
   562                     goto end;
   539                 break;
   563                 break;
   540             case 0x0033:
   564             case 0x0033:
   541                 if (ec_slave_fetch_sii_pdos(
   565                 if (ec_slave_fetch_sii_pdos( slave, (uint8_t *) cat_word,
   542                             slave, (uint8_t *) (cat_word + 2),
   566                             cat_size * 2, EC_RX_PDO))
   543                             cat_size, EC_RX_PDO))
       
   544                     goto end;
   567                     goto end;
   545                 break;
   568                 break;
   546             default:
   569             default:
   547                 if (fsm->slave->master->debug_level)
   570                 if (fsm->slave->master->debug_level)
   548                     EC_WARN("Unknown category type 0x%04X in slave %i.\n",
   571                     EC_WARN("Unknown category type 0x%04X in slave %i.\n",
   549                             cat_type, slave->ring_position);
   572                             cat_type, slave->ring_position);
   550         }
   573         }
   551 
   574 
   552         cat_word += cat_size + 2;
   575         cat_word += cat_size;
       
   576         if (cat_word - (uint16_t *) slave->eeprom_data >= eeprom_word_size) {
       
   577             EC_WARN("Unexpected end of EEPROM data in slave %u.\n",
       
   578                     slave->ring_position);
       
   579             goto end;
       
   580         }
   553     }
   581     }
   554 
   582 
   555     fsm->state = ec_fsm_slave_state_end;
   583     fsm->state = ec_fsm_slave_state_end;
   556     return;
   584     return;
   557 
   585