Subversion Repositories FlightCtrl

Compare Revisions

Ignore whitespace Rev 734 → Rev 735

/branches/V0.68d Code Redesign killagreg/uart.c
18,32 → 18,32
#include "_Settings.h"
#include "rc.h"
 
#define FALSE 0
#define TRUE 1
 
unsigned char DebugGetAnforderung = 0,DebugDisplayAnforderung = 0,DebugDataAnforderung = 0,GetVersionAnforderung = 0;
unsigned volatile char SioTmp = 0;
unsigned volatile char txd_buffer[TXD_BUFFER_LEN];
unsigned volatile char rxd_buffer[RXD_BUFFER_LEN];
uint8_t DebugGetAnforderung = 0, DebugDisplayAnforderung = 0, DebugDataAnforderung = 0, GetVersionAnforderung = 0;
 
unsigned volatile char NeuerDatensatzEmpfangen = 0;
unsigned volatile char NeueKoordinateEmpfangen = 0;
unsigned volatile char UebertragungAbgeschlossen = 1;
unsigned volatile char CntCrcError = 0;
unsigned volatile char AnzahlEmpfangsBytes = 0;
unsigned volatile char PC_DebugTimeout = 0;
unsigned char RemotePollDisplayLine = 0;
unsigned char NurKanalAnforderung = 0;
unsigned char DebugTextAnforderung = 255;
unsigned char PcAccess = 100;
unsigned char MotorTest[4] = {0,0,0,0};
unsigned char DubWiseKeys[4] = {0,0,0,0};
unsigned char MeineSlaveAdresse;
unsigned char ConfirmFrame;
struct str_DebugOut DebugOut;
struct str_ExternControl ExternControl;
struct str_VersionInfo VersionInfo;
int Debug_Timer;
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
 
const unsigned char ANALOG_TEXT[32][16] =
volatile uint8_t RxDataProcessed = 0;
volatile uint8_t txd_complete = 1;
volatile uint8_t ReceivedBytes = 0;
 
uint8_t RemotePollDisplayLine = 0;
uint8_t NurKanalAnforderung = 0;
uint8_t DebugTextAnforderung = 255;
uint8_t PcAccess = 100;
uint8_t MotorTest[4] = {0,0,0,0};
uint8_t DubWiseKeys[4] = {0,0,0,0};
uint8_t MySlaveAddr;
uint8_t ConfirmFrame;
 
DebugOut_t DebugOut;
ExternControl_t ExternControl;
VersionInfo_t VersionInfo;
 
const uint8_t ANALOG_TEXT[32][16] =
{
//1234567890123456
"IntegralPitch ", //0
148,20 → 148,22
/****************************************************************/
ISR(USART0_TX_vect)
{
static uint16_t ptr = 0;
uint8_t tmp_tx;
if(!UebertragungAbgeschlossen)
{
ptr++; // die [0] wurde schon gesendet
tmp_tx = txd_buffer[ptr];
if((tmp_tx == '\r') || (ptr == TXD_BUFFER_LEN))
{
ptr = 0;
UebertragungAbgeschlossen = 1;
}
UDR0 = tmp_tx; // send byte will trigger this ISR again
}
else ptr = 0;
static uint16_t ptr_txd_buffer = 0;
uint8_t tmp_tx;
if(!txd_complete) // transmission not completed
{
ptr_txd_buffer++; // die [0] wurde schon gesendet
tmp_tx = txd_buffer[ptr_txd_buffer];
// if terminating character or end of txd buffer was reached
if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN))
{
ptr_txd_buffer = 0; // reset txd pointer
txd_complete = 1; // stop transmission
}
UDR0 = tmp_tx; // send current byte will trigger this ISR again
}
// transmission completed
else ptr_txd_buffer = 0;
}
 
/****************************************************************/
169,64 → 171,73
/****************************************************************/
ISR(USART0_RX_vect)
{
static uint16_t crc;
static uint8_t crc1,crc2,buf_ptr;
static uint8_t UartState = 0;
uint8_t CrcOkay = 0;
static uint16_t crc;
static uint8_t crc1, crc2, ptr_rxd_buffer = 0;
static uint8_t UartState = 0;
uint8_t CrcOkay = 0;
uint8_t c;
 
SioTmp = UDR0;
if(buf_ptr >= RXD_BUFFER_LEN) UartState = 0;
if(SioTmp == '\r' && UartState == 2)
{
UartState = 0;
crc -= rxd_buffer[buf_ptr-2];
crc -= rxd_buffer[buf_ptr-1];
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
CrcOkay = 0;
if((crc1 == rxd_buffer[buf_ptr-2]) && (crc2 == rxd_buffer[buf_ptr-1])) CrcOkay = 1; else { CrcOkay = 0; CntCrcError++;};
if(!NeuerDatensatzEmpfangen && CrcOkay) // Datensatz schon verarbeitet
{
NeuerDatensatzEmpfangen = 1;
AnzahlEmpfangsBytes = buf_ptr;
rxd_buffer[buf_ptr] = '\r';
if(rxd_buffer[2] == 'R') wdt_enable(WDTO_250MS); // Reset-Commando
c = UDR0; // catch the received byte
if(ptr_rxd_buffer >= RXD_BUFFER_LEN) UartState = 0; // rxd buffer overflow -> reset rx uart state
if(c == '\r' && UartState == 2) // termination character received during data collection state
{
UartState = 0; //reset rxd uart state
// the last 2 bytes are no subject for checksum calculation
// they are the checksum itself
crc -= rxd_buffer[ptr_rxd_buffer-2];
crc -= rxd_buffer[ptr_rxd_buffer-1];
// calculate checksum from transmitted data
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
CrcOkay = 0;
// compare with transmitted checksum bytes
if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1])) CrcOkay = 1;
else CrcOkay = 0;
 
if(RxDataProcessed && CrcOkay) // data already processed and CRC OK?
{
RxDataProcessed = FALSE; // reset flag
ReceivedBytes = ptr_rxd_buffer; // store number of received bytes
rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
// if 2nd byte is an 'R' enable watchdog that will result in an reset
if(rxd_buffer[2] == 'R') wdt_enable(WDTO_250MS); // Reset-Commando
}
}
}
else
switch(UartState)
{
case 0:
if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1; // Startzeichen und Daten schon verarbeitet
buf_ptr = 0;
rxd_buffer[buf_ptr++] = SioTmp;
crc = SioTmp;
break;
case 1: // Adresse auswerten
UartState++;
rxd_buffer[buf_ptr++] = SioTmp;
crc += SioTmp;
break;
case 2: // Eingangsdaten sammeln
rxd_buffer[buf_ptr] = SioTmp;
if(buf_ptr < RXD_BUFFER_LEN) buf_ptr++;
else UartState = 0;
crc += SioTmp;
break;
default:
UartState = 0;
break;
}
else
switch(UartState)
{
case 0: // reset rxd buffer
if(c == '#' && RxDataProcessed) UartState = 1; // start character recieved and previous data already processed
ptr_rxd_buffer = 0; // reset buffer pointer
rxd_buffer[ptr_rxd_buffer++] = c; // write character to rxd buffer
crc = c; // initialize crc
break;
case 1: // check address
UartState++; // switch to next state
rxd_buffer[ptr_rxd_buffer++] = c; // write character to rxd buffer
crc += c; // update crc
break;
case 2: // collect received data
rxd_buffer[ptr_rxd_buffer] = c; // write character to rxd buffer
// if buffer overflow -> reset buffer
if(ptr_rxd_buffer < RXD_BUFFER_LEN) ptr_rxd_buffer++;
else UartState = 0;
crc += c; // update checksum
break;
default:
UartState = 0;
break;
}
}
 
 
 
// --------------------------------------------------------------------------
void AddCRC(unsigned int wieviele)
void AddCRC(uint16_t datalen)
{
uint16_t tmpCRC = 0,i;
for(i = 0; i < wieviele;i++)
for(i = 0; i < datalen;i++)
{
tmpCRC += txd_buffer[i];
}
234,8 → 245,8
txd_buffer[i++] = '=' + tmpCRC / 64;
txd_buffer[i++] = '=' + tmpCRC % 64;
txd_buffer[i++] = '\r';
UebertragungAbgeschlossen = 0;
UDR0 = txd_buffer[0];
txd_complete = 0;
UDR0 = txd_buffer[0]; // initiates the transmittion
}
 
 
243,25 → 254,25
// --------------------------------------------------------------------------
void SendOutData(uint8_t cmd,uint8_t modul, uint8_t *snd, uint8_t len)
{
uint16_t pt = 0;
uint8_t a,b,c;
uint8_t ptr = 0;
uint16_t pt = 0;
uint8_t a,b,c;
uint8_t ptr = 0;
 
txd_buffer[pt++] = '#'; // Startzeichen
txd_buffer[pt++] = modul; // Adresse (a=0; b=1,...)
txd_buffer[pt++] = cmd; // Commando
txd_buffer[pt++] = '#'; // Start character
txd_buffer[pt++] = modul; // Address (a=0; b=1,...)
txd_buffer[pt++] = cmd; // Command
 
while(len)
{
if(len) { a = snd[ptr++]; len--;} else a = 0;
if(len) { b = snd[ptr++]; len--;} else b = 0;
if(len) { c = snd[ptr++]; len--;} else c = 0;
txd_buffer[pt++] = '=' + (a >> 2);
txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
txd_buffer[pt++] = '=' + ( c & 0x3f);
}
AddCRC(pt);
while(len)
{
if(len) { a = snd[ptr++]; len--;} else a = 0;
if(len) { b = snd[ptr++]; len--;} else b = 0;
if(len) { c = snd[ptr++]; len--;} else c = 0;
txd_buffer[pt++] = '=' + (a >> 2);
txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
txd_buffer[pt++] = '=' + ( c & 0x3f);
}
AddCRC(pt); // add checksum after data block and initates the transmission
}
 
 
268,104 → 279,103
// --------------------------------------------------------------------------
void Decode64(uint8_t *ptrOut, uint8_t len, uint8_t ptrIn, uint8_t max) // Wohin mit den Daten; Wie lang; Wo im rxd_buffer
{
uint8_t a,b,c,d;
uint8_t ptr = 0;
uint8_t x,y,z;
while(len)
{
a = rxd_buffer[ptrIn++] - '=';
b = rxd_buffer[ptrIn++] - '=';
c = rxd_buffer[ptrIn++] - '=';
d = rxd_buffer[ptrIn++] - '=';
if(ptrIn > max - 2) break; // nicht mehr Daten verarbeiten, als empfangen wurden
uint8_t a,b,c,d;
uint8_t ptr = 0;
uint8_t x,y,z;
while(len)
{
a = rxd_buffer[ptrIn++] - '=';
b = rxd_buffer[ptrIn++] - '=';
c = rxd_buffer[ptrIn++] - '=';
d = rxd_buffer[ptrIn++] - '=';
if(ptrIn > max - 2) break; // nicht mehr Daten verarbeiten, als empfangen wurden
 
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
 
if(len--) ptrOut[ptr++] = x; else break;
if(len--) ptrOut[ptr++] = y; else break;
if(len--) ptrOut[ptr++] = z; else break;
}
 
if(len--) ptrOut[ptr++] = x; else break;
if(len--) ptrOut[ptr++] = y; else break;
if(len--) ptrOut[ptr++] = z; else break;
}
}
 
 
// --------------------------------------------------------------------------
void BearbeiteRxDaten(void)
void ProcessRxData(void)
{
if(!NeuerDatensatzEmpfangen) return;
// if data in the rxd buffer are alredy processed immediately return
if(RxDataProcessed) return;
 
uint8_t tmp_char_arr2[2];
uint8_t tmp_char_arr2[2]; // local buffer
 
PcAccess = 255;
switch(rxd_buffer[2])
{
case 'a':// Texte der Analogwerte
Decode64((uint8_t *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
DebugTextAnforderung = tmp_char_arr2[0];
PcAccess = 255;
switch(rxd_buffer[2])
{
case 'a':// Labels of the Analog Deboug outputs
Decode64((uint8_t *) &tmp_char_arr2[0], sizeof(tmp_char_arr2), 3, ReceivedBytes);
DebugTextAnforderung = tmp_char_arr2[0];
break;
case 'b':
Decode64((uint8_t *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
case 'b': // extern control
Decode64((uint8_t *) &ExternControl,sizeof(ExternControl), 3, ReceivedBytes);
RemoteButtons |= ExternControl.RemoteButtons;
ConfirmFrame = ExternControl.Frame;
break;
case 'c':
Decode64((uint8_t *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
ConfirmFrame = ExternControl.Frame;
break;
case 'c': // extern control with debug request
Decode64((uint8_t *) &ExternControl,sizeof(ExternControl),3,ReceivedBytes);
RemoteButtons |= ExternControl.RemoteButtons;
ConfirmFrame = ExternControl.Frame;
DebugDataAnforderung = 1;
break;
case 'h':// x-1 Displayzeilen
Decode64((uint8_t *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
RemoteButtons |= tmp_char_arr2[0];
if(tmp_char_arr2[1] == 255) NurKanalAnforderung = 1; else NurKanalAnforderung = 0; // keine Displaydaten
ConfirmFrame = ExternControl.Frame;
DebugDataAnforderung = 1;
break;
case 'h':// x-1 display columns
Decode64((uint8_t *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,ReceivedBytes);
RemoteButtons |= tmp_char_arr2[0];
if(tmp_char_arr2[1] == 255) NurKanalAnforderung = 1;
else NurKanalAnforderung = 0; // keine Displaydaten
DebugDisplayAnforderung = 1;
break;
case 't':// Motortest
Decode64((uint8_t *) &MotorTest[0],sizeof(MotorTest),3,AnzahlEmpfangsBytes);
case 't':// motor test
Decode64((uint8_t *) &MotorTest[0],sizeof(MotorTest),3,ReceivedBytes);
break;
case 'k':// Keys von DubWise
Decode64((uint8_t *) &DubWiseKeys[0],sizeof(DubWiseKeys),3,AnzahlEmpfangsBytes);
case 'k':// keys from DubWise
Decode64((uint8_t *) &DubWiseKeys[0],sizeof(DubWiseKeys),3,ReceivedBytes);
ConfirmFrame = DubWiseKeys[3];
break;
case 'v': // Version-Anforderung und Ausbaustufe
GetVersionAnforderung = 1;
break;
case 'g':// "Get"-Anforderung für Debug-Daten
// Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
DebugGetAnforderung = 1;
break;
case 'q':// "Get"-Anforderung für Settings
// Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
Decode64((uint8_t *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
if(tmp_char_arr2[0] != 0xff)
{
if(tmp_char_arr2[0] > 5) tmp_char_arr2[0] = 5;
ParamSet_ReadFromEEProm(tmp_char_arr2[0]);
SendOutData('L' + tmp_char_arr2[0] -1,MeineSlaveAdresse,(uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN);
}
else
SendOutData('L' + GetParamByte(PID_ACTIVE_SET)-1,MeineSlaveAdresse,(uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN);
case 'v': // get version and board release
GetVersionAnforderung = 1;
break;
case 'g':// get debug data
DebugGetAnforderung = 1;
break;
case 'q':// get settings
Decode64((uint8_t *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,ReceivedBytes);
if(tmp_char_arr2[0] != 0xff)
{
if(tmp_char_arr2[0] > 5) tmp_char_arr2[0] = 5; // limit to 5
// load requested parameter set
ParamSet_ReadFromEEProm(tmp_char_arr2[0]);
SendOutData('L' + tmp_char_arr2[0] -1,MySlaveAddr,(uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN);
}
else // send active parameter set
SendOutData('L' + GetParamByte(PID_ACTIVE_SET)-1,MySlaveAddr,(uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN);
 
break;
break;
 
case 'l':
case 'm':
case 'n':
case 'o':
case 'p': // Parametersatz speichern
Decode64((uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN,3,AnzahlEmpfangsBytes);
case 'l':
case 'm':
case 'n':
case 'o':
case 'p': // save parameterset
Decode64((uint8_t *) &ParamSet.ChannelAssignment[0],PARAMSET_STRUCT_LEN,3,ReceivedBytes);
ParamSet_WriteToEEProm(rxd_buffer[2] - 'l' + 1);
//SetActiveParamSet(rxd_buffer[2] - 'l' + 1); // is alredy done in ParamSet_WriteToEEProm()
TurnOver180Pitch = (int32_t) ParamSet.AngleTurnOverPitch * 2500L;
TurnOver180Roll = (int32_t) ParamSet.AngleTurnOverRoll * 2500L;
Beep(GetActiveParamSet());
break;
TurnOver180Pitch = (int32_t) ParamSet.AngleTurnOverPitch * 2500L;
TurnOver180Roll = (int32_t) ParamSet.AngleTurnOverRoll * 2500L;
Beep(GetActiveParamSet());
break;
 
 
}
// DebugOut.AnzahlZyklen = Debug_Timer_Intervall;
NeuerDatensatzEmpfangen = 0;
}
RxDataProcessed = TRUE;
}
 
//############################################################################
375,7 → 385,7
{
if (c == '\n')
uart_putchar('\r');
//Warten solange bis Zeichen gesendet wurde
// wait until previous character was send
loop_until_bit_is_set(UCSR0A, UDRE0);
//Ausgabe des Zeichens
UDR0 = c;
383,30 → 393,22
return (0);
}
 
// --------------------------------------------------------------------------
void WriteProgramData(unsigned int pos, unsigned char wert)
{
//if (ProgramLocation == IN_RAM) Buffer[pos] = wert;
// else eeprom_write_byte(&EE_Buffer[pos], wert);
// Buffer[pos] = wert;
}
 
 
 
//---------------------------------------------------------------------------------------------
void DatenUebertragung(void)
void TransmitTxData(void)
{
if(!UebertragungAbgeschlossen) return;
static int16_t Debug_Timer = 0;
if(!txd_complete) return;
 
if(DebugGetAnforderung && UebertragungAbgeschlossen) // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
if(DebugGetAnforderung && txd_complete) // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
{
SendOutData('G',MeineSlaveAdresse,(uint8_t *) &ExternControl,sizeof(ExternControl));
SendOutData('G',MySlaveAddr,(uint8_t *) &ExternControl,sizeof(ExternControl));
DebugGetAnforderung = 0;
}
 
if((CheckDelay(Debug_Timer) || DebugDataAnforderung) && UebertragungAbgeschlossen)
if((CheckDelay(Debug_Timer) || DebugDataAnforderung) && txd_complete)
{
SendOutData('D',MeineSlaveAdresse,(uint8_t *) &DebugOut,sizeof(DebugOut));
SendOutData('D',MySlaveAddr,(uint8_t *) &DebugOut,sizeof(DebugOut));
DebugDataAnforderung = 0;
Debug_Timer = SetDelay(MIN_DEBUG_INTERVALL);
}
415,16 → 417,16
SendOutData('A',DebugTextAnforderung + '0',(uint8_t *) ANALOG_TEXT[DebugTextAnforderung],16);
DebugTextAnforderung = 255;
}
if(ConfirmFrame && UebertragungAbgeschlossen) // Datensatz ohne CRC bestätigen
if(ConfirmFrame && txd_complete) // Datensatz ohne CRC bestätigen
{
txd_buffer[0] = '#';
txd_buffer[1] = ConfirmFrame;
txd_buffer[2] = '\r';
UebertragungAbgeschlossen = 0;
txd_complete = 0;
ConfirmFrame = 0;
UDR0 = txd_buffer[0];
}
if(DebugDisplayAnforderung && UebertragungAbgeschlossen)
if(DebugDisplayAnforderung && txd_complete)
{
LCD_PrintMenu();
DebugDisplayAnforderung = 0;
435,9 → 437,9
}
else SendOutData('0' + RemotePollDisplayLine,0,(uint8_t *)&DisplayBuff[20 * RemotePollDisplayLine],20); // DisplayZeile übertragen
}
if(GetVersionAnforderung && UebertragungAbgeschlossen)
if(GetVersionAnforderung && txd_complete)
{
SendOutData('V',MeineSlaveAdresse,(uint8_t *) &VersionInfo,sizeof(VersionInfo));
SendOutData('V',MySlaveAddr,(uint8_t *) &VersionInfo,sizeof(VersionInfo));
GetVersionAnforderung = 0;
}