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;
static bool state_next = 1;
static uint32_t addr_next = 0;
void buttons::init() {
@ -32,14 +31,11 @@ static void on_next() {
}
void buttons::update() {
if(!digitalRead(PIN_NEXT) && state_next) {
if(!digitalRead(PIN_NEXT)) {
delay(1);
state_next = 0;
}
else if(digitalRead(PIN_NEXT) && !state_next) {
while(!digitalRead(PIN_NEXT)) {}
delay(1);
on_next();
state_next = 1;
}
}

View File

@ -8,7 +8,8 @@ using namespace eeprom;
constexpr uint8_t WRITE_MS = 3;
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) {
bool s = mem.start_write(i2c_addr);
@ -37,6 +38,7 @@ void eeprom::init() {
}
void eeprom::jump(uint32_t p_at) {
last_block_end = 0;
at = p_at;
}
@ -44,11 +46,16 @@ void eeprom::read(char* data, uint16_t data_size) {
uint16_t recorded = 0;
while(recorded < data_size && at < LENGTH) {
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 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.read(data + recorded, read_len, true);
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.end();
delay(WRITE_MS);
last_block_end = 0;
}
uint32_t eeprom::get_addr() {

View File

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

View File

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

View File

@ -13,6 +13,17 @@ inline void swap(T& a, T& b) {
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 size(V) (sizeof(V) / sizeof(V[0]))