//USB Keyboard to UART
//using PIO USB Host on GP8/GP9=D+/D-
//LED on GP14
#define STATUS_LED 14
#define PICO_ONBOARD_LED (25)

//UART output on TX, RX actually not used
#define UART_KBD Serial2
#define UART_TX_KBD (4)
#define UART_RX_KBD (5)

// pio-usb is required for rp2040 host
#include "pio_usb.h"
#define HOST_PIN_DP   15   // Pin used as D+ for host, D- = D+ + 1
#include "Adafruit_TinyUSB.h"
#define LANGUAGE_ID 0x0409  // English
// USB Host object
Adafruit_USBH_Host TinyUSBHost;
// holding device descriptor
tusb_desc_device_t desc_device;
#include "keys.h"

//misc housekeeping and settings structs/enums
bool kbdMounted=0;
unsigned long tk=0;       //flicker counter
#define FLICKER_TIME (100)
unsigned long tmCount=0;  //typematic counter
#define CR_CODE (13)
#define LF_CODE (10)
bool serialOn=0;
char setupOn=0;       //also holds the setup mode

typedef enum{    
    ASCII_ONLY=1,
    ASCII_EXT=2,
    VT100=3,
    EMULATION_LAST
} emulation_t;

typedef enum {
    UART_LE_CRONLY=1,       //Note- this gives uartLE&1 => CR
    UART_LE_LFONLY,         //      and uartLE&2 => LF
    UART_LE_CRLF,
    UART_LE_LAST
} uartLE_t;

typedef struct {    //things that are to be saved in EEPROM/FLASH
  int tmDelay;
  int tmRepeat;
  emulation_t emulation;
  uartLE_t uartLE;  
  uint8_t debugOn;
  int baud; //signed to detect error due to blank flash
} nvSettings_t;

#define TM_DELAY_DEFAULT (300)
#define TM_REPEAT_DEFAULT (200)
#define EMULATION_DEFAULT (VT100)
#define UART_LE_DEFAULT (UART_LE_CRONLY)
#define DEBUG_DEFAULT (0)
#define BAUD_DEFAULT (115200)
#define BAUD_RATE_MAX (1000000)

nvSettings_t cur={    //live working copy
  .tmDelay=TM_DELAY_DEFAULT,
  .tmRepeat=TM_REPEAT_DEFAULT,
  .emulation = EMULATION_DEFAULT,
  .uartLE = UART_LE_DEFAULT,
  .debugOn = DEBUG_DEFAULT,
  .baud = BAUD_DEFAULT
};

//emulated EEPROM in flash for storing settings
#include <EEPROM.h>
//use flash block size
#define EEPROM_SIZE_FROM_FLASH 4096
//avoid location 0
#define EEPROM_DATA_START 1
bool eepromError=0;

void setup() {
  Serial.begin(115200);
  pinMode(STATUS_LED,OUTPUT);
  digitalWrite(STATUS_LED,LOW);
  pinMode(PICO_ONBOARD_LED,OUTPUT);
  digitalWrite(PICO_ONBOARD_LED,HIGH);  //show power on
  UART_KBD.setRX(UART_RX_KBD);
  UART_KBD.setTX(UART_TX_KBD);
  UART_KBD.begin(cur.baud);
  EEPROM.begin(EEPROM_SIZE_FROM_FLASH);
  EEPROM.get(EEPROM_DATA_START,cur);
  if((cur.tmDelay<=0)||(cur.tmRepeat<=0)||(cur.emulation<=0)||(cur.uartLE<=0)||(cur.baud<=0)){  //catch dodgy data
    eepromError=1;
    loadDefaults();     //will reload baud rate
  }
}

void loop() {  
  int d;
  int k;  
  const char* v=0;  //for passing ESC sequences etc
  keyEvent_t event;
  if(serialOn==0){  //wait til serial up before showing splash
    if(Serial){
      serialOn=1;
      Serial.println("USB Keyboard to UART for VGA PicoMite");
      Serial.println("Press ~ to show Setup Menu");
      if(eepromError){
        Serial.println("EEPROM Error, defaults loaded");
      }
    }
  }
  if(Serial.available()){
    d=Serial.read();
    checkMenu(d);
  }
  //set LED
  if(kbdMounted){
    if(millis()<tk){
      digitalWrite(STATUS_LED,LOW); //flicker off on keys pressed
    }else{
      digitalWrite(STATUS_LED,HIGH);    
    }
  }else{
    digitalWrite(STATUS_LED,LOW);
    lastEvent.event=KEYNONE;      //avoid runaway typematic if keyboard unmounted while a key is down
  }
  //check if typematic needs to send anything
  if(lastEvent.event==KEYDOWN){
    if((millis()-tmCount)>cur.tmDelay){
      tmCount=tmCount+cur.tmRepeat;
      queueEvent(lastEvent);
    }
  }
  //check if anything needs to be sent out on UART wire
  if(eventAvailable()){
    event=getEvent();    
    if(event.event==KEYDOWN){
      //all modes send basic ASCII
      if((event.key==USB_ENTER)||(event.key==USB_KPD_ENTER)){        //handle CR/LF combos
        Serial.println("ENTER PRESSED");
        if(cur.uartLE&UART_LE_CRONLY){UART_KBD.write(CR_CODE);} //CR
        if(cur.uartLE&UART_LE_LFONLY){UART_KBD.write(LF_CODE);} //CR
        UART_KBD.flush();
      }else{
        k=getAscii(event);
        if(k>-1){
          Serial.write(k);
          UART_KBD.write(k);
          UART_KBD.flush();
        }else{  
          //VT100 also sends ESC sequences
          if(cur.emulation==VT100){
            v=getVT100(event);
            if(v){
              if(v[0]){
                Serial.print("ESC: ");
                while(v[0]){
                  Serial.printf("0x%02x ",v[0]);
                  UART_KBD.write(v[0]);
                  v=v+1;
                }            
                Serial.println();
                UART_KBD.flush();
              }
            }
          //extended ASCII sends specific codes > 0x80
          }else if(cur.emulation==ASCII_EXT){
            k=getExtAscii(event);
            if(k>-1){
              //Serial.write(k);    //echo to terminal
              Serial.printf("EXT:0x%02X ",k);  //encode to hex for display on terminal
              UART_KBD.write(k);
              UART_KBD.flush();
            }
          }
        }
      }
    }
    if(cur.debugOn){Serial.printf("0x%x %s %c %c %c %c\r\n",event.key,(event.event==KEYDOWN)?"DOWN":((event.event==KEYUP)?"UP":"????"),(event.mod.lShift|event.mod.rShift)?'S':'_',(event.mod.lCtrl|event.mod.rCtrl)?'C':'_',(event.mod.lAlt|event.mod.rAlt)?'A':'_',(event.lock.capsLock)?'L':'_');}
    //check if LED state needs to be updated
    if(event.event==KEYDOWN){
      if(event.key==USB_CAPSLOCK){  //CAPS LOCK
        lockState.capsLock=lockState.capsLock^1;
        tuh_hid_set_report(keyAdd, keyInst, 0, HID_REPORT_TYPE_OUTPUT,&lockState, 1);
      }else if(event.key==USB_NUMLOCK){  //NUM LOCK
        lockState.numLock=lockState.numLock^1;
        tuh_hid_set_report(keyAdd, keyInst, 0, HID_REPORT_TYPE_OUTPUT,&lockState, 1);
      }else if(event.key==USB_SCROLLLOCK){  //SCROLL LOCK
        lockState.scrollLock=lockState.scrollLock^1;
        tuh_hid_set_report(keyAdd, keyInst, 0, HID_REPORT_TYPE_OUTPUT,&lockState, 1);
      }
    }
  }
}

// core1's setup
void setup1() {
  delay(10);
  //CPU must be 120MHz or 240MHz (Tools> CPU Speed)
  pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
  pio_cfg.pin_dp = HOST_PIN_DP;
  TinyUSBHost.configure_pio_usb(1, &pio_cfg);
  //calling USBHost.begin() on core1 to leave core 0 free
  TinyUSBHost.begin(1);
}

void loop1(){
  TinyUSBHost.task();
}

// Invoked when device with hid interface is mounted
// Report descriptor is also available for use.
// tuh_hid_parse_report_descriptor() can be used to parse common/simple enough
// descriptor. Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE,
// it will be skipped therefore report_desc = NULL, desc_len = 0
void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) {
  (void)desc_report;
  (void)desc_len;
  uint16_t vid, pid;
  tuh_vid_pid_get(dev_addr, &vid, &pid);
  if(cur.debugOn){Serial.printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance);}
  if(cur.debugOn){Serial.printf("VID = %04x, PID = %04x\r\n", vid, pid);}
  if (!tuh_hid_receive_report(dev_addr, instance)) {
    if(cur.debugOn){Serial.printf("Error: cannot request to receive report\r\n");}
  }
  if(tuh_hid_interface_protocol(dev_addr, instance)==HID_ITF_PROTOCOL_KEYBOARD){    //check if keyboard
    keyAdd=dev_addr;
    keyInst=instance;
    if(cur.debugOn){Serial.printf("Keyboard found at %d,%d\r\n",keyAdd,keyInst);}
    kbdMounted=1;
    //tuh_hid_set_report(keyAdd, keyInst, 0, HID_REPORT_TYPE_OUTPUT,&lockState, 1);   //doesn't like this on mount
  }
}

// Invoked when device with hid interface is un-mounted
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
  if(cur.debugOn){Serial.printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);}
  kbdMounted=0;
}

// Invoked when received report from device via interrupt endpoint
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
  uint8_t i,j,chg;
  keyEvent_t e;
  report_t* newReport=(report_t*)report;
  if(cur.debugOn){
    Serial.printf("HIDreport : ");
    for (uint16_t i = 0; i < len; i++) {
      Serial.printf("0x%02X ", report[i]);
    }
    Serial.println();
  }
  // continue to request to receive report
  if (!tuh_hid_receive_report(dev_addr, instance)) {
    if(cur.debugOn){Serial.printf("Error: cannot request to receive report\r\n");}
  }
  if(tuh_hid_interface_protocol(dev_addr, instance)==HID_ITF_PROTOCOL_KEYBOARD){    
    tk=millis()+FLICKER_TIME; //any report causes a flicker
    modState=newReport->mod;
    e.mod=modState;
    e.lock=lockState;
    //look for key down events
    for(i=0;i<6;i++){
      if(newReport->k[i]){  //only check non-zero
        chg=1;
        for(j=0;j<6;j++){
          if(newReport->k[i]==lastReport.k[j]){chg=0;}
        }
        if(chg){
          e.key=newReport->k[i];
          e.event=KEYDOWN;
          queueEvent(e);
          lastEvent=e;  //save for typematic
          tmCount=millis(); //and timestamp      
          //tk=millis()+FLICKER_TIME;     //trigger on all reports (see above)
        }
      }
    }
    //look for key up events
    for(i=0;i<6;i++){
      if(lastReport.k[i]){  //only check non-zero
        chg=1;
        for(j=0;j<6;j++){
          if(newReport->k[j]==lastReport.k[i]){chg=0;}
        }
        if(chg){
          e.key=lastReport.k[i];
          e.event=KEYUP;
          queueEvent(e);
          lastEvent=e;  //save for typematic
          tmCount=millis(); //and timestamp
        }
      }
    }
    lastReport=*newReport;
  }
}

int getAscii(keyEvent_t k){ //core ASCII returns, -1 if no match (eg could resolve to EXT/VT100)  
  char ctrl=0, shift=0, caps=0, num=0;
  if((k.mod.lCtrl)||(k.mod.rCtrl)){ctrl=1;}
  if((k.mod.lShift)||(k.mod.rShift)){shift=1;}
  if(k.lock.numLock){num=1;}
  if(k.lock.capsLock){caps=1;}
  //Enter handled in loop()
  //if(k.key==40){return 10;}
  //check for CTRL-x which return ASCII 0-31
  if(k.mod.lCtrl||k.mod.rCtrl){
    if((k.key>3)&&(k.key<30)){return k.key-3;}  //Ctrl-A .. Ctrl-Z
    switch(k.key){
      case 31: return 0; break; //Ctrl-2/@
      case 32: return 27;break; //Ctrl-3
      case 33: return 28;break; //Ctrl-4
      case 34: return 29;break; //Ctrl-5
      case 35: return 30;break; //Ctrl-6
      case 36: return 31;break; //Ctrl-7
      case 47: return 27;break; //Ctrl-[
      case 49: return 28;break; //Ctrl-/
      case 48: return 29;break; //Ctrl-]
      case 53: return 30;break; //Ctrl-~
      case 56: return 31;break; //Ctrl-?
    }
  }
  if((k.key>3)&&(k.key<30)){
    if(shift^caps){   //either shift or caps
      return 61+k.key;    //A..Z
    }else{            //both shift and caps or neither
      return 93+k.key;    //a..z
    }
  }
  //other keys that may be shifted
  if((k.key>29)&&(k.key<83)){
    if(shift){
      switch(k.key){
        case 30: return '!';break;
        case 31: return '@';break;
        case 32: return '#';break;
        case 33: return '$';break;
        case 34: return '%';break;
        case 35: return '^';break;
        case 36: return '&';break;
        case 37: return '*';break;
        case 38: return '(';break;
        case 39: return ')';break;
        case 44: return ' ';break; //shift-space = space
        case 45: return '_';break;
        case 46: return '+';break;
        case 47: return '{';break;
        case 48: return '}';break;
        case 49: return '|';break;
        case 50: return '|';break; //2nd \| key on some
        case 51: return ':';break;
        case 52: return '"';break;
        case 53: return '~';break;
        case 54: return '<';break;
        case 55: return '>';break;
        case 56: return '?';break;
      }
    }else{
      switch(k.key){
        case 30: return '1';break;
        case 31: return '2';break;
        case 32: return '3';break;
        case 33: return '4';break;
        case 34: return '5';break;
        case 35: return '6';break;
        case 36: return '7';break;
        case 37: return '8';break;
        case 38: return '9';break;
        case 39: return '0';break;
        case 44: return ' ';break;
        case 45: return '-';break;
        case 46: return '=';break;
        case 47: return '[';break;
        case 48: return ']';break;
        case 49: return '\\';break;
        case 50: return '\\';break; //2nd \| key on some
        case 51: return ';';break;
        case 52: return '\'';break;
        case 53: return '`';break;
        case 54: return ',';break;
        case 55: return '.';break;
        case 56: return '/';break;
      }       
    }        
  }
  //number pad
  if((k.key>83)&&(k.key<100)){
    if(num){
      switch(k.key){
        case 84: return '/';break;
        case 85: return '*';break;
        case 86: return '-';break;
        case 87: return '+';break;
        case 89: return '1';break;
        case 90: return '2';break;
        case 91: return '3';break;
        case 92: return '4';break;
        case 93: return '5';break;
        case 94: return '6';break;
        case 95: return '7';break;
        case 96: return '8';break;
        case 97: return '9';break;
        case 98: return '0';break;
        case 99: return '.';break;
      }
    }else{
      switch(k.key){      //most map to arrow keys etc- only handled in extended modes
        case 84: return '/';break;
        case 85: return '*';break;
        case 86: return '-';break;
        case 87: return '+';break;
      }
    }
  }
  //other special cases
  if(k.key==41){return 27;}     //escape
  if(k.key==42){return 8;}      //backspace
  if(k.key==43){return 9;}      //tab
  return -1;  //no result
}

int getExtAscii(keyEvent_t k){ //extended ASCII returns, -1 if no match
//see https://www.arduino.cc/reference/en/language/functions/usb/keyboard/keyboardmodifiers/ for mapping used
  char num=0;
  if(k.lock.numLock){num=1;}
  //F1-F12
  if((k.key>=58)&&(k.key<=69)){return k.key+194-58;}        //F1 > keycode 58 returns 194
  //arrow keys, home, end pgup, pgdown, insert, delete
  if((k.key>=73)&&(k.key<=82)){return k.key+209-73;}        //INSERT > keycode 73 returns 209
  if(!num){                   //number pad cursor keys
      switch(k.key){
          case 89: return 213;break;        //end
          case 90: return 217;break;        //down arrow
          case 91: return 214;break;        //page down
          case 92: return 216;break;        //left arrow
          case 94: return 215;break;        //right arrow
          case 95: return 210;break;        //home
          case 96: return 218;break;        //up arrow
          case 97: return 211;break;        //page up
          case 98: return 209;break;        //insert
          case 99: return 212;break;        //delete            
      }
  }
  if(k.key==70){return 206;}             //print screen
  if(k.key==72){return 208;}             //pause
  return -1;
}

const char* getVT100(keyEvent_t k){ //VT100 ESC sequences, empty if none
  char num=0;
  if(k.lock.numLock){num=1;}
  switch(k.key){
    case 58: return("\x1B[11~");break;      //F1
    case 59: return("\x1B[12~");break;      //F2
    case 60: return("\x1B[13~");break;      //F3
    case 61: return("\x1B[14~");break;      //F4
    case 62: return("\x1B[15~");break;      //F5
    case 63: return("\x1B[17~");break;      //F6   -16 skipped!
    case 64: return("\x1B[18~");break;      //F7
    case 65: return("\x1B[19~");break;      //F8
    case 66: return("\x1B[20~");break;      //F9
    case 67: return("\x1B[21~");break;      //F10
    case 68: return("\x1B[23~");break;      //F11   -22 skipped!
    case 69: return("\x1B[24~");break;      //F12
    case 73: return("\x1B[2~");break;       //INSERT                                  
    case 74: return("\x1B[1~");break;       //HOME                                    
    case 75: return("\x1B[5~");break;       //PAGE_UP                                 
    case 76: return("\x1B[3~");break;       //DELETE
    case 77: return("\x1B[4~");break;       //END                                     
    case 78: return("\x1B[6~");break;       //PAGE_DOWN                               
    case 79: return("\x1B[C");break;        //RIGHT_ARROW                             
    case 80: return("\x1B[D");break;        //LEFT_ARROW                              
    case 81: return("\x1B[B");break;        //DOWN_ARROW                              
    case 82: return("\x1B[A");break;        //UP_ARROW                                        
  }
  if(!num){                   //number pad cursor keys
    switch(k.key){
      case 89: return("\x1B[4~");break;     //1_AND_END                                 
      case 90: return("\x1B[B");break;      //2_AND_DOWN_ARROW                          
      case 91: return("\x1B[6~");break;     //3_AND_PAGE_DOWN                           
      case 92: return("\x1B[D");break;      //4_AND_LEFT_ARROW   (no alternate on numpad 5)                       
      case 94: return("\x1B[C");break;      //6_AND_RIGHT_ARROW                         
      case 95: return("\x1B[1~");break;     //7_AND_HOME                                
      case 96: return("\x1B[A");break;      //8_AND_UP_ARROW                            
      case 97: return("\x1B[5~");break;     //9_AND_PAGE_UP                             
      case 98: return("\x1B[2~");break;     //0_AND_INSERT                              
      case 99: return("\x1B[3~");break;     //PERIOD_AND_DELETE                         
    }
  }
  return "";
}

void showMenu(void){
  Serial.println("___________________________________");
  Serial.println("Setup Menu:");
  Serial.printf("A: Typematic delay (%d ms)\r\n",cur.tmDelay);
  Serial.printf("B: Typematic repeat (%d ms)\r\n",cur.tmRepeat);
  Serial.printf("C: Terminal emulation mode (%s)\r\n",getModeString(cur.emulation));
  Serial.printf("D: Line ending (%s)\r\n",getLEstring(cur.uartLE));
  Serial.printf("E: Toggle debugging (currently %s)\r\n",getDebugString(cur.debugOn));
  Serial.printf("F: Set baudrate (currently %d)\r\n",cur.baud);
  Serial.println("Y: Save to flash");
  Serial.println("Z: Restore defaults");
}

const char* getLEstring(uartLE_t e){
  switch(e){
    case UART_LE_CRONLY: return "CR only";break;
    case UART_LE_LFONLY: return "LF only";break;
    case UART_LE_CRLF: return "CR/LF";break;
  }
  return "ERROR";
}

const char* getModeString(emulation_t e){
  switch(e){
    case ASCII_ONLY: return "ASCII only"; break;
    case ASCII_EXT: return "Extended ASCII"; break;
    case VT100: return "VT100"; break;    
  }
  return "ERROR";
}

const char* getDebugString(uint8_t n){
  if(n){
    return "ON";
  }else{
    return "OFF";
  }
}

void checkMenu(char c){
  static int n=0;   //for multi digit numbers
  int i;
  switch(c){
    case 'a':
    case 'A':
      setupOn=1;
      Serial.println("Enter typematic delay in ms:");
      n=0;
      break;
    case 'b':
    case 'B':
      setupOn=2;
      Serial.println("Enter typematic repeat time in ms:");
      n=0;
      break;
    case 'c':
    case 'C':
      setupOn=3;
      Serial.println("Choose a Terminal Emulation Mode:");
      for(i=1;i<EMULATION_LAST;i++){
        Serial.printf("%d: %s\r\n",i,getModeString((emulation_t)i));
      }
      n=0;
      break;
    case 'd':
    case 'D':
      setupOn=4;
      Serial.println("Choose a line ending (Enter key):");
      for(i=1;i<UART_LE_LAST;i++){
        Serial.printf("%d: %s\r\n",i,getLEstring((uartLE_t)i));
      }
      n=0;
      break;
    case 'e':
    case 'E':
      if(cur.debugOn){
        cur.debugOn=0;
      }else{
        cur.debugOn=1;
      }
      Serial.printf("Debugging is %s.\r\n",getDebugString(cur.debugOn));
      showMenu();
      break;
    case 'f':
    case 'F':
      setupOn=6;
      Serial.println("Enter baud rate:");
      n=0;
      break;
/*
    //uncomment the following to help with debugging during development
    case 'x':
    case 'X':
      rp2040.reboot();
      break;
*/
    case 'y':
    case 'Y':
      saveToFlash();
      showMenu();
      break;
    case 'z':
    case 'Z':
      loadDefaults();
      showMenu();
      break;
    case '~':
     showMenu();
     break;
    default: break;   //ignore others
  }
  //handle numbers all the same
  if((c>='0')&&(c<='9')){
    n=n*10+c-'0';
    Serial.write(c);
  }
  //These take a single digit and don't need Enter
  if((setupOn==3)&&(n>0)){
    if(n<EMULATION_LAST){
      cur.emulation=(emulation_t)n;
      n=0;
      Serial.printf("\r\nTerminal emulation set to %s.\r\n",getModeString(cur.emulation));
      showMenu();
    }else{
      n=0;
      setupOn=0;
      Serial.println("\r\nError");
      showMenu();
    }
  }
  if((setupOn==4)&&(n>0)){
    if(n<UART_LE_LAST){
      cur.uartLE=(uartLE_t)n;
      n=0;
      Serial.printf("\r\nLine ending set to %s.\r\n",getLEstring(cur.uartLE));
      showMenu();
    }else{
      n=0;
      setupOn=0;
      Serial.println("\r\nError");
      showMenu();
    }
  }
  //Enter depends on setupOn selection
  if((c==CR_CODE)&&(n>0)){
    switch(setupOn){
      case 1:
        cur.tmDelay=n;
        n=0;
        setupOn=0;
        Serial.printf("\r\nTypematic delay set to %d ms.\r\n",cur.tmDelay);
        showMenu();
        break;
      case 2:
        cur.tmRepeat=n;
        n=0;
        setupOn=0;
        Serial.printf("\r\nTypematic repeat time set to %d ms.\r\n",cur.tmRepeat);
        showMenu();
        break;
      case 6:
        if(n<=BAUD_RATE_MAX){
          cur.baud=n;
          n=0;
          setupOn=0;
          Serial.printf("\r\nBaud rate set to %d.\r\n",cur.baud);
          reloadBaud();
          showMenu();
        }else{
          n=0;
          setupOn=0;
          Serial.println("\r\nError");
          showMenu();
        }
        break;
      default:        //bail out if not valid
        Serial.println();
        showMenu();
        n=0;
        setupOn=0;
        break;
    }
  }
}

void saveToFlash(void){
  EEPROM.put(EEPROM_DATA_START,cur);
  if(EEPROM.commit()){
    Serial.println("Saved to flash");
  }else{
    Serial.println("ERROR! Save to flash failed");
  }
  setupOn=0;
}

void loadDefaults(void){
  Serial.println("Defaults loaded");
  setupOn=0;
  cur.tmDelay=TM_DELAY_DEFAULT;
  cur.tmRepeat=TM_REPEAT_DEFAULT;
  cur.emulation = EMULATION_DEFAULT;
  cur.uartLE = UART_LE_DEFAULT;
  cur.debugOn = DEBUG_DEFAULT;
  cur.baud = BAUD_DEFAULT;
  reloadBaud();
}

void reloadBaud(void){
  UART_KBD.end();
  UART_KBD.begin(cur.baud);
}