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.

C5505 and IDLE3

Other Parts Discussed in Thread: TMS320C5505

I am trying to put the C5505 in IDLE3 mode and having a wake up problem.

I am setting the rtc alarm interrupt for a 500 millisecond alarm to act as a tick. Inside the ISR, I take the current time and add 500 milliseconds to re-enable the alarm.  I put the DSP into IDLE3 mode. In this mode I BYPASS and POWER DOWN the PLL, so I am running off of the 32KHz clock.

In the RTC ISR I reconfigure the PLL for 100 MHz so I meet the 3 times 32KHz requirement called out in the app note. Once the PLL is back up and running <10 ms, I clear the intflag of the RTC IP.

I will only receive the wake up interrupt ONCE. I have tried moving the PLL enable and clearing the interrupt in the main loop (after asm("  idle"); ) and experience the same problem.

Note: if I don't disable the PLL this continues to work as expected and I continue to get the interrupt every second.

Can someone else try this and let me know if they are seeing the same thing? If so, is there a work around?

Cheers!

  • Jrvanho;

    Can you show us the ISR part of the code? Than, we can take a look. Or I can post some example codes of the ISR for wake-up and idle applications, but they will not be the exact same as your case.

    Regards

    Wen

  • Jrvanho;

    Here is the example code for RTC's ISR, please pay attention to the comment part that I wrote.

    regards

    Wen

    /////////////////////////////////////////////////////////////////////
    //interrupt service routine for the external wakeup input on the pin
    /////////////////////////////////////////////////////////////////////
    interrupt void rtc_isr (void)
    {
      //DSP_wakeup_mode_0();
      wakeup_counter++; //for debugging use

      //Important: write "1" to clear the just occurred EXT-wakeup interrupt flag
      //so the next interrupt event can be seen by CPU
      *(ioport volatile unsigned int *)RTCINTFL = 0x0020;
    }

  • Wen,

    All of my registers are defined as:

      *(volatile ioport Uint16 *)

    Here is an outline of my main. after my idle, there is an io toggle that I stop getting

    main()

    {

        configure_pll_100MHz();

        configure_rtc_1sec_int();

        // disable TMR0
        *TCR0 = 0;

        // disable USB OSC
        *USBSCR = 0x804C;

        // Need to request from UART / USB / EMIF if we can disable clocks
        CSL_FINST(CSL_SYSCTRL_REGS->CLKSTOP,SYS_CLKSTOP_URTCLKSTPREQ,REQ);
        CSL_FINST(CSL_SYSCTRL_REGS->CLKSTOP,SYS_CLKSTOP_USBCLKSTPREQ,REQ);
        CSL_FINST(CSL_SYSCTRL_REGS->CLKSTOP,SYS_CLKSTOP_EMFCLKSTPREQ,REQ);

        // need to check to make sure all of the above ack before disabling clocks
        while(0x3F != *CLKSTOP)
        {
            asm("   nop");
        }

        // Disable all clocks
        *PCGCR2 = 0x007F;
        *PCGCR1 = 0x7FFF;
       
        while(1)
        {
            // wait for ISR to fire


           // disable PLL
           PLL_bypass(hPll);
       
           // Configure for Idle, enable idle on all domains
        *ICR = 0x03EF; // enable idle on all domains
         asm("  nop");
         asm("  nop");
         asm("  idle");
         asm("  nop");
         asm("  nop");

    toggle_io();          


        }

    }

    interrupt void rtc_isr (void)
    {
       
       //DSP_wakeup_mode_0();
       PLL_enable(hPll); 
       wakeup_counter++; //for debugging use

      //Important: write "1" to clear the just occurred EXT-wakeup interrupt flag
      //so the next interrupt event can be seen by CPU
      *(ioport volatile unsigned int *)RTCINTFL = 0x0020;
    }

     

    Please try this and let me know, because I stop getting those interrupts.....

    Cheers,

    Jonathan

     

  • There is a

    configure_gpio_for_toggle()

    after i call

    configure_rtc();

    Cheers

  • Wen,

    Any progress? Can you please contact me?

    Cheers

  • I'm experiencing a similar problem on the C5515 and posted a message on the forum at:

    http://e2e.ti.com/support/dsp/tms320c5000_power-efficient_dsps/f/109/t/114639.aspx

    Were you able to get your processor to idle and wakeup via RTC wakeup?

    Cheers x2 

  • Danimal,

    I am able to get the RTC to interrupt and wake from idle as long as I don't disable the PLL. Once I do that things stop working.

    I am also seeing some strangeness, if I add a asm("  nop"); to the code, sometimes it breaks it. There seems to be something with the alignment of functions. I haven't been able to work this out though.

    I will keep working and let you know what I figure out.

    Cheers!

  • Wen,

    Can I get a status update? Do you need more information?

    Cheers!

  • Wen,

    Have you had a chance to try this out?

    I have a sample eZDSP application if you are not able to reproduce this. You might look at this post for more details:

    http://e2e.ti.com/support/dsp/tms320c5000_power-efficient_dsps/f/110/t/117613.aspx

    Cheers,

    Jonathan

  • Jonathan & Wen,

    Did you find the solution of setting up your DSP core in IDLE mode.?

    I am facing a similar issue in running my CPU in IDLE3 mode. I am using TMS320C5505 EVM platform. My CPU enters the IDLE 3 mode and based on RTC periodic seconds interrupt wakes up after 1s. But when i try to loop back and enter the IDLE mode by idling the CPU domain  again by configuring the ICR (ICR = 0x03EF) and executing the idle instruction, the CPU does not IDLE and continues to execute the further instructions.

    I have included the race condition check as mentioned in http://processors.wiki.ti.com/index.php/C55xx_RTC_ONLY_MODE_SUPPORT  to avoid any race around conditions.

    To debug using emulator, I configured the ICR to idle only the CPU  (ICR = 0x000F) and checked before executing the idle instruction and after my ISR was executed if any of the bits are set in the IFR which is preventing the CPU for entering the IDLE mode but I see all bit are cleared.

    To mention, before configuring for IDLE mode, my device  has interrupt enabled DMA, I2S, SPI and UART.  I am looping on the status bits before shutting down these periperals. Also, I am globally disabling all interrupts to ensure there is no interrupt flag bit set.

    Please let me know what am I missing in taking care before trying to enter the IDLE mode again.?

    void ConfigureInterruptRTC_FE(void)
    {
    	Uint16 timeOut = 1000;
    	/* Configure and enable the RTC interrupts using INTC module*/
    	IRQ_globalDisable();
    	/*Clear any pending interrupts*/
    	IRQ_clearAll();
    	/*Disable all the interrupts*/
    	IRQ_disableAll();
    	/*Clear events*/
    	IRQ_clear(RTC_EVENT);
    	/*Plug the ISR address*/
    	IRQ_plug (RTC_EVENT, &Isr_rtc);
    	/*Enable RTC event*/
    	IRQ_enable(RTC_EVENT);
    	/*Enable global interrupts*/
    	IRQ_globalEnable();
    
    	/*Clear update bit*/
    	CSL_RTC_REGS->RTCUPDATE = 0;
    	/*Clear time register*/
    	CSL_RTC_REGS->RTCMIL   = 0;
    	CSL_RTC_REGS->RTCSEC   = 0;
    	CSL_RTC_REGS->RTCMIN   = 0;
    	CSL_RTC_REGS->RTCHOUR  = 0;
    	CSL_RTC_REGS->RTCDAY   = 0;
    	CSL_RTC_REGS->RTCMONTH = 0;
    	CSL_RTC_REGS->RTCYEAR  = 0;
    	/*Time updates enabled*/
    	CSL_RTC_REGS->RTCUPDATE |= CSL_RTC_RTCUPDATE_TIMEUPDT_MASK;
    	while(CSL_RTC_REGS->RTCUPDATE & 0x8000 && (--timeOut != 0));
    	/*Clear all RTC interrupt flags*/
    	CSL_RTC_REGS->RTCINTFL	=	(Uint16)0x803F;
    	/*Enable RTC seconds interrupt to be triggered*/
    	EnableEventRTC_FE(RTC_SECEVENT_INTERRUPT);
    	/*Clear all RTC interrupt flags*/
    	CSL_RTC_REGS->RTCINTFL	=	(Uint16)0x803F;
    	/*Clear all CPU interrupt flags*/
    	CSL_CPU_REGS->IFR1 = (Uint16)0xFFFF;
    }
    
    void Isr_rtc(void)
    {
        CSL_RTCEventType rtcEventType;
    
        rtcEventType = RTC_getEventId();	
        if (((void (*)(void))(rtcDispatchTable.isr[rtcEventType])))
         { 	
             ((void (*)(void))(rtcDispatchTable.isr[rtcEventType]))();
         }
    }
    
    
    static void SecIntc_rtc(void)
    {
    	Uint16 delay;
    	Uint16 tempIFR;
    
        /*PLL power up*/
        CSL_SYSCTRL_REGS->CGCR1 &= 0xEFFF;
        /*Wait 4 ms @ 32.768kHz = 0.004 * 32.768k = 131 (0x83)*/
        for(delay=131; delay>0; delay--)
        asm("	nop ");
    	/*PLL mode selected*/
    	CSL_SYSCTRL_REGS->CCR2 = (Uint16)0x0001;	
    	CSL_FINST(CSL_RTC_REGS->RTCINTFL, RTC_RTCINTFL_SECFL, SET);
    
    	tempIFR = CSL_CPU_REGS->IFR1;
    	if((tempIFR & 0x0004) != (Uint16)0)
    	{
    		CSL_CPU_REGS->IFR1 = CSL_CPU_REGS->IFR1;
    	}
    }
    
    Int16 main(Uint16 sleepTime)
    {
    	Int16 status;
    	Uint16 i;
    	Uint16 temp1920;
    	counter = sleepTime;
    
    	configure_pll();
    	/*Configure the RTC alarm interrupt*/
    	ConfigureInterruptRTC_FE();
    
    	/*Disable I2S interrupts*/
    	CSL_I2S2_REGS->I2SINTMASK = (Uint16)0x0000;
    	/*Disable channel 0 and channel 1 of DMA 1*/
    	CSL_DMA1_REGS->DMACH0TCR2 = CSL_DMA_CHANNEL_DISABLE;
    	CSL_DMA1_REGS->DMACH1TCR2 = CSL_DMA_CHANNEL_DISABLE;
    
    	/*Poll for DMA1 status of Transmitter Channel 2*/
    	while(CSL_DMA1_REGS->DMACH2TCR2 & (Uint16)0x4000);
    	CSL_DMA1_REGS->DMACH2TCR2 = CSL_DMA_CHANNEL_DISABLE;
    
    	/*Poll for DMA1 status of Receiver Channel 3*/
    	while(CSL_DMA1_REGS->DMACH3TCR2 & (Uint16)0x4000);
    	CSL_DMA1_REGS->DMACH3TCR2 = CSL_DMA_CHANNEL_DISABLE;
    
    	/* USB peripheral domain is never enable. Directly disable the Oscillator */
    	USBSCR = (Uint16)0x804C;
    
        /*Disable Timer 1*/
    	CSL_TIM_1_REGS->TCR = (Uint16)0x0000;
    
        /*Disable I2S2 peripheral*/
    	CSL_I2S2_REGS->I2SSCTRL = (Uint16)0x0000;
    
        /*Poll for SPI status and disable SPI clock*/
    	while(0x0006 != CSL_SPI_REGS->SPISTAT1);
    	CSL_SPI_REGS->SPICCR = CSL_SPI_SPICCR_RESETVAL;
    
    	/*Request to stop UART clock*/
    	CSL_SYSCTRL_REGS->CLKSTOP = (Uint16)0x0010;
    	/*Poll for the ACK and stop UART clock	*/
    	while(0x0030 != CSL_SYSCTRL_REGS->CLKSTOP);
    
    	/*Clear all RTC interrupt flags*/
    	CSL_RTC_REGS->RTCINTFL	=	(Uint16)0x803F;
    
    	/*Disable all clocks except SYSCLK and USB Clock*/
    	CSL_SYSCTRL_REGS->PCGCR2 = (Uint16)0x007F;
    	CSL_SYSCTRL_REGS->PCGCR1 = (Uint16)0x7FFF;
    
    	/*Reset all peripherals*/
    	CSL_SYSCTRL_REGS->PSRCR = 0x0020;
    	CSL_SYSCTRL_REGS->PRCR = 0x00BF;
    	for(i = 0x00FF; i > 0; i++)
    	{
    		asm ("   nop");
    	}
    
    	/*Enable INTM bit*/
    	CSL_CPU_REGS->ST1_55 |= 0u << 11;
    	/*Enable RTC interrupts to be triggered*/
    	RTC_start();
    
    	/*Clear all RTC interrupt flags*/
    	CSL_RTC_REGS->RTCINTFL	=	(Uint16)0x803F;
    	IRQ_clearAll();
    	do
    	{
    		/*Enter PLL bypass mode*/
    		CSL_SYSCTRL_REGS->CCR2 = (Uint16)0x0000;
    		/*PLL power down*/
    		CSL_SYSCTRL_REGS->CGCR1 |= 1u<<12;
    
    		temp1920 = CSL_RTC_REGS->RTCINTFL;
    		if((temp1920 & 0x0002) != (Uint16)0)
    		{
    			CSL_RTC_REGS->RTCINTFL = (Uint16)0x803F;
    		}
    
    		/* Configure for Idle, enable idle on CPU domain*/
    		ICR = 0x03EF;
    		asm("  nop");
    		asm("  nop");
    		asm("  nop");
    		asm("  idle");
    		asm("  nop");
    		asm("  nop");
    		asm("  nop");
    		/*Trigger the watchdog*/
    		TriggerHwWatchdog_FE();
    
    		temp1920 = CSL_RTC_REGS->RTCINTFL;
    		if((temp1920 & 0x0002) != (Uint16)0)
    		{
    			CSL_RTC_REGS->RTCINTFL = (Uint16)0x803F;
    		}
    	}while(--counter);
    
        /*Disable RTC Interrupts*/
    	DisableEventRTC_FE(RTC_SECEVENT_INTERRUPT);
    	RTC_stop();
    
    	/*Enable I2S2, SPI, UART, Timer1 and DMA1 clock, but gated all others' clocks */
    	CSL_SYSCTRL_REGS->PCGCR1 = (Uint16)0x2FD9;
    	CSL_SYSCTRL_REGS->PCGCR2 = (Uint16)0x0077;
    
        /* Clear UART stop request in the CLKSTOP register*/
        CSL_SYSCTRL_REGS->CLKSTOP = (Uint16)0x0000;   
    
        return status;
    }
    

     

  •  The issue was resolved offline. Updating the post with the resolution information. 

    With respect to RTCNOPWR flag getting set in some of the debug trials -   This shouldn’t happen and its not expected to get set. Suggestion was provided to remove the watch dog counter and check, as the suspecion was with respect to Watch dog counter.

    The issue got fixed after taking care of the watchdog in the code. Also, it was figured out why the stack was getting cleared. It was a bug in the code and was later fixed ".

    With this the C5505 - IDLE3 issue of entering to Idle3 mode and waking up through RTC Interrupts in repeated manner is resolved and code seems to be working fine.

    Regards

     Vasanth