Dynomotion

Group: DynoMotion Message: 10963 From: Hardy Family Date: 1/30/2015
Subject: 90us callback
I'm just in the process of designing a CNC machine controller, for a brand new machine design.  The DynoMotion stuff looks great so far, especially the neat C code compiler and the open source nature.

A few questions about the C callback that can be registered in the Kflop that is run at the servo update rate:

The manual states that the thread which registers the callback must not terminate, otherwise the system code might crash when it calls the (non-existent) callback.  So, what happens when a callback is registered, but the thread is re-started (maybe with a different program)?  Does the system automatically unregister the callback when a KILL command is sent from the PC?  Or am I just going to have to be really careful never to kill/restart that thread?

How much time can reasonably be spent in the callback?  What I really want to do is interface to some bit-banged SPI devices.  Since I want to send about 32 bits of data, with a SPI clock of about 10MHz, that is going to take about 3.5us for each servo update interval.  I'm going to have to use some "for(i=10;i;--i);" type of hard loops to get the timing details right, but that's not a real problem.   I just don't want to be running for so long that the servo loop rate gets affected or other threads run out of time.

Regards,
AB



Group: DynoMotion Message: 10980 From: Tom Kerekes Date: 2/2/2015
Subject: Re: 90us callback
Hi AB,

Regarding the 90us callback:  It isn't really a matter of the Thread terminating.  Once a callback is configured to execute code in a Thread space it will continue to call that code regardless of whether the Thread is executing or not.  The important thing is that the code in the Thread Space is not changed before the callback is stopped.  The code below can be used to stop the callback.  This can be executed from any Thread.   The system never automatically disables the callback.  It is up to you to do this in a way that makes sense for you.

#include "KMotionDef.h"
main()
{
    UserCallBack = NULL;  // stop the callback
}

You should probably spend less than 10us in the callback.  It depends on how much time the system is using for updating all the Axis and other system requirements and how much time you are willing to steal from the system and your other Threads.  The example Measure IRQ.c can give an indication of how much time is available for your configuration.

Regarding SPI: I doubt if you will be able to bit bang at 10MHz.  We discussed this in the following Thread and I believe the rate was ~450KHz


You might consider doing this in a User Thread.  This would result in an update time of 180us or more, but depending on your requirements (servo bandwidth) it may not be an issue.  For example with a bandwidth of 50Hz an extra 90us of delay will reduce the phase margin by only:

90us/20ms x 360 degrees = 1.62 degrees.

HTH
Regards
TK

Group: DynoMotion Message: 10983 From: Hardy Family Date: 2/2/2015
Subject: Re: 90us callback


Regarding the 90us callback:  It isn't really a matter of the Thread terminating.  Once a callback is configured to execute code in a Thread space it will continue to call that code regardless of whether the Thread is executing or not.  The important thing is that the code in the Thread Space is not changed before the callback is stopped.  The code below can be used to stop the callback.  This can be executed from any Thread.   The system never automatically disables the callback.  It is up to you to do this in a way that makes sense for you.


OK, so I do need to be very careful.  If the callback is executing thread 1 code (which I use when the INIT button is pressed in KMotion-CNC) then it must be the exact same code each time, otherwise there is a possible race condition.

Our end-users are unlikely to be tweaking the INIT C code, but I would respectfully request that you add a feature to the KFlop "OS" at some point, so that it actually registers which thread "owns" the callback code, so that when the thread is killed (or replaced) then the callback is first NULLed out.
 

Regarding SPI: I doubt if you will be able to bit bang at 10MHz.  We discussed this in the following Thread and I believe the rate was ~450KHz


Hmmm... I did search the archive for "SPI" but didn't locate this one.  Not very expert at the Yahoo interface.
 

You might consider doing this in a User Thread.  This would result in an update time of 180us or more, but depending on your requirements (servo bandwidth) it may not be an issue.  For example with a bandwidth of 50Hz an extra 90us of delay will reduce the phase margin by only:

90us/20ms x 360 degrees = 1.62 degrees.

HTH
Regards
TK


It does help indeed, thanks.  We can probably live with 450kbit/s for most stuff.  I threw out the 10MHz figure assuming that could be achieved by tight code in a DSP/ARM, but yeah, sometimes the external I/O is very slow.  If necessary, we could probably move to an 8-bit parallel type interface.  The unfortunate thing about the slower data rate is that it now takes 70us or so to do a complete SPI read, all with completely busy CPU, so it will have a noticeable impact on other processing.

I take it than one can set or clear 8 or 16 bits at a time (FPGA(BIT_SET), FPGAW(BIT_SET) etc.) so I guess to write a value one splits it into 1's and 0's and does two writes (set x then clear ~x).  Is there an 8- or 16-bit direct "replace bits" location?

Regards,
AB