improvements

This commit is contained in:
Jay Robson 2024-09-30 23:25:16 +10:00
parent 376a2ef6de
commit f71b07f499
5 changed files with 96 additions and 76 deletions

View File

@ -9,7 +9,6 @@
const int PIN_NEXT = 8; const int PIN_NEXT = 8;
static bool state_next = 1;
static uint32_t addr_next = 0; static uint32_t addr_next = 0;
void buttons::init() { void buttons::init() {
@ -32,14 +31,11 @@ static void on_next() {
} }
void buttons::update() { void buttons::update() {
if(!digitalRead(PIN_NEXT) && state_next) { if(!digitalRead(PIN_NEXT)) {
delay(1); delay(1);
state_next = 0; while(!digitalRead(PIN_NEXT)) {}
}
else if(digitalRead(PIN_NEXT) && !state_next) {
delay(1); delay(1);
on_next(); on_next();
state_next = 1;
} }
} }

View File

@ -8,7 +8,8 @@ using namespace eeprom;
constexpr uint8_t WRITE_MS = 3; constexpr uint8_t WRITE_MS = 3;
constexpr uint8_t ADDR = 0x50; constexpr uint8_t ADDR = 0x50;
uint32_t at = 0; static uint32_t at = 0;
static uint32_t last_block_end = 0;
static bool is_responsive(uint8_t i2c_addr) { static bool is_responsive(uint8_t i2c_addr) {
bool s = mem.start_write(i2c_addr); bool s = mem.start_write(i2c_addr);
@ -37,6 +38,7 @@ void eeprom::init() {
} }
void eeprom::jump(uint32_t p_at) { void eeprom::jump(uint32_t p_at) {
last_block_end = 0;
at = p_at; at = p_at;
} }
@ -44,11 +46,16 @@ void eeprom::read(char* data, uint16_t data_size) {
uint16_t recorded = 0; uint16_t recorded = 0;
while(recorded < data_size && at < LENGTH) { while(recorded < data_size && at < LENGTH) {
uint32_t block_end = at / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE; uint32_t block_end = at / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE;
uint8_t read_len = min(min(block_end - at, data_size - recorded), 255); uint8_t read_len = min(min(block_end - at, data_size - recorded), 255);
uint8_t i2c_addr = get_i2c_addr(at); uint8_t i2c_addr = get_i2c_addr(at);
set_address(i2c_addr, at); if(block_end != last_block_end) {
set_address(i2c_addr, at);
last_block_end = block_end;
}
mem.start_read(i2c_addr); mem.start_read(i2c_addr);
mem.read(data + recorded, read_len, true); mem.read(data + recorded, read_len, true);
recorded += read_len; recorded += read_len;
@ -72,6 +79,7 @@ void eeprom::page_write(uint32_t at, const char* data) {
mem.write(data, PAGE_SIZE - (at % PAGE_SIZE)); mem.write(data, PAGE_SIZE - (at % PAGE_SIZE));
mem.end(); mem.end();
delay(WRITE_MS); delay(WRITE_MS);
last_block_end = 0;
} }
uint32_t eeprom::get_addr() { uint32_t eeprom::get_addr() {

View File

@ -9,53 +9,30 @@ struct Checker {
namespace entry { namespace entry {
enum Type : uint8_t { enum Type : uint8_t {
stop, stop = 0,
config, config = 1,
set, set = 2,
set_ts, set_ts = 3,
clear, clear = 4,
clear_ts, clear_ts = 5,
tempo = 6,
}; };
struct Set { enum NextType {
uint8_t index; nt_none,
uint16_t frequency; nt_tone,
}; nt_tempo,
struct Clear {
uint8_t index;
};
struct SetTS {
uint8_t index;
uint32_t ticks;
uint16_t frequency;
};
struct ClearTS {
uint8_t index;
uint32_t ticks;
}; };
struct Stop { struct Tone {
}; uint8_t index;
struct Config {
uint32_t us_per_tick;
uint8_t amplitude; uint8_t amplitude;
uint32_t jump_addr; uint16_t frequency;
}; };
struct Generic { struct Tempo {
Type type; uint32_t ticks;
union { uint32_t us_per_tick;
Set set;
SetTS set_ts;
Clear clear;
ClearTS clear_ts;
Stop stop;
Config config;
};
}; };
inline size_t get_size(Type type) { inline size_t get_size(Type type) {
@ -70,6 +47,8 @@ namespace entry {
return 4; return 4;
case Type::config: case Type::config:
return 8; return 8;
case Type::tempo:
return 7;
case Type::stop: case Type::stop:
default: default:
return 1; return 1;

View File

@ -12,40 +12,57 @@ using namespace scheduler;
static uint32_t ts_init = 0; static uint32_t ts_init = 0;
static uint32_t ts_last = 0; static uint32_t ts_last = 0;
static uint32_t tick_offset = 0;
struct { struct {
uint8_t amplitude = 1; uint8_t amplitude = 1;
uint32_t us_per_tick = 1; uint32_t us_per_tick = 1;
} config; } config;
struct { struct {
uint8_t index; entry::NextType type = entry::nt_none;
uint8_t amplitude; union {
uint16_t frequency; entry::Tone tone;
bool active = false; entry::Tempo tempo;
};
} next; } next;
void scheduler::reset() { void scheduler::reset() {
tones::clear_all(); tones::clear_all();
ts_init = timestamp = micros(); ts_init = timestamp = micros();
tick_offset = 0;
} }
static void do_next() { static void do_next() {
int i = 1; int i = 1;
if(next.active) { if(state == State::play) {
if(state == State::play) { switch(next.type) {
tones::set(next.index, next.frequency, next.amplitude); case entry::nt_tone:
tones::set(next.tone.index, next.tone.frequency, next.tone.amplitude);
break;
case entry::nt_tempo:
ts_init += next.tempo.ticks * config.us_per_tick;
tick_offset = next.tempo.ticks;
config.us_per_tick = next.tempo.us_per_tick;
break;
} }
next.active = false;
} }
next.type = entry::nt_none;
uint64_t v = 0; uint64_t v = 0;
uint8_t buff[8]; uint8_t buff[8];
data::read(buff, 1);
if(data::read(buff, 1) != 1) {
return;
}
entry::Type type = buff[0] >> 5; entry::Type type = buff[0] >> 5;
int entry_size = entry::get_size(type); int entry_size = entry::get_size(type);
data::read(buff + 1, entry_size - 1);
if(data::read(buff + 1, entry_size - 1) != entry_size - 1) {
return;
}
for(int i = 0; i < entry_size; i++) { for(int i = 0; i < entry_size; i++) {
v = (v << 8) | buff[i]; v = (v << 8) | buff[i];
@ -62,41 +79,50 @@ static void do_next() {
scheduler::reset(); scheduler::reset();
break; break;
} }
case entry::Type::tempo: {
next.type = entry::nt_tempo;
v >>= 4;
next.tempo.ticks = (v & bm(20)) - tick_offset;
v >>= 20;
next.tempo.us_per_tick = v & bm(29);
timestamp = next.tempo.ticks * config.us_per_tick + ts_init;
break;
}
case entry::Type::set: { case entry::Type::set: {
v >>= 4; v >>= 4;
next.frequency = v & bm(12); next.type = entry::nt_tone;
next.tone.frequency = v & bm(12);
v >>= 12; v >>= 12;
next.index = v & bm(5); next.tone.index = v & bm(5);
next.amplitude = config.amplitude; next.tone.amplitude = config.amplitude;
next.active = true;
break; break;
} }
case entry::Type::set_ts: { case entry::Type::set_ts: {
next.frequency = v & bm(12); next.type = entry::nt_tone;
next.tone.frequency = v & bm(12);
v >>= 12; v >>= 12;
uint32_t ticks = v & bm(20); uint32_t ticks = (v & bm(20)) - tick_offset;
v >>= 20; v >>= 20;
next.index = v & bm(5); next.tone.index = v & bm(5);
next.amplitude = config.amplitude; next.tone.amplitude = config.amplitude;
next.active = true;
timestamp = ticks * config.us_per_tick + ts_init; timestamp = ticks * config.us_per_tick + ts_init;
break; break;
} }
case entry::Type::clear: { case entry::Type::clear: {
next.index = v & bm(5); next.type = entry::nt_tone;
next.frequency = 0; next.tone.index = v & bm(5);
next.amplitude = 0; next.tone.frequency = 0;
next.active = true; next.tone.amplitude = 0;
break; break;
} }
case entry::Type::clear_ts: { case entry::Type::clear_ts: {
v >>= 4; v >>= 4;
uint32_t ticks = v & bm(20); uint32_t ticks = (v & bm(20)) - tick_offset;
v >>= 20; v >>= 20;
next.index = v & bm(5); next.type = entry::nt_tone;
next.frequency = 0; next.tone.index = v & bm(5);
next.amplitude = 0; next.tone.frequency = 0;
next.active = true; next.tone.amplitude = 0;
timestamp = ticks * config.us_per_tick + ts_init; timestamp = ticks * config.us_per_tick + ts_init;
break; break;
} }

View File

@ -13,6 +13,17 @@ inline void swap(T& a, T& b) {
a = t; a = t;
} }
#ifdef DEBUG_BLINK
inline void debug_blink() {
digitalWrite(9, 0);
delay(120);
digitalWrite(9, 1);
delay(10);
digitalWrite(9, 0);
delay(120);
}
#endif
#define bm(V) (((uint64_t)1 << V) - 1) #define bm(V) (((uint64_t)1 << V) - 1)
#define size(V) (sizeof(V) / sizeof(V[0])) #define size(V) (sizeof(V) / sizeof(V[0]))