Skip to content

Commit

Permalink
Grids: audio bootloader
Browse files Browse the repository at this point in the history
  • Loading branch information
Olivier Gillet committed Nov 14, 2014
1 parent 0c169d1 commit 3e1f07e
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 67 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "stm_audio_bootloader"]
path = stm_audio_bootloader
url = https://github.com/pichenettes/stm-audio-bootloader.git
[submodule "avr_audio_bootloader"]
path = avr_audio_bootloader
url = [email protected]:pichenettes/avr-audio-bootloader.git
1 change: 1 addition & 0 deletions avr_audio_bootloader
Submodule avr_audio_bootloader added at 4f12c4
182 changes: 118 additions & 64 deletions grids/bootloader/bootloader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,22 @@
#include "avrlib/serial.h"
#include "avrlib/watchdog_timer.h"

#include "avr_audio_bootloader/crc32.h"
#include "avr_audio_bootloader/fsk/decoder.h"

#include "grids/hardware_config.h"

using namespace avrlib;
using namespace grids;
using namespace avr_audio_bootloader;

MidiInput midi;
Inputs inputs;
Leds leds;
Decoder decoder;

uint16_t page = 0;
uint8_t rx_buffer[SPM_PAGESIZE + 1];
uint8_t rx_buffer[SPM_PAGESIZE + 4];

void (*main_entry_point)(void) = 0x0000;

Expand Down Expand Up @@ -84,6 +89,8 @@ void FlashLedsError() {
}
}

// MIDI loader -----------------------------------------------------------------

static const uint8_t sysex_header[] = {
0xf0, // <SysEx>
0x00, 0x21, 0x02, // Mutable instruments manufacturer id.
Expand All @@ -96,7 +103,7 @@ enum SysExReceptionState {
READING_DATA = 2,
};

inline void MidiLoop() {
inline void LoaderLoop() {
uint8_t byte;
uint16_t bytes_read = 0;
uint16_t rx_buffer_index;
Expand All @@ -107,77 +114,124 @@ inline void MidiLoop() {
uint8_t page_byte = 0;

midi.Init();
decoder.Init();
decoder.Sync();
decoder.set_packet_destination(rx_buffer);
page = 0;


TCCR2A = 0;
TCCR2B = 2;

while (1) {
leds.Write(LED_CLOCK | (LED_BD >> ((page_byte + 3) & 0x3)));
byte = midi.Read();
// In case we see a realtime message in the stream, safely ignore it.
if (byte > 0xf0 && byte != 0xf7) {
continue;
}
switch (state) {
case MATCHING_HEADER:
if (byte == sysex_header[bytes_read]) {
++bytes_read;
if (bytes_read == sizeof(sysex_header)) {
bytes_read = 0;
state = READING_COMMAND;

// Sample the clock input at 20kHz and feed to the FSK decoder.
if (TCNT2 >= (F_CPU / 8 / 40000 - 1)) {
TCNT2 = 0;

switch (decoder.PushSample(inputs.Read() & INPUT_CLOCK)) {
case DECODER_STATE_ERROR_SYNC:
FlashLedsError();
decoder.Sync();
break;

case DECODER_STATE_END_OF_TRANSMISSION:
return;
break;

case DECODER_STATE_PACKET_RECEIVED:
{
uint32_t crc = crc32(0, rx_buffer, SPM_PAGESIZE);
uint32_t expected_crc = \
(static_cast<uint32_t>(rx_buffer[SPM_PAGESIZE + 0]) << 24) | \
(static_cast<uint32_t>(rx_buffer[SPM_PAGESIZE + 1]) << 16) | \
(static_cast<uint32_t>(rx_buffer[SPM_PAGESIZE + 2]) << 8) | \
(static_cast<uint32_t>(rx_buffer[SPM_PAGESIZE + 3]) << 0);
if (crc == expected_crc) {
WriteBufferToFlash();
page += SPM_PAGESIZE;
++page_byte;
} else {
FlashLedsError();
}
}
} else {
bytes_read = 0;
}
break;

case READING_COMMAND:
if (byte < 0x80) {
sysex_commands[bytes_read++] = byte;
if (bytes_read == 2) {
decoder.Sync();
break;

default:
break;
}
}

// Poll the MIDI input.
if (midi.readable()) {
byte = midi.ImmediateRead();
if (byte > 0xf0 && byte != 0xf7) {
continue;
}
switch (state) {
case MATCHING_HEADER:
if (byte == sysex_header[bytes_read]) {
++bytes_read;
if (bytes_read == sizeof(sysex_header)) {
bytes_read = 0;
state = READING_COMMAND;
}
} else {
bytes_read = 0;
rx_buffer_index = 0;
checksum = 0;
state = READING_DATA;
}
} else {
state = MATCHING_HEADER;
status = 0;
bytes_read = 0;
}
break;

case READING_DATA:
if (byte < 0x80) {
if (bytes_read & 1) {
rx_buffer[rx_buffer_index] |= byte & 0xf;
if (rx_buffer_index < SPM_PAGESIZE) {
checksum += rx_buffer[rx_buffer_index];
break;

case READING_COMMAND:
if (byte < 0x80) {
sysex_commands[bytes_read++] = byte;
if (bytes_read == 2) {
bytes_read = 0;
rx_buffer_index = 0;
checksum = 0;
state = READING_DATA;
}
++rx_buffer_index;
} else {
rx_buffer[rx_buffer_index] = (byte << 4);
state = MATCHING_HEADER;
status = 0;
bytes_read = 0;
}
++bytes_read;
} else if (byte == 0xf7) {
if (sysex_commands[0] == 0x7f &&
sysex_commands[1] == 0x00 &&
bytes_read == 0) {
// Reset.
return;
} else if (rx_buffer_index == SPM_PAGESIZE + 1 &&
sysex_commands[0] == 0x7e &&
sysex_commands[1] == 0x00 &&
rx_buffer[rx_buffer_index - 1] == checksum) {
// Block write.
WriteBufferToFlash();
page += SPM_PAGESIZE;
++page_byte;
} else {
FlashLedsError();
break;

case READING_DATA:
if (byte < 0x80) {
if (bytes_read & 1) {
rx_buffer[rx_buffer_index] |= byte & 0xf;
if (rx_buffer_index < SPM_PAGESIZE) {
checksum += rx_buffer[rx_buffer_index];
}
++rx_buffer_index;
} else {
rx_buffer[rx_buffer_index] = (byte << 4);
}
++bytes_read;
} else if (byte == 0xf7) {
if (sysex_commands[0] == 0x7f &&
sysex_commands[1] == 0x00 &&
bytes_read == 0) {
// Reset.
return;
} else if (rx_buffer_index == SPM_PAGESIZE + 1 &&
sysex_commands[0] == 0x7e &&
sysex_commands[1] == 0x00 &&
rx_buffer[rx_buffer_index - 1] == checksum) {
// Block write.
WriteBufferToFlash();
page += SPM_PAGESIZE;
++page_byte;
} else {
FlashLedsError();
}
state = MATCHING_HEADER;
bytes_read = 0;
}
state = MATCHING_HEADER;
bytes_read = 0;
}
break;
break;
}
}
}
}
Expand All @@ -188,7 +242,7 @@ int main(void) {
_delay_ms(40);
if (!(inputs.Read() & INPUT_SW_RESET)) {
FlashLedsOk();
MidiLoop();
LoaderLoop();
FlashLedsOk();
FlashLedsOk();
}
Expand Down
6 changes: 3 additions & 3 deletions grids/bootloader/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
VERSION = 0.1
MCU_NAME = 328
TARGET = grids_bootloader
PACKAGES = avrlib grids/bootloader
PACKAGES = avrlib grids/bootloader avr_audio_bootloader/fsk
EXTRA_DEFINES = -funsigned-char -fno-inline-small-functions -DDISABLE_DEFAULT_UART_RX_ISR
EXTRA_LD_FLAGS = ,--section-start=.text=0x7c00,--relax
EXTRA_LD_FLAGS = ,--section-start=.text=0x7000,--relax

LFUSE = ff
HFUSE = dc
HFUSE = d8
EFUSE = 05
LOCK = 2f

Expand Down

0 comments on commit 3e1f07e

Please sign in to comment.