This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2650 project based on SimpleBleCentral keeps rebooting.

Other Parts Discussed in Thread: CC2650

I have a project based on the CC2650 SimpleBleCentral that keeps rebooting after some random interval of time.

Are there any register that can point out the reason for the last boot?

I have enabled #define HEAPMGR_METRICS and I do not seem to have any heap issues. Anything else I can look-up for diagnostic purposes?

Also, running from under IAR with debugger, I only get a message that the CPU stops responding.

Can I have some help please?

  • Are you using custom HW? Can you try to get the reset reason?
    You can get the reset reason using this API
    /* Get the reason for reset */
    uint32_t rSrc = SysCtrlResetSourceGet();
  • Hi Christiin,

    What is the header file for SysCtrlResetSourceGet() ?
  • #include <driverlib/sys_ctrl.h>
  • Hi Christin,

    I suspect some kind of software reason for rebooting, I have two custom board with regulated power and they both run the same software and reboot every few minutes. This is very annoying. Is there any way to know if the watchdog was used to reboot the device?
  • Have you tried to read out the reason yet? If you did not implement watchdog, then it's not possible to have watchgod reset in your program as we did not have it in our example program.

    Our TRM states "The watchdog causes a warm reset in the system. This warm reset can be blocked by

    ICEPick, which is useful for debugging. When ICEPick is asserted, the warm reset is blocked

    from the rest of the system; however, watchdog itself is reset."

    If you read back the value you got from this API SysCtrlResetSourceGet(), you will get warm reset as result

  • Hi Christin,

    My target is now instrumented to report SysCtrlResetSourceGet(), I am waiting for reboot to find out what is returned.
    Note that I am implementing a watchdog.
  • Hi Christin,

    SysCtrlResetSourceGet() reports 0x00000001

    That may be consistent with a watchdog. Is there any way to know why?
  • Hi Christin,

    SysCtrlResetSourceGet() reports 0x00000007

    I am not sure I understand the #define for the return values:

    //*****************************************************************************
    // \name Return values from calling SysCtrlResetSourceGet()
    //@{
    //*****************************************************************************
    #define RSTSRC_PWR_ON (( AON_SYSCTL_RESETCTL_RESET_SRC_PWR_ON >> AON_SYSCTL_RESETCTL_RESET_SRC_S ))
    #define RSTSRC_PIN_RESET (( AON_SYSCTL_RESETCTL_RESET_SRC_PIN_RESET >> AON_SYSCTL_RESETCTL_RESET_SRC_S ))
    #define RSTSRC_VDDS_LOSS (( AON_SYSCTL_RESETCTL_RESET_SRC_VDDS_LOSS >> AON_SYSCTL_RESETCTL_RESET_SRC_S ))
    #define RSTSRC_VDD_LOSS (( AON_SYSCTL_RESETCTL_RESET_SRC_VDD_LOSS >> AON_SYSCTL_RESETCTL_RESET_SRC_S ))
    #define RSTSRC_VDDR_LOSS (( AON_SYSCTL_RESETCTL_RESET_SRC_VDDR_LOSS >> AON_SYSCTL_RESETCTL_RESET_SRC_S ))
    #define RSTSRC_CLK_LOSS (( AON_SYSCTL_RESETCTL_RESET_SRC_CLK_LOSS >> AON_SYSCTL_RESETCTL_RESET_SRC_S ))
    #define RSTSRC_SYSRESET (( AON_SYSCTL_RESETCTL_RESET_SRC_SYSRESET >> AON_SYSCTL_RESETCTL_RESET_SRC_S ))
    #define RSTSRC_WARMRESET (( AON_SYSCTL_RESETCTL_RESET_SRC_WARMRESET >> AON_SYSCTL_RESETCTL_RESET_SRC_S ))
    #define RSTSRC_WAKEUP_FROM_SHUTDOWN (( AON_SYSCTL_RESETCTL_RESET_SRC_M >> AON_SYSCTL_RESETCTL_RESET_SRC_S ) + 1 )
    //@}

    // Field: [3:1] RESET_SRC
    //
    // Shows the source of the last system reset:
    // Occurrence of one of the reset sources may trigger several other reset
    // sources as essential parts of the system are undergoing reset. This field
    // will report the root cause of the reset (not the other resets that are
    // consequence of the system reset).
    // To support this feature the actual register is not captured before the reset
    // source being released. If a new reset source is triggered, in a window of
    // four 32 kHz periods after the previous has been released, this register
    // may indicate Power on reset as source.
    // ENUMs:
    // WARMRESET Software reset via PRCM warm reset request
    // SYSRESET Software reset via SYSRESET register
    // CLK_LOSS Clock loss detect
    // VDDR_LOSS Brown out detect on VDDR
    // VDD_LOSS Brown out detect on VDD
    // VDDS_LOSS Brown out detect on VDDS
    // PIN_RESET Reset pin
    // PWR_ON Power on reset
    #define AON_SYSCTL_RESETCTL_RESET_SRC_M 0x0000000E
    #define AON_SYSCTL_RESETCTL_RESET_SRC_S 1
    #define AON_SYSCTL_RESETCTL_RESET_SRC_WARMRESET 0x0000000E
    #define AON_SYSCTL_RESETCTL_RESET_SRC_SYSRESET 0x0000000C
    #define AON_SYSCTL_RESETCTL_RESET_SRC_CLK_LOSS 0x0000000A
    #define AON_SYSCTL_RESETCTL_RESET_SRC_VDDR_LOSS 0x00000008
    #define AON_SYSCTL_RESETCTL_RESET_SRC_VDD_LOSS 0x00000006
    #define AON_SYSCTL_RESETCTL_RESET_SRC_VDDS_LOSS 0x00000004
    #define AON_SYSCTL_RESETCTL_RESET_SRC_PIN_RESET 0x00000002
    #define AON_SYSCTL_RESETCTL_RESET_SRC_PWR_ON 0x00000000

    Value 0x07 is bit 0 1 and 2 set. Define for return value is shifting right by 1 bit (divide by 2) so 0x0E / 2 = 7 so I guess I have a warm reset caused by the watchdog, right?
  • Hi Claude,

    Your asessment is correct, it looks like you are dealing with a warm reset. However, I don't believe it was the watchdog that triggered this. You mentioned that you did not implement the watchdog functionality and our SDK examples don't use it by default.

    The watchdog isn't the only source of a warm reset, they can also be caused by (from comments in hw_pcrm.h)
    // System CPU reset request, CPU_SCS:AIRCR.SYSRESETREQ
    // System CPU Lockup

    So either the CPU locked up or the device called a warm reset from firmware by writing to the SYSRESETREQ register.

    Can you check the LOCKUP_STAT bitfield of the PRCM_O_WARMRESET register to see if a lockup has occurred? See section 6.2.4.37 of the TRM for more info.
  • Sorry if I mislead you, the watchdog is implemented.

    Where can I access this TRM? Can you give me the path for the document?
  • Claude,

    You can find the TRM (Technical Reference Manual) here

    You will find CH 6 to be the most helpfu.

  • I consulted swcu177f.pdf, (revision june 2016) and cant find section 6.2.4 (got document from wiki at processors.wiki.ti.com/.../Category:BluetoothLE)
    Maybe you mean section [6.8.2.4.37 WARMRESET Register (Offset = 110h) [reset = 0h]]
  • Yes, that is the correct section.
  • Hi Sean2,

    How would I go about reading PRCM_O_WARMRESET register?
    I am a C/C++ programmer, so a ram mapped register at 0x110 does this mean something like this:

    uint32_t* register = PRCM_O_WARMRESET;
    uint32_t regValue = *register;
  • Hi Sean,

    I would read it like this:

    #include <driverlib/prcm.h>
    uint32_t regValue = HWREG( PRCM_O_WARMRESET );

    right ?
  • When unexpected boot occurs:

    PRCMWdtResetStatus() yields 0x00
    PRCM_O_WARMRESET yields 0x00000000
    SysCtrlResetSourceGet(); yields 0x0000000007

    Now what how can I interpret this?
  • Note that I have swapped units with CC2650 CPU, the behaviour is the same on both units, so I can safely put aside any flaky hw component issue.
    So I have a warm reset but it does not seem that I have anything to explain why the warm reset took place.
    Or I have a clue that the reset did not take place because of the watchdog.
    I also know that the memory heap is clean.

    Is there a way for me to put a breakpoint somewhere using IAR and know more about the cause for the boot?

    I suspect a low level condition in the stack software, would there be a way to find out about this?
  • Regarding the register read, you need a base address + the offset.
    In your case, it would be the following:

    #include <inc/hw_prcm.h>
    uint32_t regValue = HWREG(PRCM_BASE + PRCM_O_WARMRESET);


    What you are reading now does not make sense. Can you give it a try again, and keep us posted? Thanks!
  • Hi Christin,

    Is there an order I should read these values?

    Some of the registers have side effects, reading them causes some of the bits to be cleared.

    This is how I read these informations:

    uint32_t bootReason = SysCtrlResetSourceGet(); // 0x00000007

    uint32_t resetStatus = HWREG( PRCM_O_WARMRESET ); // 0x00000000

    uint8_t   watchdogResetStatus = PRCMWdtResetStatus();   // 0x00

    Please advise,

    Best regards,

    Claude

  • As stated in the comment, you can't use the following line.

    uint32_t resetStatus = HWREG( PRCM_O_WARMRESET ); // 0x00000000

    You need to use base address + offset
    uint32_t regValue = HWREG(PRCM_BASE + PRCM_O_WARMRESET);
  • Hi Christin,

    Sorry -- I did not catch that the first time around. I a testing again and will post results soon.

    Best regards,
    Claude
  • Hi, after flashing the unit I have these values, does it make sense?

    watchdogResetStatus 0x00
    resetStatus : 0x00000004
    bootReason: 0x00000007
  • Hi Again Christin,

    This is what I have now:

    SysCtrlResetSourceGet() 0x00000007
    WARMRESET 0x00000004
    PRCMWdtResetStatus() 0x00

    Reading WARMRESET can I count on the return value of PRCMWdtResetStatus() after?

    In any case, WARMRESET only has bit 2 set, so bit 0 is 0 so no watchdog reset. bit 1 is 0 so no CPU LOCK-UP event either.
    I am not using ICEPick as far as I know,
    Reset source would be AON_SYSCTL_RESETCTL_RESET_SRC_WARMRESET

    I am kind of wondering what the problem is. The problem is that the CPU reboots I just do not understand why, can you help please?
  • Sorry for guiding you to checkout reading PRCM WARMRESET register as it's a debug feature and the status is actually clear upon reset due to WR_TO_PINRESET is set to 1.

    Where do you find PRCMWdtResetStatus()?
    I think the easiest way of figuring out if the reset is caused by watchdog reset is simply set an IO in your watchdog callback.
  • #include <driverlib/prcm.h>

    PRCMWdtResetStatus();

    **************************************************************************
    //
    //! \brief Read reset status for WatchDog Timer.
    //!
    //! WDT reset is the only reset status available through the PRCM module.
    //! This function can be used to check whether or not a WDT reset has
    //! occured since last time this bit was cleared.
    //!
    //! \note This function will automatically clear the WDT reset status bit
    //! if asserted. If the reset bit is not asserted then nothing happens.
    //!
    //! \return Returns reset status of Watchdog Timer.
    //! - \c true : A WDT reset occured since last time the bit was cleared.
    //! - \c false : A WDT reset has not occured since last clear.
    //
    //*****************************************************************************
    __STATIC_INLINE bool
    PRCMWdtResetStatus(void)
    {
    //
    // Return the WDT reset status.
    //
    return ((HWREG(PRCM_BASE + PRCM_O_WARMRESET) & PRCM_WARMRESET_WDT_STAT)
    ? true : false);
    }

    It is not easy for me to connect an I/O to the board.
    I will stop using the watchdog and see if the board keeps on booting.

    So what you are telling me is that reading WARMRESET gives me 0x00000004 can not be relied on ?
    The bit telling me if a watchdog was causing the boot is cleared?

    Best regards,
    Claude
  • I was on the wrong TI-RTOS version, therefore I could not find that API.

    Because the WR_TO_PINRESET is set, the it will trigger a PIN reset which clear the WDT_STAT and LOCKUP_STAT registers.

    If you want, you can disable that bit by writing it to 0 in your watch callback function, then WDT_STAT and LOCKUP_STAT registers will not be clear once the warm reset happens

    But the warm reset is not a recommended mode to use on CC26xx, therefore in our drivers we disable warm reset by making sure warm reset will trigger a pinreset.
  • This is mycallback function:

    void wdtClear(UArg handle) 
    {  
      // clear wd
      Watchdog_clear((Watchdog_Handle) handle);
    }

    How can set bit WR_TO_PINRESET to zero ? 

  • Hi Christin,

    Is this ok ?

    void wdtClear(UArg handle) 
    {  
      if( allIsOk )
      {
        // clear wd
        Watchdog_clear((Watchdog_Handle) handle);
        HWREG( PRCM_BASE + PRCM_O_WARMRESET ) = 0;
      }
    }

  • Hi Christin,

    This is driving me crazy.

    I attempted to clear bit # 2 of PRCM_O_WARMRESET but when I do this, the code keeps rebooting, without any indication in the compiler.

    Am I missing any tools? I have the TI XDX 100 v3 debugger from the 2650 evaluation boards.

    I need to get some progress with this issue
  • Hi Christin,

    Disabling the watchdog, I allowed my program to run and crash.
    Using the IAR debugger, breaking shows an assertion in mb_PATCH.c
    I have posted a new question regarding this here:
    e2e.ti.com/.../540763

    I need some help please

    Best regards,
    Claude
  • In conclusion, the bug was an assertion in mb_PATCH.c.
    The watchdog caused the unit to boot.
    Once the watchdog was disabled, the bug was found using the IAR IDE debugger
  • What's the bug you found at mb_PATCH.c? Can you be more specific?
  • Hi Christin,

    I have posted a separate question about this, here is the link:

    e2e.ti.com/.../540763

    Best regards,
    Claude