Help! I've slowed down and I can't speed up! (SOLVED)

mparkmpark Posts: 1,206
edited 2020-07-19 - 12:33:53 in Propeller 1
I'm trying to use clkset to switch my Propeller between rcslow and xtal1+pll16x. This is what I have so far:
_clkmode = xtal1+pll16x
_clkfreq = 80_000_000

pub main | t
  dira[16]~~
  repeat
    clkset(%000_00_001, 20_000) ' rcslow
    
    outa[16]~
    waitcnt(clkfreq * 3 + cnt)

    'clkset(%011_01_001, 20_000)
    'waitcnt(clkfreq / 100 + cnt)
    'clkset(%011_01_111, 80_000_000)

    outa[16]~~
    t := cnt
    repeat until cnt - t => clkfreq * 3
This sets the clock to rcslow and the LED toggles on/off every 3 seconds. So far, so good.

If I uncomment those three commented-out lines, I expect the clock to rev up to 80MHz after 3 seconds, but it doesn't. I see current consumption jump slightly after 3 seconds (from 3.8mA to 4.8mA) but the LED remains off.

What is the correct procedure to switch from rcslow to xtal1+pll16x?




Comments

  • mpark wrote:
    Help! I've slowed down and I can't speed up!
    Well, we're all getting older, after all. :)

    -Phil
  • From the Propeller manual:

    In general, it is safe to switch between clock modes by using a single CLKSET command, however, if enabling the Crystal Oscillator circuit (CLK register’s OSCENA bit) it is important to perform the clock mode switch as a three-stage process:

    1) First set the CLK register’s PLLENA, OSCENA, OSCM1 and OSCM0 bits as necessary. See CLK Register on page 28 for more information.

    2) Wait for 10 ms to give the external crystal time to stabilize.

    3) Set the CLK register’s CLKSELx bits as necessary to switch the System Clock to the new source.

    The above process is only necessary when switching the Crystal Oscillator circuit on. No other clock mode changes require this process if the Crystal Oscillator circuit is left in its current state, either off or on. See the Clock object in the Propeller Library for clock modification and timing methods.


    But it looks like you're doing that. Can you verify that you can run at 80MHz out of the gate? IOW is your crystal circuit operational?

    -Phil
  • Another thought: your waitcnt(clkfreq / 100 + cnt) isn't guaranteed to be 10 ms, since it relies upon the inexact RC clock circuit. Try doubling the wait time.

    -Phil
  • Thank you, @Phil Pilgrim (PhiPi)! I changed clkfreq / 100 to clkfreq / 50 and it works: the LED toggles every 3 s and while it's off, the current is 3.8 mA, and when it's on, ~23 mA.

    I don't suppose there's any way to get that 3.8 mA even lower though, is there?
  • Try making any unused, unconnected pins outputs. So they're not flapping in the breeze consuming current. Curious as to the reduction you'll see.
  • Ooh, interesting thought, @whicker! I changed dira[16]~~ to dira := $ffff_ffff and the current went up to 4.4 mA and ~24 mA. But then I realized the eeprom is on pins 28 and 29, so I set dira := $cfff_ffff and the current went back to 3.8/23.

  • Well, I said unused. So isn't it more like $0fff_ffff since 30 and 31 are also used?

    But what board are you using? Are you measuring the current draw of the Propeller chip alone?
  • Oh yeah, $0fff_ffff didn't change anything (still 3.8 mA). It's a board of my own "design", just a P1, xtal, eeprom, and voltage regulator. And an LED at the moment. I'm measuring current into the regulator.

    Meanwhile, I tried to duplicate my Spin program in SimpleIDE, but strangely I had to divide CLKFREQ by 25 instead of 50:
    while (1) {
      clkset(0b00000001, 20000); // rcslow
      low(16);
      waitcnt(CLKFREQ * 3 + CNT);
    
      clkset(0b01101001, 20000);
      waitcnt(CLKFREQ / 25 + CNT);
      clkset(0b01101111, 80000000);
      
      high(16);
      pause(3000);
    }
    
    Same board, but dividing by 50 had the same problem as my first post.
    Wondering if anyone has some insight as to why Spin and C differ here.
  • maybe because spin is interpreted and C is compiled.

    Mike
  • Quite so, @msrobots. I finally came to that conclusion myself. Took me all evening, though :)
  • On a timescale of tens of millisseconds, and the fact that that both interpreted and compiled code use the native waitcnt instruction, I don't believe that the speed of execution has anything to do with it.

    -Phil
  • Wuerfel_21Wuerfel_21 Posts: 805
    edited 2020-07-19 - 17:12:06
    Well, for a line like
    waitcnt(1000+cnt)
    
    spin takes some ~380 cycles to actually get to the WAITCNT instruction, probably a good bit longer with the divide in there. At RCSLOW, that is a couple milliseconds.
  • And the difference between the two waitcnts (20_000 / 25 vs 20_000 / 50) is only 400 clocks, so I have no problem believing that Spin interpreter overhead makes up the difference.

    But if Phil has a different theory, I'd love to hear it!
  • mpark wrote:
    ...I have no problem believing that Spin interpreter overhead makes up the difference.

    In retrospect, that seems reasonable.

    -Phil
Sign In or Register to comment.