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.

PWM and Deep Sleep Mode

Other Parts Discussed in Thread: LMFLASHPROGRAMMER

Hello. I'm playing with the PWM mode at the TIVA Launchpad, to light a LED with a PWM pulse. I'm using this program:

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/pin_map.h" // Include para poder configurar el pin como salida PWM

#define PWMCYCLE    60000
#define DUTYCYCLE99 PWMCYCLE*0.99
#define DUTYCYCLE75 PWMCYCLE*0.75
#define DUTYCYCLE25 PWMCYCLE*0.25

int main(void) {
    uint32_t ui32Period, ui32DutyCycle;

    //  System clock to 40MHz (PLL-200MHz/5=40MHz)
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    //SysCtlClockSet(SYSCTL_USE_OSC | SYSCTL_OSC_INT30); // DON'T USE LFIOSC!! --> TIVA DEBUG problems (use LMFLASHPROGRAMMER to unlock)
    // PWM Square wave definition
    ui32Period = PWMCYCLE ; // PWM period
    ui32DutyCycle = DUTYCYCLE99;// PWM Duty cycle

    // Port configuration (LEDS)
    // Enable GPIOF port
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    // LED connected pins as outputs
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    //  Switch off LEDs
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);

    // PF1 pin as PWM output at Timer0B (T0CCP1)
    GPIOPinConfigure(GPIO_PF1_T0CCP1);
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);

    // Timer configuration

    // Enable Timer0
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    // Split Timers A and B, to allow TimerB to work as PWM
    TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
    // Load timer period
    TimerLoadSet(TIMER0_BASE, TIMER_B, ui32Period);
    // Load duty cycle
    TimerMatchSet(TIMER0_BASE, TIMER_B, ui32DutyCycle);
    // Enable Timer
    TimerEnable(TIMER0_BASE, TIMER_B);
    while(1) {
    	SysCtlDeepSleep();
    }
}

When I switch from SleepMode to DeepSleepMode, LED can be seen blinking. That should be OK, because in DeepSleepMode clock is changed to LFIOSC at 30KHz...
But I also tried a System Clock configuration at 30KHz from the beginning ( SysCtlClockSet(SYSCTL_USE_OSC | SYSCTL_OSC_INT30); --> BEWARE: this configuration will lock your TIVA, so you need LMFLASHProgrammer to unlock it), and the blinking rate is clearly slower than when configuring a 40MHz System clock. I supposed that 40MHz clock becomes inactive in DeepSleep Mode, so using this mode blinking rate should be the same for a System Clock at 40MHz, and a System Clock at 30KHz (considering that, in the first case, system clock switchs to 30KHz when entering DeepSleepMode)

Am I missing something?
Thanks in advance

  • Hello Ignacio,

    That is correct, the blinking rate at 30KHz will be slower than 40MHz. However to make the clock switch to 30KHz in Deep Sleep, the debugger needs to be disconnected.

    Regards

    Amit

  • Thank you, Amit.

    But my question is about that, in the above program, supposedly  the blinking rate should be the same using:

    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); --> PLL (40MHz)

    and

    SysCtlClockSet(SYSCTL_USE_OSC | SYSCTL_OSC_INT30) --> LFIOSC (30KHz)

    as, when we enter DeepSleepMode, we disconnect  all clocks but LFIOSC, and source the PWM with 30KHz in BOTH cases.

    But it doesn't happens that way: using SysCtlClockSet(SYSCTL_USE_OSC | SYSCTL_OSC_INT30) we obtain a remarkably slower blink rate than using  SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    (with CCS closed so TIVA Launchpad is NOT in Debug Mode).

    I think that it is working right with SYSCTL_USE_OSC | SYSCTL_OSC_INT30 option as I can see the LED blinking at about 1Hz ((60000/30KHz) *2), but with the other configuration the blink rate is about 20/30 times faster!! (why?)

    So I don't understand what is happening here....

  • Hi Ignacio,

    CCS closed does not mean it is not in debug mode. The debug connection inside the design of CM$ processor is a sticky bit. So simply disconnecting CCS is not sufficient.

    The other way is to power cycle the board to clear the sticky bit. I believe what you are seeing is because of the fact the debugger is not disconnected (owing to the sticky bit), the clock switchover is not happening.

    Regards

    Amit

  • @Ignacio,

    I would like to bring to your attention the followings:

    a) while your thread is about "deep sleep mode" you call the sleep function, not the deep sleep one - so it is not clear your test here. But for both functions, please look the code in driverlib - both uses a call to CPUwfi() function - "wait for interrupt" function to return from any kind of sleep, but it seems you do not provide such interrupt function so this is a possible cause of unexpected blocking code warned in the first post.

    b) if you did not upgraded to Tiva 2.x, please do - there are some useful functions here - SysCtlDeepSleepClockConfigSet(uint32_t, uint32_t) - there are some useful info both in driverlib and user's manual - there is an additional clock divider to be set, usually at reset is set to divide by 0xF, so the operating frequency is much smaller...

    Petrei

  • Hello @Petrei, and thank you for your help.

    a)Though in the code posted above I have a Sleep call, the problem is related to the commented instruction just before (a DeepSleep call). I posted the whole code with the different alternatives I'm testing; I'm sorry for the confusion. Anyway, no need of interrupts as I'm using PWM to control LED blinking.

    b). yes, I'm using  TIVA2.01.11577. The function SysCtlDeepSleepClockConfigSet could be interesting if I wanted another oscillator source in DeepSleep mode, but I'm testing LFIOSC, which is (supposed) the default clock for the device when entering DeppSleep mode.

    - Ignacio -

  • Hello @Amit.

    Power cycling doesn't help: LED continues blnking at a higher rate than it should be.

    Could you test the program at the first post, using the two alternative "SysCtlClockSet" configurations?

    I'm using a TIVA Launchpad. I expected the same blinking rate for the LED with both configurations as, after entering DeepSleep mode, LFIOSC should be the clock controlling the PWM cycle, for both cases.

    Thanks again

    - Ignacio -

  • Hello Ignacio,

    Can you attach the code that you are using. I think there are updates to it as per the thread, so would want to see if the correct configuration is being done.

    Regards

    Amit

  • Hello Amit.

    Here is the code:

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/timer.h"
    #include "driverlib/pin_map.h"
    #define PWMCYCLE    60000
    #define DUTYCYCLE99 PWMCYCLE*0.99
    #define DUTYCYCLE75 PWMCYCLE*0.75
    #define DUTYCYCLE25 PWMCYCLE*0.25
    int main(void) {
        uint32_t ui32Period, ui32DutyCycle;
        //  System clock to 40MHz (PLL-200MHz/5=40MHz)
        SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
         // (Alternative 2) System clock to 30KHz (LFIOSC)
        //SysCtlClockSet(SYSCTL_USE_OSC | SYSCTL_OSC_INT30); // DON'T USE LFIOSC!! --> TIVA DEBUG problems (use LMFLASHPROGRAMMER to unlock)
        // PWM Square wave definition
        ui32Period = PWMCYCLE ; // PWM period
        ui32DutyCycle = DUTYCYCLE99;// PWM Duty cycle
        // Port configuration (LEDS)
        // Enable GPIOF port
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        // LED connected pins as outputs
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
        //  Switch off LEDs
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
        // PF1 pin as PWM output at Timer0B (T0CCP1)
        GPIOPinConfigure(GPIO_PF1_T0CCP1);
        GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1);
        // Timer configuration
        // Enable Timer0
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
        // Split Timers A and B, to allow TimerB to work as PWM
        TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
        // Load timer period
        TimerLoadSet(TIMER0_BASE, TIMER_B, ui32Period);
        // Load duty cycle
        TimerMatchSet(TIMER0_BASE, TIMER_B, ui32DutyCycle);
        // Enable Timer
        TimerEnable(TIMER0_BASE, TIMER_B);
        while(1) {
            SysCtlDeepSleep();
        }
    }

    Also attached the file to this post.

    Thanks

    - Ignacio -

  • Hi Ignacio,

    In the case of the Deep Sleep when running of the PLL, you have not confiugured the System to use the Deep Sleep Clock Source as LFIOSC.

    I am sure that data sheet does not mention LFIOSC as the default clock source for Deep Sleep. This is configurable in the SYSCTL.DSLPCLKCFG register in which the default is MOSC

    Regards

    Amit

  • Hi Ignacio,

    I made a small change of calling the SysCtlDeepSleepClockSet(SYSCTL_DSLP_OSC_INT30) and now irrespective of the Run Mode Clock, the deep sleep blinking rate is the same.

    Regards

    Amit Ashara

  • Oh my!!

    I read "The Low Frequency internal oscillator is used during Deep Sleep power-saving mode" instead of "The Low Frequency internal oscillator is innended for use during Deep Sleep power-saving mode"!!!

    So, it's necessary to state which clock is going to be the device clock source in DeepSleep mode,...but only if you are using the MOSC I suppose....

    Thanks a lot for your help and your time.

    Just a curiosity:  in my original code (where SysCtlDeepSleepClockSet  was missing) ) which clock was using the system when entering Deep Sleep mode? It was not the 40MHz-PLL at run mode, and, obviously not the LFIOSC...

    - Ignacio -

  • Hi Ignacio,

    In the original code it was the MOSC being used since in the SysCtlClockSet function you had mentioned to use 16MHz MOSC as the clock source for PLL. Since the MOSC was active and when you did not program the deep sleep clock source, the default of MOSC continued.

    Regards

    Amit Ashara

  • Ok, thanks a lot again!

  • Hello All,

    I have never came into this section of getting TIVA in sleep mode /  Deep Sleep Mode.

    I have gone through several code examples but I have not found anything good.

    I have couple of basic query, it would be great if anyone could help:

    1) If we get into sleep mode or deep sleep mode, how can I come out of that particular mode to r=normal mode?

    2) Is it possible that if I can configure a pin as input pin and in sleep or deep sleep mode if my pin recieves high/low pulse it comes back to nomal mode?

    3) Is there any proper example code which i can refer?

    Kindly let me know if you could help me out.

    Thanks,

    Mitesh