Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 2017 → Rev 2018

/branches/dongfang_FC_rewrite/ADXRS610_FC2.0.c
5,7 → 5,7
// Nothing to calibrate.
}
 
void gyro_loadAmplifierOffsets(uint8_t overwriteWithDefaults) {
void gyro_init() {
// No amplifiers, no DAC.
}
 
/branches/dongfang_FC_rewrite/ENC-03_FC1.3.c
9,6 → 9,19
#define PITCHROLL_MINLIMIT GYRO_SUMMATION_FACTOR_PITCHROLL * 510
#define PITCHROLL_MAXLIMIT GYRO_SUMMATION_FACTOR_PITCHROLL * 515
 
void I2C_OutputAmplifierOffsets() {
uint16_t timeout = setDelay(2000);
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // initiate data transmission
// Wait for I2C to finish transmission.
while (twi_state) {
// Did it take too long?
if (checkDelay(timeout)) {
printf("\r\n DAC or I2C Error! check I2C, 3Vref, DAC, and BL-Ctrl");
break;
}
}
}
 
void gyro_calibrate(void) {
printf("gyro_calibrate");
uint8_t i, axis, factor, numberOfAxesInRange = 0;
38,35 → 51,28
/* Gyro is defective. But do keep DAC within bounds (it's an op amp not a differential amp). */
if (gyroAmplifierOffset.offsets[axis] < 10) {
gyroAmplifierOffset.offsets[axis] = 10;
versionInfo.hardwareErrors[0] |= (FC_ERROR0_GYRO_PITCH << axis);
} else if (gyroAmplifierOffset.offsets[axis] > 245) {
gyroAmplifierOffset.offsets[axis] = 245;
versionInfo.hardwareErrors[0] |= (FC_ERROR0_GYRO_PITCH << axis);
}
}
gyro_loadAmplifierOffsets(0);
I2C_OutputAmplifierOffsets();
}
gyroAmplifierOffset_writeToEEProm();
delay_ms_with_adc_measurement(70, 0);
}
 
void gyro_loadAmplifierOffsets(uint8_t overwriteWithDefaults) {
uint16_t timeout = setDelay(2000);
 
if (overwriteWithDefaults) {
gyroAmplifierOffset.offsets[PITCH] =
void gyro_init() {
if (gyroAmplifierOffset_readFromEEProm()) {
printf("gyro amp invalid%s", recal);
gyroAmplifierOffset.offsets[PITCH] =
gyroAmplifierOffset.offsets[ROLL] =
gyroAmplifierOffset.offsets[YAW] = (uint8_t)(255 * 1.2089 / 3.0);
}
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // initiate data transmission
// Wait for I2C to finish transmission.
while (twi_state) {
// Did it take too long?
if (checkDelay(timeout)) {
printf("\r\n DAC or I2C Error! check I2C, 3Vref, DAC, and BL-Ctrl");
break;
}
}
} else {
I2C_OutputAmplifierOffsets();
}
}
 
void gyro_setDefaultParameters(void) {
/branches/dongfang_FC_rewrite/analog.c
524,12 → 524,8
}
 
void analog_setNeutral() {
if (gyroAmplifierOffset_readFromEEProm()) {
printf("gyro amp invalid%s",recal);
gyro_loadAmplifierOffsets(1);
} else
gyro_loadAmplifierOffsets(0);
 
gyro_init();
if (gyroOffset_readFromEEProm()) {
printf("gyro offsets invalid%s",recal);
gyroOffset.offsets[PITCH] = gyroOffset.offsets[ROLL] = 512 * GYRO_SUMMATION_FACTOR_PITCHROLL;
571,6 → 567,11
for (axis = PITCH; axis <= YAW; axis++) {
gyroOffset.offsets[axis] = (offsets[axis] + GYRO_OFFSET_CYCLES / 2) / GYRO_OFFSET_CYCLES;
 
int16_t min = (512-200) * (axis==YAW) ? GYRO_SUMMATION_FACTOR_YAW : GYRO_SUMMATION_FACTOR_PITCHROLL;
int16_t max = (512+200) * (axis==YAW) ? GYRO_SUMMATION_FACTOR_YAW : GYRO_SUMMATION_FACTOR_PITCHROLL;
if(gyroOffset.offsets[axis] < min || gyroOffset.offsets[axis] > max)
versionInfo.hardwareErrors[0] |= FC_ERROR0_GYRO_PITCH << axis;
}
 
gyroOffset_writeToEEProm();
588,7 → 589,6
#define ACC_OFFSET_CYCLES 32
uint8_t i, axis;
int32_t offsets[3] = { 0, 0, 0 };
int16_t filteredDelta;
 
for (i = 0; i < ACC_OFFSET_CYCLES; i++) {
delay_ms_with_adc_measurement(10, 1);
599,6 → 599,24
 
for (axis = PITCH; axis <= YAW; axis++) {
accOffset.offsets[axis] = (offsets[axis] + ACC_OFFSET_CYCLES / 2) / ACC_OFFSET_CYCLES;
int16_t min,max;
if (axis==Z) {
if (staticParams.imuReversedFlags & 8) {
// TODO: This assumes a sensitivity of +/- 2g.
min = (256-200) * ACC_SUMMATION_FACTOR_Z;
max = (256+200) * ACC_SUMMATION_FACTOR_Z;
} else {
// TODO: This assumes a sensitivity of +/- 2g.
min = (768-200) * ACC_SUMMATION_FACTOR_Z;
max = (768+200) * ACC_SUMMATION_FACTOR_Z;
}
} else {
min = (512-200) * ACC_SUMMATION_FACTOR_PITCHROLL;
max = (512+200) * ACC_SUMMATION_FACTOR_PITCHROLL;
}
if(gyroOffset.offsets[axis] < min || gyroOffset.offsets[axis] > max) {
versionInfo.hardwareErrors[0] |= FC_ERROR0_ACC_X << axis;
}
}
 
accOffset_writeToEEProm();
/branches/dongfang_FC_rewrite/analog.h
16,7 → 16,6
* Temporarily replaced by userparam-configurable variable.
*/
// #define GYROS_ATT_FILTER 1
// Temporarily replaced by userparam-configurable variable.
// #define ACC_FILTER 4
 
/*
29,9 → 28,7
- Nose down for pitch
- Left hand side down for roll
- Clockwise seen from above for yaw.
Declare the GYRO_REVERSE_YAW, GYRO_REVERSE_ROLL and
GYRO_REVERSE_PITCH #define's if the respective gyros are reverse.
 
Setting gyro gain correctly: All sensor measurements in analog.c take
place in a cycle, each cycle comprising all sensors. Some sensors are
sampled more than ones, and the results added. The pitch and roll gyros
/branches/dongfang_FC_rewrite/attitude.c
388,12 → 388,12
}
 
void calculateAccVector(void) {
uint16_t temp;
temp = filteredAcc[0]/4;
int16_t temp;
temp = filteredAcc[0] >> 3;
accVector = temp * temp;
temp = filteredAcc[1]/4;
temp = filteredAcc[1] >> 3;
accVector += temp * temp;
temp = filteredAcc[2]/4;
temp = filteredAcc[2] >> 3;
accVector += temp * temp;
debugOut.analog[18] = accVector;
debugOut.analog[19] = dynamicParams.maxAccVector;
/branches/dongfang_FC_rewrite/configuration.c
67,6 → 67,8
uint8_t boardRelease = 13;
uint8_t requiredMotors;
 
VersionInfo_t versionInfo;
 
// MK flags. TODO: Replace by enum. State machine.
uint16_t isFlying = 0;
volatile uint8_t MKFlags = 0;
/branches/dongfang_FC_rewrite/configuration.h
7,7 → 7,37
#define MAX_CHANNELS 10
#define MAX_MOTORS 12
 
// bitmask for VersionInfo_t.HardwareError[0]
#define FC_ERROR0_GYRO_PITCH 0x01
#define FC_ERROR0_GYRO_ROLL 0x02
#define FC_ERROR0_GYRO_YAW 0x04
#define FC_ERROR0_ACC_X 0x08
#define FC_ERROR0_ACC_Y 0x10
#define FC_ERROR0_ACC_Z 0x20
#define FC_ERROR0_PRESSURE 0x40
#define FC_ERROR1_RES0 0x80
// bitmask for VersionInfo_t.HardwareError[1]
#define FC_ERROR1_I2C 0x01
#define FC_ERROR1_BL_MISSING 0x02
#define FC_ERROR1_SPI_RX 0x04
#define FC_ERROR1_PPM 0x08
#define FC_ERROR1_MIXER 0x10
#define FC_ERROR1_RES1 0x20
#define FC_ERROR1_RES2 0x40
#define FC_ERROR1_RES3 0x80
 
typedef struct {
uint8_t SWMajor;
uint8_t SWMinor;
uint8_t protoMajor;
uint8_t protoMinor;
uint8_t SWPatch;
uint8_t hardwareErrors[5];
}__attribute__((packed)) VersionInfo_t;
 
extern VersionInfo_t versionInfo;
 
typedef struct {
// IMU
/*PMM*/uint8_t gyroP;
/* P */uint8_t gyroD;
91,22 → 121,23
uint8_t bitConfig; // see upper defines for bitcoding
// Height Control
uint8_t heightP; // Value : 0-32
uint8_t heightD; // Value : 0-250
uint8_t heightSetting; // Value : 0-32
uint8_t heightControlMaxThrottleChange; // Value : 0-100
uint8_t heightSlewRate; // Value : 0-50
uint8_t airpressureFilter;
uint8_t heightP;
uint8_t heightD;
uint8_t heightSetting;
uint8_t heightControlMaxThrottleChange;
uint8_t heightSlewRate;
 
// Attitude Control
uint8_t attitudeControl;
 
// Control
uint8_t stickP; // Value : 1-6
uint8_t stickD; // Value : 0-64
uint8_t stickYawP; // Value : 1-20
uint8_t stickP;
uint8_t stickD;
uint8_t stickYawP;
uint8_t stickThrottleD;
uint8_t minThrottle; // Value : 0-32
uint8_t maxThrottle; // Value : 33-250
uint8_t minThrottle;
uint8_t maxThrottle;
uint8_t externalControl; // for serial Control
uint8_t maxAccVector;
uint8_t maxControlActivity;
122,11 → 153,11
uint8_t gyroDFilterConstant;
uint8_t accFilterConstant;
 
uint8_t gyroP; // Value : 10-250
uint8_t gyroI; // Value : 0-250
uint8_t gyroD; // Value : 0-250
uint8_t gyroP;
uint8_t gyroI;
uint8_t gyroD;
 
uint8_t zerothOrderCorrection; // Value : 1-64
uint8_t zerothOrderCorrection;
uint8_t driftCompDivider; // 1/k (Koppel_ACC_Wirkung)
uint8_t driftCompLimit; // limit for gyrodrift compensation
 
135,9 → 166,9
uint8_t axisCouplingYawCorrection;// Value: 0-250 Faktor, mit dem Nick und Roll verkoppelt werden
 
uint8_t dynamicStability; // PID limit for Attitude controller
uint8_t IFactor; // Value : 0-250
uint8_t IFactor;
uint8_t yawIFactor;
uint8_t compassYawEffect; // Value : 0-32
uint8_t compassYawEffect;
uint8_t levelCorrection[2];
 
// Servos
146,9 → 177,9
servo_t servoConfigurations[2]; // [PITCH, ROLL]
 
// Battery warning and emergency flight
uint8_t batteryVoltageWarning; // Value : 0-250
uint8_t emergencyThrottle; // Value : 0-250
uint8_t emergencyFlightDuration; // Value : 0-250
uint8_t batteryVoltageWarning;
uint8_t emergencyThrottle;
uint8_t emergencyFlightDuration;
 
// Outputs
output_flash_t outputFlash[2];
156,7 → 187,7
uint8_t outputFlags;
 
// User params
uint8_t userParams[8]; // Value : 0-250
uint8_t userParams[8];
 
// Name
char name[12];
/branches/dongfang_FC_rewrite/controlMixer.c
132,8 → 132,8
uint8_t rcQ = RC_getSignalQuality();
uint8_t ecQ = EC_getSignalQuality();
//if (rcQ < SIGNAL_GOOD) debugOut.digital[0] |= DEBUG_SIGNAL; else debugOut.digital[0] &= ~DEBUG_SIGNAL;
//if (ecQ < SIGNAL_GOOD) debugOut.digital[1] |= DEBUG_SIGNAL; else debugOut.digital[1] &= ~DEBUG_SIGNAL;
if (rcQ < SIGNAL_GOOD) debugOut.digital[0] |= DEBUG_SIGNAL; else debugOut.digital[0] &= ~DEBUG_SIGNAL;
if (ecQ < SIGNAL_GOOD) debugOut.digital[1] |= DEBUG_SIGNAL; else debugOut.digital[1] &= ~DEBUG_SIGNAL;
// This needs not be the only correct solution...
return rcQ > ecQ ? rcQ : ecQ;
249,8 → 249,8
lastCommand = COMMAND_NONE;
}
 
if (rcCommand != COMMAND_NONE) debugOut.digital[0] |= DEBUG_SIGNAL; else debugOut.digital[0] &= ~DEBUG_SIGNAL;
if (isCommandRepeated) debugOut.digital[1] |= DEBUG_SIGNAL; else debugOut.digital[1] &= ~DEBUG_SIGNAL;
//if (rcCommand != COMMAND_NONE) debugOut.digital[0] |= DEBUG_SIGNAL; else debugOut.digital[0] &= ~DEBUG_SIGNAL;
//if (isCommandRepeated) debugOut.digital[1] |= DEBUG_SIGNAL; else debugOut.digital[1] &= ~DEBUG_SIGNAL;
}
 
// TODO: Integrate into command system.
/branches/dongfang_FC_rewrite/invenSense.c
30,8 → 30,8
delay_ms_with_adc_measurement(100, 0);
}
 
void gyro_loadAmplifierOffsets(uint8_t overwriteWithDefaults) {
// No amplifiers, no DAC.
void gyro_init() {
gyro_calibrate();
}
 
void gyro_setDefaultParameters(void) {
/branches/dongfang_FC_rewrite/main.c
100,7 → 100,7
output_init();
timer0_init();
timer2_init();
usart0_Init();
usart0_init();
if (CPUType == ATMEGA644P);// usart1_Init();
RC_Init();
analog_init();
191,12 → 191,12
 
printf("\n\rControl: ");
if (staticParams.bitConfig & CFG_HEADING_HOLD)
printf("HeadingHold");
else printf("Neutral (ACC-Mode)");
printf("Heading Hold");
else printf("RTL Mode");
 
printf("\n\n\r");
 
LCD_Clear();
LCD_clear();
 
I2CTimeout = 5000;
 
204,6 → 204,7
if (runFlightControl) { // control interval
runFlightControl = 0; // reset Flag, is enabled every 2 ms by ISR of timer0
if (!analogDataReady) {
// Analog data should have been ready but is not!!
debugOut.digital[0] |= DEBUG_MAINLOOP_TIMER;
} else {
debugOut.digital[0] &= ~DEBUG_MAINLOOP_TIMER;
217,14 → 218,15
I2C_Reset();
I2CTimeout = 5;
}
beepI2CAlarm();
}
// Allow Serial Data Transmit if motors must not updated or motors are not running
if (!runFlightControl || !(MKFlags & MKFLAG_MOTOR_RUN)) {
usart0_TransmitTxData();
usart0_transmitTxData();
}
 
usart0_ProcessRxData();
usart0_processRxData();
 
if (checkDelay(timer)) {
if (UBat <= UBAT_AT_5V) {
255,7 → 257,7
 
calculateServoValues();
if (runFlightControl) { // control interval
if (runFlightControl) { // Time for the next iteration was up before the current finished. Signal error.
debugOut.digital[1] |= DEBUG_MAINLOOP_TIMER;
} else {
debugOut.digital[1] &= ~DEBUG_MAINLOOP_TIMER;
/branches/dongfang_FC_rewrite/menu.c
61,15 → 61,15
#include "attitude.h"
 
#if (!defined (USE_NAVICTRL))
uint8_t MaxMenuItem = 13;
uint8_t maxMenuItem = 13;
#else
#ifdef USE_NAVICTRL
#include "gps.c"
uint8_t MaxMenuItem = 14;
uint8_t maxMenuItem = 14;
#endif
#endif
uint8_t MenuItem = 0;
uint8_t RemoteKeys = 0;
uint8_t menuItem = 0;
uint8_t remoteKeys = 0;
 
#define KEY1 0x01
#define KEY2 0x02
78,16 → 78,16
#define KEY5 0x10
 
#define DISPLAYBUFFSIZE 80
int8_t DisplayBuff[DISPLAYBUFFSIZE] = "Hello World";
uint8_t DispPtr = 0;
int8_t displayBuff[DISPLAYBUFFSIZE] = "Hello World";
uint8_t dispPtr = 0;
 
/************************************/
/* Clear LCD Buffer */
/************************************/
void LCD_Clear(void) {
void LCD_clear(void) {
uint8_t i;
for (i = 0; i < DISPLAYBUFFSIZE; i++)
DisplayBuff[i] = ' ';
displayBuff[i] = ' ';
}
 
/************************************/
94,35 → 94,35
/* Update Menu on LCD */
/************************************/
// Display with 20 characters in 4 lines
void LCD_PrintMenu(void) {
if (RemoteKeys & KEY1) {
if (MenuItem)
MenuItem--;
void LCD_printMenu(void) {
if (remoteKeys & KEY1) {
if (menuItem)
menuItem--;
else
MenuItem = MaxMenuItem;
menuItem = maxMenuItem;
}
 
if (RemoteKeys & KEY2) {
if (MenuItem == MaxMenuItem)
MenuItem = 0;
if (remoteKeys & KEY2) {
if (menuItem == maxMenuItem)
menuItem = 0;
else
MenuItem++;
menuItem++;
}
if ((RemoteKeys & KEY1) && (RemoteKeys & KEY2))
MenuItem = 0;
if ((remoteKeys & KEY1) && (remoteKeys & KEY2))
menuItem = 0;
 
LCD_Clear();
LCD_clear();
 
if (MenuItem > MaxMenuItem)
MenuItem = MaxMenuItem;
if (menuItem > maxMenuItem)
menuItem = maxMenuItem;
// print menu item number in the upper right corner
if (MenuItem < 10) {
LCD_printfxy(17,0,"[%i]",MenuItem);
if (menuItem < 10) {
LCD_printfxy(17,0,"[%i]", menuItem);
} else {
LCD_printfxy(16,0,"[%i]",MenuItem);
LCD_printfxy(16,0,"[%i]", menuItem);
}
 
switch (MenuItem) {
switch (menuItem) {
case 0:// Version Info Menu Item
LCD_printfxy(0,0,"+ MikroKopter +")
;
289,9 → 289,9
#endif
 
default:
MaxMenuItem = MenuItem - 1;
MenuItem = 0;
maxMenuItem = menuItem - 1;
menuItem = 0;
break;
}
RemoteKeys = 0;
remoteKeys = 0;
}
/branches/dongfang_FC_rewrite/menu.h
5,13 → 5,11
 
#define DISPLAYBUFFSIZE 80
 
extern void LCD_PrintMenu(void);
extern void LCD_Clear(void);
extern int8_t DisplayBuff[DISPLAYBUFFSIZE];
extern uint8_t DispPtr;
extern uint8_t MenuItem;
extern uint8_t MaxMenuItem;
extern uint8_t RemoteKeys;
extern void LCD_printMenu(void);
extern void LCD_clear(void);
extern int8_t displayBuff[DISPLAYBUFFSIZE];
extern uint8_t dispPtr;
extern uint8_t menuItem;
extern uint8_t maxMenuItem;
extern uint8_t remoteKeys;
#endif //_MENU_H
 
 
/branches/dongfang_FC_rewrite/output.c
114,7 → 114,7
// alarm
flashingLight(1, 25, 0x55, 25);
} else {
flashingLight(1, staticParams.outputFlash[0].timing, staticParams.outputFlash[0].bitmask, dynamicParams.output0Timing);
flashingLight(1, staticParams.outputFlash[1].timing, staticParams.outputFlash[1].bitmask, dynamicParams.output1Timing);
}
}
}
/branches/dongfang_FC_rewrite/printf_P.c
98,7 → 98,7
 
char Putchar(char zeichen)
{
if(PrintZiel == OUT_LCD) { DisplayBuff[DispPtr++] = zeichen; return(1);}
if(PrintZiel == OUT_LCD) { displayBuff[dispPtr++] = zeichen; return(1);}
else return(uart_putchar(zeichen));
}
 
/branches/dongfang_FC_rewrite/printf_P.h
13,7 → 13,7
 
#define printf_P(format, args...) _printf_P(OUT_V24,format , ## args)
#define printf(format, args...) _printf_P(OUT_V24,PSTR(format) , ## args)
#define LCD_printfxy(x,y,format, args...) { DispPtr = y * 20 + x; _printf_P(OUT_LCD,PSTR(format) , ## args);}
#define LCD_printfxy(x,y,format, args...) { dispPtr = y * 20 + x; _printf_P(OUT_LCD,PSTR(format) , ## args);}
#define LCD_printf(format, args...) { _printf_P(OUT_LCD,PSTR(format) , ## args);}
 
#endif
/branches/dongfang_FC_rewrite/sensors.h
4,15 → 4,6
#include <inttypes.h>
#include "configuration.h"
 
/*
* Whether (pitch, roll, yaw) gyros are reversed (see analog.h).
*/
extern const uint8_t GYRO_REVERSED[3];
 
/*
* Whether (pitch, roll, Z) acc. meters are reversed(see analog.h).
*/
extern const uint8_t ACC_REVERSED[3];
extern sensorOffset_t gyroAmplifierOffset;
 
/*
26,7 → 17,7
/*
* FC 1.3: Output data in gyroAmplifierOffset to DAC. All other versions: Do nothing.
*/
void gyro_loadAmplifierOffsets(uint8_t overwriteWithDefaults);
void gyro_init(void);
 
/*
* Set some default FC parameters, depending on gyro type: Drift correction etc.
/branches/dongfang_FC_rewrite/uart0.c
1,28 → 1,28
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 04.2007 Holger Buss
// + Nur f�r den privaten Gebrauch
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt f�r das gesamte Projekt (Hardware, Software, Bin�rfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur f�r den privaten und nicht-kommerziellen Gebrauch zul�ssig ist.
// + Es gilt für das gesamte Projekt (Hardware, Software, Binürfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten und nicht-kommerziellen Gebrauch zulüssig ist.
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
// + bzgl. der Nutzungsbedingungen aufzunehmen.
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Best�ckung und Verkauf von Platinen oder Baus�tzen,
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausützen,
// + Verkauf von Luftbildaufnahmen, usw.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder ver�ffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright m�ssen dann beiliegen
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder verüffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
// + auf anderen Webseiten oder Medien ver�ffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
// + auf anderen Webseiten oder Medien verüffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
// + eindeutig als Ursprung verlinkt und genannt werden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Keine Gew�hr auf Fehlerfreiheit, Vollst�ndigkeit oder Funktion
// + Keine Gewühr auf Fehlerfreiheit, Vollstündigkeit oder Funktion
// + Benutzung auf eigene Gefahr
// + Wir �bernehmen keinerlei Haftung f�r direkte oder indirekte Personen- oder Sachsch�den
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschüden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zul�ssig
// + mit unserer Zustimmung zulüssig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
77,30 → 77,30
#define FALSE 0
#define TRUE 1
//int8_t test __attribute__ ((section (".noinit")));
uint8_t request_VerInfo = FALSE;
uint8_t request_ExternalControl = FALSE;
uint8_t request_Display = FALSE;
uint8_t request_Display1 = FALSE;
uint8_t request_DebugData = FALSE;
uint8_t request_Data3D = FALSE;
uint8_t request_DebugLabel = 255;
uint8_t request_verInfo = FALSE;
uint8_t request_externalControl = FALSE;
uint8_t request_display = FALSE;
uint8_t request_display1 = FALSE;
uint8_t request_debugData = FALSE;
uint8_t request_data3D = FALSE;
uint8_t request_debugLabel = 255;
uint8_t request_PPMChannels = FALSE;
uint8_t request_MotorTest = FALSE;
uint8_t request_motorTest = FALSE;
uint8_t request_variables = FALSE;
 
uint8_t DisplayLine = 0;
uint8_t displayLine = 0;
 
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
volatile uint8_t rxd_buffer_locked = FALSE;
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
volatile uint8_t txd_complete = TRUE;
volatile uint8_t ReceivedBytes = 0;
volatile uint8_t receivedBytes = 0;
volatile uint8_t *pRxData = 0;
volatile uint8_t RxDataLen = 0;
volatile uint8_t rxDataLen = 0;
 
uint8_t motorTestActive = 0;
uint8_t motorTest[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t ConfirmFrame;
uint8_t confirmFrame;
 
typedef struct {
int16_t Heading;
107,16 → 107,15
}__attribute__((packed)) Heading_t;
 
DebugOut_t debugOut;
Data3D_t Data3D;
UART_VersionInfo_t UART_VersionInfo;
Data3D_t data3D;
 
uint16_t DebugData_Timer;
uint16_t Data3D_Timer;
uint16_t DebugData_Interval = 0; // in 1ms
uint16_t Data3D_Interval = 0; // in 1ms
uint16_t debugData_timer;
uint16_t data3D_timer;
uint16_t debugData_interval = 0; // in 1ms
uint16_t data3D_interval = 0; // in 1ms
 
#ifdef USE_MK3MAG
int16_t Compass_Timer;
int16_t compass_timer;
#endif
 
// keep lables in flash to save 512 bytes of sram space
158,7 → 157,7
/****************************************************************/
/* Initialization of the USART0 */
/****************************************************************/
void usart0_Init(void) {
void usart0_init(void) {
uint8_t sreg = SREG;
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK / (8 * USART0_BAUD) - 1);
 
213,25 → 212,25
UCSR0B |= (1 << TXCIE0);
 
// initialize the debug timer
DebugData_Timer = setDelay(DebugData_Interval);
debugData_timer = setDelay(debugData_interval);
 
// unlock rxd_buffer
rxd_buffer_locked = FALSE;
pRxData = 0;
RxDataLen = 0;
rxDataLen = 0;
 
// no bytes to send
txd_complete = TRUE;
 
#ifdef USE_MK3MAG
Compass_Timer = setDelay(220);
compass_timer = setDelay(220);
#endif
 
UART_VersionInfo.SWMajor = VERSION_MAJOR;
UART_VersionInfo.SWMinor = VERSION_MINOR;
UART_VersionInfo.SWPatch = VERSION_PATCH;
UART_VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR;
UART_VersionInfo.ProtoMinor = VERSION_SERIAL_MINOR;
versionInfo.SWMajor = VERSION_MAJOR;
versionInfo.SWMinor = VERSION_MINOR;
versionInfo.SWPatch = VERSION_PATCH;
versionInfo.protoMajor = VERSION_SERIAL_MAJOR;
versionInfo.protoMinor = VERSION_SERIAL_MINOR;
 
// restore global interrupt flags
SREG = sreg;
240,8 → 239,7
/****************************************************************/
/* USART0 transmitter ISR */
/****************************************************************/
ISR(USART0_TX_vect)
{
ISR(USART0_TX_vect) {
static uint16_t ptr_txd_buffer = 0;
uint8_t tmp_tx;
if (!txd_complete) { // transmission not completed
262,8 → 260,7
/****************************************************************/
/* USART0 receiver ISR */
/****************************************************************/
ISR(USART0_RX_vect)
{
ISR(USART0_RX_vect) {
static uint16_t checksum;
static uint8_t ptr_rxd_buffer = 0;
uint8_t checksum1, checksum2;
303,7 → 300,7
== rxd_buffer[ptr_rxd_buffer - 1])) {
// checksum valid
rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
ReceivedBytes = ptr_rxd_buffer + 1;// store number of received bytes
receivedBytes = ptr_rxd_buffer + 1;// store number of received bytes
rxd_buffer_locked = TRUE; // lock the rxd buffer
// if 2nd byte is an 'R' enable watchdog that will result in an reset
if (rxd_buffer[2] == 'R') {
336,9 → 333,9
 
// --------------------------------------------------------------------------
// application example:
// SendOutData('A', FC_ADDRESS, 2, (uint8_t *)&request_DebugLabel, sizeof(request_DebugLabel), label, 16);
// sendOutData('A', FC_ADDRESS, 2, (uint8_t *)&request_DebugLabel, sizeof(request_DebugLabel), label, 16);
/*
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
void sendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
va_list ap;
uint16_t txd_bufferIndex = 0;
uint8_t *currentBuffer;
385,7 → 382,7
}
*/
 
void SendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
void sendOutData(uint8_t cmd, uint8_t addr, uint8_t numofbuffers, ...) { // uint8_t *pdata, uint8_t len, ...
va_list ap;
uint16_t pt = 0;
uint8_t a, b, c;
456,7 → 453,7
uint8_t x, y, z;
uint8_t ptrIn = 3;
uint8_t ptrOut = 3;
uint8_t len = ReceivedBytes - 6;
uint8_t len = receivedBytes - 6;
 
while (len) {
a = rxd_buffer[ptrIn++] - '=';
483,11 → 480,11
break;
}
pRxData = &rxd_buffer[3];
RxDataLen = ptrOut - 3;
rxDataLen = ptrOut - 3;
}
 
// --------------------------------------------------------------------------
void usart0_ProcessRxData(void) {
void usart0_processRxData(void) {
// We control the motorTestActive var from here: Count it down.
if (motorTestActive)
motorTestActive--;
508,7 → 505,7
break;
#endif
case 't': // motor test
if (RxDataLen > 20) {
if (rxDataLen > 20) {
memcpy(&motorTest[0], (uint8_t*) pRxData, sizeof(motorTest));
} else {
memcpy(&motorTest[0], (uint8_t*) pRxData, 4);
520,7 → 517,7
case 'n':// "Get Mixer Table
while (!txd_complete)
; // wait for previous frame to be sent
SendOutData('N', FC_ADDRESS, 1, (uint8_t *) &mixerMatrix, sizeof(mixerMatrix));
sendOutData('N', FC_ADDRESS, 1, (uint8_t *) &mixerMatrix, sizeof(mixerMatrix));
break;
 
case 'm':// "Set Mixer Table
533,7 → 530,7
} else {
tempchar[0] = 0;
}
SendOutData('M', FC_ADDRESS, 1, &tempchar, 1);
sendOutData('M', FC_ADDRESS, 1, &tempchar, 1);
break;
 
case 'p': // get PPM channels
556,7 → 553,7
tempchar[2] = sizeof(staticParams);
while (!txd_complete)
; // wait for previous frame to be sent
SendOutData('Q', FC_ADDRESS, 2, &tempchar, 3, (uint8_t *) &staticParams, sizeof(staticParams));
sendOutData('Q', FC_ADDRESS, 2, &tempchar, 3, (uint8_t *) &staticParams, sizeof(staticParams));
break;
 
case 's': // save settings
574,7 → 571,7
}
while (!txd_complete)
; // wait for previous frame to be sent
SendOutData('S', FC_ADDRESS, 1, &tempchar, 1);
sendOutData('S', FC_ADDRESS, 1, &tempchar, 1);
}
break;
 
586,31 → 583,31
default: // any Slave Address
switch (rxd_buffer[2]) {
case 'a':// request for labels of the analog debug outputs
request_DebugLabel = pRxData[0];
if (request_DebugLabel > 31)
request_DebugLabel = 31;
request_debugLabel = pRxData[0];
if (request_debugLabel > 31)
request_debugLabel = 31;
break;
 
case 'b': // submit extern control
memcpy(&externalControl, (uint8_t*) pRxData, sizeof(externalControl));
ConfirmFrame = externalControl.frame;
confirmFrame = externalControl.frame;
externalControlActive = 255;
break;
 
case 'h':// request for display columns
RemoteKeys |= pRxData[0];
if (RemoteKeys)
DisplayLine = 0;
request_Display = TRUE;
remoteKeys |= pRxData[0];
if (remoteKeys)
displayLine = 0;
request_display = TRUE;
break;
 
case 'l':// request for display columns
MenuItem = pRxData[0];
request_Display1 = TRUE;
menuItem = pRxData[0];
request_display1 = TRUE;
break;
 
case 'v': // request for version and board release
request_VerInfo = TRUE;
request_verInfo = TRUE;
break;
 
case 'x':
618,19 → 615,19
break;
 
case 'g':// get external control data
request_ExternalControl = TRUE;
request_externalControl = TRUE;
break;
 
case 'd': // request for the debug data
DebugData_Interval = (uint16_t) pRxData[0] * 10;
if (DebugData_Interval > 0)
request_DebugData = TRUE;
debugData_interval = (uint16_t) pRxData[0] * 10;
if (debugData_interval > 0)
request_debugData = TRUE;
break;
 
case 'c': // request for the 3D data
Data3D_Interval = (uint16_t) pRxData[0] * 10;
if (Data3D_Interval > 0)
request_Data3D = TRUE;
data3D_interval = (uint16_t) pRxData[0] * 10;
if (data3D_interval > 0)
request_data3D = TRUE;
break;
 
default:
641,12 → 638,12
}
// unlock the rxd buffer after processing
pRxData = 0;
RxDataLen = 0;
rxDataLen = 0;
rxd_buffer_locked = FALSE;
}
 
/************************************************************************/
/* Routine f�r die Serielle Ausgabe */
/* Routine für die Serielle Ausgabe */
/************************************************************************/
int16_t uart_putchar(int8_t c) {
if (c == '\n')
659,69 → 656,68
}
 
//---------------------------------------------------------------------------------------------
void usart0_TransmitTxData(void) {
void usart0_transmitTxData(void) {
if (!txd_complete)
return;
 
if (request_VerInfo && txd_complete) {
SendOutData('V', FC_ADDRESS, 1, (uint8_t *) &UART_VersionInfo,
sizeof(UART_VersionInfo));
request_VerInfo = FALSE;
if (request_verInfo && txd_complete) {
sendOutData('V', FC_ADDRESS, 1, (uint8_t *) &versionInfo, sizeof(versionInfo));
request_verInfo = FALSE;
}
 
if (request_Display && txd_complete) {
LCD_PrintMenu();
SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine),
&DisplayBuff[DisplayLine * 20], 20);
DisplayLine++;
if (DisplayLine >= 4)
DisplayLine = 0;
request_Display = FALSE;
if (request_display && txd_complete) {
LCD_printMenu();
sendOutData('H', FC_ADDRESS, 2, &displayLine, sizeof(displayLine),
&displayBuff[displayLine * 20], 20);
displayLine++;
if (displayLine >= 4)
displayLine = 0;
request_display = FALSE;
}
 
if (request_Display1 && txd_complete) {
LCD_PrintMenu();
SendOutData('L', FC_ADDRESS, 3, &MenuItem, sizeof(MenuItem), &MaxMenuItem,
sizeof(MaxMenuItem), DisplayBuff, sizeof(DisplayBuff));
request_Display1 = FALSE;
if (request_display1 && txd_complete) {
LCD_printMenu();
sendOutData('L', FC_ADDRESS, 3, &menuItem, sizeof(menuItem), &maxMenuItem,
sizeof(maxMenuItem), displayBuff, sizeof(displayBuff));
request_display1 = FALSE;
}
 
if (request_DebugLabel != 0xFF) { // Texte f�r die Analogdaten
if (request_debugLabel != 0xFF) { // Texte für die Analogdaten
uint8_t label[16]; // local sram buffer
memcpy_P(label, ANALOG_LABEL[request_DebugLabel], 16); // read lable from flash to sram buffer
SendOutData('A', FC_ADDRESS, 2, (uint8_t *) &request_DebugLabel,
sizeof(request_DebugLabel), label, 16);
request_DebugLabel = 0xFF;
memcpy_P(label, ANALOG_LABEL[request_debugLabel], 16); // read lable from flash to sram buffer
sendOutData('A', FC_ADDRESS, 2, (uint8_t *) &request_debugLabel,
sizeof(request_debugLabel), label, 16);
request_debugLabel = 0xFF;
}
 
if (ConfirmFrame && txd_complete) { // Datensatz ohne checksum bestätigen
SendOutData('B', FC_ADDRESS, 1, (uint8_t*) &ConfirmFrame, sizeof(ConfirmFrame));
ConfirmFrame = 0;
if (confirmFrame && txd_complete) { // Datensatz ohne checksum bestätigen
sendOutData('B', FC_ADDRESS, 1, (uint8_t*) &confirmFrame, sizeof(confirmFrame));
confirmFrame = 0;
}
 
if (((DebugData_Interval && checkDelay(DebugData_Timer)) || request_DebugData)
if (((debugData_interval && checkDelay(debugData_timer)) || request_debugData)
&& txd_complete) {
SendOutData('D', FC_ADDRESS, 1, (uint8_t *) &debugOut, sizeof(debugOut));
DebugData_Timer = setDelay(DebugData_Interval);
request_DebugData = FALSE;
sendOutData('D', FC_ADDRESS, 1, (uint8_t *) &debugOut, sizeof(debugOut));
debugData_timer = setDelay(debugData_interval);
request_debugData = FALSE;
}
 
if (((Data3D_Interval && checkDelay(Data3D_Timer)) || request_Data3D)
if (((data3D_interval && checkDelay(data3D_timer)) || request_data3D)
&& txd_complete) {
SendOutData('C', FC_ADDRESS, 1, (uint8_t *) &Data3D, sizeof(Data3D));
Data3D.AngleNick = (int16_t) ((10 * angle[PITCH])
sendOutData('C', FC_ADDRESS, 1, (uint8_t *) &data3D, sizeof(data3D));
data3D.anglePitch = (int16_t) ((10 * angle[PITCH])
/ GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1°
Data3D.AngleRoll = (int16_t) ((10 * angle[ROLL])
data3D.angleRoll = (int16_t) ((10 * angle[ROLL])
/ GYRO_DEG_FACTOR_PITCHROLL); // convert to multiple of 0.1°
Data3D.Heading = (int16_t) ((10 * yawGyroHeading) / GYRO_DEG_FACTOR_YAW); // convert to multiple of 0.1°
Data3D_Timer = setDelay(Data3D_Interval);
request_Data3D = FALSE;
data3D.heading = (int16_t) ((10 * yawGyroHeading) / GYRO_DEG_FACTOR_YAW); // convert to multiple of 0.1°
data3D_timer = setDelay(data3D_interval);
request_data3D = FALSE;
}
 
if (request_ExternalControl && txd_complete) {
SendOutData('G', FC_ADDRESS, 1, (uint8_t *) &externalControl,
if (request_externalControl && txd_complete) {
sendOutData('G', FC_ADDRESS, 1, (uint8_t *) &externalControl,
sizeof(externalControl));
request_ExternalControl = FALSE;
request_externalControl = FALSE;
}
 
#ifdef USE_MK3MAG
731,25 → 727,25
toMk3Mag.UserParam[0] = dynamicParams.userParams[0];
toMk3Mag.UserParam[1] = dynamicParams.userParams[1];
toMk3Mag.CalState = compassCalState;
SendOutData('w', MK3MAG_ADDRESS, 1,(uint8_t *) &toMk3Mag,sizeof(toMk3Mag));
sendOutData('w', MK3MAG_ADDRESS, 1,(uint8_t *) &toMk3Mag,sizeof(toMk3Mag));
// the last state is 5 and should be send only once to avoid multiple flash writing
if(compassCalState > 4) compassCalState = 0;
Compass_Timer = setDelay(99);
compass_timer = setDelay(99);
}
#endif
 
if (request_MotorTest && txd_complete) {
SendOutData('T', FC_ADDRESS, 0);
request_MotorTest = FALSE;
if (request_motorTest && txd_complete) {
sendOutData('T', FC_ADDRESS, 0);
request_motorTest = FALSE;
}
 
if (request_PPMChannels && txd_complete) {
SendOutData('P', FC_ADDRESS, 1, (uint8_t *) &PPM_in, sizeof(PPM_in));
sendOutData('P', FC_ADDRESS, 1, (uint8_t *) &PPM_in, sizeof(PPM_in));
request_PPMChannels = FALSE;
}
 
if (request_variables && txd_complete) {
SendOutData('X', FC_ADDRESS, 1, (uint8_t *) &variables, sizeof(variables));
sendOutData('X', FC_ADDRESS, 1, (uint8_t *) &variables, sizeof(variables));
request_variables = FALSE;
}
}
/branches/dongfang_FC_rewrite/uart0.h
11,12 → 11,12
//Baud rate of the USART
#define USART0_BAUD 57600
 
extern void usart0_Init(void);
extern void usart0_TransmitTxData(void);
extern void usart0_ProcessRxData(void);
extern void usart0_init(void);
extern void usart0_transmitTxData(void);
extern void usart0_processRxData(void);
extern int16_t uart_putchar(int8_t c);
 
extern uint8_t RemotePollDisplayLine;
// extern uint8_t remotePollDisplayLine;
 
extern uint8_t motorTestActive;
extern uint8_t motorTest[16];
23,25 → 23,16
 
typedef struct {
uint8_t digital[2];
uint16_t analog[32]; // Debugvalues
uint16_t analog[32]; // debug values
}__attribute__((packed)) DebugOut_t;
 
extern DebugOut_t debugOut;
 
typedef struct {
int16_t AngleNick; // in 0.1 deg
int16_t AngleRoll; // in 0.1 deg
int16_t Heading; // in 0.1 deg
uint8_t reserve[8];
int16_t anglePitch; // in 0.1 deg
int16_t angleRoll; // in 0.1 deg
int16_t heading; // in 0.1 deg
uint8_t reserved[8];
}__attribute__((packed)) Data3D_t;
 
typedef struct {
uint8_t SWMajor;
uint8_t SWMinor;
uint8_t ProtoMajor;
uint8_t ProtoMinor;
uint8_t SWPatch;
uint8_t Reserved[5];
}__attribute__((packed)) UART_VersionInfo_t;
 
#endif //_UART0_H