Shop OBEX P1 Docs P2 Docs Learn Events
Interrupts are delayed until after wait* instructions complete? — Parallax Forums

Interrupts are delayed until after wait* instructions complete?

I'm trying to wrap my head around this constraint. I'd like to write a program that does something in a software loop on a periodic basis (blinking an LED is fine for my example) and also transmits data out a serial port. I'd like to use a smart pin to do that transmission, and I'd like to buffer the data into an array that is emptied via WYPIN in an interrupt to produce a constant stream of serial data.

But I normally write software loops for outputting to LEDs like so:
while (1) {
    drive_invert(58); // Executes a drvnot instruction
    waitx(CLOCK_FREQ / 20);
}

Well that's no good, is it? Now I'm going to have a big gap between each byte of my serial transmission because I have to wait for the waitx instruction to complete before the next byte can be loaded. Is there a special instruction that I'm missing which allows me to do this better? My best idea right now is to write a new function "interruptable_wait()" that does multiple waitx instructions in a loop, allowing interrupts to happen in the middle, or maybe even just does a "while(CT != value);" but that just makes me cry tears of inefficiency.

Comments

  • potatoheadpotatohead Posts: 10,261
    edited 2019-01-13 02:50
    There are polling versions of all the wait instructions.

    Instructions are basically atomic. Interrupts happen once one is complete.

    Maybe you can get some work done in a loop?
  • There are 3 timers per cog CT1,CT2 and CT3.
    Use one of them instead of WAITX with POLLCTx.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2019-01-13 04:36
    That's what I'm trying now... I was hoping for something better (I liked the idea of the core going to "sleep" with the wait* instructions) but I guess we already know that doesn't actually make much difference in this piece of silicon.

    So... I'm starting to feel really dumb. Almost every single thing I've tried to do with this chip has not worked the first time around. I can't even get a simple program working that use pollct1 or jnct1.

    The instruction sheet says
    addct1: Set CT1 event to trigger on CT = D + S. Adds S into D.

    So if I pre-load a register with "getct timer", I should be able to do "addct1 timer, period" to set up the event, right?
    dat	org
        hubset  #0
    
        getct timer
    blink:
        drvnot  #58
    
        addct1 timer, period
    foo:
        jnct1 #foo:
    
        jmp #blink:
    
    timer       long
    period      long    1_000_000
    

    But, this isn't working.
  • evanhevanh Posts: 15,915
    Lol, I stared at that and couldn't see the problem. I pasted it and ran it and still couldn't see the problem. I changed it, filled it out with lots of extra things. I even removed the jnct1 and replaced it with a plain waitx, but still couldn't see the problem.

    I finally commented out the addct1 and wham it started working. It was what the hell? Only then did I look at the timer variable that addct1 operates on. It should be long 0. :)

  • evanhevanh Posts: 15,915
    The assembler, fastspin, gives me no error.
  • Timer and period are being compiled as the same address because no value is being initialized in timer.
    Try this instead
    timer       long    0
    period      long    1_000_000
    
  • evanh wrote: »
    Lol, I stared at that and couldn't see the problem. I pasted it and ran it and still couldn't see the problem. I changed it, filled it out with lots of extra things. I even removed the jnct1 and replaced it with a plain waitx, but still couldn't see the problem.

    I finally commented out the addct1 and wham it started working. It was what the hell? Only then did I look at the timer variable that addct1 operates on. It should be long 0. :)

    I had that at one point... I removed it when I started using "getct timer" because I thought getct would override whatever value was in timer prior to the instruction and that the "0" after "timer long" was just an optional initial value. Is it not?
  • evanhevanh Posts: 15,915
    As Oz says, the assembler will be making a symbol to the same address as period. The addct1 instruction modifies the period then!
  • Thank you all!
    evanh wrote: »
    As Oz says, the assembler will be making a symbol to the same address as period. The addct1 instruction modifies the period then!

    That is definitely the behavior I was seeing. And, sorry about asking the second dumb question :P when I typed up that reply, all I could see was evan's first response. Browser oddity? Blind user? Who knows...
  • evanhevanh Posts: 15,915
    There'll be some reason why Chip chose to do the summing against a general register instead of the internal hidden timer register.
Sign In or Register to comment.