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.

TMS320F28388D: CM Configurable Watchdog timer

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE

Hello all,

I'm using F28388D for my product development.

As I'm facing issues related to unexpected LWIP hang I want to use watchdog in CM  to reset all 3 cores.

So I learnt that on CM watchdog expiry, it will either Reset(XRST) or will generate an NMI interrupt in CM core and If we dont serve that NMI interrupt CM core will get reset which inturn will also generate an NMI interrupt in CPU1.

Till here I'm able to implement and test as expected, I'm able to configure WD on CM and generate an NMI on CPU1 and reset CPU1 in NMI callback which will inturn resets all cores.

But the problem is : I'm unable to control watchdog reset time period.

I want Reset to happen only if execution  is stuck in certain function for sometime, ideally it will excute that function for ~10mS (for instance) but in error case In my debug I found that LWIP is stuck in certain function  infinitely.  So If I can Enable watchdog's counter with some measured time (lets say  ~1sec) at the start of certain function and at the end of that function again I want to disable watchdog timer, This repeats endlessly.

To perform this I want to configure watchdog for certain timing/count which I'm facing issues and unable to validate.

I've gone through "watchdog_ex1_nmi_handling" example code and using configuring WD in CM as below:

I'm calling this function from main() after CM_init();

I have kept breakpoint after executing above (screenshot ) watchDogConfig function,

This is my register window status:

WD registers:

NMI registers:

I tried using "SysCtl_serviceWatchdog" in main while(1) loop with above configurations, It still generates NMI Interrupt. Is this expected ? Am I missing something here ?

I tried setting SysCtl_setWatchdogWindowValue(0) and SysCtl_setNMIWatchdogPeriod(0xFFFF), this also generates NMI immediately.

From TRM we can infer that, WDCHK shall be set to 101 inorder to access WDCR register, but here I see that even after enabling watchdog ie., WDDIS is 0, WDCHK is still 0 which is not expected. correct ?

But in code I see that 101 is being written to WDCHK but it seems like it isn't taking effect. Can somebody confirm.

I also tried same excercise using F28388 DVK kit and example code, it see same behavior there aswell. No matter what Configuration I make I see NMI interrupt is being generated immediately. Also In Register window I tried to change WDCHK value manually but it isn't taking efffect.

  / @   Can you please help me out here.

Thanks and regards,

Pranay.

  • As I'm facing issues related to unexpected LWIP hang I want to use watchdog in CM  to reset all 3 cores.

    OK, you are using the windowed watchdog. It is important to differentiate it from the NMI WD. 

    So I learnt that on CM watchdog expiry, it will either Reset(XRST) or will generate an NMI interrupt in CM core and If we dont serve that NMI interrupt CM core will get reset which inturn will also generate an NMI interrupt in CPU1.

    It does not generate a reset right away. What it does is to generate a NMI to the CMNMIWD module. Only when the code fails to service the interrupt within a time stipulated by you, the WDCNTR will overflow and reset the CM. This also generates a NMI to CPU1. 

    But the problem is : I'm unable to control watchdog reset time period.

    The reset time period is dependent on the timeout period of two different watchdogs: (1) The Windowed watchdog (WWD). The timeout period is controlled by two bit-fields: WDPRECLKDIV and WDPS in the WDCR register. (2) From the time the WWD times out, how long it takes for the CMNMIWD to timeout (and reset the CM) is determined by the value you write to the CMNMIWDPRD register. Double-check your configuration for both the watchdogs.

    I tried using "SysCtl_serviceWatchdog" in main while(1) loop with above configurations, It still generates NMI Interrupt. Is this expected ? Am I missing something here ?

    This function does reset the WD. However, if you do not reset it before the counter overflows, it will generate the NMI. How do you ensure the WD is serviced in time to prevent the overflow from happening?

    I tried setting SysCtl_setWatchdogWindowValue(0) and SysCtl_setNMIWatchdogPeriod(0xFFFF), this also generates NMI immediately.

    The first function disables the windowing function. The 2nd function makes the period 0xFFFF, the max value. Not sure what you mean by "immediately". If the WWD overflows, it starts the CMNMIWDCNTR. Only when that overflows is the reset triggered. It cannot be triggered "immediately".

    From TRM we can infer that, WDCHK shall be set to 101 inorder to access WDCR register, but here I see that even after enabling watchdog ie., WDDIS is 0, WDCHK is still 0 which is not expected. correct ?

    These bits always read back as 000. i.e. you can only write to these bits, but not read.

    I also tried same excercise using F28388 DVK kit and example code, it see same behavior there aswell. No matter what Configuration I make I see NMI interrupt is being generated immediately.

    I suggest you create a very simple test case. All it should do is to let the CMWDCNTR overflow and assert NMI. Allow the CMNMIWDCNTR to overflow and reset the CM. Try different values for the preescalers WDPRECLKDIV and WDPS in the WDCR register. Also try different values for CMNMIWDPRD register. Ensure your writes are going through correctly before running your tests. You could toggle a GPIO pin as an diagnostic aid.

  • Hi

    Thanks for the answer, I was able to solve my problem.

    All I was missing was - WDPRECLKDIV and WDPS in the WDCR register configuration, I was not configuring these register values and these register values defaults to WWD expiry in uSec and Hence I was unable to control the reset time. And once I configured above values I was able to control and service the WWD. Thanks for your inputs.

    Also after WWD expiry it is generating a NMI to the CMNMIWD module and in CM FW  i'm intentionally not handling/clearing/servicing the NMI interrupt.

    Implementation 1 : At this point : In this case, As NMI is getting generated on CPU1 aswell, we've added logic in CPU1 application FW to reset total 3 controllers and it is working as expected.

    Implementation 2: But now we dont want this to happen, we want only CM core to get RESET independent of CPU1. 

    So I will not enable NMI on CPU1 (or) even if enabled I will service NMI in CPU1 and be idle there (I wont reset), And in CM, as WWD NMI is not serviced., After the WDCNTR will overflow and reset the CM. CORRECT ?

    After reset, Do CPU1 again need to BOOT CM as it does during the regular boot-up time using Device_bootCM() function ?

    To emulate this, My Custom application is already running as TCP server so I will start PINGING continuously and once WWD expires I will not service WWD making it reset CM core and Hence I should be able to observe PING lost/timed-out right ? 

    Implementation 3: I'm trying to use AIRCR Register (Offset = D0Ch) [Reset = FA050000h] to reset CM core based on learning from TRM,

    To do this, I'm using below method:

    void AIRCRCReset()
    {
    
        uint32_t VECTKEY = 0x5FA00000;
        VECTKEY |= 0x04;
        HWREGH(WD_BASE + 0xD0C) = (HWREGH(WD_BASE + 0xD0C) | (VECTKEY) );
    
    }

    But I see that CM is not getting resetted as there is PING always.

    Please correct me what I'm missing and suggest me a way to achieve our requirement.

    Thanks and regards,

    pranay.

  • Hi Pranay, unfortunately Hareesh is out of the office.  I am trying to ID another subject matter expert who can assist, but worst case, you should hear back from Hareesh by the end of next week.

  • Hello Joe,

    Thanks for reply. Please assign another subject matter expert.

    Vivek Singh  Can you please help me out here.

    Thanks.

  • Hi Pranay,

    Implementation 2: But now we dont want this to happen, we want only CM core to get RESET independent of CPU1. 

    So I will not enable NMI on CPU1 (or) even if enabled I will service NMI in CPU1 and be idle there (I wont reset), And in CM, as WWD NMI is not serviced., After the WDCNTR will overflow and reset the CM. CORRECT ?

    Yes, this is correct.

    After reset, Do CPU1 again need to BOOT CM as it does during the regular boot-up time using Device_bootCM() function ?

    Yes, it's needed. Please refer the CM BOOT flow in device TRM (below snapshot)

    To emulate this, My Custom application is already running as TCP server so I will start PINGING continuously and once WWD expires I will not service WWD making it reset CM core and Hence I should be able to observe PING lost/timed-out right ? 

    I would say yes, if CM boot is not setup properly by CPU1.

    Implementation 3: I'm trying to use AIRCR Register (Offset = D0Ch) [Reset = FA050000h] to reset CM core based on learning from TRM,

    To do this, I'm using below method:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    void AIRCRCReset()
    {
    uint32_t VECTKEY = 0x5FA00000;
    VECTKEY |= 0x04;
    HWREGH(WD_BASE + 0xD0C) = (HWREGH(WD_BASE + 0xD0C) | (VECTKEY) );
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    But I see that CM is not getting resetted as there is PING always.

    This does not look correct. VECTKEY value should be 0x05FA. You have it as 0x5FA0. Also you are doing read modify reset. As per spec read value for VECTKEY is 0xFA05 so when you do read modify write this will get updated to different value. Why not just write the fix value. Also can you use SYSRESETREQ bit instead.

    Regards,

    Vivek Singh

  • Hi Vivek,

    Thanks for the reply.

    Case 1:

    I tried below 3 tries for resetting CM through AIRCR register but all the time I'm unsuccessful in doing so.

    void AIRCRCReset()
    {
    
    //Try 1:
        //
        // Write the predivider to the appropriate register.
        //
        uint32_t VECTKEY = ((0x05FA<<16) | 0x04);
    //    HWREGH(WD_BASE + 0xD0C) = (HWREGH(WD_BASE + 0xD0C) | (VECTKEY) );
        HWREGH(WD_BASE + 0xD0C) = VECTKEY;//Not Working
        
    //Try 2:
        uint32_t VECTKEY = ((0x5FA<<16) | 0x04);
        HWREGH(WD_BASE + 0xD0C) = VECTKEY;//Not Working
    
    //Try 3:  
        uint32_t VECTKEY = ((0x5FA<<16) | 0x04);
        HWREGH(WD_BASE + 0xD0C) = (HWREGH(WD_BASE + 0xD0C) | (VECTKEY) ); //Not working
    }

    I'm confirming you that I'm not seeing any reset is by :

    1. I've kept a LED blinking continuously in CM main while(1) Application FW  -> I've not seen this stopped when I execute above function by sending an API over TCP..

    2. By keeping continuous PING and checking if there is any PING lost -> There is no PING lost when I execute above function.

    FYI: I'm not running in debug mode. I'm flashing FW all the time and sending commands over TCP.

    Need help resetting CM core using this register access method...

    Case 2:

    //
    // NMI ISR
    //
     __interrupt void cmnmiISR(void)
    {
    //     bool wdstatus;
    //    //
    //    // Get the WWD status and clear it
    //    //
    //    wdstatus = SysCtl_getWatchdogStatus();
    
        Tx_cpu1_intr(0xE2);
        Tx_cpu2_intr(0xE2);
        
    //    if(wdstatus)
    //        SysCtl_clearWatchdogStatus();
    //
    //    //
    //    // NMI was handled after the WWD expired
    //    //
    //    nmiflagstatus = SysCtl_getNMIFlagStatus();
    //    SysCtl_clearAllNMIFlags();
    
    }
    //
    // NMI ISR
    //
     __interrupt void cmnmiISR(void)
    {
    //     bool wdstatus;
    //    //
    //    // Get the WWD status and clear it
    //    //
    //    wdstatus = SysCtl_getWatchdogStatus();
    
    //    Tx_cpu1_intr(0xE2);
    //    Tx_cpu2_intr(0xE2);
    //    if(wdstatus)
    //        SysCtl_clearWatchdogStatus();
    //
    //    //
    //    // NMI was handled after the WWD expired
    //    //
    //    nmiflagstatus = SysCtl_getNMIFlagStatus();
    //    SysCtl_clearAllNMIFlags();
    
    }

    This is NMI ISR of CM. This gets executed every time when WWD expires and as I'm not serving the interrupt it supposed to be resetted. Yes in this case I see that LED blinking is stopped and PING also LOST. Means Resetted.

     As you can see in above snippet I tried writing IPC data to CPU1 so that it can execute "Flash_releasePumpSemaphore();" (thought it'd be required just in case) and  "Device_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0); I see that IPC has been received and executed commands aswell.

    But I see that as CM is not getting booted after executing Device_bootCM();   function....

    Not sure what I'm missing here. Anything else that I'd need to perform ?

    Thanks and regards,

    Pranay

  • Pranay,

    Why are you writing at this location (at WD base address) ?

    WD_BASE + 0xD0C

    This should be written to NVIC_BASE location like below -

    NVIC_BASE + 0xD0C

    See below snapshot -

    Please correct that and hope that fixes this issue.

    Vivek Singh

  • HI Vivek,

    Case 1:

    I tried this but I dont see CM restarting. Can you please try this on your end and let me know how it goes.

    Case 2:

    Whenever WWD expires I see PING is stopping, But I dont think so CM is rebooting or restarting from SSBL. It is not turning on at all.

    Do I need to execute any commands in CPU1 to start booting CM apart from Device_bootCM() I'm already executing this function but dont see CM restart ? Do we any API to restart CM from CPU1 ? even this would help us.

    Regards,
    Pranay

  • I am assuming now CM is getting reset. Please confirm. Also please note that when WWD expires, it only fires NMI on CM and after NMIWD counter expires, it fires reset.

    Can you read the value from CM IPCBOOTSTATUS register and see what is the value there ? 

  • HI Vivek,

    Also please note that when WWD expires, it only fires NMI on CM and after NMIWD counter expires, it fires reset.

    As main while(1) is not running and PING is lost, I believe CM got restarted because of WWD expiry (case 2), But the question is how do I boot CM again from SSBL ?

    Case 1:

    This one I'm unable to achive, can you please help me figure this one out ?

    --pranay

  • Case 1:

    This one I'm unable to achive, can you please help me figure this one out ?

    Have you corrected the address, as I mentioned in my last post.

    For CM Boot, I'll loop-in BOOR expert.

    Vivek Singh

  • Hi Vivek,

    Regarding case 1:

    Yes, I have corrected address as you suggested. Still I see same behavior.

    --pranay

  • For CM BOOT issue, I am going to assign this to our BOOTROM expert. On the reset case, we'll check and get back to you. 

    Regards,

    Vivek Singh

  • Hi Vivek,

    Can you please assign to your bootrom expert to this thread and try to solve my issue.

    Thanks and regards,

    pranay

  • Let me remined him again.

  • Hi Pranay,

    The bootROM expert for F28388D is out of office and will be back next week. Please expect a reply by mid of next week.

    Meanwhile can you check if you are entering CM boot or not by selecting CM wait boot mode. Add CM ROM symbol from C2000Ware\libraries\boot_rom\f2838x\revA\rom_sources\cm\ccs_files\Release and point to source files in C2000Ware\libraries\boot_rom\f2838x\revA\rom_sources\cm\F2838x_ROM\bootROM\source. Then you should be able to debug the ROM boot flow.

    Thanks and regards, Pawan