tone-generator/eeprom.cpp

81 lines
1.5 KiB
C++

#include <Arduino.h>
#include "eeprom.hpp"
#include "util.hpp"
using namespace eeprom;
constexpr uint8_t WRITE_MS = 3;
constexpr uint8_t ADDR = 0x50;
uint32_t at = 0;
static bool is_responsive(uint8_t i2c_addr) {
bool s = mem.start_write(i2c_addr);
return s;
}
static void wait_for_responsive(uint8_t i2c_addr) {
while(!is_responsive(i2c_addr)) {
delay(1);
}
}
static uint8_t get_i2c_addr(uint32_t at) {
return ADDR ^ (at >> 16);
}
static void set_address(uint8_t i2c_addr, uint16_t at) {
char addr_bytes[2] = {at >> 8, at};
mem.start_write(i2c_addr);
mem.write(at >> 8);
mem.write(at);
}
void eeprom::init() {
mem.begin();
}
void eeprom::jump(uint32_t p_at) {
at = p_at;
}
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);
mem.start_read(i2c_addr);
mem.read(data + recorded, read_len, true);
recorded += read_len;
at += read_len;
}
mem.end();
for(uint16_t i = recorded; i < data_size; i++) {
data[i] = 0;
}
}
void eeprom::page_write(uint32_t at, const char* data) {
if(at >= LENGTH) return;
uint8_t i2c_addr = get_i2c_addr(at);
wait_for_responsive(i2c_addr);
mem.start_write(i2c_addr);
mem.write(at >> 8);
mem.write(at);
mem.write(data, PAGE_SIZE - (at % PAGE_SIZE));
mem.end();
delay(WRITE_MS);
}
uint32_t eeprom::get_addr() {
return at;
}