Speichern von Dateien auf einem Stick

Dependencies:   KL46Z-USBHost MODSERIAL-RTOS mbed-rtos mbed

Revision:
0:dc4ad683fe77
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun May 11 15:23:50 2014 +0000
@@ -0,0 +1,482 @@
+//------------------------------------------------------------------------
+//
+// kl25z_USB_4
+// Programm zum Speichern von Dateien auf einem memery Stick
+//
+// Erstellt am 10.05.14 R. Schäfer
+//
+#include "mbed.h"
+#include "rtos.h"
+#include "USBHostMSD.h"
+#include "MODSERIAL.h"
+
+#define LED_OFF 1
+#define LED_ON  0
+#define COM_LINE_LEN 128             // maximale Länge der Eingabezeile  
+
+struct com_struct {
+    uint8_t flag;                     // Flag zur Steuerung
+    uint8_t sm;                       // State maschine
+    uint8_t index;                    // Index für Zeichenzähler
+    char line[COM_LINE_LEN];
+};
+
+struct msd_struct {
+    bool    connect;                  // wird bei Verbindung true
+    uint8_t flag;                     // Flag zur Steuerung
+    uint8_t sm;                       // State maschine
+    uint8_t index;                    // Index für Zeichenzähler
+    char line[COM_LINE_LEN];
+};
+
+extern "C" void NVIC_SystemReset();
+
+Thread *(msdTaskp);
+
+Serial pc(USBTX,USBRX);
+
+// Make TX buffer 1024bytes and RX buffer use 512bytes.
+// MODSERIAL uart1(PTA2, PTA1, 256, 1024); // tx, rx
+MODSERIAL uart1(PTC4, PTC3, 128, 1024); // tx, rx
+
+DigitalOut led1(PTB18);
+DigitalOut led2(PTB19);
+int err_counter = 0;
+
+// ---- globle Veariablen ----------------------------------------------
+
+// Bitposition und Belegung
+//  bit 1 CR Flag
+//  bit 2 byte speichern
+//  bit 4
+//  bit 8
+
+struct com_struct com;      // Eingangszeile
+
+// Bitposition und Belegung
+//  bit 1 Daten speichern in aktion
+//  bit 2 Datei anlegen
+//  bit 4 Daten schreiben
+//  bit 8 Datei schließen
+
+struct msd_struct m_msd;    // Speicher für Stick
+
+// mit dieser Task werden die Datem in Hintergrund im Stick abgespeichert
+// es wird auch geprüft ob für das Speichern ein Stick vorhanden ist
+// falls kein Stick erkannt wird, löst das Programm einen Reset aus, womit
+// die USB Schnittstelle neu initialiesiert wird. Damit kann auch ein Stick
+// im Betieb abgesteckt und wieder angestecht werden.
+//
+// Änderungen
+// Thread Zeit reduzieren
+// Dateinamen über globale Variable ersetzen
+
+void msd_task(void const *) 
+{
+    int i = 0;
+    int n;
+    FILE * fp = 0;  
+    
+    USBHostMSD msd("usb");
+    err_counter = 0;
+    
+    // in a loop, append a file
+    // if the device is disconnected, we try to connect it again
+    while(msd.connect()) 
+    {
+        m_msd.connect = true;
+        Thread::signal_wait(0x1);
+ 
+        // uart1.printf("\nmsd> ");            
+        //              
+        // for (i = 0; i < com.index; i++)
+        // {
+        //   uart1.printf(" %02x",m_msd.line[i]);   
+        // }           
+            
+        // uart1.printf("\n"); 
+                   
+        switch (m_msd.line[0])
+        {
+            case 02:                                // Datei anlegen
+                              
+                char buffer[40];
+                sprintf(buffer, "/usb/%s", &m_msd.line[1]);
+                fp = fopen(buffer, "w");
+                
+                // uart1.printf("\nMSD Datei %s anlegen",buffer);
+
+                break;
+
+            case 03:                                // Daten schreiben
+
+                if (fp) 
+                {
+                    n = fprintf(fp,"%s",&m_msd.line[1]);
+                    // uart1.printf("\nwrite file [%d] %s",n,&m_msd.line[1]);
+                }   // if (fp ..
+                
+                break;
+
+            case 04:                     // Datei schließen
+
+                if (fp) n = fclose(fp);  
+                // uart1.printf("\n close file");               
+                break;
+                
+        } // end switch(msd-line[0]
+
+        // Speicher für die Zeile löschen
+        for (i=0; i < COM_LINE_LEN; i++) m_msd.line[i] = 0;
+        m_msd.flag &= ~0x01;
+
+        // if device disconnected, try to connect again
+        if (!msd.connected()) 
+        {
+            // uart1.printf("\n disconnected break");
+            m_msd.connect = false;
+            break;
+        }
+
+    } // end while (msd_connected)
+
+    // Task wird beendet
+}
+
+// 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_thread(void const *args)
+{
+    char ch;
+    int i;
+
+    while (true) 
+    {
+        if ((uart1.readable()) && ((com.flag & 0x80) == 0))
+        {
+            //----------------------------------------------------------------------------------------------------
+            // Eingehende Zeichen lesen und abspeichern           
+            
+            ch = uart1.getc();                                              // Zeichen lesen und auswerten
+            // uart1.printf("\ntel> ");            
+            
+            com.line[com.index] = ch;                                       // Zeichen einfuegen
+            com.index++;                                                    // Zeichenzähler erhöhen
+            if (com.index >= 125) com.sm = 2;                               // ein Telegramm enthält maximal 1125 Zeichen
+                      
+            // for (i = 0; i < com.index; i++)
+            // {
+            //   uart1.printf(" %02x",com.line[i]);   
+            // }           
+            
+            // uart1.printf("\n"); 
+ 
+            //----------------------------------------------------------------------------------------------------
+            // Abschlußbit auswerten und Telegramm umsetzen
+            
+            switch (com.sm)   // com.sm ist state machine
+            {
+                case 0 :      // erstes Zeichen aus einem Telegramm
+                
+                    switch(ch) 
+                    {
+                        case 0x00:                                          // Endzeichen an erter Stelle zum testen
+                            // uart1.puts("Telegramm 0x00\n");                 // direkt ausführen 
+                            com.sm = 12;                                    // neues Telegramm
+                            break;
+
+                        case 0x01:                                          // Reset
+                            // uart1.puts("Telegramm 0x01\n");                 // direkt ausführen
+                            com.sm = 12;                                    // nur ein Zeichen
+                            break;
+                                
+                        case 0x02:                                          // Datei anlegen und öffnen
+                            com.sm = 1;                                     // Kommando Byte abspeichern
+                            break;                                          // Dateinamen bis 0x00 lesen
+
+                        case 0x03:                                          // Daten schreiben
+                            com.sm = 1;                                     // Kommando Byte abspeichern
+                            break;                                          // Dateinamen bis 0x00 lesen
+    
+                        case 0x04:                                          // Datei schließen
+                            // uart1.puts("Telegramm 0x04\n");                 // direkt ausführen
+                            com.sm = 10;                                    // Kommando besteht nur aus einem Zeichen
+                            break;
+
+                        case 0x05:                                          // SD Stick erkannt, direkt ausführen
+                            if (m_msd.connect)
+                                uart1.puts("\nStick erkannt");               
+                            else
+                                uart1.puts("\nStick nicht erkannt");          
+                            
+                            com.sm = 12;                                    // Kommando besteht nur aus einem Zeichen
+                            break; 
+                               
+                        default:                                            // Zeichen zum abspeichern
+                            // uart1.puts("\nsm 0 unbekannter Befehl");
+                            com.sm = 12;                                    // Speicher löschen
+                            break;
+    
+                    }   // ende SWITCH
+                     
+                    break; // end case 0:
+                
+                case 1:  // Lesen von weitern Zeichen nach dem ersten Zeichen
+                
+                    //----------------------------------------------------------------------------------------------------
+                    // bis Abschlussbit alle Zeichen lesen und bei Abschlußzeichen die Auswertung angehen
+                    
+                    if (ch == 0x00)
+                    {
+                        com.sm = 10;    
+                    } // end if (ch == 0x00)
+                    
+                    break; // end case 1:
+                
+                case 2:  // Zeichenkette ist länger als 125 Zeichen
+                
+                    // uart1.puts("\nsm 2 String ist groesser 125 Zeichen");
+                    com.sm = 11;
+                    
+                    break;  // end case 2         
+
+            } // end switch
+
+            //----------------------------------------------------------------------------------------------------            
+            // Telegramme die an die Task msd weitergeleitet werden
+            
+            if (com.sm == 10)
+            {
+                if ((m_msd.flag & 0x01) == 0)
+                {       
+                    // uart1.puts("\nsm 10 Speicher kopieren");
+                    
+                    for (i = 0; i < COM_LINE_LEN; i++) 
+                    {
+                        m_msd.line[i] = com.line[i];
+                        if (com.line[i] == 0x00) break;                      
+                    }
+
+                    m_msd.flag = 0x01;
+                    com.sm = 12;
+                         
+                    msdTaskp->signal_set(0x1);
+                }
+                else
+                {
+                    com.flag |= 0x80;           // kann erst später gespeichert werden
+                }
+                
+            }
+
+            //----------------------------------------------------------------------------------------------------            
+            // bei mehr asl 125 Zeichen werden die Daten an die msd Task übergeben
+
+            if (com.sm == 11)
+            {
+                //----------------------------------------------------------------------------------------------------
+                // Daten abspeichern
+                
+                if ((m_msd.flag & 0x01) == 0)
+                {  
+                    for (i = 0; i < COM_LINE_LEN; i++) 
+                    {
+                        m_msd.line[i] = com.line[i];
+                        if (com.line[i] == 0x00) break;
+                    }
+
+                    m_msd.flag = 0x01;
+                    m_msd.sm = 0x03;
+                    
+                    msdTaskp->signal_set(0x1); 
+                    
+                    for (i = 1; i < COM_LINE_LEN; i++) com.line[i] = 0x00;
+    
+                    com.index = 1;
+                    com.sm = 1;
+                    
+                }
+                else
+                {
+                    com.flag |= 0x80;           // kann erst später gespeichert werden                        
+                }
+                    
+            } // end if com.sm == 11
+            
+            //----------------------------------------------------------------------------------------------------
+            // Zeile wieder löschen            
+            
+            if (com.sm == 12)
+            { 
+                // 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;   
+             }
+            
+                
+        } // end if (uart1.readabel
+        else 
+        {
+            //----------------------------------------------------------------------------------------------------
+            // prüfen ob die Daten auf dem Stick schon abgespeichert sind
+            
+            if ((com.flag & 0x80) == 0x80)
+            {
+                if ((m_msd.flag & 0x01) == 0)
+                {
+                    //----------------------------------------------------------------------------------------------------            
+                    // Telegramme die an die Task msd weitergeleitet werden
+                    
+                    if (com.sm == 10)
+                    {     
+                        for (i = 0; i < COM_LINE_LEN; i++) 
+                        {
+                            m_msd.line[i] = com.line[i];
+                            if (com.line[i] == 0x00) break;
+                        }
+    
+                        m_msd.flag = 0x01;
+                        com.sm = 12;
+                                 
+                        msdTaskp->signal_set(0x1);
+                    }
+
+                    if (com.sm == 11)
+                    {
+                        //----------------------------------------------------------------------------------------------------
+                        // Daten abspeichern
+
+                        for (i = 0; i < COM_LINE_LEN; i++) 
+                        {
+                            m_msd.line[i] = com.line[i];
+                            if (com.line[i] == 0x00) break;
+                        }
+
+                        m_msd.flag = 0x01;
+                        
+                        msdTaskp->signal_set(0x1); 
+                        
+                        for (i = 1; i < COM_LINE_LEN; i++) com.line[i] = 0x00;
+        
+                        com.index = 1;
+                        com.sm = 1;
+                            
+                    } // end if com.sm == 11
+            
+                    //----------------------------------------------------------------------------------------------------
+                    // Zeile wieder löschen            
+            
+                    if (com.sm == 12)
+                    { 
+                        // uart1.puts("\nsm 10 Speicher loeschen");
+                        
+                        for (i = 0; i < COM_LINE_LEN; i++) com.line[i] = 0x00;
+            
+                        com.index = 0;
+                        com.flag = 0;
+                        com.sm = 0;   
+                     }
+                }
+                Thread::wait(10);   // falls keine Zeichn mehr im Buffer 10 ms warten 
+            }
+            else
+            {
+                Thread::wait(100);  // falls keine Zeichn mehr im Buffer 10 ms warten
+            }
+        }
+
+        led2 = !led2;
+    }
+}
+
+//---------------------------------------------------------------------
+
+int main() 
+{
+        int i;
+
+        // 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;
+
+        // Speicher für den Stick Speicher löschen
+        for (i=0; i < COM_LINE_LEN; i++) 
+        {
+            m_msd.line[i] = 0;
+        }
+        m_msd.connect = false;
+        m_msd.flag = 0;
+        m_msd.sm = 0;
+        m_msd.index = 0;
+
+        led2 = LED_OFF;
+
+        // Uhrzeit initialisieren
+        struct tm t;
+        t.tm_sec  = 00;   // 0-59
+        t.tm_min  = 01;   // 0-59
+        t.tm_hour = 11;   // 0-23
+        t.tm_mday = 4;    // 1-31
+        t.tm_mon  = 2;    // 0-11 0 = Januar
+        t.tm_year = 114;  // year since 1900
+
+        // Zeit umwandeln und setzen >> die Zeit wird für die Datei benötigt
+        time_t seconds = mktime(&t);
+        set_time(seconds);
+
+        // pc ist die USB Schnittstelle des Debuggers
+        pc.baud(56700);
+        pc.printf("\nUSB_4 Test Programm V1.0d");
+
+        // uart1 ist die Schnittstelle zur microSPS
+        uart1.baud(56700);
+        // uart1.printf("\nUSB_2 Test Programm V1.0d");
+        
+        //uart1.attach(&txCallback, MODSERIAL::TxIrq);
+        //uart1.attach(&rxCallback, MODSERIAL::RxIrq);
+        //uart1.attach(&txEmpty,    MODSERIAL::TxEmpty);
+
+        // diese Task werden die nakommenden Zeichen gelesen und ausgewertet
+        Thread thread(com_thread, NULL, osPriorityNormal, 512);
+
+        // diese Taks ist die Schnittstelle zum Stick
+        Thread msdTask(msd_task, NULL, osPriorityNormal, 1024 * 4);
+        msdTaskp = &msdTask;
+        
+        while(1) 
+        {
+            // falls der Stick gezogen wurde, wird damit die USB Schnittstelle neu initialisiert
+            if (err_counter >= 10) 
+            {
+                NVIC_SystemReset();
+            }
+
+            // Systemzeit neu setzen, da keine Hardwareuhr
+            // auf der oginal Karte wird die Uhr über einen Eingang angesteuert
+            time_t seconds = time(NULL);
+            char buffer[40];
+            strftime(buffer, 40, "%a,%d %m %Y.%H:%M:%S", localtime(&seconds));
+            pc.printf("\nTime as a custom formatted string = %s %02x %02x %02x", buffer, com.index, com.sm, com.flag);
+            // uart1.printf("\nTime as a custom formatted string");
+            seconds++;
+            set_time(seconds);
+
+            // Zeitintervall
+            // könnte auch in eine Taks verlagert werden
+            led1 = !led1;
+            Thread::wait(1000);
+
+        } // end while
+    }
+