Angular Signals

Creating the angular signals

To create output signals with the expected accuracy over the whole engine speed range is not easily possible even with 32bit timers.
After investigating several approaches, I came up with the following solution:

- One of the four timer channels is used to create an angular clock (e.g. 256 ticks per tooth) depending on engine speed
- the output of this angular clock is (physically) connected as input to two other timer channels which are configured to counter mode with external clock input
- On each of these timers, the first two match events are used to create edges on two output channels each (2x2 = 4)

If a new engine speed N is set, the tooth period is calculated as follows:

... where  ftimer is the timer frequency of 100MHz, N is engine speed (in rotations per minute) and m is the number of teeth per rotation (typically 60).

For m = 60, this is reduced to 

Now within this tooth period a given number X (256) of ticks must be created

The problem is that rounding errors will occur which would lead to a wrong tooth period.
E.g. with  ftimer= 100MHz, N = 515, m = 60 (rounded up):

With X = 256

If this is truncated to 758, the resulting tooth period after 256 ticks would be

which is quite different from the correct value 194175.

To avoid this inaccuracy, the following approach is used:
First the remainder r of the division (modulo, the "%" operator in C ) is calculated

Now instead of simply repeating the tick period X (256) times, it is split as follows:

Or with the given values:


These X (256) periods are created with two DMA transfer descriptors which are linked (after transfer 1 is finished, it's linked to transfer descriptor 2, if transfer 2 is finished, it's linked to transfer descriptor 1).
So when a new engine speed is requested, the tick period is calculated and then the two tick periods (ttick and ttick+1) and the two repeat counters (error and X-error) have to be entered into the two linked DMA transfer descriptors.

To avoid consistency issues during the update, a double buffering strategy is used where the new transfer descriptors are prepared offline and then the "next" entry of the currently active transfer descriptor is patched to point to the offline descriptor.

Back to main page