/* * Created on: Jul 27, 2024 * * code taken from example WCH code, which was likely stolen from somewhere else. * directly uses i2c peripheral in shitty way. no time to make this better. * modified to support multiple "pages" (addresses) for 02/04/08/16 EEPROMs. * * ensure i2c bus has been configured before using these functions. */ #define EEPROM_BASE_ADDR 0xa0 #include #include #include "eeprom.h" #include "i2c.h" static inline uint8_t page_to_i2caddr(uint8_t page) { page &= 0x7; // limit page to 3 bits (8 pages) page <<= 1; // shift page to required position page |= EEPROM_BASE_ADDR; // merge top address bits to form address return page; } /********************************************************************* * @fn eeprom_read_byte * * @brief Read one data from EEPROM. * @param page - Which 256-byte EEPROM page. * @param addr - First read address. * @param data - Pointer to byte(s) to write. * @param len - Count of data to write. */ void eeprom_read_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len) { page = page_to_i2caddr(page); i2c_read_addr1b(page, addr, data, len); } /********************************************************************* * @fn eeprom_write_bytes * * @brief Write data to EEPROM. * Note that some EEPROMs have buffers smaller than the page size. * * @param page - Which 256-byte EEPROM page. * @param addr - Starting write address. * @param data - Pointer to byte(s) to write. * @param len - Count of data to write. */ void eeprom_write_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len) { page = page_to_i2caddr(page); // disable systick interrupt NVIC_DisableIRQ(SysTicK_IRQn); // write the data #ifdef EEPROM_WP_PORT EEPROM_WP_PORT->BCR = EEPROM_WP_PIN; #endif while (!i2c_addr_scan(page)); i2c_write_addr1b(page, addr, data, len); while (!i2c_addr_scan(page)); #ifdef EEPROM_WP_PORT EEPROM_WP_PORT->BSHR = EEPROM_WP_PIN; #endif // clear systick timer SysTick->CNT = 0; SysTick->SR = 0; // re-enable systick interrupt NVIC_EnableIRQ(SysTicK_IRQn); }