Subversion Repositories Projects

Rev

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 */