add eeprom support, user config loading
This commit is contained in:
parent
6a4284176b
commit
d33cc2f775
|
@ -10,6 +10,9 @@
|
|||
|
||||
|
||||
|
||||
#include "global.h"
|
||||
|
||||
|
||||
#ifdef SOFT_I2C_MASTER
|
||||
|
||||
|
||||
|
@ -17,9 +20,9 @@
|
|||
|
||||
|
||||
#define i2c_init() i2cm_init()
|
||||
#define i2c_start() SetSysClock(CLK_SOURCE_PLL_32MHz); i2cm_start()
|
||||
#define i2c_start() SetSysClock(SYSCLK_FREQ_USEI2C); i2cm_start()
|
||||
#define i2c_restart() i2cm_restart()
|
||||
#define i2c_stop() SetSysClock(CLK_SOURCE_HSE_16MHz); i2cm_stop()
|
||||
#define i2c_stop() SetSysClock(SYSCLK_FREQ_NORMAL); i2cm_stop()
|
||||
#define i2c_rd(ack) i2cm_rd(ack)
|
||||
#define i2c_wr(dat) i2cm_wr(dat)
|
||||
#define i2c_addr(a, w) i2c_start(); i2cm_addr(a, w)
|
||||
|
|
|
@ -123,7 +123,7 @@ uint8_t i2cm_wr(uint8_t dat)
|
|||
|
||||
for (x = 8; x; x--) {
|
||||
if (dat & 0x80) { SDA_IN_HI(); SCL_IN_HI(); wr_delay_hi(); }
|
||||
else { SDA_OUTLO(); SCL_OUTLO(); wr_delay_lo(); }
|
||||
else { SDA_OUTLO(); SCL_OUTLO(); wr_delay_lo(); }
|
||||
|
||||
dat <<= 1;
|
||||
SCL_OUTLO();
|
||||
|
@ -149,7 +149,7 @@ uint8_t i2cm_addr(uint8_t addr, uint8_t reading_bit)
|
|||
|
||||
void i2cm_rdbuf(uint8_t *dat, uint8_t len)
|
||||
{
|
||||
while(len--) *dat++ = i2cm_rd(len > 0);
|
||||
while (len--) *dat++ = i2cm_rd(len > 0);
|
||||
// i2cm_stop();
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ void i2cm_wrbuf(const uint8_t *dat, uint8_t len)
|
|||
{
|
||||
uint8_t nack;
|
||||
|
||||
while(len--) {
|
||||
while (len--) {
|
||||
nack = i2cm_wr(*dat++);
|
||||
if (nack) break;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
|
||||
|
||||
|
||||
#define SYSCLK_FREQ_NORMAL CLK_SOURCE_HSE_16MHz
|
||||
#define SYSCLK_FREQ_USEI2C CLK_SOURCE_PLL_32MHz
|
||||
|
||||
|
||||
|
||||
extern const uint8_t vers[];
|
||||
|
||||
extern uint8_t cpu_use;
|
||||
|
|
|
@ -1,8 +1,56 @@
|
|||
/*
|
||||
* eeprom16.c
|
||||
*
|
||||
* Created on: Oct 11, 2024
|
||||
* Author: true
|
||||
* code to interface with 16-bit addressed I2C EEPROMs
|
||||
* tested up to max size of 512Kbit (64Kbyte)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "eeprom16.h"
|
||||
#include "comm/i2c.h"
|
||||
|
||||
|
||||
uint8_t e16_read_byte(uint16_t addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void e16_read(uint16_t addr, uint8_t *dat, uint32_t len)
|
||||
{
|
||||
if (len > EEPROM_SIZE) return;
|
||||
|
||||
i2c_start();
|
||||
i2c_addr(EEPROM_I2C_ADDR, 0);
|
||||
i2c_wr(addr >> 8);
|
||||
i2c_wr(addr & 0xff);
|
||||
i2c_restart();
|
||||
i2c_addr(EEPROM_I2C_ADDR, 1);
|
||||
|
||||
while (len--) *dat++ = i2cm_rd(len > 0);
|
||||
|
||||
i2c_stop();
|
||||
}
|
||||
|
||||
void e16_write(uint16_t addr, uint8_t *dat, uint16_t len)
|
||||
{
|
||||
uint8_t nack;
|
||||
|
||||
// this function can only write one page at a time
|
||||
if (len > EEPROM_PAGE_SIZE) return;
|
||||
|
||||
// this function does not detect page boundaries.
|
||||
// it is your responsibility to correctly address for
|
||||
// page boundaries. most eeprom roll over page boundaries.
|
||||
|
||||
i2c_start();
|
||||
i2c_addr(EEPROM_I2C_ADDR, 0);
|
||||
i2c_wr(addr >> 8);
|
||||
i2c_wr(addr & 0xff);
|
||||
|
||||
while (len--) {
|
||||
nack = i2cm_wr(*dat++);
|
||||
if (nack) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,4 +10,20 @@
|
|||
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
#define EEPROM_I2C_ADDR 0xa0
|
||||
|
||||
#define EEPROM_SIZE 65536
|
||||
#define EEPROM_PAGE_SIZE 128
|
||||
|
||||
|
||||
|
||||
void e16_read(uint16_t addr, uint8_t *dat, uint32_t len);
|
||||
void e16_write(uint16_t addr, uint8_t *dat, uint16_t len);
|
||||
|
||||
|
||||
|
||||
#endif /* USER_DEVICE_EEPROM16_H_ */
|
||||
|
|
|
@ -26,14 +26,33 @@
|
|||
#include <hw/ch32sub.h>
|
||||
#include "CH59x_common.h"
|
||||
|
||||
#include "port_intr.h"
|
||||
|
||||
#include "comm/i2c.h"
|
||||
|
||||
#include "hw/gat/gat_gpio.h"
|
||||
|
||||
#include "led/rgbled.h"
|
||||
|
||||
#include "misc/accel.h"
|
||||
|
||||
#include "global.h"
|
||||
#include "port_intr.h"
|
||||
#include "user_config.h"
|
||||
|
||||
|
||||
|
||||
const uint8_t vers[] = "241013.01";
|
||||
|
||||
uint8_t cpu_use = 0;
|
||||
uint8_t cpu_max = 0;
|
||||
|
||||
uint32_t uptime = 0;
|
||||
uint16_t uptime_hour;
|
||||
uint8_t uptime_min;
|
||||
uint8_t uptime_sec;
|
||||
|
||||
uint32_t idle_time_menu;
|
||||
uint32_t idle_time_still;
|
||||
uint8_t idle_go_sleep;
|
||||
|
||||
|
||||
|
||||
|
@ -47,33 +66,43 @@ int main()
|
|||
{
|
||||
// configure clock
|
||||
ch59x_xtal_conf();
|
||||
SetSysClock(CLK_SOURCE_PLL_32MHz);
|
||||
SetSysClock(SYSCLK_FREQ_USEI2C);
|
||||
|
||||
// enable DC-DC converter; brings significant power saving
|
||||
PWR_DCDCCfg(ENABLE);
|
||||
|
||||
// get i2c up and running
|
||||
// get i2c initialized since most stuff will need it
|
||||
i2c_init();
|
||||
|
||||
// decrease clock speed when not using i2c
|
||||
SetSysClock(CLK_SOURCE_HSE_16MHz);
|
||||
// read the user config
|
||||
uconf_load();
|
||||
|
||||
// configure port-based interrupts (used for chsub interrupt, mainly)
|
||||
port_intr_init();
|
||||
|
||||
// configure aux MCU initial settings, attention interrupt
|
||||
// initialize aux MCU
|
||||
ch32sub_init();
|
||||
// and enable RGBLED controller hardware pin so the controller can wake up
|
||||
ch32sub_rgb_hwen(1);
|
||||
|
||||
// configure RGBLED controller
|
||||
// initialize accelerometer
|
||||
accel_init();
|
||||
|
||||
// initialize RGBLED controller
|
||||
rgbled_init();
|
||||
|
||||
// configure GAT aux GPIOs, get gat ID
|
||||
gat_gpio_init();
|
||||
// configure GAT i2c slave
|
||||
// not yet implemented
|
||||
|
||||
// configure port-based interrupts (used for ch32sub interrupt)
|
||||
port_intr_init();
|
||||
|
||||
// note that system clock speed is decreased after every use of I2C
|
||||
|
||||
while(1) {
|
||||
// only care about aux MCU when all other processing is done
|
||||
ch32sub_process();
|
||||
|
||||
// sleep when we're doing nothing
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,14 +73,14 @@ static void uconf_defaults()
|
|||
|
||||
static int8_t uconf_validate()
|
||||
{
|
||||
// blank check
|
||||
if (uconf.checksum == 0xffff) return -1;
|
||||
|
||||
// version check
|
||||
if (uconf.ver != UCONF_VER) {
|
||||
return -1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
// blank check
|
||||
if (uconf.checksum == 0xffff) return -2;
|
||||
|
||||
// checksum verify
|
||||
if (!checksum_verify((uint8_t *)&uconf, sizeof(uconf) - 2, uconf.checksum)) {
|
||||
return -3;
|
||||
|
@ -96,20 +96,16 @@ void uconf_load()
|
|||
{
|
||||
uint8_t i;
|
||||
|
||||
w25q_power_up();
|
||||
|
||||
for (i = 0; i < FLASH_RSVD_PAGES; i++) {
|
||||
// find last page of valid config from flash
|
||||
uconf_flash_offset = (FLASH_RSVD_PAGES - 1) - i;
|
||||
w25q_read(uconf_flash_offset * FLASH_UCONF_BYTES, (uint8_t *)&uconf, FLASH_UCONF_BYTES);
|
||||
e16_read(uconf_flash_offset * FLASH_UCONF_BYTES, (uint8_t *)&uconf, FLASH_UCONF_BYTES);
|
||||
if (!uconf_validate()) {
|
||||
// valid data
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
w25q_power_down();
|
||||
|
||||
// flash has no valid data whatsoever
|
||||
// don't worry about flash setup; that is done during writing
|
||||
uconf_flash_offset = 0xf0;
|
||||
|
@ -118,16 +114,22 @@ void uconf_load()
|
|||
|
||||
void uconf_write()
|
||||
{
|
||||
eclic_global_interrupt_disable();
|
||||
uint32_t intr;
|
||||
|
||||
w25q_power_up();
|
||||
uint16_t fsize;
|
||||
uint16_t faddr;
|
||||
uint8_t *uaddr;
|
||||
|
||||
|
||||
SYS_DisableAllIrq(&intr);
|
||||
|
||||
// track writes and set up next page to write
|
||||
uconf.iter++;
|
||||
uconf_flash_offset++;
|
||||
if (uconf_flash_offset >= FLASH_RSVD_PAGES) {
|
||||
// we need to erase flash and start writing at the beginning
|
||||
w25q_erase_sector(0x000000, 1);
|
||||
// w25q_erase_sector(0x000000, 1);
|
||||
|
||||
uconf_flash_offset = 0;
|
||||
}
|
||||
|
||||
|
@ -135,9 +137,17 @@ void uconf_write()
|
|||
uconf.checksum = checksum_gen((uint8_t *)&uconf, sizeof(uconf) - 2);
|
||||
|
||||
// write config data
|
||||
w25q_write(uconf_flash_offset * FLASH_UCONF_BYTES, (uint8_t *)&uconf, FLASH_UCONF_BYTES);
|
||||
fsize = FLASH_UCONF_BYTES;
|
||||
faddr = uconf_flash_offset * FLASH_UCONF_BYTES;
|
||||
uaddr = (uint8_t *)&uconf;
|
||||
|
||||
w25q_power_down();
|
||||
while (fsize) {
|
||||
e16_write(faddr, uaddr, (fsize > 128) ? 128 : fsize);
|
||||
if (fsize < 128) break;
|
||||
fsize -= 128;
|
||||
faddr += 128;
|
||||
uaddr += 128;
|
||||
}
|
||||
|
||||
eclic_global_interrupt_enable();
|
||||
SYS_RecoverIrq(intr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue