Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 1658 → Rev 1659

/beta/Code Redesign killagreg/eeprom.c
76,7 → 76,6
paramset_t ParamSet;
MixerTable_t Mixer;
uint8_t RequiredMotors = 0;
BLConfig_t BLConfig[MAX_MOTORS];
 
 
uint8_t RAM_Checksum(uint8_t* pBuffer, uint16_t len)
594,66 → 593,8
Mixer.crc = RAM_Checksum((uint8_t*)(&Mixer), sizeof(Mixer) - 1);
}
 
/***************************************************/
/* Read BL-Config from EEPROM */
/***************************************************/
uint8_t BLConfig_ReadFromEEProm(uint8_t index)
{
uint8_t crc;
uint16_t eeadr = EEPROM_ADR_BLCONFIG + (uint16_t)index * sizeof(BLConfig_t);
// calculate checksum in eeprom
crc = EEProm_Checksum(eeadr, sizeof(BLConfig_t) - 1);
 
// check crc
if( crc != eeprom_read_byte((uint8_t*)(eeadr + sizeof(BLConfig_t) - 1)) ) return 0;
 
// check revision
if(eeprom_read_byte((uint8_t*)(eeadr)) != EEBLCONFIG_REVISON) return 0;
 
// read mixer BLConfig
eeprom_read_block((void *)&(BLConfig[index]), (void*)(eeadr), sizeof(BLConfig_t));
return 1;
}
 
/***************************************************/
/* Write BL-Config to EEPROM */
/***************************************************/
uint8_t BLConfig_WriteToEEProm(uint8_t index)
{
uint16_t eeadr = EEPROM_ADR_BLCONFIG + (uint16_t)index * sizeof(BLConfig_t);
if(index >= MAX_MOTORS) return 0;
if(BLConfig[index].Revision == EEBLCONFIG_REVISON)
{
// update crc
BLConfig[index].crc = RAM_Checksum((uint8_t*)(&(BLConfig[index])), sizeof(BLConfig_t) - 1);
 
// write to eeprom
eeprom_write_block((void *) &(BLConfig[index]), (void*)(eeadr), sizeof(BLConfig_t));
return 1;
}
else return 0;
}
 
/***************************************************/
/* Default BLConfig */
/***************************************************/
void BLConfig_SetDefault(uint8_t index)
{
if(index < MAX_MOTORS)
{
BLConfig[index].Revision = EEBLCONFIG_REVISON; // set revision
BLConfig[index].SetMask = MASK_SET_PWM_SCALING|MASK_SET_CURRENT_LIMIT|MASK_SET_TEMP_LIMIT|MASK_SET_CURRENT_SCALING|MASK_SET_BITCONFIG;
BLConfig[index].PwmScaling = 255; // MaxPWM
BLConfig[index].CurrentLimit = 30; // Current Limit in A
BLConfig[index].TempLimit = 99; // Temperature Limit in °C
BLConfig[index].CurrentScaling = 64; // Current Scaling
BLConfig[index].BitConfig = 0; // BitConfig
BLConfig[index].crc = RAM_Checksum((uint8_t*)&(BLConfig[index]), sizeof(BLConfig_t) - 1); // update checksum
}
}
 
 
/***************************************************/
/* Get active parameter set */
/***************************************************/
uint8_t GetActiveParamSet(void)
745,18 → 686,6
ParamSet_ReadFromEEProm(i);
printf("\n\rUsing Parameter Set %d", i);
 
 
// load all BLConfig's
for(i=0; i<MAX_MOTORS; i++)
{
if(ee_default || !BLConfig_ReadFromEEProm(i)) // could not read BLConfig from eeprom
{
printf("\n\rGenerating default BL-Config for motor %d", i+1);
BLConfig_SetDefault(i);
BLConfig_WriteToEEProm(i);
}
}
 
// load mixer table
if(ee_default || !MixerTable_ReadFromEEProm() )
{
/beta/Code Redesign killagreg/eeprom.h
19,7 → 19,6
#define EEPROM_ADR_CHANNELS 80 // 80 - 93, 12 bytes + 1 byte crc
#define EEPROM_ADR_PARAMSET 100 // 100 - 650, 5 * 110 bytes
#define EEPROM_ADR_MIXERTABLE 1000 // 1000 - 1078, 78 bytes
#define EEPROM_ADR_BLCONFIG 1200 // 1200 - 1296, 12 * 8 bytes
 
 
#define MIX_GAS 0
38,39 → 37,6
extern MixerTable_t Mixer;
extern uint8_t RequiredMotors;
 
#define MASK_SET_PWM_SCALING 0x01
#define MASK_SET_CURRENT_LIMIT 0x02
#define MASK_SET_TEMP_LIMIT 0x04
#define MASK_SET_CURRENT_SCALING 0x08
#define MASK_SET_BITCONFIG 0x10
#define MASK_RESET_CAPCOUNTER 0x20
#define MASK_SET_DEFAULT_PARAMS 0x40
#define MASK_SET_SAVE_EEPROM 0x80
 
#define BITCONF_REVERSE_ROTATION 0x01
#define BITCONF_RES1 0x02
#define BITCONF_RES2 0x04
#define BITCONF_RES3 0x08
#define BITCONF_RES4 0x10
#define BITCONF_RES5 0x20
#define BITCONF_RES6 0x40
#define BITCONF_RES7 0x80
 
typedef struct
{
uint8_t Revision; // must be BL_REVISION
uint8_t SetMask; // settings mask
uint8_t PwmScaling; // maximum value of control pwm, acts like a thrust limit
uint8_t CurrentLimit; // current limit in A
uint8_t TempLimit; // in °C
uint8_t CurrentScaling; // scaling factor for current measurement
uint8_t BitConfig; // see defines above
uint8_t crc; // checksum
} __attribute__((packed)) BLConfig_t;
 
extern BLConfig_t BLConfig[MAX_MOTORS];
 
 
// bit mask for ParamSet.Config0
#define CFG0_AIRPRESS_SENSOR 0x01
#define CFG0_HEIGHT_SWITCH 0x02
126,7 → 92,7
 
#define EEPARAM_REVISION 82 // is count up, if paramater stucture has changed (compatibility)
#define EEMIXER_REVISION 1 // is count up, if mixer stucture has changed (compatibility)
#define EEBLCONFIG_REVISON '#'
#define EEBLCONFIG_REVISON 35 // is count up, if blconfig stucture has changed (compatibility to BLs!)
 
// values above 247 representing poti1 to poti8
// poti1 = 255
/beta/Code Redesign killagreg/fc.c
235,8 → 235,6
 
ExpandBaro = 0;
 
I2C_SendBLConfig();
 
// sample values with bias set to zero
Delay_ms_Mess(100);
 
696,7 → 694,6
 
Mean();
GRN_ON;
DebugOut.Analog[16] = Calibration_Done;
 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// RC-signal is bad
/beta/Code Redesign killagreg/libfc1284.a
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/beta/Code Redesign killagreg/libfc644.a
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/beta/Code Redesign killagreg/spi.c
467,11 → 467,9
memcpy(ptr, (uint8_t *) SPI_RxBuffer, sizeof(FromNaviCtrl));
sei();
SPI_RxDataValid = 1;
//DebugOut.Analog[18]++;
}
else
{ // checksum does not match
//DebugOut.Analog[17]++;
SPI_RxDataValid = 0; // reset valid flag
}
SPI_RXState = SPI_SYNC1; // reset state sync
/beta/Code Redesign killagreg/twimaster.c
58,11 → 58,12
#include "fc.h"
#include "analog.h"
 
volatile uint8_t twi_state = TWI_STATE_MOTOR_TX;
volatile uint8_t twi_state = TWI_STATE_MOTOR_TX;
volatile uint8_t dac_channel = 0;
volatile uint8_t motor_write = 0;
volatile uint8_t motor_read = 0;
 
 
volatile uint16_t I2CTimeout = 100;
 
uint8_t MissingMotor = 0;
70,16 → 71,20
volatile uint8_t BLFlags = 0;
 
MotorData_t Motor[MAX_MOTORS];
BLConfig_t BLConfig[MAX_MOTORS];
 
#define I2C_WriteByte(byte) {TWDR = byte; TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);}
#define I2C_ReceiveByte() {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);}
#define I2C_ReceiveLastByte() {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);}
 
#define BL_CONF_SYNC_BYTE '#'
 
#define SCL_CLOCK 200000L
#define I2C_TIMEOUT 30000
#define TWI_BASE_ADDRESS 0x52
 
/**************************************************/
/* Initialize I2C (TWI) */
/**************************************************/
 
void I2C_Init(void)
{
uint8_t i;
117,90 → 122,10
SREG = sreg;
}
 
/****************************************/
/* Start I2C */
/****************************************/
/*
void I2C_Start(uint8_t start_state)
{
twi_state = start_state;
// TWI Control Register
// clear TWI interrupt flag (TWINT=1)
// disable TWI Acknowledge Bit (TWEA = 0)
// enable TWI START Condition Bit (TWSTA = 1), MASTER
// disable TWI STOP Condition Bit (TWSTO = 0)
// disable TWI Write Collision Flag (TWWC = 0)
// enable i2c (TWEN = 1)
// enable TWI Interrupt (TWIE = 1)
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
}
*/
 
/****************************************/
/* Stop I2C */
/****************************************/
/*void I2C_Stop(uint8_t start_state)
{
twi_state = start_state;
// TWI Control Register
// clear TWI interrupt flag (TWINT=1)
// disable TWI Acknowledge Bit (TWEA = 0)
// diable TWI START Condition Bit (TWSTA = 1), no MASTER
// enable TWI STOP Condition Bit (TWSTO = 1)
// disable TWI Write Collision Flag (TWWC = 0)
// enable i2c (TWEN = 1)
// disable TWI Interrupt (TWIE = 0)
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}*/
 
 
/****************************************/
/* Write to I2C */
/****************************************/
#define I2C_WriteByte(byte) {TWDR = byte; TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);}
/*
void I2C_WriteByte(int8_t byte)
{
// move byte to send into TWI Data Register
TWDR = byte;
// clear interrupt flag (TWINT = 1)
// enable i2c bus (TWEN = 1)
// enable interrupt (TWIE = 1)
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
}
*/
 
/****************************************/
/* Receive byte and send ACK */
/****************************************/
#define I2C_ReceiveByte() {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);}
/*
void I2C_ReceiveByte(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);
}
*/
 
/****************************************/
/* I2C receive last byte and send no ACK*/
/****************************************/
#define I2C_ReceiveLastByte() {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);}
/*
void I2C_ReceiveLastByte(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
}
*/
 
/****************************************/
/* Reset I2C */
/****************************************/
void I2C_Reset(void)
{
// stop i2c bus
I2C_Stop(TWI_STATE_MOTOR_TX);
twi_state = 0;
motor_write = TWDR;
motor_write = 0;
motor_read = 0;
TWCR = (1<<TWINT); // reset to original state incl. interrupt flag reset
210,7 → 135,8
TWSR = 0;
TWBR = 0;
I2C_Init();
I2C_Start(TWI_STATE_MOTOR_TX);
I2C_WriteByte(0);
BLFlags |= BLFLAG_READ_VERSION;
}
 
/****************************************/
218,13 → 144,19
/****************************************/
ISR (TWI_vect)
{
static uint8_t missing_motor = 0, byte_counter = 0, read_more = 0, motor_read_temperature = 0;
static uint8_t *pTxBuff;
static uint8_t missing_motor = 0, motor_read_temperature = 0;
static uint8_t *pBuff = 0;
static uint8_t BuffLen = 0;
 
switch (twi_state++) // First i2c_start from SendMotorData()
#define BL_READ_STATUS 0
#define BL_READ_CONFIG 16
static uint8_t BLReadMode = BL_READ_STATUS;
 
switch (twi_state++)
{
// Master Transmit
case 0: // TWI_STATE_MOTOR_TX
 
// skip motor if not used in mixer
while((Mixer.Motor[motor_write][MIX_GAS] <= 0) && (motor_write < MAX_MOTORS)) motor_write++;
if(motor_write >= MAX_MOTORS) // writing finished, read now
231,9 → 163,9
{
motor_write = 0; // reset motor write counter for next cycle
twi_state = TWI_STATE_MOTOR_RX;
I2C_WriteByte(0x53 + (motor_read * 2) ); // select slave address in rx mode
I2C_WriteByte(TWI_BASE_ADDRESS + TW_READ + (motor_read<<1) ); // select slave address in rx mode
}
else I2C_WriteByte(0x52 + (motor_write * 2) ); // select slave address in tx mode
else I2C_WriteByte(TWI_BASE_ADDRESS + TW_WRITE + (motor_write<<1) ); // select slave address in tx mode
break;
case 1: // Send Data to Slave
I2C_WriteByte(Motor[motor_write].SetPoint); // transmit setpoint
243,17 → 175,20
twi_state = 4; //jump over sending more data
}
// the new version has been detected
else if(!( (Motor[motor_write].SetPointLowerBits && (RequiredMotors < 7)) || (BLFlags & BLFLAG_SEND_CONFIG)) )
else if(!( (Motor[motor_write].SetPointLowerBits && (RequiredMotors < 7)) || (BLFlags & (BLFLAG_SET_CONFIG|BLFLAG_GET_CONFIG)) ) )
{ // or LowerBits are zero and no BlConfig should be sent (saves round trip time)
twi_state = 4; //jump over sending more data
}
break;
case 2: // lower bits of setpoint (higher resolution)
I2C_WriteByte((Motor[motor_write].SetPointLowerBits << 1) & 0x07); // send the lower bits of setpoint
if (BLFlags & BLFLAG_GET_CONFIG) BLReadMode = BL_READ_CONFIG;
else BLReadMode = BL_READ_STATUS;
I2C_WriteByte((BLReadMode<<3)|(Motor[motor_write].SetPointLowerBits & 0x07)); // send read mode and the lower bits of setpoint
// transmit config only on demand and the motors are not running and only for one motor per round trip
if( (BLFlags & BLFLAG_SEND_CONFIG) && (motor_write == motor_read))
if( (BLFlags & BLFLAG_SET_CONFIG) && (motor_write == motor_read))
{ // prepare sending of configuration
byte_counter = 0; // reset send byte counter
pBuff = (uint8_t*)(&BLConfig[motor_write]); // select config for motor
BuffLen = sizeof(BLConfig_t);
}
else
{ // jump to state for end of transmission for that motor
261,23 → 196,9
}
break;
case 3: // send configuration
if(!byte_counter) // first byte?
{
pTxBuff = (uint8_t*)&BLConfig[motor_write]; // select configuration for motor
I2C_WriteByte(pTxBuff[byte_counter]);
twi_state = 3;
}
else if(byte_counter >= sizeof(BLConfig_t))
{
I2C_WriteByte(0);
// continue in state 4
}
else // transmit configuration to BLs
{
I2C_WriteByte(pTxBuff[byte_counter]); // submit next byte
twi_state = 3; // stay in this state
}
byte_counter++; // next byte
I2C_WriteByte(*pBuff);
pBuff++;
if(--BuffLen > 0) twi_state = 3; // if there are some bytes left
break;
case 4: // repeat case 0-4 for all motors
if(TWSR == TW_MT_DATA_NACK) // Data transmitted, NACK received
292,13 → 213,14
break;
// Master Receive Data
case 5: // TWI_STATE_MOTOR_RX
if(TWSR != TW_MR_SLA_ACK) // SLA+R transmitted, if not ACK received
if(TWSR != TW_MR_SLA_ACK) // SLA+R transmitted but no ACK received
{ // no response from the addressed slave received
Motor[motor_read].State &= ~MOTOR_STATE_PRESENT_MASK; // clear present bit
if(++motor_read >= MAX_MOTORS)
{ // all motors read
motor_read = 0; // restart from beginning
BLFlags &= ~BLFLAG_SEND_CONFIG;
BLFlags &= ~(BLFLAG_GET_CONFIG|BLFLAG_SET_CONFIG);
BLReadMode = BL_READ_STATUS;
if(++motor_read_temperature >= MAX_MOTORS)
{
motor_read_temperature = 0;
311,33 → 233,66
else
{ // motor successfully addressed
Motor[motor_read].State |= MOTOR_STATE_PRESENT_MASK; // set present bit
// read cylclic more data
if((motor_read == motor_read_temperature) || (BLFlags & BLFLAG_READ_VERSION))
 
if(Motor[motor_read].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)
{
read_more = 1;
I2C_ReceiveByte(); // read next byte
// new BL found
switch(BLReadMode)
{
case BL_READ_CONFIG:
pBuff = (uint8_t*)&BLConfig[motor_read];
BuffLen = sizeof(BLConfig_t);
break;
 
case BL_READ_STATUS:
pBuff = (uint8_t*)&(Motor[motor_read].Current);
if(motor_read == motor_read_temperature) BuffLen = 3; // read Current, MaxPwm & Temp
else BuffLen = 1;// read Current only
break;
}
}
else // old BL version
{
pBuff = (uint8_t*)&(Motor[motor_read].Current);
if(BLFlags & BLFLAG_READ_VERSION) BuffLen = 2; // Current & MaxPwm
else BuffLen = 1; // read Current only
}
if(BuffLen == 1)
{
I2C_ReceiveLastByte(); // read last byte
}
else
{
read_more = 0;
I2C_ReceiveLastByte(); //read last byte
I2C_ReceiveByte(); // read next byte
}
}
MissingMotor = missing_motor;
missing_motor = 0;
break;
case 6: // 1st byte recieved
Motor[motor_read].Current = TWDR; // get Current
if(read_more)
case 6: // receive bytes
*pBuff = TWDR;
pBuff++;
BuffLen--;
if(BuffLen>1)
{
I2C_ReceiveByte(); // read 2nd byte
I2C_ReceiveByte(); // read next byte
}
else
else if (BuffLen == 1)
{
I2C_ReceiveLastByte(); // read last byte
}
else // nothing left
{
if(BLFlags & BLFLAG_READ_VERSION)
{
if(!(FCFlags & FCFLAG_MOTOR_RUN) && (Motor[motor_read].MaxPWM == 250) ) Motor[motor_read].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK;
else Motor[motor_read].Version = 0;
}
if(++motor_read >= MAX_MOTORS)
{
motor_read = 0; // restart from beginning
BLFlags &= ~BLFLAG_SEND_CONFIG;
BLFlags &= ~(BLFLAG_GET_CONFIG|BLFLAG_SET_CONFIG);
BLReadMode = BL_READ_STATUS;
if(++motor_read_temperature >= MAX_MOTORS)
{
motor_read_temperature = 0;
346,40 → 301,11
}
I2C_Stop(TWI_STATE_MOTOR_TX);
BLFlags |= BLFLAG_TX_COMPLETE;
return;
}
twi_state = 6; // if there are some bytes left
break;
case 7: // 2nd byte recieved
Motor[motor_read].MaxPWM = TWDR; // get MaxPWM
if(BLFlags & BLFLAG_READ_VERSION)
{
if(TWDR == 250)
{ // a new BL found
if(!(FCFlags & FCFLAG_MOTOR_RUN)) Motor[motor_read].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK;
}
else
{ // its not a new BL
Motor[motor_read].Version = 0;
}
}
I2C_ReceiveLastByte(); // nack
break;
 
case 8: // 3rd byte received
Motor[motor_read].Temperature = TWDR; // get Temperature
if(++motor_read >= MAX_MOTORS)
{
motor_read = 0; // restart reading of first motor
BLFlags &= ~BLFLAG_SEND_CONFIG;
if(++motor_read_temperature >= MAX_MOTORS)
{
motor_read_temperature = 0;
BLFlags &= ~BLFLAG_READ_VERSION;
}
}
I2C_Stop(TWI_STATE_MOTOR_TX);
BLFlags |= BLFLAG_TX_COMPLETE;
break;
 
// writing Gyro-Offsets
case 18:
I2C_WriteByte(0x98); // Address the DAC
431,16 → 357,16
motor_read = 0;
break;
}
 
}
 
 
void I2C_SendBLConfig(void)
uint8_t I2C_SetBLConfig(void)
{
uint8_t i;
 
if(FCFlags & FCFLAG_MOTOR_RUN) return; // not when motors are running!
if(FCFlags & FCFLAG_MOTOR_RUN) return(0); // not when motors are running!
while(!(BLFlags & BLFLAG_TX_COMPLETE)); //wait for complete transfer
BLFlags |= BLFLAG_SEND_CONFIG; // enable sending of BL config
for(i = 0; i < MAX_MOTORS; i++)
{
Motor[i].SetPoint = 0;
447,11 → 373,34
Motor[i].SetPointLowerBits = 0;
}
motor_read = 0;
BLFlags |= BLFLAG_SET_CONFIG; // enable sending of BL config
// needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms)
do
{
I2C_Start(TWI_STATE_MOTOR_TX); // start an i2c transmission
while(!(BLFlags & BLFLAG_TX_COMPLETE)); //wait for complete transfer
}while(BLFlags & BLFLAG_SEND_CONFIG); // repeat until the BL config has been send to all motors
}while(BLFlags & BLFLAG_SET_CONFIG); // repeat until the BL config has been send to all motors
return(1);
}
 
uint8_t I2C_GetBLConfig(void)
{
uint8_t i;
 
if(FCFlags & FCFLAG_MOTOR_RUN) return(0); // not when motors are running!
while(!(BLFlags & BLFLAG_TX_COMPLETE)); //wait for complete transfer
for(i = 0; i < MAX_MOTORS; i++)
{
Motor[i].SetPoint = 0;
Motor[i].SetPointLowerBits = 0;
}
motor_read = 0;
BLFlags |= BLFLAG_GET_CONFIG; // enable request of BL config
// needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms)
do
{
I2C_Start(TWI_STATE_MOTOR_TX); // start an i2c transmission
while(!(BLFlags & BLFLAG_TX_COMPLETE)); //wait for complete transfer
}while(BLFlags & BLFLAG_GET_CONFIG); // repeat until the BL config has been received from all motors
return(1);
}
/beta/Code Redesign killagreg/twimaster.h
21,9 → 21,10
 
#define MOTOR_STATE_NEW_PROTOCOL_MASK 0x01
 
#define BLFLAG_READ_VERSION 0x01
#define BLFLAG_SEND_CONFIG 0x02
#define BLFLAG_TX_COMPLETE 0x04
#define BLFLAG_TX_COMPLETE 0x01
#define BLFLAG_READ_VERSION 0x02
#define BLFLAG_SET_CONFIG 0x04
#define BLFLAG_GET_CONFIG 0x08
 
extern volatile uint8_t BLFlags;
 
33,6 → 34,7
uint8_t SetPoint; // written by attitude controller
uint8_t SetPointLowerBits; // for higher Resolution of new BLs
uint8_t State; // 7 bit for I2C error counter, highest bit indicates if motor is present
// 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
int8_t Temperature; // old BL-Ctrl will return a 255 here, the new version the temp. in °C
40,6 → 42,40
 
extern MotorData_t Motor[MAX_MOTORS];
 
#define BLCONFIG_REVISION 1
 
#define MASK_SET_PWM_SCALING 0x01
#define MASK_SET_CURRENT_LIMIT 0x02
#define MASK_SET_TEMP_LIMIT 0x04
#define MASK_SET_CURRENT_SCALING 0x08
#define MASK_SET_BITCONFIG 0x10
#define MASK_RESET_CAPCOUNTER 0x20
#define MASK_SET_DEFAULT_PARAMS 0x40
#define MASK_SET_SAVE_EEPROM 0x80
 
#define BITCONF_REVERSE_ROTATION 0x01
#define BITCONF_RES1 0x02
#define BITCONF_RES2 0x04
#define BITCONF_RES3 0x08
#define BITCONF_RES4 0x10
#define BITCONF_RES5 0x20
#define BITCONF_RES6 0x40
#define BITCONF_RES7 0x80
 
typedef struct
{
uint8_t Revision; // must be BL_REVISION
uint8_t SetMask; // settings mask
uint8_t PwmScaling; // maximum value of control pwm, acts like a thrust limit
uint8_t CurrentLimit; // current limit in A
uint8_t TempLimit; // in °C
uint8_t CurrentScaling; // scaling factor for current measurement
uint8_t BitConfig; // see defines above
uint8_t crc; // checksum
} __attribute__((packed)) BLConfig_t;
 
extern BLConfig_t BLConfig[MAX_MOTORS];
 
extern volatile uint16_t I2CTimeout;
 
void I2C_Init (void); // Initialize I2C
46,6 → 82,7
#define I2C_Start(start_state) {twi_state = start_state; BLFlags &= ~BLFLAG_TX_COMPLETE; TWCR = (1<<TWSTA) | (1<<TWEN) | (1<<TWINT) | (1<<TWIE);}
#define I2C_Stop(start_state) {twi_state = start_state; TWCR = (1<<TWEN) | (1<<TWSTO) | (1<<TWINT);}
void I2C_Reset(void); // Reset I2C
void I2C_SendBLConfig(void);
uint8_t I2C_SetBLConfig(void);
uint8_t I2C_GetBLConfig(void);
 
#endif
/beta/Code Redesign killagreg/uart0.c
115,27 → 115,6
int16_t Heading;
} __attribute__((packed)) Heading_t;
 
#define BLPARAM_REVISION 1
#define MASK_SET_PWM_SCALING 0x01
#define MASK_SET_CURRENT_LIMIT 0x02
#define MASK_SET_TEMP_LIMIT 0x04
#define MASK_SET_CURRENT_SCALING 0x08
#define MASK_SET_BITCONFIG 0x10
#define MASK_RESET_CAPCOUNTER 0x20
#define MASK_SET_DEFAULT_PARAMS 0x40
#define MASK_SET_SAVE_EEPROM 0x80
typedef struct
{
uint8_t Revision; // revision of parameter structure
uint8_t Address; // target address
uint8_t PwmScaling; // maximum value of pwm setpoint
uint8_t CurrentLimit; // current limit in 1A steps
uint8_t TemperatureLimit; // in °C
uint8_t CurrentScaling; // scaling factor for current measurement
uint8_t BitConfig; // see defines above
uint8_t SetMask; // filter for active paramters
uint8_t Checksum; // checksum for parameter sturcture
} __attribute__((packed)) BLParameter_t;
 
DebugOut_t DebugOut;
Data3D_t Data3D;
625,6 → 604,56
PPM_in[24] = (int8_t)pRxData[11];
break;
 
case 'u': // request BL parameter
tempchar1 = pRxData[0];
Debug("Reading BL %d", tempchar1);
if( (tempchar1 > 0) && (tempchar1 <= MAX_MOTORS) )
{ // valid motor address
BLConfig[tempchar1-1].Revision = 0; // bad revision
BLConfig[tempchar1-1].crc = 0; // bad checksum
if(I2C_GetBLConfig())
{ // try to get the BL configs
if(BLConfig[tempchar1-1].crc == RAM_Checksum((uint8_t*)(&BLConfig[tempchar1-1]), sizeof(BLConfig_t)-1) )
{ // when crc is fine, send out
while(!txd_complete); // wait for previous frame to be sent
SendOutData('U', FC_ADDRESS, 2, tempchar1, 1, &BLConfig[tempchar1-1], sizeof(BLConfig_t));
}
}
}
break;
 
case 'w': // write BL parameter
tempchar1 = 0;
Debug("Writing BL %d", pRxData[0]);
if(!(FCFlags & FCFLAG_MOTOR_RUN) && (pRxData[0] <= MAX_MOTORS)) // save parameter only if motors are off and a valid motor address was sent
{
BLConfig_t *pBLConfig = (BLConfig_t*)(&pRxData[1]);
// version check
if(pBLConfig->Revision == BLCONFIG_REVISION)
{
uint8_t i, start, end;
if(pRxData[0] == 0) // all BLs!
{
start = 0;
end = MAX_MOTORS - 1;
}
else
{ // only one specific
start = pRxData[0] - 1;
end = start;
}
pBLConfig->crc = RAM_Checksum((uint8_t*)pBLConfig, sizeof(BLConfig_t) - 1); // update crc
for(i = start; i <= end; i++)
{
memcpy(&BLConfig[i], pBLConfig, sizeof(BLConfig_t));
}
tempchar1 = I2C_SetBLConfig();
}
}
while(!txd_complete); // wait for previous frame to be sent
SendOutData('W', FC_ADDRESS,1, &tempchar1, sizeof(tempchar1));
break;
 
default:
//unsupported command received
break;
689,68 → 718,6
AboTimeOut = SetDelay(ABO_TIMEOUT);
break;
 
case 'u': // request BL parameter
tempchar1 = pRxData[0];
Debug("Reading BL-Parameter %d", tempchar1);
if( (tempchar1 > 0) && (tempchar1 <= MAX_MOTORS) )
{
BLParameter_t BLParam;
tempchar1--;
BLParam.Revision = BLPARAM_REVISION;
BLParam.Address = tempchar1+1;
BLParam.PwmScaling = BLConfig[tempchar1].PwmScaling;
BLParam.CurrentLimit = BLConfig[tempchar1].CurrentLimit;
BLParam.TemperatureLimit = BLConfig[tempchar1].TempLimit;
BLParam.CurrentScaling = BLConfig[tempchar1].CurrentScaling;
BLParam.BitConfig = BLConfig[tempchar1].BitConfig;
BLParam.SetMask = 0;
BLParam.Checksum = RAM_Checksum((uint8_t*)&(BLConfig[tempchar1]), sizeof(BLParam)-1);
SendOutData('U', FC_ADDRESS, 1, &BLParam, sizeof(BLParam));
}
break;
 
case 'w': // write BL parameter
tempchar1 = 0;
if(!(FCFlags & FCFLAG_MOTOR_RUN)) // save parameter only if motors are off
{
BLParameter_t *pBLParam = (BLParameter_t*)pRxData;
// version and address check
if( (pBLParam->Revision == BLPARAM_REVISION) && (pBLParam->Address <= MAX_MOTORS) )
{
uint8_t i, start, end;
if(pBLParam->Address == 0)
{ // all BLs
start = 0;
end = MAX_MOTORS - 1;
}
else
{ // only one specific
start = pBLParam->Address - 1;
end = start;
}
for(i = start; i <= end; i++)
{
if(pBLParam->SetMask & MASK_SET_DEFAULT_PARAMS) BLConfig_SetDefault(i);
else
{
if(pBLParam->SetMask & MASK_SET_PWM_SCALING) BLConfig[i].PwmScaling = pBLParam->PwmScaling;
if(pBLParam->SetMask & MASK_SET_CURRENT_LIMIT) BLConfig[i].CurrentLimit = pBLParam->CurrentLimit;
if(pBLParam->SetMask & MASK_SET_TEMP_LIMIT) BLConfig[i].TempLimit = pBLParam->TemperatureLimit;
if(pBLParam->SetMask & MASK_SET_CURRENT_SCALING) BLConfig[i].CurrentScaling = pBLParam->CurrentScaling;
if(pBLParam->SetMask & MASK_SET_BITCONFIG) BLConfig[i].BitConfig = pBLParam->BitConfig;
BLConfig[i].crc = RAM_Checksum((uint8_t*)&(BLConfig[i]), sizeof(BLConfig_t)-1); // update crc
 
}
if(pBLParam->SetMask & MASK_SET_SAVE_EEPROM) BLConfig_WriteToEEProm(i);
}
I2C_SendBLConfig();
tempchar1 = 1;
}
}
while(!txd_complete); // wait for previous frame to be sent
SendOutData('W', FC_ADDRESS,1, &tempchar1, sizeof(tempchar1));
break;
 
default:
//unsupported command received
break;