Examples: ISR in COG/LUT/HUB
mindrobots
Posts: 6,506
A simple counter based ISR entirely in COG space - all COG EXEC
A simple counter based ISR that has its ISR code in LUT space (interrupt is LUT EXEC, main is COG EXEC).
EDIT: A few posts below, is an updated version of this with changes suggested by Chip to better handle the LUT address references.
A simple counter based ISR that has its code in HUB space (interrupt is HUB EXEC, main is COG EXEC).
I just wanted to get these up as examples if anyone is playing and wants some quickies to try.
I intend to better document these and provide a narrative if anyone thinks they will be useful for the P2 examples library.
con main_led = 0 isr_led = 1 dat orgh 0 org start setb dirb,#main_led setb dirb,#isr_led getct isrticks addct1 isrticks,isr_wait mov ijmp1,#isr setint1 #1 blink notb outb,#main_led 'flip its output state waitx main_wait ' WAITX blocks interrupts jmp #blink 'do it again isr_wait long 25_000_000 main_wait long 5_000_000 isrticks long 1 isr notb outb,#isr_led addct1 isrticks,isr_wait reti1
A simple counter based ISR that has its ISR code in LUT space (interrupt is LUT EXEC, main is COG EXEC).
EDIT: A few posts below, is an updated version of this with changes suggested by Chip to better handle the LUT address references.
con main_led = 0 isr_led = 1 dat orgh 0 org 0 start loc adra,#@isr setq2 #3 rdlong 0,adra setb dirb,#main_led setb dirb,#isr_led getct isrticks addct1 isrticks,isr_wait mov ijmp1,##isr>>2 setint1 #1 blink notb outb,#main_led 'flip its output state waitx main_wait 'wait that many clocks jmp #blink 'do it again isr_wait long 50_000_000 main_wait long 5_000_000 isrticks long orgh $200 isr notb outb,#isr_led addct1 isrticks, isr_wait reti1
A simple counter based ISR that has its code in HUB space (interrupt is HUB EXEC, main is COG EXEC).
con main_led = 0 isr_led = 1 dat orgh 0 org 0 start setb dirb,#main_led setb dirb,#isr_led getct isrticks addct1 isrticks,isr_wait loc adra,#@isr mov ijmp1,adra setint1 #1 blink notb outb,#main_led 'flip its output state waitx main_wait ' WAITX blocks interrupts jmp #blink 'do it again isr_wait long 50_000_000 main_wait long 5_000_000 isrticks long 0 isr_in_hub long 0 orgh $400 isr notb outb,#isr_led addct1 isrticks, isr_wait reti1
I just wanted to get these up as examples if anyone is playing and wants some quickies to try.
I intend to better document these and provide a narrative if anyone thinks they will be useful for the P2 examples library.
Comments
As discussed in another thread, the WAITX I use in my examples BLOCKS interrupts. This code is not a best practices for how to code a mainline but it does give you structure and how to set up a simple ISR and how to get the proper address references (that still causes me trouble).
Enjoy...or not.....
If WAITx is not best practices, it might pay to change to POLL form for the examples ?
I guess if someone really wanted last-ns precision, they could combine polling, with an INT disable and a very short wait. viz poll to within some few cycles, then use fine delay if needed.
In the middle example, change 'ORGH $200' to 'ORG $200'. ORG allows two ranges, $000..$1FF for cog and $200..$3FF for lut.
One other thing... Change 'mov ijmp1,##isr>>2' to 'mov ijmp1,##isr'.
Thanks! I think I tried that and it wasn't working. I'll go back and try again and see where I messed up or what was getting complaints. PNUT didn't like the org at first until I got very explicit with 'org 0,$1ff' and then 'org $200' once i got that squared away, I think my LUT load sequence was having issues. But I'll go bang away at it more and report back.
Thanks! I'm not sure anybody has best practices yet. I mostly wanted to post these for the memory structure and organization. How to structure and reference things still doesn't jump out at me when I start playing with COG, LUT and HUB all tied together. I also wanted to test interrupts going back and forth across execution modes.
I do have a 2 ISR version that has a WAITINT in the main path. It's fun to watch the slightly out of sync blinkies beat against each other and the the main led that has no timing control of its own.
It may be better to have ?
ORGH
ORGC
ORGL
to make it clear where-you-are, and then the tools can check you are not trying to do stuff illegal in that code area.
Chip,
To get your changes to work, the only additional thing I needed to do was insert 'orgf $200' before the 'org $200'. Without the orgf, PNUT doesn't generate the code to fill out to $200. Ctrl-M looks a bit empty. With the orgf, you get zeroes out to byte 800 before the LUT code starts.
This is the final result for the middle program above:
If anyone thinks the 'orgf $200' followed by 'org $200' seems redundant, if you remove the 'org $200', PNUT tells you the 'Cog origin exceeds limit.'
I'm pretty sure you shouldn't need the orgf. I think you're doing something wrong. Check your "loc adra, #@isr". What if you replace it with "mov adra, ##@isr", since you probably want an absolute hub address in this case and loc is generally for resolving relative addresses?
Yup! That works! I can get rid of the orgf. Thanks!!
Accidentally, I tried 'mov adra,#@isr' also worked.....which is just in this case and would soon break as my COG image grows. The address references are still making me scratch my head sometimes.
I got rid of the WAITX in the main code. It has no timer, it just toggles LED0 on and off as it gets notified that an interrupt has occurred.
A warning / error sort of makes sense because you do not want to casually cross the COG-LUT bondary.
( IIRC aren't the SFRs there anyway - you should be warned when you bump into those ?)
It does make a better case for ORGL to explicitly move into LUT area. Using the same ORG for two of three areas is just confusing.