Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 2494 → Rev 2495

/I2C_Telemetry/trunk/GPS.c
48,7 → 48,7
// check for new GPS data
void GPS_Update(void)
{
/* static uint16_t GPS_Timeout = 0;
static uint16_t GPS_Timeout = 0;
static uint16_t beep_rythm = 0;
 
switch(GPSData.Status)
70,7 → 70,6
GPS_Timeout = SetDelay(GPS_TIMEOUT); // reset gps timeout
//Error &= ~ERROR_GPS_RX_TIMEOUT; // clear possible error
beep_rythm++;
 
// update data in the follow me message
if((GPSData.SatFix & SATFIX_3D) && (GPSData.NumOfSats >= GPS_MINSATS))
{
80,19 → 79,11
{
// GPS_ClearPosition(&(FollowMe.Position)); // clear followme position
}
 
// NC like sound on bad gps signals
if(FollowMe_active)
{
if(!(GPSData.Flags & FLAG_GPSFIXOK) && !(beep_rythm % 5)) BeepTime = 100;
else if ((GPSData.NumOfSats < GPS_MINSATS) && !(beep_rythm % 5)) BeepTime = 10;
}
 
// NC like sound on bad gps signals
GPSData.Status = PROCESSED; // set to processed unlocks the buffer for new data
break;
 
default:
GPSData.Status = INVALID;
break;
}*/
}
}
/I2C_Telemetry/trunk/analog.c
90,7 → 90,7
void SucheLuftruckOffset(void)
{
unsigned int off;
char txt[10];
// char txt[10];
ExpandBaro = 0;
CalcExpandBaroStep();
off = GetParamByte(PID_PRESSURE_OFFSET);
134,11 → 134,11
kanal = AD_U_MESS;
break;
case 1:
U_mess = (3 * U_mess + (100 * ADC) / 31) / 4; // 1K/10K @ Vref = 3V
U_mess = (3 * U_mess + (100 * ADC) / 310) / 4; // 1K/10K @ Vref = 3V
kanal = AD_U_BAT;
break;
case 2:
U_Bat = (3 * U_Bat + (100 * ADC) / 31) / 4; // 1K/10K @ Vref = 3V
U_Bat = (3 * U_Bat + (100 * ADC) / 310) / 4; // 1K/10K @ Vref = 3V
kanal = AD_RES4;
break;
case 3:
/I2C_Telemetry/trunk/capacity.c
94,8 → 94,8
{
unsigned short Current, SetSum; // max value will be 255 * 12 = 3060
static unsigned short SubCounter = 0;
static unsigned short CurrentOffset = 0;
static unsigned long SumCurrentOffset = 0;
// static unsigned short CurrentOffset = 0;
// static unsigned long SumCurrentOffset = 0;
unsigned char i, NumOfMotors, MinOfMaxPWM;
 
if(CheckDelay(update_timer))
102,7 → 102,7
{
update_timer += CAPACITY_UPDATE_INTERVAL; // do not use SetDelay to avoid timing leaks
// determine sum of all present BL currents and setpoints
Current = 0;
Current = FC_OFFSET_CURRENT;
SetSum = 0;
NumOfMotors = 0;
MinOfMaxPWM = 255;
116,12 → 116,13
Current += BL3_Current(i); // extended Current measurement -> 200 = 20A 201 = 21A 255 = 75A (20+55)
}
else Current += (unsigned int)(Motor[i].Current);
SetSum += (unsigned int)(Motor[i].SetPoint);
// SetSum += (unsigned int)(Motor[i].SetPoint);
if(Motor[i].MaxPWM < MinOfMaxPWM) MinOfMaxPWM = Motor[i].MaxPWM;
}
}
Capacity.MinOfMaxPWM = MinOfMaxPWM;
 
if(Current > 10) Current += NumOfMotors * BL_OFFSET_CURRENT;
/*
if(SetSum == 0) // if all setpoints are 0
{ // determine offsets of motor currents
#define CURRENT_AVERAGE 8 // 8bit = 256 * 10 ms = 2.56s average time
138,7 → 139,7
// add the FC and BL Offsets
Current += FC_OFFSET_CURRENT + NumOfMotors * BL_OFFSET_CURRENT;
}
 
*/
// update actual Current
Capacity.ActualCurrent = Current;
// update actual Power
/I2C_Telemetry/trunk/fc.c
174,10 → 174,11
//############################################################################
{
unsigned char i;
if(Capacity.ActualCurrent > 20) FC_StatusFlags |= FC_STATUS_MOTOR_RUN;
else FC_StatusFlags &= ~FC_STATUS_MOTOR_RUN;
 
if(!MotorenEin)
{
FC_StatusFlags &= ~(FC_STATUS_MOTOR_RUN | FC_STATUS_FLY);
FC_StatusFlags2 &= ~FC_STATUS2_WAIT_FOR_TAKEOFF;
for(i=0;i<MAX_MOTORS;i++)
{
if(!MotorTest_Active) MotorTest[i] = 0;
186,7 → 187,7
}
if(MotorTest_Active) MotorTest_Active--;
}
else FC_StatusFlags |= FC_STATUS_MOTOR_RUN;
// else FC_StatusFlags |= FC_STATUS_MOTOR_RUN;
 
if(I2C_TransferActive)
{
/I2C_Telemetry/trunk/hottmenu.c
344,6 → 344,8
 
case HOTT_GPS_PACKET_ID:
GPSPacket.Altitude = HoehenWert/100 + 500;
GPSPacket.Distance = Logged_GPX_Counter;
 
// GPSPacket.Distance = GPSInfo.HomeDistance/10; // macht die NC
// GPSPacket.Heading = GPSInfo.HomeBearing/2; // macht die NC
// GPSPacket.Speed = (GPSInfo.Speed * 36) / 10; // macht die NC
/I2C_Telemetry/trunk/logging.c
179,16 → 179,17
logging_active = 1;
appendtimer = SetDelay(APPEND_LOG_TIME_MS);
}
/*
else
{
if(CheckDelay(appendtimer)) logging_active = 1; // TODO
else logging_active = 0;
}
 
 
*/
if(logging_active)
{
if(CheckDelay(appendtimer)) logging_active = 0;
 
 
switch(logfilestate)
{
case LOGFILE_IDLE:
326,13 → 327,10
logging_active = 1;
appendtimer = SetDelay(APPEND_LOG_TIME_MS);
}
else
{
if(CheckDelay(appendtimer)) logging_active = 1; // TODO
}
 
if(logging_active || part)
{
if(CheckDelay(appendtimer)) logging_active = 0;
switch(logfilestate)
{
case LOGFILE_IDLE:
453,7 → 451,7
Logging_KML(0); // initialize
LogCfg.GPX_Interval = 0; //default
LogCfg.GPX_Interval = 500; //default
// Settings_GetParamValue(PID_GPX_LOGGING, (unsigned int*)&LogCfg.GPX_Interval); // overwrite by settings value
if(LogCfg.GPX_Interval != 0 && LogCfg.GPX_Interval < MIN_SD_INTERVAL_GPX) LogCfg.GPX_Interval = MIN_SD_INTERVAL_GPX;
Logging_GPX(0); // initialize
/I2C_Telemetry/trunk/main.c
52,7 → 52,7
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <util/delay.h>
#include "main.h"
unsigned char BoardRelease = 0;
unsigned char BoardRelease = 0, RequiredMotors = 4;
unsigned int Receiver;
unsigned char DisableRcOffBeeping = 0;
unsigned int BattLowVoltageWarning = 94;
102,13 → 102,13
 
void LipoDetection(unsigned char print)
{
#define MAX_CELL_VOLTAGE 430 // max cell volatage for LiPO
#define MIN_CELL_VOLTAGE 330 // max cell volatage for LiPO
#define MAX_CELL_VOLTAGE 43 // max cell volatage for LiPO
#define MIN_CELL_VOLTAGE 33 // max cell volatage for LiPO
unsigned int timer, cells;
 
timer = SetDelay(500);
if(print) while (!CheckDelay(timer));
if(print) printf("\n\rBatt: %d.%02dV", U_Bat/100, U_Bat%100);
if(print) printf("\n\rBatt: %d.%dV", U_Bat/10, U_Bat%10);
// up to 6s LiPo, less than 2s is technical impossible
for(cells = 2; cells < 7; cells++)
{
122,7 → 122,7
printf(" %d Cells ", cells);
}
 
if(print) printf(" Low warning: %d.%02dV",BattLowVoltageWarning/100, BattLowVoltageWarning%100);
if(print) printf(" Low warning: %d.%dV",BattLowVoltageWarning/10, BattLowVoltageWarning%10);
}
 
 
192,7 → 192,7
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
 
printf("\n\rDetected BL-Ctrl: ");
timer = SetDelay(4000);
timer = SetDelay(2000);
 
timer1000ms = SetDelay(1000);
 
200,11 → 200,9
{
SendMotorData();
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
 
while(!CheckDelay(timer) && !(Motor[i].State & MOTOR_STATE_PRESENT_MASK) )
{
SendMotorData();
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
if((BLFlags & BLFLAG_TX_COMPLETE)) SendMotorData();
}
if(Motor[i].State & MOTOR_STATE_PRESENT_MASK)
{
218,18 → 216,17
{
if(!(Motor[i].State & MOTOR_STATE_PRESENT_MASK))
{
printf("\n\rNot detected BL-Ctrl: %d",i+1);
// printf("\n\rNot detected BL-Ctrl: %d",i+1);
}
Motor[i].State &= ~MOTOR_STATE_ERROR_MASK; // clear error counter
}
PrintLine();// ("\n\r===================================");
 
// no mixer table here!
RequiredMotors = FoundMotors;
 
printf("\n\rRequired Motors: %d",RequiredMotors);
if(RequiredMotors < FoundMotors) UART_VersionInfo.HardwareError[1] |= FC_ERROR1_MIXER;
PrintLine();
 
 
Fat16_Init();
// initialize the settings
Settings_Init();
238,8 → 235,6
// initialize logging (needs settings)
Logging_Init();
 
 
 
printf("\n\rCalibrating pressure sensor..");
timer = SetDelay(1000);
SucheLuftruckOffset();
253,8 → 248,6
 
beeptime = 2000;
 
 
 
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);
 
277,7 → 270,7
 
DebugOut.Status[0] = 0x01 | 0x02;
JetiBeep = 0;
DisableRcOffBeeping = 0;
DisableRcOffBeeping = 1;
 
EEAR = EE_DUMMY; // Set the EEPROM Address pointer to an unused space
 
304,9 → 297,9
sei();
 
MotorRegler();
GPS_Update();
// FC_StatusFlags |= FC_STATUS_FLY;
 
FC_StatusFlags |= FC_STATUS_FLY;
 
SendMotorData();
RED_OFF;
if(SenderOkay)
421,7 → 414,7
{
second = 0;
if(ShowSettingNameTime) ShowSettingNameTime--;
if(FC_StatusFlags & FC_STATUS_FLY) FlugSekunden++;
if(FC_StatusFlags & FC_STATUS_MOTOR_RUN) FlugSekunden++;
else timer2 = 1450; // 0,5 Minuten aufrunden
 
if(modell_fliegt < 1024)
450,4 → 443,4
} // EOF if(UpdateMotor && AdReady) ca. 488Hz
} //EOF while(1)
}
 
//DebugOut.Analog[]
/I2C_Telemetry/trunk/main.h
34,7 → 34,7
#define RECEIVER_UNKNOWN 0xFF
extern unsigned int Receiver;
 
extern unsigned char BoardRelease;
extern unsigned char BoardRelease,RequiredMotors;
extern unsigned char FoundMotors, DisableRcOffBeeping;
extern unsigned char JetiBeep;
void LipoDetection(unsigned char print);
/I2C_Telemetry/trunk/menu.c
161,7 → 161,12
for(i=1;i<9;i+=2) LCD_printfxy(0,i/2,"K%i:%4i K%i:%4i ",i,PPM_in[i],i+1,PPM_in[i+1]);
break;
case 4:
 
LCD_printfxy(0,0,"BL MaxPWM " );
for(i=0;i<3;i++)
{
LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",Motor[i*4].MaxPWM,Motor[i*4+1].MaxPWM,Motor[i*4+2].MaxPWM,Motor[i*4+3].MaxPWM);
if(4 + i * 4 >= RequiredMotors) break;
}
break;
 
case 5:
192,7 → 197,7
}
break;
case 7:
LCD_printfxy(0,0,"Voltage: %3i.%02iV",U_Bat/100, U_Bat%100);
LCD_printfxy(0,0,"Voltage: %3i.%1iV",U_Bat/10, U_Bat%10);
LCD_printfxy(0,1,"Current: %3i.%1iA",Capacity.ActualCurrent/10, Capacity.ActualCurrent%10);
LCD_printfxy(0,2,"Power: %4iW",Capacity.ActualPower);
LCD_printfxy(0,3,"Discharge:%5imAh", Capacity.UsedCapacity);
/I2C_Telemetry/trunk/twimaster.c
4,7 → 4,7
// + Software Nutzungsbedingungen (english version: see below)
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15,7 → 15,7
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand
// + des Mitverschuldens offen.
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
29,7 → 29,7
// + Software LICENSING TERMS
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
// + The Software may only be used with the Licensor's products.
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
60,21 → 60,23
#include "analog.h"
#include "uart.h"
#include "timer0.h"
#include "main.h"
 
volatile uint8_t twi_state = TWI_STATE_MOTOR_TX;
volatile uint8_t twi_state = TWI_STATE_MOTOR_TX, ReadBlSize = 9;
volatile uint8_t dac_channel = 0;
volatile uint8_t motor_write = 0;
volatile uint8_t motor_read = 0;
volatile uint8_t I2C_TransferActive = 0;
uint8_t Max_I2C_Packets = 12;
 
volatile uint16_t I2CTimeout = 100;
 
uint8_t MissingMotor = 0;
unsigned char RequiredMotors = 12;
 
volatile uint8_t BLFlags = 0;
 
MotorData_t Motor[MAX_MOTORS];
RedundantBl_t RedundantMotor[MAX_MOTORS];
 
// bit mask for witch BL the configuration should be sent
volatile uint16_t BLConfig_WriteMask = 0;
121,14 → 123,21
 
if(clear) for(i=0; i < MAX_MOTORS; i++)
{
Motor[i].Version = 0;
Motor[i].SetPoint = 0;
Motor[i].Version = 0;
Motor[i].SetPoint = 0;
Motor[i].SetPointLowerBits = 0;
Motor[i].State = 0;
Motor[i].ReadMode = BL_READMODE_STATUS;
Motor[i].Current = 0;
Motor[i].MaxPWM = 0;
Motor[i].Temperature = 0;
Motor[i].State = 0;
Motor[i].ReadMode = BL_READMODE_STATUS;
Motor[i].Current = 0;
Motor[i].MaxPWM = 0;
Motor[i].Temperature = 0;
Motor[i].NotReadyCnt = 0;
Motor[i].RPM = 0;
Motor[i].reserved1 = 0;
Motor[i].Voltage = 0;
Motor[i].SlaveI2cError = 0;
Motor[i].VersionMajor = 0;
Motor[i].VersionMinor = 0;
}
sei();
SREG = sreg;
158,7 → 167,7
static uint8_t missing_motor = 0, motor_read_temperature = 0;
static uint8_t *pBuff = 0;
static uint8_t BuffLen = 0;
 
static uint8_t max_packets = 0;
switch (twi_state++)
{
// Master Transmit
165,12 → 174,14
case 0: // TWI_STATE_MOTOR_TX
I2C_TransferActive = 1;
// skip motor if not used in mixer
// here we have no mixer table
// while((Mixer.Motor[motor_write][MIX_GAS] <= 0) && (motor_write < MAX_MOTORS))
while((motor_write >= RequiredMotors) && (motor_write < MAX_MOTORS)) motor_write++;
if(motor_write >= MAX_MOTORS) // writing finished, read now
motor_write %= MAX_MOTORS;
if(++max_packets > Max_I2C_Packets) // writing finished, read now
{
max_packets = 0;
BLConfig_WriteMask = 0; // reset configuration bitmask
motor_write = 0; // reset motor write counter for next cycle
//motor_write = 0; // reset motor write counter for next cycle
twi_state = TWI_STATE_MOTOR_RX;
I2C_WriteByte(TWI_BASE_ADDRESS + TW_READ + (motor_read<<1) ); // select slave address in rx mode
}
184,7 → 195,7
twi_state = 4; //jump over sending more data
}
// the new version has been detected
else if(!( (Motor[motor_write].SetPointLowerBits && (RequiredMotors < 7)) || BLConfig_WriteMask || BLConfig_ReadMask ) )
else if(!(/* (Motor[motor_write].SetPointLowerBits && (RequiredMotors < 7)) ||*/ BLConfig_WriteMask || BLConfig_ReadMask ) )
{ // or LowerBits are zero and no BlConfig should be sent (saves round trip time)
twi_state = 4; //jump over sending more data
}
248,6 → 259,7
}
else
{ // motor successfully addressed
DebugOut.Analog[30]++;
Motor[motor_read].State |= MOTOR_STATE_PRESENT_MASK; // set present bit
if(Motor[motor_read].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)
{
261,7 → 273,7
break;
case BL_READMODE_STATUS:
pBuff = (uint8_t*)&(Motor[motor_read].Current);
if(motor_read == motor_read_temperature) BuffLen = 3; // read Current, MaxPwm & Temp
if(motor_read == motor_read_temperature) BuffLen = ReadBlSize; // read Current, MaxPwm & Temp (is 3 or 9)
else BuffLen = 1;// read Current only
break;
}
286,7 → 298,7
break;
case 6: // receive bytes
*pBuff = TWDR;
pBuff++;
pBuff++; // set Pointer to next element : Motor[].Current,Motor[].Temperature
BuffLen--;
if(BuffLen>1)
{
296,21 → 308,34
{
I2C_ReceiveLastByte(); // read last byte
}
else // nothing left
else // nothing left -> ready
{
if(BLFlags & BLFLAG_READ_VERSION)
{
// if(!(FC_StatusFlags & FC_STATUS_MOTOR_RUN) && ((Motor[motor_read].MaxPWM & 252) == 248)) Motor[motor_read].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK;
// else Motor[motor_read].Version = 0;
if(!(FC_StatusFlags & FC_STATUS_MOTOR_RUN))
{
{
if((Motor[motor_read].MaxPWM & 252) == 248) Motor[motor_read].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK;
else Motor[motor_read].Version = 0;
if(Motor[motor_read].MaxPWM == 248) Motor[motor_read].Version |= (MOTOR_STATE_FAST_MODE | MOTOR_STATE_BL30);
else
if(Motor[motor_read].MaxPWM == 249) Motor[motor_read].Version |= MOTOR_STATE_BL30;
}
}
}
 
if(FC_StatusFlags & FC_STATUS_FLY)
{
// Starting -> 40
// I2C-Setpoint is zero -> 250
// 255 -> Running and no Redundancy
// 254 -> Running and active Redundancy
if(Motor[motor_read].MaxPWM < 254)
{
Motor[motor_read].NotReadyCnt++;
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__))
SpeakHoTT = SPEAK_ERR_MOTOR;
#endif
}
}
if(++motor_read >= MAX_MOTORS)
{
motor_read = 0; // restart from beginning
328,7 → 353,7
}
twi_state = 6; // if there are some bytes left
break;
 
/*
// writing Gyro-Offsets
case 18:
I2C_WriteByte(0x98); // Address the DAC
339,12 → 364,41
break;
 
case 20:
switch(dac_channel)
{
case 0:
I2C_WriteByte(AnalogOffsetNick); // 1st byte for Channel A
break;
case 1:
I2C_WriteByte(AnalogOffsetRoll); // 1st byte for Channel B
break;
case 2:
I2C_WriteByte(AnalogOffsetGier); // 1st byte for Channel C
break;
}
break;
 
case 21:
I2C_WriteByte(0x80); // 2nd byte for all channels is 0x80
break;
 
case 22:
I2C_Stop(TWI_STATE_MOTOR_TX);
I2C_TransferActive = 0;
I2CTimeout = 10;
BLFlags |= BLFLAG_TX_COMPLETE;
 
// repeat case 18...22 until all DAC Channels are updated
if(dac_channel < 2)
{
dac_channel ++; // jump to next channel
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // start transmission for next channel
}
else
{
dac_channel = 0; // reset dac channel counter
BLFlags |= BLFLAG_TX_COMPLETE;
}
break;
*/
default:
I2C_Stop(TWI_STATE_MOTOR_TX);
BLFlags |= BLFLAG_TX_COMPLETE;
369,11 → 423,11
return crc;
}
 
 
uint8_t I2C_WriteBLConfig(uint8_t motor)
{
uint8_t i;
uint8_t i, packets;
uint16_t timer;
 
if(MotorenEin || MotorTest_Active) return(BLCONFIG_ERR_MOTOR_RUNNING); // not when motors are running!
if(motor > MAX_MOTORS) return (BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist!
if(motor)
386,34 → 440,27
i = RAM_Checksum((uint8_t*)&BLConfig, sizeof(BLConfig_t) - 1);
if(i != BLConfig.crc) return(BLCONFIG_ERR_CHECKSUM); // bad checksum
 
timer = SetDelay(2000);
packets = Max_I2C_Packets;
Max_I2C_Packets = 12;
I2CTimeout = 100;
 
timer = SetDelay(100);
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
 
// prepare the bitmask
if(!motor) // 0 means all
{
BLConfig_WriteMask = 0xFF; // all motors at once with the same configuration
}
else //only one specific motor
{
BLConfig_WriteMask = 0x0001<<(motor-1);
}
for(i = 0; i < MAX_MOTORS; i++)
{
if((0x0001<<i) & BLConfig_WriteMask)
{
Motor[i].SetPoint = 0;
Motor[i].SetPointLowerBits = 0;
}
}
if(!motor) BLConfig_WriteMask = 0x0FFF; // 0 means all -> all motors at once with the same configuration
else BLConfig_WriteMask = 0x0001<<(motor-1); //only one specific motor
 
motor_write = 0;
motor_read = 0;
// needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms)
timer = SetDelay(1000);
do
{
I2C_Start(TWI_STATE_MOTOR_TX); // start an i2c transmission
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
}while(BLConfig_WriteMask && !CheckDelay(timer)); // repeat until the BL config has been sent
} while(BLConfig_WriteMask && !CheckDelay(timer)); // repeat until the BL config has been sent
Max_I2C_Packets = packets;
if(BLConfig_WriteMask) return(BLCONFIG_ERR_MOTOR_NOT_EXIST);
return(BLCONFIG_SUCCESS);
}
429,22 → 476,14
if(!(Motor[motor-1].State & MOTOR_STATE_PRESENT_MASK)) return(BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist!
if(!(Motor[motor-1].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)) return(BLCONFIG_ERR_HW_NOT_COMPATIBLE); // not a new BL!
 
timer = SetDelay(2000);
timer = SetDelay(1000);
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
 
// prepare the bitmask
BLConfig_ReadMask = 0x0001<<(motor-1);
 
for(i = 0; i < MAX_MOTORS; i++)
{
if((0x0001<<i) & BLConfig_ReadMask)
{
Motor[i].SetPoint = 0;
Motor[i].SetPointLowerBits = 0;
}
}
 
motor_read = 0;
motor_write = 0;
motor_read = 0;
BLConfig.Revision = 0; // bad revision
BLConfig.crc = 0; // bad checksum
// needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms)
452,7 → 491,7
{
I2C_Start(TWI_STATE_MOTOR_TX); // start an i2c transmission
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer
}while(BLConfig_ReadMask && !CheckDelay(timer)); // repeat until the BL config has been received from all motors
} while(BLConfig_ReadMask && !CheckDelay(timer)); // repeat until the BL config has been received from all motors
// validate result
if((BLConfig.Revision & 0x0B) != BLCONFIG_REVISION) return (BLCONFIG_ERR_SW_NOT_COMPATIBLE); // bad revison
i = RAM_Checksum((uint8_t*)&BLConfig, sizeof(BLConfig_t) - 1);
/I2C_Telemetry/trunk/twimaster.h
6,14 → 6,14
 
#define TWI_STATE_MOTOR_TX 0
#define TWI_STATE_MOTOR_RX 5
//#define TWI_STATE_GYRO_OFFSET_TX 18
 
extern volatile uint8_t twi_state;
extern volatile uint8_t twi_state, ReadBlSize;
extern volatile uint8_t motor_write;
extern volatile uint8_t motor_read;
extern volatile uint8_t I2C_TransferActive;
 
extern uint8_t Max_I2C_Packets;
extern uint8_t MissingMotor;
unsigned char RequiredMotors;
 
#define MAX_MOTORS 12
#define MOTOR_STATE_PRESENT_MASK 0x80
42,11 → 42,35
// the following bytes must be exactly in that order!
uint8_t Current; // in 0.1 A steps, read back from BL
uint8_t MaxPWM; // read back from BL -> is less than 255 if BL is in current limit, not running (250) or starting (40)
int8_t Temperature; // old BL-Ctrl will return a 255 here, the new version the temp. in °C
uint8_t Temperature; // old BL-Ctrl will return a 255 here, the new version the temp. in °C
uint8_t RPM; // Raw value for RPM
uint8_t reserved1; // Voltage (BL3) or mAh (BL2)
uint8_t Voltage; // in 0.1V (BL3 is limited to 255, BL2 is only low-byte)
uint8_t SlaveI2cError; // BL2 & BL3
uint8_t VersionMajor; // BL2 & BL3
uint8_t VersionMinor; // BL2 & BL3
uint8_t NotReadyCnt; // Counts up is the Motor is not ready during flight -> MotorRestart etc.
} __attribute__((packed)) MotorData_t;
 
extern MotorData_t Motor[MAX_MOTORS];
 
// BitSate
#define BL_BIT_STATE_I2C_OK 0x01
#define BL_BIT_STATE_I2C_VALUE 0x02
#define BL_BIT_STATE_I2C_BAD 0x04
#define BL_BIT_STATE_PPM_OK 0x08
#define BL_BIT_STATE_MOTOR_RUN 0x10
 
typedef struct
{
unsigned char BitSate;
unsigned char Current;
unsigned char State;
unsigned char TemperatureInDeg;
unsigned char Voltage80;
} __attribute__((packed)) RedundantBl_t;
extern RedundantBl_t RedundantMotor[MAX_MOTORS];
 
#define BLCONFIG_REVISION 2
 
#define MASK_SET_PWM_SCALING 0x01
/I2C_Telemetry/trunk/uart.c
155,7 → 155,7
"27 ",
"I2C-Error ",
"BL Limit ",
"30 ", //30
"I2C-Okay ", //30
"31 "
};
 
/I2C_Telemetry/trunk/ubx.h
21,6 → 21,7
#define INVALID 0x00
#define NEWDATA 0x01
#define PROCESSED 0x02
#define UPDATE 0x04
 
// message sync bytes
#define UBX_SYNC1_CHAR 0xB5