Schnittstelle zur microSPS

Fork of com_0 by V09

Revision:
0:3eabf0cac42a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/com.cpp	Sat Jan 03 15:25:35 2015 +0000
@@ -0,0 +1,351 @@
+
+//---------------------------------------------------------------------------
+// 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;
+}
+
+
+