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.

RTOS/OMAP-L138: ARM put DSP into sleep mode in OMAP L138

Part Number: OMAP-L138
Other Parts Discussed in Thread: OMAPL138,

Tool/software: TI-RTOS

Hi All.


Now I'm develop feature ARM put DSP into sleep mode in OMAPL138.

I had done put DSP into sleep mode by ARM of OMAPL138. But When I wake DSP up by ARM, DSP not wakeup, and after DSP not working. I don't understand why?

I follow the steps detailed in 10.7.4 C674x Megamodule Clock ON/OFF of SPRUH77.

Here is MY Code:

ARM code:

/*****************************************************************************
 * @file        main.c
 * @author      
 * @version     V0.0.1
 * @date        
 * @brief       
 * @revision
 *****************************************************************************/

/******************************************************************************
 **                               INCLUDES
 ******************************************************************************/
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/knl/Semaphore.h>
#include "main.h"
#include "interrupt.h"
#include "delay.h"
#include "lcdkOMAPL138.h"


/* static function */
static void pmu_DSPExitSleepMode (void);
static void pmu_DSPEnterSleepMode (void);

/* Main function */
void main(void)
{
	while(1)
	{
		pmu_DSPEnterSleepMode();
		delay(10000);// delay 10s
		pmu_DSPExitSleepMode();
		delay(10000);// delay 10s	
	}
}


/*******************************************************************************
 ** @brief      sleep DSP
 ** @param      None
 ** @return     None
 ** @time       1:51 PM Friday, March 29, 2019
 ** @revision
 ******************************************************************************/
static void pmu_DSPEnterSleepMode (void)
{
    volatile unsigned int timeout = 0xFFFFFF;
    unsigned int    status = 0;
    unsigned int    regTmp = 0;
    SOS_DEBUG("ARM: set dsp sleep\r\n");
    //PSCModuleControl_1(SOC_PSC_0_REGS, HW_PSC_DSP, PSC_POWERDOMAIN_PD_DSP,\
            PSC_MDCTL_NEXT_DISABLE);

    /* C674x Megamodule Clock OFF */
    /* Step 1: The ARM stops all masters from accessing the DSP and DSP memory */

    /* Step 2: The ARM polls all masters for write-completion status */

    /* Step 3: ARM initiates the following DSP clock shutdown procedure*/

    /* Step 3a: DSP clock stop command */
    regTmp = (HWREG(SOC_PSC_0_REGS +  PSC_MDCTL(HW_PSC_DSP)) & ~PSC_MDCTL_NEXT);
    HWREG(SOC_PSC_0_REGS +  PSC_MDCTL(HW_PSC_DSP)) = regTmp | PSC_MDCTL_NEXT_DISABLE;

    /* step 3b: Write 1 to GO[1] bit */
    HWREG(SOC_PSC_0_REGS + PSC_PTCMD) =  HWREG(SOC_PSC_0_REGS + PSC_PTCMD) | PSC_PTCMD_GO1;

    /* step 3c: Check (poll for 0) the GOSTAT[1] bit in the power domain transition status register (PSC0.PTSTAT) */
    do
    {
        status = HWREG(SOC_PSC_0_REGS + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT1;
    }
    while (status && timeout--);
    /* step 3d: Check (poll for 2h) the STATE bit field in the DSP LPSC module status register (PSC0.MDSTAT15) */
    if (timeout != 0)
    {
        timeout = 0xFFFFFF;
        status = PSC_MDCTL_NEXT_DISABLE;
        do
        {
            timeout--;
        }
        while(timeout && (HWREG(SOC_PSC_0_REGS + PSC_MDSTAT(HW_PSC_DSP)) & PSC_MDSTAT_STATE) != status);
    }

    if (timeout == 0)
    {
    	SOS_DEBUG("ARM: set dsp sleep Fail!\r\n");
    }
    else
    {
    	SOS_DEBUG("ARM: set dsp sleep DONE!\r\n");
    }
}

/*******************************************************************************
 ** @brief      sleep DSP
 ** @param      None
 ** @return     None
 ** @time       1:56 PM Friday, March 29, 2019
 ** @revision
 ******************************************************************************/
static void pmu_DSPExitSleepMode (void)
{

	SOS_DEBUG("ARM: wakeup dsp\r\n");

	volatile unsigned int timeout = 0xFFFFFF;
	unsigned int    status = 0;
	unsigned int    regTmp = 0;
    /* C674x Megamodule Clock ON */
    /* step 1: Wait for the GOSTAT[1] bit in the power domain transition status register (PSC0.PTSTAT) to clear to 0. */
	do
	{
		status = HWREG(SOC_PSC_0_REGS + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT1;
		SOS_DEBUG(".\r\n");
	}
	while (status && timeout--);
    /* step 2: Write a 3h to the NEXT bit field in the DSP local power sleep controller (LPSC) module control register (PSC0.MDCTL15)*/
    regTmp = (HWREG(SOC_PSC_0_REGS +  PSC_MDCTL(HW_PSC_DSP)) & ~PSC_MDCTL_NEXT);
    HWREG(SOC_PSC_0_REGS +  PSC_MDCTL(HW_PSC_DSP)) = regTmp | PSC_MDCTL_NEXT_ENABLE;

    /* step 3: Write a 1 to the GO[1] bit */
    HWREG(SOC_PSC_0_REGS + PSC_PTCMD) =  HWREG(SOC_PSC_0_REGS + PSC_PTCMD) | PSC_PTCMD_GO1;

    /* step 4: Check (poll for 0) the GOSTAT[1] bit in PSC0.PTSTAT */
    timeout = 0xFFFFFF;
    do
    {
        status = HWREG(SOC_PSC_0_REGS + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT1;
    }
    while (status && timeout--);

    /* step 5: Wait for the STATE bit field in the DSP LPSC module status register (PSC0.MDSTAT15) to change to 3h.*/
    if (timeout != 0)
    {
        timeout = 0xFFFFFF;
        status = PSC_MDCTL_NEXT_ENABLE;
        do
        {
            timeout--;
        }
        while(timeout && (HWREG(SOC_PSC_0_REGS + PSC_MDSTAT(HW_PSC_DSP)) & PSC_MDSTAT_STATE) != status);
    }

    if (timeout == 0)
    {
    	SOS_DEBUG("ARM: wakeup dsp Fail!\r\n");
    }
    else
    {
    	SOS_DEBUG("ARM: wakeup dsp DONE!\r\n");
    }
	/*SYSCFG_CHIPSIG_CHIPSIG2 interrupt to wake DSP */
    regTmp = HWREG (SOC_SYSCFG_0_REGS + SYSCFG0_CHIPSIG) | SYSCFG_CHIPSIG_CHIPSIG2;//0x00000004;
    HWREG (SOC_SYSCFG_0_REGS + SYSCFG0_CHIPSIG) = regTmp;
}

DSP Code:

#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Mailbox.h>
#include <ti/sysbios/knl/Task.h>

#include "hw_syscfg0_OMAPL138.h"
#include "hw_types.h"
#include "soc_OMAPL138.h"

#include "middleware/debug/debug.h"
#include "middleware/ipc/ipc.h"

uint32_t isSleepDSP = 0;
uint32_t noSleep = 0;

void main(void)
{
	
	while(1)
	{
        /* toggle LED */
		toggle_LED();
        delay(5000);

	}
}


/*******************************************************************************
 ** @brief     	interrupt handle from POWER DOWN CONTROL
 ** @param     	func_param
 ** @return    	none
 ** @time		
 ** @revision
 ******************************************************************************/
void pdc_IRQHandler(void)
{
	IntEventClear(SYS_INT_PDC_INT);
	/* Write a 0001 5555h to PDCCMD */
    HWREG(SOC_PWRDWN_PDC_REGS)=0x00015555;
    isSleepDSP = 1;
    SOS_DEBUG("pdc interrup\r\n");
    asm("  IDLE");
}
 
/*******************************************************************************
 ** @brief     	interrupt handle from ARM
 ** @param     	func_param
 ** @return    	none
 ** @time		
 ** @revision
 ******************************************************************************/
void ipc_IRQ_handler ()
{

    Hwi_disableInterrupt (5);
    if(isSleepDSP)
    {
    	Wakeup_IRQHandler();
    	isSleepDSP = 0;
	noSleep++;
    	SOS_DEBUG("DSP is sleep, noSleep: %d\r\n",noSleep);
    }
    else
    {
    	SOS_DEBUG("DSP is active\r\n");
    }
    Hwi_enableInterrupt (5);
}

note: SOS_DEBUG is my debug function by UART.

The running result : ARM running normal. But DSP print log "pdc interrup" and then DSP does not work.


could someone help me put DSP sleep and wake up it?


Thanks and Best regard!
HUY DAI