diff --git a/firmware/retro_tech_fw/user/src/config.c b/firmware/retro_tech_fw/user/src/config.c index 6b91f2a..7cd889d 100644 --- a/firmware/retro_tech_fw/user/src/config.c +++ b/firmware/retro_tech_fw/user/src/config.c @@ -31,7 +31,7 @@ static uint16_t checksum() void userconf_load() { - uint8_t csum; + uint16_t csum; eeprom_read_bytes(0, 0, (uint8_t *)&userconf, sizeof(userconf)); csum = checksum(); diff --git a/firmware/retro_tech_fw/user/src/eeprom.c b/firmware/retro_tech_fw/user/src/eeprom.c index b802777..bab313d 100644 --- a/firmware/retro_tech_fw/user/src/eeprom.c +++ b/firmware/retro_tech_fw/user/src/eeprom.c @@ -8,7 +8,7 @@ * ensure i2c bus has been configured before using these functions. */ -#define EEPROM_BASE_ADDR (0xa0 >> 1) +#define EEPROM_BASE_ADDR 0xa0 #include @@ -18,6 +18,17 @@ #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 * @@ -29,9 +40,7 @@ */ 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 |= EEPROM_BASE_ADDR; // add address to page - page <<= 1; // make i2c address from page + page = page_to_i2caddr(page); 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 * - * @brief Write one data to EEPROM. + * @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. + * @param len - Count of data to write. */ 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 |= EEPROM_BASE_ADDR; // add address to page - page <<= 1; // make i2c address from page + page = page_to_i2caddr(page); // disable systick interrupt 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; #endif - while (i2c_ack_poll(page)); + while (!i2c_addr_scan(page)); i2c_write_addr1b(page, addr, data, len); - while (i2c_ack_poll(page)); + while (!i2c_addr_scan(page)); #ifdef EEPROM_WP_PORT EEPROM_WP_PORT->BSHR = EEPROM_WP_PIN; diff --git a/firmware/retro_tech_fw/user/src/eeprom.h b/firmware/retro_tech_fw/user/src/eeprom.h index d498341..a990be4 100644 --- a/firmware/retro_tech_fw/user/src/eeprom.h +++ b/firmware/retro_tech_fw/user/src/eeprom.h @@ -15,7 +15,7 @@ #define EEPROM_WP_PORT GPIOC -#define EEPROM_WP_PIN GPIO_Pin_7 +#define EEPROM_WP_PIN GPIO_Pin_6 diff --git a/firmware/retro_tech_fw/user/src/i2c.c b/firmware/retro_tech_fw/user/src/i2c.c index f332540..a7ec75f 100644 --- a/firmware/retro_tech_fw/user/src/i2c.c +++ b/firmware/retro_tech_fw/user/src/i2c.c @@ -29,8 +29,7 @@ void i2c_init() i2c.I2C_ClockSpeed = 666666; i2c.I2C_Mode = I2C_Mode_I2C; - i2c.I2C_DutyCycle = I2C_DutyCycle_16_9; - i2c.I2C_OwnAddress1 = 0x7f; + i2c.I2C_DutyCycle = I2C_DutyCycle_2; // 16_9; i2c.I2C_Ack = I2C_Ack_Enable; i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 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--); if (!timeout) return -3; + I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_SendData(I2C1, reg); timeout = I2C_TIMEOUT; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--); if (!timeout) return -4; + I2C_AcknowledgeConfig(I2C1, ENABLE); I2C_GenerateSTART(I2C1, ENABLE); timeout = I2C_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--); if (!timeout) return -1; + I2C_AcknowledgeConfig(I2C1, ENABLE); + I2C_GenerateSTART(I2C1, ENABLE); timeout = I2C_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++); len--; 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); } -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; 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--); if (!timeout) return -2; - I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver); + I2C_Send7bitAddress(I2C1, addr, (addr & 1)); timeout = I2C_TIMEOUT_ACK_POLL; - while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) && timeout--); - if (!timeout) { - addr_match = -128; + if (addr & 1) event = I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED; + else event = I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED; + + 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); - return addr_match; + if (!found) { + return 0; + } + + return addr; } diff --git a/firmware/retro_tech_fw/user/src/i2c.h b/firmware/retro_tech_fw/user/src/i2c.h index 9cc9b13..9e68ba7 100644 --- a/firmware/retro_tech_fw/user/src/i2c.h +++ b/firmware/retro_tech_fw/user/src/i2c.h @@ -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); 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); diff --git a/firmware/retro_tech_fw/user/src/ui.c b/firmware/retro_tech_fw/user/src/ui.c index 6bb668d..c91d1b0 100644 --- a/firmware/retro_tech_fw/user/src/ui.c +++ b/firmware/retro_tech_fw/user/src/ui.c @@ -189,8 +189,9 @@ void ui_btn_release_cb(uint8_t idx) userconf.cursor_color++; userconf.cursor_color &= 0x3; - // force cursor to change immediately + // force cursor to change immediately, force cursor on cursor_flash = 0; + cursor_state = 0; config_save_timer = UI_CONF_SAVE_TIMEOUT; @@ -310,7 +311,7 @@ static void ui_cursor_flash() cursor_state++; cursor_state &= 1; - // set new cursor rate + // set new cursor rate, force cursor on cursor_flash = cursor_flash_rates[flash] >> 1; // set all colors off @@ -321,20 +322,22 @@ static void ui_cursor_flash() cursor_flash--; // set brightness of led, if we're in an on state - if (cursor_state && (color < CONF_CURSOR_OFF)) { - // first frame of on = not quite full brightness - level = (cursor_flash == cursor_flash_rates[flash] - 1) ? 160 : 255; + if (color < CONF_CURSOR_OFF) { + if (cursor_state) { + // first frame of on = not quite full brightness + level = (cursor_flash == cursor_flash_rates[flash] - 1) ? 160 : 255; - // at final frames, dim - if (cursor_flash <= 4) { - level >>= (4 - cursor_flash); + // at final frames, dim + if (cursor_flash <= 4) { + level >>= (4 - cursor_flash); + } } - } - // set the level on the cursor - if (cursor[color] != level) { - cursor[color] = led_gamma(level); - led_is_updated(); + // set the level on the cursor + if (cursor[color] != level) { + cursor[color] = led_gamma(level); + led_is_updated(); + } } } @@ -383,7 +386,7 @@ void ui_render() // deal with eeprom if (config_save_timer) { config_save_timer--; - if (config_save_timer) { + if (!config_save_timer) { userconf_save(); } }