Real-Time DSM Timing Data

Like DSM2/DSMX? Want to mod your radio to support it? Post your messages here!
Post Reply
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Real-Time DSM Timing Data

Post by gruvin »

As requested, I'm porting this information to the forum, from various private emails, as well as consolidating the several confusing messages sent to Bertrand and friends, as the full nature of the issues herein gradually came to light.

By way of background, I had been experiencing the odd glitch with DSM2 data, since I started using DSM2=PPM, instead of DSM2=SERIAL, as I had previously. So I inserted some debug code, such that I could see the real-world timing of related invents in the system. This was achieved by outputting on two spare PORTH pins (G9X board) so that relative event timing could be seen on my logic analyser. The results were truly enlightening and valuable, leaving me wondering why I had not thought of this diagnostics approach before!

The following partial screen shots show logic analyser data collected from open9x (approx. r1541). The various signals displayed include PPM (or UART serial) output, the start and end timing of the mixer interrupt routine (HIGH and LOW levels, respectively) and the same again for the entire setupPulses() procedure. Most importantly for the topic at hand, the data shows the relative timing between those three.

First, let's look at normal PPM mode (no DSM2 involved, yet) ...
Image

Here (above) we see that the mixer routine is completing at a tidy 883us before the start of setupPulses(). Quite good. However, in terms of system latency, it could be said that both mixer and setupPulses() are occurring some 6ms too early, relative to the start of the next PPM output frame. (From previous communications, I am confident this was not the intention and indeed, my own fuzzy analysis of the code suggests it should be otherwise. Clearly, we've missed something.)

I should note, just in case it does actually crop for someone else, that I could swear the first time I collected the above PPM normal mode data, the timing was much closer in, as intended by design. But I have tried many things and many times to try and get different results and simply cannot. So for now, I have to write the former recollection off to my now almost famous, unreliable memory.

Now, DSM2=SERIAL mode timing ...
Image

Here we see that setupPulses() is consistently completing just 1.5us before next output stream. Really good. However, now the mixer's completion is way back at around 4,000us (4ms) prior to setupPulses(). I believe the intention here was to have only 500us. So something not quite right there, also.

So far, nothing too serious in terms of practical operation has been discovered. However, this will not remain the case, as we continue onto DSM2=PPM mode ...

DSM2=PPM mode ...
Image

Here we see that setupPulses() is not so ideally timed, but still a safe and respectable 1.13ms before start of next output frame.

But something is wrong with the mixer interrupt timing, entirely.

Let's zoom out to get a clearer picture ...
Image

Unlike the other cases above, where the mixer interrupt is always phase locked in time relative to setupPulses -- I have viewed those zoomed right out, also -- this time we can see that the mixer interrupt is no longer phase locked, but rather asynchronous and drifting backwards in time, relative to setupPulses().

Perhaps more importantly, further tests showed that, on the odd occasion when the mixer interrupt collides with setupPulses(), then the end of setupPulses() is delayed until after the start of the next output frame, resulting in unpredictable or even no output for that frame.

- - -

So there it is. I hope I've laid things out clearly, without missing anything important out, whilst still avoiding the many confusing charts and musings Bertrand et al had to endure the first time around. :-P

Naturally, I am available to run more tests, as the need arises. However, it would be best to email me direct. (I believe all those who need, already have my direct email address.) Thanks.

Gruvin.

P.S: [EDIT: The following now known to apply only to the ATmega2560/G9X board ...] Tangled up with all the above originally, was a problem with the individual bit timings of DSM2 data in DSM2=PPM mode -- namely that they varied from 6us to 10us in length, when they should have been exactly 8us, for 125,000bps. This actually still worked in practice -- but only just! In any case, that issue has now been fixed, so I have left it out of this post entirely, to save the probable confusion. If anyone wants to see the before and after "open9x-r1541 fix" timing diagrams, I have kept some PNG images on file.
Last edited by gruvin on Tue Nov 06, 2012 10:09 am, edited 1 time in total.

User avatar
Kilrah
Posts: 11108
Joined: Sat Feb 18, 2012 6:56 pm
Country: Switzerland

Re: Real-Time DSM Timing Data

Post by Kilrah »

No comment so far about the DSM2=PPM, but...
gruvin wrote: However, in terms of system latency, it could be said that both mixer and setupPulses() are occurring some 6ms too early, relative to the start of the next PPM output frame.
[...]
However, now the mixer's completion is way back at around 4,000us (4ms) prior to setupPulses(). I believe the intention here was to have only 500us. So something not quite right there, also.
As far as I know the start of the next PPM frame is triggered by a timer interrupt, i.e. it's fixed in time. The mixer processing duration is however variable, so there must be enough margin between the start of the mixer processing and the start of the next frame. So yes, if you have a simple 4-CH model with no extras then mixer processing will be quick and there will be a few ms of idle time before the next frame is output, but then if your model is a complex glider with 20 mixers, flight phases, expos, curves, slows,... processing will be way longer, yet should still finish before the next frame is output... hence the "conservative" margin.
I don't see how you can reduce the latency other than internally timing the mixers and dynamically repositoning the mixer interrupt to occur at the right time. But then you'd risk that the user flips a switch, activates 10 more mixers, which increases processing time and causes a "missed frame".
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

Kilrah wrote: As far as I know the start of the next PPM frame is triggered by a timer interrupt, i.e. it's fixed in time. The mixer processing duration is however variable, so there must be enough margin between the start of the mixer processing and the start of the next frame. So yes, if you have a simple 4-CH model ...
I believe Bertrand's code is far more clever than that. It measures mixer time requirements etc, frame to frame and adjusts accordingly, on the fly, continuously, for best latency performance -- when it's working correctly. :-D

If I understand correctly, the design aims to have the mixer interrupt end 500us before setupPulses, which in turn should be completed directly before the start of the next PPM output frame. In one case above, we see it close to that, at 833us. Some time extension is to be expected for interrupt branching and stack management ... though now I think of it, that should have things go the opposite direction. Hmm. Maybe it's just timer resolution then -- or just a fluke of some kind, at present.
I don't see how you can reduce the latency other than internally timing the mixers and dynamically repositoning the mixer interrupt to occur at the right time.
Quite right. That is what is being done. (Bertrand, correct me if I'm wrong.)

In any case, the main issue here -- the one needing attention (and getting it) -- is the floating mixer interrupt timing for DSM2=PPM mode. The rest is only intended as informational, having learned from Bertrand the intentions for the timing and noting it wasn't quite working out at present.
Last edited by gruvin on Tue Nov 06, 2012 10:34 am, edited 4 times in total.
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

Note that I have just added an edit to the P.S. in the original post. I have just completed testing of open9x-r1553 (trunk) and found that the original code, with no bit transition timing adjustments is producing good 8us bit lengths, as was always expected.

In summary then, that sub-topic can now be safely ignored, since it is resolved for the gruvin9x v4.x boards and was never actually a problem on the stock boards, as it turns out.
bertrand35
9x Developer
Posts: 2764
Joined: Fri Dec 30, 2011 11:11 pm
Country: -

Re: Real-Time DSM Timing Data

Post by bertrand35 »

Hi Bryan,

If I am right we are still missing the mechanism (perhaps you didn't commit the change) for launching the mix calculations at the right time when DSM2=PPM?

case PROTO_DSM2:
#if defined(PCBGRUVIN9X)
OCR5A = (uint16_t)0x7d * (40-g_timeMainLast-2/*1ms*/);
TCNT5 = 0;
#endif

sei();
setupPulsesDsm2();
break;

Also we will need the same for PXX. Is it true?
Thanks!

Bertrand.

User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

bertrand35 wrote:Hi Bryan,If I am right we are still missing the mechanism (perhaps you didn't commit the change) for launching the mix calculations at the right time when DSM2=PPM
Yes, still missing. I have thus far been unable to fully comprehend how the timing calculations work and therefore unable to contribute in that regard, save the external logic chats. That said, you do make it seem simple with ...

Code: Select all

OCR5A = (uint16_t)0x7d * (40-g_timeMainLast-2/*1ms*/);
Alas, I am not clear what is running in main and what is under interrupt control these days. Mostly, I am confused about how main loop timing relates to mixer and pulse output timing, which as far as I can see is now entirely interrupt/timer driven and thus not related to the main loop at all (good!) So why the variable label g_timeMainLast? Is that merely some legacy name, where the label's context has changed since the mixer calcs went into interrupt routine, perhaps?

I tried to ascertain exactly when the ADC sampling is happening, relative to mixer scheduling. Far as I can tell, ADC is still in the main loop. But I am not clear on this. I think that ADC should be scheduled to happen directly before mixer, if that is feasible in the bigger picture of things.

To further answer your question, I have committed everything I have done to date (not much) as at r1553 (just a comment edit) and have made no local changes since. My intention has been to stay out of the code entirely, while you are working on these things.

(Unfortunately, this stuff is now at the outer edge of my skills envelope. I have great difficulty reverse engineering other people's code design into flow charts on paper that I can understand. I am learning a lot from the master, so to speak ... but clearly lagging behind in terms of contribution. Keep up the amazing work! ;-) )
Also we will need the same for PXX. Is it true?
Thus far, I have avoided PXX entirely -- and PPM16, since it cannot work on the G9X hardware's trainer port anyway. But yes, my guess is that we need something similar done in both those places, too.

Let me know as soon as you need more real-world testing done. I can't wait to see it working beautifully, as I'm sure it will soon.

Bryan.
bertrand35
9x Developer
Posts: 2764
Joined: Fri Dec 30, 2011 11:11 pm
Country: -

Re: Real-Time DSM Timing Data

Post by bertrand35 »

g_timeMainLast should be renamed to mixerLastDuration (as it has nothing to do with main!) And yes the ADC conversions are done just before the mixes calculations (and are taken into account for this mixer duration!)
Bertrand.
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

bertrand35 wrote:

Code: Select all

#if defined(PCBGRUVIN9X)
      OCR5A = (uint16_t)0x7d * (40-g_timeMainLast-2/*1ms*/);
      TCNT5 = 0;
#endif
Bertrand, I finally realised that you were suggesting a complete solution in the code above, not just a thought or possibility as I interpreted earlier. So I tried it out and it seems to work just fine! :) Here is the data from the analyser ...

Image

The actual time between the end of the mixer interrupt and start of setupPulses is around 2.88ms. The code comment seems to suggest you were expecting 1ms. Is that right?

So that we may better understand what is happening, can you please explain the various values in the calculation? That is to ask, why 0x7d and what is the reason for 40-, and what exactly is g_timeMainLast recording? Thanks.

I am now going to test with a more complex mixer set, to be sure the mixer extends back in time as it needs to.

EDIT: Yes, that seems fine. There are small changes in the mixer/setupPulses gap, but a full 1ms prepended to the beginning of the mixer routine.

So the fix was so simple in the end. Just a couple lines of code. Amazing.

Bryan.
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

Bertrand,

Also, what is the situation with the stock board? I believe there is no TCNT5 on the '64A, so how is the timing managed in that case? Thanks.
bertrand35
9x Developer
Posts: 2764
Joined: Fri Dec 30, 2011 11:11 pm
Country: -

Re: Real-Time DSM Timing Data

Post by bertrand35 »

On the stock board I have no flash available, so it remains the same for all protocols: the mixer is in the same branch of code than the menus and everything else.

By the way, it's REALLY needed on gruvin9x board because of the LOGS feature! Writing on SD is too long and cannot be in the same branch than the mixer, that's why I moved the mixer code in an interrupt. It would be desirable, but not really needed on the stock board.

Bertrand.

The calculations:
- 0x7d gives us 500ms. This is the step.
- 40 gives 20ms (I didn't check that 20ms is the right interval between two trains for DSM2)
- g_timeMainLast is the last mixer duration (multiplied by 500ms of course)
- 2 /*1 ms*/ is the margin

So ... 2.88ms is not ok, there is something wrong for DSM2.

Bertrand.
bertrand35
9x Developer
Posts: 2764
Joined: Fri Dec 30, 2011 11:11 pm
Country: -

Re: Real-Time DSM Timing Data

Post by bertrand35 »

If DSM2 has an interval of 22ms it will be consistent with PPM measurements you did: 2ms (we would replace 40 by 44) + 0.88ms = 2.88ms
Bertrand.

EDIT: 44 instead of 40 commited on trunk
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

Thanks for the explanations Bertrand. It helped a lot. (See next post.)
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

After much fuss on my own part, punctuated by lashings of self-doubt (skills lacking, etc) and a good dose of help from Bertrand, I have finally managed to get the above issues ironed out -- as well as disturbing and thus finding a few more tricky bugs to fix, along the way! As part of my slow learning throughout this little challenge, I have also added or edited quite a few code comments in pulses_avr.cpp.

The following charts and commentary are valid as at open9x trunk revision r1579.

So then, here are the final timing charts, for the three modes I have worked on ...

PPM mode ...
Image

Note that the mixer interrupt and setupPulses() are a fair way back from each PPM output frame start, still. We could probably introduce a Timer1 / COMPC hold-off delay, as is done for DSM2_PPM mode. But with user-settable frame length and other cleverness involved, that's a little out of my league for now. Besides, I really don't think anyone is going to notice the 2-4ms difference.


DSM2 using PPM output (Build option DSM2=PPM) ...
Image

In this case, setupPulses() ends about 0.12ms before each DSM2 data frame begins, afforded by the afore mentioned COMPC hold-off delay. (I think that was introduced by Mike and friend? It's pretty darn clever anyway!)


DSM2 using serial USART output (Build option DSM2=SERIAL) ...
Image

In this case, the setupPulses / data frame gap is only 7.5us. This was alarming at first, on the ground that it left very little room for error. But then I realised that setupPulses() directly trigger the USART to begin transmitting data. So there's no interrupt scheduled collision possibility, like what was happening in DSM2_PPM as told in the original post herein. Whew.

Of course, there is also now no drifting of the mixer interrupt, relative to setupPulses() as was also originally posted herein.

Oh and by the way, these tests were done with 8 active mixer channels, with two flight phases configured with fade-in/out and two sets of DR/EXPO settings for the four main input sources. The mixer interrupt duration is 2.88ms.

- - -

For those still wondering at this point, the scheduling of the mixer code is dynamically adjusted to compensate for more complex and thus time mixer set-ups. This is done by measuring the duration of the last mixer calculation run and re-scheduling the next run accordingly, frame to frame. Just another one of Bertrand's little inventions to marvel at. ;-)

All of this dynamic scheduling is of course done to keep overall stick-to-data-output latency as low as possible. It is way beyond what I would have been able to come up with -- and I must admit that it took me ages to understand it all, too! :oops:

- - -

Oh -- there is likely yet work to do to tune PPM16 and PXX modes. I am not able to use either of those in practice at this, so I've not spent any time on them.

- - -

I am also unclear as to when exactly the analogue sampling from sticks and pots is taking place, relative to all the above. I have a suspicion that these are still asynchronous, running in the main loop, which would not be the ideal case. Bertrand ... can you confirm or correct? Thanks.

- - -

Last but not least, I would support changing the name of, "PPM16" to either, "PPM8+8" or, "PPM8x2", since I believe those would more accurately describe what is actually going on, no? (PPM16 sends mixer channels 9 to 16 out the trainer jack -- unless I'm mistaken?)



Gruvin.
User avatar
Rob Thomson
Site Admin
Posts: 4543
Joined: Tue Dec 27, 2011 11:34 am
Country: United Kingdom
Location: Albury, Guildford
Contact:

Re: Real-Time DSM Timing Data

Post by Rob Thomson »

Gruvin... Talk about you not knowing what you are doing makes me smile.

I don't do nearly so much 9x coding these days; primarily because I am finding it harder and harder to understand what the code does!

Hats off to the core dev team for understanding it! I can't express how skilled they are!!
Slope Soaring, FPV, and pretty much anything 'high tech'
...........if you think it should be in the wiki.. ask me for wiki access, then go add it!
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

It makes me laugh too ... weeks later, when I reminisce and my hair has grown back! :geek:

I just hope and pray I haven't messed anything up this time. Had a bad run, lately. I tested and retested this time -- and carefully pawed over output from 'svn diff' before every commit ... and still had to commit a couple fixes, after the fact. Sheesh. :roll:

It's all a great learning experience though and it's worth the pain, once I finally get something right and praised by No. 1. (Here's hoping! :shock: ) It's really nice to have people be so tolerant and friendly, that's for sure.

Gruvin.
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: Real-Time DSM Timing Data

Post by MikeB »

I don't know if the other firmwares are the same, but on er9x, if you use PPM16, and (e.g.) set the number of channels to 5, then channels 1-5 go to the main tx module, while channels 6-13 go to the trainer port.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

Mike,

I was wondering about that after my post last night, when I noticed that PPM mode in the chart above is outputting 10 channels, not 8 as expected. It turns out that if one sets the protocol to DSM2/DSMonl and then back to PPM, then the PPM channel count is bumped from 8 up to 10. I see now that the same data field is being used for the DSM sub-mode and the PPM channel count, but hadn't noticed it happening before. No biggie.

Otherwise, yes ... you're point noted. I'll check into that for the open9x case later today. Certainly, "PPM8x2" would not be a good name if it might in fact be 5+8. But then, neither would PPM16 in that case. Maybe "PPM+8" then? So easy to get caught up in the details. hehe We might as well try to get it 'right', though.

The DSM mode field labels make little sense to me, either. But I've led us off topic, so I've just created a separate post to discuss the label name issue, here.

Bryan.
User avatar
gruvin
9x Developer
Posts: 131
Joined: Tue Jul 24, 2012 10:02 pm
Country: New Zealand
Location: Auckland
Contact:

Re: Real-Time DSM Timing Data

Post by gruvin »

I just tried 11ms frame rates for DSM2 mode, using the worst-case DSM2=PPM mode for data transfer. IT WORKS.

I'm using an older, non-DSMX TX module. I didn't even have to re-bind.

I'm also amazed how much more responsive the servo movements are! I really didn't expect to notice a difference. FAST.

Here's the timing from the logic analyser ...

Image

Gruvin.

Post Reply

Return to “DSM2/DSMX Mods”