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; |
} |
} |