monitor

Fork of mon by V09

mon.cpp

Committer:
rs27
Date:
2015-01-03
Revision:
0:401f3ae5ab50

File content as of revision 0:401f3ae5ab50:


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

extern MODSERIAL pc;                       // definiert in main
extern SDFileSystem sd;
extern PwmOut lcd_kontrast;             // definiert in main
extern timer0 down_timer;               // Timer für Zeitsteuerung
extern menu menu_var;
extern TextLCD lcd;

// Taster für die Eingabe
extern DigitalIn S1;
extern DigitalIn S2;
extern DigitalIn S3;
extern DigitalIn S4;
extern DigitalIn S5;

Timer t; 
   
#define COMMAND_MAX    12
#define COMMAND_LEN    7

const char command[COMMAND_MAX][COMMAND_LEN] = {"CLCD","DATE","DEL","DIR","DUMP","FILL","HELP","LIST","MENU","RN","SET","TIME"};

//-----------------------------------------------------------------------------
// constructor

monitor::monitor(void)
{
    uint8_t i;
    
    for (i = 0; i < MON_LINE_LEN; mon_line[i++] = 0);
    MonLinePtr = 0;
    
    tasten = 0; 
    tasten_old = 0;
}  

//---------------------------------------------------------------------------
//
//   Function name :    PARSER
//
//   Returns :          none
//
//   Parameters :       none
//
//   Purpose :          wertet die Eingangszeile aus und verzweigt zum gewünschten 
//                      Programm
//
//---------------------------------------------------------------------------
void monitor::parser (void)
{
  uint8_t i, ch, tch, top, bottom, len;
  int8_t res;

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

  bottom = 0;                                        // untere Suchgrenze 
  top = COMMAND_MAX;                                 // obere Suchgerenze 
  ch = mon_line[0];                            // hole erstes Suchzeichen
  
  do 
  {
        i = (top + bottom) >> 1;    // suche in der Mitte des Feldes beginnen
        tch = 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; mon_line[i] != ' ' &&  mon_line[i] != 0; i++);
  len = i;

  
  if (i == 0) return;

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

  for ( ; mon_line[i] == ' ' && mon_line[i] != 0; i++);
  MonLinePtr = i;
  
  // die binäre Suche nach den restlichen Zeichen wird hier fortgesetzt 

  do
  {
        i = (top + bottom) >> 1;                 // berechnen des Suchplatzes
        //printf_P (PSTR("\n\rVergleich 1 com_line = [%s] und Länge = [%d]"),com_line,len);
        //strcpy_P (temp, &command[i][0]);
        //printf_P (PSTR("\n\rVergleich 2 command[i] = [%s] und Index = [%d]"),temp,i);
        res = strncmp(mon_line, &command[i][0], len);
        //printf_P (PSTR("\n\rVergleich 3 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 
  {
        pc.printf("\nAufruf von Funktion %d",i);
        
        // "CLCD","DATE","DEL","DIR","DUMP","FILL","HELP","LIST","SET","TIME"};        
        
        switch(i)                       // Programmaufruf
        {
          case  0: clcd(); break;
          case  1: date(); break;
          case  2: del(); break;
          case  3: dir(); break;
          case  4: dump(); break;
          case  5: fill(); break;
          case  6: help(); break;
          case  7: list(); break;
          case  8: read_menu(); break;
          case  9: rename(); break;
          case 10: set(); break;
          case 11: time(); break;
        }                                   
  }
}

//---------------------------------------------------------------------------
//
//  Function name : monitor
//
//  Returns :       none
//
//  Parameters :    none
//
//  Purpose :       Monitor für die Benutzereingabe
//
//---------------------------------------------------------------------------
void monitor::monPC(void)
{
    uint8_t i;
    char ch;

    monLine();
    if (cr_flag)                   // Neue Eingabezeile  
    {
        if (mon_line[0] != 0)
        {
            // Zeichenkette in Großbuchstaben umwandeln
            for (i = 0; mon_line[i] != 0; i++)
            {
                ch = mon_line[i];
                ch = toupper(ch);                          // Nur Großbuchstaben 
                mon_line[i] = ch;
                //pc.printf(("\n[%02x] %c"),ch,ch);                
                if (ch == ' ') i = MON_LINE_LEN;
            }
            
            // pc.printf("\n monitor %s", mon_line);        // zum Testen => später wird der parcer aufgerufen
            parser();                                       // Parcer wird aufgerufen
        }
 
        for (i=0; i < MON_LINE_LEN; mon_line[i++] = 0);
        MonLinePtr = 0;                         
        cr_flag = 0;
  }     
}

//---------------------------------------------------------------------------
//
//  Function name : mon_line
//
//  Returns :       none
//
//  Parameters :    none
//
//  Purpose :       
//      Wird periodisch in unregelmäsigen Abständen aufgerufen und ermittelt,    
//      ob weitere Zeichen von der Schnittstelle empfangen und die Eingabe      
//      mit Carrige Return abgeschlossen wurde. Sollte dies der Fall sein,      
//      wird das CR_FLAG gesetzt. Auch Editierfunktionen werden in diesem      
//      Rahmen behandelt.                               
//
//---------------------------------------------------------------------------

void monitor::monLine (void)
{
    int ch;
  
    if (pc.readable() == false) return;     // kein Zeichen vorhanden 
    
    if (MonLinePtr >= 40)                   // Zeilenüberlauf ?  
    {
        cr_flag = 1;
        return;
    }

    ch = pc.getc();                             // Hole das Zeichen  
    //pc.printf("\nmon_line: %c [%02x]",ch,ch);   // nur zum Test
  
    switch(ch) 
    {
        //case ESC: esc_flag = 1;           // Sonder Stringkommandos 
        //  break;

        case '\r':                          // CARRIAGE RETURN  
            cr_flag = 1;
            break;

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

        default:                            // Normales Zeichen  
            if (~iscntrl(ch)) 
            {
                mon_line[MonLinePtr] = ch;  // Zeichen einfuegen 
                MonLinePtr++;
                // pc.putc(ch);
            }
            break;

    }   // Ende SWITCH 
}

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

void monitor::dump(void)
{
  pc.printf("\nin dump");
}

//-----------------------------------------------------------------------------
// monitor Aufruf clcd  contrast lcd

void monitor::clcd (void)
{
    int n, val;

    n = sscanf(&mon_line[MonLinePtr],"%d",&val); 
    
    switch (n)
    {
      case -1:

            pc.printf("\n bitte Wert angeben");
            pc.printf("\n Wert >>  0 bis 100");
            pc.printf("\n default Wert = 30");
            break;
                   
      case 1: //status[pos] = val;
            if (val < 0) val = 0;
            if (val > 100) val = 100;
            lcd_kontrast.pulsewidth_us(val);      // Kontrastwert setzen
            pc.printf("\n LCD Kontrast = %d",val); 
            break;
     } // end switch
  
}
//-----------------------------------------------------------------------------
// monitor Aufruf help

void monitor::help(void)
{
  pc.printf("\n -- help ------------------------");
  pc.printf("\n clcd val >> lcd Kontrast");
  pc.printf("\n set index [val] >> Sensor auswaehlen");
  pc.printf("\n time [std min sek tag monat jahr]");   
  pc.printf("\n"); 
  pc.printf("\n -- files ------------------------");
  pc.printf("\n dir  >> Dateien anzeigen");  
  pc.printf("\n list name >> den Inhalte einer Datei anzeigen"); 
  pc.printf("\n del name >> eine Datei loeschen"); 
  pc.printf("\n fill name [zeilen] >> eine Datei anlegen und fuellen");        
  pc.printf("\n rn name name >> eine Datei umbenennen");
  pc.printf("\n menu testen der menu Funktion");
  pc.printf("\n");
}

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

void monitor::set(void)
{
    int n, pos, val;

    n = sscanf(&mon_line[MonLinePtr],"%d %d",&pos,&val);
    
    switch (n)
    {
      case -1: pc.printf("\nbitte index [wert] angeben");
              pc.printf("\n Index >> Sonsor 0 bis 7");
              pc.printf("\n wert  >> 0 = inaktiv, 1 = Rohwerte, 2 = errechneter Wert");
              break;
      
      case 1: pc.printf("\nread status[%d] ",pos);
              break;
              
      case 2: //status[pos] = val;
              pc.printf("\nset status[%d] = %d",pos);
              break;
     } // end switch
}

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

void monitor::date(void)
{
  pc.printf("\nin date");
}

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

void monitor::time(void)
{
    int sek, min, std, day, month, year, n;    
    
    sek     = 0;   
    min     = 0;    
    std     = 0;
    day     = 0;
    month   = 0;
    year    = 0; 
    
    n = sscanf(&mon_line[MonLinePtr],"%d %d %d %d %d %d",&std, &min, &sek, &day, &month, &year);

    switch (n)
    {
        case -1 :  // keine Zeichenübergabe
        case  0 :  // keine Zeichenübergabe
     
                strftime(buffer, 40, "%a, %d.%m.%Y %H:%M:%S", localtime(&down_timer.seconds));
                pc.printf("\nTime = %s\n", buffer);
                break;
                
        case 1 :   // std
        case 2 :   // min
        case 3 :   // sek
        case 4 :   // tag
        case 5 :   // mon
        case 6 :   // jahr
                            
                if (sek > 59) sek = 59;
                if (sek < 0)  sek = 0;
                buffer[0] = (uint8_t)sek;;

                if (min > 59) min = 59;
                if (min < 0) min = 0;
                buffer[1] = (uint8_t)min;
                
                if (std > 23) std = 23;
                if (std < 0) std = 0;
                buffer[2] = (uint8_t)std;

                if (day > 31) day = 31;
                if (day < 0)  day = 0;
                buffer[3] = (uint8_t)day;;

                if (month > 12) month = 12;
                if (month < 0) month = 0;
                buffer[4] = (uint8_t)month;
                
                if (year > 2100) year = 2100;
                if (year < 2000) year = 2000;
                buffer[5] = (uint8_t)(year - 1900);

                down_timer.Set_t((uint8_t *)buffer);
 
                strftime(buffer, 40, "%a, %d.%m.%Y %H:%M:%S", localtime(&down_timer.seconds));
                pc.printf("\nnew Time = %s\n", buffer);    
                break;
    }
}

//-----------------------------------------------------------------------------
// monitor Aufruf dir
//
// weiter Infos siehe auch
// http://elm-chan.org/fsw/ff/00index_e.html
//
void monitor::dir(void)
{

    long size;
    float f_size;
    int i, len;  
    
    DIR *d;
    struct dirent *p;

    d = opendir("/sd");
    if (d != NULL) 
    {
        while ((p = readdir(d)) != NULL) 
        {
            sprintf(buffer,"/sd/%s",p->d_name);
            pc.printf("\n %s", p->d_name);
            FILE * f = fopen(buffer, "r");
            fseek(f, 0, SEEK_END); // seek to end of file
            size = ftell(f);       // get current file pointer
            
            len = strlen(p->d_name);
            for (i = len; i < 16; i++) pc.printf("%c",' ');
            
            if (size < 1024)
            {
                sprintf(buffer,"    %ld bytes ",size);            
            }
            else
            {
                if (size > 1048576)
                {
                    f_size = size / 1048576.0;
                    sprintf(buffer,"    %0.3f MB  ",f_size);                    

                }
                else
                {
                    f_size = size / 1024.0;
                    sprintf(buffer,"    %0.3f kB  ",f_size);
                }
            }
            
            pc.printf("%s",buffer);
            
            len = strlen(buffer);
            for (i = len; i < 16; i++) pc.printf("%c",' ');
            
            // fno.fdate = (WORD)(((year - 1980) * 512U) | month * 32U | mday);
            // fno.ftime = (WORD)(hour * 2048U | min * 32U | sec / 2U);            
            
            unsigned long fdate = p->fdate;
            unsigned long ftime = p->ftime; 
            
            pc.printf("%02d:",(ftime>>11));                    // Stunden           
            pc.printf("%02d:",((ftime & 0x000007E0)>>5));      // Minuten
            pc.printf("%02d  ",((ftime & 0x0000001F)*2));      // Sekunden
            
            pc.printf("%02d.",(fdate & 0x0000001F));           // Tag
            pc.printf("%02d.",((fdate & 0x000001E0)>>5));      // Monat
            pc.printf("%04d ",((fdate>>9)+1980));              // Monat
            

//          time_t fattime = get_fattime();
//          strftime(buffer, 40, "%a,%d %m %Y.%H:%M:%S", localtime(&fattime));
//          pc.printf(" %s ", buffer);

            fclose(f);
        }
        
    }
    else 
    {
        pc.printf("\nCould not open directory!\n");
    }
    closedir(d);
    
    
    FATFS* fs;
    DWORD fre_clust;
    f_getfree("0:",&fre_clust,&fs);
    const float frs = float(fs->csize)*float(fs->free_clust)
    #if _MAX_SS != 512
        *(fs->ssize);
    #else
        *512;
    #endif
    pc.printf("\n\nfree space = %0.3f GB",frs/1073741824.0);
    
    pc.printf("\ndone\n");
}

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

void monitor::list(void)
{
    char dname[25];
      
    sscanf(&mon_line[MonLinePtr],"%s",dname);
    sprintf(buffer,"/sd/%s",dname);
    pc.printf("\nlist, file %s \n",buffer);
    FILE * fp = fopen(buffer, "r");
    if(fp == NULL) 
    {
        pc.printf("\nCould not open file for read\n\r");
        return;
    }
    
    // mit fgets werden die Zeile einzeln gelesen, wenn die Länge < 64 Zeichen ist
    
    while (fgets(buffer, 64, fp))
    {
        pc.printf("> %s", buffer);
    }
    
    fclose(fp);        
    pc.printf("\ndone\n");
}

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

void monitor::del(void)
{
    char dname[25];
    
    sscanf(&mon_line[MonLinePtr],"%s",dname);
    sprintf(buffer,"/sd/%s",dname);
    pc.printf("\ndelete file %s",buffer);
    remove(buffer);
    //int res = sd.re_name("/sd/test1","/sd/test1.txt");
    pc.printf("\ndone");
}

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

void monitor::fill(void)
{
    char dname[25];
    int n = 20;
    
    sscanf(&mon_line[MonLinePtr],"%s %d",dname,&n);
    sprintf(buffer,"/sd/%s",dname);
    pc.printf("\nfill file %s \n",buffer);
    FILE *fp = fopen(buffer, "w");
    if(fp == NULL) 
    {
        pc.printf("Could not open file for write\n");
    }
    for (int i = 0; i<n; i++)
    {
        fprintf(fp, "\nschreibe eine Zeile %d ",i);
    }
    fclose(fp); 
    pc.printf("\ndone\n");
}

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

void monitor::rename(void)
{
    // char str1[20];      // neuer Dateiname
    // char str2[25];      // neuer Dateiname
    // char str3[20];      // alter Dateiname
    // char str4[25];      // alter Dateiname
    int ch;
    
    pc.printf("\nrename ");
    sscanf(&mon_line[MonLinePtr],"%s %s",str3,str1);
    sprintf(str4,"/sd/%s",str3);
    pc.printf("%s ",str4);
    FILE *fpold = fopen(str4, "r");   // src file
    sprintf(str2,"/sd/%s",str1);
    pc.printf("%s \n",str2);
    FILE *fpnew = fopen(str2, "w");   // dest file
    
    while (1)                       // Copy src to dest  
    {
        ch = fgetc(fpold);          // until src EOF read. 
        if (ch == EOF) break;
        fputc(ch, fpnew);  
    }
    
    fclose(fpnew);
    fclose(fpold);
 
    fpnew = fopen(str2, "r");       // Reopen dest to insure
    if(fpnew == NULL)               // that it was created.
    {
        pc.printf("\nerror\n");     // Return Error.
    } 
    else 
    {
        fclose(fpnew);  
        remove(str4);               // Remove original file.
        pc.printf("\ndone\n");      // Return Success.
    }
}

//-----------------------------------------------------------------------------
// wird für die Abfrage der Tasten verwendet

uint8_t monitor::taste(void)
{
    tasten_old = tasten;
    
    while(1)
    {
        if (S1 == 0) tasten |= 0x01; else tasten &= ~0x01;
        if (S2 == 0) tasten |= 0x02; else tasten &= ~0x02;
        if (S3 == 0) tasten |= 0x04; else tasten &= ~0x04;
        if (S4 == 0) tasten |= 0x08; else tasten &= ~0x08;
        if (S5 == 0) tasten |= 0x10; else tasten &= ~0x10;
        
        if (tasten != tasten_old)
        {
          break;  
        }
        com_line(); // in dieser Schleife läuft der Buffer sonst über
    }
    return tasten;
}

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

void monitor::read_menu(void)
{
    uint8_t flag;
    int anf, len, len_neu, end, index;
    
    char ch;
    int n = 1, pos, a;
    int wert;
    
    t.reset();
    t.start();
    
    n = sscanf(&mon_line[MonLinePtr],"%s %s %s %s",str1,str2,str3,str4);
    
    if (n == 1)
    {
        pos = atoi(str1);
        if (menu_var.getValue(pos,str2,str3,str4))
        {
          pc.printf("\nmenu: %d; %s; %s; %s",pos,str2,str3,str4);    
        }
    }
    
    t.stop();
    
    lcd.set_lcd_flag(false);
    
    lcd.cls();  // LCD löschen
    
    wert = 555;   
    
    //wert = atoi(str4);    
    sprintf(str4," %d",wert);
    
    end = 8;       
    len = strlen(str4);     // drei Zeichen                
    anf = end - len;        // position des erstes Zeichens in der Anzeige
    index = len;            // letzte Stelle im String    
    index--;                // null zählt als das erste Zeichen

    while(1)
    {
        // Wert auf der Anzeige ausgeben und ändern
        
        sprintf(str4," %d",wert);

        len_neu = strlen(str4);     // drei Zeichen                        
        anf = end - len_neu;        // Position bestimmen
        index += (len_neu - len);
        len = len_neu;
        if (index < 0) index = 0;
        lcd.print_LCD(str4,1,anf);          
        
        ch = str4[index];
        
        // Cursor setzen
        a = lcd.address(anf + index,1);
        lcd.writeCommand(a);
        lcd.writeCommand(0x0F); // Curor einschalten
        
        pc.printf("\n[%s], anf %d, end %d, index %d",str4, anf, end, index); 
        
        flag = taste();
        pc.printf("\ntaste %02x wert %d",flag,wert); 
        
        switch (flag)
        {
            case 0x01: // left
                    if (index > 0)
                    {
                      index--;
                    }
                    break;
                    
            case 0x02: // down
                    if( ch > '0') 
                    {
                        ch--;
                        str4[index] = ch;
                    }
                    break;
                    
            case 0x04:  // up
                    if ((ch >= '0') && (ch < '9')) 
                    {
                        ch++;
                        str4[index] = ch;
                    }
                    
                    if (ch == ' ')
                    {
                        ch = '1';
                        str4[index] = ch;
                    }
                        
                    break;
                    
            case 0x08:  // rigth
                    if (index < len)
                    {
                       index++;
                    }
                    break;
                    
        } // end while
       
        wert = atoi(str4); 
        if (flag == 0x10) break;
    }
    
    // die alten Daten wieder anzeigen 
    lcd.writeCommand(0x0C); // Cursor ausschalten
    wait_us(40);
    
    lcd.writeALL();
    lcd.set_lcd_flag(true);
    
    pc.printf("\ndone %f us\n",t.read());    // Return Success.
    
}