Blame |
Last modification |
View Log
| RSS feed
/*****************************************************************************
Project : Roboboard
Date : 1/14/2007
Author : Gunter Logemann (C) ALL RIGHTS RESERVED
Comments: This project is optimized to work with the Mikrocopter (www.mikrokopter.de)
Redistributions of this source code (with or without modifications) or parts
of this sourcode must retain the above copyright notice, this list of
conditions and the following disclaimer.
* Neither the name of the copyright holders nor the names of contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
* The use of this source code permittet for non-commercial use (directly
or indirectly) only.
* Commercial use Is only permitted with our written permission by
Gunter Logemann (gunter@pccon.de)
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Chip type : ATmega8
Program type : Application
Clock frequency : CPUSPEED
*****************************************************************************/
#include <avr/interrupt.h>
#include <avr/sleep.h>
//#include <avr/signal.h>
#include <avr/io.h>
//#include <avr/stdio.h>
#include "StdDefines.h"
#include "Main.h"
//#define CPUSPEED_20
//#define CPUSPEED_16
#define CPUSPEED_11059
// Macros
#define WatchdogReset() asm("wdr")
#define Wait() while(!(SPSR & (1<<SPIF)))
// Define CPU speed dependant constants:
#define MAX_RX_BUF 100
#define MAX_TX_BUF 100
unsigned volatile char SioTmp = 0;
unsigned volatile char RxdBuffer[MAX_RX_BUF];
unsigned volatile char TxdBuffer[MAX_TX_BUF];
unsigned volatile char NeuerDatensatzEmpfangen = 0;
unsigned volatile char UebertragungAbgeschlossen = 1;
unsigned volatile char CntCrcError = 0;
unsigned volatile char AnzahlEmpfangsBytes = 0;
struct str_VersionInfo VersionInfo;
struct str_AnalogData AnalogData;
struct str_Exception Exception;
// --------------------------------------------------------------------------
int uart_putchar (char c)
{
UDR = c;
return (0);
}
// --------------------------------------------------------------------------
SIGNAL(SIG_UART_TRANS)
{
static unsigned int ptr = 0;
unsigned char tmp_tx;
if(!UebertragungAbgeschlossen)
{
ptr++; // die [0] wurde schon gesendet
tmp_tx = TxdBuffer[ptr];
if((tmp_tx == '\r') || (ptr == MAX_TX_BUF))
{
ptr = 0;
UebertragungAbgeschlossen = 1;
}
UDR = tmp_tx;
}
else ptr = 0;
}
// --------------------------------------------------------------------------
SIGNAL(SIG_UART_RECV)
{
static unsigned int crc;
static unsigned char crc1,crc2,buf_ptr;
static unsigned char UartState = 0;
unsigned char CrcOkay = 0;
SioTmp = UDR;
if(buf_ptr >= MAX_RX_BUF)
UartState = 0;
if(SioTmp == '\r' && UartState == 2)
{
UartState = 0;
crc -= RxdBuffer[buf_ptr-2];
crc -= RxdBuffer[buf_ptr-1];
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
CrcOkay = 0;
if((crc1 == RxdBuffer[buf_ptr-2]) && (crc2 == RxdBuffer[buf_ptr-1]))
{
CrcOkay = 1;
}
else
{
CrcOkay = 0;
CntCrcError++;
}
if(!NeuerDatensatzEmpfangen && CrcOkay) // Datensatz schon verarbeitet
{
NeuerDatensatzEmpfangen = 1;
AnzahlEmpfangsBytes = buf_ptr;
RxdBuffer[buf_ptr] = '\r';
}
}
else
switch(UartState)
{
case 0:
if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1; // Startzeichen und Daten schon verarbeitet
buf_ptr = 0;
RxdBuffer[buf_ptr++] = SioTmp;
crc = SioTmp;
break;
case 1: // Adresse auswerten
UartState++;
RxdBuffer[buf_ptr++] = SioTmp;
crc += SioTmp;
break;
case 2: // Eingangsdaten sammeln
RxdBuffer[buf_ptr] = SioTmp;
if(buf_ptr < MAX_RX_BUF) buf_ptr++;
else UartState = 0;
crc += SioTmp;
break;
default:
UartState = 0;
break;
}
}
// --------------------------------------------------------------------------
void AddCRC(unsigned int wieviele)
{
unsigned int tmpCRC = 0,i;
for(i = 0; i < wieviele;i++)
{
tmpCRC += TxdBuffer[i];
}
tmpCRC %= 4096;
TxdBuffer[i++] = '=' + tmpCRC / 64;
TxdBuffer[i++] = '=' + tmpCRC % 64;
TxdBuffer[i++] = '\r';
UebertragungAbgeschlossen = 0;
UDR = TxdBuffer[0];
}
// --------------------------------------------------------------------------
void SendOutData(unsigned char cmd,unsigned char modul, unsigned char *snd, unsigned char len)
{
unsigned int pt = 0;
unsigned char a,b,c;
unsigned char ptr = 0;
TxdBuffer[pt++] = '#'; // Startzeichen
TxdBuffer[pt++] = modul; // Adresse (a=0; b=1,...)
TxdBuffer[pt++] = cmd; // Commando
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;
TxdBuffer[pt++] = '=' + (a >> 2);
TxdBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
TxdBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
TxdBuffer[pt++] = '=' + ( c & 0x3f);
}
AddCRC(pt);
}
//-----------------------------------------------------------------------------
//main
//main execution loop
//-----------------------------------------------------------------------------
int main(void)
{
// int message structures;
VersionInfo.identifier = XIDENTIFIER_VERSION;
VersionInfo.majorversion = MAJORVERSION;
VersionInfo.minorversion = MINORVERSION;
AnalogData.identifier = XIDENTIFIER_ANALOG;
Exception.identifier = XIDENTIFIER_EXCEPTION;
// PORT D - unused right now
PORTD = 0x10;
DDRD = 0x00;
//Enable TXEN im Register UCR TX-Data Enable & RX Enable
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART RX/TX interrupt enable
// USART Mode: Asynchronous
// USART Baud rate: 57600
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
#ifdef CPUSPEED_20 //20.000MHz
UBRRH=0x00;
UBRRL=0x15;
#endif
#ifdef CPUSPEED_16 //16.000MHz
UBRRH=0x00;
UBRRL=0x10;
#endif
#ifdef CPUSPEED_11059 //11.059MHz
UBRRH=0x00;
UBRRL=0x0B;
#endif
// Enable interrupts
sei();
NeuerDatensatzEmpfangen = 0;
// main loop
while (1)
{
if(NeuerDatensatzEmpfangen==1) {
switch(RxdBuffer[3])
{
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// version request
case XIDENTIFIER_VERSION:
SendOutData('X',0x00,(unsigned char *) &VersionInfo,sizeof(VersionInfo));
break;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case XIDENTIFIER_ANALOG:
break;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
default:
Exception.errorcode = ERRORCODE_NOTIMPLEMENTED;
SendOutData('X',0x00,(unsigned char *) &Exception,sizeof(VersionInfo));
}
NeuerDatensatzEmpfangen=0;
}
}
return(1);
} /* main */