Shop OBEX P1 Docs P2 Docs Learn Events
Response time to pin transition in spin — Parallax Forums

Response time to pin transition in spin

pgbpsupgbpsu Posts: 460
edited 2009-03-07 19:52 in Propeller 1
How long should it take spin to respond to a high/low transition in spin using:

     waitpeq(0, |<4, 0)





I'm using the Prop to check the stability of a GPS based triggering system. The system should trigger every 10 seconds with an accuracy of about 30ns. I'm simply trying to confirm that the trigger occurs every 10 seconds +/- a few microseconds. So I wrote this loop which runs in its own cog:

PUB ELAPSED_TIME | c_time, o_time, diff
   DelayMS(6_000)

   o_time := cnt

   uarts.str(DEBUG,string(13,"Starting elapsed time counter at: "))
   uarts.str(DEBUG,gps.time_string)
   uarts.str(DEBUG,string( "  Counts: "))
   uarts.dec(DEBUG,o_time)

   repeat
     waitpeq(0, |<4, 0)
     c_time := cnt
     if o_time > c_time
       diff := ( $FFFF_FFFF - o_time )  + c_time
     else
       diff := c_time - o_time
     uarts.str(DEBUG,string(13,"Event at: "))
     uarts.str(DEBUG,gps.time_string)
     uarts.str(DEBUG,string("  Elapsed time(us): "))
     o_time := diff/80
     uarts.dec(DEBUG, o_time)
     uarts.str(DEBUG,string("  Error (us): "))
     uarts.dec(DEBUG, (10_000_000 - o_time) )
     o_time := c_time
     DelayMS(1_000)
     




In words:
When P4 goes low
1. grab the system counter
2. subtract that from the system counter at the last event (unsigned sub)
3. convert difference in counts to difference in time (usec) by diving by 80 (I'm using an 80Mhz system clock)
4. subtract this time from how long it should have taken (10_000_000 useconds)
5. print out some info and repeat

I captured the output of this for about 3 hours (about 1000 events) and found only 2 possible error times (usec):
-9393 and -9394

The stability is encouraging. But I don't understand where the delay comes from. It's nearly 10 milliseconds. Is this the time it takes the spin WAITPEQ to react?
Any and all comments appreciated.

Thanks,
pgb

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-02-27 16:47
    pgb,

    Just use diff := c_time - o_time without all the checking. The math still works out, even when the counter rolls over. Also, get rid of that DelayMS(1_000). That's probably what's causing the trouble. Replace it instead with waitpne(0, |<4).

    Finally, what you'll probably end up measuring is the accuracy of your crystal, not that of the GPS, which is likely to be much more accurate.

    -Phil

    Post Edited (Phil Pilgrim (PhiPi)) : 2/27/2009 4:52:28 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2009-02-27 16:54
    The WAITPEQ reacts in tens of nanoseconds. You're doing a lot of time consuming I/O between when you read the system clock and when you read it next. Part of the I/O involves reading the GPS time which could take a (relatively) long time to get. All of this causes the time to slip by, perhaps causing you to miss some events. At 9600 Baud, it takes 1ms per character alone.
  • pgbpsupgbpsu Posts: 460
    edited 2009-02-27 18:15
    Phil and Mike-

    Thanks for your feedback. But I'm not sure I follow. Between one iteration of the loop and the next I *should* have 10 seconds. So all the debug messages and the wait 1 second should happen then during this down time. The reason the wait 1 sec is there is because I was concerned initially about the getting through this loop too quickly. The low time of P4 (the Event trigger) is 5ms. I put the wait 1 sec in so I wouldn't catch the same low on P4 more than once.

    If Mike's right that WAITPEQ (even in spin) responds in nanoseconds, I would expect c_time to be the system counter to within a few 10s of nanoseconds from the falling edge of P4. The next falling edge is nearly 10 seconds away so I can do the math, print stuff out, take a shower, and feed the dog, and still get back around to the WAITPEQ long before P4 goes low again. When I do, I should again catch the falling edge on P4 to within nanoseconds of it happening. I now have the system counter of 2 consecutive events (o_time and c_time; old and current). If I subtract them I have the number of system clocks between events. Convert from counts to time and compare that to the number of microseconds in 10seconds and I *should* be getting nanoseconds if Mike is right, but at the very least I should be getting microseconds. But certainly not 10 milliseconds.

    I'm not trying to be stubborn, but I still don't see the problem.
    Thanks,
    pgb
  • mctriviamctrivia Posts: 3,772
    edited 2009-02-27 18:25
    spin is dreadfully slow 1000 cycles per instruction write it in pasm

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Need to make your prop design easier or secure? Get a PropMod $50CAN has crystal, eeprom, and programing header in a 40 pin dip 0.7" pitch module.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-02-27 18:32
    pgbpsu said...
    The low time of P4 (the Event trigger) is 5ms. I put the wait 1 sec in so I wouldn't catch the same low on P4 more than once.
    That's why I suggested replacing it with the waitpne, which makes sure the pin goes high before resuming the loop. (I missed the 10-second thing, though, and assumed you were monitoring a PPS output.)

    That being the case, your debug outputs should not interfere with the timing at all. There will certainly be a delay between your waitpeq and reading cnt, but it will be exactly the same delay every time through the loop. So the "slowness" of Spin is completely irrelevant in this case.

    My recommendation would be to start another cog which outputs a similar pulse on another pin — one which you know has the correct timing. Then retry your program on that.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-02-27 18:57
    Here is a program, based on yours, that uses another cog to generate an 8 us pulse every second. I get zero for the error each time through.

    [b]CON[/b]
    
       [b]_clkmode[/b]     = [b]xtal1[/b] + [b]pll16x[/b]
       [b]_xinfreq[/b]     = 5_000_000
    
       PIN          = 0
    
    [b]OBJ[/b]
    
      tv : "tv_wtext"
    
    [b]VAR[/b]
    
      [b]long[/b]  stack[noparse][[/noparse]&#173;64&#093;
    
    [b]PUB[/b]  Start
    
      tv.start(12)
      [b]cognew[/b] (blipper, @stack)
      elapsed_time
      
    [b]PUB[/b] elapsed_time | c_time, o_time, diff, ready
    
      ready~
      [b]repeat[/b]
        [b]waitpne[/b](0, constant(|<PIN), 0)
        [b]waitpeq[/b](0, constant(|<PIN), 0)
        c_time := [b]cnt[/b]
        diff := c_time - o_time
        [b]if[/b] (ready)
          tv.[b]str[/b]([b]string[/b]("Error (us): "))
          tv.dec(1_000_000 - diff / 80)
          tv.out(13)
        ready~~
        o_time := c_time
    
    [b]PUB[/b] blipper | time
    
      [b]dira[/b][noparse][[/noparse]&#173;PIN&#093;~~
      [b]outa[/b][noparse][[/noparse]&#173;PIN&#093;~~
      time := [b]cnt[/b]
      [b]repeat[/b]
        [b]waitcnt[/b](time += 80_000_000)
        [b]outa[/b][noparse][[/noparse]&#173;PIN&#093;~
        [b]outa[/b][noparse][[/noparse]&#173;PIN&#093;~~   
    
    
    



    -Phil
  • pgbpsupgbpsu Posts: 460
    edited 2009-02-27 20:32
    @mctrivia-

    I agree that spin is much slower. But I'm convinced that for what I want to do, spin should be plenty fast. I'm looking for accuracy, not speed. Besides, 10 seconds between pulses of interest is much to long for me to see any detail on my scope, so I'm stuck with a debug window of some kind.

    @Phil-

    Thanks for the code. I've run it on the very system that was giving me trouble and it gives me the same result you get. That includes when I switch the waitcnt in blipper from 1 sec to 10. So I think the hardware is doing what it should.

    This hardware in fact does have a GPS 1PPS ( my first attempt was to look at something derived from the 1PPS) which I can look at. When I run your program without blipper and instead use my gps 1PPS as input for elapsed time I get:
    Error (us): -938
    Error (us): -939

    I just assumed I had a software error, but now I'm not convinced. The main difference here that I see is these two have different clocks. If one assumes that the 1PPS is really good to its spec, this error I'm seeing must be in the 5Mhz crystal (an error of 12ppm: 938/16 to take out the PLL 58parts/5Mhz = 12ppm). I guess this is what you said in your first post. So maybe things are working just fine after all. At least I now have an explaination for what I was seeing. hop.gif

    Back to my original error of ~9394us/10 seconds that works out to 939us error/1 second which fits very nicely with this measurement.

    Would you believe that kind of error in the 5Mhz crystal?

    Many thanks,
    pgb
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-02-27 21:16
    pgb said...
    Would you believe that kind of error in the 5Mhz crystal?
    939 ppm would be an enormous error for a crystal. Are you using a Parallax dev board with a supplied crystal, or something homebrew? Can you get NTSC color video output from your setup? That's something that's very sensitive to crystal frequency errors.

    -Phil
  • pgbpsupgbpsu Posts: 460
    edited 2009-02-27 21:52
    Phil-

    I'm afraid NTSC output is not possible. This is a homebrew printed circuit board with a 5Mhz crystal. I'm not the brewer, just the programmer. It does handle serial comms without any trouble so it can't be too bad. How did you come up with 939ppm?

    To get the error of 939us I took the difference in counts and divided by 80. So 939us is ~75,000 counts. 75,000/80Mhz ~= 939.

    I see how you got 939ppm. Alright then, I'm back to not understanding the problem!

    pgb
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-02-27 22:29
    Okay, see if you can get the specs for the crystal to check its tolerance. Also, make sure that XTI and XTO have good connections to the crystal leads. I've seen cases where a crystal will oscillate without a solid connection, but at the wrong frequency. How close is the crystal to the Propeller? I wonder if there may be extra trace capacitance causing trouble. It doesn't have any load caps attached to it, does it? Can you post a good close-up photo of the board? And a schematic, perhaps?

    -Phil
  • pgbpsupgbpsu Posts: 460
    edited 2009-02-27 22:35
    Phil-
    I appreciate your willingness to help. I'll get the best close-up shot I can and I'll ask the engineer to look at the schematic and release a copy if possible. Unfortunately this will have to wait till Monday before I can look into it further.

    Does the fact that serial comms are good mean anything useful? Sure seems to me to be running fine otherwise. I'm not convinced this is simply an crystal problem. First thing Monday I'll try running some square wave tests with the high time set to something well know (and fast). If the crystal is that far off, my predictions for counts to wait should be off as well.


    Stay tuned....

    Post Edited (pgbpsu) : 2/27/2009 10:46:41 PM GMT
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-02-27 23:49
    pgbpsu said...
    Does the fact that serial comms are good mean anything useful?
    Not really. Asynchronous serial comms are pretty forgiving, since they resynchronize on each character. So a 900 ppm timing error is really insignificant (i.e. less than 1/100th of a bit error between the start bit and stop bit).

    -Phil

    Post Edited (Phil Pilgrim (PhiPi)) : 2/27/2009 11:55:28 PM GMT
  • pgbpsupgbpsu Posts: 460
    edited 2009-02-28 01:54
    Phil-

    Something came to me on my bike ride home from work. Unfortunately, it does nothing to explain the behavior, but maybe it will help me track it. This system has a 1PPS input so if I write a an assembly routine which waits for that 1pps pulse, then enters a loop where it grabs the time and adds 80_000_000 counts, raises a line for a short time, then lowers it, jumps back up waiting for the counter to reach the 1 second mark, and keeps looping over this.

    What I'm trying to do is sync up to the 1PPS, and then generate a pseudo-1PPS based on the prop's clock. That should very quickly show if my crystal is off and by how much.

    I'll see what that gives and hopefully post a photo and schematic on Monday.

    Thanks again for all your input.

    p
  • pgbpsupgbpsu Posts: 460
    edited 2009-03-02 17:50
    I've checked the crystal visually and it's 5Mhz; looks just like the one on the Parallax website. Which means it should have an accuracy of +/- 30 ppm at room temp (which is where we are operating).

    I ran a spin program which simply counts the system clocks between GPS 1PPS. If what I wrote is correct, 1 GPS second has 80075360 system counts in it. Which means my crystal is off by 75360 counts in 80_000_000 or 1 in ~1000. I've been watching this program for ~ hour and the number of system counts/GPS second is very stable. It's just not very accurate.

    I've talked with the engineer who laid out the board. He says the layout follows standard good practices. I've included a portion of the schematic at Phil's request.

    Scoping XO shows a 5Mhz sawtooth wave with 1.4V pk-pk but DC shifted by +2.2V. The XI line has a 5Mhz 600mV pk-pk sine wave with the same DC shift.

    Comparing that to the Prop Demo board. The XO and XI lines there look exactly the same as each other; nice clean sine waves with 2.2Vpk-pk and a 2.2V DC shift.

    I'm not sure where the 2.2V DC shift comes from, but it looks like it belongs there. The sawtooth, however doesn't look correct. So it looks like there's something wrong with our circuit?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-03-02 20:13
    Which crystal drive level have you specified in your program?

    -Phil
  • pgbpsupgbpsu Posts: 460
    edited 2009-03-02 21:04
    Phil-

    My program has the following clock decleration:
    _clkmode = xtal1 + pll16x ' use crystal x 16
    _xinfreq = 5_000_000 ' 5 MHz cyrstal (sys clock = 80 MHz)
  • pgbpsupgbpsu Posts: 460
    edited 2009-03-05 20:51
    For those following this thread, especially Phil, I wanted to post the resolution to this problem. Turns out to be a bad crystal. When we finally found a decent frequency counter, the crystal which should have been 5Mhz was actually about ~.1% fast. I don't know if that a problem with the crystal, or if it's running on a spur. In fact, for this application it doesn't really matter and I never would have noticed it if I hadn't counted the number of prop clocks between GPS 1PPS. But I did and that send me down this road.

    Anyway, thanks to all for making suggestions and helping find the cause of my strange results. In light of this incorrect crystal, the system runs fine. I'll probably replace this crystal, but at least I now know what's going on.

    Regards,
    Peter
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-03-07 07:22
    Peter,

    It's very unusual for a crystal to be off by this much. I suspect that the wrong kind of crystal was specified for the board, rather than the crystal itself being defective. The Propeller specs call for a parallel-resonant crystal with about a 20pF load capacitance (for 5MHz). If you were to substitute a series-resonant crystal or one with the wrong load capacitance, you might well see a frequency discrepancy

    -Phil
  • pgbpsupgbpsu Posts: 460
    edited 2009-03-07 19:52
    Phil-

    Thanks for pointing that out. I'll let the engineer who designs and builds our boards know. I did look at the crystal to verify that it was 5Mhz, but I didn't realize that a series-resonant crystal or incorrect load capacitance might cause this large of an error.

    Thanks again for all you help.
    Peter
Sign In or Register to comment.