Schnittstelle zur microSPS

Fork of com_0 by V09

com.cpp

Committer:
rs27
Date:
2015-01-03
Revision:
0:3eabf0cac42a

File content as of revision 0:3eabf0cac42a:


//---------------------------------------------------------------------------
// Modul...: COM.CPP    
// Chip....: KL25Z
// 
//---------------------------------------------------------------------------
// Author..: Reinhold Schäfer
// Date....: 2014.06.08
// http....: //www.microsps.net
//---------------------------------------------------------------------------
#include <stdarg.h>
#include <ctype.h>
#include "mon.h"
#include "MODSERIAL.h"
#include "SDFileSystem.h"
#include "FATDirHandle.h"
#include "myTextLCD.h"
#include "timer0.h"

#define LED_OFF 1
#define LED_ON  0
#define COM_LINE_LEN 128              // maximale Länge der Eingabezeile  
#define TEL_SIZE 10

#define XON     0x11
#define XOFF    0x13

struct com_struct 
{
    uint8_t flag;                     // Flag zur Steuerung
    uint8_t sm;                       // State maschine
    uint8_t index;                    // Index für Zeichenzähler
    uint8_t len;                      // Zeichenzähler für Telegramlänge
    uint8_t nr;                       // Zähler für array
    uint8_t byte[10];                 // Bytes für Zwischenablage
    char line[COM_LINE_LEN];
};

extern MODSERIAL pc;        // definiert in main
extern MODSERIAL uart1;     // definiert in main, tx, rx
extern TextLCD lcd;
extern timer0 down_timer;   // Timer für Zeitsteuerung
extern DigitalOut led3;     // definiert in main
extern DigitalOut lcd_bl;   // definiert in main, Hintergrundbeleuchtung
extern PwmOut lcd_kontrast; // Kontrast wird über PWM gesteuert

// Bitposition und Belegung
//  bit 1 CR Flag
//  bit 2 byte speichern
//  bit 4
//  bit 8

struct com_struct com;      // Schnittstelle zur microSPS

void com_init(void)
{
    uint8_t i;
    
    led3 = LED_OFF;

    
    // Speicher für die Eingangszeile löschen
    for (i=0; i < COM_LINE_LEN; i++) 
    {
        com.line[i] = 0;
    }
    com.flag = 0;
    com.sm  = 0;
    com.index = 0;
}       
        
// Bitposition und Belegung
//  bit 1 Daten speichern in aktion
//  bit 2 Datei anlegen
//  bit 4 Daten schreiben
//  bit 8 Datei schließen


// In dieser therad werden Daten aus der Seriellen Schnittstelle gelesen. Nach dem lesen
// von einem Telegramm wird dieses falls es für das Speicher verwendet wird in m_msd abgelegt.
// Die anderen Telergamme und die Antworten werde in dieser thread gleich bearbeitet.

void com_line(void)
{

    char ch;
    uint8_t n;
    int i;
    FILE *fp;
    
    while (true) 
    {
        if (uart1.readable())
        {
            led3 = 0;
            
            // Falls mehr Zeichen ankommen als verarbeitet werden, wird die microSPS gebremst
            //i = uart1.rxBufferGetCount();
            //if (i > 800) // buffer hat 1014 Zeichen
            //{
            //  uart1.putc(XOFF);
            //  pc.printf("\nrxBuffer XOFF %d",i);    
            //}
            
            //----------------------------------------------------------------------------------------------------
            // Eingehende Zeichen lesen und abspeichern           
            
            ch = uart1.getc();                                              // Zeichen lesen und auswerten
            // pc.printf("\ntel> SM[%02d]",com.sm);            
            
            com.line[com.index] = ch;                                       // Zeichen einfuegen
            com.index++;                                                    // Zeichenzähler erhöhen
            if (com.index >= 80) com.sm = 100;                              // ein Telegramm enthält maximal 80 Zeichen
            /*         
            for (i = 0; i < com.index; i++)
            {
               pc.printf(" %02x",com.line[i]);   
            }           
            
            pc.printf("\n"); 
            */
            //----------------------------------------------------------------------------------------------------
            // auf Startzeichen auswerten 
            
            switch (com.sm)   // com.sm ist state machine
            {
                case 0 :      // erstes Zeichen aus einem Telegramm
                    
                    if (ch == 0xE5) com.sm = 1;                             // Telegramm erstes Startzeichen wurde erkannt
                    if (ch == 0x00) com.sm = 100;                           // 0 ist kein gültiges Telegramm
                    break;                
                
                case 1 :      // zweites Zeichen aus einem Telegramm
                
                    if (ch == 0x02) com.sm = 2;                             // Telegramm zweites Startzeichen wurde erkannt
                    if (ch != 0x02) com.sm = 100;                           // 0 ist kein gültiges Telegramm
                    break;
                    
                 case 2 :     // Command byte auswerten   
                    
                    switch(ch) 
                    {
                        case 0x00:
                            com.sm = 100;                                   // bei 0 wieder von vorne starten
                            break;
                            
                        case 0x04:                                          // RESET Kennung
                        case 0x06:                                          // Zeit Stempel lesen
                        case 0x10:                                          // LCD löschen
                        case 0x11:                                          // Hintergundbeleuchtung aus
                        case 0x12:                                          // Hintergundbeleuchtung an
                        case 0x13:                                          // Cursor setzen
                        case 0x14:                                          // Text für die LCD Anzeige
                            com.sm = 5;                                     // nur ein Zeichen
                            break;
                        
                        case 0x15:                                          // Text für die LCD Anzeige mit Positionsangabe    
                        case 0x20:
                            com.sm = 5; 
                            break;
                                    
                        default:                                            // Zeichen zum abspeichern
                            uart1.puts("\nsm CMD unbekannt");
                            com.sm = 12;                                    // Speicher löschen
                            break;
    
                    }   // ende SWITCH
                     
                    break; // end case 0:
                
                case 5:  // Telegrammlänge ermitteln, danach folgt Text
                    
                    com.len = ch;
                    com.nr = 0;
                    if (com.len == 0xff) 
                    {
                        com.sm = 11;
                    }
                    else 
                    {
                        com.sm = 7; 
                    }            
                    break;                
                
                case 7:  // Index Zeichen lesen    
                    com.byte[com.nr] = ch,
                    com.nr++;
                    com.len--;
                    if (com.len == 0) 
                    {
                        com.sm = 12;
                        
                        // Telegramm zum Testen ausgeben
                        /*
                        pc.printf("\ntel: ");
                        for(i=0; i <= com.index; i++)
                        {
                          pc.printf(" %02x",com.line[i]);
                        }
                        */
                    }
                    break;
                    
                case 11:
                    //----------------------------------------------------------------------------------------------------
                    // bis Abschlussbit alle Zeichen lesen und bei Abschlußzeichen die Auswertung angehen
                    // bei einer Zeichenkette bis 00 lesen

                    if (ch == 0x00) 
                    {
                        com.sm = 12;
                        
                        // Telegramm zum Testen ausgeben
                        /*
                        pc.printf("\ntel ");
                        for(i=0; i < com.index; i++)
                        {
                          pc.printf(" %02x",com.line[i]);
                        }
                        */
                    }                       

                    break; // end case 1:
                
            } // end switch

            //----------------------------------------------------------------------------------------------------            
            // Hier werden die Telegramme ausgewertet
            
            if (com.sm == 12)   // Hardware Reset
            {
                switch (com.line[2])
                {
                    case 0x04:
                        char buffer[40];
                        fp = fopen("/sd/log.txt", "a");
                        if(fp == NULL) 
                        {
                            pc.printf("\ncom_line #4 Could not open file for write");
                        }
                        else
                        {    
                            strftime(buffer, 40, "%a,%d.%m.%Y %H:%M:%S", localtime(&down_timer.seconds));
                            fprintf(fp, "\n%s Reset %02x ", buffer,com.line[4]);
                        }
                        fclose(fp); 
                        pc.printf("\n%s RESET %02x\n",buffer,com.line[4]);
                        break;
                    
                    case 0x06:    // Systemzeit setzen
                        com.line[9] += 80;      // Zeitstempel für Jahr ist beim RTC 1980 und bei kl25z 1900
                        //
                        // pc.printf("\n telegramm #6 "); 
                        // for (i = 0; i < 12; i++)
                        // {
                        //   pc.printf(" %02x",com.line[i]);    
                        // }
                        // pc.printf("\n");
                        down_timer.Set_t((uint8_t *)&com.line[4]);
                        break;
                        
                    case 0x10:    // LCD löschen   
                        lcd.cls();
                        break;

                    case 0x11 :   // LCD backlight off
                        lcd_bl = 0;
                        break;                      

                    case 0x12 :   // LCD backlight on
                        lcd_bl = 1;
                        break;
                     
                     case 0x13:    // Cursor setzen 
                        //pc.printf("\nCursor setzen %d %d",com.line[4],com.line[5]);
                        lcd.locate(com.line[4], com.line[5]);
                        break;
                                               
                     case 0x14:    // Text auf LCD ausgeben   
                        //pc.printf("\nLCD '%s'",&com.line[4]);
                        lcd.printf("%s",&com.line[4]); 
                        lcd.writeLCD();
                        break;                                            
                    
                     case 0x15:    // Text auf LCD ausgeben   
                        lcd.locate(com.byte[0], com.byte[1]);
                        lcd.printf("%s",&com.line[6]); 
                        lcd.writeLCD();
                        break;                       
                     
                     case 0x20:
                        char name[] = "/sd/SD_000.CSV"; // create a file name
                        
                        // Dateiname bilden
                        uint8_t index = com.byte[0];
                        n = index / 100;
                        name[7] = n + '0';
                        index -= n * 100;
                        name[8] = index/10 + '0';
                        name[9] = index%10 + '0';  
                        
                        // Daten abspeichern
                        fp = fopen(name, "a");
                        if(fp == NULL) 
                        {
                            pc.printf("\ncom_line #20 Could not open file for append");
                        }
                        else
                        {    
                            fprintf(fp, "%s",&com.line[5]);
                            // pc.printf("\nfile %d %s",com.byte[0],&com.line[5]);
                        }
                        fclose(fp);                      
                        break;
                        
                    default:    // ungültiges Telegram
                        
                        pc.printf("\nTelegramm 02 ungueltiges Zeichen %02x\n",com.line[2]);  
                        break;
                } // end switch
                
                com.sm = 100; // Eingabe wieder löschen 
                
            } // end if (com.sm == 8)
  
            
            //----------------------------------------------------------------------------------------------------
            // Zeile wieder löschen            
            
            if (com.sm == 100)
            { 
                // uart1.puts("\nsm 12 Speicher loeschen");
                
                for (i = 0; i < COM_LINE_LEN; i++) com.line[i] = 0x00;
    
                com.index = 0;
                com.flag = 0;
                com.sm = 0;
                break;  // nach einem Befehl wieder zum Hauptprogramm verzweigen
             }      
             
        } // end if (uart1.readabel
        else break;      
    
   } // end while(1)
   
   led3 = 1;
}