Monitor für das Tasterprogramm

Dependents:   19_Taster_BSW_oo 19_Taster_a

Fork of monitor by Temp27

monitor.cpp

Committer:
mauchcontrols
Date:
2015-08-18
Revision:
9:7bd52cbe4782
Parent:
8:99a94e782c8a

File content as of revision 9:7bd52cbe4782:


#include <stdarg.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mbed.h"
#include "main.h"
#include "monitor.h"
#include "FreescaleIAP.h"

extern "C" void mbed_reset();

extern MODSERIAL pc;

extern DigitalOut OUT1;      // Summer
extern DigitalOut OUT2;      // LED Rot
extern DigitalOut OUT3;      // LED Grün
extern DigitalOut OUT4;      // LED Gelb
extern DigitalOut OUT5;      // nicht belegt
extern DigitalOut OUT6;      // Relais


extern DigitalIn IN1;        // nicht belegt
extern DigitalIn IN2;        // nicht belegt
extern DigitalIn IN3;        // Signalstation, Öffner => null im Ruheezustand ?
extern DigitalIn IN4;        // Sabotageschalter, nach Zeichnung müsste 1 der Ruhezustand sein => null ist Ruhezustand ?
extern DigitalIn IN5;        // Notaus, Öffner gegen GND => 0 ist der Ruhezustand

// test von variablen

int i = 0;

#define COMMAND_MAX    9
#define COMMAND_LEN    7
const char command[COMMAND_MAX][COMMAND_LEN] = {"DATE","DUMP","FLASH","HELP","IN","OUT","RESET","RGB","TIME"};

//-----------------------------------------------------------------------------
// destructor

monitor::monitor(void)
{
    uint8_t i;
    
    for (i = 0; i < COM_LINE_LEN; com_line[i++] = 0);
    ComLinePtr = ComLineTop = 0;
    cr_flag = false;        
}

//-------------------------------------------------------------------------------
// _atoi
//
uint8_t monitor::_atoi(char c)
{
    if ((c >= '0') && (c <= '9')) return (c - '0');
    if ((c >= 'a') && (c <= 'f')) return ((c - 'a') + 10);
    if ((c >= 'A') && (c <= 'F')) return ((c - 'A') + 10);
    return 0;
}


//-----------------------------------------------------------------------------
// parser

/*-------------------------------------------------------------------------*/
/*                                                                         */
/*  Synopsis    :  void parser (void)                                      */
/*                                                                         */
/*  Funktion    :                                                          */
/*                                                                         */
/*  Analysiert das Kommando und springt die entsprechende Routine aus der  */
/*  Kommandotabelle an. Die Kommandos mssen in der Tabelle alphabetisch   */
/*  sortiert sein. Der Index in der Kommandotabelle entspricht dem in der  */
/*  Sprungtabelle. Die Suche nach dem Buchstaben beginnt beim Ersten mit-  */
/*  tels der bin„ren Suche. Alle restlichen Zeichen werden durch String-   */
/*  vergleiche nach der gleichen Methode ermittelt.                        */
/*                                                                         */
/*-------------------------------------------------------------------------*/

void monitor::parser (char p_line[])
{
  char  ch, tch;
    uint8_t i, top, bottom, len;
  int res;

    // die Eingabe in Großbuchstaben umwandeln                             

  for (i = 0; !(com_line[i] == 0 || com_line[i] == ' '); i++)
    com_line[i] = toupper (com_line[i]);

  /* Zuerst wird der erste Buchstabe aus dem Eingabestring mit den ersten */
  /* Buchstaben aus der Befehlstabelle verglichen                         */

  bottom = 0;                                        /* untere Suchgrenze */
  tch = 0;
  top = COMMAND_MAX;                                 /* obere Suchgerenze */
  ComLinePtr = 0;                       /* Parameterübergabe auf 0 setzen */
  ch = p_line[0];                              /* hole erstes Suchzeichen */
  
  do 
  {
    i = (top + bottom) >> 1;    /* suche in der Mitte des Feldes beginnen */
    tch = (char) command [i][0];                   /* Vergleichszeichen laden */
    if (tch == ch) break;                             /* Zeichen gefunden */
    if (tch > ch) top = i;                           /* nach unten suchen */
    else bottom = i;                                  /* nach oben suchen */
    if (bottom != 0 && top == bottom + 1) break;   /* kein Buchstabe gef. */
  
  } while (i > 0 && i < COMMAND_MAX - 1);

  if (tch != ch)
  {
    pc.printf("\nParser, Kommando nicht gefunden\n");
    return;                              /* Kommando nicht gefunden wurde */
  }
  
  /* das erst Wort soll von den Übergabeparametern isoliert werden        */
  
  for (i = 0; p_line[i] != ' ' &&  p_line[i] != 0; i++);
  len = i;

  
  if (i == 0) return;

  /* die Übergabparameter ermitteln und in als Indexzeiger in            */
  /* 'ComLinePtr' abspeichern                                            */

  for ( ; p_line[i] == ' ' && p_line[i] != 0; i++);
  ComLinePtr = i;


   /* die binäre Suche nach den restlichen Zeichen wird hier fortgesetzt */

  do
  {
    i = (top + bottom) >> 1;                 /* berechnen des Suchplatzes */
    // pc.printf("\nVergleich [%d] com_line [%s] command [%s] Länge [%d]",i,com_line, &command[i][0],len);
    res = strncmp(p_line, &command[i][0], len);
    // pc.printf("\nErgebnis res = [%d]",res);
    if (res == 0) break;                     /* Zeichen gefunden */
    if (res > 0) 
      bottom = i;                            /* nach unten suchen */
    else 
      top = i;                             /* nach oben suchen */
    if (bottom != 0 && top == bottom + 1) break;
  
  } while (i > 0 && i < COMMAND_MAX - 1);

  
  if (res) 
  {
    pc.printf("\nParser, Kommando nicht gefunden.\n");
  }
  else 
  {
    // "DATE","DUMP","HELP","RESET","RGB","TIME"
    // pc.printf("\nAufruf von Funktion %d",i);
    switch (i)  // Programmaufruf
    {
            case  0:  mdate();          break;
            case  1:  dump();           break;
            case  2:  flash();          break;
            case  3:  help();           break;
            case  4:  in();             break;
            case  5:  out();            break;
            case  6:  soft_reset();     break;
            case  7:  rgb();            break;
            case  8:  mtime();          break;
     }
       
  }
}


//-----------------------------------------------------------------------------
// eine Zeile aus dem Eingangsbuffer lesen 
  
void monitor::get_line(void)
{
  // char ch;
  uint8_t i;
   
  get_ch();
  if (cr_flag)                            // Neue Eingabezeile  
  {
    if (com_line[0] != 0)
    {
      // uart_puts(com_line);           // zum Testen => später wird der parcer aufgerufen
      parser(&com_line[0]);                                   // Parcer wird aufgerufen
    }

    for (i=0; i < COM_LINE_LEN; com_line[i++] = 0);
    ComLinePtr = ComLineTop = 0;                         
    cr_flag = 0;                                   // Parcer wird aufgerufen
  }    
}

//-----------------------------------------------------------------------------
// eine Zeichen aus dem Eingangsbuffer lesen 

void monitor::get_ch (void)
{
  char ch;
  
  if (!pc.readable()) return;                 // kein Zeichen vorhanden 
     
    ch = pc.getc();                             // hole das Zeichen  
    // printf("mon_line: %c %02x\n",ch,ch);     // nur zum Test

    switch(ch) 
    {
        case '\r':     // CARRIAGE RETURN  
                cr_flag = true;
                break;

        case '\n':      // LF empfangen
                cr_flag = true;
                break;

        default:                                 // Normales Zeichen  
                if (~iscntrl(ch)) 
                {
                    com_line[ComLinePtr] = ch;       // Zeichen einfuegen 
                    ComLinePtr++;
                }
                break;

    }   // Ende SWITCH

    if (ComLinePtr >= 80) cr_flag = 1;           // Zeilenüberlauf ?  
    
}

//-----------------------------------------------------------------------------
// monitor Aufruf

void monitor::mdate(void)
{
  int day, month, year, n; 
  
    n = 0;
    day = 0;
    month = 0;
    year = 0;

    n = sscanf(&com_line[ComLinePtr],"%d %d %d",&day, &month, &year);

    // seconds = time(NULL);

    struct tm t, *tp;
    time_t seconds = time(NULL);
    tp = localtime(&seconds);
    t = *tp;    
    
    switch (n)
    {
        case -1 :  // keine Zeichenübergabe
        case  0 :  // keine Zeichenübergabe

                        pc.printf("\ndate %02d.%02d.%04d",t.tm_mday, t.tm_mon + 1, t.tm_year + 1900);
                        break;

        case 1 :   // day
        case 2 :   // month
        case 3 :   // year
                    
                        if (day > 31) day = 31;
                        if (day < 1) day = 1;

                        if (month > 12) month = 12;
                        if (month < 0) month = 0;
                    
                        if (year > 2053) year = 2053;
                        if (year < 2013) year = 2013;
                    
                        // setup time structure for Wed, 11 April 2013 5:00:00
                        // t.tm_sec = sek;          // 0-59
                        // t.tm_min = min;          // 0-59
                        // t.tm_hour = std;         // 0-23
                        t.tm_mday = day;            // 1-31
                        t.tm_mon = (month - 1);   // 0-11 >> prüfen warum 0 bis 11 ???
                        t.tm_year = (year - 1900); // year since 1900

                        // Set RTC time today
                        set_time(mktime(&t));       
            
                        pc.printf("\nnew date %02d.%02d.%04d",t.tm_mday, t.tm_mon+1, t.tm_year + 1900);
                        break;
  }  // end while 

}

void monitor::flash()
{
  int n, address, val;
  uint8_t _val;
  
  address = 0;
  val = 0;
  char *p;
  
  n = sscanf(&com_line[ComLinePtr],"%d %d", &address, &val);
  
  // Abfrage der Eingabe
  
  if ((n == -1) || (n == 0))
  {
    pc.printf("\nder letzte Speicherblock wird fuer Variablen verwendet");  
    pc.printf("\n flash adr [value]");
    pc.printf("\n   adr     ist die Adresse im ausgewaehlten Block");
    pc.printf("\n   value   ist der Wert der als INT abgespeichert wird"); 
    pc.printf("\n   bei der Adresse -1 wird der flash Speicher geloescht");
    pc.printf("\n");
  }
  
  if (n == 1)
  {
    if (address == -1)
    {
      address = 0x1fc00;
      //Erase sectors of 4096 bytes
      pc.printf("\nflash erace");
      erase_sector(address);
      return;  
    }
    
    address += 0x1fc00;
    p = (char*)address;
    pc.printf("\nflash data = %d oder 0x%02x",*p);  
  } 
  
  if (n == 2)
  {
    address += 0x1fc00;
    _val = (uint8_t) val;
    if (program_flash(address, (char*)&_val, 4) != 0) {// 1 bytes 
        pc.printf("\nData Write Error!");   
    } else {
        pc.printf("\nData Write Success!");  
    }   
  }    
}

//-----------------------------------------------------------------------------
// monitor Aufruf

void monitor::dump(void)
{
    char c, szBuf[17];
    //uint16_t lOutLen;
    unsigned int lSize, n;
    unsigned long adr;

    char *p;


    adr = 0x1fc00; // letzter Block
    lSize = 100;

    n = sscanf((char *)&com_line[ComLinePtr],"%lx %u",&adr, &lSize);

    pc.printf( "\ndump from 0x%08X for %d bytes", adr, lSize );

    p   = (char *)adr;

    for ( int i = 0; i < lSize; i++, p++, n++ ) 
    {
        if ( !(i % 16) )
        {
            if (i > 0) pc.printf(" %s",szBuf);
                             
            for (n = 0; n < 16; n++) szBuf[n] = ' ';
            szBuf[16] = 0; // nullterminierter String
    
            n = 0;

            pc.printf( "\r\n  0x%08X :", (unsigned int)p );
        }
        
        c = *p;
    if ((c >= 0x30) && (c <= 128))szBuf[n] = c;
    else szBuf[n] = '.';
        
    pc.printf( " %02x", c ); 
  }

  pc.printf( "\r\n" );

}


//-----------------------------------------------------------------------------
// monitor Aufruf

void monitor::help(void)
{
    pc.printf("\n -- help ------------------------");
    pc.printf("\n date  dd mm jjjj >> Datum abfragen / setzen");
    pc.printf("\n dump  Speicherbereich ausgeben");
    pc.printf("\n flash Speicherbereich letzter Block fuer Variablen");
    pc.printf("\n in    Lesen und Anzeigen der digitalen Eingaenge");
    pc.printf("\n out [x] [y] [t] Schalten der Ausgaenge ");
    pc.printf("\n rgb   Testen der LED's ");
    pc.printf("\n reset Soft Reset ausfuehren ");
    pc.printf("\n time  hh mm ss >> Zeit abfragen / setzen");
    pc.printf("\n");      
}

//-----------------------------------------------------------------------------
// monitor Aufruf

void monitor::mtime(void)
{
    int std,min,sek, n;
    
    std = 0;
    min = 0;
    sek = 0;

    n = sscanf(&com_line[ComLinePtr],"%d %d %d",&std, &min, &sek);
    
    struct tm t, *tp;
    time_t seconds = time(NULL);
    tp = localtime(&seconds);
    t = *tp;    
    
    switch (n)
    {
        case -1 :  // keine Zeichenübergabe
        case  0 :  // keine Zeichenübergabe

                pc.printf("\ntime %02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
                break;
            
        case 1 :   // std
        case 2 :   // min
        case 3 :   // sek
                    
    
                if (sek > 59) sek = 59;
                if (sek < 0) sek = 0;

                if (min > 59) min = 59;
                if (min < 0) min = 0;
                
                if (std > 23) std = 23;
                if (std < 0) std = 0;
                
              // setup time structure for Wed, 11 April 2013 5:00:00
                t.tm_sec = sek;    // 0-59
                t.tm_min = min;    // 0-59
                t.tm_hour = std;   // 0-23
                // t.tm_mday = 23;   // 1-31
                // t.tm_mon = 6;     // 0-11
                // t.tm_year = 113;  // year since 1900
    
                // Set RTC time today
                set_time(mktime(&t));
        
                pc.printf("\nnew time %02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
                break;
  }
}

//------------------------------------------------------------------------
// ein RESET ausführen

void monitor::soft_reset(void)
{
    pc.printf("\nauf WDT Reset warten");
    // mbed_reset();
    while(1);           // auf watchdog warten
}

//------------------------------------------------------------------------
// die LED's testen
//
// DigitalOut OUT2;      // LED Rot
// DigitalOut OUT3;      // LED Grün
// DigitalOut OUT4;      // LED Gelb
//

void monitor::rgb(void)
{
  bool out2, out3, out4;
  
  pc.printf("\nLED TEST");
  out2 = OUT2;
  out3 = OUT3;
  out4 = OUT4;
  
  OUT2 = LED_AUS;
  OUT3 = LED_EIN;
  OUT4 = LED_AUS;
  
  pc.printf("\n gruene LED an");
  wait(1);

  OUT2 = LED_AUS;
  OUT3 = LED_AUS;
  OUT4 = LED_EIN;
  
  pc.printf("\n gelbe LED an");
  wait(1);
  
  OUT2 = LED_EIN;
  OUT3 = LED_AUS;
  OUT4 = LED_AUS;
  
  pc.printf("\n rote LED an");
  wait(1);
  
  OUT2 = out2;
  OUT3 = out3;
  OUT4 = out4;
      
}

//------------------------------------------------------------------------
// die Ausgänge 1 bis 5 ansteuern ( für eine Sekunge aktiv schalten
//
// DigitalOut OUT1;      // nicht belegt    lo aktiv
// DigitalOut OUT2;      // LED Rot         lo aktiv
// DigitalOut OUT3;      // LED Grün        lo aktiv
// DigitalOut OUT4;      // LED Gelb        lo aktiv
// DigitalOut OUT5;      // Summer          hi aktiv
// DigitalOut OUT6;      // Relais          lo aktiv
// 


void monitor::out(void)
{
  int n, x, y;
  bool out;
  float w_zeit;
  
  x = 1;
  y = 0;
  w_zeit = 10;
  
  n = sscanf(&com_line[ComLinePtr],"%d %d %f", &x, &y, &w_zeit);
  
  // Abfrage der Eingabe
  
  if ((n == -1) || (n == 0))
  {
    pc.printf("\ntest der digitalen Ausgaenge");  
    pc.printf("\n out x y t");
    pc.printf("\n     x ist die Nummer des Ausgangs 1 bis 5");
    pc.printf("\n     y ist der Schaltzustand 0 oder 1"); 
    pc.printf("\n     t ist die Zeit in Sekunden 0 bis 1000"); 
    pc.printf("\n");
    pc.printf("\n Ausgang 1 (Summer) = %d",(uint8_t)OUT1);
    pc.printf("\n Ausgang 2 (LED rot     ) = %d",(uint8_t)OUT2);
    pc.printf("\n Ausgang 3 (LED gruen   ) = %d",(uint8_t)OUT3);
    pc.printf("\n Ausgang 4 (LED gelb    ) = %d",(uint8_t)OUT4);
    pc.printf("\n Ausgang 5 (nicht belegt      ) = %d",(uint8_t)OUT5);
    pc.printf("\n Ausgang 6 (Relais      ) = %d",(uint8_t)OUT6);
  }  

  // Auswerten auf gültige Eingaben
  if (!((x > 0) && (x <=6)))
  {
      pc.printf("\nFuer x bitte nur Werte von 1 bis 6 eingeben   [x = %d]\n",x);
      return;
  } 
    

  if (!((y == 0) || (y == 1)))
  {
      pc.printf("\nFuer y bitte nur Werte von 0 oder 1 eingeben   [y = %d]",y);
      return; 
  } 

      
  if ((w_zeit <= 0) || (w_zeit > 1000))
  {
      pc.printf("\nFuer w_zeit bitte nur Werte von 0 oder 1000 eingeben   [w_zeit = %f]",w_zeit);
      return;       
  }
  
  // Ausgänge schalten
 
  switch(x)
  {
    case 1:
            pc.printf("\n OOU1 auf %d schalten, Wartezeit %0.1f",y,w_zeit);
            out = OUT1;
            OUT1 = (bool)y;
            wait(w_zeit);
            OUT1 = out;
            break;
    case 2:
            pc.printf("\n OOU2 auf %d schalten, Wartezeit %0.1f",y,w_zeit);
            out = OUT2;
            OUT2 = (bool)y;
            wait(w_zeit);
            OUT2 = out;            
            break;    
    case 3:
            pc.printf("\n OOU3 auf %d schalten, Wartezeit %0.1f",y,w_zeit);
            out = OUT3;
            OUT3 = (bool)y;
            wait(w_zeit);
            OUT3 = out; 
            break;    
    case 4:
            pc.printf("\n OOU4 auf %d schalten, Wartezeit %0.1f",y,w_zeit);
            out = OUT4;
            OUT4 = (bool)y;
            wait(w_zeit);
            OUT4 = out;
            break;    
    case 5:
            pc.printf("\n OOU5 auf %d schalten, Wartezeit %0.1f",y,w_zeit);
            out = OUT5;
            OUT5 = (bool)y;
            wait(w_zeit);
            OUT5 = out;            
            break;    
    case 6:   
            pc.printf("\n Relais auf %d schalten, Wartezeit %0.1f",y,w_zeit);
            out = OUT6;
            OUT6 = (bool)y;
            wait(w_zeit);
            OUT6 = out;            
            break;      
  } // end switch        


  pc.printf("\n done \n");
      
}

//------------------------------------------------------------------------
// Lesen und Anzeigen der Eingänge
// 
//  DigitalIn IN1;        // nicht belegt
//  DigitalIn IN2;        // nicht belegt
//  DigitalIn IN3;        // Signalstation, Öffner => null im Ruheezustand ?
//  DigitalIn IN4;        // Sabotageschalter, nach Zeichnung müsste 1 der Ruhezustand sein => null ist Ruhezustand ?
//  DigitalIn IN5;        // Notaus, Öffner gegen GND => 0 ist der Ruhezustand
//

void monitor::in(void)
{
    pc.printf("\nLesen und Anzeigen der digitalen Eingaenge");  
    pc.printf("\n");
    pc.printf("\n Eingang 1 (nicht belegt     ) = %d Schaltpegel 24V    offener Eingang  = 0",(uint8_t)IN1);    
    pc.printf("\n Eingang 2 (nicht belegt     ) = %d Schaltpegel 24V    offener Eingang  = 0",(uint8_t)IN2);
    pc.printf("\n Eingang 3 (Signalstation    ) = %d Schaltpegel 24V    offener Eingang  = 0",(uint8_t)IN3);
    pc.printf("\n Eingang 4 (Sabotageschalter ) = %d schaltet gegen GND offener Eingang  = 1",(uint8_t)IN4);
    pc.printf("\n Eingang 5 (Notaus           ) = %d schaltet gegen GND offener Eingang  = 1",(uint8_t)IN5);
    pc.printf("\n");
}