tone-generator/eeprom.cpp

81 lines
1.6 KiB
C++
Raw Normal View History

#include <Arduino.h>
#include "eeprom.hpp"
2024-08-31 01:53:25 +10:00
#include "util.hpp"
2024-08-31 01:53:25 +10:00
using namespace eeprom;
constexpr uint8_t WRITE_MS = 3;
constexpr uint8_t ADDR = 0x50;
2024-08-31 01:53:25 +10:00
uint32_t at = 0;
2024-08-31 01:53:25 +10:00
static bool is_responsive(uint8_t i2c_addr) {
bool s = mem.start_write(i2c_addr);
return s;
}
2024-08-31 01:53:25 +10:00
static void wait_for_responsive(uint8_t i2c_addr) {
while(!is_responsive(i2c_addr)) {
delay(1);
}
}
2024-08-31 01:53:25 +10:00
static uint8_t get_i2c_addr(uint32_t at) {
uint8_t i2c_addr = ADDR;
if(at > 0xffff) {
i2c_addr |= 1;
2024-08-31 01:53:25 +10:00
}
return i2c_addr;
}
2024-08-31 01:53:25 +10:00
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);
}
2024-08-31 01:53:25 +10:00
void eeprom::init() {
mem.begin();
}
2024-08-31 01:53:25 +10:00
void eeprom::jump(uint32_t p_at) {
at = p_at;
2024-08-31 01:53:25 +10:00
}
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;
}
}
2024-08-31 01:53:25 +10:00
void eeprom::page_write(uint32_t at, const char* data) {
if(at >= LENGTH) return;
2024-08-31 01:53:25 +10:00
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);
}