Skip to content

Commit

Permalink
Merge pull request #36 from 16n-faderbank/LC_support
Browse files Browse the repository at this point in the history
Add support for Teensy LC based 16ns (requires editor v1.11)
  • Loading branch information
infovore authored Apr 9, 2020
2 parents fe1b3eb + 4672899 commit 27df7d4
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 22 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions firmware/_16n_faderbank_firmware/README.md
Original file line number Diff line number Diff line change
@@ -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!

Expand All @@ -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.

Expand Down
27 changes: 27 additions & 0 deletions firmware/_16n_faderbank_firmware/SYSEX_SPEC.md
Original file line number Diff line number Diff line change
@@ -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`.
8 changes: 6 additions & 2 deletions firmware/_16n_faderbank_firmware/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions firmware/_16n_faderbank_firmware/configuration.ino
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void loadSettingsFromEEPROM() {
}

D(Serial.println("USB CCs loaded:"));
// D(printIntArray(usbCCs,channelCount));
D(printIntArray(usbCCs,channelCount));


// load TRS ccs
Expand All @@ -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);
Expand Down
72 changes: 60 additions & 12 deletions firmware/_16n_faderbank_firmware/sysex.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down

0 comments on commit 27df7d4

Please sign in to comment.