From 37387f91fd5e5b2e16bf8637713d1e641b6320b2 Mon Sep 17 00:00:00 2001 From: "gruvin@gmail.com" Date: Thu, 1 Nov 2012 08:44:14 +0000 Subject: [PATCH] GTRUVIN9XPCB: DSM2=PPM mode -- Implemented hardware switching of PPM_OUT pin and compensated for main clock synchronisation to get accurate 8us bit lengths, as measured on the logic analsyser. Specifically, all 1 and 0 bits now measure 8.000us in length, instead of varyting from 6.250us to 10.750us, as before. NOTE: A similar len-5 / len+3 compensation is almost certainly required to improve bit timing on the stock board, in software bit-bang mode, but I did not want to commit such a change to trunk without being able to bench test it first. The values might differ slightly, due to the number of instruction cycles executed before the actual PORT B bit toggle code is reached. But it will NOT be the same for both 1 and 0 bits. --- src/Makefile | 1 + src/pulses_avr.cpp | 70 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/Makefile b/src/Makefile index 501deb00f..f98b5fc34 100644 --- a/src/Makefile +++ b/src/Makefile @@ -183,6 +183,7 @@ EXTRA_ROTARY_ENCODERS = NO # On G9X V4 board, when VOICE=NO: # PORTH:7 --> Transistion LOW to HIGH = start of setupPulses(). Transistion HIGH to LOW = end of setupPulses(). # PORTH:6 --> LOW->HIGH = start of mixer calcs. HIGH->LOW, end of mixer calcs. +# Values = YES, NO DEBUG = NO # Flight Phases diff --git a/src/pulses_avr.cpp b/src/pulses_avr.cpp index b4cc3ba44..32d2815dc 100644 --- a/src/pulses_avr.cpp +++ b/src/pulses_avr.cpp @@ -501,13 +501,27 @@ void sendByteDsm2(uint8_t b) //max 10changes 0 10 10 10 10 1 if(lev == nlev){ len += BITLEN_DSM2; }else{ +#if defined (GRUVIN9XPCB) + // G: Compensate for main clock synchronisation -- to get accurate 8us bit length + // NOTE: This is probably required for the stock board (S/W bit-bang mode) also, + // but I did not want to commit that to trunk without testing it first. + if (nlev) + _send_1(len-5);// -1); + else + _send_1(len+3); +#else _send_1(len -1); +#endif len = BITLEN_DSM2; lev = nlev; } b = (b>>1) | 0x80; //shift in stop bit } +#if defined (GRUVIN9XPCB) + _send_1(len+BITLEN_DSM2+3); // 2 stop bits +#else _send_1(len+BITLEN_DSM2-1); // 2 stop bits +#endif } void setupPulsesDsm2() @@ -556,7 +570,10 @@ void setupPulsesDsm2() sendByteDsm2(dsmDat[counter]); pulses2MHzWPtr -= 1; //remove last stopbits and - _send_1(255); //prolong them + +//G: Removed to get waveform correct on analyser +//_send_1(255); //prolong them + _send_1(0); //end of pulse stream pulses2MHzRPtr = pulses2MHz; @@ -730,7 +747,7 @@ void setupPulses() { uint8_t required_protocol = g_model.protocol; -#if defined(PCBGRUVIN9X) && defined(DEBUG) && !defined(VOICE) +#if defined(DEBUG) && !defined(VOICE) PORTH |= 0x80; // PORTH:7 LOW->HIGH signals start of setupPulses() #endif @@ -751,10 +768,12 @@ void setupPulses() TCNT1 = 300; // Past the OCR1C value ICR1 = 44000; // Next frame starts in 22 mS #if defined(PCBGRUVIN9X) - TIMSK1 &= ~0x2F; // All interrupts off + TIMSK1 &= ~0x2F; // All Timer1 interrupts off TIFR1 = 0x2F; - TIMSK1 |= 0x28; // Enable CAPT and COMPC - TCCR1A = (0 << WGM10); // Also disconnects OC1B for PPM_OUT bit-bang mode + TIMSK1 |= 0x28; // Enable COMPC and CAPT interrupts + TCCR1A = (0 << WGM10); // Set output waveform mode to normal, for now. Note that + // WGM will be set to toggle OCR1B pin on compare capture, + // in next switch(required_protocol) {...}, below #else TIMSK &= ~0x3C; // All Timer1 interrupts off TIFR = 0x3C; @@ -873,6 +892,12 @@ void setupPulses() case PROTO_DSM2: sei(); setupPulsesDsm2(); +#if defined(PCBGRUVIN9X) + // Ensure each DSM packet starts out with the correct bit polarity + TCCR1A = (0 << WGM10) | (3<LOW signals end of setupPulses() #endif + } #ifndef SIMU @@ -900,12 +926,35 @@ void setupPulses() #if defined(DSM2_PPM) || defined(PXX) ISR(TIMER1_CAPT_vect) // 2MHz pulse generation { +#if defined (PCBGRUVIN9X) + + /*** G9X V4 hardware toggled PPM_out avoids interrupt latency jitter on the output. + + In most (but not all) foreseeable cases, the jitter removal afforded by this is + inside the bit timing tolerances of async serial data at 125,000bps. But I cannot + afford to crash models. So I like to have the extra assurance. Gruvin. + (It can be done on the stock board's PB7 too. Nove LED BL to PB0.) ***/ + + // OCR1B output pin (PPM_OUT) is pre-set to HIGH in setupPulses -- for safety, on each + // and every frame -- and configured to toggle on each OCR1B / TC1 count register match. + // All we need to do here then, is update the compare regisiter(s) ... uint8_t x ; - PORTB ^= (1< 200) PORTB |= (1< 200) PORTB |= (1<