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.

Trying to reduce power usage during deep sleep while using a timer as a PWM to control a speaker

Basically what I am trying to do is create an audio tone using a small speaker on a pin using a timer and then stop/disable the timer when the tone should be off so as to have the micro use as little power as possible for when I enter Deep Sleep.  The code below works great for creating the audio tone and using little power.  My question is what exactly happens when I call the following function and is there any undesired consequences of calling this function as I have?  MAP_TimerConfigure(AUDIO_TIMER_BASE, 0);  I'm wondering if the pin may get set to the wrong state randomly and use more power than expected at times or that some other unsafe operation may result.  

Without using this function above, we see the power used by the micro increase to a higher than expected value after entering/exiting Deep Sleep 1-4 times.  The first 1-4 times, the power usage is as expected, but then the pin will get stuck in a high state (and thus use more power) whenever we enter deep sleep without this function in the code.  Any explanation of why this happens would be great as well.

I am using PC6 with WTMR1 and CCP0 on a LM4F112C4QC.

Let me know if any further details are needed.  Thank you

//***This section initialized upon powering the micro***

// Compute the PWM period based on the system clock and ideal frequency of speaker
ulPeriod = MAP_SysCtlClockGet() / AUDIO_FREQUENCY;

//
// Enable the peripherals used by the audio.
//
MAP_SysCtlPeripheralEnable(AUDIO_TIMER_PERIPH);
MAP_GPIOPinConfigure(AUDIO_PWM_PIN);
MAP_GPIOPinTypeTimer(MAC_GET_BASE_ADDRESS(AUDIO_PIN), MAC_GET_PIN(AUDIO_PIN));

//
// Configure the timers.
//
MAP_TimerConfigure(AUDIO_TIMER_BASE, TIMER_CFG_SPLIT_PAIR | AUDIO_TIMER_PWM);
MAP_TimerLoadSet(AUDIO_TIMER_BASE, AUDIO_TIMER_AB, ulPeriod-1);

//***This section called every 10 ms***

MAP_GPIODirModeSet(MAC_GET_BASE_ADDRESS(AUDIO_PIN), MAC_GET_PIN(AUDIO_PIN), GPIO_DIR_MODE_HW); //Set the direction as HW/Peripheral

if(msAudio > 0   //Check if audio timer is expired
&& volume != VOLUME_OFF_CUCHAR)
{
MAP_TimerConfigure(AUDIO_TIMER_BASE, TIMER_CFG_SPLIT_PAIR | AUDIO_TIMER_PWM);   //Configure timer to be a PWM Split Pair Type
MAP_TimerEnable(AUDIO_TIMER_BASE, AUDIO_TIMER_AB);   //Enable the Audio timer for audible tones
}
else //If it is, turn off the audio
{
common_audiodr_setVolume_void(VOLUME_OFF_CUCHAR);   //Set volume to be OFF
MAP_TimerControlLevel(AUDIO_TIMER_BASE, AUDIO_TIMER_AB, 1);   //When true, timer's output is made active low
MAP_TimerDisable(AUDIO_TIMER_BASE, AUDIO_TIMER_AB);   //Disable the Audio timer after setting the volume to off
MAP_TimerConfigure(AUDIO_TIMER_BASE, 0);   //Un-configure the timer so that it doesn't work with no audio tone and cause extra power usage
}

if(msAudio > 0) //If audio timer is not 0
{
msAudio -= 10; //Decrement timer
}

  • From my read of SW-DRL-UG9453: functions TimerControlLevel() & TimerDisable() seek TIMER_A, TIMER_B or TIMER_BOTH for param. ulTimer.  You've created your own unique defines - can't find them w/in your listing - suspect that they do comply but wise to verify. 

    The fact that your method works 1-4 times does concern - and intrigue.  Unstated (my belief) is your method to invoke "Deep Sleep."  And - might the timer some way/how "escape" from the "turn off the audio" function - prior to entry into Deep Sleep? 

    As you list "section called every 10mS" - might some unplanned event occur just prior to entry to Deep Sleep - upsetting your orderly shut-down? 

  • Thanks for your response on this.  

    Yes, all parameters are valid and comply.  All defines used in the first post are to allow flexibility in our designs when going from one micro to another for different projects.  TIMER_A is used in this case as it is associated with CCP0, if you want details of the other parameters, let me know. 

    As for the timer escaping before entering deep sleep, even calling these lines of code that update every 10ms directly before entering the deep sleep (without the call to MAP_TimerConfigure(AUDIO_TIMER_BASE, 0); in the 10ms update), will result in power usage to increase after a few repetitions of entering and exiting deep sleep. 

    Just adding MAP_TimerConfigure(AUDIO_TIMER_BASE, 0); as shown in my first post will cause it to always have the lower power usage while in deep sleep.  My main concern right now is that I don't know if by setting the parameter to 0, if it will cause any undesired effects or possibly will eventually cause the higher power usage to occur, just not as quick.  

    I'm still not sure why the power can increase after a few times of going to deep sleep, but if we can understand what the effect of using TimerConfigure(AUDIO_TIMER_BASE, 0) has on the micro, maybe then we will be able to understand better the issue that arises with deep sleep as I believe the code should be able to always use the lower amount of power without having to call TimerConfigure(AUDIO_TIMER_BASE, 0) when the audio is off.

  • Have not bumped against this in nearly 7 years w/Stellaris.  (last 2+ via LX4F)  (use many ARM MCUs - several vendors)

    Have 6 (started w/3...) further suggestions which will potentially add to your knowledge base:

    a) w/in driverlib - timer.c will reveal "inner workings/lurkings" of each/every timer function

    b) might something else w/in your code - seemingly far from this "stuck high" issue - be intruding?  When you return from deep sleep - is it possible to immediately capture all key MCU set-ups/configs - thus determine if something has altered?

    c) unfortunate but present (this vendor, all others) have you thoroughly checked errata - keyed at/near your issue?  (or related)

    d) try another Timer - see if issue persists.  Surely will get better response from "officials" - if this issue is broader than you initially report.   And - this 2nd timer may "escape" any unsuspected linkage - dooming your first attempt...  (always clients "roll their eyes" when we so suggest - yet later may be pleasantly surprised...)

    and e) might the offender be the audio device - which feeds thru to your timer pin - and becomes disruptive?  We're not told if your timer drives high or low to actuate - but there is some potential for unwanted signal flow from the audio device into the timer - when the MCU sleeps...

    now f) Best for Last (of course) ... Simply break the connection to the Audio Device - see how the Timer output behaves when "free."   You may then add 10K pull-up/down - see how/if this influences...

    Long past - Stellaris was never "famed" for competitive low power operation - and our LX4F reveals (via data sheet) a "deep sleep" nominal current of 1.05mA - and this only w/all peripherals off - and IOSC30KHz.  While the sleep may be (wishfully described) as "deep" - current drain forces one eye to frequently open - checking declining VBat... 

    Perhaps marketing & engineering could join forces - "comatose" (and its sub 50uA drain) likely will prove far more restful...