Beispiel #1
0
void SucheLuftruckOffset(void)
{
 unsigned int off;
 ExpandBaro = 0;

#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
 {
  unsigned char off2;
  OCR0A = 150;
  off2 = GetParamByte(PID_PRESSURE_OFFSET);
  if(off2 < 230) off2 += 10;
  OCR0B = off2;
  Delay_ms_Mess(100);
  if(MessLuftdruck > DESIRED_H_ADC) off2 = 240;
  for(; off2 >= 5; off2 -= 5)
   {
   OCR0B = off2;
   Delay_ms_Mess(50);
   printf("*");
   if(MessLuftdruck > DESIRED_H_ADC) break;
   }
   SetParamByte(PID_PRESSURE_OFFSET, off2);
  if(off2 >= 15) off = 140; else off = 0;
  for(; off < 250;off++)
   {
   OCR0A = off;
   Delay_ms_Mess(50);
   printf(".");
   if(MessLuftdruck < DESIRED_H_ADC) break;
   }
   DruckOffsetSetting = off;
 }
#else
  off = GetParamByte(PID_PRESSURE_OFFSET);
  if(off > 20) off -= 10;
  OCR0A = off;
  Delay_ms_Mess(100);
  if(MessLuftdruck < DESIRED_H_ADC) off = 0;
  for(; off < 250;off++)
   {
   OCR0A = off;
   Delay_ms_Mess(50);
   printf(".");
   if(MessLuftdruck < DESIRED_H_ADC) break;
   }
   DruckOffsetSetting = off;
   SetParamByte(PID_PRESSURE_OFFSET, off);
#endif
 if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG) && (DruckOffsetSetting < 10 || DruckOffsetSetting >= 245)) VersionInfo.HardwareError[0] |= FC_ERROR0_PRESSURE;
 OCR0A = off;
 Delay_ms_Mess(300);
}
void SucheLuftruckOffset(void)
{
 unsigned int off;
 ExpandBaro = 0;
 CalcExpandBaroStep();
  off = GetParamByte(PID_PRESSURE_OFFSET);
  if(off < 240) off += 10;
  OCR0A = off;
  OCR0B = 255-off;
  Delay_ms_Mess(150);
  if(MessLuftdruck > DESIRED_H_ADC) off = 240;
  for(; off > 5; off--)
   {
    OCR0A = off;
    OCR0B = 255-off;
    Delay_ms_Mess(100);
    printf(".");
    if(MessLuftdruck > DESIRED_H_ADC) break;
   }
   DruckOffsetSetting = off;
   SetParamByte(PID_PRESSURE_OFFSET, off);
 if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG) && (DruckOffsetSetting < 10 || DruckOffsetSetting >= 230)) VersionInfo.HardwareError[0] |= FC_ERROR0_PRESSURE;

#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + correction of the altitude error in higher altitudes
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 CalAthmospheare = 15;                                      // re-claibrated from 16 to 15 at 2.09 -> the baro-Altimeter was about 7% too high
 if(ACC_AltitudeControl)
  {
   if(PlatinenVersion < 23) { if(off < 140) CalAthmospheare += (160 - off) / 26; }
//   else { if(off < 170) CalAthmospheare += (188 - off) / 19; }
   else { if(off < 170) CalAthmospheare += (188 - off) / 15; } // rescaled at 2.09
  }
 Luftdruck = MessLuftdruck * CalAthmospheare;
#endif
 Delay_ms_Mess(300);
}
void ParamSet_Init(void)
{
	uint8_t channel_backup  = 0, bad_params = 0, ee_default = 0,i;
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
	if(PlatinenVersion != GetParamByte(PID_HARDWARE_VERSION)) 
	 {
	  if(PlatinenVersion == 22 && GetParamByte(PID_HARDWARE_VERSION) == 21 && !(PIND & 0x10)) SetParamByte(PID_EE_REVISION,0); // reset the Settings if the Version changed to V2.2
	  SetParamByte(PID_HARDWARE_VERSION,PlatinenVersion); // Remember the Version number
	  wdt_enable(WDTO_15MS); // Reset-Commando
	  printf("\n\r--> Hardware Version Byte Changed <--");
	  while(1);
	 } 
#endif
	if((EEPARAM_REVISION) != GetParamByte(PID_EE_REVISION))  
	{
		ee_default = 1; // software update or forced by mktool
	}
	// 1st check for a valid channel backup in eeprom
	i = EEProm_Checksum(EEPROM_ADR_CHANNELS, sizeof(EE_Parameter.Kanalbelegung));
	if(i == eeprom_read_byte((uint8_t*)(EEPROM_ADR_CHANNELS + sizeof(EE_Parameter.Kanalbelegung)))) channel_backup = 1;

	// parameter check

	// check all 5 parameter settings
	for (i = 1;i < 6; i++)
	{
		if(ee_default || !ParamSet_ReadFromEEProm(i)) // could not read paramset from eeprom
		{
			bad_params = 1;
			printf("\n\rGenerating default Parameter Set %d",i);
			switch(i)
			{
				case 1:
					ParamSet_DefaultSet1(); // Fill ParamSet Structure to default parameter set 1 (Sport)
					break;
				case 2:
					ParamSet_DefaultSet2(); // Normal
					break;
				default:
					ParamSet_DefaultSet3(); // Easy
					break;
			}
			if(channel_backup) // if we have an channel mapping backup in eeprom
			{	// restore it from eeprom
				eeprom_read_block((void *)EE_Parameter.Kanalbelegung, (void*)(EEPROM_ADR_CHANNELS), sizeof(EE_Parameter.Kanalbelegung));
			}
			else
			{	// use default mapping
				ParamSet_DefaultStickMapping();
			}
			ParamSet_WriteToEEProm(i);
		}
	}
	if(bad_params) // at least one of the parameter settings were invalid
	{
		// default-Setting is parameter set 3
		SetActiveParamSet(3);
	}
	// read active parameter set to ParamSet stucture
	i = GetActiveParamSet();
	ParamSet_ReadFromEEProm(i);
	printf("\n\rUsing Parameter Set %d", i);

	// load mixer table
	if(GetParamByte(PID_EE_REVISION) == 0xff || !MixerTable_ReadFromEEProm() )
	{
		printf("\n\rGenerating default Mixer Table");
		MixerTable_Default(); // Quadro
		MixerTable_WriteToEEProm();
	}
	if(ee_default)	SetParamByte(PID_EE_REVISION, (EEPARAM_REVISION));
	// determine motornumber
	RequiredMotors = 0;
	for(i = 0; i < 16; i++)
	{
		if(Mixer.Motor[i][MIX_GAS] > 0) RequiredMotors++;
	}

	printf("\n\rMixer-Config: '%s' (%u Motors)",Mixer.Name, RequiredMotors);
 PrintLine();// ("\n\r===================================");

}
Beispiel #4
0
//############################################################################
//Hauptprogramm
int main (void)
//############################################################################
{
	unsigned int timer,i,timer2 = 0, timerPolling;

    DDRB  = 0x00;
    PORTB = 0x00;
    for(timer = 0; timer < 1000; timer++); // verzögern
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
	PlatinenVersion = 21;
#else
	if(PINB & 0x01)
     {
      if(PINB & 0x02) PlatinenVersion = 13;
       else           PlatinenVersion = 11;
     }
    else
     {
      if(PINB & 0x02) PlatinenVersion = 20;
       else           PlatinenVersion = 10;
     }
#endif
    DDRC  = 0x81; // SCL
    DDRC  |=0x40; // HEF4017 Reset
    PORTC = 0xff; // Pullup SDA
    DDRB  = 0x1B; // LEDs und Druckoffset
    PORTB = 0x01; // LED_Rot
    DDRD  = 0x3E; // Speaker & TXD & J3 J4 J5
	PORTD = 0x47; // LED
    HEF4017R_ON;
    MCUSR &=~(1<<WDRF);
    WDTCSR |= (1<<WDCE)|(1<<WDE);
    WDTCSR = 0;

    beeptime = 2500;
	StickGier = 0; PPM_in[K_GAS] = 0; StickRoll = 0; StickNick = 0;
    if(PlatinenVersion >= 20)  GIER_GRAD_FAKTOR = 1220; else GIER_GRAD_FAKTOR = 1291; // unterschiedlich für ME und ENC
    ROT_OFF;

    Timer_Init();
	TIMER2_Init();
	UART_Init();
    rc_sum_init();
   	ADC_Init();
	I2C_Init(1);
	SPI_MasterInit();
	Capacity_Init();
	LIBFC_Init();
	GRN_ON;
    sei();
	ParamSet_Init();


// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Check connected BL-Ctrls
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// Check connected BL-Ctrls
	BLFlags |= BLFLAG_READ_VERSION;
	motor_read = 0;  // read the first I2C-Data
	SendMotorData();
	timer = SetDelay(500);
	while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer

    printf("\n\rFound BL-Ctrl: ");
    timer = SetDelay(4000);
	for(i=0; i < MAX_MOTORS; i++)
	{
		SendMotorData();
		while(!(BLFlags & BLFLAG_TX_COMPLETE)  && !CheckDelay(timer)); //wait for complete transfer
		if(Mixer.Motor[i][0] > 0) // wait max 4 sec for the BL-Ctrls to wake up
		{
			while(!CheckDelay(timer) && !(Motor[i].State & MOTOR_STATE_PRESENT_MASK) )
			{
				SendMotorData();
				while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
			}
		}
		if(Motor[i].State & MOTOR_STATE_PRESENT_MASK)
		{
			printf("%d",i+1);
			FoundMotors++;
//			if(Motor[i].Version & MOTOR_STATE_NEW_PROTOCOL_MASK) printf("(new) ");
		}
	}
	for(i=0; i < MAX_MOTORS; i++)
	{
		if(!(Motor[i].State & MOTOR_STATE_PRESENT_MASK) && Mixer.Motor[i][0] > 0)
		{
			printf("\n\r\n\r!! MISSING BL-CTRL: %d !!",i+1);
			ServoActive = 2; // just in case the FC would be used as camera-stabilizer
		}
		Motor[i].State &= ~MOTOR_STATE_ERROR_MASK; // clear error counter
	}
 	printf("\n\r===================================");

    if(RequiredMotors < FoundMotors) VersionInfo.HardwareError[1] |= FC_ERROR1_MIXER;

	//if(EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)
	{
		printf("\n\rCalibrating pressure sensor..");
		timer = SetDelay(1000);
		SucheLuftruckOffset();
		while (!CheckDelay(timer));
		printf("OK\n\r");
	}

	SetNeutral(0);

	ROT_OFF;

    beeptime = 2000;
    ExternControl.Digital[0] = 0x55;


	FlugMinuten = (unsigned int)GetParamByte(PID_FLIGHT_MINUTES) * 256 + (unsigned int)GetParamByte(PID_FLIGHT_MINUTES + 1);
	FlugMinutenGesamt = (unsigned int)GetParamByte(PID_FLIGHT_MINUTES_TOTAL) * 256 + (unsigned int)GetParamByte(PID_FLIGHT_MINUTES_TOTAL + 1);

	if((FlugMinutenGesamt == 0xFFFF) || (FlugMinuten == 0xFFFF))
	{
		FlugMinuten = 0;
		FlugMinutenGesamt = 0;
	}
    printf("\n\rFlight-time %u min  Total:%u min", FlugMinuten, FlugMinutenGesamt);

	printf("\n\rControl: ");
	if (EE_Parameter.GlobalConfig & CFG_HEADING_HOLD) printf("HeadingHold");
	else printf("Normal (ACC-Mode)");

    LcdClear();
    I2CTimeout = 5000;
    WinkelOut.Orientation = 1;
    LipoDetection(1);

	LIBFC_ReceiverInit(EE_Parameter.Receiver);

	printf("\n\r===================================\n\r");
	//SpektrumBinding();
    timer = SetDelay(2000);
	timerPolling = SetDelay(250);

	Debug(ANSI_CLEAR "FC-Start!\n\rFlugzeit: %d min", FlugMinutenGesamt);  	// Note: this won't waste flash memory, if #DEBUG is not active
    DebugOut.Status[0] = 0x01 | 0x02;
	JetiBeep = 0;
	while (1)
	{
	
	if (JetiUpdateModeActive) while (1);
	
	if(CheckDelay(timerPolling))
	{
	  timerPolling = SetDelay(100);
	  LIBFC_Polling();
	}
	if(UpdateMotor && AdReady)      // ReglerIntervall
            {
  		    UpdateMotor=0;
            if(WinkelOut.CalcState) CalMk3Mag();
            else  MotorRegler();
			SendMotorData();
            ROT_OFF;
            if(SenderOkay)  { SenderOkay--; VersionInfo.HardwareError[1] &= ~FC_ERROR1_PPM; }
			else
			{
				TIMSK1 |= _BV(ICIE1); // enable PPM-Input
				PPM_in[0] = 0; // set RSSI to zero on data timeout
				VersionInfo.HardwareError[1] |= FC_ERROR1_PPM;
			}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//if(HoehenReglerAktiv && NaviDataOkay && SenderOkay < 160 && SenderOkay > 10 && FromNaviCtrl_Value.SerialDataOkay > 220) SenderOkay = 160;
//if(HoehenReglerAktiv && NaviDataOkay && SenderOkay < 101 && SenderOkay > 10 && FromNaviCtrl_Value.SerialDataOkay > 1) SenderOkay = 101;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            if(!--I2CTimeout || MissingMotor)
                {
                  if(!I2CTimeout)
				   {
				    I2C_Reset();
                    I2CTimeout = 5;
					DebugOut.Analog[28]++; // I2C-Error
					VersionInfo.HardwareError[1] |= FC_ERROR1_I2C;
					DebugOut.Status[1] |= 0x02; // BL-Error-Status
  				   }
                  if((BeepMuster == 0xffff) && MotorenEin)
                   {
                    beeptime = 10000;
                    BeepMuster = 0x0080;
                   }
                }
            else
                {
                 ROT_OFF;
				 if(!beeptime)
				  {
				   VersionInfo.HardwareError[1] &= ~FC_ERROR1_I2C;
				  }
                }
          if(!UpdateMotor)
		   {
			if(CalculateServoSignals) CalculateServo();
			DatenUebertragung();
			BearbeiteRxDaten();
			if(CheckDelay(timer))
			{
				static unsigned char second;
				timer += 20; // 20 ms interval
				if(MissingMotor)
				 {
				  VersionInfo.HardwareError[1] |= FC_ERROR1_BL_MISSING;
				  DebugOut.Status[1] |= 0x02; // BL-Error-Status
				 }
				 else
				 {
				   VersionInfo.HardwareError[1] &= ~FC_ERROR1_BL_MISSING;
				   if(I2CTimeout > 6) DebugOut.Status[1] &= ~0x02; // BL-Error-Status
				 }

			    if(I2CTimeout > 6) VersionInfo.HardwareError[1] &= ~FC_ERROR1_I2C;

				if(PcZugriff) PcZugriff--;
				else
				{
					ExternControl.Config = 0;
					ExternStickNick = 0;
					ExternStickRoll = 0;
					ExternStickGier = 0;
					if(BeepMuster == 0xffff && SenderOkay == 0)
					{
						beeptime = 15000;
						BeepMuster = 0x0c00;
					}
				}
				if(NaviDataOkay > 200)
				{
					NaviDataOkay--;
					VersionInfo.HardwareError[1] &= ~FC_ERROR1_SPI_RX;
				}
				else
				{
					if(NC_Version.Compatible)
					 {
						VersionInfo.HardwareError[1] |= FC_ERROR1_SPI_RX;
                       if(BeepMuster == 0xffff && MotorenEin)
						{
							beeptime = 15000;
							BeepMuster = 0xA800;
						}
					 }
					GPS_Nick = 0;
					GPS_Roll = 0;
					//if(!beeptime)
                    FromNaviCtrl.CompassValue = -1;
                    NaviDataOkay = 0;
				}
			   if(UBat < BattLowVoltageWarning)
				{
					FC_StatusFlags |= FC_STATUS_LOWBAT;
					if(BeepMuster == 0xffff)
					{
						beeptime = 6000;
						BeepMuster = 0x0300;
					}
				}
				else if(!beeptime) FC_StatusFlags &= ~FC_STATUS_LOWBAT;

				SPI_StartTransmitPacket();
				SendSPI = 4;
				if(!MotorenEin) timer2 = 1450; // 0,5 Minuten aufrunden
				else
                if(++second == 49)
				 {
				   second = 0;
				   FlugSekunden++;
				 }
				if(++timer2 == 2930)  // eine Minute
				 {
				   timer2 = 0;
               	   FlugMinuten++;
	               FlugMinutenGesamt++;
                   SetParamByte(PID_FLIGHT_MINUTES,FlugMinuten / 256);
                   SetParamByte(PID_FLIGHT_MINUTES+1,FlugMinuten % 256);
                   SetParamByte(PID_FLIGHT_MINUTES_TOTAL,FlugMinutenGesamt / 256);
                   SetParamByte(PID_FLIGHT_MINUTES_TOTAL+1,FlugMinutenGesamt % 256);
				   timer = SetDelay(20); // falls "timer += 20;" mal nicht geht
	  		     }
			}
           LED_Update();
           Capacity_Update();
           } //else DebugOut.Analog[26]++;
          }
     if(!SendSPI) { SPI_TransmitByte(); }
    }
 return (1);
}