Commits

Gordon McGregor  committed 868ad40

working 'seceret' press mode to enable pedal reconfig - hit CH1 3 times

  • Participants
  • Parent commits 0ea7faf

Comments (0)

Files changed (5)

File bank_config.pde

 
 void handle_system_reset_midi() {
   setup_default_bank();
+  show_status(STATUS_RESET);  
+  send_byte('0xff');
 }
 
-typedef enum {
-  CMD_RECONFIG, CMD_RESET, CMD_STORE, CMD_RETRIVE} 
-midi_sysex_cmds_e;
-
-
 void reconfig_command(byte * data, byte size) {
   if (size != 13 ) {
     indicate_error();
+    return;
   }
 
-  int bank, channel;
+  int bank, channel, index;
 
-  bank = data[3];
-  channel = data[4];
+  index = 3;
+
+  bank = data[index++];
+  channel = data[index++];
 
   // 0xF0 0x78 0xCMD 0xBANK 0xSWITCH 0xTOGGLE 0xS00 0xS01 0xS02 0xS10 0xS11 0xS12 0xF7
-  banks.bank[ bank ].switches[ channel ].toggle_not_immediate = data[5];
-  banks.bank[ bank ].switches[ channel ].messages[0][0] = data[6];   
-  banks.bank[ bank ].switches[ channel ].messages[0][1] = data[7];
-  banks.bank[ bank ].switches[ channel ].messages[0][2] = data[8];
-  banks.bank[ bank ].switches[ channel ].messages[1][0] = data[9];   
-  banks.bank[ bank ].switches[ channel ].messages[1][1] = data[10];
-  banks.bank[ bank ].switches[ channel ].messages[1][2] = data[11];
+  banks.bank[ bank ].switches[ channel ].toggle_not_immediate = data[index++];
+
+  for (int s=0; s < MAX_STATES; s++) {
+    for (int m=0; m< MIDI_MESSAGE_LENGTH; m++) {
+      banks.bank[ bank ].switches[ channel ].messages[s][m] = data[index++];        
+    }
+  }
 }
 
 void store_bank(byte * data, int size){
+  int storage_bank;
+
   if (size != 5 ) {
     indicate_error();
+    return;
+  }
+  show_status(STATUS_STORE);
+  delay(500);
+  storage_bank = data[3];
+  show_status(storage_bank);
+
+  if(storage_bank <0 || storage_bank > MAX_STORAGE) {
+    indicate_error();
+    return; 
   }
   // 2 store config 0xCMD 0xCONFIG_BANK
+
+  EEPROM_writeAnything(storage_bank * sizeof(banks), banks);
 }
 
 void retrive_bank(byte * data, int size) {
+
+  int storage_bank;
+
   if (size != 5) {
     indicate_error();
+    return;
   }
-  // 3 restore config 0xCMD 0xCONFIG_BANK
+  show_status(STATUS_RETRIVE);
+  delay(500);
+  storage_bank = data[3];
+  show_status(storage_bank);
+
+  if(storage_bank <0 || storage_bank > MAX_STORAGE) {
+    indicate_error();
+    return; 
+  }
+  // 2 store config 0xCMD 0xCONFIG_BANK
+  read_bank(storage_bank);
+  
 }
 
+void read_bank(int storage_bank) {
+  EEPROM_readAnything(storage_bank * sizeof(banks), banks);
+}
+
+
 void handle_system_exclusive_midi(byte * data, byte size) {
   if (data[1] != MIDI_DEVICE_ID) {
     indicate_error();
     reconfig_command(data, size);
     break;
   case CMD_RESET: 
-    setup_default_bank();
+    handle_system_reset_midi();
     break;
   case CMD_STORE: 
     store_bank(data, size);
   case CMD_RETRIVE: 
     retrive_bank(data, size);
     break;
+  case CMD_TESTER:
+    reconfig_mode();
+    break;
   default: 
     indicate_error();
     break;
 }
 
 
+void reconfig_mode() {
+  
+ int index, previous_index, sample;
+ cycle_leds(); 
 
+ previous_index = -1;
+ 
+ while(previous_index != BANK0_OPEN && previous_index != BANK1_OPEN ) { // wait for release 
+   sample = analogRead(0);
+   previous_index = find_closest_level_index(sample);
+   delay(DEBOUNCE_DELAY);
+ }
+ 
+ index = previous_index;
+ 
+ while(index == previous_index) {
+   sample =  analogRead(0);
+   index = find_closest_level_index(sample);
+   delay(DEBOUNCE_DELAY);
+ }
+ 
+ index = index % 5;
+ 
+ read_bank(index);
+ 
+ strobe_led(10, index+LOW_LED);
+ reverse_cycle_leds();
+}
 
+
+
+

File bank_types.h

 const int LED_OFFSET = 2;
 const int MAX_BANKS = 2;
 const int MAX_SWITCHES = 4;
+const int MAX_STORAGE = 4;
+const int INDEX_PER_BANK = 5;
 const int MAX_STATES = 2;
+
+const int DEBOUNCE_DELAY = 50;  // 100ms delay on each switch read to let values settle
+
 const int MIDI_MESSAGE_LENGTH = 3;
 const int MIDI_DEVICE_ID = 0x78;
 
 
 const int MIDI_SYSEX_LENGTH = 5;
 
+const int STATUS_LED = 5;
 const int ERROR_LED = 6;
+const int LOW_LED = 2;
+const int HIGH_LED = 6;
+
+const int CYCLE_LOOP = 3;
 
 enum {OFF=0, INFO, DEBUG, TRACE} debug_levels_e;
 typedef enum {STATE0=0, STATE1=1} switch_state_e;
 
+enum {BANK0_OPEN=0, BANK0_0=1, BANK0_1, BANK0_2, BANK0_3, BANK1_OPEN=5, BANK1_0, BANK1_1, BANK1_2, BANK1_3} switch_names_e;
+enum {BANK0=0, BANK1=1} bank_names_e;
+
+typedef enum { CMD_RECONFIG=0, CMD_RESET=1, CMD_STORE=2, CMD_RETRIVE=3, CMD_TESTER=4}  midi_sysex_cmds_e;
+enum {STATUS_RECONFIG=2, STATUS_RESET=5, STATUS_STORE=4, STATUS_RETRIVE=3} status_code_e;
+
 const int DEBUG_LEVEL = OFF;
 typedef struct {
   int toggle_not_immediate;
 } 
 banks_t;
 
+const int RECONFIG_TIMES = 5;
+const int RECONFIG_CHANNEL = 0;
+const long RECONFIG_INTERVAL = 2000;
 
+

File faux_vox.pde

 /* 
-
-TODOs: SysEx reconfig now working
-Need MIDI commands to support variable length send
-Need nicer programming tool for host end (yaml -> SysEx programmer
-Need to implement EEPROM storage
-Need to implement switch based bank selection
-*/
+ 
+ TODOs: SysEx reconfig now working
+ Need MIDI commands to support variable length send
+ Need nicer programming tool for host end (yaml -> SysEx programmer
+ Need to implement EEPROM storage
+ Need to implement switch based bank selection
+ */
 
 #include <MIDI.h>
 #include <EEPROM.h>
 #include "bank_types.h"
 
 int previous_index, current_bank;
+long reconfig_start_time = 0;
+int reconfig_presses = 0;  // hit the RECONFIG switch RECONFIG_TIMES in RECONFIG_INTERVAL and switch to reconfig_mode()
+
+
 
 banks_t banks;
 
 void setup() {
   if (DEBUG_LEVEL != OFF) {
     Serial.begin(FASTEST_BAUD_RATE);
-  } else {
+  } 
+  else {
     Serial.begin(MIDI_BAUD_RATE); 
     MIDI.begin(MIDI_CHANNEL_OMNI);
     MIDI.setHandleSystemExclusive(handle_system_exclusive_midi);
     MIDI.setHandleSystemReset(handle_system_reset_midi);
   }
-  
-  
+
+  reconfig_presses = 0;
+  reconfig_start_time = 0;
+
   current_bank = 0;
   previous_index = 0;
   memset(&banks, 0, sizeof(banks_t));
   setup_default_bank();
-  
+
   for (int i = LED_OFFSET; i < LED_OFFSET + MAX_SWITCHES + 1; i++) {
     pinMode(i, OUTPUT); 
   }
   debug("Debug MIDI alive",0, INFO);
-  
+
 }
 
 
 void loop() {
   int channel, index, sample;
-  
+
   sample = analogRead(0);
   index = find_closest_level_index(sample);
 
   if (previous_index != index) { // a switch was pressed or released
     debug("New index", index, DEBUG);
-  if ((index == 0 && previous_index == 5) || (index == 5 && previous_index == 0)) {
+    if ((index == BANK0_OPEN && previous_index == BANK1_OPEN) || (index == BANK1_OPEN && previous_index == BANK0_OPEN)) {
       // BANK switch occurred, track current bank
-      current_bank = (index == 0) ? 0 : 1;
-      debug("bank switch", current_bank, INFO);      
-    } else {
-      if (index == 0 || index == 5) {
-       // a switch, other than bank switch was released 
-        channel = (previous_index % 5) - 1;
+      current_bank = (index == BANK0_OPEN) ? BANK0 : BANK1;
+      debug("bank switch", current_bank, INFO);   
+      reconfig_presses = 0;
+      reconfig_start_time = 0;  
+      channel = -1; 
+    } 
+    else {
+      if (index == BANK0_OPEN || index == BANK1_OPEN) {
+        // a switch, other than bank switch was released 
+        channel = (previous_index % INDEX_PER_BANK) - 1; // subtract 1 because switches are 1-4 but indices are 0-3
         debug("released", channel, DEBUG);
         debug("TnI ", banks.bank[current_bank].switches[channel].toggle_not_immediate, DEBUG);
         // if IMMEDIATE send on button press and release, if TOGGLE only send on button press
           debug("immediate", channel, INFO);
           toggle_control_state(current_bank, channel);
         }    
-      } else {
-       // a non-bank switch was pressed 
-        channel = (index % 5) - 1;
+      } 
+      else {
+        // a non-bank switch was pressed 
+        channel = (index % INDEX_PER_BANK) - 1;
         debug("pressed", channel, DEBUG);
         // always send on button press
         debug("toggle", channel, INFO);
         toggle_control_state(current_bank, channel);               
       }
     }
-  
-  previous_index = index; // update the index variables at the end, so we can know which was changed through the processing stages
+
+    if (channel == RECONFIG_CHANNEL) {
+      if(reconfig_presses == 0) {
+        reconfig_start_time = millis(); 
+      }
+
+      reconfig_presses++;
+      if (reconfig_presses > RECONFIG_TIMES) {
+        if((millis() - reconfig_start_time) < RECONFIG_INTERVAL) { // if we hit it fast enough
+          reconfig_mode(); 
+          reconfig_presses = 0;
+          previous_index = -1;
+        } 
+        else {
+          reconfig_presses = 0;
+        }
+      }
+    } 
+    else {
+      reconfig_presses = 0;
+    }
+    previous_index = index; // update the index variables at the end, so we can know which was changed through the processing stages
 
   } // end previos != index loop
-  
+
   MIDI.read();
   display_banks_status();
-  delay(100);// cheap debounce - probably needs to change
+  delay(DEBOUNCE_DELAY);// cheap debounce - probably needs to change
 }
 
 void toggle_control_state(int channel, int control) {
 
 void send_midi_message(char* message) {
 
+  for(int i=0; i < MIDI_MESSAGE_LENGTH; i++) {
 
-  for(int i=0; i < MIDI_MESSAGE_LENGTH; i++) {
-    send_byte(message[i]);
-  
-  
-//  
-//    if(i==0 && (message[0] < 128)) {
-//      break; // first byte has to be a control / command byte, value 1xxx_xxxx 
-//    } 
-//    else {
-//      send_byte(message[i]); 
-//    }
-//
-//    if(i>0 && message[i] > 127) {
-//      break; // data bytes are 127 or less 
-//    } 
-//    else {
-//      send_byte(message[i]);
-//    }
-//  }
-}
+    if(i==0) {   // first byte should be a command
+      if ((byte)message[0] >= 0x80) {
+        send_byte(message[0]); 
+      } 
+      else {
+        indicate_error();
+        return; 
+      }
+    }
+
+    if(i>0) {
+      if ((byte)message[i] < 0x80) {
+        send_byte(message[i]);
+      } 
+      else {
+        return;
+      } 
+    }
+  }
 }
 
 void send_byte(byte b) {
   } 
 }
 
-
-
 void debug(char*message, int val, int level) {
   if(DEBUG_LEVEL < level) {
     return;
   Serial.print(message);
   Serial.print(" ");
   Serial.println(val);
- 
+
 }
 
 
 
 
 
+
   flash_led(pin, 50);
 }
 
+// wrapper around flash with faster delay
+void slow_flash(int pin) {
+  flash_led(pin, 200);
+}
+
+void strobe_led(int repeat, int pin) {
+  for (int i = 0; i < repeat; i++){
+    fast_flash(pin); 
+  }  
+}
+
+void show_status(int val) {
+  for (int i = 0; i < val; i++) {
+    slow_flash(STATUS_LED);
+  }
+}
+
+
 void indicate_error() {
- for (int i = 0; i<4; i++) {
-  fast_flash(ERROR_LED);
- } 
+  for (int i = 0; i<4; i++) {
+    fast_flash(ERROR_LED);
+  } 
 }
 
 void display_banks_status() {
   }
 }
 
+void cycle_leds() {
+  for(int loop=0;loop<CYCLE_LOOP; loop++) {
+    for(int led = LOW_LED; led<= HIGH_LED;led++) {
+      digitalWrite(led, HIGH);
+      delay(50);
+      digitalWrite(led, LOW);
+    }   
+  }
+}
+
+void reverse_cycle_leds() {
+  for(int loop=0;loop<CYCLE_LOOP; loop++) {
+    for(int led = HIGH_LED; led>=LOW_LED;led--) {
+      digitalWrite(led, HIGH);
+      delay(50);
+      digitalWrite(led, LOW);
+    }   
+  }
+}
+

File vfs5_decoder.pde

 
-int switch_levels[10] = {561, 459, 384, 261, 163, 641, 510, 416, 277, 169};
-
+const int switch_levels[10] = {561, 459, 384, 261, 163, 641, 510, 416, 277, 169};
 
 int find_closest_level_index(int sample) {