Shop OBEX P1 Docs P2 Docs Learn Events
Clkset — Parallax Forums

Clkset

computer guycomputer guy Posts: 1,113
edited 2012-08-01 14:12 in Propeller 1
Hello,

I want to slow the propellers internal clock down during idle times (to save battery power).
I currently have these settings:
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000

Can someone give me a good example of values to put into the CLKSET function to put it into an "idle" state.
In this state all I need to do is wake up every 30 seconds for 2 seconds or so. FDS will also be looking for serial data at 115,200kbps.

So the clock speed needs to be fast enough to receive at 115,200kbps. Apart from that as long as I can WAITCNT for 30 seconds, it should be ok.


Basically the program wakes up every 30 seconds, reads a sensor using RCTIME, sends the value over Bluetooth and then goes back to sleep.



Thank you :)

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-07-30 07:48
    Here are a couple of methods from a program that would put the Prop to sleep and wait for a button press to wake up.
    PUB WakeUp
    '' Start debug cog and Nordic cog
    '' Change clock settings to 80MHz
      [B]Speed.SetClock(_Fast)
    [/B]  [B]debugCog := Debug.start(31, 30, 0, 57600) - 1
    [/B]  nordicCog := Nordic.Restart
      Debug.str(String(13, "Powering Up"))
      Debug.str(String(13, "wakeupEvent ="))
      Debug.dec(wakeupEvent)
      ToggleAlarm(1) 
      powerMode := Header#_HighPower
      lastActivityTime := cnt
      DisplayDebugInfo
      
    PUB Sleep
    '' Stop all other cogs
    '' Change clock mode to RCSLOW
      Debug.str(String(13, "Powering Down"))
      Led.Stop
      ledCog := -1
      Nordic.Stop
      nordicCog := -1
      ToggleAlarm(0)
      DisplayDebugInfo
      waitcnt(clkfreq / 2 + cnt)
      [B]Debug.Stop
    [/B]  debugCog := -1
      powerMode := Header#_LowPower
      [B]Speed.SetClock(_Slow)
    [/B]  
      waitpne(waitpneState, waitpneMask, 0)
      if ina[spiIrq]  == 0 
        wakeupEvent := Header#_IrqWake
      else
        wakeupEvent := Header#_ButtonWake
      WakeUp 
      
    
    

    Here are a couple of the constants used above.
    CON
      _Fast = xtal1 + pll16x
      _Slow = RCSLOW
    
    

    The "Speed" object is the program "Clock.spin" from the Prop Tool's library.

    I left a bunch of extra house keeping statements in the method.

    Instead of a waitpne you could use a waitcnt with the appropriate wait amount with the Prop running in RCSLOW mode.

    All other cogs are stopped before putting the Prop in RCSLOW mode. When the Prop wakes back up all the other cogs have to be restarted.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2012-07-30 08:30
    Here are the methods I use:
    PRI _rcslow_prop
    '' put propeller into slowest power save speed (using internal oscilator)
    
      clkset(%0_0_0_00_001, 20_000)                                                 ' ~20kHz no PLL
    
    PRI _rcfast_prop
    '' put propeller into ~12MHz (using internal oscilator)
    
      clkset(%0_0_0_00_000, 12_000_000)                                             ' ~12MHz no PLL
      
    PRI _rc_to_slow_prop
    '' put propeller into slowest power save speed (using XTAL), intended to be used after propeller was put in rcslow/rcfast mode
    
      clkset(%0_0_1_01_001, 20_000)                                                 ' turn on crystal, but don't use it
      waitcnt(351 + cnt)                                                            ' wait [at least] 10ms for PLL/crystal to stabilize
      clkset(%0_0_1_01_010, 5_000_000)                                              ' 5MHz no PLL 
        
    PRI _rc_to_med_prop
    '' put propeller into a medium speed (20MHz), intended to be used after propeller was put in rcslow/rcfast mode
    
      clkset(%0_1_1_01_000, 12_000_000)                                             ' turn on PLL/crystal, but don't use it
      waitcnt(120000 + cnt)                                                         ' wait 10ms for PLL/crystal to stabilize
      clkset(%0_1_1_01_101, 20_000_000)                                             ' 20MHz
    
    PRI _rc_to_fast_prop
    '' put propeller into a fast speed (80MHz), intended to be used after propeller was put in rcslow/rcfast mode
    
      clkset(%0_1_1_01_000, 12_000_000)                                             ' turn on PLL/crystal, but don't use it
      waitcnt(120000 + cnt)                                                         ' wait 10ms for PLL/crystal to stabilize
      clkset(%0_1_1_01_111, 80_000_000)                                             ' 80MHz
    
    PRI _slow_prop
    '' put propeller into slowest power save speed (using XTAL)
    
      clkset(%0_0_1_01_010, 5_000_000)                                              ' 5MHz no PLL 
        
    PRI _slow_to_med_prop
    '' put propeller into a medium speed (20MHz), intended to be used after propeller was put in slow mode
    
      clkset(%0_1_1_01_010, 5_000_000)                                              ' turn on PLL, but don't use it
      waitcnt(500 + cnt)                                                            ' wait 100us for PLL to stabilize
      clkset(%0_1_1_01_101, 20_000_000)                                             ' 20MHz
    
    PRI _slow_to_fast_prop
    '' put propeller into a fast speed (80MHz), intended to be used after propeller was put in slow mode
    
      clkset(%0_1_1_01_010, 5_000_000)                                              ' turn on PLL, but don't use it
      waitcnt(500 + cnt)                                                            ' wait 100us for PLL to stabilize
      clkset(%0_1_1_01_111, 80_000_000)                                             ' 80MHz
    

    These methods take into account enabling and disabling of XTAL and PLL, to correctly save you power. It also has the right timing between clkset operations.

    If the timing doesn't need to be exactly 30 seconds, it would be best to put the Prop into _rcslow_prop (20kHz), then "wake it up" using _rc_to_fast_prop (80MHz). If the 30 seconds need to be precise/accurate, you will have to continually use the crystal, so the slowest you can go is 5MHz. So then you would have to use _slow_prop and _slow_to_fast_prop.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-07-30 09:23
    So the clock speed needs to be fast enough to receive at 115,200kbps. Apart from that as long as I can WAITCNT for 30 seconds, it should be ok.
    If I understand correctly, you want to be able to receive serial data at 115,200 kbps when in the slow mode. You might be able to change the PLL multiplier from 16x to 1x to do this. You would need a serial receiver that is basically capable of running at 1.84 mbps in the 16x mode so that it can run at 115,200 in the 1x mode. I think that's doable. If not, you should be able to use the 2x mode instead. If you want your serial receiver to work at both the fast and slow clock rates you will need to reconfigure it whenever you change the clock speed.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-07-30 09:48
    If you do have to receive asynchronous serial data without error, there is always a chance that your program is in the middle of changing clock speed and restarting the UARTs at the exact moment a serial packet arrives. If you can detect that and/or live with it, fine. Otherwise, it is better to try to live with one single lower clock speed. I had posted a receive-only UART that can take in packets at full-on 115kB with 1 stop bit with clkfreq=5MHz.

    If your scheme does allow a drop to micro-power RCslow, the slow phase code should be absolute minimum and in-line, not levels of methods removed. It will usually consist of a WAIT for a pin or a count and then (in line) perhaps a simple conditional test and loop, or an immediate switchover to 12MHz RCfast, with or without the crystal oscillator enabled to allow it to get up to speed while the program executes non-time-critical tasks.
  • ElectricAyeElectricAye Posts: 4,561
    edited 2012-08-01 14:12
    Hey guys,
    thanks for posting your code examples and ideas on this. It's been very helpful today.
Sign In or Register to comment.