VRC Listings

AF104 VRC Monitor Update Description

Änderungsübersicht 14.5.12
1. Anpassungen für Datenaustausch mit Arduino Yun
2. Ausgabe startet nach Bootvorgang automatisch - Debug_ModeActivate()
3. diverse Verzögerungschleifen zwischen einzelnen Parameterausgaben,
    da der Pufferspeicher der Arduino Yun Realisierungs mittels AltSoftSerial
    auf 80 Zeichen begrenzt ist und maximal auf 255 Zeichen
    per #DEFINE konfiguriert werden kann - AbsDelay()
    Hinweis (TODO):
    Verbesserungen durch alternatives Konzept zur Verzögerung jedes einzelnen Zeichens
    um die Zeitdauert der 10 bit Übertragung (Bitratenspezifische Anpassung)
4. Ausgabe optimiert für Baudrate 19200 Bd
5. bislang (für TC65T) auskommentierte Kommandos reaktiviert

AF104 VRC Monitor Listings

Vaillant Heizungssteuerung
(Reverse Engineering Project)

VRC.cc

/*
File:       VRC.cc
Creation:   2009-04-19
Version:    14.5.12  (change #DEFINE VERSION below)
Author:     Michael Gries   (c)2009
IDE-Lib:    2.13.0.15 (06.2011)
*/

/*
Version history:
2009-04-19 Erstellung
2009-06-14 X-Parameter hinzu
2009-12-13 Versionsangabe im Zeitstempel
2010-03-08 Kommando '~' zur Statusabfrage durch TC65T
2011-10-07 Umstellung von IDE-Lib 2.01 auf 2.13.0.15 (06.2011)

*/

// Generic Preprozessor: http://nothingisreal.com/gpp/gpp.html

//------------------------------------------------------------------------------
// Hauptprogramm
//

/*
Verwendete Module (in config entsprechender Reihenfolge):
VRC.cc          Hauptprogramm
Serial.cc       2xRS232 (Kommandointerpreter von TC65 Terminal)
Datagram.cc     Datagramm-Anylsyse von iroVIT-Signal
Ports.cc        Def. benutzter Mega128 Prots der C-Control Pro
Clock.cc        internes Zeitmanagement
EEPROM.cc       internes EEProm handling
Debug.cc        Diagnoseprozeduren
DirectAccess.cc direkter Zugriff auf die Register des MEGA128
String_Lib.cc   (explicit), d.h. nicht als Interpreter Lib eingebunden
ascii.ch        (include Datei), ascii Zeichen
*/

/*
Signature Bytes
All Atmel microcontrollers have a three-byte signature code
which identifies the device. This code can be read in both serial and
parallel mode, also when the device is locked.

The three bytes reside in a separate address space.
For the ATmega128 the signature bytes are:
1. $000: $1E (indicates manufactured by Atmel)
2. $001: $97 (indicates 128KB Flash memory)
3. $002: $02 (indicates ATmega128 device when $001 is $97)
*/



#include ascii.ch   // ASCII Steuerzeichen

#define PRJ         "VRC"
#define PROJECT     "VRC-Monitor"
#define VERSION     "14.5.12"
#define AUTHOR      "Michael Gries"
#define COPYRIGHT   "(c)2009-2014"
#define LIBRARY     "2.13.0.15 (06.2011)"
#ifdef MEGA128
  #define TARGET    "Atmel Mega128"
#else
  #define TARGET    "Atmel Mega32"
#endif



#define TRACE       false

char buffer0[255];
char buffer1[255];
char message[255];
char filename[128];
char function[128];


void main(void)
{
    int sz;
    int inv; inv=1;
    word wsz;
    byte bsz;
    word ws0;
    byte bs0;
    unsigned char value[5];
    int count;

    byte mode;
    /*
    Initialisierungen
    */
    Ports_InitVRC();
    Clock_InitVRC();
    DebugCnt=0; TraceCnt=0; YunCnt=0;
    DebugMode=0;     // Debug mode deactivated - press 'D' for activation
    TraceMode=0;     // default: Trace mode deactived if Heartbeat from TC65T
    YunMode=0;     // Yun mode deactived
    //TraceMode=1;     // Trace mode activated - press 'T' for deactivation

    ATempMin=0x0555;
    ATempMax=0x0016;
    KTempMin=0x0666;
    KTempMax=0x0022;
    WTempMin=0x0777;
    WTempMax=0x0011;
    Brenner=0x0000; BrennerDauer=0x0000;

    mode = Ports_GetMode();
    int baud;  baud=mode;
    message="\r\nMode: ";
    Str_WriteInt(baud,message,STR_APPEND);
    Serial_WriteText(0,message);                  // Text über RS232 ausgeben
    char sline[8];
    filename=__FILE__;
    function=__FUNCTION__;
    char nachricht[100]; nachricht=PROJECT; sline=__LINE__;  //an dieser Stelle
    //debug(__LINE__,__FILE__,"Test");
    //EEPROM_Init();
    //resetEEPROM(); // auskommentieren nach Produktstionsstart
    Serial_InitVRC(baud);

    //prnBetriebsstunden();

    float bs;

    /*     Test EEProm
    bs = EEPROM_GetBetriebsstunden(); bs=bs+0.16;
    EEPROM_SetBetriebsstunden(bs);
    */
    Debug(sline,function,nachricht);

    char para2[10]; Str_WriteWord(SR_BD19200,10,para2,0,6);
    Str_Copy(nachricht,para2,0); sline=__LINE__;
    Debug(sline,function,nachricht);

    /*
    message="\r\nWait 2 seconds ...\r\n";
    Serial_WriteText(0,message); // Text über RS232 ausgeben
    AbsDelay(1000);                 // 1 Sek. Wartezeit

    // Abfrage wieviel Zeichen empfangen wurden
    count=Serial_IRQ_Info(0,RS232_FIFO_RECV);

    // Die Anzahl der Zeichen wird als Meldung ausgegeben
    Msg_WriteWord(count);
    Serial_WriteHex(0,count);
    message=" Zeichen im IRQ-Modus empfangen\r\n\n";
    Msg_WriteText(message);
    Serial_WriteText(0,message);
    */

    Debug_Info();
    AbsDelay(1000);                 // 1 Sek. Wartezeit
    Debug_TraceModeDeactivate();
    AbsDelay(500);                 // 1 Sek. Wartezeit
    Debug_ModeActivate();

    while(true)   // Endlosschleife
    {
        Serial_HandleVRCdata();    // periodische Daten von der iroVIT-Anlage
        Serial_HandleCommands();   // Statusabfragen vom PC oder TC65T

    } // end while
}


    

Yun.cc

/*
File:       Yun.cc
Creation:   2014-05-12
Version:    14.5.12
Author:     Michael Gries   (c)2014
*/

/*
Version history:
14.5.12 Arduino Yun interface added
*/

#define SIZE 67

byte vrcdata[SIZE];
unsigned int octetNo;

void Yun_Print(void)
{
    word w; char s[5];
    for(octetNo=0; octetNo < SIZE; octetNo++)
    {
        w=vrcdata[octetNo];
        Str_WriteWord(w,16,s,0,2);
        Serial_WriteText(0,s);
        AbsDelay(10);   // wichtig: Verzögerung  TODO: tuning
    }
}


    

Datagram.cc

/*
File:       Datagram.cc
Creation:   2009-05-24
Version:    10.3.7
Author:     Michael Gries   (c)2009
*/

/*
Version history:
9.5.24  Datagram analysis added
9.6.6   Char parameterInfo[] added -> Parameter interpretaion
9.6.14  X-Parameter added (veränderlicher unbekannter Parameter)
9.6.16  Wochentag encoding added
9.6.21  Wassertemp Min/Max added
9.12.13 bug fix negative temperature
9.12.27 Datagram_SMSdata() hinzu
10.3.7  Datagram_CSVdata() hinzu
*/


#define SIZE 67

#define posSTATUS   18       // Position Heizstatus
#define posDCF      21       // DCF77 Status
#define posSEK      22       // Sekunden (BCD)
#define posMIN      23       // Minute (BCD)
#define posSTD      24       // Stunde (BCD)
#define posWO       25       // Wochentag (0-6 = M0-S0)
#define posTAG      26       // Tag (BCD)
#define posMON      27       // Monat (BCD)
#define posJAH      28       // Jahr (BCD-zweistellig)
#define posAT       32       // Position Aussentemp
#define posWT       35       // Position Wassertemp
#define posKT       38       // Position Kesseltemp
#define posHK       47       // Position Heizkurve
#define posXPara    52       // Position unbekannter Parameter
#define posWB       64       // Position Winterbetrieb

byte datagram[SIZE];
char parameterInfo[60];
char datavalueInfo[60];
char SMSdata[162];
char SMSdata1[81];
char SMSdata2[81];
char CSVdata[200];
unsigned int pos;

unsigned int Status;
word Brenner; word BrennerLast; word BrennerDauer;
byte DCFstatus;
byte Sek;   byte Min;      byte Std;
byte Tag;   byte Monat;    byte Jahr;
byte Wochentag;  char WOT[3];
word ATemp; word ATempMin; word ATempMax;
word WTemp; word WTempMin; word WTempMax;
word KTemp; word KTempMin; word KTempMax;
word HKurve;
word Betriebsart;
word XPara;

void Datagram_Clear(void)
{
for(pos=0; pos < SIZE; pos++) datagram[pos] = 0;
}

void Datagram_Set(void)
{
for(pos=0; pos < SIZE; pos++) datagram[pos]=0x23;
}

void Datagram_Debug(void)
{
    word w; char s[5];
    for(pos=0; pos < SIZE; pos++)
    {
        w=datagram[pos];
        Str_WriteWord(w,16,s,0,2);
        Serial_WriteText(0,s);
        AbsDelay(10);   // wichtig: Verzögerung  TODO: tuning
    }
}

void Datagram_Analyse(void)
{
   Status=      Datagram_Word(posSTATUS);
   DCFstatus=   Datagram_Byte(posDCF);
   Sek=         Datagram_Byte(posSEK);
   Min=         Datagram_Byte(posMIN);
   Std=         Datagram_Byte(posSTD);
   Wochentag=   Datagram_Byte(posWO);
   Tag=         Datagram_Byte(posTAG);
   Monat=       Datagram_Byte(posMON);
   Jahr=        Datagram_Byte(posJAH);
   ATemp=       Datagram_Word(posAT);
   WTemp=       Datagram_Word(posWT);
   KTemp=       Datagram_Word(posKT);
   HKurve=      Datagram_Word(posHK);
   XPara=       Datagram_Word(posXPara);
   Betriebsart= Datagram_Word(posWB);
   Datagram_TestATemp();
   Datagram_TestKTemp();
   Datagram_TestWTemp();
   Datagram_TestBetriebsstunden();
 }

void Datagram_Print(void)
{
   AbsDelay(500);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nVRC-Status : ";
   Serial_WriteText(0,message);
   Serial_WriteHex(0,Status);
   Datagram_InfoStatus();
   Serial_WriteTextDelayed(0,parameterInfo);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nBrenndauer : ";
   Serial_WriteText(0,message);
   Serial_WriteHex(0,BrennerDauer);
   Datagram_InfoBrennerDauer();
   Serial_WriteTextDelayed(0,parameterInfo);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nDCF-Status : ";
   Serial_WriteText(0,message);
   Serial_WriteHex(0,DCFstatus);
   Datagram_InfoDCF();
   Serial_WriteTextDelayed(0,parameterInfo);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning

   //AbsDelay(500);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nDCF77 Zeit : ";
   Serial_WriteTextDelayed(0,message);
   Datagram_InfoWochentag();
   Str_Printf(message,"20%02d-%02d-%02d %s %02d:%02d:%02d ",
                Jahr,Monat,Tag,WOT,Std,Min,Sek);
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   Clock_SetDCF77();

   message="\r\nAussentemp.: ";
   Serial_WriteTextDelayed(0,message);
   Serial_WriteHex(0,ATemp);
   Datagram_InfoTemp(ATemp);
   Serial_WriteTextDelayed(0,parameterInfo);
   //AbsDelay(200);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nKesseltemp.: ";
   Serial_WriteTextDelayed(0,message);
   Serial_WriteHex(0,KTemp);
   Datagram_InfoTemp(KTemp);
   Serial_WriteTextDelayed(0,parameterInfo);
   //AbsDelay(200);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nHeiz-Kurve : ";
   Serial_WriteTextDelayed(0,message);
   Serial_WriteHex(0,HKurve);
   Datagram_InfoTemp(HKurve);
   Serial_WriteTextDelayed(0,parameterInfo);
   //AbsDelay(200);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nWassertemp.: ";
   Serial_WriteTextDelayed(0,message);
   Serial_WriteHex(0,WTemp);
   Datagram_InfoTemp(WTemp);
   Serial_WriteTextDelayed(0,parameterInfo);
   //AbsDelay(200);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nX-Parameter: ";
   Serial_WriteTextDelayed(0,message);
   Serial_WriteHex(0,XPara);
   //Datagram_InfoTemp(XPara);
   //Serial_WriteText(0,parameterInfo);

   //AbsDelay(500);   // wichtig: Verzögerung  TODO: tuning

   message="\r\nBetriebsart: ";
   Serial_WriteTextDelayed(0,message);
   Serial_WriteHex(0,Betriebsart);
   Datagram_InfoBetriebsart();
   Serial_WriteTextDelayed(0,parameterInfo);
   Serial_WriteNewLine();
   Serial_WriteNewLine();
}

word Datagram_Word(unsigned int ind)
{
  word wh; word wl;
  wh=datagram[ind];  wh=wh<<8;
  wl=datagram[ind+1];
  return wh+wl;
}

byte Datagram_Byte(unsigned int ind)
{ // 9.6.7
  byte b;
  b=datagram[ind];
  return b;
}


void Datagram_InfoBetriebsart(void)
{ // 9.6.6
    parameterInfo=" ";
    switch(Betriebsart)
    {
        case 0x00:  parameterInfo=" = Sommerbetrieb"; break;
        case 0x01:  parameterInfo=" = Winterbetrieb"; break;
    }
}

void Datagram_InfoStatus(void)
{ // 9.6.6 & 11.10.7
    parameterInfo=" ";
    switch(Status)
    {
        case 0x0000:  parameterInfo=" = Bereitschaft";break;
        case 0x0001:  parameterInfo=" = Heizbetrieb"; break;
        case 0x0002:  parameterInfo=" = Warmwasser"; break;
        // 0x0400 geht seit IDE-Lib 2.13.0.15 nicht mehr. Muss unsigned int sein
        case 1024:    parameterInfo=" = Warmwasser (Pumpenachlauf)"; break;
        // 0x0402 geht seit IDE-Lib 2.13.0.15 nicht mehr. Muss unsigned int sein
        case 1026:    parameterInfo=" = Warmwasser (und Pumpe)"; break;
    }
}

void Datagram_InfoBrennerDauer(void)
{ // 9.6.6
    parameterInfo=" ";
    if(BrennerDauer)
    {
        parameterInfo=" = Brenner aktiv";
    } else
    {
        parameterInfo=" = Brenner aus";
    }
}

void Datagram_InfoDCF(void)
{ // 9.6.6
    parameterInfo=" ";
    switch(DCFstatus)
    {
        case 0x00:  parameterInfo=" = kein Empfang"; break;
        case 0x01:  parameterInfo=" = Empfang"; break;
        case 0x02:  parameterInfo=" = Synchonisierung"; break;
        case 0x03:  parameterInfo=" = Signal gueltig"; break;
    }
}

void Datagram_InfoWochentag(void)
{ // 9.6.16
    WOT="--";
    switch(Wochentag)
    {
        case 0x00:  WOT="Mo"; break;
        case 0x01:  WOT="Di"; break;
        case 0x02:  WOT="Mi"; break;
        case 0x03:  WOT="Do"; break;
        case 0x04:  WOT="Fr"; break;
        case 0x05:  WOT="Sa"; break;
        case 0x06:  WOT="So"; break;
    }
}

void Datagram_InfoTemp(word temp)
{ // 9.6.6
    #define DIVIDER 16
    #define OFFSET 0.0
    int g; g=temp;   // due to 16bit value signed
    float f; f=g;
    f=f/DIVIDER+OFFSET;
    Str_Printf(parameterInfo," (%03.1f'C)",f);
    Str_Printf(datavalueInfo,"%03.1f'C ",f);
    // note: char ''' (0x27) used instead of '°'
    // due to valid ascii range 0..128 and char of GSM 03.38 alphabet
}

void Datagram_TestATemp(void)
{ // 9.6.7
    #define DIVIDER 16
    #define OFFSET 0.0
    /*
    Serial_WriteHex(0,ATemp);
    Serial_WriteHex(0,ATempMin);
    Serial_WriteHex(0,ATempMax);
    */
    float f; f = ATemp; f = f/DIVIDER+OFFSET;
    if(ATemp < ATempMin)
    {
        EEPROM_SetAussentempMin(f);
        ATempMin = ATemp;
    }
    if(ATemp > ATempMax)
    {
        EEPROM_SetAussentempMax(f);
        ATempMax = ATemp;
    }
}

void Datagram_TestKTemp(void)
{ // 9.6.7
    #define DIVIDER 16
    #define OFFSET 0.0
    /*
    Serial_WriteHex(0,KTemp);
    Serial_WriteHex(0,KTempMin);
    Serial_WriteHex(0,KTempMax);
    */
    float f; f=KTemp; f = f/DIVIDER+OFFSET;
    if(KTemp < KTempMin)
    {
        EEPROM_SetKesseltempMin(f);
        KTempMin = KTemp;
    }
    if(KTemp > KTempMax)
    {
        EEPROM_SetKesseltempMax(f);
        KTempMax = KTemp;
    }
}


void Datagram_TestWTemp(void)
{ // 9.6.21
    #define DIVIDER 16
    #define OFFSET 0.0
    /*
    Serial_WriteHex(0,WTemp);
    Serial_WriteHex(0,WTempMin);
    Serial_WriteHex(0,WTempMax);
    */
    float f; f = WTemp; f = f/DIVIDER+OFFSET;
    if(WTemp < WTempMin)
    {
        EEPROM_SetWassertempMin(f);
        WTempMin = WTemp;
    }
    if(WTemp > WTempMax)
    {
        EEPROM_SetWassertempMax(f);
        WTempMax = WTemp;
    }
}

void Datagram_TestBetriebsstunden(void)
{ // 9.6.21
    #define DIVIDER 60 //hex value in seconds -> set to minutes
    #define OFFSET 0.0
    Brenner = Status & 0x000F;  // !=0 wenn aktiv
    if(!Brenner && BrennerLast)  // Wechsel auf Brenner aus
    {
        float f; f=BrennerDauer; f=f/DIVIDER+OFFSET;
        float b;
        b = EEPROM_GetBetriebsstunden();
        b =  b + f;
        EEPROM_SetBetriebsstunden(b);
        BrennerDauer=0;
    }
    if(Brenner && !BrennerLast)  // Wechsel auf Brenner an
    {
        BrennerDauer=0;
    }
    if (Brenner && BrennerLast)  // Brenner noch aktiv
    {
        BrennerDauer = BrennerDauer + 0x000A;
    }
    BrennerLast  = Brenner;
}

void Datagram_SMSdata(void)
{   // 9.12.27
    #define SMSMAXLENGTH 160
    SMSdata="Status Heizung (";
    Str_Copy(SMSdata,PRJ,STR_APPEND);
    Str_Copy(SMSdata,".",STR_APPEND);
    Str_Copy(SMSdata,VERSION,STR_APPEND);
    Str_Copy(SMSdata,")",STR_APPEND);
    Str_Copy(SMSdata,"\r\nAussentemperatur: ",STR_APPEND);
    Datagram_InfoTemp(ATemp);
    Str_Copy(SMSdata,datavalueInfo,STR_APPEND);
    Str_Copy(SMSdata,"\r\nKesseltemperatur: ",STR_APPEND);
    Datagram_InfoTemp(KTemp);
    Str_Copy(SMSdata,datavalueInfo,STR_APPEND);
    Str_Copy(SMSdata,"\r\nHeizkurveVorgabe: ",STR_APPEND);
    Datagram_InfoTemp(HKurve);
    Str_Copy(SMSdata,datavalueInfo,STR_APPEND);
    Str_Copy(SMSdata,"\r\nWassertemperatur: ",STR_APPEND);
    Datagram_InfoTemp(WTemp);
    Str_Copy(SMSdata,datavalueInfo,STR_APPEND);
    /*
    Str_Copy(SMSdata,"\r\nAussen: ",STR_APPEND);
    Datagram_InfoTemp(ATempMin);
    Str_Copy(SMSdata,datavalueInfo,STR_APPEND);
    Datagram_InfoTemp(ATemp);
    Str_Copy(SMSdata,datavalueInfo,STR_APPEND);
    Datagram_InfoTemp(ATempMax);
    Str_Copy(SMSdata,datavalueInfo,STR_APPEND);
    */
    word l; l=Str_Len(SMSdata);
    if(l>SMSMAXLENGTH)
    {
        Serial_WriteText(0,"Maximum number of SMS characters exceeded");
    }else
    {
        /*
        Str_Printf(SMSdata1,"%20s",SMSdata);
        Str_Copy(SMSdata2,SMSdata,30);
        Serial_WriteText(PC,SMSdata1);
        AbsDelay(1000);   // wichtig: Verzögerung  TODO: tuning
        Serial_WriteText(PC,"\r\n");
        AbsDelay(1000);   // wichtig: Verzögerung  TODO: tuning
        Serial_WriteText(PC,SMSdata2);
        */
        Serial_WriteTextDelayed(0,SMSdata);
    }
}

void Datagram_CSVdata(void)
{   // 10.3.7
    CSVdata="\r\nCSV;";
    Str_Copy(CSVdata,PRJ,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    Str_Copy(CSVdata,VERSION,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    Str_Copy(CSVdata,LIBRARY,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    Str_Copy(CSVdata,TARGET,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    Str_Copy(CSVdata,sTimestamp,STR_APPEND);
    Str_Copy(CSVdata,";\r\n",STR_APPEND);
    Datagram_InfoTemp(ATemp);
    Str_Copy(CSVdata,datavalueInfo,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    Datagram_InfoTemp(WTemp);
    Str_Copy(CSVdata,datavalueInfo,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    Datagram_InfoTemp(KTemp);
    Str_Copy(CSVdata,datavalueInfo,STR_APPEND);
    Str_Copy(CSVdata,";\r\n",STR_APPEND);

    /*
    Datagram_InfoTemp(ATempMin);
    Str_Copy(CSVdata,datavalueInfo,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    Datagram_InfoTemp(ATemp);
    Str_Copy(CSVdata,datavalueInfo,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    Datagram_InfoTemp(ATempMax);
    Str_Copy(CSVdata,datavalueInfo,STR_APPEND);
    Str_Copy(CSVdata,";",STR_APPEND);
    */
    Serial_WriteTextDelayed(0,CSVdata);
    //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
 }

    

Ports.cc

/*
File:       Ports.cc
Creation:   2009-05-03
Version:    9.6.6
Author:     Michael Gries   (c)2009
*/

/*
Version history:
9.5.3   LED feature added
9.5.23  Mode feature added
9.6.6   pre-processor define statements added:
        concatenated: e.g. MODE -> PD5 -> 29(MEGA128)
*/

#define MODE PD5  // Mode (0=19k2 oder 1=115k2)
#define LED  PG3  // LED  (Datagram Empfang)

#ifdef MEGA128
  #define PD5 29  // Mode (0=19k2 oder 1=115k2)
  #define PG3 51  // LED  (Datagram Empfang)
#endif


void Ports_InitVRC (void)
{
    Port_DataDirBit(MODE,PORT_IN);   // Mode
    Port_WriteBit  (MODE,1);         // Mode (Pull-up aktivieren)
    Port_DataDirBit(LED,PORT_OUT);   // LED
}

byte Ports_GetMode(void)
{
    return Port_ReadBit(MODE);       // Betriebsart lesen
}

void Ports_SetLED(void)
{
    Port_WriteBit(LED,PORT_ON);     // LED an (active low)
}

void Ports_ResetLED(void)
{
    Port_WriteBit(LED,PORT_OFF);    // LED aus (active high)
}

    

Serial.cc

/*
File:       Serial.cc
Creation:   2009-05-22
Version:    9.12.26
Author:     Michael Gries   (c)2009
*/

/*
Version history:
2009-05-22 Erstellung
2009-12-26 Bug beseitigt wenn erstes Zeichen FF
2009-12-27 SMSdata hinzu
*/


void Serial_InitVRC(int baud)
{
  // Serial 0 (to PC or TC65Terminal)
  #define TC65T PC
  #define PC 0
  if(baud==1)
  {
      Serial_Init_IRQ(0,buffer0,100,100,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD19200);
  }else
  {
      Serial_Init_IRQ(0,buffer0,100,100,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD115200);
  }
  // Serial 1  (from iroVIT-VRC interface)
  #define VRC   1
  Serial_Init_IRQ(VRC,buffer1,100,100,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD2400);
}

void Serial_HandleCommands(void)
{
  word w; w=Serial_ReadExt(PC); // read TC65T Command-buffer
  if(!(w==0x100))
  {
    switch(w)
    {
        case 'h':
        case 'H':
        case '?':   Debug_Help();  break;
        case 'y':   Debug_YunModeDeactivate();  break;
        case 'Y':   Debug_YunModeActivateTest();  break;
        case 'd':   Debug_ModeDeactivate();  break;
        case 'D':   Debug_ModeActivateTest();  break;
        case 'a':   EEPROM_PrintAussentempMin();  break;
        case 'A':   EEPROM_PrintAussentempMax();  break;
        case 'b':
        case 'B':   EEPROM_PrintBetriebsstunden();  break;
        case 'c':   Clock_PrintTimestamp();  break;
        case 'i':   Debug_Info();  break;
        case 'k':   EEPROM_PrintKesseltempMin();  break;
        case 'K':   EEPROM_PrintKesseltempMax();  break;
        case 'w':   EEPROM_PrintWassertempMin();  break;
        case 'W':   EEPROM_PrintWassertempMax();  break;
        case 't':   Debug_TraceModeDeactivate();  break;
        case 'T':   Debug_TraceModeActivateTest();  break;
        case '@':   Datagram_CSVdata();  break;
        case '~':   Datagram_SMSdata();  break;
        case ':':   Serial_Write(0,'.'); break;  //Heartbeat from/to TC65T
        case ESC:
        case TAB:   Serial_WriteNewLine(); break;
        case SP:    Serial_WriteMarkLine(); break;
        /*
        case 0x30:  Serial_Write(0,'0'); break;
        case 0x31:  Serial_Write(0,'1'); break;
        case 0x32:  Serial_Write(0,'2'); break;
        case 0x33:  Serial_Write(0,'3'); break;
        case 0x34:  Serial_Write(0,'4'); break;
        case 0x35:  Serial_Write(0,'5'); break;
        case 0x36:  Serial_Write(0,'6'); break;
        case 0x37:  Serial_Write(0,'7'); break;
        case 0x38:  Serial_Write(0,'8'); break;
        case 0x39:  Serial_Write(0,'9'); break;
        default:    Serial_Write(0,w);  // for test purposes only
        */
        default:    DebugCnt=0; TraceCnt=0; YunCnt=0; break;
    }
  }
}

void Serial_HandleVRCdata(void)
{
    char Text1[40];                             // Array deklariert
    char ausgabe[40];
    int sz;
    int inv; inv=1;
    word wsz; byte bsz;
    unsigned char value[5];
    int dCount;

    wsz=Serial_ReadExt(VRC);    // Puffer auslesen
    if(!(wsz==0x100))           //0x100 == Puffer leer
    {
      Ports_SetLED();
      bsz=wsz;
      datagram[pos++]=bsz;
      if((pos==1) && (bsz==0xFF))  // bekannter Übertragungsfehler
      {
        Serial_ErrorFF();
        Ports_ResetLED();
        pos=0;
      }
      //datagram[count]=wsz;
      message="#";
      //Str_Copy(datagram,message,STR_APPEND);
      //count=count+1;
      if(YunMode)
      {
        //Yun_Print();
        Str_WriteWord(wsz,16,value,0,2);   //formatiert ausgeben
        Serial_WriteText(PC,value);
        Serial_Write(PC,' ');
      }
      if(DebugMode)
      {
        Str_WriteWord(wsz,16,value,0,2);   //formatiert ausgeben
        Serial_WriteText(PC,value);
        Serial_Write(PC,' ');
        //Serial_Write(PC,' ');
        // Formatierung nach Datagram-Grenzen (Nr. 1-3,4,5-6,7-8
        if((pos==16)||(pos==31)||(pos==42)||(pos==57))
        {
            Serial_WriteNewLine();
        }
      } else
      {
        if(TraceMode)
        {
            Serial_Write(0,bsz);
        }
      }
      if((wsz==0x22 || wsz==0x23) && (pos>60))
      {
        Ports_ResetLED();
        if(YunMode)
        {
            Serial_WriteNewLine();
        }
        if(DebugMode)
        {
            Serial_WriteNewLine();
            //wsz=sizeof(datagram)*SIZE;
            message="Bytes: ";
            Serial_WriteText(0,message);
            Serial_WriteInt(0,pos);
            Serial_WriteNewLine();
            AbsDelay(300);
            //clearDatagram();
            //setDatagram();
            //Serial_WriteText(0,datagram);
            //Datagram_Debug();
        }
        Datagram_Analyse();
        if(DebugMode)
        {
            Datagram_Print();
            AbsDelay(300);
            Serial_WriteText(0,"\r\nTP: Serial_HandleVRCdata -> Datagram_Print");
            AbsDelay(300);
            Serial_WriteMarkLine();
            AbsDelay(300);
            Serial_WriteText(0,"\r\nTP: Serial_HandleVRCdata -> Datagram_Print 2");
            Serial_WriteNewLine();
        }
        pos=0;
      }
    }   // end serial 1 read
}

void Serial_WriteHex(byte ser, word value)
{
    char sValue[10];
    Str_WriteWord(value,16,sValue,0,4);
    Serial_WriteText(ser,sValue);
}

void Serial_WriteInt(byte ser, word value)
{
    char sValue[10];
    Str_WriteWord(value,10,sValue,0,1);
    Serial_WriteText(ser,sValue);
}

void Serial_WriteTextDelayed(byte ser, char text[])
{
    char linebuffer[255];  linebuffer="";
    Str_Copy(linebuffer,text,STR_APPEND);
    int i; i=0;
    while(linebuffer[i])
    {
        Serial_Write(0,linebuffer[i++]);
        AbsDelay(10);
    }

}

void Serial_WriteNewLine(void)
{
    Serial_Write(0,LF); Serial_Write(0,CR);
}

void Serial_WriteMarkLine(void)
{
   #define TERMINALSIZE 80
Serial_WriteText(0,"\r\nTP: Serial_WriteMarkLine");
AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   Serial_WriteNewLine();
   Clock_UpdateTimestamp();   // into global variable sTimestamp[]
   char cAuthor[40];  cAuthor=" ";
   Str_Copy(cAuthor,COPYRIGHT,STR_APPEND);
   Str_Copy(cAuthor,", ",STR_APPEND);
   Str_Copy(cAuthor,AUTHOR,STR_APPEND);
   Str_Copy(cAuthor," ",STR_APPEND);
   unsigned int a; a=Str_Len(cAuthor);
Serial_WriteText(0,"\r\nTP: Serial_WriteMarkLine 2");
AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
/*
   char cVersion[20];  cVersion=" ";
   Str_Copy(cVersion,PRJ,STR_APPEND);
   Str_Copy(cVersion," ",STR_APPEND);
   Str_Copy(cVersion,VERSION,STR_APPEND);
   Str_Copy(cVersion," ---",STR_APPEND);
   unsigned int v; v=Str_Len(cVersion);
   message="--- ";
   Str_Copy(message,sTimestamp,STR_APPEND);
   unsigned int t; t=Str_Len(message);
   unsigned int f; f=TERMINALSIZE-t-v-a-3;
   char cLine[255]; Str_Fill(cLine,'-',f);
   Str_Copy(message,"---",STR_APPEND);
Serial_WriteText(0,"\r\nTP: Serial_WriteMarkLine 2");
AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
/*
   Serial_WriteText(0,message);
      //AbsDelay(1000);   // wichtig: Verzögerung  TODO: tuning
   message="";
   Str_Copy(message,cAuthor,STR_APPEND);
   Str_Copy(message,cLine,STR_APPEND);
   Serial_WriteText(0,message);
      //AbsDelay(200);   // wichtig: Verzögerung  TODO: tuning
   message="";
   Str_Copy(message,cVersion,STR_APPEND);
   Serial_WriteText(0,message);
   Serial_WriteNewLine();
      //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
*/
}

void Serial_ErrorFF(void)
{
   Serial_WriteNewLine();
   Serial_WriteText(PC,"Bus Error 0xFF at ");
   Clock_UpdateTimestamp();   // into global variable sTimestamp[]
   Serial_WriteText(PC,sTimestamp);
   Serial_WriteNewLine();
    // Abfrage wieviel Zeichen empfangen wurden
   word cntBuffer;
   cntBuffer=Serial_IRQ_Info(VRC,RS232_FIFO_RECV);
        AbsDelay(100);
   Serial_WriteText(PC,"No of received characters: ");
   Serial_WriteInt(PC,cntBuffer);
   Serial_WriteNewLine();

   while(false)      // endlosschleife
   {
     Serial_Write(PC,'.');
     AbsDelay(60000);
   }
}

    

Clock.cc

/*
File:       Clock.cc
Creation:   2009-05-24
Version:    9.5.24
Author:     Michael Gries   (c)2009
*/

// Interpreter Funktionen ab IDE 2.00 (14.05.2009):
// Clock_GetVal();
// Clock_SetDate();
// Clock_SetTime();


char sTimestamp[30];   // Format: "YYYY-MM-DD hh.mm.ss "


void Clock_InitVRC(void)
{   // 9.5.24
    Clock_SetDate(24,05,09);
    Clock_SetTime(21,34,55,0);
}

void Clock_UpdateTimestamp(void)
{
    byte Y; byte M; byte D;
    byte h; byte m; byte s;
    Y=Clock_GetVal(CLOCK_YEAR);
    M=Clock_GetVal(CLOCK_MON);
    D=Clock_GetVal(CLOCK_DAY);
    h=Clock_GetVal(CLOCK_HOUR);
    m=Clock_GetVal(CLOCK_MIN);
    s=Clock_GetVal(CLOCK_SEC);
    sTimestamp="no clock";
    Str_Printf(sTimestamp,"20%02d-%02d-%02d %02d:%02d:%02d ",Y,M,D,h,m,s);
}

void Clock_PrintTimestamp(void)
{
    Clock_UpdateTimestamp();   // into global variable sTimestamp[]
    Serial_WriteText(0,sTimestamp);
}

void Clock_SetDCF77(void)
{
    if(DCFstatus==3)
    {
      Clock_SetDate(Tag,Monat,Jahr);
      Clock_SetTime(Std,Min,Sek,0);
    }
}


    

DirectAccess.cc

/*
File:       DirectAccess.cc
Creation:   2009-12-26
Version:    9.12.26
Author:     Michael Gries   (c)2009
*/

/*
Interpreter Funktionen ab IDE 2.0:
byte DirAcc_Read(byte register);
void DirAcc_Write(byte register, byte val);

for register details see section
'Register Summary' in ATmega128_datasheet.pdf
*/

#define OSCCAL 0x6F

byte DirectAccess_Frequency(void)
{   // 9.12.26
    byte bReg;
    bReg = DirAcc_Read(OSCCAL);
    return(bReg);
}


    

EEPROM.cc

/*
File:       EEPROM.cc
Creation:   2009-04-19
Version:    9.6.14
Author:     Michael Gries   (c)2009
*/

/*
Version history:
9.4.19  Betriebstunden added
9.5.22  Aussen-/Kesseltemperatur added
9.6.14  Warmwassertemperatur added
*/

// EEPROM: Datenspeicherung im internen EEPROM
// erforderliche Library: IntFunc_Lib.cc

// Globale Parameter
// Datenaufzeichnung alle 10 Sekunden
// *6[==min]*60[==h]*24[==d] = 8640 Datensätze pro Tag -> Speichergröße: word

#define adrBetriebsstunden  0x1000  // Datentyp float
#define adrAussentempMin    0x1010  // Datentyp float
#define adrAussentempMax    0x1020  // Datentyp float
#define adrWassertempMin    0x1030  // Datentyp float
#define adrWassertempMax    0x1040  // Datentyp float
#define adrKesseltempMin    0x1050  // Datentyp float
#define adrKesseltempMax    0x1060  // Datentyp float


word Datensatz;
float fBetriebsstunden; // max 65535[h] = 2730[D] = 91[M] = 7[Y]
float fAussentempMin;   // -40.0 ... +80.0 °C
float fAussentempMax;   // -40.0 ... +80.0 °C
float fWassertempMin;   // +10.0 ... +70.0 °C
float fWassertempMax;   // +10.0 ... +70.0 °C
float fKesseltempMin;   // +32.0 ... +95.0 °C
float fKesseltempMax;   // +32.0 ... +95.0 °C

void EEPROM_Init(void)
{
 //adrBetriebsstunden=0x1000;
 float fData;
 char sData[80];
 fData = EEPROM_GetBetriebsstunden();
 fData = fData/10;
 Str_WriteFloat(fData,1,sData,0);
 char sUnit[8]; sUnit = " [h]";
 Str_Copy(sData,sUnit,STR_APPEND);
 Debug_Println(adrBetriebsstunden,sData);
}

void EEPROM_Reset(void)
{
    EEPROM_SetBetriebsstunden(0.0);
    EEPROM_SetAussentempMin(0.0);
    EEPROM_SetAussentempMax(0.5);
    EEPROM_SetWassertempMin(0.0);
    EEPROM_SetWassertempMax(0.5);
    EEPROM_SetKesseltempMin(0.0);
    EEPROM_SetKesseltempMax(0.5);
}


void EEPROM_SetBetriebsstunden(float value)
{
    EEPROM_WriteFloat(adrBetriebsstunden,value);
}

float EEPROM_GetBetriebsstunden(void)
{
    fBetriebsstunden=EEPROM_ReadFloat(adrBetriebsstunden);
    return fBetriebsstunden;
}

void EEPROM_PrintBetriebsstunden(void)
{
    #define DIVIDER 60  // in minutes -> set in hours
    #define OFFSET 0.0
    float fData; fData = EEPROM_GetBetriebsstunden();
    fData = fData/DIVIDER+OFFSET;
    char sData[80]; sData="Betriebsstunden: ";
    Str_WriteFloat(fData,3,sData,STR_APPEND);
    char sUnit[8]; sUnit = " [h]";
    Str_Copy(sData,sUnit,STR_APPEND);
    //println(adrBetriebsstunden,sData);
    Debug_Send(adrBetriebsstunden,sData);
}

void EEPROM_SetAussentempMin(float value)
{
    EEPROM_WriteFloat(adrAussentempMin,value);
}

void EEPROM_SetAussentempMax(float value)
{
    EEPROM_WriteFloat(adrAussentempMax,value);
}

float EEPROM_GetAussentempMin(void)
{
    fAussentempMin=EEPROM_ReadFloat(adrAussentempMin);
    return fAussentempMin;
}

float EEPROM_GetAussentempMax(void)
{
    fAussentempMax=EEPROM_ReadFloat(adrAussentempMax);
    return fAussentempMax;
}

void EEPROM_PrintAussentempMin(void)
{
    float fData; fData = EEPROM_GetAussentempMin();
    char sData[30]; sData="AussentempMin: ";
    Str_WriteFloat(fData,1,sData,STR_APPEND);
    char sUnit[8]; sUnit = " [`C]";
    Str_Copy(sData,sUnit,STR_APPEND);
    //println(adrAussentempMin,sData);
    Debug_Send(adrAussentempMin,sData);
}

void EEPROM_PrintAussentempMax(void)
{
    float fData; fData = EEPROM_GetAussentempMax();
    char sData[30]; sData="AussentempMax: ";
    Str_WriteFloat(fData,1,sData,STR_APPEND);
    char sUnit[8]; sUnit = " [`C]";
    Str_Copy(sData,sUnit,STR_APPEND);
    //println(adrAussentempMax,sData);
    Debug_Send(adrAussentempMax,sData);
}

void EEPROM_SetWassertempMin(float value)
{
    EEPROM_WriteFloat(adrWassertempMin,value);
}

void EEPROM_SetWassertempMax(float value)
{
    EEPROM_WriteFloat(adrWassertempMax,value);
}

float EEPROM_GetWassertempMin(void)
{
    fWassertempMin=EEPROM_ReadFloat(adrWassertempMin);
    return fWassertempMin;
}

float EEPROM_GetWassertempMax(void)
{
    fWassertempMax=EEPROM_ReadFloat(adrWassertempMax);
    return fWassertempMax;
}

void EEPROM_PrintWassertempMin(void)
{
    float fData; fData = EEPROM_GetWassertempMin();
    char sData[20]; sData="WassertempMin: ";
    Str_WriteFloat(fData,1,sData,STR_APPEND);
    char sUnit[8]; sUnit = " [`C]";
    Str_Copy(sData,sUnit,STR_APPEND);
    //println(adrWassertempMin,sData);
    Debug_Send(adrWassertempMin,sData);
}

void EEPROM_PrintWassertempMax(void)
{
    float fData; fData = EEPROM_GetWassertempMax();
    char sData[20]; sData="WassertempMax: ";
    Str_WriteFloat(fData,1,sData,STR_APPEND);
    char sUnit[8]; sUnit = " [`C]";
    Str_Copy(sData,sUnit,STR_APPEND);
    //println(adrWassertempMax,sData);
    Debug_Send(adrWassertempMax,sData);
}

void EEPROM_SetKesseltempMin(float value)
{
    EEPROM_WriteFloat(adrKesseltempMin,value);
}

void EEPROM_SetKesseltempMax(float value)
{
    EEPROM_WriteFloat(adrKesseltempMax,value);
}

float EEPROM_GetKesseltempMin(void)
{
    fKesseltempMin=EEPROM_ReadFloat(adrKesseltempMin);
    return fKesseltempMin;
}

float EEPROM_GetKesseltempMax(void)
{
    fKesseltempMax=EEPROM_ReadFloat(adrKesseltempMax);
    return fKesseltempMax;
}

void EEPROM_PrintKesseltempMin(void)
{
    float fData; fData = EEPROM_GetKesseltempMin();
    char sData[20]; sData="KesseltempMin: ";
    Str_WriteFloat(fData,1,sData,STR_APPEND);
    char sUnit[8]; sUnit = " [`C]";
    Str_Copy(sData,sUnit,STR_APPEND);
    //println(adrKesseltempMin,sData);
    Debug_Send(adrKesseltempMin,sData);
}

void EEPROM_PrintKesseltempMax(void)
{
    float fData; fData = EEPROM_GetKesseltempMax();
    char sData[20]; sData="KesseltempMax: ";
    Str_WriteFloat(fData,1,sData,STR_APPEND);
    char sUnit[8]; sUnit = " [`C]";
    Str_Copy(sData,sUnit,STR_APPEND);
    //println(adrKesseltempMax,sData);
    Debug_Send(adrKesseltempMax,sData);
}


void EEPROM_WriteTimestamp(unsigned int adr)
{
    EEPROM_Write(adr+4+1,Jahr);
    EEPROM_Write(adr+4+2,Monat);
    EEPROM_Write(adr+4+3,Tag);
    EEPROM_Write(adr+4+4,Std);
    EEPROM_Write(adr+4+5,Min);
    EEPROM_Write(adr+4+6,Sek);
}
    

Debug.cc

/*
File:       Debug.cc
Creation:   2009-04-19
Version:    9.12.26
Author:     Michael Gries   (c)2009
*/

/*
Version history:
2009-04-19 Erstellung
2009-05-21 Debug_help() hinzu
2009-12-26 Debug_info() hinzu
*/



#ifdef MEGA128
    #pragma Warning "Counter Funktionen nicht bei Timer0 und Mega128"
#endif

//#ifdef __DEBUG__
#pragma Message __DATE__
#pragma Message __TIME__

int DebugCnt;
int DebugMode;
int TraceCnt;
int TraceMode;
int YunCnt;
int YunMode;

void Debug_YunModeActivateTest(void)
{
    if(++YunCnt > 2)
    {
        Debug_YunModeActivate(); YunCnt=0;
    }
}

void Debug_YunModeActivate(void)
{
    YunMode=1;
    message="\r\nYun mode activated ! - for deactivation press 'y'\r\n";
    Serial_WriteText(0,message);
}

void Debug_YunModeDeactivate(void)
{
    message="\r\nYun mode deactivated ! - for activation press 'YYY'\r\n";
    Serial_WriteText(0,message);
    YunMode=0;
}


void Debug_ModeActivateTest(void)
{
    if(++DebugCnt > 2)
    {
        Debug_ModeActivate(); DebugCnt=0;
    }
}

void Debug_ModeActivate(void)
{
    DebugMode=1;
    message="\r\nDebug mode activated ! - for deactivation press 'd'\r\n";
    Serial_WriteText(0,message);
}

void Debug_ModeDeactivate(void)
{
    message="\r\nDebug mode deactivated ! - for activation press 'DDD'\r\n";
    Serial_WriteText(0,message);
    DebugMode=0;
}

void Debug_TraceModeActivateTest(void)
{
    if(++TraceCnt > 2)
    {
        Debug_TraceModeActivate(); TraceCnt=0;
    }
}

void Debug_TraceModeActivate(void)
{
    TraceMode=1;
    message="\r\nTrace mode activated ! - for deactivation press 't'\r\n";
    Serial_WriteText(0,message);
}

void Debug_TraceModeDeactivate(void)
{
    message="\r\nTrace mode deactivated ! - for activation press 'TTT'\r\n";
    Serial_WriteText(0,message);
    TraceMode=0;
}

void Debug(char sLine[], char sFunction[], char sMessage[])
{
  char txt[81];
  //Str_Fill(txt,' ',80);
  Str_Copy(txt,sLine,0);
  AbsDelay(1000);
  Msg_WriteText(txt);  // Zeilennummer ausgeben
  Msg_WriteChar('-');
  //Str_Copy(txt,sFunction,STR_APPEND);
  Str_Copy(txt,sFunction,0);
  Msg_WriteText(txt);  // Funktionsnamenausgeben
  Msg_WriteChar(':'); Msg_WriteChar(' ');
  //Str_Copy(txt,sMessage,12);
  Str_Copy(txt,sMessage,0);
  Msg_WriteText(txt);  // Nachricht ausgeben
  Msg_WriteChar(13);   // LF
  AbsDelay(1000);
}

void Debug_Print(word adr, byte data)
{
    Msg_WriteHex(adr);              // Ausgabe der Adresse
    Msg_WriteChar(':');             // Ausgabe: :
    Msg_WriteHex(data);             // Ausgabe des Adressinhaltes
    Msg_WriteChar(0x20);            // Ausgabe: Leerzeichen
}

void Debug_Println(word adr, char data[])
{
    char mem[15]; mem="EEPROM-0x";
    Msg_WriteText(mem);             // Ausgabe des Adressinhaltes
    Msg_WriteHex(adr);              // Ausgabe der Adresse
    Msg_WriteChar(':');             // Ausgabe: :
    Msg_WriteChar(' ');            // CR
    Msg_WriteText(data);             // Ausgabe des Adressinhaltes
    Msg_WriteChar(0x20);            // Ausgabe: Leerzeichen
    Msg_WriteChar('\r');            // CR
    Msg_WriteChar('\n');            // LF
}

void Debug_Send(word adr, char data[])
{
    Serial_Write(0,CR);            // CR
    Serial_Write(0,LF);            // LF
    char mem[15]; mem="EEPROM-0x";
    Serial_WriteText(0,mem);             // Ausgabe des Adressinhaltes
    Serial_WriteHex(0,adr);              // Ausgabe der Adresse
    Serial_Write(0,':');             // Ausgabe: :
    Serial_Write(0,' ');            // CR
    Serial_WriteText(0,data);             // Ausgabe des Adressinhaltes
    Serial_Write(0,0x20);            // Ausgabe: Leerzeichen
    //Serial_Write(0,'\r');            // CR
}

void Debug_Help(void)
{
   Serial_WriteNewLine();
   message="VRC-Monitor Helpmenue \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="?   - this menue \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="i   - program info \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message=":   - heartbeat stimulation (returns '.') \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="YYY - Yun mode activation \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="y   - Yun mode deactivation \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="DDD - debug mode activation \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="d   - debug mode deactivation (default)\r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="TTT - trace mode activation \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="t   - trace mode deactivation (default)\r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="a   - Aussentemperatur min \r\n";
   Serial_WriteTextDelayed(0,message);
   message="A   - Aussentemperatur max \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="k   - Kesseltemperatur min \r\n";
   Serial_WriteTextDelayed(0,message);
   message="K   - Kesseltemperatur max \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="w   - Wassertemperatur min \r\n";
   Serial_WriteTextDelayed(0,message);
   message="W   - Wassertemperatur max \r\n";
   Serial_WriteTextDelayed(0,message);
   //AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   message="b   - Betriebsstunden \r\n";
   Serial_WriteTextDelayed(0,message);
   message="@   - Datagram_CSVdata \r\n";
   Serial_WriteTextDelayed(0,message);
   message="~   - Datagram_SMSdata \r\n";
   Serial_WriteTextDelayed(0,message);
   Serial_WriteNewLine();
}


void Debug_Info(void)
{  //9.12.26
   Serial_WriteNewLine();
   Serial_WriteText(PC,PROJECT); Serial_WriteText(PC," version: ");
   Serial_WriteText(PC,VERSION); Serial_WriteText(PC,CRLF);
        AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   Serial_WriteText(PC,"Compilation: "); Serial_WriteText(PC,__DATE__);
   Serial_WriteText(PC,"_");
   Serial_WriteText(PC,__TIME__); Serial_WriteText(PC,CRLF);
        AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   Serial_WriteText(PC,"Directory: ");
   Serial_WriteText(PC,filename); Serial_WriteText(PC,CRLF);
        AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   Serial_WriteText(PC,"Library: ");
   Serial_WriteText(PC,LIBRARY); Serial_WriteText(PC,CRLF);
        AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   Serial_WriteText(PC,"Target: ");
   Serial_WriteText(PC,TARGET); Serial_WriteText(PC,CRLF);
        AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   byte bFreq;
   bFreq=DirectAccess_Frequency();
    //MEGA128   14,7456MHz
    #define OSC 14.7456
   char cValue[20];
   Str_Printf(cValue,"%2.4f MHz\r\n",OSC);
   Serial_WriteText(PC,"Frequency: "); Serial_WriteText(PC,cValue);
   Serial_WriteNewLine();
        AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   Serial_WriteText(PC,COPYRIGHT); Serial_WriteText(PC,", ");
      AbsDelay(100);   // wichtig: Verzögerung  TODO: tuning
   Serial_WriteText(PC,AUTHOR); Serial_WriteText(PC,CRLF);
      AbsDelay(300);   // wichtig: Verzögerung  TODO: tuning
}



    

IntFunc_Lib.cc


void AbsDelay               $opc(0x00)(word val);
void Port_DataDir           $opc(0x01)(byte port,byte val);
void Port_Write             $opc(0x02)(byte port,byte val);
byte Port_Read              $opc(0x03)(byte port);
#ifdef MEGA32
void Timer_T0CNT            $opc(0x04)(void);
byte Timer_T0GetCNT         $opc(0x05)(void);
#endif
word Timer_T1GetCNT         $opc(0x06)(void);
void Timer_T1CNT            $opc(0x07)(void);
void Timer_T1CNT_Int        $opc(0x08)(word limit);
void Timer_T0Start          $opc(0x09)(byte prescaler);
void Timer_T0Stop           $opc(0x0A)(void);
void Timer_T0FRQ            $opc(0x0B)(byte Period,byte PS);
void Timer_T0PWM            $opc(0x0C)(byte PW,byte PS);
void Timer_T0PW             $opc(0x0D)(byte PW);
void Timer_T1Start          $opc(0x0E)(byte prescaler);
void Timer_T1Stop           $opc(0x0F)(void);
void Timer_T1FRQ            $opc(0x10)(word Period,byte PS);
void Timer_T1FRQX           $opc(0x11)(word Period,word skew,byte PS);
void Timer_T1PWM            $opc(0x12)(word Period,word PW0,byte PS);
void Timer_T1PWA            $opc(0x13)(word PW0);
void Timer_T1PWMX           $opc(0x14)(word Period,word PW0,word PW1,byte PS);
void Timer_T1PWB            $opc(0x15)(word PW1);
void LCD_SubInit            $opc(0x16)(void);
word Key_Scan               $opc(0x17)(void);
void LCD_WriteRegister      $opc(0x18)(byte x,byte c);
byte LCD_TestBusy           $opc(0x19)(void);
word ADC_Read               $opc(0x1A)(void);
word ADC_ReadInt            $opc(0x1B)(void);
void ADC_Set                $opc(0x1C)(byte v_ref,byte channel);
void ADC_SetInt             $opc(0x1D)(byte v_ref,byte channel);
void ADC_StartInt           $opc(0x1E)(void);
void ADC_Disable            $opc(0x1F)(void);
void Msg_WriteChar          $opc(0x20)(char c);
void Msg_WriteInt           $opc(0x21)(int val);
void Msg_WriteWord          $opc(0x22)(word val);
void Msg_WriteHex           $opc(0x23)(word val);
void I2C_Init               $opc(0x24)(byte I2C_BR);
void I2C_Start              $opc(0x25)(void);
void I2C_Stop               $opc(0x26)(void);
void I2C_Write              $opc(0x27)(byte data);
byte I2C_Read_ACK           $opc(0x28)(void);
byte I2C_Read_NACK          $opc(0x29)(void);
byte I2C_Status             $opc(0x2A)(void);
void Port_DataDirBit        $opc(0x2B)(byte portbit,byte val);
void Port_WriteBit          $opc(0x2C)(byte portbit,byte val);
byte Port_ReadBit           $opc(0x2D)(byte portbit);
void Serial_Write           $opc(0x2E)(byte serport,byte val);
byte Serial_Read            $opc(0x2F)(byte serport);
void Serial_Init            $opc(0x30)(byte serport,byte par,word divider);
word Serial_ReadExt         $opc(0x31)(byte serport);
void Timer_Disable          $opc(0x32)(byte timer);
void Irq_SetVect            $opc(0x33)(byte irqnr,float vect);
byte Irq_GetCount           $opc(0x34)(byte irqnr);
void Thread_Start           $opc(0x35)(byte thread,float func);
void Thread_Kill            $opc(0x36)(byte thread);
void EEPROM_Write           $opc(0x37)(word pos,byte val);
byte EEPROM_Read            $opc(0x38)(word pos);
void Timer_T0Time           $opc(0x39)(byte Time, byte PS);
void Timer_T1Time           $opc(0x3A)(word Time, byte PS);
void Timer_T1PM             $opc(0x3B)(byte Mode, byte PS);
word Timer_T1GetPM          $opc(0x3C)(void);
byte AComp                  $opc(0x3D)(byte BG);
void Ext_IntEnable          $opc(0x3E)(byte IRQ,byte Mode);
void Ext_IntDisable         $opc(0x3F)(byte IRQ);
void Thread_Delay           $opc(0x40)(word delay);
void Thread_Lock            $opc(0x41)(byte lock);
void Thread_Wait            $opc(0x42)(byte Thread, byte signal);
void Thread_Resume          $opc(0x43)(byte thread);
void Thread_Signal          $opc(0x44)(byte signal);
void Thread_Cycles          $opc(0x45)(byte thread, word cycles);
#ifdef MEGA128
float sqrt                  $opc(0x46)(float val);
float floor                 $opc(0x47)(float val);
float ceil                  $opc(0x48)(float val);
float ldexp                 $opc(0x49)(float val,int expn);
float fabs                  $opc(0x4A)(float val);
float ln                    $opc(0x4B)(float val);
float log                   $opc(0x4C)(float val);
float sin                   $opc(0x4D)(float val);
float asin                  $opc(0x4E)(float val);
float cos                   $opc(0x4F)(float val);
float acos                  $opc(0x50)(float val);
float tan                   $opc(0x51)(float val);
float atan                  $opc(0x52)(float val);
float pow                   $opc(0x53)(float x,float y);
float exp                   $opc(0x54)(float val);
#endif
void Msg_WriteText          $opc(0x55)(char text[]);
void Serial_WriteText       $opc(0x56)(byte serport,char text[]);
void Str_WriteInt           $opc(0x57)(int n,char text[],word offset);
void Str_WriteFloat         $opc(0x58)(float n,byte decimal,char text[],word offset);
word Str_Len                $opc(0x59)(char text[]);
void Str_Copy               $opc(0x5A)(char dest[],char source[],word offset);
char Str_Comp               $opc(0x5B)(char str1[],char str2[]);
void Msg_WriteFloat         $opc(0x5C)(float val);
void Str_WriteWord          $opc(0x5D)(word n,byte base,char text[],word offset,byte minwidth);
word Thread_Info            $opc(0x5E)(byte info);
word Thread_MemFree         $opc(0x5F)(void);
void SPI_Disable            $opc(0x60)(void);
void Serial_Disable         $opc(0x61)(byte serport);
#ifdef MEGA128
word Timer_T3GetCNT         $opc(0x62)(void);
void Timer_T3CNT            $opc(0x63)(void);
void Timer_T3CNT_Int        $opc(0x64)(word limit);
void Timer_T3Start          $opc(0x65)(byte PS);
void Timer_T3Stop           $opc(0x66)(void);
void Timer_T3FRQ            $opc(0x67)(word Period,byte PS);
void Timer_T3FRQX           $opc(0x68)(word Period,word skew,byte PS);
void Timer_T3PWM            $opc(0x69)(word Period,word PW0,byte PS);
void Timer_T3PWA            $opc(0x6A)(word PW0);
void Timer_T3PWMX           $opc(0x6B)(word Period,word PW0,word PW1,byte PS);
void Timer_T3PWMY           $opc(0x6C)(word Period,word PW0,word PW1,word PW2,byte PS);
void Timer_T3PWB            $opc(0x6D)(word PW1);
void Timer_T3Time           $opc(0x6E)(word Time, byte PS);
void Timer_T3PM             $opc(0x6F)(byte Mode, byte PS);
word Timer_T3GetPM          $opc(0x70)(void);
void Timer_T1PWMY           $opc(0x71)(word Period,word PW0,word PW1,word PW2,byte PS);
#endif
word Timer_TickCount        $opc(0x72)(void);
void Serial_Init_IRQ        $opc(0x73)(byte serport,byte ramaddr[],byte recvfifolen,byte sendfifolen,byte par,word divider);
byte Serial_IRQ_Info        $opc(0x74)(byte serport,byte info);
word EEPROM_ReadWord        $opc(0x75)(word pos);
float EEPROM_ReadFloat      $opc(0x76)(word pos);
void EEPROM_WriteWord       $opc(0x77)(word pos,word val);
void EEPROM_WriteFloat      $opc(0x78)(word pos,float val);
byte OneWire_Reset          $opc(0x79)(byte pin);
void OneWire_Write          $opc(0x7A)(byte data);
byte OneWire_Read           $opc(0x7B)(void);
byte SPI_Read               $opc(0x7C)(void);
void SPI_Write              $opc(0x7D)(byte data);
void SPI_ReadBuf            $opc(0x7E)(byte buf[], byte length);
void SPI_WriteBuf           $opc(0x7F)(byte buf[], byte length);
void SPI_Enable             $opc(0x80)(byte ctrl);
#ifdef MEGA128
float round                 $opc(0x81)(float val);
#endif
void Sleep				 	$opc(0x82)(byte ctrl);
void Clock_SetTime		 	$opc(0x83)(byte hour, byte min, byte sec, char corr);
void Clock_SetDate		 	$opc(0x84)(byte day, byte mon, byte year);
byte Clock_GetVal		 	$opc(0x85)(byte indx);
void Port_Toggle		 	$opc(0x86)(byte port);
void Port_ToggleBit		 	$opc(0x87)(byte portbit);
byte DirAcc_Read	   	    $opc(0x88)(byte reg);
void DirAcc_Write		 	$opc(0x89)(byte reg, byte val);
void RC5_Init               $opc(0x8A)(byte	pin);
void RC5_Write              $opc(0x8B)(word data);
word RC5_Read               $opc(0x8C)(void);
void Servo_Set              $opc(0x8D)(byte portbit, word pos);
void Str_Printf             $opc(0x8E)(char str[], char format[], ...);
word Str_ReadNum            $opc(0x8F)(char str[], byte base);
int Str_ReadInt             $opc(0x90)(char str[]);
float Str_ReadFloat         $opc(0x91)(char str[]);
void Servo_Init             $opc(0x92)(byte servo_cnt, byte servo_interval, byte ramaddr[], byte timer);
// mathematische Definitionen
#define PI 3.1415926


// Interrupt Definitionen
#define INT_0         0
#define INT_1         1
#define INT_2         2
#define INT_TIM1CAPT  3
#define INT_TIM1CMPA  4
#define INT_TIM1CMPB  5
#define INT_TIM1OVF   6
#define INT_TIM0COMP  7
#define INT_TIM0OVF   8
#define INT_ANA_COMP  9
#define INT_ADC       10
#define INT_TIM2COMP  11
#define INT_TIM2OVF   12

#ifdef MEGA128
#define INT_3         13
#define INT_4         14
#define INT_5         15
#define INT_6         16
#define INT_7         17
#define INT_TIM3CAPT  18
#define INT_TIM3CMPA  19
#define INT_TIM3CMPB  20
#define INT_TIM3CMPC  21
#define INT_TIM3OVF   22
#endif

// Deklaration der ADC Referenzspannung (max. Eingangsspannung)
#define ADC_VREF_BG  0xC0               // 2,56V interne Referenzspannung
#define ADC_VREF_VCC 0x40               // 5V Referenzspannung
#define ADC_VREF_EXT 0x00               // externe Referenzspannung
                                        // an PAD3 /links neben PortB)
// Deklaration der ADC Kanäle
#define ADC0 0
#define ADC1 1
#define ADC2 2
#define ADC3 3
#define ADC4 4
#define ADC5 5
#define ADC6 6
#define ADC7 7

//differencial input, ADC2 = negativ input
//diff.input +/-9 bit resolution
//bit9=1 => result negativ (two's complement)
//ADC22... können zur Offsetmessung verwendet werden
//Verstärkung: x1, x10, x200
#define ADC22x10    0x0C
#define ADC23x10    0x0D
#define ADC22x200   0x0E
#define ADC23x200   0x0F
#define ADC20x1     0x18
#define ADC21x1     0x19
#define ADC22x1     0x1A
#define ADC23x1     0x1B
#define ADC24x1     0x1C
#define ADC25x1     0x1D


// Port Definitionen
#define PortA 0
#define PortB 1
#define PortC 2
#define PortD 3

#ifdef MEGA128
#define PortE 4
#define PortF 5
#define PortG 6
#endif


// Bit Rate fuer  I2C
#define I2C_100kHz   72
#define I2C_400kHz   12

// String Definitionen
#define STR_APPEND   0xffff


// serielle Schnittstelle
#define SR_5BIT   0x80
#define SR_6BIT   0x82
#define SR_7BIT   0x84
#define SR_8BIT   0x86

#define SR_1STOP  0x00
#define SR_2STOP  0x08

#define SR_NO_PAR     0x00
#define SR_EVEN_PAR   0x20
#define SR_ODD_PAR    0x30


// Baud Rate definitions Oszillatorfrequenz 14,7456MHz
#define SR_BD2400   383    // baudrate    2400bps
#define SR_BD4800   191    // baudrate    4800bps
#define SR_BD9600    95    // baudrate    9600bps
#define SR_BD14400   63    // baudrate   14400bps
#define SR_BD19200   47    // baudrate   19200bps
#define SR_BD28800   31    // baudrate   28800bps
#define SR_BDMIDI    0x8039// baudrate   31250bps MIDI
#define SR_BD38400   23    // baudrate   38400bps
#define SR_BD57600   15    // baudrate   57600bps
#define SR_BD76800   11    // baudrate   76800bps
#define SR_BD115200   7    // baudrate  115200bps
#define SR_BD230400   3    // baudrate  230400bps


// Deklaration der Timer Prescaler Variablen
// ueber den Timer Prescaler wird das Teilungsverhältnis (Oszillatorfrequenz/ps)
// festgelegt. (14,7456MHz/ps)
#define PS_1      1
#define PS_8      2
#define PS_64     3
#define PS_256    4
#define PS_1024   5


// Deklaration der Timer Prescaler Variablen
// ueber den Timer Prescaler wird das Teilungsverhältnis (Oszillatorfrequenz/ps)
// festgelegt. (14,7456MHz/ps)
#ifdef MEGA32
#define PS0_1      1
#define PS0_8      2
#define PS0_64     3
#define PS0_256    4
#define PS0_1024   5
#endif // MEGA32


// Deklaration der Timer Prescaler Variablen für Timer 0 beim MEGA128
// ueber den Timer Prescaler wird das Teilungsverhältnis (Oszillatorfrequenz/ps)
// festgelegt. (14,7456MHz/ps)
#ifdef MEGA128
#define PS0_1      1
#define PS0_8      2
#define PS0_32     3
#define PS0_64     4
#define PS0_128    5
#define PS0_256    6
#define PS0_1024   7
#endif // MEGA128

// Thread_Info  Deklarationen
#define TI_THREADNUM 0
#define TI_STACKSIZE 1
#define TI_CYCLES    2


// RS232 Definitionen
#define RS232_FIFO_RECV 0
#define RS232_FIFO_SEND 1


// Deklaration der I/O Variablen
// die PortPins werden von 0 bis 31 angesprochen (4 Ports a 8 Pins)
// Beispiele: 0=PortA.0, 9=PortB.1
#ifdef MEGA32
#define PORT_LED1 30
#define PORT_LED2 31
#endif


#ifdef MEGA128
//  Application Board PortG
//  LED1=PortG.3, LED2=PortG.4
//  alle ADCs können genutzt werden
#define PORT_LED1 51
#define PORT_LED2 52
#endif

#define PORT_ON    0
#define PORT_OFF   1
#define PORT_OUT   1
#define PORT_IN    0


#ifdef MEGA32
#define PORT_SW1 26
#define PORT_SW2 27
#endif

#ifdef MEGA128
#define PORT_SW1 36
#define PORT_SW2 38
#endif


// Clock
#define CLOCK_SEC  0
#define CLOCK_MIN  1
#define CLOCK_HOUR 2
#define CLOCK_DAY  3
#define CLOCK_MON  4
#define CLOCK_YEAR 5
#define CLOCK_TICK 6


    

String_Lib.cc

/**************************************************************************
 String Library
***************************************************************************/

//-------------------------------------------------------------------------

void Str_Fill(char dest[],char c,word len)
{
    word i;

    for(i=0;i='a' && c<='z') || (c>='A' && c<='Z'));
}

//-------------------------------------------------------------------------

byte Str_Isalnum(char c)
{
    return((c>='0' && c<='9') || Str_Isalpha(c));
}


    

ascii.ch

/*
File:       ascii.ch
Creation:   2009-05-22
Version:    9.5.23
Author:     Michael Gries   (c)2009
*/

// C-Control Pro (Mega128) C-Compact definition file

#define NUL 0x00
#define TAB 0x09
#define CR  '\r'
#define LF  '\n'
#define CAN 0x18
#define ESC 0x1B
#define SP  0x20
#define DEL 0x7F

#define CRLF "\r\n"
///