Shop OBEX P1 Docs P2 Docs Learn Events
CORDIC and interrupts — Parallax Forums

CORDIC and interrupts

I use interrupts to handle smart pins by using the rising edge on IN event to trigger the interrupt service. But I still like to use the CORDIC solver in my main code.

Is it safe if I limit the use of the CORDIC to one instruction at a time so that the pipeline doesn't stall if interrupts get invoked while the CORDIC solver is working? I guess that interrupts are delayed while GETQX/Y are waiting for a result. But that should do no harm because it's less than 56 cycles and I currently have 256 cycles before I loose samples.

Comments

  • evanhevanh Posts: 15,187
    ManAtWork wrote: »
    Is it safe if I limit the use of the CORDIC to one instruction at a time so that the pipeline doesn't stall if interrupts get invoked while the CORDIC solver is working?
    Yep, providing the ISR doesn't also use the cordic.

    I guess that interrupts are delayed while GETQX/Y are waiting for a result. But that should do no harm because it's less than 56 cycles and I currently have 256 cycles before I loose samples.
    Yeah, it has to be so. Reinstating the GETQX/GETQY after an interrupt would be messy. The docs don't explicitly list GETQX or GETQY but do have the rather generic "The cog must not be stalled in any WAITx instruction".

  • evanhevanh Posts: 15,187
    If you do create a buggy situation around the use of cordic ops, it certainly can get confusing. I've tripped up a few times with being eager to optimise then subsequently changing the loop structure so that the cordic sequencing becomes out of sync.

  • OK, I have tested it and it seems to work.

    BTW, I have to say that the P2 is absolutely ingenius and superior over any other microprocessor I have seen so far when it comes to interrupts. I trigger an interrupt every 256 clock cycles. The ISR takes ~120 cycles to complete so the system is almost half occupied but still runs well.

    This would never by possible with an ARM procesor. There, it takes ~100 cycles to call an interrupt and another 100 cycles to return from it. Even with 300MHz there is no way servering so many interrupt requests and still doing something useful.
  • Looks like I'll be checking the Hercules line of safety micros from TI this evening followed by the latest H7 offerings from ST that go as high as 550MHz.

    Whatever the result might be, the P2 is an extremely powerful and flexible micro controller, no doubts about it.
  • Annoyingly, it does seem like getqx will stall interrupts. What we really want is to run the interrupt while we are waiting for the cordic.

    There is an easy fix. Just use a simple delay loop while the cordic is running. If you want to maximize performance, have the ISR cancel the delay when it runs.

    I flipped a pin every time I completed a cordic operation to benchmark.
    ' 15.137khz with fixed djnz
    ' 20.000khz smart djnz
    ' 24.618khz waitx *isr jitter
    ' 24.718khz none *isr jitter

            qdiv    my,mx
            mov cordic_delay_count,#30
    .wait1  djnz    cordic_delay_count,#.wait1
            getqx   mx          
    
    
    isr     ...
            mov cordic_delay_count,#1
    

    The 30 could be reduced a little, but I don't want to risk stalling my interrupt. The smart djnz causes the cordic operations to sync with the interrupt, reducing the count to 28 didn't improve anything.

  • evanhevanh Posts: 15,187
    edited 2021-06-24 09:48

    Branching instructions are four ticks. Meaning, #14 will be heaps.

    EDIT: Oh, neat trick with the ISR changing the value. Compensates for the ISR execution time. I didn't notice that at first.

  • Thanks, @evanh

    With #14, I measured 26.670khz on my toggle pin. So, letting the cordic work while the ISR is running increases overall throughput.

  • evanhevanh Posts: 15,187

    Cool. That's compared to 20 KHz before, right?

  • ManAtWork wrote: »
    This would never by possible with an ARM procesor. There, it takes ~100 cycles to call an interrupt and another 100 cycles to return from it.
    What is this referring to? ARM claims that the Cortex M-7 has a 12-14 cycle interrupt latency. M-3 and M-4 are 12 cycles exactly.
  • That was an ATSAME70N21, a Cortex M7. We tried really hard to get a fast interrupt response, programming on the bare metal and placing the IRQ code into fast SRAM. Running at 300MHz we were not able to get under ~600ns total IRQ processing time even if the IRQ routine was only a single assembler instruction toggeling a pin.

    Main code was executed in flash memory. Maybe the long response time was caused by a required cache re-fill or flash pre-fetch queue or something. It probably gets better if you switch off the cache and run the main code also from fast SRAM. But that conditions are not realistic. You can never know where the main program counter is when the interrupt happens.

  • @evanh said:
    Cool. That's compared to 20 KHz before, right?

    Correct.

    @ManAtWork said:
    That was an ATSAME70N21, a Cortex M7. We tried really hard to get a fast interrupt response, programming on the bare metal and placing the IRQ code into fast SRAM. Running at 300MHz we were not able to get under ~600ns total IRQ processing time even if the IRQ routine was only a single assembler instruction toggeling a pin.

    Main code was executed in flash memory. Maybe the long response time was caused by a required cache re-fill or flash pre-fetch queue or something. It probably gets better if you switch off the cache and run the main code also from fast SRAM. But that conditions are not realistic. You can never know where the main program counter is when the interrupt happens.

    Wow! Makes you really appreciate the SX which did great running out of flash.

Sign In or Register to comment.