#include "m95128.h" uint8_t read_value; uint8_t old_last_page; uint8_t new_last_page; void spi_eeprom_select(bool state) { SET_PIN_OUT(DDRB, DDB0); if (!state) { SET_PIN_HIGH(PORTB, PB0); } else { SET_PIN_LOW(PORTB, PB0); } } void eeprom_write(uint8_t page, unsigned const char* msg, uint8_t msg_len) { spi_rfm69_select(false); spi_eeprom_select(true); spi_write(EEPROM_WREN); spi_eeprom_select(false); spi_eeprom_select(true); spi_write(EEPROM_WRITE); write_page_address(page); for (int i = 0; i < msg_len; i++) { spi_write(msg[i]); } spi_eeprom_select(false); spi_eeprom_select(true); spi_write(EEPROM_WRDI); spi_eeprom_select(false); // Poll the write-in-progress bit, but give up rather than spin forever if // the EEPROM is unpowered or absent. for (uint16_t attempts = 0; attempts < EEPROM_POLL_TIMEOUT_MS; attempts++) { spi_eeprom_select(true); spi_write(EEPROM_RDSR); read_value = spi_read(); spi_eeprom_select(false); if ((read_value & EEPROM_STATUS_WIP) == 0) { return; } _delay_ms(1); } } void eeprom_read(uint8_t page, unsigned char* msg, uint8_t msg_len) { spi_eeprom_select(true); spi_write(EEPROM_WRDI); spi_eeprom_select(false); spi_eeprom_select(true); spi_write(EEPROM_READ); write_page_address(page); for (int i = 0; i < msg_len; i++) { msg[i] = spi_read(); } spi_eeprom_select(false); } void delete_last_page(void) { old_last_page = get_last_page(); if (old_last_page == 0) // If we have nothing, no need to delete anything { return; } new_last_page = old_last_page - 1; write_last_page_value(new_last_page); eeprom_clear_page(old_last_page); } uint8_t get_last_page(void) { memset(DATA_BUFFER_65, 0, 1); eeprom_read(0, DATA_BUFFER_65, 1); return (uint8_t)DATA_BUFFER_65[0]; } void write_last_page_value(uint8_t page) { DATA_BUFFER_7[0] = page; eeprom_write(0, DATA_BUFFER_7, 1); } void write_page_address(uint8_t page) { uint16_t addr = page * 0x40; // Each page starts at 64 byte intervals. And 64 byte is 0x40 or // 0b01000000; spi_write((addr >> 8) & 0xFF); spi_write(addr & 0xFF); } void eeprom_write_tx_data(uint8_t page, tx_rx_data_struct tx_data_in) { if (page == 0) { return; } memset(DATA_BUFFER_65, ' ', 64); DATA_BUFFER_65[64] = '\0'; memcpy(DATA_BUFFER_65, tx_data_in.msg, 60); DATA_BUFFER_65[60] = tx_data_in.flags; DATA_BUFFER_65[61] = tx_data_in.from; DATA_BUFFER_65[62] = tx_data_in.to; DATA_BUFFER_65[63] = tx_data_in.dtype; eeprom_write(page, DATA_BUFFER_65, 64); } tx_rx_data_struct eeprom_read_tx_data(uint8_t page) { reset_txrx_struct(&TX_DATA); memset(DATA_BUFFER_65, ' ', 64); DATA_BUFFER_65[64] = '\0'; eeprom_read(page, DATA_BUFFER_65, 64); memcpy(TX_DATA.msg, DATA_BUFFER_65, 60); TX_DATA.flags = DATA_BUFFER_65[60]; TX_DATA.from = DATA_BUFFER_65[61]; TX_DATA.to = DATA_BUFFER_65[62]; TX_DATA.dtype = DATA_BUFFER_65[63]; TX_DATA.len = 60; return TX_DATA; } tx_rx_data_struct read_struct_last_page(void) { uint8_t page_num = get_last_page(); return eeprom_read_tx_data(page_num); } void write_struct_to_last_page(tx_rx_data_struct tx_data_in) { uint8_t page_val = get_last_page(); uint8_t next_page_val; if (page_val == 255) { next_page_val = 1; } else { next_page_val = page_val + 1; } eeprom_write_tx_data(next_page_val, tx_data_in); write_last_page_value(next_page_val); } void eeprom_clear_page(uint8_t page) { memset(DATA_BUFFER_65, ' ', 64); eeprom_write(page, DATA_BUFFER_65, 64); }