86 lines
2.2 KiB
C
86 lines
2.2 KiB
C
/*
|
|
* 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 <ch32v00x.h>
|
|
#include <stdint.h>
|
|
|
|
#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);
|
|
}
|