Schnittstelle zur microSPS
Fork of com_0 by
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; }