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.

TMS570LC4357: FreeRTOS and Sleep Mode.

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN

Hi,

I'm tying to implement idle sleep with a TMS570LC and the FreeRTOS HALCoGen project. I can get the proessor to sleep by implementing:

void vApplicationIdleHook( void )

      systemPowerDown(SYS_SLEEP_MODE);

}

and with SCI3 interface enable wake up. I initialze the SCI3 interface with the wakeup flag:

/** - set interrupt enable */
sciREG3->SETINT = (uint32)((uint32)0U << 26U) /* Framing error */
| (uint32)((uint32)0U << 25U) /* Overrun error */
| (uint32)((uint32)0U << 24U) /* Parity error */
| (uint32)((uint32)1U << 9U) /* Receive */
| (uint32)((uint32)1U << 1U) /* Wakeup */
| (uint32)((uint32)0U << 0U); /* Break detect */

However, once asleep it doesn't wake up again!: 

1). Do I need to make a call to wake it up again, if so where (tick hook?)

2). What should the wakeup/powerdown clock sources be set to?

3). Can I send any signal by SCI3 for wakeup?

Many thanks in advance.

Best regards

Pablo

  • Hi QJ Wang,

    Thanks for the repley. I enable the vim wakeup as:

    vimREG->WAKEMASKSET2 = 1<<0 | 1<< 10; // SCI3 High, Low

    but this does not work.

    Best regards

    Pablo

  • I'm sure this is just something silly in the implementation. Do you have any example HALCoGen-generated examples which show the use of Doze/Sleep modes for the TMS570?

    Pablo

  • Hi Pablo,

    I don't have example for TMS570LC43x.

  • Does the device get into the sleep mode?

  • Hi QJ,

    I'm Sorry for delay.  Yes, it does into sleep mode. But it doesn't wake up when it receives data by sci.

  • Thank you. Can you share your code with me, so I can test on my board?

  • Yes, I have a function in main to initialize the hardware and create a couple of tasks and initialize the freeRTOS scheduler:

    static void hardwareInit(void)
    {
    /* Enable IRQ via VIC controller */
        _enable_interrupt_();
    
        sciInit();
        sciEnableNotification(sciREG3, SCI_RX_INT);
        sciReceive(sciREG3,1,&cmd);
    
        vimREG->WAKEMASKSET2 = 1<<0 | 1<< 10; // SCI3 High, Low
    }
    
    

    Here is the function to initialize the communication interface SCI3 to enable wake up

    void sciInit(void)
    {
     /** @b initialize @b SCI3 */
    
        /** - bring SCI3 out of reset */
        sciREG3->GCR0 = 0U;
        sciREG3->GCR0 = 1U;
    
        /** - Disable all interrupts */
        sciREG3->CLEARINT    = 0xFFFFFFFFU;
        sciREG3->CLEARINTLVL = 0xFFFFFFFFU;
    
        /** - global control 1 */
        sciREG3->GCR1 =  (uint32)((uint32)1U << 25U)  /* enable transmit */
                      | (uint32)((uint32)1U << 24U)  /* enable receive */
                      | (uint32)((uint32)1U << 5U)   /* internal clock (device has no clock pin) */
                      | (uint32)((uint32)(2U-1U) << 4U)  /* number of stop bits */
                      | (uint32)((uint32)0U << 3U)  /* even parity, otherwise odd */
                      | (uint32)((uint32)0U << 2U)  /* enable parity */
                      | (uint32)((uint32)1U << 1U);  /* asynchronous timing mode */
    
        /** - set baudrate */
        sciREG3->BRS = 40U;  /* baudrate */
    
        /** - transmission length */
        sciREG3->FORMAT = 8U - 1U;  /* length */
    
        /** - set SCI3 pins functional mode */
        sciREG3->PIO0 = (uint32)((uint32)1U << 2U)  /* tx pin */
                     | (uint32)((uint32)1U << 1U); /* rx pin */
    
        /** - set SCI3 pins default output value */
        sciREG3->PIO3 = (uint32)((uint32)0U << 2U)  /* tx pin */
                     | (uint32)((uint32)0U << 1U); /* rx pin */
    
        /** - set SCI3 pins output direction */
        sciREG3->PIO1 = (uint32)((uint32)0U << 2U)  /* tx pin */
                     | (uint32)((uint32)0U << 1U); /* rx pin */
    
        /** - set SCI3 pins open drain enable */
        sciREG3->PIO6 = (uint32)((uint32)0U << 2U)  /* tx pin */
                     | (uint32)((uint32)0U << 1U); /* rx pin */
    
        /** - set SCI3 pins pullup/pulldown enable */
        sciREG3->PIO7 = (uint32)((uint32)0U << 2U)  /* tx pin */
                     | (uint32)((uint32)0U << 1U); /* rx pin */
    
        /** - set SCI3 pins pullup/pulldown select */
        sciREG3->PIO8 = (uint32)((uint32)1U << 2U)  /* tx pin */
                     | (uint32)((uint32)1U << 1U);  /* rx pin */
    
        /** - set interrupt level */
        sciREG3->SETINTLVL = (uint32)((uint32)0U << 26U)  /* Framing error */
                          | (uint32)((uint32)0U << 25U)  /* Overrun error */
                          | (uint32)((uint32)0U << 24U)  /* Parity error */
                          | (uint32)((uint32)0U << 9U)  /* Receive */
                          | (uint32)((uint32)0U << 8U)  /* Transmit */
                          | (uint32)((uint32)1U << 1U)  /* Wakeup */
                          | (uint32)((uint32)0U << 0U);  /* Break detect */
    
        /** - set interrupt enable */
        sciREG3->SETINT = (uint32)((uint32)0U << 26U)  /* Framing error */
                       | (uint32)((uint32)0U << 25U)  /* Overrun error */
                       | (uint32)((uint32)0U << 24U)  /* Parity error */
                       | (uint32)((uint32)1U << 9U)  /* Receive */
                       | (uint32)((uint32)1U << 1U)  /* Wakeup */
                       | (uint32)((uint32)0U << 0U);  /* Break detect */
    
        /** - initialize global transfer variables */
        g_sciTransfer_t[2U].mode   = (uint32)0U << 8U;
        g_sciTransfer_t[2U].tx_length = 0U;
    	g_sciTransfer_t[2U].rx_length = 0U;
    
        /** - Finaly start SCI3 */
        sciREG3->GCR1 |= 0x80U;
    
    
    }

     

    When FreeRTOS run the IDLE task. That task calls an Idle task hook which is a place to put the microcontroller into low power mode:

    void vApplicationIdleHook(void)
    {
        for( ;; )
        {
            systemPowerDown(SYS_SLEEP_MODE);
        }
    }

    Please let me know if the code I sent is helpful.

    Pablo

  • Hi Pablo,

    Can I have the systemPowerDown()?

  • Yes, I copy the code:

    /* SourceId : SYSTEM_SourceId_007 */
    /* DesignId : SYSTEM_DesignId_007 */
    /* Requirements : HL_CONQ_SYSTEM_SR8 */
    void systemPowerDown(uint32 mode)
    {
    
    /* USER CODE BEGIN (23) */
    /* USER CODE END */
    
        /* Disable clock sources */
        systemREG1->CSDISSET = mode & 0x000000FFU;
    
        /* Disable clock domains */
        systemREG1->CDDIS = (mode >> 8U) & 0x00000FFFU;
    
        /* Idle CPU */
        /*SAFETYMCUSW 88 S MR:2.1 <APPROVED> "Assembly in C needed" */
        _gotoCPUIdle_();
    
    /* USER CODE BEGIN (24) */
    /* USER CODE END */
    
    }

  • Hi Pablo,

    The flash banks and flash pump should be programmed to sleep mode too. 

    The L2FMC on LC4357 is different from the FMC used on other Cortex-R4F devices. The L2FMC doesn't have BAGP (bank active grace period) and PAGP. (Pump active grace period). When the PUMP power mode is switched to SLEEP mode (by clearing PUMPPWR bit in FPAC1 register), the L2FMC will immediately apply the new power mode to the PUMP. When the BANK1, BANK2 and BANK7 power mode is switched to a mode other than ACTIVE mode (FBPWRMODE register), the L2FMC will immediately apply the new power mode to the affected banks.

    This means that the code to disable clock source and clock domain should be executed from SRAM.

    BTW, the TMS570 devices are not low power devices. There are some current leakage even in sleep mode.

  • Hi QJ,

    Thanks you! Very good explained.

    Pablo