Shop OBEX P1 Docs P2 Docs Learn Events
Pitfalls and crawling out... GetSec() behaves not as I expected, to slow and counting down — Parallax Forums

Pitfalls and crawling out... GetSec() behaves not as I expected, to slow and counting down

ErNaErNa Posts: 1,794
edited 2025-03-11 11:32 in PASM2/Spin2 (P2)

I use this setting for timing:

con { timing }

  CLK_FREQ = 200_000_000                                        ' system freq as a constant
  MS_001   = CLK_FREQ / 1_000                                   ' ticks in 1ms
  US_001   = CLK_FREQ / 1_000_000                               ' ticks in 1us

  _xtlfreq = 20_000_000 '25_000_000
  _clkfreq = CLK_FREQ                                           ' set system clock

repeat
    term.PutValhex ( 5, 15, "i", ":", GetCt() )
    term.PutValhex ( 5, 16, "T", ":", Getsec() )
    term.PutValhex ( 5, 17, "S", ":", GetmS() )


But GetSec() needs about 10 seconds to count. Do I have to configure something else?
The baud rate works perfect with the setting, I'm using a P2 Eval board
p.s. GetSec counts backward

Some more analysis: GetCt() works as expected, Getsec() counts when GetCt() wraps round. Getms() counts fast, but not milliseconds and GetSec and Getms start at $FFFF_FFFF and count down

Strange things happen: If I use Getsec() is a demo program, it works fine. But no longer in the application., running in a different COG. GetSec() actually counts backward at the overflow of GetCt().
I'll run more tests when time comes..

Comments

  • JonnyMacJonnyMac Posts: 9,236
    edited 2025-03-02 21:30

    It's very possible that you're creating a buffer overrun in the terminal you're using. There is no breathing room between loops in your code to let the terminal clear its buffer. If it takes more time to process/display your input than it does for the terminal to receive it, you'll eventually step on yourself.

    I ran a simple test and getsec() works as expected (incrementing count). I used PST (which has that overrun problem if you don't give it breathing room).

  • JonnyMacJonnyMac Posts: 9,236

    This seems to work, too:

  • ErNaErNa Posts: 1,794

    Thanks for help, it was just to take advantage of this new feature. The application is quite complex and doesn't work completely, I finally did it the old-fashioned way and now the display show the right ticks of seconds. The moment the screen updates all the variables (just now, it is reluctant), I'll give GetSec() another try.

  • ErNaErNa Posts: 1,794
    edited 2025-03-02 22:33

    Where to find the subtle difference between
    _clkfreq, clkfreq and clkfreq_?

  • evanhevanh Posts: 16,300
    edited 2025-03-02 23:09

    Last section, called Clock Setup, of Spin 2 Language Documentation - https://docs.google.com/document/d/16qVkmA6Co5fUNKJHF6pBfGfDupuRwDtf-wyieh_fbqw

    • _clkfreq and _clkmode are the user constants of desired startup sysclock frequency/mode to be compiled. Should never be used in methods. Only define in the CON section.
    • clkfreq_ and clkmode_ are the compiled constants of startup sysclock frequency/mode. Use these in your methods.
    • clkfreq and clkmode are system variables that contain dynamic runtime settings. These are adjusted by clkset(). If such is used then all timing methods should also use these variables in place of the above compiled constants.

    I used both in pllset() method. It adjusts the runtime variables as well as extracting board specific compile-time parameters from the constants - https://obex.parallax.com/obex/pllset/

  • ErNaErNa Posts: 1,794

    OK. I now have a first statement in the Main: clkset (clkmode_, clkfreq_) and the program show sound behavior, no symptoms of overrun. Another step. Thanks.

  • ErNaErNa Posts: 1,794

    I'm falling into another pit: as mentioned, I initated clkfreq : clkset (clkmode_, clkfreq_) A timer is running on a cog started. This timer created problems before, because I migrated software from the P1, that used clkfreq, the compiler was fine with that.
    Now I'm working to implement Cluso's LCD driver, overcome some hurdles, but so far, it's ok. What happens: In the main I create a tick reading clkfreq
    if (tick - GetCt()) < 0 Lcd_.HandsRoundclock() tick += clkfreq ' +1S
    This works as long as I do not activate the other cog creating a tick. I checked, I never write to clkfreq and I only once use clkset.
    If I change clkfreq to clkfreq_, it works fine.
    The behavior is, that clkfreq looks to be a constant, because ticks run for about the same time as they stall. I'll try to find the reason, but any idea is welcome.

  • If you only want to set speed once, do not use CLKSET, just set

    CON
    _CLKFREQ = 300_000_000 ' Or whatever you need it to be
    

    Computing the right clkmode value at runtime is tricky

  • ErNaErNa Posts: 1,794

    If I understood correctly, clkfreq and clkfreq are constants. clkfreq is a register. From Spin-documentation:
    CLKSET(NewCLKMODE, NewCLKFREQ) Safely establish new clock settings and update CLKMODE and CLKFREQ.
    As ClkFreq is located in Hub-Ram, I suspect, I accidently overwrite this location, have to investigate...

  • evanhevanh Posts: 16,300

    @ErNa said:
    clkfreq is a register.

    HubRAM variable only.

    As ClkFreq is located in Hub-Ram, I suspect, I accidently overwrite this location, have to investigate...

    That would be bad,

  • JonnyMacJonnyMac Posts: 9,236
    edited 2025-03-10 17:18

    I'm really simple. I set the program running speed from the constants section in my topmost cog.

    con { timing }
    
      CLK_FREQ = 200_000_000                                        ' system freq as a constant
      MS_001   = CLK_FREQ / 1_000                                   ' ticks in 1ms
      US_001   = CLK_FREQ / 1_000_000                               ' ticks in 1us
    
      _clkfreq = CLK_FREQ                                           ' set system clock 
    

    Since child objects don't have access to my CLK_FREQ constant, they use the system variable clkfreq to determine running speed when needed.

  • evanhevanh Posts: 16,300

    @JonnyMac said:
    Since child objects don't have access to my CLK_FREQ constant, they use the system variable clkfreq to determine running speed when needed.

    Wise move for library type code. It can then handle the user program making runtime frequency changes too.

  • ErNaErNa Posts: 1,794

    OK, it looks as if the hub ram is corrupted. I output the value, correct 200.000.000, the moment, the other program starts, it nullified. So there is a bug in another place and I have to find it. So using this register is a bug-indicator ;-)

  • ErNaErNa Posts: 1,794

    clkfreq is located $44 in hub memory. So it is unlikely I overwrite this location and the SPIN-interpreter is not corrupted? I tested $40 and $48, they are unchanged ;-(

  • ErNaErNa Posts: 1,794

    I'm coming close:

                 long[LONG[@Val011[MirrOffs]]] := ((long[LONG[@Val014[MirrOffs]]]*AnzaPoPa)<<12 / WklMeDiv)//3600  
                 long[LONG[@Val009[MirrOffs]]] :=   long[LONG[@Val014[MirrOffs]]]          <<12 / WklMeDiv
                 long[LONG[@Val007[MirrOffs]]] := (((long[LONG[@Val079[MirrOffs]]]*((ClkFreq~>8))) / long[LONG[@Val080[MirrOffs]]]~>8)*60) / IncrRevo
    

    I can see, that clkfreq ($44) is set to zero, if and only if, the last of the lines above is executed. If the line is commented out, the timer runs correctly! Maybe there is a bug only when this program is running on a P2. We'll see.

  • evanhevanh Posts: 16,300
    edited 2025-03-10 23:14

    Yep, the ~ operator changed from Spin1 to Spin2. It now erases the variable!
    From docs:

    var~ Return var, post-clear all bits in var

    EDIT: Oh, err, wow, never even knew about ~> operator. The equivalent Spin2 is: (ClkFreq SAR 8)

    PS: I wouldn't used that operator though. The frequency variable is unsigned in nature. Just use >> right-shift operator instead.

  • ErNaErNa Posts: 1,794
    edited 2025-03-11 07:55

    That's unexpected:
    Separation of ClkFreq fixes the problem!

                 fxck := ClkFreq
                 long[LONG[@Val007[MirrOffs]]] := (((long[LONG[@Val079[MirrOffs]]] * (( fxck~>8))) / long[LONG[@Val080[MirrOffs]]]~>8)*60) / IncrRevo
    

    Even if I shift ClkFreq~>2, the variable is set to $0

  • ErNaErNa Posts: 1,794

    @evanh said:
    Yep, the ~ operator changed from Spin1 to Spin2. It now erases the variable!
    From docs:

    var~ Return var, post-clear all bits in var

    PS: I wouldn't used that operator though. The frequency variable is unsigned in nature. Just use >> right-shift operator instead.

    Thanks, luckily you didn't know about this operator.
    I had changed ~> to SAR in other source files, but it slipped through here. You see other places, and I wouldn't have the starting point if not clkFreq was nulled. ;-) Lucky me.

Sign In or Register to comment.