#include #include #include #include "midi_data.hpp" #include "data.hpp" const int SERIAL_RX = A4; const int SERIAL_TX = A5; enum Mode : uint8_t { none, ready, local, serial, read, jump, }; static char buff[64]; static bool buff_full = false; static unsigned buff_at = 0; static unsigned address = 0; static SoftwareSerial serial_dev(SERIAL_RX, SERIAL_TX); static Mode mode = Mode::local; void data::init() { pinMode(SERIAL_RX, INPUT); pinMode(SERIAL_TX, OUTPUT); serial_dev.begin(57600); serial_dev.listen(); serial_dev.write(Mode::ready); unsigned long ts_end = millis() + 1000; while(ts_end > millis()) { if(check()) { break; } } } bool data::check() { if(serial_dev.available()) { mode = serial_dev.read(); return true; } else { return false; } } void data::jump(unsigned long loc) { switch(mode) { case Mode::local: address = loc; break; case Mode::serial: serial_dev.write(Mode::jump); serial_dev.write(loc >> 24); serial_dev.write(loc >> 16); serial_dev.write(loc >> 8); serial_dev.write(loc); break; } } inline uint8_t proc_len(uint8_t len) { if(address + len >= sizeof(MIDI)) { return sizeof(MIDI) - address; } else { return len; } } static void fill_buffer() { serial_dev.write(Mode::read); serial_dev.write(sizeof(buff)); for(int i = 0; i < sizeof(buff); i++) { while(!serial_dev.available()) {} buff[i] = serial_dev.read(); } buff_at = 0; buff_full = true; } void data::read(void* data, uint8_t len) { char* bytes = (char*)data; switch(mode) { case Mode::local: len = proc_len(len); memcpy_P(bytes, &MIDI[address], len); address += len; break; case Mode::serial: if(!buff_full) { fill_buffer(); } while(sizeof(buff) - buff_at < len) { auto l = sizeof(buff) - buff_at; memcpy(bytes, buff + buff_at, l); bytes += l; len -= l; fill_buffer(); } memcpy(bytes, buff + buff_at, len); buff_at += len; break; } } void data::write(const void* data, uint8_t len) { }