i2c problem win stm32F412 Topic is solved

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: barthess, RoccoMarco

enrico.dallavia
Posts: 104
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 1 time

i2c problem win stm32F412

Postby enrico.dallavia » Wed Aug 26, 2020 6:27 pm

Hello,
I'm stuck with a problem with i2c, it seems the chibios 20.3.1 is not producing any signal from i2c1 (pin PB7 and PB8). They are configured as: alternate(4), high speed, opendrain.
But every attempt give me -2 as status and i2cGetErrors is 4

Code: Select all

static const I2CConfig i2ccfg = {
OPMODE_I2C,
400000,
FAST_DUTY_CYCLE_2,
};

static THD_FUNCTION(reader_thread, arg) {
 
  chRegSetThreadName("reader");
 
  (void)arg;

  uint8_t txbuf[2];
  uint8_t rxbuf[2];

  txbuf[0] = 0x00;
  txbuf[1] = 0x00;

  chThdSleepMilliseconds(1000);

  chprintf(chout, "entrato lettura\r\n");
 
  chThdSleepMilliseconds(1000);

  sysinterval_t tmo = TIME_MS2I(100);

  i2caddr_t addr = 0xA1;
   
  i2cStart(&I2CD1,&i2ccfg);

  chprintf(chout, "partito driver i2c: %d\r\n",I2CD1.state);

  chThdSleepMilliseconds(1000);
 
  while(true) {

    chprintf(chout, "invio richiesta\r\n");
    chThdSleepMilliseconds(100);

    i2cAcquireBus(&I2CD1);
   
    msg_t status = i2cMasterTransmit(&I2CD1, addr, txbuf, 1, rxbuf, 0);

    i2cReleaseBus(&I2CD1);
   
    chprintf(chout, "risultato: %d [%d]\r\n", status, i2cGetErrors(&I2CD1));

    chThdSleepMilliseconds(1000);
  }
}


What it bother me is that if I use the CubeMxIDE with STM primitives, I've got both the signals on the pin and the correct answer from the eeprom I'm trying to access

Code: Select all

uint8_t data[10];

  char buff[64];
  /* Infinite loop */
  for(;;)
  {
     HAL_UART_Transmit(&huart6, "i2cTest\r\n", strlen("i2cTest\r\n"),10);
     data[0] = 0xFA;

     if (HAL_I2C_Master_Transmit(&hi2c1, 0xA0, data, 1, HAL_MAX_DELAY) == HAL_OK) {
        for(int i = 0; i < 6; i+=1) {
           if( HAL_I2C_Master_Receive(&hi2c1, 0xA1, &data[i], 1, HAL_MAX_DELAY) == HAL_OK) {
           } else {
              HAL_UART_Transmit(&huart6, "receive fails\r\n", strlen("receive fails\r\n"),10);
           }
        }

        sprintf(buff,"%x %x %x %x %x %x\n\r", data[0], data[1], data[2], data[3], data[4], data[5]);

        HAL_UART_Transmit(&huart6, buff, strlen(buff),10);
     } else {
        HAL_UART_Transmit(&huart6, "transmit fails\r\n", strlen("transmit fails\r\n"),10);
     }


     osDelay(1000);
  }


The other periphericals enabled in chconf is the USART6 and USB_OTG (and they works fine). The clock is configured exactly as CubeMx.
I have used few years ago chibios 3 for reading from i2c with an STM32F429 and the settings for the pin / initialization of the driver / writing are almost the same. Could it be another settings I'm not aware of for this board? I've already searched inside the forum for some idea (I've disabled most of the other peripherical to avoid dma conflict, check for correct pin assignment, ecc)
I would rather not to switch to CubeMxIde because I find Chibios more easy to work with.
Any help / suggestion would be very appreciate.

ps: if the pin is wrongly configured, is there any means to check them at runtime (like a variable where I can check the bitmask for the correctness)?

Thanks

Enrico

User avatar
Giovanni
Site Admin
Posts: 13086
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 759 times
Been thanked: 637 times
Contact:

Re: i2c problem win stm32F412  Topic is solved

Postby Giovanni » Wed Aug 26, 2020 6:34 pm

You may inspect the GPIO registers and verify settings, also make sure you have NOT assigned the same peripheral function to multiple pins. Also verify the address, "A1" is not valid, you need to pass only the 7 address bits aligned to right without the RW bit.

Giovanni

enrico.dallavia
Posts: 104
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 1 time

Re: i2c problem win stm32F412

Postby enrico.dallavia » Thu Aug 27, 2020 9:09 am

Good morning.
Thank you Giovanni for the useful tips, indeed the problem was the address!
After looking in the primitive STM32/LLD/I2Cv1/hal_i2c_lld.c I found out that the i2c address is composed by shifting left by 1 the original address I gave to the API function.

Code: Select all

msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
                                      const uint8_t *txbuf, size_t txbytes,
                                      uint8_t *rxbuf, size_t rxbytes,
                                      sysinterval_t timeout) {
  I2C_TypeDef *dp = i2cp->i2c;
  systime_t start, end;
  msg_t msg;

#if defined(STM32F1XX_I2C)
  osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));
#endif

  /* Resetting error flags for this transfer.*/
  i2cp->errors = I2C_NO_ERROR;

  /* Initializes driver fields, LSB = 0 -> transmit.*/
 i2cp->addr = (addr << 1);
 
  .............


On the other side, the STM primitive from CubeMx, take the address as it as, and only perform a binary AND to set the R/W bit

Code: Select all

if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
  {
    /* Send slave address */
    hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
  }


where I2C_7BIT_ADD_WRITE is a #define as follows

Code: Select all

#define I2C_OAR1_ADD0  0x01
#define I2C_7BIT_ADD_WRITE(__ADDRESS__)                    ((uint8_t)((__ADDRESS__) & (uint8_t)(~I2C_OAR1_ADD0)))
#define I2C_7BIT_ADD_READ(__ADDRESS__)                     ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))


So I can't take the same address I wrote in CubeMx on ChibiOS.
Changing my address to 0x50 do the trick! And now I'm happily reading the data from the eeprom with ChibiOS!

THANKS for the help

Enrico


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 3 guests