Shop OBEX P1 Docs P2 Docs Learn Events
Pin bank clock rate observation — Parallax Forums

Pin bank clock rate observation

HumanoidoHumanoido Posts: 5,770
edited 2009-12-06 11:43 in Propeller 1
(just for study) re: Propeller

The internal clock frequency changes based on the pin bank.
Compare pins 8 and then 16 using the program below.
With pin 8, the on time is much shorter.
What can you say about the system counter register (cnt) in each case?
The program (and circuit) are from the PE kit manual, see page 35.
What other clock rate effects can you find?

humanoido

CON
 _CLKMODE = RCFAST                           ' This mode is fast (12 MHz)
  LEDs_START      = 0                        ' Start of I/O pin group for on/off signals
  LEDs_END        = 15                       ' End of I/O pin group for on/off signals
  PUSHBUTTON      =  8                       ' Pushbutton Input Pin
'  PUSHBUTTON      = 16                       ' Pushbutton Input Pin 
PUB ButtonBlinkSpeed                         ' Main method ' Sends on/off signals approx 1 Hz
  dira[noparse][[/noparse]LEDs_START..LEDs_END]~~               ' Set entire pin group to output
  repeat                                     ' Endless loop
    ! outa[noparse][[/noparse]LEDs_START..LEDs_END]             ' Change the state of pin group    
    if ina[noparse][[/noparse]PUSHBUTTON] == 1                  ' If pushbutton pressed
      waitcnt(clkfreq / 20 + cnt)            ' Wait
    else                                     ' If pushbutton not pressed
      waitcnt(clkfreq / 1 + cnt)             ' Wait

Post Edited (humanoido) : 12/4/2009 6:04:12 PM GMT

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-12-04 18:17
    Actually, you can't tell anything about the clock frequency. Your LED pin group is 0..15 which includes the pin you're using for the pushbutton. Your "ina[noparse][[/noparse]PUSHBUTTON]" is testing the state of pin 8 which is being toggled by the outa statement. Obviously a closed pushbutton can't be overcome by an opposite output state, but, if the pushbutton is open, the pullup (or pulldown) can be overcome on alternate repeats by the state of the output pin.
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-04 19:07
    Another observation. If both switches are entirely removed,
    and left floating with nothing connected, exactly the same
    results are observed -
    the two pins remain different in timing consistently. Is there a
    rule that is used to determine the frequency and why is
    the opposite state different for both pins? What is affecting
    the state to change the clock? I may need a much more simple
    explanation. Thanks Mike.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-12-04 19:32
    Be careful about labelling this as a "clock change". The RC clocks (RCFAST and RCSLOW) are sensitive to the chip temperature (and supply voltage). If you're driving a bunch of LEDs at significant currents, that will cause some heating of the chip, particularly in the areas around the I/O pin circuitry around the periphery of the chip. I don't know where the RC clocks are located on the chip, but I think they're in the more central hub control area, so they'd be less affected by the local heating and more by the average chip temperature. There may be some voltage drops across the chip at high I/O currents, but I don't know enough about the chip's power distribution to say. I suspect the only real changes in clock speed are thermally based and would be slow, not state-like changes.

    You need to change the pins used for PUSHBUTTON to not include pins 0-15 for the reasons I stated. You could use 16 and 24 if you want to use other pin groups.

    Floating inputs are indeed affected by other signals nearby on the chip because they're high impedance. They're supposed to work that way. If you want a defined state, you have to provide it. There will be variations in pin thresholds from chip to chip and the signal received by the pin will vary from PCB to PCB, so it's anybody's guess how a particular floating input will react. There are no rules. You have to provide some kind of known state if you want it.
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-05 00:12
    I did more tests, and Mike, I can confirm the difference is between two blocks, i.e. pins P0 through P15 and P16 through P31. The 1st block of pins each have the exact same clock rate when no switch is pressed. However the 2nd block is considerably slower from the 1st block, and each pin of the 2nd block gives exactly the same clock blink rate.

    If this is an internal heat difference, it affects two blocks very differently. Is there that much of a dramatic difference in blink rate between the two blocks that internal heat can cause? I am not so convinced that one entire side of the chip would be so affected compared to the other side. There must be something else going on?

    The other effect you mentioned, an increase of clock speed based on voltage is confirmed. As the voltage increases, so does the rate of blinking. In this experiment, I used 1.8 to 3.5 volts to observe a change in rate. However, I have kept the voltage constant and regulated when testing the blocks.

    Floating or not, I see the same rate within the block.

    The circuit provides a known state across the two pin banks. The results are stable and unchanging in each block. The known state is a switch with a pull down arrangement.

    Whatever is causing the variance, it is certainly interesting, and, if it is consistent from chip to chip, it could be exploited in some programming techniques. But I think we need to know more about exactly what is happening first...

    Post Edited (humanoido) : 12/5/2009 12:22:05 AM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2009-12-05 00:31
    One other possibility is the use of small constants. There are special "push constant" bytecodes for small integers including powers of two of small integers. The lower numbered pins are accessed using smaller numbers which take less room and execute quicker than the larger numbers.

    Part of my objections to your characterization of the difference in performance based on pin banks is that there's nothing in the hardware that would account for this behavior. There are differences in signal propagation across the chip and along the DIR/OUT logic chain to the actual I/O pins, but we're talking about nanosecond and subnanosecond differences that are independent of clock speed rather than the several orders of magnitude greater differences you're observing in a Spin program.
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-05 00:56
    The possibility of lower numbered pins accessed using smaller numbers which take less room and execute quicker than the larger numbers does appear to best fit the observed results.

    The characterization of the difference in the observed results should be accurately represented, and by all means, the information you have provided to rule out hardware is certainly noted and well appreciated.

    Is there a way to read the special "push constant" bytecodes (that could lead to developing a quantitative algorithm)?
    Mike Green said...
    One other possibility is the use of small constants. There are special "push constant" bytecodes for small integers including powers of two of small integers. The lower numbered pins are accessed using smaller numbers which take less room and execute quicker than the larger numbers.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-12-05 03:46
    Use BST or HomeSpun to compile your program. Both of them will produce program listings with the compiled bytecodes. The Propeller Wikipedia has some detailed documentation on the byte codes as well (propeller.wikispaces.com/).
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-05 14:26
    Compiled with BST (PIN = 16 BANK =2)
    Where is the byte code of interest that indicates a difference when one pin bank is selected over the over?

    ===========================================================================|
    Objects : -
    +Untitled1
    
    Object Address : 0010 : Object Name : +Untitled1
    
    Binary Image Information :
    PBASE : 0010
    VBASE : 0044
    DBASE : 004C
    PCURR : 0018
    DCURR : 0050
    |===========================================================================|
    |===========================================================================|
    Object +Untitled1
    Object Base is 0010
    |===========================================================================|
    Object Constants
    |===========================================================================|
    Constant _CLKMODE = 00000001 (1)
    Constant LEDs_START = 00000000 (0)
    Constant LEDs_END = 0000000F (15)
    Constant PUSHBUTTON = 00000010 (16)
    |===========================================================================|
    |===========================================================================|
    Spin Block ButtonBlinkSpeed with 0 Parameters and 0 Extra Stack Longs. Method 1
    PUB ButtonBlinkSpeed                         ' Main method ' Sends on/off signals approx 1 Hz
    
    Local Parameter DBASE:0000 - Result
    |===========================================================================|
    14                        dira[noparse][[/noparse]LEDs_START..LEDs_END]~~               ' Set entire pin group to output
    Addr : 0018:             35  : Constant 1 $00000000
    Addr : 0019:          37 23  : Constant Mask Y=35 Decrement 0000000F
    Addr : 001B:       3E D6 1C  : Register [noparse][[/noparse]Bit..Bit] op DIRA VAR~~ Post-set
    Addr : 001E: Label0002
    16                          ! outa[noparse][[/noparse]LEDs_START..LEDs_END]             ' Change the state of pin group
    Addr : 001E:             35  : Constant 1 $00000000
    Addr : 001F:          37 23  : Constant Mask Y=35 Decrement 0000000F
    Addr : 0021:       3E D4 47  : Register [noparse][[/noparse]Bit..Bit] op OUTA LongMathop !
    17                          if ina[noparse][[/noparse]PUSHBUTTON] == 1                  ' If pushbutton pressed
    Addr : 0024:          37 03  : Constant Mask Y=3 00000010
    Addr : 0026:          3D 92  : Register [noparse][[/noparse]Bit] op INA Read
    Addr : 0028:             36  : Constant 2 $00000001
    Addr : 0029:             FC  : Math Op ==    
    Addr : 002A: JZ Label0005
    Addr : 002A:          0A 0B  : jz Address = 0037 11
    18                            waitcnt(clkfreq / 20 + cnt)            ' Wait 1 second -> 2 Hz
    Addr : 002C:             35  : Constant 1 $00000000
    Addr : 002D:             C0  : Memory Op Long POP Address READ 
    Addr : 002E:          38 14  : Constant 1 Bytes - 14 
    Addr : 0030:             F6  : Math Op /     
    Addr : 0031:          3F 91  : Register op CNT Read
    Addr : 0033:             EC  : Math Op +     
    Addr : 0034:             23  : WaitCnt(count)
    Addr : 0035: JMP Label0006
    Addr : 0035:          04 08  : Jmp 003F 8    
    Addr : 0037: Label0005
    20                            waitcnt(clkfreq / 1 + cnt)             ' Wait 1/40 second -> 10 Hz
    Addr : 0037:             35  : Constant 1 $00000000
    Addr : 0038:             C0  : Memory Op Long POP Address READ 
    Addr : 0039:             36  : Constant 2 $00000001
    Addr : 003A:             F6  : Math Op /     
    Addr : 003B:          3F 91  : Register op CNT Read
    Addr : 003D:             EC  : Math Op +     
    Addr : 003E:             23  : WaitCnt(count)
    Addr : 003F: Label0007
    Addr : 003F: Label0006
    Addr : 003F: Label0003
    Addr : 003F: JMP Label0002
    Addr : 003F:          04 5D  : Jmp 001E -35  
    Addr : 0041: Label0004
    Addr : 0041:             32  : Return
    



    PORT = 8 BANK = 1


    |===========================================================================|
    Objects : -
    +Untitled1
    
    Object Address : 0010 : Object Name : +Untitled1
    
    Binary Image Information :
    PBASE : 0010
    VBASE : 0044
    DBASE : 004C
    PCURR : 0018
    DCURR : 0050
    |===========================================================================|
    |===========================================================================|
    Object +Untitled1
    Object Base is 0010
    |===========================================================================|
    Object Constants
    |===========================================================================|
    Constant _CLKMODE = 00000001 (1)
    Constant LEDs_START = 00000000 (0)
    Constant LEDs_END = 0000000F (15)
    Constant PUSHBUTTON = 00000008 (8)
    |===========================================================================|
    |===========================================================================|
    Spin Block ButtonBlinkSpeed with 0 Parameters and 0 Extra Stack Longs. Method 1
    PUB ButtonBlinkSpeed                         ' Main method ' Sends on/off signals approx 1 Hz
    
    Local Parameter DBASE:0000 - Result
    |===========================================================================|
    14                        dira[noparse][[/noparse]LEDs_START..LEDs_END]~~               ' Set entire pin group to output
    Addr : 0018:             35  : Constant 1 $00000000
    Addr : 0019:          37 23  : Constant Mask Y=35 Decrement 0000000F
    Addr : 001B:       3E D6 1C  : Register [noparse][[/noparse]Bit..Bit] op DIRA VAR~~ Post-set
    Addr : 001E: Label0002
    16                          ! outa[noparse][[/noparse]LEDs_START..LEDs_END]             ' Change the state of pin group
    Addr : 001E:             35  : Constant 1 $00000000
    Addr : 001F:          37 23  : Constant Mask Y=35 Decrement 0000000F
    Addr : 0021:       3E D4 47  : Register [noparse][[/noparse]Bit..Bit] op OUTA LongMathop !
    17                          if ina[noparse][[/noparse]PUSHBUTTON] == 1                  ' If pushbutton pressed
    Addr : 0024:          37 02  : Constant Mask Y=2 00000008
    Addr : 0026:          3D 92  : Register [noparse][[/noparse]Bit] op INA Read
    Addr : 0028:             36  : Constant 2 $00000001
    Addr : 0029:             FC  : Math Op ==    
    Addr : 002A: JZ Label0005
    Addr : 002A:          0A 0B  : jz Address = 0037 11
    18                            waitcnt(clkfreq / 20 + cnt)            ' Wait 1 second -> 2 Hz
    Addr : 002C:             35  : Constant 1 $00000000
    Addr : 002D:             C0  : Memory Op Long POP Address READ 
    Addr : 002E:          38 14  : Constant 1 Bytes - 14 
    Addr : 0030:             F6  : Math Op /     
    Addr : 0031:          3F 91  : Register op CNT Read
    Addr : 0033:             EC  : Math Op +     
    Addr : 0034:             23  : WaitCnt(count)
    Addr : 0035: JMP Label0006
    Addr : 0035:          04 08  : Jmp 003F 8    
    Addr : 0037: Label0005
    20                            waitcnt(clkfreq / 1 + cnt)             ' Wait 1/40 second -> 10 Hz
    Addr : 0037:             35  : Constant 1 $00000000
    Addr : 0038:             C0  : Memory Op Long POP Address READ 
    Addr : 0039:             36  : Constant 2 $00000001
    Addr : 003A:             F6  : Math Op /     
    Addr : 003B:          3F 91  : Register op CNT Read
    Addr : 003D:             EC  : Math Op +     
    Addr : 003E:             23  : WaitCnt(count)
    Addr : 003F: Label0007
    Addr : 003F: Label0006
    Addr : 003F: Label0003
    Addr : 003F: JMP Label0002
    Addr : 003F:          04 5D  : Jmp 001E -35  
    Addr : 0041: Label0004
    Addr : 0041:             32  : Return
    

    Post Edited (humanoido) : 12/5/2009 5:02:52 PM GMT
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-06 00:34
    Even with the pushbutton code redefined from pin 8 to 16, there is no
    difference in the compiled code. So how does this show there is
    a change in compiled byte codes leading to different execution time?
  • Mike GreenMike Green Posts: 23,101
    edited 2009-12-06 00:42
    Maybe it doesn't. I thought you would be moving PUSHBUTTON to something other than 8 (and above 16). Remember that the program toggles I/O pin 8, thus overriding the value of the actual pushbutton on pin 8. I mentioned this earlier.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-12-06 00:43
    Are you sure that you compiled 2 different versions? In both LED_start and LED_end are the same. Should be different!
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-06 02:03
    Mike Green said...
    Maybe it doesn't. I thought you would be moving PUSHBUTTON to something other than 8 (and above 16).
    Let's call pins 8-15 group 1. Pins 16-31 group 2. We will put pushbuttons on each pin. But, we will not push any pushbuttons. We have the same code, but run it twice, changing the pin from 8 to 16. The first time we use code to show a button on pin 8. The second time we change the button to pin 16.

    The code gives the same blink rate when changed to any switch in group 1. The blink rate changes when the switch is anywhere in group 2. So I tried all these values, including all the pins in the group (other than 8 and above 16). The examples I gave used a pin from each group.
    Mike Green said...
    Remember that the program toggles I/O pin 8, thus overriding the value of the actual pushbutton on pin 8. I mentioned this earlier.
    If it toggles the pin in group 1, it should also toggle the pin in group 2. I don't see how that would give a different observed blinking rate.

    Group one has a quick short blink rate while group 2 has a much longer blink rate, i.e. the led on time is much longer.
    MagIO2 said...
    Are you sure that you compiled 2 different versions? In both LED_start and LED_end are the same. Should be different!
    As far as I know, the LED start and end statements should be the same. It's for LEDs on p0 through p7 which are not moved from one program to the next. The pin that is changed is the pushbutton on p8 to a pushbutton on p16 and you can see this change in the defined statement at the compilation beginning.

    Post Edited (humanoido) : 12/6/2009 2:14:28 AM GMT
  • BradCBradC Posts: 2,601
    edited 2009-12-06 02:15
    As Mike suggested already, if the push button input is in the bank you are toggling you will see differences in the flash time.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    If you always do what you always did, you always get what you always got.
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-06 03:00
    BradC: Very good. However, we are trying to isolate executed (compiled) statements that would lead to different timing from bank 1 to bank 2. As seen, the toggle takes place in both banks. If one refers to the toggle when on pin 8, there is also a toggle when on pin 16. If there is a better explanation, it would help understand the process.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-12-06 03:13
    I still think you're missing the bug. You're using pins 0-15 for the blink and pin 8 is one of those pins. When your toggle code toggles pin 8, it affects what's read from pin 8 and that changes the toggle rate. When you switch to use pin 16 for your input, the input reflects only the pushbutton status. As I suggested, you need to switch your pin assignments so that the pushbutton pin is different from the pins used for the LEDs in both cases.
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-06 04:46
    Thanks Mike for this lucid explanation. The code was changed to define the state of just the LEDs on pins 0 though 7 and this fixed the rate on pins 8 through 15 and 16 through 31 to the same. Code below. It is interesting that "outa" across pins 8 to 15 caused the on time rate of the LED to decrease (faster blink) over the pins that had no state change.

    CON
     _CLKMODE = RCFAST                           ' This mode is fast (12 MHz)
      LEDs_START      = 0                        ' Start of I/O pin group for on/off signals
      LEDs_END        = 7                        ' End of I/O pin group for on/off signals
      PUSHBUTTON      =  8                       ' Pushbutton Input Pin
    '  PUSHBUTTON      = 16                      ' Pushbutton Input Pin 
    PUB ButtonBlinkSpeed                         ' Main method ' Sends on/off signals approx 1 Hz
      dira[noparse][[/noparse]LEDs_START..LEDs_END]~~               ' Set entire pin group to output
      repeat                                     ' Endless loop
        ! outa[noparse][[/noparse]LEDs_START..LEDs_END]             ' Change the state of pin group    
        if ina[noparse][[/noparse]PUSHBUTTON] == 1                  ' If pushbutton pressed
          waitcnt(clkfreq / 20 + cnt)            ' Wait
        else                                     ' If pushbutton not pressed
          waitcnt(clkfreq / 1 + cnt)             ' Wait
    
  • BradCBradC Posts: 2,601
    edited 2009-12-06 05:27
    humanoido said...
    Thanks Mike for this lucid explanation. The code was changed to define the state of just the LEDs on pins 0 though 7 and this fixed the rate on pins 8 through 15 and 16 through 31 to the same. Code below. It is interesting that "outa" across pins 8 to 15 caused the on time rate of the LED to decrease (faster blink) over the pins that had no state change.

    If you set dira[noparse][[/noparse]PUSHBUTTON] to 1 (as you were doing initially) your test is _aways_ invalid and broken. Ensure that dira[noparse][[/noparse]PUSHBUTTON] always = 0 and re-run all your tests please.

    See added line below.

    CON
     _CLKMODE = RCFAST                           ' This mode is fast (12 MHz)
      LEDs_START      = 0                        ' Start of I/O pin group for on/off signals
      LEDs_END        = 7                        ' End of I/O pin group for on/off signals
      PUSHBUTTON      =  8                       ' Pushbutton Input Pin
    '  PUSHBUTTON      = 16                      ' Pushbutton Input Pin 
    PUB ButtonBlinkSpeed                         ' Main method ' Sends on/off signals approx 1 Hz
      dira[noparse][[/noparse]LEDs_START..LEDs_END]~~               ' Set entire pin group to output
      dira[noparse][[/noparse]PUSHBUTTON]~
      repeat                                     ' Endless loop
        ! outa[noparse][[/noparse]LEDs_START..LEDs_END]             ' Change the state of pin group    
        if ina[noparse][[/noparse]PUSHBUTTON] == 1                  ' If pushbutton pressed
          waitcnt(clkfreq / 20 + cnt)            ' Wait
        else                                     ' If pushbutton not pressed
          waitcnt(clkfreq / 1 + cnt)             ' Wait
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    If you always do what you always did, you always get what you always got.
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-12-06 11:43
    BradC: Very nice! All the tests were performed again using your code addition and the results
    are perfect. The addition of dira[noparse][[/noparse]PUSHBUTTON]~ took care of the anomaly. Thanks for pointing
    this out and for providing the working code. It just goes to show that what appears on the surface
    is not always the case. Here it was coding that resulted in what appeared to be a variance inside
    hardware, clock, from pins on one side of the chip to the other side. Thanks to Mike for making the
    state change information clear. But now... I wonder if there is any useful application for speeding
    up the apparent rate using the previous program as a technique...
Sign In or Register to comment.