I2C err

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
steved
Posts: 550
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 4 times
Been thanked: 58 times

Re: I2C err

Postby steved » Sat Sep 08, 2018 3:47 pm

BreederBai wrote:
Giovanni wrote:Are I2C pins programmed in the right way? do you have external pull up resistors? there are several possible causes for the I2C to hang, how you call that function is not very important.

Giovanni


Hello, I am using PB6, 7 pins, configured as ‘Alternate Open Drain output 2MHz’ Mode, initial level is high.

Code: Select all

#define VAL_GPIOBCRL            0xEE222888
#define VAL_GPIOBCRH            0x88488A48
#define VAL_GPIOBODR            ((1 << 6) | (1 << 7))

The submission number of the ChibiOS I am using is 7d187a140e64db297eb5ef788f0f5dc0dd0d3fde, November 21, 2016 4:52 PM.
I have an external pull-up resistor and the pull-up resistor is 1K.

This make it look as if you are manually writing to the CPIO registers, rather than using Chibi's capabilities.
Have you configured the relevant alternate function number? (I've not used the 32F1XX family, but on the 32F4XX, which has the same I2C peripheral, its AF4).
It also looks as if you might be using a relatively old version of ChibiOs (although the I2C has worked fine for years).
You can generally set up the initial mode etc for I/O pins in the board configuration file; then you just need to do i2cstart().

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

Re: I2C err

Postby Giovanni » Sat Sep 08, 2018 4:08 pm

On F1 (GPIOv1) there are no alternate numbers, just alternate or not.

The driver is very old and proved to work, probably the problem is not where you are looking, I would bet on some HW issue (because bus locked).

Giovanni

BreederBai
Posts: 19
Joined: Tue Aug 14, 2018 3:57 pm

Re: I2C err

Postby BreederBai » Sun Sep 09, 2018 6:18 am

Giovanni wrote:On F1 (GPIOv1) there are no alternate numbers, just alternate or not.

The driver is very old and proved to work, probably the problem is not where you are looking, I would bet on some HW issue (because bus locked).

Giovanni


I also suspect the reason for the hardware configuration.This is the code for my print debug information.

Code: Select all

os::lowsyslog("read in\n");

    i2cAcquireBus(&I2C);
    os::lowsyslog("read out,%d\n",int(i2cMasterTransmitTimeout(&I2C,
                               HAL_COMPASS_IST8310_I2C_ADDR,
                               tx_buf.data(),
                               tx_buf.size(),
                               rx_buf.data(),
                               rx_buf.size(),
                               10)));//TIME_INFINITE
    i2cReleaseBus(&I2C);


This is the debug information printed.

Code: Select all

Bootloader struct values: CAN bitrate: 1000000, UAVCAN Node ID: 125             
UniqueID :38FFD9054747353644301643                                             
re                                                                             
PANIC [mag_ist8310] i2c_lld_master_transmit_timeout                             
                                                                               
Core registers:                                                                 
CONTROL 2                                                                       
IPSR    0                                                                       
APSR    60000000                                                               
xPSR    60000000                                                               
PRIMASK 1                                                                       
BASEPRI 20                                                                     
FAULTMASK       0                                                               
                                                                               
Process stack:                                                                 
Pointer 20003328                                                               
R0      2                                                                       
R1      30325555                                                               
R2      35353233                                                               
R3      1003333                                                                 
R12     8030e90                                                                 
R14[LR] 40005400                                                               
R15[PC] 0                                                                       
PSR     a                                                                       
                                                                               
Main stack:                                                                     
Pointer 20000900                                                               
R0      55555555                                                               
R1      55555555                                                               
R2      55555555                                                               
R3      55555555                                                               
R12     55555555                                                               
R14[LR] 55555555                                                               
R15[PC] 55555555                                                               
PSR     55555555                                                               
                                                                               
SCB:                                                                           
AIRCR   fa050300                                                               
SCR     0                                                                       
CCR     0                                                                       
SHCSR   0                                                                       
CFSR    0                                                                       
HFSR    0                                                                       
DFSR    0                                                                       
MMFAR   e000ed34                                                               
BFAR    e000ed38                                                               
AFSR    0               


By debugging the code and debugging information, it can be seen that the debugging information is not printed and the operating system is restarted. It should be that the I2C read/write program triggered a hardware error.I am talking to you through Google Translate, I hope you can understand my reply.

steved
Posts: 550
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 4 times
Been thanked: 58 times

Re: I2C err

Postby steved » Sun Sep 09, 2018 8:28 am

Check that you have sufficient stack allocated to the task that reads the I2c.

(If you use ChibiStudio, in includes a plugin that can show you stack usage)

Polux
Posts: 11
Joined: Thu Apr 28, 2016 11:52 am
Been thanked: 3 times

Re: I2C err

Postby Polux » Mon Sep 10, 2018 7:33 am

From the message "i2c_lld_master_transmit_timeout" you could find the possible cause in the source code.

My guess is your peripheral is not correctly receiving, and it is not answering the read/write request => timout.

The peripheral address could be also wrong. Check if the address is not depending of some CS line on the chip. I had an issue with MS5611 (barometric pressure sensor), the address LSB is connected to a pin. On all flight controllers, this pin is connected to Vcc, but on mine it is connected to Gnd. Obviously, I had to change the address in the ArduPilot config, after searching for hours what was wrong :oops: .

Angelo

BreederBai
Posts: 19
Joined: Tue Aug 14, 2018 3:57 pm

Re: I2C err

Postby BreederBai » Tue Sep 11, 2018 2:05 am

Polux wrote:From the message "i2c_lld_master_transmit_timeout" you could find the possible cause in the source code.

My guess is your peripheral is not correctly receiving, and it is not answering the read/write request => timout.

The peripheral address could be also wrong. Check if the address is not depending of some CS line on the chip. I had an issue with MS5611 (barometric pressure sensor), the address LSB is connected to a pin. On all flight controllers, this pin is connected to Vcc, but on mine it is connected to Gnd. Obviously, I had to change the address in the ArduPilot config, after searching for hours what was wrong :oops: .

Angelo

"i2c_lld_master_transmit_timeout" is a function.I guess the error was triggered while executing this function. Because the operating system does not restart when the I2C read/write function is not called.

BreederBai
Posts: 19
Joined: Tue Aug 14, 2018 3:57 pm

Re: I2C err

Postby BreederBai » Tue Sep 11, 2018 2:27 am

steved wrote:Check that you have sufficient stack allocated to the task that reads the I2c.

(If you use ChibiStudio, in includes a plugin that can show you stack usage)


I am using ”make“ compiled ChibiOS, may I ask how to increase the I2C stack in this case

steved
Posts: 550
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 4 times
Been thanked: 58 times

Re: I2C err

Postby steved » Tue Sep 11, 2018 8:12 am

BreederBai wrote:
steved wrote:Check that you have sufficient stack allocated to the task that reads the I2c.

(If you use ChibiStudio, in includes a plugin that can show you stack usage)


I am using ”make“ compiled ChibiOS, may I ask how to increase the I2C stack in this case

Updating the stack size is nothing to do with the development environment.

There isn't a specific stack for I2C; you need to ensure that there is sufficient stack space assigned to the thread(s) which call I2C routines.

For the main thread, this is done in the main make file (USE_PROCESS_STACKSIZE). For other threads, its specified when you create the thread.

BreederBai
Posts: 19
Joined: Tue Aug 14, 2018 3:57 pm

Re: I2C err

Postby BreederBai » Mon Sep 17, 2018 7:14 am

I found a strange phenomenon,When I commented the code like this.Calling the i2cMasterTransmitTimeout function will still restart.

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,
                                      systime_t timeout) {
  I2C_TypeDef *dp = i2cp->i2c;
  systime_t start, end;

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

  /* Releases the lock from high level driver.*/
  //osalSysUnlock();

  /* TX DMA setup.*/
//  dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
//  dmaStreamSetMemory0(i2cp->dmatx, txbuf);
//  dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);

  /* RX DMA setup.*/
//  dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
//  dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
//  dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);

  /* Calculating the time window for the timeout on the busy bus condition.*/
//  start = osalOsGetSystemTimeX();
//  end = start + OSAL_MS2ST(STM32_I2C_BUSY_TIMEOUT);

  /* Waits until BUSY flag is reset or, alternatively, for a timeout
     condition.*/
//  while (true) {
    osalSysLock();

    /* If the bus is not busy then the operation can continue, note, the
       loop is exited in the locked state.*/
//    if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))
//      break;

    /* If the system time went outside the allowed window then a timeout
       condition is returned.*/
//    if (!osalOsIsTimeWithinX(osalOsGetSystemTimeX(), start, end))
//      return MSG_TIMEOUT;

    osalSysUnlock();
//  }

  /* Starts the operation.*/
  //dp->CR2 |= I2C_CR2_ITEVTEN;
  //dp->CR1 |= I2C_CR1_START;

  /* Waits for the operation completion or a timeout.*/
  //return osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
  return true;
}

But after I commented out osalSysLock() and osalSysUnlock(), the system will not restart repeatedly.But when I further commented and modified the code, the system started to restart again and again.

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,
                                      systime_t timeout) {
  I2C_TypeDef *dp = i2cp->i2c;
  systime_t start, end;

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

  /* Releases the lock from high level driver.*/
  //osalSysUnlock();

  /* TX DMA setup.*/
//  dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
//  dmaStreamSetMemory0(i2cp->dmatx, txbuf);
//  dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);

  /* RX DMA setup.*/
//  dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
//  dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
//  dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);

  /* Calculating the time window for the timeout on the busy bus condition.*/
//  start = osalOsGetSystemTimeX();
//  end = start + OSAL_MS2ST(STM32_I2C_BUSY_TIMEOUT);

  /* Waits until BUSY flag is reset or, alternatively, for a timeout
     condition.*/
//  while (true) {
    //osalSysLock();

    /* If the bus is not busy then the operation can continue, note, the
       loop is exited in the locked state.*/
//    if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))
//      break;

    /* If the system time went outside the allowed window then a timeout
       condition is returned.*/
//    if (!osalOsIsTimeWithinX(osalOsGetSystemTimeX(), start, end))
//      return MSG_TIMEOUT;

    //osalSysUnlock();
//  }

  /* Starts the operation.*/
  //dp->CR2 |= I2C_CR2_ITEVTEN;
  //dp->CR1 |= I2C_CR1_START;

  /* Waits for the operation completion or a timeout.*/
  return osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
  //return true;
}

BreederBai
Posts: 19
Joined: Tue Aug 14, 2018 3:57 pm

Re: I2C err

Postby BreederBai » Tue Sep 18, 2018 3:09 am

Giovanni wrote:On F1 (GPIOv1) there are no alternate numbers, just alternate or not.

The driver is very old and proved to work, probably the problem is not where you are looking, I would bet on some HW issue (because bus locked).

Giovanni


After debugging, I found that the system restarts should be related to this broken code.

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,
                                      systime_t timeout) {
  I2C_TypeDef *dp = i2cp->i2c;
  systime_t start, end;

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

  /* Releases the lock from high level driver.*/
  osalSysUnlock();


In this line, if read a byte, an error will be reported. The system will be stuck in an infinite loop until the watchdog times out and the system restarts.

Code: Select all

osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));


Return to “ChibiOS/HAL”

Who is online

Users browsing this forum: No registered users and 1 guest