rev.1

Dependencies:   RA8875 SDFileSystem mbed

Revision:
0:6ef3fd4921d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Feb 17 16:53:53 2017 +0000
@@ -0,0 +1,1784 @@
+// MW771 Laser Press HMI.
+// V.Nemera, 10/07/2016, ver.1.0, C++
+// CPU: mbed NXP LPC1768 (ARM Cortex-M3, 32bit, 90MHz)
+//#pragma once
+#include "mbed.h"           
+#include "RA8875.h"         
+#include "MyFont18x32.h"
+#include "BPG_Arial08x08.h"
+#include "BPG_Arial10x10.h"
+#include "BPG_Arial20x20.h"
+#include "BPG_Arial31x32.h"
+#include "BPG_Arial63x63.h"
+#include "SDFileSystem.h"
+#include "stdint.h"
+#include <string>
+using std::string;
+
+#include "main.h"
+#include "comm.h"
+
+int a7, b7, c7, d7;
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+int iLed;
+
+Serial pc(USBTX, USBRX);     // pc feedback
+
+extern void main_cycle_add(void);
+extern void initHMIio(void);
+extern int SetLasComm(int icLC);
+extern void flipRS(void);
+
+// These two defines can be enabled, or commented out
+#define BIG_SCREEN
+//#define CAP_TOUCH
+#define LCD_C 16         // color - bits per pixel
+
+#ifdef CAP_TOUCH
+RA8875 lcd(p5, p6, p7, p8, NC, p11,p12,p13, "tft"); // MOSI,MISO,SCK,/ChipSelect,/reset, SDA,SCL,/IRQ, name
+#else
+RA8875 lcd(p5, p6, p7, p8, NC, "tft");             //MOSI, MISO, SCK, /ChipSelect, /reset, name
+//LocalFileSystem local ("sd");                     // access to calibration file for resistive touch.
+#endif
+
+#define PC_BAUD 115200  // I like the serial communications to be fast
+
+#ifdef BIG_SCREEN
+    #define LCD_W 800
+    #define LCD_H 480
+    #define DEF_RADIUS 50   // default radius of the fingerprint
+    #define BL_NORM 25      // Backlight Normal setting (0 to 255)
+#else
+    #define LCD_W 480
+    #define LCD_H 272
+    #define DEF_RADIUS 20   // default radius of the fingerprint
+    #define BL_NORM 25      // Backlight Normal setting (0 to 255)
+#endif
+
+#define Gray        (color_t)(RGB(187,187,187))
+
+color_t fingerColor[5] = {Blue, Red, Green, Yellow, Magenta};
+point_t last[5];        // space for tracking 5 touches
+int layer = 0;
+
+
+//SDFileSystem(mosi,miso,sclk,cs,name,cd, SwitchType, int hz);
+SDFileSystem sd(p5, p6, p7, p29, "sd", p30, SDFileSystem::SWITCH_NEG_NO, 8000000);
+
+int iPC;
+char bufferNL[512];
+//const char *rDr = "/";
+char *rDr = "/";
+
+Ticker tickRS;               //rs232 pc, io, laser 
+timestamp_t tickTime = 2048;  // ticker interval in microSec
+
+//Timer IOwait;                //timeout for IO controller RS232 connection
+int usMeasure;
+
+point_t lastTP;
+
+const char *cPN[8];
+const char *cWM[3];
+//---------------------------------------------------------------------------------
+TextBox txtBox[] = {
+    { 290, 15, 348, 57, 310, 20, Gray, Black, "1"},
+    { 350, 15, 408, 57, 370, 20, Gray, Black, "2"},
+    { 410, 15, 468, 57, 430, 20, Gray, Black, "3"},
+    { 470, 15, 528, 57, 490, 20, Gray, Black, "4"},
+    { 530, 15, 588, 57, 550, 20, Gray, Black, "5"},
+    { 590, 15, 648, 57, 610, 20, Gray, Black, "6"},
+    { 650, 15, 708, 57, 670, 20, Gray, Black, "7"},
+    { 710, 15, 768, 57, 730, 20, Gray, Black, "8"},
+    { 290, 70, 408, 112, 300, 75, Gray, Black, "Circle"},
+    { 410, 70, 528, 112, 420, 75, Gray, Black, "Eight"},
+    { 530, 70, 648, 112, 540, 75, Gray, Black, "Infinity"}
+};
+int TextBoxSize = 11;
+int progNumber = 0;     //program# 0..7
+int wobbleMode = 0;     //wobble mode
+int Lmode = 0;          //laser mode
+
+ProgPar prPar[] = {     //default (init) parameters
+    { 0, 10,  50, 0, 100, 100, 1, 4, 230,  500,  4},
+    { 0, 20,  80, 0, 200,  50, 2, 5, 200, 1000,  7},
+    { 0, 30,  90, 0, 400,  25, 3, 3, 100, 1500,  1},
+    { 0, 40, 100, 0, 500,  10, 4, 5,  50, 1600,  3},
+    { 1, 50,  70, 1, 100,   8, 1, 5, 250, 1100,  9},
+    { 1, 60, 100, 1, 200,   5, 2, 5, 180,  800,  5},
+    { 2, 70,  75, 1, 400,  10, 1, 3, 120,  600,  7},
+    { 2, 80,  85, 1, 500,   9, 3, 5, 240,  750, 21}
+};
+char nCh[] = {'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};
+                             
+TextBoxR txtBoxR[] = {
+    { 290, 125, 380, 167, 10, 8, 320, 130, Gray, Black, "10"},          //LPbeg
+    { 470, 125, 560, 167, 10, 8, 500, 130, Gray, Black, "100"},         //LPend
+    { 650, 125, 768, 167, 10, 8, 660, 130, Gray, Black, "CW"},          //Lmode
+    { 290, 180, 380, 222, 10, 8, 320, 185, Gray, Black, "500"},         //Lfreq
+    { 470, 180, 560, 222, 10, 8, 500, 185, Gray, Black, "10"},          //Lpulse
+    { 290, 235, 380, 277, 10, 8, 320, 240, Gray, Black, "20"},          //amplBeg
+    { 470, 235, 560, 277, 10, 8, 500, 240, Gray, Black, "50"},          //amplEnd
+    { 290, 290, 380, 332, 10, 8, 320, 295, Gray, Black, "250"},         //wobFreq
+    { 290, 345, 380, 387, 10, 8, 310, 350, Gray, Black, "1500"},        //wobtime
+    { 470, 345, 560, 387, 10, 8, 500, 350, Gray, Black, "4"},           //amplNum
+    { 200, 410, 600, 452, 10, 8, 210, 415, Gray, Green, "R E A D Y"},   //status line
+    { 625, 253, 775, 343,  5, 3, 635, 283, Yellow, Black, "  E D I T"},   //edit btn
+    { 625, 365, 775, 455,  5, 3, 635, 395, Yellow, Black, "  M A I N"}    //main btn
+};
+int TextBoxRSize = 13;
+int numTPstatus = 10;   // # txtBoxR[10] for status line    
+int numTPeditBtn = 11;  // # txtBoxR[11] for edit btn
+int numTPmainBtn = 12;  // # txtBoxR[12] for main btn
+int numTPvalBtn = 11;   // # txtBoxR[11] for values btn
+int numTPservBtn = 12;  // # txtBoxR[12] for service btn
+int numPrPar = 10;      // # of integer programm parameters
+int numLmode = 2;       // # of Lmode parameter
+
+int flagParChanged = 0;
+int flagLrsConnected = 0;
+int flagLcomProcess = 0;
+int flagWeld = 0;       //welding in progress    
+int TPmode = 0;         //0-Operate mode, 1-Edit mode, 2-Service mode
+int editBtnMode = 0;    //0-edit, 1-set
+int TPstatus = 0;       //index Stat[]
+char sTatus[32];
+
+// Status reported by controller
+TPstring Stat[] = {"R E A D Y",             //status 0
+                   "IO NOT READY",          //status 1
+                   "E-STOP ON",             //status 2
+                   "LASER POWER OFF",       //status 3
+                   "LASER NOT READY",       //status 4
+                   "LASER RS232 NOT READY", //status 5
+                   "SHORT IO COMMAND",      //status 6
+                   "WRONG IO COMMAND",      //status 7
+                   "",                      //status 8
+                   "",                      //status 9
+                   "",                      //status 10 (do not change it)
+                   "LASER DOES NOT ANSWER", //error 11
+                   "LASER COMMAND ERROR",   //error 12
+                   "",                      //error 13
+                   "",                      //status 14
+                   "",                      //status 15
+                   "READY FOR WELDING",     //status 16 
+                   "WOBBLE HEAD INIT...",   //status 17 
+                   "WOBBLE HEAD ERROR",     //status 18 
+                   "IO CONTROLLER ERROR",   //status 19 
+                   "WELDING IN PROGRESS..", //status 20 
+                   "",                      //status 21 (auto reset e-stop) 
+                   };
+int indStat = 0;
+                   
+// Errors reported by controller    
+TPstring fErr[] = {"Done!",
+                   "Write error!",
+                   "Failed to close file!",
+                   "Failed to create file!",
+                   "Failed to open file!",
+                   "No card present!",
+                   "Failed mount SD!"};
+//Numpad screen label 
+TPstring Labels[] = {"Laser power [%] beg",
+                     "Laser power [%] end",
+                     "Laser mode",
+                     "Laser frequency [Hz]",
+                     "Laser pulse length [%]",
+                     "Amplitude [0.1mm] beg.",
+                     "Amplitude [0.1mm] end",
+                     "Wobble frequency [Hz]",
+                     "Welding time [mS]",
+                     "# of amplitude steps",
+                     "File p#"};
+int LabelsIndex = 0;                     
+
+TextBox txtBoxNP[] = {
+    { 656, 166, 776, 261, 706, 186, Gray, Black, "0"},
+    { 290, 360, 410, 455, 340, 380, Gray, Black, "1"},
+    { 412, 360, 532, 455, 462, 380, Gray, Black, "2"},
+    { 534, 360, 654, 455, 584, 380, Gray, Black, "3"},
+    { 290, 263, 410, 358, 340, 283, Gray, Black, "4"},
+    { 412, 263, 532, 358, 462, 283, Gray, Black, "5"},
+    { 534, 263, 654, 358, 584, 283, Gray, Black, "6"},
+    { 290, 166, 410, 261, 340, 186, Gray, Black, "7"},
+    { 412, 166, 532, 261, 462, 186, Gray, Black, "8"},
+    { 534, 166, 654, 261, 584, 186, Gray, Black, "9"},
+    { 656, 263, 776, 358, 706, 283, Gray, Black, "."},
+    { 656, 360, 776, 455, 680, 380, Gray, Black, "BACK"},
+    { 656, 69, 776, 164, 695, 89, Gray, Black, "OK"}
+};
+int TextBoxNPSize = 13;
+int NPinp = 0;
+bool flagNPinp = false;
+                                             
+int LPscreen = 0;    //0-values, 1-numpad, 2-sevice, 3-main screen
+
+TextBoxR txtBNP = { 300, 120, 640, 162, 10, 8, 320, 130, Gray, Black, ""};
+
+MinMax miMa[] = {
+    { 0, 100},    //0-LPbeg
+    { 0, 100},    //1-LPend
+    { 0, 1},      //2
+    { 1, 1000},   //3-Lfreq
+    { 1, 100},    //4-Lpulse
+    { 0, 90},     //5-amplBeg
+    { 0, 90},     //6-amplEnd
+    { 1, 100},    //7-wFreq
+    { 1, 5000},   //8-wTime
+    { 1, 100},    //9-amplNum
+    { 0, 99}      //10-file p#
+};
+int miMaSize = 9;
+
+IOPar ioPar;    //io controller parameters
+
+//------service-------------------------
+TextBoxR txtRServ[] = {
+    { 625, 365, 775, 455, 10, 8, 650, 395, Yellow, Black, "M A I N"},     //btn main
+    { 625, 276, 775, 346, 10, 8, 650, 296, Yellow, Black, "S A V E"},     //btn save
+    { 625, 196, 775, 266, 10, 8, 650, 216, Yellow, Black, "L O A D"},     //btn load
+    { 625, 116, 775, 186, 10, 8, 650, 136, Yellow, Black, " D I R"},      //btn dir
+    { 715,  26, 775,  86, 10, 8, 725,  40, Gray,   Black,   "0"},         //file #
+};
+int txtRServSize = 5;
+int fileNum = 0;
+
+TextBox txtBoxDir[] = {
+    { 20,  54, 400,  91, 25,  58, Gray, Black, " "},
+    { 20,  93, 400, 130, 25,  97, Gray, Black, " "},
+    { 20, 132, 400, 169, 25, 136, Gray, Black, " "},
+    { 20, 171, 400, 208, 25, 175, Gray, Black, " "},
+    { 20, 210, 400, 247, 25, 214, Gray, Black, " "},
+    { 20, 249, 400, 286, 25, 253, Gray, Black, " "},
+    { 20, 288, 400, 325, 25, 292, Gray, Black, " "},
+    { 20, 327, 400, 364, 25, 331, Gray, Black, " "},
+    { 20, 366, 400, 403, 25, 370, Gray, Black, " "}
+};
+int TextBoxDirSize = 9;
+
+TextBoxR txtRdir[] = {
+    { 410,  20, 560, 110, 10, 8, 425,  48, Yellow, Black, "SPLASH"},   //btn splash
+    { 410, 210, 560, 300, 10, 8, 450, 238, Yellow, Black, "  UP"},     //btn up
+    { 410, 310, 560, 400, 10, 8, 440, 338, Yellow, Black, " DOWN"},    //btn down
+};
+int txtRdirSize = 3;
+//---------------------------------------------------------------------------------
+void flipUS(void) {
+    NVIC_DisableIRQ(TIMER3_IRQn);    //disable timer3 interrupt
+    flipRS();    
+    LPC_TIM3->IR |= 1 << 0;         // Clear MR0 interrupt flag
+    NVIC_EnableIRQ(TIMER3_IRQn);    //enable timer3 interrupt
+}   
+
+ void writeTestFile(void)
+ {
+    //creating a 1MB test file <Test File.bin>
+    iPC = pc.printf("Write <Test File.bin> from %iB buffer", sizeof(bufferNL));
+    FileHandle* file = sd.open("Test File.bin", O_WRONLY | O_CREAT | O_TRUNC);
+    if (file != NULL) {
+        for (int i = 0; i < (1048576 / sizeof(bufferNL)); i++) {
+            if (file->write(bufferNL, sizeof(bufferNL)) != sizeof(bufferNL)) {
+                pc.printf("write error!\n");
+                return;
+            }
+        }
+        if (file->close())
+            pc.printf("failed to close file!\n");
+        else
+            pc.printf("done!\n");
+    } else {
+        printf("failed to create file!\n");
+    }
+}
+
+void readTestFile(void)
+{
+    //read buffer from the 1MB file created by writeTest()
+    pc.printf("Read <Test File.bin> to %iB buffer.. ", sizeof(bufferNL));
+    FileHandle* file = sd.open("Test File.bin", O_RDONLY);
+    if (file != NULL) {
+        file->read(bufferNL, sizeof(bufferNL));
+        if (file->close())
+           pc.printf("failed to close file!\n");
+        else
+           pc.printf("done!\n");
+    }
+    else {
+        pc.printf("failed to open file!\n");
+    }
+}
+
+void fillTestBuffer(void){
+    for (int i = 0; i < 40; i++) {bufferNL[i] = (char)48;} 
+    for (int i = 0; i < 440; i++) {bufferNL[i+40] = (char)49;}    
+    for (int i = 0; i < 60; i++) {bufferNL[i+440] = (char)48;}
+    
+    for (int i = 0; i < 10; i++) {
+        for (int j = 0; j < 50; j++) {
+            pc.printf("%c",bufferNL[i * 50 + j]);
+        }
+        pc.printf("\n");
+    }
+}
+
+int connectSD(void){
+    //Make sure a card is present
+    if (!sd.card_present()) {
+        pc.printf("\nNo card present!\n");
+        return 1;
+    }
+    //Try to mount the SD card
+    //pc.printf("\nMounting SD card...");  //%u", aaa);
+    if (sd.mount() != 0) {
+        pc.printf("failed mount SD!\n");
+        return 2;
+    }
+    //pc.printf("success!\n");
+    return 0;
+}
+
+
+void disconnectSD(void) {
+    sd.unmount();    
+}
+    
+void infoSD(void)
+{
+     //Display the card type
+    pc.printf("\tCard type: ");
+    SDFileSystem::CardType cardType = sd.card_type();
+    if (cardType == SDFileSystem::CARD_NONE)
+        pc.printf("None\n");
+    else if (cardType == SDFileSystem::CARD_MMC)
+        pc.printf("MMC\n");
+    else if (cardType == SDFileSystem::CARD_SD)
+        pc.printf("SD\n");
+    else if (cardType == SDFileSystem::CARD_SDHC)
+        pc.printf("SDHC\n");
+    else
+        pc.printf("Unknown\n");
+    //Display the card capacity
+    pc.printf("\tSectors: %u\n", sd.disk_sectors());
+    pc.printf("\tCapacity: %.1fMB\n", sd.disk_sectors() / 2048.0);
+}
+
+bool readDirSD(char *pDr)
+{
+    bool result = true;
+    DIR *dir;
+    struct dirent *ent;
+    //pc.printf("D- %i\n", pDr);    
+    if ((dir = sd.opendir (pDr)) != NULL) {
+        // print all the files and directories within directory
+        while ((ent = readdir (dir)) != NULL) {
+            pc.printf("%s\r\n", ent->d_name);
+        }
+        closedir (dir);
+    } else {
+        // could not open directory
+        pc.printf("Could not open directory");
+        result = false;
+    }
+    return !result;
+}
+
+char dirName[40][40];
+int indName = 0;
+string dirS;
+ 
+bool readDirHmiSD(char *pDr)
+{
+    bool result = true;
+    DIR *dir;
+    struct dirent *ent;
+    if ((dir = sd.opendir (pDr)) != NULL) {
+        dirS.assign(pDr);
+        // copy all the files and directories within directory
+        indName = 0;
+        while ((ent = readdir (dir)) != NULL) {
+            strcpy(dirName[indName++], ent->d_name);
+        }
+        closedir (dir);
+    } else {
+        // could not open directory
+        pc.printf("Could not open directory");
+        result = false;
+    }
+    return !result;
+} 
+//ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+int bufferPar[128];
+
+void saveBufferPar(void){
+    //clean bufferPar[]
+    for (int i = 0; i < 128; i++) {
+        bufferPar[i] = 0;
+    }
+    //save parameters in bufferPar 
+    for (int i = 0; i < 8; i++) {
+        bufferPar[i*16] = prPar[i].wMode;
+        bufferPar[i*16+1] = prPar[i].LPbeg;
+        bufferPar[i*16+2] = prPar[i].LPend;
+        bufferPar[i*16+3] = prPar[i].Lmode;
+        bufferPar[i*16+4] = prPar[i].Lfreq;
+        bufferPar[i*16+5] = prPar[i].Lpulse;
+        bufferPar[i*16+6] = prPar[i].amplBeg;
+        bufferPar[i*16+7] = prPar[i].amplEnd;
+        bufferPar[i*16+8] = prPar[i].wFreq;
+        bufferPar[i*16+9] = prPar[i].wTime;
+        bufferPar[i*16+10] = prPar[i].amplNum;   
+    }
+    //print bufferPar
+//    /*
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16]);}
+    pc.printf("wMode\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+1]);}
+    pc.printf("LPbeg\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+2]);}
+    pc.printf("LPend\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+3]);}
+    pc.printf("Lmode\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+4]);}
+    pc.printf("Lfreq\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+5]);}
+    pc.printf("Lpulse\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+6]);}
+    pc.printf("amplBeg\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+7]);}
+    pc.printf("amplEnd\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+8]);}
+    pc.printf("wFreq\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+9]);}
+    pc.printf("wTime\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+10]);}
+    pc.printf("amplNum\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",bufferPar[j * 16+11]);}
+    pc.printf("\n");
+//    */
+}
+
+void readBufferPar(void){
+    //save parameters in prPar
+    for (int i = 0; i < 8; i++) {
+        if(bufferPar[i*16] < 0) bufferPar[i*16] = 0;
+        if(bufferPar[i*16] > 2) bufferPar[i*16] = 2;
+        prPar[i].wMode = bufferPar[i*16];
+        if(bufferPar[i*16+1] < miMa[0].min) bufferPar[i*16+1] = miMa[0].min;
+        if(bufferPar[i*16+1] > miMa[0].max) bufferPar[i*16+1] = miMa[0].max;
+        prPar[i].LPbeg = bufferPar[i*16+1];
+        if(bufferPar[i*16+2] < miMa[1].min) bufferPar[i*16+2] = miMa[1].min;
+        if(bufferPar[i*16+2] > miMa[1].max) bufferPar[i*16+2] = miMa[1].max;
+        prPar[i].LPend = bufferPar[i*16+2];
+        if(bufferPar[i*16+3] < miMa[2].min) bufferPar[i*16+3] = miMa[2].min;
+        if(bufferPar[i*16+3] > miMa[2].max) bufferPar[i*16+3] = miMa[2].max;
+        prPar[i].Lmode = bufferPar[i*16+3];
+        if(bufferPar[i*16+4] < miMa[3].min) bufferPar[i*16+4] = miMa[3].min;
+        if(bufferPar[i*16+4] > miMa[3].max) bufferPar[i*16+4] = miMa[3].max;
+        prPar[i].Lfreq = bufferPar[i*16+4];
+        if(bufferPar[i*16+5] < miMa[4].min) bufferPar[i*16+5] = miMa[4].min;
+        if(bufferPar[i*16+5] > miMa[4].max) bufferPar[i*16+5] = miMa[4].max;
+        prPar[i].Lpulse = bufferPar[i*16+5];
+        if(bufferPar[i*16+6] < miMa[5].min) bufferPar[i*16+6] = miMa[5].min;
+        if(bufferPar[i*16+6] > miMa[5].max) bufferPar[i*16+6] = miMa[5].max;
+        prPar[i].amplBeg = bufferPar[i*16+6];
+        if(bufferPar[i*16+7] < miMa[6].min) bufferPar[i*16+7] = miMa[6].min;
+        if(bufferPar[i*16+7] > miMa[6].max) bufferPar[i*16+7] = miMa[6].max;
+        prPar[i].amplEnd = bufferPar[i*16+7];
+        if(bufferPar[i*16+8] < miMa[7].min) bufferPar[i*16+8] = miMa[7].min;
+        if(bufferPar[i*16+8] > miMa[7].max) bufferPar[i*16+8] = miMa[7].max;
+        prPar[i].wFreq = bufferPar[i*16+8];
+        if(bufferPar[i*16+9] < miMa[8].min) bufferPar[i*16+9] = miMa[8].min;
+        if(bufferPar[i*16+9] > miMa[8].max) bufferPar[i*16+9] = miMa[8].max;
+        prPar[i].wTime = bufferPar[i*16+9];
+        if(bufferPar[i*16+10] < miMa[9].min) bufferPar[i*16+10] = miMa[9].min;
+        if(bufferPar[i*16+10] > miMa[9].max) bufferPar[i*16+10] = miMa[9].max;
+        prPar[i].amplNum = bufferPar[i*16+10];   
+    }
+    //print prPar
+//    /*
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].wMode);}
+    pc.printf("wMode\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].LPbeg);}
+    pc.printf("LPbeg\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].LPend);}
+    pc.printf("LPend\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].Lmode);}
+    pc.printf("Lmode\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].Lfreq);}
+    pc.printf("Lfreq\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].Lpulse);}
+    pc.printf("Lpulse\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].amplBeg);}
+    pc.printf("amplBeg\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].amplEnd);}
+    pc.printf("amplEnd\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].wFreq);}
+    pc.printf("wFreq\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].wTime);}
+    pc.printf("wTime\n");
+    for (int j = 0; j < 8; j++) {pc.printf("%i ",prPar[j].amplNum);}
+    pc.printf("amplNum\n");
+//    */
+}
+
+char fileN[20];
+int errOK;
+
+int wrFile(char *fName)
+{
+    errOK = connectSD();
+    if(errOK == 0) {
+        FileHandle* file = sd.open(fName, O_WRONLY | O_CREAT | O_TRUNC);
+        if (file != NULL) {
+            if (file->write(bufferPar, sizeof(bufferPar)) != sizeof(bufferPar)) {
+                pc.printf("write error!\n");
+                errOK = 1;
+            }
+            if (file->close()) {
+                pc.printf("failed to close file!\n");
+                errOK = 2;
+            }    
+            else {
+                pc.printf("done!\n");
+                errOK = 0;
+            }
+        }        
+        else {
+            printf("failed to create file!\n");
+            errOK = 3;
+        }
+        disconnectSD();
+    }
+    else {errOK = errOK + 4;}
+    return errOK;
+}
+
+int writeIniFile(void)
+{
+    for (int i = 0; i < 128; i++) {bufferPar[i] = 0;}   //clean bufferPar[]
+    bufferPar[0] = fileNum;
+    bufferPar[1] = progNumber;
+    
+    sprintf(fileN, "p.ini");
+    pc.printf("%s\n", fileN);
+    
+    int resp = wrFile(fileN);
+    return resp;
+}
+
+int writeParFile(int numP)
+{
+    saveBufferPar();
+
+    sprintf(fileN, "p%i.par", numP);
+    pc.printf("%s\n", fileN);
+    
+    int resp = wrFile(fileN);
+    if(resp == 0) {resp = writeIniFile();}
+    return resp;
+}
+
+int rdFile(char *fName)
+{
+    errOK = connectSD();
+    if(errOK == 0) {
+        FileHandle* file = sd.open(fName, O_RDONLY);
+        if (file != NULL) {
+            file->read(bufferPar, sizeof(bufferPar));
+            if (file->close()) {
+               pc.printf("failed to close file!\n");
+               errOK = 2;
+            }   
+            else {
+               pc.printf("done!\n");
+               errOK = 0;
+            }   
+        }
+        else {
+            pc.printf("failed to open file!\n");
+            errOK = 4;
+        }
+        disconnectSD();
+    }
+    else {errOK = errOK + 4;}
+    return errOK;
+}
+
+int readParFile(int numP)
+{
+    sprintf(fileN, "p%i.par", numP);
+    pc.printf("%s\n", fileN);
+    
+    int resp = rdFile(fileN);
+    if(resp == 0) {
+        readBufferPar();
+        resp = writeIniFile();
+    }
+    return resp;
+}
+
+void readIniFile(void)
+{
+    sprintf(fileN, "p.ini");
+    pc.printf("%s\n", fileN);
+    
+    int resp = rdFile(fileN);
+    if(resp == 0) {
+        if(bufferPar[0] < miMa[10].min) bufferPar[0] = miMa[10].min;
+        if(bufferPar[0] > miMa[10].max) bufferPar[0] = miMa[10].max;
+        fileNum = bufferPar[0];    
+        if(bufferPar[1] < 1) bufferPar[1] = 1;
+        if(bufferPar[1] > 8) bufferPar[1] = 8;
+        progNumber = bufferPar[1];    
+        resp = readParFile(fileNum);
+    }    
+}
+//ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+
+//---------------------------------------------
+// When drawing a "fingerprint" under the touch point - the RA8875 
+// cannot draw an object partially off-screen, so this shrinks the 
+// fingerprint as the touch approaches the edge of the screen.
+//
+int ComputeRadius(point_t p)
+{
+    int radius = DEF_RADIUS;
+    
+    if (p.x < radius)
+        radius = p.x;
+    else if (LCD_W - p.x < radius)
+        radius = LCD_W - p.x;
+    if (p.y < radius)
+        radius = p.y;
+    else if (LCD_H - p.y < radius)
+        radius = LCD_H - p.y;
+    return radius;
+}
+
+// Calibrate the resistive touch screen, and store the data on the local file system.
+void CalibrateTS(void)
+{
+    tpMatrix_t matrix;
+    RetCode_t r;
+    Timer testperiod;
+ 
+    r = lcd.TouchPanelCalibrate("Calibrate the touch panel", &matrix);
+    if (r == noerror) {
+        if (connectSD() == 0) {
+            FileHandle* fh = sd.open("tpcal.cfg", O_WRONLY | O_CREAT | O_TRUNC);
+            if (fh) {
+                if (fh->write(&matrix, sizeof(tpMatrix_t)) != sizeof(tpMatrix_t))
+                {
+                    pc.printf("write error!\n");
+                }
+                if (fh->close()) pc.printf("failed to close file!\n");
+            }
+            else printf("failed to create tpcal.cfg file!\n");
+        }    
+    } 
+    else printf("error TP Calibrate: %d\r\n", r);
+    disconnectSD();
+    pc.printf("TS ok\n");
+    lcd.cls();
+}
+
+// Try to load a previous resistive touch screen calibration from storage. If it
+// doesn't exist, activate the touch screen calibration process.
+void InitTS(void)
+{
+    tpMatrix_t matrix;
+    if (connectSD() == 0) {
+        FileHandle* fh = sd.open("tpcal.cfg", O_RDONLY);
+        if (fh) {
+            if (fh->read(&matrix, sizeof(tpMatrix_t)) != sizeof(tpMatrix_t))
+            {
+                pc.printf("read error!\n");
+                //return;
+                if (fh->close()) pc.printf("failed to close file!\n");
+            }
+            else
+            {
+                lcd.TouchPanelSetMatrix(&matrix);
+                if (fh->close()) pc.printf("failed to close file!\n");
+                disconnectSD();
+                pc.printf("ok\n");
+                return;
+            }
+        }
+        else printf("failed to open tpcal.cfg file!\n");
+    }
+    disconnectSD();
+    CalibrateTS();
+}
+
+//-------------------------------------------------------
+void lcd800x480Init(void)
+{
+    lcd.init(LCD_W,LCD_H,LCD_C);
+    //lcd.init();
+    lcd.Backlight(0.5f);
+    //lcd.Backlight_u8(BL_NORM);
+
+    lcd.foreground(RGB(255,255,0));
+    lcd.background(RGB(0,0,0));
+    
+    lcd.SelectUserFont(BPG_Arial08x08);
+    lcd.puts(300, 0, "www.ipgphotonics.com\r\n");
+
+    lcd.SelectUserFont(BPG_Arial31x32);
+    
+    lastTP.x = 0;
+    lastTP.y = 0;
+}
+
+void showTPstatus(int k)
+{
+    int i = numTPstatus;
+    lcd.fillroundrect(txtBoxR[i].x1, txtBoxR[i].y1, txtBoxR[i].x2, txtBoxR[i].y2, txtBoxR[i].r1, txtBoxR[i].r2, txtBoxR[i].color);
+    lcd.foreground(txtBoxR[i].textColor);
+    lcd.background(txtBoxR[i].color);
+    
+    lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "                               ");
+    lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, Stat[k]);
+    //pc.printf("q%i\n", k);
+}
+
+void showTPeditBtn(int k)
+{
+    int i = numTPeditBtn;
+    lcd.fillroundrect(txtBoxR[i].x1, txtBoxR[i].y1, txtBoxR[i].x2, txtBoxR[i].y2, txtBoxR[i].r1, txtBoxR[i].r2, txtBoxR[i].color);
+    lcd.foreground(txtBoxR[i].textColor);
+    lcd.background(txtBoxR[i].color);
+    
+    if(k == 0) {lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "  E D I T");}
+    else {lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "   S E T");}
+}
+
+void showTPmainBtn(void)
+{
+    int i = numTPmainBtn;
+    lcd.fillroundrect(txtBoxR[i].x1, txtBoxR[i].y1, txtBoxR[i].x2, txtBoxR[i].y2, txtBoxR[i].r1, txtBoxR[i].r2, txtBoxR[i].color);
+    lcd.foreground(txtBoxR[i].textColor);
+    lcd.background(txtBoxR[i].color);
+    
+    lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "  M A I N");
+}
+
+void showTPvalBtn(void)
+{
+    int i = numTPvalBtn;
+    lcd.fillroundrect(txtBoxR[i].x1, txtBoxR[i].y1, txtBoxR[i].x2, txtBoxR[i].y2, txtBoxR[i].r1, txtBoxR[i].r2, txtBoxR[i].color);
+    lcd.foreground(txtBoxR[i].textColor);
+    lcd.background(txtBoxR[i].color);
+    
+    lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, " VALUES");
+}
+
+void showTPservBtn(void)
+{
+    int i = numTPservBtn;
+    lcd.fillroundrect(txtBoxR[i].x1, txtBoxR[i].y1, txtBoxR[i].x2, txtBoxR[i].y2, txtBoxR[i].r1, txtBoxR[i].r2, txtBoxR[i].color);
+    lcd.foreground(txtBoxR[i].textColor);
+    lcd.background(txtBoxR[i].color);
+    
+    lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "SERVICE");
+}
+
+void showProgNum(int i)
+{
+    //pc.printf("%i\n", i);
+    if((i >= 0) && (i < 8)) { //&& (i != progNumber) ) {
+        //pc.printf(":\n");
+        lcd.fillrect(txtBox[progNumber].x1, txtBox[progNumber].y1, txtBox[progNumber].x2, txtBox[progNumber].y2, txtBox[progNumber].color);
+        lcd.foreground(txtBox[progNumber].textColor);
+        lcd.background(txtBox[progNumber].color);
+        lcd.puts(txtBox[progNumber].textX, txtBox[progNumber].textY, txtBox[progNumber].text);
+        
+        lcd.fillrect(txtBox[i].x1, txtBox[i].y1, txtBox[i].x2, txtBox[i].y2, Green);
+        lcd.foreground(txtBox[i].textColor);
+        lcd.background(Green);
+        lcd.puts(txtBox[i].textX, txtBox[i].textY, txtBox[i].text);
+        progNumber = i; 
+    }
+}
+ 
+void showWobMode(int i)
+{
+    if((i >= 0) && (i < 3)) {
+        //pc.printf(";\n");
+        int k;
+        k = wobbleMode + 8;
+        lcd.fillrect(txtBox[k].x1, txtBox[k].y1, txtBox[k].x2, txtBox[k].y2, txtBox[k].color);
+        lcd.foreground(txtBox[k].textColor);
+        lcd.background(txtBox[k].color);
+        lcd.puts(txtBox[k].textX, txtBox[k].textY, txtBox[k].text);
+        k = i + 8;
+        lcd.fillrect(txtBox[k].x1, txtBox[k].y1, txtBox[k].x2, txtBox[k].y2, Green);
+        lcd.foreground(txtBox[k].textColor);
+        lcd.background(Green);
+        lcd.puts(txtBox[k].textX, txtBox[k].textY, txtBox[k].text);
+        wobbleMode = i;
+    }
+}
+    
+void showWobParam(int i)
+{
+    showWobMode(i);
+    prPar[progNumber].wMode = i;
+}
+
+void showProgParam(int k)
+{
+    showProgNum(k);
+    //fill round text boxes (TextBoxR)
+    showWobMode(prPar[progNumber].wMode);
+    for(int i = 0; i < numPrPar; i++) {
+        lcd.fillroundrect(txtBoxR[i].x1, txtBoxR[i].y1, txtBoxR[i].x2, txtBoxR[i].y2, txtBoxR[i].r1, txtBoxR[i].r2, txtBoxR[i].color);
+        lcd.foreground(txtBoxR[i].textColor);
+        lcd.background(txtBoxR[i].color);
+        if (i == 2) {
+             if(prPar[progNumber].Lmode == 0) {
+                 lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "CW");
+                 if(Lmode == 1) { 
+                     Lmode = 0;
+                     if(SetLasComm(33) == 1) {TPstatus = 5;}      //DPM -disable pulse mode
+                     else {
+                        if(SetLasComm( 1) == 1) {TPstatus = 5;}   //STA -read laser status
+                        else TPstatus = 0; 
+                    }
+                }               
+             }    
+             else if(prPar[progNumber].Lmode == 1) {
+                 lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "PULSE");
+                 if(Lmode == 0) {
+                     Lmode = 1;
+                     if(SetLasComm(32) == 1) {TPstatus = 5;}       //EPM -enable pulse mode
+                     else {
+                        if(SetLasComm( 1) == 1) {TPstatus = 5;}   //STA -read laser status
+                        else TPstatus = 0; 
+                    }
+                }                    
+            }    
+        }
+        else {
+            switch (i) {
+                case 0: {sprintf(txtBoxR[0].text, "%i", prPar[progNumber].LPbeg); break;}
+                case 1: {sprintf(txtBoxR[1].text, "%i", prPar[progNumber].LPend); break;}
+                case 3: {sprintf(txtBoxR[3].text, "%i", prPar[progNumber].Lfreq); break;}
+                case 4: {sprintf(txtBoxR[4].text, "%i", prPar[progNumber].Lpulse); break;}
+                case 5: {sprintf(txtBoxR[5].text, "%i", prPar[progNumber].amplBeg); break;}
+                case 6: {sprintf(txtBoxR[6].text, "%i", prPar[progNumber].amplEnd); break;}
+                case 7: {sprintf(txtBoxR[7].text, "%i", prPar[progNumber].wFreq); break;}
+                case 8: {sprintf(txtBoxR[8].text, "%i", prPar[progNumber].wTime); break;}
+                case 9: {sprintf(txtBoxR[9].text, "%i", prPar[progNumber].amplNum); break;}
+            }
+            lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, txtBoxR[i].text);
+        }
+    }
+}
+
+void lcd800x480main(int a)
+{
+    lcd.roundrect(    2,10, 798,478, 10,8,    Yellow);  //full screen
+    lcd.fillroundrect(3,11, 797,477, 8,6,     Black);   //do full screen black
+    lcd.roundrect(    620,360, 780,460, 10,8, Yellow);  //around btn edit
+    lcd.roundrect(    620,248, 780,348, 10,8, Yellow);  //around btn service
+    lcd.roundrect(    5,62, 615,405, 10,8,    Yellow);  //picture screen
+    
+    lcd.foreground(Yellow);
+    lcd.background(Black);
+    lcd.puts(100, 20, "Program #");
+    lcd.puts(20, 415, "STATUS:");
+   
+    //fill text boxes (TextBox)
+    for(int i = 0; i < 8; i++) {
+        lcd.fillrect(txtBox[i].x1, txtBox[i].y1, txtBox[i].x2, txtBox[i].y2, txtBox[i].color);
+        lcd.foreground(txtBox[i].textColor);
+        lcd.background(txtBox[i].color);
+        lcd.puts(txtBox[i].textX, txtBox[i].textY, txtBox[i].text);
+    }
+    showProgNum(a);
+    //fill round text boxes (TextBoxR)
+
+}
+
+void lcd800x480val(int a)
+{
+    lcd.roundrect(    2,10, 798,478, 10,8,    Yellow);  //full screen
+    lcd.fillroundrect(3,11, 797,477, 8,6,     Black);   //do full screen black
+    lcd.roundrect(    620,360, 780,460, 10,8, Yellow);  //around btn edit
+    lcd.roundrect(    620,248, 780,348, 10,8, Yellow);  //around btn service
+    
+    lcd.foreground(Yellow);
+    lcd.background(Black);
+    lcd.puts(10, 20, "Program #");
+    lcd.puts(10, 75, "Wobble mode");
+    lcd.puts(10, 130, "Laser power [%] beg");
+    lcd.puts(390, 130, " end");
+    lcd.puts(570, 130, "mode");
+    lcd.puts(10, 185, "Laser freq.[Hz]");
+    lcd.puts(390, 185, "Pulse");
+    lcd.puts(575, 185, "[%]");
+    lcd.puts(10, 240, "Size [0.1mm] beg.");
+    lcd.puts(390, 240, " end");
+    lcd.puts(10, 295, "Wobble freq.[Hz]");
+    lcd.puts(10, 350, "Welding time [mS]");
+    lcd.puts(390, 350, "Steps");
+    lcd.puts(20, 415, "STATUS:");
+   
+    //fill text boxes (TextBox)
+    for(int i = 0; i < TextBoxSize; i++) {
+        lcd.fillrect(txtBox[i].x1, txtBox[i].y1, txtBox[i].x2, txtBox[i].y2, txtBox[i].color);
+        lcd.foreground(txtBox[i].textColor);
+        lcd.background(txtBox[i].color);
+        lcd.puts(txtBox[i].textX, txtBox[i].textY, txtBox[i].text);
+    }
+    //fill round text boxes (TextBoxR)
+    showProgParam(a);
+}
+
+void lcd800x480NP(int k)
+{
+    lcd.roundrect(    285,65, 781,460, 10,8,    Yellow);
+    lcd.fillroundrect(288,68, 776,455, 5,3,    Black);
+    
+    lcd.foreground(Yellow);
+    lcd.background(Black);
+    lcd.puts(300, 75, Labels[k]);
+   
+    //fill text boxes (TextBox)
+    for(int i = 0; i < TextBoxNPSize; i++) {
+        lcd.fillrect(txtBoxNP[i].x1, txtBoxNP[i].y1, txtBoxNP[i].x2, txtBoxNP[i].y2, txtBoxNP[i].color);
+        lcd.foreground(txtBoxNP[i].textColor);
+        lcd.background(txtBoxNP[i].color);
+        lcd.puts(txtBoxNP[i].textX, txtBoxNP[i].textY, txtBoxNP[i].text);
+    }
+    //fill round text box
+    lcd.fillroundrect(txtBNP.x1, txtBNP.y1, txtBNP.x2, txtBNP.y2, txtBNP.r1, txtBNP.r2, txtBNP.color);
+    lcd.foreground(txtBNP.textColor);
+    lcd.background(txtBNP.color);
+    *txtBNP.text = '\0';
+    lcd.puts(txtBNP.textX, txtBNP.textY, txtBNP.text);
+}
+
+void lcd800x480Serv(void)
+{
+    lcd.roundrect(    2,10, 798,478, 10,8,    Yellow);  //full screen
+    lcd.fillroundrect(3,11, 797,477, 8,6,     Black);   //do full screen black
+    lcd.roundrect(    620,360, 780,460, 10,8, Yellow);  //around main btn 
+    lcd.roundrect(    620,20, 780,348, 10,8, Yellow);   //around file btns
+    lcd.roundrect(    20,418, 600,460, 10,8, Yellow);   //around status line
+    
+    lcd.foreground(Yellow);
+    lcd.background(Black);
+    lcd.puts(623, 40, "File p#");
+   
+    //fill round text box
+    int i;
+    i = txtRServSize-1;
+    sprintf(txtRServ[i].text, "%i", fileNum);
+    for(i = 0; i < txtRServSize; i++) {
+        lcd.fillroundrect(txtRServ[i].x1, txtRServ[i].y1, txtRServ[i].x2, txtRServ[i].y2, txtRServ[i].r1, txtRServ[i].r2, txtRServ[i].color);
+        lcd.foreground(txtRServ[i].textColor);
+        lcd.background(txtRServ[i].color);
+        lcd.puts(txtRServ[i].textX, txtRServ[i].textY, txtRServ[i].text);
+    }
+}
+
+void lcd800x480dirB(void)
+{
+    lcd.fillrect(20, 15, 565, 405, Black);
+}
+
+void lcd800x480dir(char *pDr)
+{
+    int i;
+    
+    lcd.fillrect(20, 15, 565, 405, Black);            //clean area
+    lcd.roundrect(20,15, 400,52, 10,8,    Yellow);    //around dir name
+    lcd.roundrect(405,15, 565,405, 10,8,    Yellow);  //around buttons
+    
+    lcd.foreground(Yellow);
+    lcd.background(Black);
+    lcd.puts(25, 19, rDr);
+   
+    //fill round text box
+    for(i = 0; i < txtRdirSize; i++) {
+        lcd.fillroundrect(txtRdir[i].x1, txtRdir[i].y1, txtRdir[i].x2, txtRdir[i].y2, txtRdir[i].r1, txtRdir[i].r2, txtRdir[i].color);
+        lcd.foreground(txtRdir[i].textColor);
+        lcd.background(txtRdir[i].color);
+        lcd.puts(txtRdir[i].textX, txtRdir[i].textY, txtRdir[i].text);
+    }
+    //fill text boxes (TextBox)
+    for(i = 0; i < TextBoxDirSize; i++) {
+        lcd.fillrect(txtBoxDir[i].x1, txtBoxDir[i].y1, txtBoxDir[i].x2, txtBoxDir[i].y2, txtBoxDir[i].color);
+        lcd.foreground(txtBoxDir[i].textColor);
+        lcd.background(txtBoxDir[i].color);
+        //lcd.puts(txtBoxDir[i].textX, txtBoxDir[i].textY, txtBoxDir[i].text);
+    }
+}
+
+void showMain(int i) {
+    lcd800x480main(i);
+    showTPvalBtn();
+    showTPservBtn();
+    showTPstatus(TPstatus);
+    LPscreen = 3;
+}
+
+void showVal(int i) {
+    lcd800x480val(i);
+    showTPeditBtn(editBtnMode);
+    showTPmainBtn();
+    showTPstatus(TPstatus);
+}
+
+void showNP(int i) {
+    lcd800x480NP(i);    
+}
+
+void showService(void) {
+    lcd800x480Serv();    
+}
+
+void statServErr(int stS) {
+    lcd.foreground(Gray);
+    lcd.background(Black);
+    lcd.puts(30, 423, "                               ");
+    lcd.puts(30, 423, Stat[stS]);    
+}
+
+void statServ(int stS) {
+    lcd.foreground(Gray);
+    lcd.background(Black);
+    lcd.puts(30, 423, "                               ");
+    lcd.puts(30, 423, fErr[stS]);    
+}
+
+void dirOpenHmi(char *pDr) {
+    if(connectSD() == 0) {
+        readDirHmiSD(pDr);
+    }    
+    disconnectSD();
+    
+    lcd800x480dir(rDr);
+    if(indName > 9) {
+        for(int i=0; i<9; i++) {
+            lcd.puts(txtBoxDir[i].textX, txtBoxDir[i].textY, dirName[i]);
+        }    
+    }
+    else {
+        for(int i=0; i<indName; i++) {
+            lcd.puts(txtBoxDir[i].textX, txtBoxDir[i].textY, dirName[i]);
+        }    
+    }
+    for(int i=0; i<indName; i++) {
+        pc.printf("%s\n", dirName[i]);
+    }    
+    pc.printf(">>%i\n", indName);
+}            
+
+int flagDirOpen = 0;
+    
+void btnServ(int k) {
+    int retSt;
+    switch (k) {
+    case 0:    //btn main
+        showMain(progNumber);
+        LPscreen = 3;   //main screen
+        pc.printf("\n>");
+        break;
+    case 1:    //btn save
+        retSt = writeParFile(fileNum);
+        statServ(retSt);
+        pc.printf("\ns>%i ", retSt);
+        break;
+    case 2:    //btn load
+        retSt = readParFile(fileNum);
+        statServ(retSt);
+        pc.printf("\nl>%i ", retSt);
+        flagParChanged = 0;
+        break;
+    case 3:    //btn dir
+        if(flagDirOpen ==0) {
+            flagDirOpen = 1;
+            dirOpenHmi(rDr);
+        }
+        else {
+            flagDirOpen = 0;
+            lcd800x480dirB();
+        }    
+        break;
+    case 4:    //txtBox file#
+        showNP(10);
+        LabelsIndex = 10;
+        NPinp = 0;
+        flagNPinp = false;
+        LPscreen = 1;   //LP screen
+    
+        pc.printf("\nf ");
+        break;
+    }
+}
+/*
+RetCode_t showBitmap(loc_t x, loc_t y, uint32_t fileOffset, FILE * Image)
+{
+    BITMAPINFOHEADER BMP_Info;
+    RGBQUAD * colorPalette = NULL;
+    int colorCount;
+    uint8_t * lineBuffer = NULL;
+    color_t * pixelBuffer = NULL;
+    uint16_t BPP_t;
+    dim_t PixelWidth, PixelHeight;
+    unsigned int    i, offset;
+    int padd,j;
+
+    // Now, Read the bitmap info header
+    Image->read(&BMP_Info, sizeof(BMP_Info));
+    HexDump0("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info));
+    BPP_t = BMP_Info.biBitCount;
+    pc.printf("biBitCount %04X", BPP_t);
+    if (BPP_t != 1 && BPP_t != 4 && BPP_t != 8 && BPP_t != 16 && BPP_t != 24) { // Support 4, 8, 16, 24-bits per pixel
+        Image->close();
+        pc.printf("not_supported_format");
+        return(not_supported_format);
+    }
+    if (BMP_Info.biCompression != 0) {  // Only the "no comporession" option is supported.
+        Image->close();
+        pc.printf("not_supported_format");
+        return(not_supported_format);
+    }
+    PixelHeight = BMP_Info.biHeight;
+    PixelWidth = BMP_Info.biWidth;
+    pc.printf("(%d,%d) (%d,%d) (%d,%d)", x,y, PixelWidth,PixelHeight, width(), height());
+    if (PixelHeight > 340 || PixelWidth > 608 {
+        Image->close();
+        pc.printf("image_too_big");
+        return(image_too_big);
+    }
+    if (BMP_Info.biBitCount <= 8) {
+        int paletteSize;
+        // Read the color palette
+        colorCount = 1 << BMP_Info.biBitCount;
+        paletteSize = sizeof(RGBQUAD) * colorCount;
+        colorPalette = (RGBQUAD *)malloc(paletteSize);
+        if (colorPalette == NULL) {
+        Image->close();
+        pc.printf("not_enough_ram");
+            return(not_enough_ram);
+        }
+        Image->read(colorPalette, paletteSize);
+        HexDump0("Color Palette", (uint8_t *)colorPalette, paletteSize);
+    }
+
+    int lineBufSize = ((BPP_t * PixelWidth + 7)/8);
+    pc.printf("BPP_t %d, PixelWidth %d, lineBufSize %d", BPP_t, PixelWidth, lineBufSize);
+    lineBuffer = (uint8_t *)malloc(lineBufSize);
+    if (lineBuffer == NULL) {
+        free(colorPalette);
+        fclose(Image);
+        return(not_enough_ram);
+    }
+    pixelBuffer = (color_t *)malloc(PixelWidth * sizeof(color_t));
+    if (pixelBuffer == NULL) {
+        free(lineBuffer);
+        if (colorPalette)
+            free(colorPalette);
+        Image->close();
+        pc.printf("not_enough_ram");
+        return(not_enough_ram);
+    }
+
+    padd = (lineBufSize % 4);
+    if (padd)
+        padd = 4 - padd;
+
+    // Define window for top to bottom and left to right so writing auto-wraps
+    rect_t restore = windowrect;
+    window(x,y, PixelWidth,PixelHeight);
+    SetGraphicsCursor(x, y);
+    //StartGraphicsStream
+    WriteCommand(0x40,0x00);    // Graphics write mode
+    WriteCommand(0x02);         // Prepare for streaming data
+
+    //start_data = BMP_Info.bfOffBits;
+    //HexDump("Raw Data", (uint8_t *)&start_data, 32);
+    pc.printf("(%d,%d) (%d,%d), [%d,%d]", x,y, PixelWidth,PixelHeight, lineBufSize, padd);
+    for (j = PixelHeight - 1; j >= 0; j--) {                //Lines bottom up
+        offset = fileOffset + j * (lineBufSize + padd);     // start of line
+        //fseek(Image, offset, SEEK_SET);
+        Image->read(lineBuffer, lineBufSize);               // read a line - slow !
+        //INFO("offset: %6X", offset);
+        //HexDump("Line", lineBuffer, lineBufSize);
+        for (i = 0; i < PixelWidth; i++) {                  // copy pixel data to TFT
+            if (BPP_t == 1) {
+                uint8_t dPix = lineBuffer[i/8];
+                uint8_t bMask = 0x80 >> (i % 8);
+                uint8_t bit = (bMask & dPix) ? 0 : 1;
+                //INFO("%02X & %02X ? => %02X", dPix, bMask, bit);
+                pixelBuffer[i] = RGBQuadToRGB16(colorPalette, bit);                
+            } else if (BPP_t == 4) {
+                uint8_t dPix = lineBuffer[i/2];
+                if ((i & 1) == 0)
+                    dPix >>= 4;
+                dPix &= 0x0F;
+                pixelBuffer[i] = RGBQuadToRGB16(colorPalette, dPix);
+            } else if (BPP_t == 8) {
+                pixelBuffer[i] = RGBQuadToRGB16(colorPalette, lineBuffer[i]);
+            } else if (BPP_t == 16) {
+                pixelBuffer[i] = lineBuffer[i];
+            } else if (BPP_t == 24) {
+                color_t color;
+                color = RGB(lineBuffer[i*3+2], lineBuffer[i*3+1], lineBuffer[i*3+0]);
+                pixelBuffer[i] = color;
+            }
+        }
+        pixelStream(pixelBuffer, PixelWidth, x, y++);
+    }
+    window(restore);
+    free(pixelBuffer);      // don't leak memory
+    free(lineBuffer);
+    if (colorPalette)
+        free(colorPalette);
+    return (noerror);
+}
+
+static void HexDump0(const char * title, const uint8_t * p, int count)
+{
+    int i;
+    char buf[100] = "0000: ";
+    
+    if (*title)
+    for (i=0; i<count; ) {
+        sprintf(buf + strlen(buf), "%02X ", *(p+i));
+        if ((++i & 0x0F) == 0x00) {
+            if (i < count)
+                sprintf(buf, "%04X: ", i);
+            else
+                buf[0] = '\0';
+        }
+    }
+}
+
+void showPic(void) {
+    const char Name_BMP[] = "/local/48027224.bmp";
+    
+    if (connectSD() == 0) {
+        FileHandle* fh = sd.open(Name_BMP, O_RDONLY);
+        if (fh) {
+             if (fh->read(&BMP_Header, sizeof(BMP_Header)) != sizeof(BMP_Header))
+            {
+                pc.printf("read error!\n");
+                if (fh->close()) pc.printf("failed to close file!\n");
+            }
+            else
+            {
+                pc.printf("bfType %04X", BMP_Header.bfType);
+                HexDump0("BMP_Header", (uint8_t *)&BMP_Header, sizeof(BMP_Header));
+                if (BMP_Header.bfType != BF_TYPE) {
+                    fh->close();
+                    pc.printf("not_bmp_format");
+                }
+                pc.printf("bfOffits %04X", BMP_Header.bfOffBits);
+                RetCode_t rt = showBitmap(5, 62, BMP_Header.bfOffBits, fh);
+                pc.printf("==%i\n", rt);
+                if (fh->close()) pc.printf("failed to close file!\n");
+            }                
+        }
+        else {
+            pc.printf("file_not_found");    
+        }    
+    }       
+    disconnectSD();
+                
+            
+    char fqfn[50];
+    int i = 0;
+
+            if (fh->read(&matrix, sizeof(tpMatrix_t)) != sizeof(tpMatrix_t))
+            {
+                pc.printf("read error!\n");
+                //return;
+                if (fh->close()) pc.printf("failed to close file!\n");
+            }
+            else
+            {
+                lcd.TouchPanelSetMatrix(&matrix);
+                if (fh->close()) pc.printf("failed to close file!\n");
+                disconnectSD();
+                pc.printf("ok\n");
+                return;
+            }
+        }
+        else printf("failed to open tpcal.cfg file!\n");
+    }
+    disconnectSD();
+
+
+    INFO("Screen Capture... ");
+    for (i=1; i< 100; i++) {
+        snprintf(fqfn, sizeof(fqfn), "/local/Screen%02d.bmp", i);
+        FILE * fh = fopen(fqfn, "rb");
+        if (!fh) {
+            lcd.PrintScreen(0,0,lcd.width(),lcd.height(),fqfn);
+            INFO(" as /local/Screen%02d.bmp", i);
+            return i;
+        } else {
+            fclose(fh);     // close this and try the next
+        }
+    }
+    return 0;
+
+        RetCode_t r = lcd.PrintScreen(5,62,615,405,"/sd/local/48027224.bmp");
+}
+*/
+LocalFileSystem local("local"); 
+void showPic(void) {
+    RetCode_t r = lcd.RenderImageFile(8, 66, "/local/Rio24.bmp");    
+}    
+
+int indDirFirst = 0;
+int indDirCheck = 0;
+
+void btnDir(int k) {
+    int nn = indName;
+    switch (k) {
+    case 0:   //btn splash
+        showMain(progNumber);
+        LPscreen = 3;   //main screen
+
+        showPic();
+
+        break;
+    case 1:   //btn up
+        if(nn > 9) {
+            lcd800x480dir(rDr);
+            if((indDirFirst) > 8) indDirFirst = indDirFirst - 8;
+            else indDirFirst = 0;
+            for(int i=0; i<9; i++) {
+                lcd.puts(txtBoxDir[i].textX, txtBoxDir[i].textY, dirName[indDirFirst + i]);
+            }    
+        }
+        break;
+    case 2:   //btn down
+        if(nn > 9) {
+            lcd800x480dir(rDr);
+            if((nn - indDirFirst) > 16) indDirFirst = indDirFirst + 8;
+            else indDirFirst = nn - 9;
+            for(int i=0; i<9; i++) {
+                lcd.puts(txtBoxDir[i].textX, txtBoxDir[i].textY, dirName[indDirFirst + i]);
+            }    
+        }
+        break;
+    }
+}
+
+int indDirText = 0;
+char ccD[40];
+
+void btnDirText(int k) {
+    int nn = indDirText - 1;
+    
+    if(indDirText != 0) {
+        lcd.fillrect(txtBoxDir[nn].x1, txtBoxDir[nn].y1, txtBoxDir[nn].x2, txtBoxDir[nn].y2, txtBoxDir[nn].color);
+        lcd.foreground(txtBoxDir[nn].textColor);
+        lcd.background(txtBoxDir[nn].color);
+        lcd.puts(txtBoxDir[nn].textX, txtBoxDir[nn].textY, dirName[indDirFirst + nn]);
+    }
+    indDirText = k + 1;
+    nn = k;
+    lcd.fillrect(txtBoxDir[k].x1, txtBoxDir[k].y1, txtBoxDir[k].x2, txtBoxDir[k].y2, Yellow);
+    lcd.foreground(txtBoxDir[k].textColor);
+    lcd.background(Yellow);
+    lcd.puts(txtBoxDir[k].textX, txtBoxDir[k].textY, dirName[indDirFirst + k]);
+    
+    if (strchr(dirName[indDirFirst + k], '.') == NULL) {
+        //pc.printf("<%s>", dirName[indDirFirst + k]);
+        dirS.append(dirName[indDirFirst + k]);
+        //pc.printf("<%s>", dirS.c_str());
+        strcpy(&ccD[0], dirS.c_str());
+        //pc.printf("<%s>", ccD);
+        dirOpenHmi(ccD);
+        // clean directory
+        for(int i =indName; i<40; i++) {
+           strcpy(&dirName[indName++][0], "  ");
+        }
+            
+    }    
+}
+
+void txtBoxNPadd(int i) {
+    if(i < 10) {
+        NPinp =10 * NPinp + i;
+        if(NPinp > miMa[LabelsIndex].max) {NPinp = miMa[LabelsIndex].max;}
+        
+        lcd.fillroundrect(txtBNP.x1, txtBNP.y1, txtBNP.x2, txtBNP.y2, txtBNP.r1, txtBNP.r2, txtBNP.color);
+        lcd.foreground(txtBNP.textColor);
+        lcd.background(txtBNP.color);
+        sprintf(txtBNP.text, "%i", NPinp);
+        lcd.puts(txtBNP.textX, txtBNP.textY, txtBNP.text);
+        flagNPinp = true;
+    }    
+    if(i == 11) {
+        lcd.fillroundrect(txtBNP.x1, txtBNP.y1, txtBNP.x2, txtBNP.y2, txtBNP.r1, txtBNP.r2, txtBNP.color);
+        lcd.foreground(txtBNP.textColor);
+        lcd.background(txtBNP.color);
+        NPinp = NPinp / 10;
+        if(NPinp == 0) {
+            lcd.puts(txtBNP.textX, txtBNP.textY, "");
+            flagNPinp = false;
+        }
+        else {
+            sprintf(txtBNP.text, "%i", NPinp);
+            lcd.puts(txtBNP.textX, txtBNP.textY, txtBNP.text);
+        }
+    }    
+    if(i == 12) {
+        if(TPmode == 1) {
+            if(flagNPinp == true) {
+                if(NPinp < miMa[LabelsIndex].min) {NPinp = miMa[LabelsIndex].min;}
+                switch (LabelsIndex) {
+                    case 0: {prPar[progNumber].LPbeg = NPinp; break;}
+                    case 1: {prPar[progNumber].LPend = NPinp; break;}
+                    case 3: {prPar[progNumber].Lfreq = NPinp; break;}
+                    case 4: {prPar[progNumber].Lpulse = NPinp; break;}
+                    case 5: {prPar[progNumber].amplBeg = NPinp; break;}
+                    case 6: {prPar[progNumber].amplEnd = NPinp; break;}
+                    case 7: {prPar[progNumber].wFreq = NPinp; break;}
+                    case 8: {prPar[progNumber].wTime = NPinp; break;}
+                    case 9: {prPar[progNumber].amplNum = NPinp; break;}
+                }
+                sprintf(txtBoxR[LabelsIndex].text, "%i", NPinp);
+            }    
+            showVal(progNumber);
+            LPscreen = 0;   //value screen
+            flagParChanged = 0;    
+        }    
+        else if(TPmode == 2) {
+            if(flagNPinp == true) {
+                if(NPinp < miMa[LabelsIndex].min) {NPinp = miMa[LabelsIndex].min;}
+                switch (LabelsIndex) {
+                    case 10: {fileNum = NPinp; break;}
+                }
+                sprintf(txtRServ[4].text, "%i", NPinp);
+            }    
+            showService();
+            LPscreen = 2;   //service screen
+            
+        }    
+    }    
+}
+    
+void testTP(void) {
+    TouchCode_t touch;
+    
+    touch = lcd.TouchPanelReadable();         // any touch to report?
+    if (touch) {
+        uint8_t id = lcd.TouchID();           // 'id' tracks the individual touches
+        TouchCode_t ev = lcd.TouchCode();     // 'ev'ent 0-no_touch,1-touch,2-held,3-release,4-no_cal
+        point_t xy = lcd.TouchCoordinates();  // and of course the (x,y) coordinates
+
+        pc.printf("%2d,%d:(%4d,%4d)\n", id, ev, xy.x, xy.y);
+        int lastRadius, newRadius;
+        lastRadius = ComputeRadius(lastTP);           // To erase the last fingerprint
+        newRadius = ComputeRadius(xy);                  // Shrink near edge of screen
+        lcd.circle(xy, newRadius, Red); // draw new fingerprint
+        lcd.circle(lastTP, lastRadius, Black);    // erase old fingerprint
+        lastTP = xy;
+
+        led2 = 1;
+        wait_ms(100);
+        led2 = 0;
+    }
+}
+
+void checkTP(void) {
+    TouchCode_t touch;
+    
+    touch = lcd.TouchPanelReadable();         // any touch to report?
+    //pc.printf("TP\n");
+    if (touch) {
+        uint8_t id = lcd.TouchID();           // 'id' tracks the individual touches
+        TouchCode_t ev = lcd.TouchCode();     // 'ev'ent 0-no_touch,1-touch,2-held,3-release,4-no_cal
+        point_t xy = lcd.TouchCoordinates();  // and of course the (x,y) coordinates
+
+        //printf("(%4d,%4d)\n", xy.x, xy.y);
+        pc.printf("%d,%d:(%4d,%4d)\n", TPmode, LPscreen, xy.x, xy.y);
+
+        if(LPscreen == 0) {     //value screen 
+            //8 program#
+            for(int i = 0; i < TextBoxSize; i++) {
+                if((xy.x > txtBox[i].x1)&(xy.x < txtBox[i].x2)&(xy.y > txtBox[i].y1)&(xy.y < txtBox[i].y2)) {
+                    pc.printf("%i\n", i);
+                    if(i<8) {showProgParam(i); flagParChanged = 0; goto checkTPend;}
+                    else {if(editBtnMode == 1) {showWobParam(i-8); flagParChanged = 0; goto checkTPend;}}  //edit mode, 3 wob.mode      
+                }    
+            }
+            // text boxes
+            if(editBtnMode == 1) {
+                for(int i = 0; i < numPrPar; i++) {
+                    if((xy.x > txtBoxR[i].x1)&(xy.x < txtBoxR[i].x2)&(xy.y > txtBoxR[i].y1)&(xy.y < txtBoxR[i].y2)) {
+                        pc.printf("%i\n", i);
+                        if(i == numLmode) {
+                            lcd.fillroundrect(txtBoxR[i].x1, txtBoxR[i].y1, txtBoxR[i].x2, txtBoxR[i].y2, txtBoxR[i].r1, txtBoxR[i].r2, txtBoxR[i].color);
+                            lcd.foreground(txtBoxR[i].textColor);
+                            lcd.background(txtBoxR[i].color);
+                            if(Lmode == 0) {
+                                Lmode = 1;
+                                prPar[progNumber].Lmode = 1;
+                                lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "PULSE");
+                                if(SetLasComm(32) == 1) {TPstatus = 5;}       //EPM -enable pulse mode
+                                else {
+                                    if(SetLasComm( 1) == 1) {TPstatus = 5;}   //STA -read laser status
+                                    else TPstatus = 0; 
+                                }
+                            }
+                            else {
+                                Lmode = 0;
+                                prPar[progNumber].Lmode = 0;
+                                lcd.puts(txtBoxR[i].textX, txtBoxR[i].textY, "CW");
+                                if(SetLasComm(33) == 1) {TPstatus = 5;}       //DPM -disable pulse mode
+                                else {
+                                    if(SetLasComm( 1) == 1) {TPstatus = 5;}   //STA -read laser status
+                                    else TPstatus = 0; 
+                                }
+                            }
+                            flagParChanged = 0;
+                        }
+                        else {    
+                            showNP(i);
+                            LabelsIndex = i;
+                            NPinp = 0;
+                            flagNPinp = false;
+                            LPscreen = 1;   //LP screen
+                        }
+                        goto checkTPend;
+                    }    
+                }
+            }
+            //btn Edit
+            if((xy.x > txtBoxR[numTPeditBtn].x1)&(xy.x < txtBoxR[numTPeditBtn].x2)&(xy.y > txtBoxR[numTPeditBtn].y1)&(xy.y < txtBoxR[numTPeditBtn].y2)) {
+                if(TPmode == 1) {
+                    showTPeditBtn(0);  //set operate mode
+                    TPmode = 0; 
+                    editBtnMode = 0;               
+                }
+                else {
+                    showTPeditBtn(1);  //set edit mode
+                    TPmode = 1;                
+                    editBtnMode = 1;               
+               }
+                goto checkTPend;            
+            }    
+            //btn Main
+            if((xy.x > txtBoxR[numTPmainBtn].x1)&(xy.x < txtBoxR[numTPmainBtn].x2)&(xy.y > txtBoxR[numTPmainBtn].y1)&(xy.y < txtBoxR[numTPmainBtn].y2)) {
+                pc.printf("MainBtn");
+                
+                showMain(progNumber);
+                TPmode = 0;
+                LPscreen = 3;                
+            }    
+            //status line
+            if((xy.x > txtBoxR[numTPstatus].x1)&(xy.x < txtBoxR[numTPstatus].x2)&(xy.y > txtBoxR[numTPstatus].y1)&(xy.y < txtBoxR[numTPstatus].y2)) {
+                showTPstatus(10);   //clean status line
+            }    
+            goto checkTPend;            
+        }
+        else if(LPscreen == 1) {   //numpad screen
+            if(xy.x < txtBoxNP[1].x1) { //touch left from form
+                showVal(progNumber);
+                LPscreen = 0;   //values screen
+                pc.printf("<<");
+                goto checkTPend;
+            }    
+            //btn 0..9, ok, back
+            for(int i = 0; i < 13; i++) {
+                if((xy.x > txtBoxNP[i].x1)&(xy.x < txtBoxNP[i].x2)&(xy.y > txtBoxNP[i].y1)&(xy.y < txtBoxNP[i].y2)) {
+                    pc.printf("%i\n", i);
+                    txtBoxNPadd(i);
+                    goto checkTPend;
+                }    
+            }
+        
+        }
+        else if(LPscreen == 2) {     //service screen 
+            for(int i = 0; i < txtRServSize; i++) {
+                if((xy.x > txtRServ[i].x1)&(xy.x < txtRServ[i].x2)&(xy.y > txtRServ[i].y1)&(xy.y < txtRServ[i].y2)) {
+                    btnServ(i);
+                    break;
+                }    
+            }
+            if(flagDirOpen != 0) {
+                for(int i = 0; i < txtRdirSize; i++) {
+                    if((xy.x > txtRdir[i].x1)&&(xy.x < txtRdir[i].x2)&&(xy.y > txtRdir[i].y1)&&(xy.y < txtRdir[i].y2)) {
+                        btnDir(i);
+                        break;
+                    }    
+                }
+                for(int i = 0; i < TextBoxDirSize; i++) {
+                    if((xy.x > txtBoxDir[i].x1)&&(xy.x < txtBoxDir[i].x2)&&(xy.y > txtBoxDir[i].y1)&&(xy.y < txtBoxDir[i].y2)) {
+                        btnDirText(i);
+                        break;
+                    }    
+                }
+            }
+        }
+        else if(LPscreen == 3) {     //main screen
+            //8 program#
+            for(int i = 0; i < TextBoxSize; i++) {
+                if((xy.x > txtBox[i].x1)&(xy.x < txtBox[i].x2)&(xy.y > txtBox[i].y1)&(xy.y < txtBox[i].y2)) {
+                    pc.printf("%i\n", i);
+                    if(i<8) {showProgNum(i); flagParChanged = 0; goto checkTPend;}
+                }    
+            }
+            //btn Values
+            if((xy.x > txtBoxR[numTPvalBtn].x1)&(xy.x < txtBoxR[numTPvalBtn].x2)&(xy.y > txtBoxR[numTPvalBtn].y1)&(xy.y < txtBoxR[numTPvalBtn].y2)) {
+                pc.printf("ValuesBtn");
+                
+                showVal(progNumber);
+                TPmode = 0;
+                LPscreen = 0;                
+            }    
+            //btn Service
+            if((xy.x > txtBoxR[numTPservBtn].x1)&(xy.x < txtBoxR[numTPservBtn].x2)&(xy.y > txtBoxR[numTPservBtn].y1)&(xy.y < txtBoxR[numTPservBtn].y2)) {
+                pc.printf("ServiceBtn");
+                
+                showService();
+                TPmode = 2;
+                LPscreen = 2;                
+            }    
+            //status line
+            if((xy.x > txtBoxR[numTPstatus].x1)&(xy.x < txtBoxR[numTPstatus].x2)&(xy.y > txtBoxR[numTPstatus].y1)&(xy.y < txtBoxR[numTPstatus].y2)) {
+                showTPstatus(10);   //clean status line
+            }    
+        }
+ checkTPend:       
+        led2 = 1;
+        wait_ms(100);
+        led2 = 0;
+        
+        while(touch) {
+            touch = lcd.TouchPanelReadable();         // any touch to report?
+            wait_ms(1);
+        }
+    }
+}
+//ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+    
+void LasCommInit(void) {
+    if(LPscreen == 2) statServErr(10);    //service screen, status " "
+    else showTPstatus(10);                // main screen, status " "
+    
+    if(SetLasComm(52) == 1) {c7=52; goto met1;}    //RERR -Resets any resettable errors 
+    if(SetLasComm(54) == 1) {c7=54; goto met1;}    //EMOFF -Stop Emission
+    if(SetLasComm(41) == 1) {c7=41; goto met1;}    //DMOD -disable external modulation input
+    if(SetLasComm(47) == 1) {c7=47; goto met1;}    //DEABC -disable external aiming beam control input
+    if(SetLasComm(34) == 1) {c7=34; goto met1;}    //ABN -aiming beam on
+    //if(SetLasComm(35) == 1) {c7=35; goto met1;}    //ABF -aiming beam off
+    //if(SetLasComm(46) == 1) {c7=46; goto met1;}    //EEABC -enable external aiming beam control input
+    if(SetLasComm(39) == 1) {c7=39; goto met1;}    //DGM -disable gate mode
+    if(SetLasComm(36) == 1) {c7=36; goto met1;}    //EEC -enable external analog power control input
+    if(SetLasComm(40) == 1) {c7=40; goto met1;}    //EMOD -enable external modulation input
+    if(SetLasComm(42) == 1) {c7=42; goto met1;}    //ELE -enable external emission input
+    if(SetLasComm( 1) == 1) {c7=1; goto met1;}    //STA -read laser status 
+    c7 = 99;   
+    if(LPscreen == 2) statServErr(0);    //service screen, status READY
+    else showTPstatus(0);                // main screen, status READY
+    return;
+    
+met1:
+    if(LPscreen == 2) statServErr(5);    //service screen
+    else showTPstatus(5);                // main screen
+}  
+
+void initIOparam(void) {
+    for(int i=0; i<4; i++) {
+        ioPar.o3[i] = '\0';
+        ioPar.o2[i] = '\0';
+        ioPar.o1[i] = '\0';
+        ioPar.i3[i] = '\0';
+        ioPar.i2[i] = '\0';
+        ioPar.i1[i] = '\0';
+        ioPar.aiLPow[i] = '\0';
+        ioPar.aiLCur[i] = '\0';
+        ioPar.aiLTemp[i] = '\0';
+        ioPar.aiLBR[i] = '\0';
+    }
+}
+
+uint8_t bitOstate = 0x80; //d7=1 need set/reset, d6=1-set,0-reset, d5-d0 bit number
+uint8_t ioReq = 0;        //0-no request, 1-inp.request, 2-out.request
+     
+//============================================================================== 
+int main()
+{
+    a7=0;
+    b7=0;
+    c7=0;
+    
+    //Configure CRC, large frames, and write validation
+    sd.crc(true);
+    sd.large_frames(true);
+    sd.write_validation(true);
+    
+    pc.baud(PC_BAUD);    //
+    
+    pc.printf("\nRA8875 Touch Screen. Date: " __DATE__ " " __TIME__ "\r\n");
+    //wait_ms(5000);
+    //pc.printf("\n>>\n");
+    //wait_ms(5000);
+    
+    initHMIio();
+    initIOparam();
+    
+    lcd800x480Init();
+    //showMain(progNumber+1);
+    tickRS.attach_us(&flipUS, tickTime); // the address of the function to be attached (flip) to ticker
+
+    wait_ms(5000);
+    LasCommInit();
+    
+    fillTestBuffer();
+    if(connectSD() == 0) {
+        infoSD();
+        //writeTestFile();
+        readTestFile();
+        
+        readDirSD(rDr);
+        
+        //RetCode_t r = lcd.RenderImageFile(0, 0, "/sd/local/48027208.bmp");
+        //printf("returned %d\r\n", r);
+        //wait(3);
+        //r = lcd.RenderJpegFile(0, 0, "/sd/local/p480272.jpg");
+        //printf("returned %d\r\n", r);
+      
+        disconnectSD();
+    }
+    pc.printf("a7=%i b7=%i c7=%i d7=%i\n", a7, b7, c7, d7);
+    
+    InitTS();
+    readIniFile();       
+    showMain(progNumber);
+    //int x, y, z;
+    
+    while(true)
+    {
+        //testTP();
+        if(flagWeld == 0) checkTP();
+        
+        main_cycle_add();
+        
+        iLed++;
+        if(iLed > 500) {
+            led1 = !led1;
+            iLed = 0;
+        }    
+        wait_ms(1);
+    }
+}
+