Imitating an Interrupt driven system
To all the Gurus out there.
My application requires doing some things at specific intervals. I understand waitcnt but it doesn't address what I really want.
Lets say I have a main loop in which I want to run 1 routine 100 times each second or at 10ms intervals,
and a second routine that runs 50 times a second or 20ms intervals,
and a third routine that runs at 5/sec or 200ms,
and finally 1 routine that runs once per second.
Can this be done when you have no timer interrupt?
That is assumming each process is done well within its allotted timeslot.
Or does this require each function to be in its own cog?
·
My application requires doing some things at specific intervals. I understand waitcnt but it doesn't address what I really want.
Lets say I have a main loop in which I want to run 1 routine 100 times each second or at 10ms intervals,
and a second routine that runs 50 times a second or 20ms intervals,
and a third routine that runs at 5/sec or 200ms,
and finally 1 routine that runs once per second.
Can this be done when you have no timer interrupt?
That is assumming each process is done well within its allotted timeslot.
Or does this require each function to be in its own cog?
·

Comments
you could have a main_loop checking to see if cnt has gone over a value for each routine, then call it's function if it has.
initmain mov prevcnt1,cnt mov prevcnt2,prevcnt1 mov prevcnt3,prevcnt1 mov prevcnt4,prevcnt1 mainloop mov tmp,cnt ' get current cnt sub tmp,prevcnt1 ' subtract prevcnt1, ie when routine 1 last had a value cmp tmp,addcnt1 wz,wc if_ae add prevcnt1,addcnt1 if_ae call #routine1 mov tmp,cnt ' get current cnt sub tmp,prevcnt2 ' subtract prevcnt1, ie when routine 2 last had a value cmp tmp,addcnt2 wz,wc if_ae add prevcnt2,addcnt2 if_ae call #routine2 mov tmp,cnt ' get current cnt sub tmp,prevcnt3 ' subtract prevcnt1, ie when routine 3 last had a value cmp tmp,addcnt3 wz,wc if_ae add prevcnt3,addcnt3 if_ae call #routine3 mov tmp,cnt ' get current cnt sub tmp,prevcnt4 ' subtract prevcnt1, ie when routine 4 last had a value cmp tmp,addcnt4 wz,wc if_ae add prevcnt4,addcnt4 if_ae call #routine4 jmp #mainloop routine1 nop ' put code for routine 1 here routine1_ret ret routine2 nop ' put code for routine 2 here routine2_ret ret routine3 nop ' put code for routine 3 here routine3_ret ret routine4 nop ' put code for routine 4 here routine4_ret ret tmp long 0 prev1cnt long 0 prev2cnt long 0 prev3cnt long 0 prev4cnt long 0 'assuming 80 Mhz tick speed add1cnt long 80_000_000 / 100 add2cnt long 80_000_000 / 50 add3cnt long 80_000_000 / 5 add4cnt long 80_000_000Hope this helps [noparse];)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://www.propgfx.co.uk/forum/·home of the PropGFX Lite
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
JMH - Electronics: Engineer - Programming: Professional
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://www.propgfx.co.uk/forum/·home of the PropGFX Lite
·
It looks like it may work except no routine can run over 20s. My 200ms routine actually takes ~80ms so it will have to go into its own cog. I haven't finished or timed the others yet.
Donald
How do you mean no routine can run over 20s?
On a side note, if they do overrun into another routine's time, it the other routine will be delayed until the one executing is finished, then it will execute, slightly late, but should re-steady itself, should it not over run again.
but yes, if it's timing critical, that no routine stops another, any that will overflow into another's execution timescale, then by all means put it into a seperate cog [noparse]:)[/noparse]
also on another note, on the init part, you might want to add an offset for each routine's start.
if all your routines times add up to more than 10 ms then you'll want to move one or some of the bigger ones to another cog, as if they should start on same tick, they'll be delayed.
so add something like this.
initmain mov prevcnt1,cnt mov prevcnt2,prevcnt1 mov prevcnt3,prevcnt1 mov prevcnt4,prevcnt1 add prevcnt1,add1off add prevcnt2,add2off add prevcnt3,add3off add prevcnt4,add4off mainloop ... rest of stuff from before add1off long 80_000_000 / 1000 add2off long 80_000_000 / 2000 add3off long 80_000_000 / 3000 add4off long 80_000_000 / 4000▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://www.propgfx.co.uk/forum/·home of the PropGFX Lite
·
Jim Woods, who wrote the IMU objects says it needs 4 cogs including the 2 floating point objects, so if I put that on the same MCU as the GPS/FPU, then both should use 3 cogs. Since most of the data to be transferred to the SD card will be located here, it stands to reason that the SD object should be there also. That makes 5 plus the RC Input makes 6. The serial to prop#2 makes 7 and the main loop makes 8. Everything else can go into prop #2. Whew! If I can do that, it will beat the heck out of 60Mhz ARM. The main loop cog will also use its counters to measure RPM for 2 motors but that takes very little cpu time. The IMU MCP3208 interface will possibly have 2 8 input A/D so I can measure other analog inputs as well for battery voltage/current, air speed, etc.
I think its going to take me some time but I certainly think I can use your algorithms.
Donald
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://www.propgfx.co.uk/forum/·home of the PropGFX Lite
·
you could have something like this
etc..
then to access it in your cog asm program
hope this helps.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://www.propgfx.co.uk/forum/·home of the PropGFX Lite
·
Not quite true. My favorite way to pass pointers into ASM is to have "psychic code" I.e. all the pointers are written into variables in my code BEFORE I start the code in a new cog.
Pub Start(some_pointer) 'start is passed a pointer to a variable in Hub-ram Hub_ptr_1 = some_pointer 'modify my ASM code to contain the pointer value cognew(@entry,0) org 0 entry 'asm code here . . RDlong temp, Hub_ptr_1 . . Hub_ptr_1 Long 0-0 'the "0-0" tells me my code will change this value at run-time. temp res 1 fit 496Best of luck,
Marty
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Lunch cures all problems! have you had lunch?
your way is good for savng room.
but my way was a simple way for having a joined buffer for sharing info between all the cogs that need access to it, plus less chance of missing setting up a pointer [noparse];)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://www.propgfx.co.uk/forum/·home of the PropGFX Lite
·
You can review the object here: http://obex.parallax.com/objects/389/
I have commented it pretty heavily. In time I will post a template and app note for this time of structure so that others can take advantage of it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, uOLED-IOC, eProto for SunSPOT, BitScope
www.tdswieter.com