master/slave.c
changeset 754 0b47b49c5976
parent 750 bc42cd59329b
child 758 8fa6f825eb7d
equal deleted inserted replaced
753:7ba5f9cd8f7e 754:0b47b49c5976
   976     }
   976     }
   977 
   977 
   978     // init EEPROM write request
   978     // init EEPROM write request
   979     INIT_LIST_HEAD(&request.list);
   979     INIT_LIST_HEAD(&request.list);
   980     request.slave = slave;
   980     request.slave = slave;
   981     request.words = (const uint16_t *) data;
   981     request.data = data;
   982     request.offset = 0;
   982     request.word_offset = 0;
   983     request.size = size / 2;
   983     request.word_size = size / 2;
   984 
   984 
   985     if (request.size < 0x0041) {
   985     if (request.word_size < 0x0041) {
   986         EC_ERR("EEPROM data too short! Dropping.\n");
   986         EC_ERR("EEPROM data too short! Dropping.\n");
   987         return -EINVAL;
   987         return -EINVAL;
   988     }
   988     }
   989 
   989 
   990     // calculate checksum
   990     // calculate checksum
   991     crc = ec_slave_eeprom_crc(data, 14); // CRC over words 0 to 6
   991     crc = ec_slave_eeprom_crc(data, 14); // CRC over words 0 to 6
   992     if (crc != data[14]) {
   992     if (crc != data[14]) {
   993         EC_WARN("EEPROM CRC incorrect. Must be 0x%02x.\n", crc);
   993         EC_WARN("EEPROM CRC incorrect. Must be 0x%02x.\n", crc);
   994     }
   994     }
   995 
   995 
   996     cat_header = request.words + EC_FIRST_EEPROM_CATEGORY_OFFSET;
   996     cat_header = (const uint16_t *) request.data
       
   997 		+ EC_FIRST_EEPROM_CATEGORY_OFFSET;
   997     cat_type = EC_READ_U16(cat_header);
   998     cat_type = EC_READ_U16(cat_header);
   998     while (cat_type != 0xFFFF) { // cycle through categories
   999     while (cat_type != 0xFFFF) { // cycle through categories
   999         if (cat_header + 1 > request.words + request.size) {
  1000         if (cat_header + 1 >
       
  1001 				(const uint16_t *) request.data + request.word_size) {
  1000             EC_ERR("EEPROM data corrupted! Dropping.\n");
  1002             EC_ERR("EEPROM data corrupted! Dropping.\n");
  1001             return -EINVAL;
  1003             return -EINVAL;
  1002         }
  1004         }
  1003         cat_size = EC_READ_U16(cat_header + 1);
  1005         cat_size = EC_READ_U16(cat_header + 1);
  1004         if (cat_header + cat_size + 2 > request.words + request.size) {
  1006         if (cat_header + cat_size + 2 >
       
  1007 				(const uint16_t *) request.data + request.word_size) {
  1005             EC_ERR("EEPROM data corrupted! Dropping.\n");
  1008             EC_ERR("EEPROM data corrupted! Dropping.\n");
  1006             return -EINVAL;
  1009             return -EINVAL;
  1007         }
  1010         }
  1008         cat_header += cat_size + 2;
  1011         cat_header += cat_size + 2;
  1009         cat_type = EC_READ_U16(cat_header);
  1012         cat_type = EC_READ_U16(cat_header);
  1028         size_t size /**< size of data in bytes */
  1031         size_t size /**< size of data in bytes */
  1029         )
  1032         )
  1030 {
  1033 {
  1031     ec_eeprom_write_request_t request;
  1034     ec_eeprom_write_request_t request;
  1032     char *remainder;
  1035     char *remainder;
  1033     uint16_t alias, words[8];
  1036     uint16_t alias;
  1034     int ret;
  1037     int ret;
  1035     uint8_t crc;
  1038     uint8_t eeprom_data[16], crc;
  1036 
  1039 
  1037     if (slave->master->mode != EC_MASTER_MODE_IDLE) { // FIXME
  1040     if (slave->master->mode != EC_MASTER_MODE_IDLE) { // FIXME
  1038         EC_ERR("Writing to EEPROM is only allowed in idle mode!\n");
  1041         EC_ERR("Writing to EEPROM is only allowed in idle mode!\n");
  1039         return -EBUSY;
  1042         return -EBUSY;
  1040     }
  1043     }
  1050                 slave->ring_position);
  1053                 slave->ring_position);
  1051         return -EINVAL;
  1054         return -EINVAL;
  1052     }
  1055     }
  1053 
  1056 
  1054     // copy first 7 words of recent EEPROM contents
  1057     // copy first 7 words of recent EEPROM contents
  1055     memcpy(words, slave->eeprom_data, 14);
  1058     memcpy(eeprom_data, slave->eeprom_data, 14);
  1056     
  1059     
  1057     // write new alias address
  1060     // write new alias address in word 4
  1058     EC_WRITE_U16(words + 4, alias);
  1061     EC_WRITE_U16(eeprom_data + 8, alias);
  1059 
  1062 
  1060     // calculate new checksum over words 0 to 6
  1063     // calculate new checksum over words 0 to 6
  1061     crc = ec_slave_eeprom_crc((const uint8_t *) words, 14);
  1064     crc = ec_slave_eeprom_crc(eeprom_data, 14);
  1062     EC_WRITE_U16(words + 7, crc);
  1065     EC_WRITE_U16(eeprom_data + 14, crc);
  1063 
  1066 
  1064     // init EEPROM write request
  1067     // init EEPROM write request
  1065     INIT_LIST_HEAD(&request.list);
  1068     INIT_LIST_HEAD(&request.list);
  1066     request.slave = slave;
  1069     request.slave = slave;
  1067     request.words = words;
  1070     request.data = eeprom_data;
  1068     request.offset = 0x0000;
  1071     request.word_offset = 0x0000;
  1069     request.size = 8;
  1072     request.word_size = 8;
  1070 
  1073 
  1071     if ((ret = ec_slave_schedule_eeprom_writing(&request)))
  1074     if ((ret = ec_slave_schedule_eeprom_writing(&request)))
  1072         return ret; // error code
  1075         return ret; // error code
  1073 
  1076 
  1074     slave->sii_alias = alias; // FIXME: do this in state machine
  1077     slave->sii_alias = alias; // FIXME: do this in state machine