Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 687 → Rev 688

/branches/V0.68d Code Redesign killagreg/rc.c
16,71 → 16,121
#include "fc.h"
 
volatile int16_t PPM_in[11];
volatile int16_t PPM_diff[11]; // das diffenzierte Stick-Signal
volatile int16_t PPM_diff[11];
volatile uint8_t NewPpmData = 1;
volatile uint8_t SenderOkay = 0;
 
/***************************************************************/
/* zum decodieren des PPM-Signals wird Timer1 mit seiner Input */
/* Capture Funktion benutzt: */
/* 16bit timer 1 is used to decode the PPM-Signal */
/***************************************************************/
 
void rc_sum_init (void)
{
TCCR1B=(1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);//|(1 << WGM12); //timer1 prescale 64
uint8_t sreg = SREG;
 
// PWM
//TCCR1A = (1 << COM1B1) | (1 << WGM11) | (1 << WGM10);
//TCCR1B |= (1 << WGM12);
//OCR1B = 55;
// disable all interrupts before reconfiguration
cli();
 
TIMSK1 |= _BV(ICIE1);
// PPM-signal is connected to the Input Capture Pin (PD6) of timer 1
DDRD &= ~(1<<DDD6);
PORTD |= (1<<PORTD6);
 
// Timer/Counter1 Control Register A, B, C
 
// Normal Mode (bits: WGM13=0, WGM12=0, WGM11=0, WGM10=0)
// Compare output pin A & B is disabled (bits: COM1A1=0, COM1A0=0, COM1B1=0, COM1B0=0)
// Set clock source to SYSCLK/64 (bit: CS12=0, CS11=1, CS10=1)
// Enable input capture noise cancler (bit: ICNC1=1)
// Trigger on positive edge of the input capture pin (bit: ICES1=1),
// Therefore the counter incremets at a clock of 20 MHz/64 = 312.5 kHz or 3.2µs
// The longest period is 0xFFFF / 312.5 kHz = 0.209712 s.
TCCR1A &= ~((1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10));
TCCR1B &= ~((1<<WGM13)|(1<<WGM12)|(1<<CS12));
TCCR1B |= (1<<CS11)|(1<<CS10)|(1<<ICES1)|(1<<ICNC1);
TCCR1C &= ~((1<<FOC1A)|(1<<FOC1B));
 
// Timer/Counter1 Interrupt Mask Register
 
// Enable Input Capture Interrupt (bit: ICIE1=1)
// Disable Output Compare A & B Match Interrupts (bit: OCIE1B=0, OICIE1A=0)
// Disable Overflow Interrupt (bit: TOIE1=0)
TIMSK1 &= ~((1<<OCIE1B)|(1<<OCIE1A)|(1<<TOIE1));
TIMSK1 |= (1<<ICIE1);
 
AdNeutralGier = 0;
AdNeutralRoll = 0;
AdNeutralNick = 0;
return;
 
SREG = sreg;
}
 
//############################################################################
//Diese Routine startet und inizialisiert den Timer für RC
SIGNAL(SIG_INPUT_CAPTURE1)
//############################################################################
 
/********************************************************************/
/* Every time a positive edge is detected at PD6 */
/********************************************************************/
/*
The PPM-Frame length is 22.5 ms.
Channel high pulse width range is 0.7 ms to 1.7 ms completed by an 0.3 ms low pulse.
The mininimum time delay of two events coding a channel is ( 0.7 + 0.3) ms = 1 ms.
The maximum time delay of two events coding a chanel is ( 1.7 + 0.3) ms = 2 ms.
The minimum duration of all channels at minimum value is 8 * 1 ms = 8 ms.
The maximum duration of all channels at maximum value is 8 * 2 ms = 16 ms.
The remaining time of (22.5 - 8 ms) ms = 14.5 ms to (22.5 - 16 ms) ms = 6.5 ms is
the syncronization gap.
*/
ISR(TIMER1_CAPT_vect) // typical rate of 1 ms to 2 ms
{
static unsigned int AltICR=0;
signed int signal = 0,tmp;
static int index;
static uint16_t oldICR1 = 0;
int16_t signal = 0, tmp;
static int16_t index;
 
signal = (unsigned int) ICR1 - AltICR;
AltICR = ICR1;
// 16bit Input Capture Register ICR1 contains the timer value TCNT1
// at the time the edge was detected
 
//Syncronisationspause?
// if((signal > (int) Parameter_UserParam2 * 10) && (signal < 8000))
// calculate the time delay to the previous event time which is stored in oldICR1
signal = (uint16_t) ICR1 - oldICR1;
oldICR1 = ICR1;
 
 
//sync gap? (3.52 ms < signal < 25.6 ms)
if((signal > 1100) && (signal < 8000))
{
// if a sync gap happens and there where at least 4 channels decoded before
// then the NewPpmData flag is reset indicating valid data in the PPM_in[] array.
if(index >= 4) NewPpmData = 0; // Null means NewData
// synchronize channel index
index = 1;
}
else // within the PPM frame
{
if(index >= 4) NewPpmData = 0; // Null bedeutet: Neue Daten
index = 1;
}
else
if(index < 10) // channel limit is 9 because of the frame length of 22.5 ms
{
if(index < 10)
// check for valid signal length (0.8 ms < signal < 2.1984 ms)
if((signal > 250) && (signal < 687))
{
if((signal > 250) && (signal < 687))
signal -= 466; // offset of 1.4912 ms ??? (469 * 3.2µs = 1.5008 ms)
// check for stable signal
// the deviation of the current signal level from the average must be less than 6 (aprox. 1%)
if(abs(signal - PPM_in[index]) < 6)
{
signal -= 466;
// Stabiles Signal
if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10;}
// tmp = (7 * (PPM_in[index]) + signal) / 8;
// a good signal condition increases SenderOkay by 10
// SignalOkay is decremented every 2 ms in timer0.c
// this variable is a level for the average rate of noiseless signal
if(SenderOkay < 200) SenderOkay += 10;
}
// calculate exponential history for signal
tmp = (3 * (PPM_in[index]) + signal) / 4;
if(tmp > signal+1) tmp--; else
if(tmp < signal-1) tmp++;
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3;
// calculate signal difference on good signal level
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; // cut off lower 3 bit for nois reduction
else PPM_diff[index] = 0;
PPM_in[index] = tmp;
}
index++;
if(index == 5) PORTD |= 0x20; else PORTD &= ~0x20; // Servosignal an J3 anlegen
if(index == 6) PORTD |= 0x10; else PORTD &= ~0x10; // Servosignal an J4 anlegen
if(index == 7) PORTD |= 0x08; else PORTD &= ~0x08; // Servosignal an J5 anlegen
PPM_in[index] = tmp; // update channel value
}
index++; // next channel
// demux sum signal fpr channels 5 to 7
if(index == 5) PORTD |= 0x20; else PORTD &= ~0x20; // Servosignal an J3 anlegen
if(index == 6) PORTD |= 0x10; else PORTD &= ~0x10; // Servosignal an J4 anlegen
if(index == 7) PORTD |= 0x08; else PORTD &= ~0x08; // Servosignal an J5 anlegen
}
}
}