ATSHA204A - I2C bus problem after lock command

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everyone,
 
I'm not sure if I post this problem into the right forum, so if I'm wrong let me know.
I'm working with the ATSHA204A crypto EEPROM (with I2C interface) and a PIC32MX230F256D as the I2C master. During the personalization of the EEPROM I am facing a problem which I wasn't able to solve and therefore need some help now. My problem is the following: When I wrote data to a zone (either the Configuration zone or the Data zone) I want to lock this zone. To check if the lock command was successful, I am waiting for the specified amount of ms and then read the result of the command. But when I try to read, the bus colission bit (I2CxSTATbits.BCL) is set and my I2C bus hangs up.
 
My personalization process looks like the following:

  1. I always have to wake the device first
  2. I write the whole configuration to the Config zone
  3. Then I lock the Config zone
  4. Now I write the whole Data zone
  5. And finally I lock the Data zone

 
And here the same in code:

 

// always wake the device first
DRV_ATSHA204A_Wake();
                    
/* Write slot configuration (slot 0 - 5) of block 0. */
for(i = 5; i < 8; i++){
     err = DRV_ATSHA204A_WriteConfig(&decryptedKeyFileData[448 + ((i - 5) * 4)], 0, i);
     if(err != ATSHA_SUCCESS){
        USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
        commandStatus = err;
        return;
     }
}
                    
/* Write slot configuration (slot 6 - 15) of block 1. */
for(i = 0; i < 5; i++){
    err = DRV_ATSHA204A_WriteConfig(&decryptedKeyFileData[460 + (i * 4)], 1, i);
    if(err != ATSHA_SUCCESS){
         USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
         commandStatus = err;
         return;
    }
}
                    
/* Now we want to write the CheckMac and OTP Mode configuration. Since we don't change all four
 * bytes of this block at offset 4, we're gonna read first and change then the two relevant bytes. */
err = DRV_ATSHA204A_ReadConfig(&configBuffer[0], 0, 4);
if(err != ATSHA_SUCCESS){
     USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
     commandStatus = err;
     return;
}
configBuffer[1] = decryptedKeyFileData[482];
configBuffer[2] = decryptedKeyFileData[483];
err = DRV_ATSHA204A_WriteConfig(&configBuffer[0], 0, 4);
if(err != ATSHA_SUCCESS){
     USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
     commandStatus = err;
     return;
}
                    
/* Since the data zone can only be written if the configuration zone is locked, we check now the
 * LockConfig byte. If the LockConfig byte was set to "lock" we can proceed with locking the 
 * Configuration Zone and then writing the Data Zone. If Configuration Zone should not be locked,
 * the program process ends here. */
if(decryptedKeyFileData[481] == 0x00){ // Configuration Zone should be locked
     /* Before we can write to the Data Zone we have to lock the Configuration Zone */
     err = DRV_ATSHA204A_LockZone(DRV_ATSHA204A_ZONE_CONFIG);
     if(err != ATSHA_SUCCESS){
          USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
          commandStatus = err;
          return;
     }
                        
     /* Write Key B and Challenge to slot 1 & 2. These two values are transmitted encrypted. */
     memcpy(&tempBuffer[0], &decryptedKeyFileData[32], 32);
     err = DRV_ATSHA204A_WriteData_Encrypted(&tempBuffer[0], 1);
     if(err != ATSHA_SUCCESS){
          USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
          commandStatus = err;
          return;
     }
     memcpy(&tempBuffer[0], &decryptedKeyFileData[64], 32);
     err = DRV_ATSHA204A_WriteData_Encrypted(&tempBuffer[0], 2);
     if(err != ATSHA_SUCCESS){
          USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
          commandStatus = err;
          return;
     }
                        
     /* Now we write slot data from slot 3 - 15. */
     for(i = 3; i < 15; i++){
          err = DRV_ATSHA204A_WriteData(&decryptedKeyFileData[i * 32], i, 0, 32);
          if(err != ATSHA_SUCCESS){
               USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
               commandStatus = err;
               return;
          }
     }
                        
     /* If necessary, we lock the Data Zone after writing all data */
     if(decryptedKeyFileData[480] == 0x00){
          err = DRV_ATSHA204A_LockZone(DRV_ATSHA204A_ZONE_DATA);
          if(err != ATSHA_SUCCESS){
               USB_DEVICE_ControlStatus(appData.usbDevHandle,USB_DEVICE_CONTROL_STATUS_ERROR);
               commandStatus = err;
               return;
          }
          commandStatus = 4;
      } else {
          commandStatus = 3;
      }
} else {
    commandStatus = 2;
}

What happens now is, the I2C bus hangs up after the third step, after I sent the "lock config zone" command. When I check the lock status of the configuration zone, I see that the "lock config zone" command was processed successfully and the zone is locked. After I have restarted the device I tried to only send the data to the Data zone and then lock the Data zone (Config zone is still locked). The same happens here: After I sent the lock command the I2C bus hangs up. But this time, the Data zone was not locked and stays unlocked.
When I debug I see that the BCL bit is set after the I2C-address byte was sent (while reading the result after the command was sent) and before I want to set the RCEN bit to receive the result. Since this only happens with the lock command I expect that I am doing something wrong here with the crypto EEPROM. Does anyone have an idea what could cause this issue?