Need testers for SoftPWMServo library

rasmadrak
Posts: 218
Joined: Mon Aug 15, 2011 9:21 pm
Location: Sweden
Contact:

Re: Need testers for SoftPWMServo library

Post by rasmadrak » Sun Sep 06, 2015 5:43 pm

I see, servos are a little more complicated than I believed they were.
However, since my line-by-line rendering updates at ~15360Hz I believe it should be possible to maintain a steady wave manually for servos inside that function as well. Theoritically it only adds a few lines of code to the rendering (only using two servos) so it should be feasible, and wouldn't interfere with the rendering itself either. :)

Thanks!

EmbeddedMan
Posts: 597
Joined: Tue May 24, 2011 9:24 pm
Location: Minneapolis, MN
Contact:

Re: Need testers for SoftPWMServo library

Post by EmbeddedMan » Tue Sep 08, 2015 2:18 am

Majenko is correct - the way the library is written, it's not possible to tell it when you want the pulses sent on a case-by-case basis.

However, if you want, you can call SoftPWMServoUnload() any time you want all interrupt activity (due to the library) to stop, and then re-start the library after you are done with your vision processing code. Another thing you could do is to make your vision processing interrupt based, and set it to a higher priority than the core timer.

*Brian

rasmadrak
Posts: 218
Joined: Mon Aug 15, 2011 9:21 pm
Location: Sweden
Contact:

Re: Need testers for SoftPWMServo library

Post by rasmadrak » Wed Sep 09, 2015 8:32 am

EmbeddedMan wrote: However, if you want, you can call SoftPWMServoUnload() any time you want all interrupt activity (due to the library) to stop, and then re-start the library after you are done with your vision processing code. Another thing you could do is to make your vision processing interrupt based, and set it to a higher priority than the core timer.

*Brian
Thanks!
I am using a interrupt driven approach with the priority set to 3, what priority does SoftPWM run at? I figure this would be the best way of solving it since the load/unload-routine could possibly take some time to process?

Edit: I'll just go ahead and bump my rendering up to 6-7 and see what happens. :)

User avatar
majenko
Site Admin
Posts: 2165
Joined: Wed Nov 09, 2011 7:51 pm
Location: UK
Contact:

Re: Need testers for SoftPWMServo library

Post by majenko » Wed Sep 09, 2015 11:06 am

The core timer interrupt (defined in wiring.c) runs at "_CT_IPL_IPC" which is defined (in System_Defs.h) as priority 7.

If you want to get to a higher priority than that you will need to change the CT priority:

Code: Select all

setIntPriority(_CORE_TIMER_VECTOR, 4, 0);
That would change the priority to 4 with a sub-priority of 0.

It's anyone's guess what effect that would have on the system though - there' lots that is handled by that CT ISR. You should read through the comments section just above CoreTimerHandler in wiring.c to see what it does:
A CoreTimer Service is a callback routine that will get called when the core timer value equals the last value returned by your service; also known as your requested compare time. When registering a CoreTimerService callback routine, the routine will be called on the next regularly scheduled event currently waiting the CoreTimerHandler. From system start, there is a millisecond CoreTimerService running, so in most cases once you register your callback serivce it should be called within 1 ms of attaching (registering). In some cases if interrupts are diaabled it may be as long as 50 ms before your first call is made. Passed in to your Service is the current value of the CoreTimer count register, this is a rolling count that rolls once every 2^32 / 40000000 ~ 107seconds. The return value from your service should be the next value of count that you want to be notified; logically like setting the compare register; however, CoreTimerHandler is managing several services and will notify you when your value has been hit. You will totally screw up CoreTimerHandler if you set the compare register directly. Here are the rules for writing a CoreTimerService callback routine.

The rules:

1. You do NOT set "compare"!
2. Do not do anything that could cause CoreTimerHandler to be called recursively. For example, do not enable interrupts as the CT flag is still set and will immeditely cause the system to call CoreTimerHandler.
3. The value of the count register is passed to you, however this could be several ticks old. Usually this is not a problem. It is allowed for you to read the count register directly, however you must return a compare value that is greater in time (so it can be a uint32 wrapped value than the count value passed to you.
4. You will NOT be called before your compare value has been hit; however you may be called late should interrupts get disabled.
5. Unfortunately, because of things like the EEProm writes, you can be called late and you must "catch-up" however best you can and return the next requested "compare" time on your next call.
6. There are limits to how far in the future you can set your next "compare" time. Right now this is limited to 90 seconds. If you need a longer delay you should be using something other than a CoreTimer Services to do this. You probably should really limit your next "compare" time to less than few seconds.
7. Your next requested "compare" time MUST be equal to or after (in time) the "current" time as passed in to you. You may add up to 90 seconds to the current time, even if this causes uint32 wrap; but do not subtract from the current time and return that. There is a region known to CoreTimerHandler that is before the current time, but that uint32 "value" is after the current time + 90 seconds.
8. CoreTimerHandler will keep looping until count is less than whatever the next compare is "after" CT was cleared to insure that CT is not missed. It is possible that you could be called a second time before exiting the CoreTimerHandler ISR if you request a new compare time that is very close to the current time.
9. After attaching, your service will be called on the next schedule call to CoreTimerHandler. Since there is always a ms service that gets triggered, this will typically mean your first call to your Service will be within 1 ms of attaching, unless interrupts are disabled and you are delayed; it could then be as much as 50ms.
10. Understand, your callback is being called while executing inside the CoreTimerHandler ISR. Your code should be as fast as possible. If too much time is taken, the ISR may never exit and no sketch will ever run!
So you can see it is a pretty complex and delicate operation and upsetting the balance could have dire consequences; or you may notice no change in the functionality at all. It's a case of "suck it and see". You could end up with your other interrupts causing the CT system to run too slowly, so it causes collisions and crashes. If you use millis() or delay() you could well end up with clock drift and timing inaccuracies (although the "base" clock that it uses is accurate, if the response to the ticks from that clock are delayed or interrupted it can have an effect on the outcome of that response).
Why not visit my shop? http://majenko.co.uk/catalog
Universal IDE: http://uecide.org
"I was trying to find out if it was possible to only eat one Jaffa Cake. I had to abandon the experiment because I ran out of Jaffa Cakes".

rasmadrak
Posts: 218
Joined: Mon Aug 15, 2011 9:21 pm
Location: Sweden
Contact:

Re: Need testers for SoftPWMServo library

Post by rasmadrak » Wed Sep 09, 2015 4:00 pm

I see...
Messing with the core timer is not really desirable, it's something about the word "core" that upsets me. ;)
Maybe I can try to change the rendering-routine to draw a single layer (i.e 32 lines) at a time and attach to the CoreTimer instead, with a sub-priority slightly higher than SoftPWMServo.

User avatar
majenko
Site Admin
Posts: 2165
Joined: Wed Nov 09, 2011 7:51 pm
Location: UK
Contact:

Re: Need testers for SoftPWMServo library

Post by majenko » Wed Sep 09, 2015 4:19 pm

It's called "core" because the hardware for it is at the heart of the PIC32. It's actually inside the "Co-Processor 0" which performs various housekeeping tasks including interrupt and exception management, etc. You can't really affect the core timer in any way. You can zero it, and you can query it, and that's about it. It's always running as long as the system clock is running (so not in sleep mode) and always at the same speed (one tick per system clock tick).

With the core timer service in chipKIT you register a core timer service. The core timer handler then looks to see when that service is due to be executed and executes it. You don't have priorities within the core timer services, only "due times". That way things get interleaved between each other. The software PWM is just one of those services that has been registered and gets called at the appropriate intervals.
Why not visit my shop? http://majenko.co.uk/catalog
Universal IDE: http://uecide.org
"I was trying to find out if it was possible to only eat one Jaffa Cake. I had to abandon the experiment because I ran out of Jaffa Cakes".

Post Reply