diff --git a/README.md b/README.md index ad09012..01276ad 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,7 @@ Once upon a time, Sean Hellfritsch and Brian Crabtree [made a faderbank][linespo **16n** is the revised version of that object: it is open-source and ready for you to make, modify, or hack. -It is currently at hardware version **1.34**, firmware version **2.0.0**. - -_Firmware version 2.0.0 is designed for Teensy 3.2 boards. If you're using a 16n derivative with another board, such as a Teensy LC, the hex files available will not currently work._ +It is currently at hardware version **1.34**, firmware version **2.0.1**. # Repository contents diff --git a/firmware/_16n_faderbank_firmware/README.md b/firmware/_16n_faderbank_firmware/README.md index e8c1e08..0de8468 100644 --- a/firmware/_16n_faderbank_firmware/README.md +++ b/firmware/_16n_faderbank_firmware/README.md @@ -1,8 +1,8 @@ # 16n Firmware -16n Firmware is designed to run on a Teensy 3.2. It is not supported on any other platform. **In particular, it is currently entirely unsupported on Teensy LC right now.** If you aren't sure what board is inside your 16n, ask your supplier. +16n Firmware is designed to run on a Teensy 3.2; it is also compatible with a Teensy LC, although the official BOM recommends a 3.2. -This README serves as a guide for **developing** and **compiling** your own versions of the firwmare. As of Firmware v2.0.0, the recommended method for putting firmware onto a 16n is to use Teensy Loader directly. [Find out more on the wiki][load-firmware] +This README serves as a guide for **developing** and **compiling** your own versions of the firwmare. Since firmware v2.0.0, the recommended method for putting firmware onto a 16n is to use Teensy Loader directly. [Find out more on the wiki][load-firmware] If you are interested in compiling your own firmware, or hacking on it, read on! @@ -22,7 +22,7 @@ If you are interested in compiling your own firmware, or hacking on it, read on! As of 16n firmware 2.0.0, you no longer should do ANY configuration through the Arduino IDE. All configuration is conducted from a web browser, using the [16n editor][editor] -When you upgrade to 2.0.0 you will LOSE ANY CONFIGURATION YOU HAVE. This is a one-time thing; apologies. +When you upgrade to 2.0.0 you will LOSE ANY CONFIGURATION YOU HAVE from v1.3x. This is a one-time thing; apologies. You will not lose future configurations (and also, they are easier to back up). The 16n will be initialised to a set of default settings (All outputs for TRS and USB set to MIDI channel 1, CCs 32-47, I2C set to follower). Once this is done, connect over USB, and go to the [editor][editor] in Google Chrome; you will be able to see the current configuration, edit the configuration, and transmit the new config to your device. You will likely need to customise the maximum fader value calibrations. diff --git a/firmware/_16n_faderbank_firmware/SYSEX_SPEC.md b/firmware/_16n_faderbank_firmware/SYSEX_SPEC.md new file mode 100644 index 0000000..ea72c99 --- /dev/null +++ b/firmware/_16n_faderbank_firmware/SYSEX_SPEC.md @@ -0,0 +1,27 @@ +# 16n Sysex spec + +The 16n interfaces with its editor via MIDI Sysex. This document describes the supported messages. + +## `0x1F` - "1nFo" + +Request for 16n to transmit current state via sysex. No other payload. + +## `0x0F` - "c0nFig" + +"Here is my current config." Only sent by 16n as an outbound message, in response to `0x1F`. Payload of 80 bytes, describing current EEPROM state. + +## `0x0E` - "c0nfig Edit" + +"Here is a new complete configuration for you". Payload (other than mfg header, top/tail, etc) of 80 bytes to go straight into EEPROM, according to the memory map described in `README.md`. + +## `0x0D` - "c0nfig edit (Device options)" + +"Here is a new set of device options for you". Payload (other than mfg header, top/tail, etc) of 16 bytes to go straight into appropriate locations of EEPROM, according to the memory map described in `README.md`. + +## `0x0C` - "c0nfig edit (usb options)" + +"Here is a new set of USB options for you". Payload (other than mfg header, top/tail, etc) of 32 bytes to go straight into appropriate locations of EEPROM, according to the memory map described in `README.md`. + +## `0x0B` - "c0nfig edit (trs options)" + +"Here is a new set of TRS options for you". Payload (other than mfg header, top/tail, etc) of 32 bytes to go straight into appropriate locations of EEPROM, according to the memory map described in `README.md`. diff --git a/firmware/_16n_faderbank_firmware/config.h b/firmware/_16n_faderbank_firmware/config.h index b474b3c..f004551 100644 --- a/firmware/_16n_faderbank_firmware/config.h +++ b/firmware/_16n_faderbank_firmware/config.h @@ -11,13 +11,17 @@ int MAJOR_VERSION = 0x02; int MINOR_VERSION = 0x00; -int POINT_VERSION = 0x00; +int POINT_VERSION = 0x01; /* * device metadata */ -int DEVICE_ID = 0x02; // 16n, do not change, needed by editor +#if defined(__MKL26Z64__) || defined(__MK20DX128__) || defined(_LC_DEBUG) +const int DEVICE_ID = 0x03; // 16nLC, do not change, needed by editor +#else +const int DEVICE_ID = 0x02; // 16n, do not change, needed by editor +#endif // restricts output to only channel 1 for development purposes // #define DEV 1 diff --git a/firmware/_16n_faderbank_firmware/configuration.ino b/firmware/_16n_faderbank_firmware/configuration.ino index 3fc65e2..36f87b1 100644 --- a/firmware/_16n_faderbank_firmware/configuration.ino +++ b/firmware/_16n_faderbank_firmware/configuration.ino @@ -104,7 +104,7 @@ void loadSettingsFromEEPROM() { } D(Serial.println("USB CCs loaded:")); - // D(printIntArray(usbCCs,channelCount)); + D(printIntArray(usbCCs,channelCount)); // load TRS ccs @@ -115,7 +115,7 @@ void loadSettingsFromEEPROM() { } D(Serial.println("TRS CCs loaded:")); - // D(printIntArray(trsCCs,channelCount)); + D(printIntArray(trsCCs,channelCount)); // load other config ledOn = EEPROM.read(0); diff --git a/firmware/_16n_faderbank_firmware/sysex.ino b/firmware/_16n_faderbank_firmware/sysex.ino index 374074f..8a53075 100644 --- a/firmware/_16n_faderbank_firmware/sysex.ino +++ b/firmware/_16n_faderbank_firmware/sysex.ino @@ -29,37 +29,85 @@ void processIncomingSysex(byte* sysexData, unsigned size) { case 0x0e: // 0E - c0nfig Edit - here is a new config D(Serial.println("Incoming c0nfig Edit")); - updateSettingsAndStoreInEEPROM(sysexData, size); + updateAllSettingsAndStoreInEEPROM(sysexData, size); + break; + case 0x0d: + // 0D - c0nfig Device edit - new config just for device opts + D(Serial.println("Incoming c0nfig Device edit")); + updateDeviceSettingsAndStoreInEEPROM(sysexData, size); + break; + case 0x0c: + // 0C - c0nfig usb edit - here is a new config just for usb + D(Serial.println("Incoming c0nfig usb edit")); + updateUSBSettingsAndStoreInEEPROM(sysexData, size); + break; + case 0x0b: + // 0B - c0nfig trs edit - here is a new config just for trs + D(Serial.println("Incoming c0nfig trs edit")); + updateTRSSettingsAndStoreInEEPROM(sysexData, size); break; } } -void updateSettingsAndStoreInEEPROM(byte* newConfig, unsigned size) { +void updateAllSettingsAndStoreInEEPROM(byte* newConfig, unsigned size) { // store the settings from sysex in flash // also update all our settings. D(Serial.print("Received a new config with size ")); D(Serial.println(size)); // D(printHexArray(newConfig,size)); - // walk the config - // ignore the top, tail, and firmware version - int startIndex = 9; // after the start signal + - int dataLength = 80; // five chunks of 16 + updateSettingsBlockAndStoreInEEPROM(newConfig,size,9,80,0); +} - byte dataToWrite[dataLength]; +void updateDeviceSettingsAndStoreInEEPROM(byte* newConfig, unsigned size) { + // store the settings from sysex in flash + // also update all our settings. + D(Serial.print("Received a new device config with size ")); + D(Serial.println(size)); + // D(printHexArray(newConfig,size)); - for(int i = 0; i < (dataLength); i++) { - int configIndex = i + startIndex; - dataToWrite[i] = newConfig[configIndex]; + updateSettingsBlockAndStoreInEEPROM(newConfig,size,5,16,0); +} + +void updateUSBSettingsAndStoreInEEPROM(byte* newConfig, unsigned size) { + // store channels + updateSettingsBlockAndStoreInEEPROM(newConfig,size,5,16,16); + // store CCs + updateSettingsBlockAndStoreInEEPROM(newConfig,size,21,16,48); +} + +void updateTRSSettingsAndStoreInEEPROM(byte* newConfig, unsigned size) { + // store channels + updateSettingsBlockAndStoreInEEPROM(newConfig,size,5,16,32); + // store CCs + updateSettingsBlockAndStoreInEEPROM(newConfig,size,21,16,64); +} + +void updateSettingsBlockAndStoreInEEPROM(byte* configFromSysex, unsigned sysexSize, int configStartIndex, int configDataLength, int EEPROMStartIndex) { + D(Serial.print("Storing data of size ")); + D(Serial.print(configDataLength)); + D(Serial.print(" at location ")); + D(Serial.print(EEPROMStartIndex)); + D(Serial.print(" from data of length ")); + D(Serial.print(sysexSize)); + D(Serial.print(" beginning at byte ")); + D(Serial.println(configStartIndex)); + D(printHexArray(configFromSysex, sysexSize)); + + // walk the config, ignoring the top, tail, and firmware version + byte dataToWrite[configDataLength]; + + for(int i = 0; i < (configDataLength); i++) { + int configIndex = i + configStartIndex; + dataToWrite[i] = configFromSysex[configIndex]; } // write new Data - writeEEPROMArray(0, dataToWrite, dataLength); + writeEEPROMArray(EEPROMStartIndex, dataToWrite, configDataLength); // now load that. loadSettingsFromEEPROM(); } - void sendCurrentState() { // 0F - "c0nFig" - outputs its config: byte sysexData[88];