Shop OBEX P1 Docs P2 Docs Learn Events
Another Question: strange behavior of timer — Parallax Forums

Another Question: strange behavior of timer

ErNaErNa Posts: 1,752
edited 2014-11-13 07:20 in Propeller 1
I'm developing a control software which runs a timer:
    if (ttimer -  cnt) < 0
      ttimer += ClkFreq
      testoffset := ( testoffset // 9000 ) + 1000
This code runs on one propeller in parallel to other processes, like full duplex serial, stepper driver etc.
A second propeller does the UI with screen and buttons.
There is a communication in between in a very early stage of development, so there might be bugs like overflow, write unintended to memory etc.

Every second this timer changes the offset value and this value is transfered to the UI.
Normally that works fine, but it may happen, that the timer runs much faster than one second (about ten times :-( ) and then stops for about 27 seconds like this is the case with a counter overflow.
Is there a way to unintended write to the counter? Or could it be that the value of ClkFreq is corrupted?
Up to now I did not find a way to stimulate the behavior, so I am in a very early stage of debugging, anyway the software needs a revision, as the communicator has to be merged with the serial IO to save a cog.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2014-11-12 14:23
    The problem is that CNT is a 32-bit unsigned number and Spin does its arithmetic with 32-bit signed numbers. When you compute ttimer-cnt, you may get a positive or negative number depending on the difference between ttimer and cnt. You have to compute these time differences so that the difference is always a 31-bit (positive) unsigned value. That would be a time difference on the order of 25 minutes or less at 80MHz.
  • ErNaErNa Posts: 1,752
    edited 2014-11-12 17:55
    This way normally works very well. And so it does in case, the system starts correctly. The problem may come from this: I start two propellers, a master and a slave and master waits until slave is ready time controlled. Then they synchronize. If the master is running and the slave is reprogrammed, the slave gets arbitrary information and there is a chance to overwrite memory. This seems to happen, but I wonder how it could happen, that the timer now ticks about 10 times a second. And then it overruns the 31 bits, not under normal conditions.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-11-12 20:01
    I have a program that needed a lot of asynchronous timers and I had no cogs left for that feature. I developed the attached object that takes care of things nicely. The only caveat is that each timer must be processed before the 32-bit rollover -- about 54 seconds at 80MHz. That's not a problem for may app as the main loop is running every 25ms.

    If you want something to happen every 100ms you might do this:
    ms := timer.millis                    ' get milliseconds
      if (ms => 100)                        ' if at or past time
        timer.adjust(ms-100)                ' roll back for next time
        ' do process                        ' run process
    
  • ErNaErNa Posts: 1,752
    edited 2014-11-13 00:28
    OK, I think, this is similar to what I implemented. As mentioned: under normal conditions the timer loop runs stable, creating a 1 second tick. I wondering, what can change the timer frequency and the first idea was (or the last) that the counter runs faster or I changed the PLL value, or something else. But now I realized, that communication still works, so other processes are in synch. I can imagine, that the timer increment value was overwritten incidently and that changes loop frequency.
    Anyway, I know that my communication routine can be asynchronous and so get a wrong destination address, so I write data to an arbitrary place. That has to be fixed.
    Thanks for contributions!
  • AribaAriba Posts: 2,690
    edited 2014-11-13 05:22
    ErNa

    The ClkFreq value is stored at HubRAM location 0..3. If some code overwrites this locations you get a wrong value when you use ClkFreq.
    Because all variables are initialized with 0, the chance to overwrite at this address is high, if a wrong pointer variable is used or you forget a @ to specify the address, or something like that.

    Andy
  • ErNaErNa Posts: 1,752
    edited 2014-11-13 07:20
    Yes, that looks very plausible! When storing information I do not check for valid addresses (and 0 is never a valid) so this place will be overwritten very likely. My sync char is 0 and when by accident a 0 in a long is detected as sync (what could happen) then the following 0's are taken for addresses. Or something else.
Sign In or Register to comment.