eeprom config save / restore working

This commit is contained in:
true 2024-08-05 15:43:13 -07:00
parent 6785261d08
commit 00a428a425
6 changed files with 79 additions and 37 deletions

View File

@ -31,7 +31,7 @@ static uint16_t checksum()
void userconf_load() void userconf_load()
{ {
uint8_t csum; uint16_t csum;
eeprom_read_bytes(0, 0, (uint8_t *)&userconf, sizeof(userconf)); eeprom_read_bytes(0, 0, (uint8_t *)&userconf, sizeof(userconf));
csum = checksum(); csum = checksum();

View File

@ -8,7 +8,7 @@
* ensure i2c bus has been configured before using these functions. * ensure i2c bus has been configured before using these functions.
*/ */
#define EEPROM_BASE_ADDR (0xa0 >> 1) #define EEPROM_BASE_ADDR 0xa0
#include <ch32v00x.h> #include <ch32v00x.h>
@ -18,6 +18,17 @@
#include "i2c.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 * @fn eeprom_read_byte
* *
@ -29,9 +40,7 @@
*/ */
void eeprom_read_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len) void eeprom_read_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
{ {
page &= 0x7; // limit page to 3 bits (8 pages) page = page_to_i2caddr(page);
page |= EEPROM_BASE_ADDR; // add address to page
page <<= 1; // make i2c address from page
i2c_read_addr1b(page, addr, data, len); i2c_read_addr1b(page, addr, data, len);
} }
@ -39,19 +48,17 @@ void eeprom_read_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
/********************************************************************* /*********************************************************************
* @fn eeprom_write_bytes * @fn eeprom_write_bytes
* *
* @brief Write one data to EEPROM. * @brief Write data to EEPROM.
* Note that some EEPROMs have buffers smaller than the page size. * Note that some EEPROMs have buffers smaller than the page size.
* *
* @param page - Which 256-byte EEPROM page. * @param page - Which 256-byte EEPROM page.
* @param addr - Starting write address. * @param addr - Starting write address.
* @param data - Pointer to byte(s) to write. * @param data - Pointer to byte(s) to write.
* @param len - Count of data 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) void eeprom_write_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
{ {
page &= 0x7; // limit page to 3 bits (8 pages) page = page_to_i2caddr(page);
page |= EEPROM_BASE_ADDR; // add address to page
page <<= 1; // make i2c address from page
// disable systick interrupt // disable systick interrupt
NVIC_DisableIRQ(SysTicK_IRQn); NVIC_DisableIRQ(SysTicK_IRQn);
@ -61,9 +68,9 @@ void eeprom_write_bytes(uint8_t page, uint8_t addr, uint8_t *data, uint8_t len)
EEPROM_WP_PORT->BCR = EEPROM_WP_PIN; EEPROM_WP_PORT->BCR = EEPROM_WP_PIN;
#endif #endif
while (i2c_ack_poll(page)); while (!i2c_addr_scan(page));
i2c_write_addr1b(page, addr, data, len); i2c_write_addr1b(page, addr, data, len);
while (i2c_ack_poll(page)); while (!i2c_addr_scan(page));
#ifdef EEPROM_WP_PORT #ifdef EEPROM_WP_PORT
EEPROM_WP_PORT->BSHR = EEPROM_WP_PIN; EEPROM_WP_PORT->BSHR = EEPROM_WP_PIN;

View File

@ -15,7 +15,7 @@
#define EEPROM_WP_PORT GPIOC #define EEPROM_WP_PORT GPIOC
#define EEPROM_WP_PIN GPIO_Pin_7 #define EEPROM_WP_PIN GPIO_Pin_6

View File

@ -29,8 +29,7 @@ void i2c_init()
i2c.I2C_ClockSpeed = 666666; i2c.I2C_ClockSpeed = 666666;
i2c.I2C_Mode = I2C_Mode_I2C; i2c.I2C_Mode = I2C_Mode_I2C;
i2c.I2C_DutyCycle = I2C_DutyCycle_16_9; i2c.I2C_DutyCycle = I2C_DutyCycle_2; // 16_9;
i2c.I2C_OwnAddress1 = 0x7f;
i2c.I2C_Ack = I2C_Ack_Enable; i2c.I2C_Ack = I2C_Ack_Enable;
i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &i2c); I2C_Init(I2C1, &i2c);
@ -57,11 +56,13 @@ int8_t i2c_read_addr1b(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len)
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) && timeout--); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) && timeout--);
if (!timeout) return -3; if (!timeout) return -3;
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_SendData(I2C1, reg); I2C_SendData(I2C1, reg);
timeout = I2C_TIMEOUT; timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--);
if (!timeout) return -4; if (!timeout) return -4;
I2C_AcknowledgeConfig(I2C1, ENABLE);
I2C_GenerateSTART(I2C1, ENABLE); I2C_GenerateSTART(I2C1, ENABLE);
timeout = I2C_TIMEOUT; timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
@ -102,6 +103,8 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--); while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
if (!timeout) return -1; if (!timeout) return -1;
I2C_AcknowledgeConfig(I2C1, ENABLE);
I2C_GenerateSTART(I2C1, ENABLE); I2C_GenerateSTART(I2C1, ENABLE);
timeout = I2C_TIMEOUT; timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
@ -124,6 +127,11 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
I2C_SendData(I2C1, *data++); I2C_SendData(I2C1, *data++);
len--; len--;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
continue;
}
// failed to acknowledge...
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) {
break;
} }
} }
@ -137,9 +145,15 @@ void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const uint8_t dat)
i2c_write_addr1b(addr, reg, &dat, 1); i2c_write_addr1b(addr, reg, &dat, 1);
} }
int8_t i2c_ack_poll(uint8_t addr) uint8_t i2c_addr_scan(uint8_t addr)
{ {
int8_t addr_match = 0; uint8_t found = 1;
uint32_t event;
// no low addresses
if ((addr >> 4) == 0) return 0;
// no high addresses
if ((addr & 0xf8) == 0xf8) return 0;
timeout = I2C_TIMEOUT; timeout = I2C_TIMEOUT;
while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--); while((I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) && timeout--);
@ -150,14 +164,32 @@ int8_t i2c_ack_poll(uint8_t addr)
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
if (!timeout) return -2; if (!timeout) return -2;
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver); I2C_Send7bitAddress(I2C1, addr, (addr & 1));
timeout = I2C_TIMEOUT_ACK_POLL; timeout = I2C_TIMEOUT_ACK_POLL;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) && timeout--); if (addr & 1) event = I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED;
if (!timeout) { else event = I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED;
addr_match = -128;
while (I2C_CheckEvent(I2C1, event) && timeout--) {
if (I2C_GetFlagStatus(I2C1, I2C_FLAG_AF)) {
found = 0;
break;
}
} }
if (!timeout) {
found = 0;
}
// reset flags; it might be in a fucked state
I2C1->STAR1 = 0;
// send a stop to make sure anything listening knows to stfu
I2C_GenerateSTOP(I2C1, ENABLE); I2C_GenerateSTOP(I2C1, ENABLE);
return addr_match; if (!found) {
return 0;
}
return addr;
} }

View File

@ -19,7 +19,7 @@ int8_t i2c_write_addr1b(uint8_t addr, uint8_t reg, const uint8_t *data, uint8_t
uint8_t i2c_read_reg_8b(uint8_t addr, uint8_t reg); uint8_t i2c_read_reg_8b(uint8_t addr, uint8_t reg);
void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const uint8_t dat); void i2c_write_reg_8b(uint8_t addr, uint8_t reg, const uint8_t dat);
int8_t i2c_ack_poll(uint8_t devaddr); uint8_t i2c_addr_scan(uint8_t addr);

View File

@ -189,8 +189,9 @@ void ui_btn_release_cb(uint8_t idx)
userconf.cursor_color++; userconf.cursor_color++;
userconf.cursor_color &= 0x3; userconf.cursor_color &= 0x3;
// force cursor to change immediately // force cursor to change immediately, force cursor on
cursor_flash = 0; cursor_flash = 0;
cursor_state = 0;
config_save_timer = UI_CONF_SAVE_TIMEOUT; config_save_timer = UI_CONF_SAVE_TIMEOUT;
@ -310,7 +311,7 @@ static void ui_cursor_flash()
cursor_state++; cursor_state++;
cursor_state &= 1; cursor_state &= 1;
// set new cursor rate // set new cursor rate, force cursor on
cursor_flash = cursor_flash_rates[flash] >> 1; cursor_flash = cursor_flash_rates[flash] >> 1;
// set all colors off // set all colors off
@ -321,20 +322,22 @@ static void ui_cursor_flash()
cursor_flash--; cursor_flash--;
// set brightness of led, if we're in an on state // set brightness of led, if we're in an on state
if (cursor_state && (color < CONF_CURSOR_OFF)) { if (color < CONF_CURSOR_OFF) {
// first frame of on = not quite full brightness if (cursor_state) {
level = (cursor_flash == cursor_flash_rates[flash] - 1) ? 160 : 255; // first frame of on = not quite full brightness
level = (cursor_flash == cursor_flash_rates[flash] - 1) ? 160 : 255;
// at final frames, dim // at final frames, dim
if (cursor_flash <= 4) { if (cursor_flash <= 4) {
level >>= (4 - cursor_flash); level >>= (4 - cursor_flash);
}
} }
}
// set the level on the cursor // set the level on the cursor
if (cursor[color] != level) { if (cursor[color] != level) {
cursor[color] = led_gamma(level); cursor[color] = led_gamma(level);
led_is_updated(); led_is_updated();
}
} }
} }
@ -383,7 +386,7 @@ void ui_render()
// deal with eeprom // deal with eeprom
if (config_save_timer) { if (config_save_timer) {
config_save_timer--; config_save_timer--;
if (config_save_timer) { if (!config_save_timer) {
userconf_save(); userconf_save();
} }
} }