i2c driver problem after resume from standby

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

Moderator: RoccoMarco

enrico.dallavia
Posts: 105
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 2 times

Re: i2c driver problem after resume from standby

Post by enrico.dallavia »

I found the origin of system's hang,

inside

Code: Select all

msg_t i2cMasterTransmitTimeout(I2CDriver *i2cp,
                               i2caddr_t addr,
                               const uint8_t *txbuf,
                               size_t txbytes,
                               uint8_t *rxbuf,
                               size_t rxbytes,
                               systime_t timeout) {


I got

Code: Select all

osalDbgCheck((i2cp != NULL) && (addr != 0U) &&
               (txbytes > 0U) && (txbuf != NULL) &&
               ((rxbytes == 0U) || ((rxbytes > 0U) && (rxbuf != NULL))) &&
               (timeout != TIME_IMMEDIATE));


which has an argument of 0 from the result of
(i2cp != NULL) && (addr != 0U) &&
(txbytes > 0U) && (txbuf != NULL) &&
((rxbytes == 0U) || ((rxbytes > 0U) && (rxbuf != NULL))) &&
(timeout != TIME_IMMEDIATE);
enrico.dallavia
Posts: 105
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 2 times

Re: i2c driver problem after resume from standby

Post by enrico.dallavia »

after fix the 0 assert, now the system hangs on

osalSysLock();

does for stm32f429, calls the following code?

Code: Select all

static inline void port_lock(void) {

#if CORTEX_SIMPLIFIED_PRIORITY == FALSE
  __set_BASEPRI(CORTEX_BASEPRI_KERNEL);
#else /* CORTEX_SIMPLIFIED_PRIORITY */
  __disable_irq();
#endif /* CORTEX_SIMPLIFIED_PRIORITY */
}

and

__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
  __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
}



if yes, what could bring the system to hangs?
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: i2c driver problem after resume from standby

Post by Giovanni »

Fixed the assert?

You fixed the effect not the cause...

Also define "hangs": http://chibios.org/dokuwiki/doku.php?id ... ebug_guide

Giovanni
enrico.dallavia
Posts: 105
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 2 times

Re: i2c driver problem after resume from standby

Post by enrico.dallavia »

Sorry, I mean I've fixed the call of function which I used with bad params (so it was corrent that the ChibiOs went to a chSysHalt(__func__); )

after a lot of difficulties I got from gdb the following backtrace
#0 chSysHalt (reason=0x8033f00 <__func__.7798> "i2cMasterTransmitTimeout") at ../../../os/rt/src/chsys.c:179
#1 0x08005164 in i2cMasterTransmitTimeout (i2cp=0x20001808 <I2CD1>, addr=52, txbuf=0x20000768 "", txbytes=2, rxbuf=0x0, rxbytes=0, timeout=4294967295) at ../../../os/hal/src/i2c.c:237
#2 0x08019962 in i2c_write_reg (reg=0 '\000', val=118 'v') at ../../../ugfx/boards/base/STM32F429i-BigBoard/board_STM32F429i-BigBoard.h:129
#3 0x08019b4a in InitController (g=0x2000dc38) at ../../../ugfx/drivers/gdisp/STM32F429i-BigBoard/gdisp_lld_STM32F429i-BigBoard.c:123
#4 0x08019fca in gdisp_lld_init (g=0x2000dc38) at ../../../ugfx/drivers/gdisp/STM32F429i-BigBoard/gdisp_lld_STM32F429i-BigBoard.c:382
#5 0x08011b66 in _gdispInitDriver (g=0x2000dc38, param=0x0, driverinstance=0, systeminstance=0) at ../../../ugfx/src/gdisp/gdisp.c:649
#6 0x080114bc in gdriverRegister (vmt=0x8050650 <GDISPVMT_OnlyOne>, param=0x0) at ../../../ugfx/src/gdriver/gdriver.c:63
#7 0x08011af2 in _gdispInit () at ../../../ugfx/src/gdisp/gdisp.c:599
#8 0x0801130a in gfxInit () at ../../../ugfx/src/gfx.c:115
#9 0x08021ff6 in main () at main.c:296
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: i2c driver problem after resume from standby

Post by Giovanni »

So, there is an assertion that fails, have you checked the condition?

Giovanni
enrico.dallavia
Posts: 105
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 2 times

Re: i2c driver problem after resume from standby

Post by enrico.dallavia »

ok, I have 2 kind of problems:

1) when I use the reset button on my board, when system starts again I got inside i2cMasterTransmitTimeout: i2cp->state != I2C_READY that makes system fails on osalDbgAssert(i2cp->state == I2C_READY, "not ready");

2) when the system went under standby and wakes up, the crash happens on osalSysLock();

for the problem nr 1 I'm not so troubled, since only the prototype has reset button, so it is not my top priority to solve this.

for problem nr 2, I'm quite confused (because if I'm not mistaken, it should disable the interrupts only)

and I've a problem to trigger problem nr 2 because, after loading the program with gdb and openocd, I'm always falling on problem nr 1.
is there a way to start the program erasing everything from memory (like I'm booting from power lost)?
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: i2c driver problem after resume from standby

Post by Giovanni »

Not ready means that the I2C driver has not been started, it is a SW issue.

I also doubt that the crash is actually a crash, does it go in the exception handler?

Giovanni
enrico.dallavia
Posts: 105
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 2 times

Re: i2c driver problem after resume from standby

Post by enrico.dallavia »

mhhh, I've tried this so I will make first time the initialization of the screen that uses i2c bus to talk with the display controller
flash program, detach power for a cold boot.
i2c bus works fine
then go to standby.

when wake up try to check if the chSysLock() call works. With my disappointment IT WORK.

Code: Select all

int main(void) {
    /*
    * System initializations.
    * - HAL initialization, this also initializes the configured device drivers
    *   and performs the board-specific initializations.
    * - Kernel initialization, the main() function becomes a thread and the
    *   RTOS is active.
    */
    halInit();
    chSysInit();

    palClearPad(GPIOA,GPIOA_PWR_OFF);

    wkup = 0;

    palSetPad(GPIOC,GPIOC_2V5_EN);//2.5v en

    sdStart(&SERIAL_PORT, NULL);

    chprintf((BaseSequentialStream *)&SERIAL_PORT, "\r\nApplication started!\r\n");

    /* Initialize backup SRAM */
    //TM_BKPSRAM_Init();//non serve visto che ho abilitato in mcuconf.h la backup sram!

    //TestBkpRam();

    if (TM_LOWPOWER_StandbyReset()) {

        chprintf((BaseSequentialStream *)&SERIAL_PORT, "detect wakeup from standby!\r\n");

        wkup = 1;

#if 1
        chThdCreateStatic(waThread10, sizeof(waThread10), NORMALPRIO, Thread10, NULL);

        chThdSleepMilliseconds(1000);

        chSysLock();

        chSysUnlock();

         while (true) {
            chThdSleepMilliseconds(1000);
        }
 #endif
    }

   
    i2cStart(&I2CD1, &i2cfg1);

    chThdCreateStatic(waThread10, sizeof(waThread10), NORMALPRIO, Thread10, NULL);

    SRAM_Init();

    // Clear the SDRAM
    memset((void *)SRAM_BANK_ADDR, 0, 0x400000);

    chThdSleepMilliseconds(1000);

    NOR_Init();

    ffs_init();

    chHeapObjectInit(&ext_heap, (void*)(SRAM_BANK_ADDR+4*1024*1024), 10*1024*1024);

    ImgManagement_Init();

    gfxInit();

    TM_LOWPOWER_DisableWakeUpPin();

    PWR_ClearFlag(PWR_FLAG_SB | PWR_FLAG_WU);

    TM_LOWPOWER_EnableWakeUpPin();

    chThdSleepMilliseconds(1000);

    TM_LOWPOWER_Standby();

    while (true) {
        chThdSleepMilliseconds(1000);
    }

}


But I'm sure, since I got the log from serial, that after a standby and wakup, the system hangs around osalSysLock(); inside i2cMasterTransmitTimeout, because I've checked the argument of osalDbgCheck(chk); and osalDbgAssert(i2cp->state == I2C_READY, "not ready"); and both are good (I reach the first chprintf((BaseSequentialStream *)&SERIAL_PORT, "%s: %d\n\r",__func__,i++);)

Code: Select all

  osalDbgCheck(chk);

  osalDbgAssert(i2cp->state == I2C_READY, "not ready");

if(wkup){
      chprintf((BaseSequentialStream *)&SERIAL_PORT, "%s: %d\n\r",__func__,i++);
      chThdSleepMilliseconds(250);
  }

  osalSysLock();
  i2cp->errors = I2C_NO_ERROR;
  i2cp->state = I2C_ACTIVE_TX;
  if(wkup){
      chprintf((BaseSequentialStream *)&SERIAL_PORT, "%s: %d\n\r",__func__,i++);
      chThdSleepMilliseconds(250);
  }
  rdymsg = i2c_lld_master_transmit_timeout(i2cp, addr, txbuf, txbytes,
                                           rxbuf, rxbytes, timeout);



So I don't understand.. and quite lost..
enrico.dallavia
Posts: 105
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 2 times

Re: i2c driver problem after resume from standby

Post by enrico.dallavia »

I've got i2cStart(&I2CD1, &i2cfg1); just after halInit(); chSysInit();

and still after a standby, from i2c

Application started!
detect wakeup from standby!
enter blinker thread

FMC FLASH INIT
1
2
3
4
5

load_fs
ImgManagement_Init: available 10485752 bytes
gfxInit
_gdispInit
GDISPVMT const GDISPVMT_OnlyOne[1];
gdriverRegister

chHeapAlloc: 96
gdisp_lld_init
InitController
i2cMasterTransmitTimeout: 0

the system won't go after osalSysLock();

Code: Select all

osalDbgCheck(chk);

  osalDbgAssert(i2cp->state == I2C_READY, "not ready");

if(wkup){
      chprintf((BaseSequentialStream *)&SERIAL_PORT, "%s: %d\n\r",__func__,i++);
      chThdSleepMilliseconds(250);
  }

  osalSysLock();
  i2cp->errors = I2C_NO_ERROR;
  i2cp->state = I2C_ACTIVE_TX;
enrico.dallavia
Posts: 105
Joined: Thu Mar 12, 2015 10:15 am
Has thanked: 2 times

Re: i2c driver problem after resume from standby

Post by enrico.dallavia »

I've tried also

Code: Select all

int main(void) {
    halInit();
    chSysInit();

    palClearPad(GPIOA,GPIOA_PWR_OFF);

    wkup = 0;

    palSetPad(GPIOC,GPIOC_2V5_EN);//2.5v en

    sdStart(&SERIAL_PORT, NULL);

    i2cStop(&I2CD1);

    i2cStart(&I2CD1, &i2cfg1);


flash appliucation, works fine, if I push reset button, so the program starts from first line of main again, I got the message
i2cMasterTransmitTimeout: i2cp->state != I2C_READY
:roll:
Post Reply