I am currently using a michrochip's eeprom ( 24cw160 ) connected with an stm32f4 (11RET) via i2c. The configurations and the connection seem to work as my logical analyzer prints some i2c messages (with ACK) and I can send data and receive data back. After reading the reference manual(especially pages 13 and 18 that have the schematics for the two operations I am doing) I am expecting the code below to send the data 0,1,2... to the addresses after x10 sequentially and then receiving the same data back and printing them :
while(true){
HAL_Delay(1000);
std::array<uint8_t,100> arr{};
int counter=0;
for(auto&i :arr){
i=counter;
counter++;
}
auto ret1 = HAL_I2C_Mem_Write_DMA(&hi2c1 , 0xa0 , 0x10 , 1 ,arr.data() , arr.size());
HAL_Delay(1000);
std::array<uint8_t,100> arr2{};
arr2.fill(1);
auto ret2 = HAL_I2C_Mem_Read( &hi2c1 , 0xa1 , 0x10 , 1 , arr2.data() , arr2.size(),100);
printf("arr2:\n");
for(auto i:arr2){
printf("%d,",(int)i);
}
printf("\nWrite ret status: %d\nRead ret status: %d\n",ret1,ret2);
}
Instead what I get on my terminal is :
arr2:
70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Write ret status: 0
Read ret status: 0
arr2:
68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Write ret status: 0
Read ret status: 0
Notice ,that the first line of prints has some differences with the second and the second is recurring (so the while true at the first time print a little bit different things than the others) I honestly think I have confused myself with the constant parameters I give to HAL_I2C_Mem_Write
and read
and I would like some explanation on that too.
For more info comment me and I will provide all the necessary diagnostics/initializations etc.
Thanks to the comments I managed to send a byte at whatever address I want . One noticed error on the previous code is the MemAddress
parameter( third parameter of HAL_I2C_Write_Mem
) ,because my eeprom is 11 bit addressable I should declare to hal that it is 16 and not 8 as the 5 extra bits are ignored bits ,but less than 11 might malfunction.
A second problem was that I was trying to write more than 32 bytes and I was reading only the first 32 as the protocol doesn't accept writing or reading more than one 32 byte page at a time. So here is the modified code with some comments on the changes:
std::array<uint8_t,32> arr{0}; //32 bytes instead of something silly
unsigned counter=0;
for(auto&i :arr){
i=counter;
counter++;
}
// 0x20 is a start of a page so it can write all 32 bits
// I2C_MEMADD_SIZE_16BIT is the value 2 instead of 1 I had
// The extra 5 bits are ignored
// For the testing I call the blocking write
auto ret1 = HAL_I2C_Mem_Write(&hi2c1 , 0xa0 , 0x20 , I2C_MEMADD_SIZE_16BIT , arr.data() , arr.size(),4);
HAL_Delay(4);
std::array<uint8_t,32> arr2{0};
arr2.fill(1);
auto ret2 = HAL_I2C_Mem_Read( &hi2c1 , 0xa1 , 0x20 , I2C_MEMADD_SIZE_16BIT , arr2.data() ,arr2.size(),4);
HAL_Delay(4);
printf("arr2: ");
for(auto i:arr2)
printf(" %d,",(int)i);
printf("\nWrite ret status: %d\nRead ret status: %d\n",ret1,ret2);