c++memorystm32i2ceeprom

EEPROM protocol misconception


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.


Solution

  • 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);