ATAES132A i2c Write/Read help

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am working with a ATAES132A (AES Serial EEPROM) - I am using a SAMD21J18A (xplained pro) and ASF. I am trying to do a simple write/read operation to generate a Random number with the ATAES132A. I am able to successfully read the status register but unable to do a Write/Read operation. My status after the write/read is 0x90 (bit 7 is 1), which means "1b = 0xFF was returned in place of one or more invalid or prohibited bytes read." . It looks like I am not sending the commands correctly.

 

Per the datasheet, my write should be:

 

 

Also, the datasheet says (Section 19 page 123):

 

The Host sends ATAES132A extended commands to the device by writing the command packet to the
Command Memory Buffer at address 0xFE00. The ATAES132A processes the command packet and
places the response in the Response Memory Buffer. The Host retrieves the response by reading the
response packet from address 0xFE00.

I am sending the command to generate a random number (0x02) with a write command as follows:

 

uint8_t readBuffer[5];
uint8_t writebuffer[5];

memset(readBuffer, 0, sizeof readBuffer);	 // clear
memset(writebuffer, 0, sizeof writebuffer);	 // clear
writebuffer[0] = 0xFE; // write command hi byte
writebuffer[1] = 0x00; // write command low byte
writebuffer[2] = RANDOM; // 0x02
writebuffer[3] = 0x00;
	writebuffer[4] = 0x00;

w_packet.address    = ADDRESS; // 0x50
w_packet.data_length = 5;
w_packet.ten_bit_address = false;
w_packet.data  = writebuffer;
i2c_master_write_packet_wait(&i2c_master_instance, &w_packet);
		
rd_packet.address = ADDRESS;
rd_packet.data_length = 3;
rd_packet.ten_bit_address = false;
rd_packet.data = readBuffer;
i2c_master_read_packet_wait(&i2c_master_instance, &rd_packet);
	
for(uint8_t a = 0; a < 3; a++){
	
	printf("Reading: 0x%x\n\r", readBuffer[a]);
}	

Which looks like this:

 

 

Any help is appreciated. Thx

This topic has a solution.

"When all else fails, read the directions"

Last Edited: Sun. Jun 17, 2018 - 09:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like you are not sending the command according to the specification in the datasheet

The Host sends the ATAES132A extended commands to the device in a block of at least nine bytes.

/Lars 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lajon wrote:
Looks like you are not sending the command according to the specification in the datasheet

Thanks. I am now able to get a valid status, but still having issues. I needed to add the number of bytes sent as the 3 byte. I must admit the datasheet sucks. Crap is all over the place and IMO poorly written. You'd think they would make it easier **end rant**

 

Her is what I have so far:

 

memset(readBuffer, 0, sizeof readBuffer);	 // clear
memset(writebuffer, 0, sizeof writebuffer);	 // clear

writebuffer[0] = 0xFE; // write command hi byte
writebuffer[1] = 0x00; // write command low byte
writebuffer[2] = 0x09; // nine bytes sent
writebuffer[3] = RANDOM;// 0x02
writebuffer[4] = 0x00;
writebuffer[5] = 0x00;
writebuffer[6] = 0x00;
writebuffer[7] = 0x00;
writebuffer[8] = 0x00;

w_packet.address    = ADDRESS; // 0x50
w_packet.data_length = 9;
w_packet.ten_bit_address = false;
w_packet.data  = writebuffer;
i2c_master_write_packet_wait(&i2c_master_instance, &w_packet);

rd_packet.address = ADDRESS;
rd_packet.data_length = 9;
rd_packet.ten_bit_address = false;
rd_packet.data = readBuffer;	

i2c_master_read_packet_wait(&i2c_master_instance, &rd_packet);

for(uint8_t a = 0; a < 9; a++){

	printf("Reading: 0x%x\n\r", readBuffer[a]);
}

Which I now get response back of 0xFF, which means

 

"The Host retrieves the response by reading the response block using a standard SPI or I2C Read command. If the Host reads beyond the end of the block, then 0xFF is returned."

 

Any thoughts? In the mean while, I'll continue reading.

 

"When all else fails, read the directions"

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What about the checksum in the block?

The response will not be available immediately, you are supposed to poll the status (or add a delay).

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lajon wrote:
What about the checksum in the block?

 

That was it. I think I needs to still mess with the timing, but I am getting good response (0x14) - Device not in sleep mode and no checksum error.

 


void random_number_example(void){
	
	memset(readBuffer, 0, sizeof readBuffer);	 // clear
	memset(writebuffer, 0, sizeof writebuffer);	 // clear

	writebuffer[0] = 0xFE; // write command hi byte
	writebuffer[1] = 0x00; // write command low byte
	writebuffer[2] = 0x09; // nine bytes sent
	writebuffer[3] = RANDOM;// 0x02
	writebuffer[4] = 0x00;
	writebuffer[5] = 0x00;
	writebuffer[6] = 0x00;
	writebuffer[7] = 0x00;
	writebuffer[8] = 0x00;

	calculate_checksum(7, &writebuffer[2], checksum);
	printf("Check Sum 0x%X%X \n\r", checksum[0],checksum[1]);
	
	writebuffer[9] = checksum[0];
	writebuffer[10] = checksum[1];

	w_packet.address    = ADDRESS; // 0x50
	w_packet.data_length = 11;
	w_packet.ten_bit_address = false;

	w_packet.data  = writebuffer;
	i2c_master_write_packet_wait(&i2c_master_instance, &w_packet);
	delay_ms(10);
	rd_packet.address = ADDRESS;
	rd_packet.data_length = 9;
	rd_packet.ten_bit_address = false;
	rd_packet.data = readBuffer;	

	i2c_master_read_packet_wait(&i2c_master_instance, &rd_packet);
	
	for(uint8_t a = 0; a < 9; a++){
		
		printf("Reading: 0x%x\n\r", readBuffer[a]);
	}
	
	delay_ms(500);
	
	read_status();

}

/** \This function calculates a 16-bit CRC.
* \param[in] count number of bytes in data buffer
* \param[in] data pointer to data
* \param[out] crc pointer to calculated CRC (high byte at crc[0])
*/
void calculate_checksum(uint8_t length, uint8_t *data, uint8_t *crc)
{
	uint8_t counter;
	uint8_t crcLow = 0, crcHigh = 0, crcCarry;
	uint8_t polyLow = 0x05, polyHigh = 0x80;
	uint8_t shiftRegister;
	uint8_t dataBit, crcBit;
	for (counter = 0; counter < length; counter++) {
		for (shiftRegister = 0x80; shiftRegister > 0x00; shiftRegister >>= 1) {
			dataBit = (data[counter] & shiftRegister) ? 1 : 0;
			crcBit = crcHigh >> 7;
			// Shift CRC to the left by 1.
			crcCarry = crcLow >> 7;
			crcLow <<= 1;
			crcHigh <<= 1;
			crcHigh |= crcCarry;
			if ((dataBit ^ crcBit) != 0) {
				crcLow ^= polyLow;
				crcHigh ^= polyHigh;
			}
		}
	}
	crc[0] = crcHigh;
	crc[1] = crcLow;
}

My response is 0xA5 which is as expected:

 

"If the LockConfig Register is unlocked (0x55), then the RNG is latched in the test mode, and the Random Command will always return 16 bytes of 0xA5. If the LockConfig register is locked (!0x55), then the RNG generates random numbers."

 

Thank you very much!

"When all else fails, read the directions"