Compare commits

..

No commits in common. "56cd06876a321ee3a6b421a7bbbee2be20ca0d9a" and "64ce976b97af76024fe18b8321e3f9f39e77d667" have entirely different histories.

25 changed files with 211 additions and 324 deletions

View File

@ -152,9 +152,6 @@ SECTIONS
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
*(.ramfunc)
*(.ramfunc*)
. = ALIGN(4);
PROVIDE( _edata = .);
} >RAM AT>FLASH

View File

@ -1,41 +1,30 @@
/*
* soft_i2c.c
*
* looked at random i2c code, used as inspiration, and wrote some
* garbage for CH59x.
* looked at random code and fixed it up for CH59x.
*
* i2c hardware peripheral on CH59x is shared with debug pins.
* i2c hw is also not attached to DMA. while using the peripheral
* even in interrupt mode would result in higher speeds and less
* power consumption, living without debug is worse.
* also, i2c on CH59x is not attached to DMA. while using the
* peripheral would result in higher speeds and less power usage,
* living without debug is worse. maybe I'll use hw i2c later.
*
* quirks and features:
* - this implementation is blocking.
* - clock stretching is supported, and somewhat tested
*
* known good settings:
* CYCLES_TO_HI = 5, CYCLES_TO_LOW = 2: ~400-500kHz
* CYCLES_TO_HI = 2, CYCLES_TO_LOW = 0: ~650KHz
* - partial clock stretching is supported
* (only during start of write, and within read phase).
* - timings likely haven't been tested so long as this message exists.
*/
#include <CH59x_common.h>
#include <stdint.h>
#define CYCLES_TO_HI 2
#define CYCLES_TO_LO 0
#define CYCLES_TO_HI 5 // these settings will result in ~500KHz (32MHz HCLK)
#define CYCLES_TO_LO 2
//#define CYCLES_RD 2 // cycles spent in read routine
//#define CYCLES_WR_HI 2 // extra cycles spent in write routine
//#define CYCLES_WR_LO 4
#define bit_delay_hi() { spin = delay_hi; while(spin--); }
#define bit_delay_lo() { spin = delay_lo; while(spin--); }
#define rd_delay() bit_delay_hi()
#define wr_delay_hi() bit_delay_hi()
#define wr_delay_lo() bit_delay_hi() // spin = delay_hi - CYCLES_EXTRA_WR_HI; while(spin--)
#define CYCLES_RD 2 // cycles spent in read routine
#define CYCLES_WR_HI 2 // extra cycles spent in write routine
#define CYCLES_WR_LO 4
#define SDA_PIN 4
@ -70,6 +59,14 @@ static uint16_t delay_hi, delay_lo;
static volatile uint16_t spin;
#define bit_delay_hi() spin = delay_hi; while(spin--)
#define bit_delay_lo() spin = delay_lo; while(spin--)
#define rd_delay() bit_delay_hi()
#define wr_delay_hi() bit_delay_hi()
#define wr_delay_lo() bit_delay_hi() // spin = delay_hi - CYCLES_EXTRA_WR_HI; while(spin--)
// re-run init any time the clock speed changes to recalculate delays.
@ -107,7 +104,6 @@ void i2cm_restart()
{
SDA_IN_HI(); bit_delay_hi();
SCL_IN_HI();
while (!SCL_GET()); // clock stretch
i2cm_start();
}
@ -128,8 +124,7 @@ void i2cm_stop()
__attribute__((section(".ramfunc")))
uint8_t i2cm_rd(uint8_t ack)
{
int8_t x;
uint8_t in = 0;
uint8_t x, in = 0;
SDA_IN_HI();
@ -143,13 +138,15 @@ uint8_t i2cm_rd(uint8_t ack)
if (SDA_GET()) in |= 1;
SCL_OUTLO(); bit_delay_lo();
SCL_OUTLO();
}
if (ack) { SDA_OUTLO(); } // ack
else { SDA_IN_HI(); } // nack
SCL_IN_HI(); bit_delay_hi();
SDA_IN_HI();
SCL_OUTLO(); bit_delay_lo();
return in;
@ -159,7 +156,7 @@ uint8_t i2cm_rd(uint8_t ack)
__attribute__((section(".ramfunc")))
uint8_t i2cm_wr(uint8_t dat)
{
int8_t x;
uint8_t x;
uint8_t ack;
SCL_OUTLO();
@ -168,9 +165,8 @@ uint8_t i2cm_wr(uint8_t dat)
if (dat & 0x80) { SDA_IN_HI(); }
else { SDA_OUTLO(); }
SCL_IN_HI();
SCL_IN_HI(); wr_delay_hi();
while (!SCL_GET()); // clock stretch
wr_delay_hi();
dat <<= 1;
@ -183,7 +179,6 @@ uint8_t i2cm_wr(uint8_t dat)
ack = SDA_GET();
SCL_OUTLO(); bit_delay_lo();
return ack;
}
@ -191,7 +186,7 @@ uint8_t i2cm_wr(uint8_t dat)
__attribute__((section(".ramfunc")))
uint8_t i2cm_addr(uint8_t addr, uint8_t reading_bit)
{
addr &= 0xfe;
addr &= ~0x1;
addr |= reading_bit ? 1 : 0;
return i2cm_wr(addr);
}

View File

@ -12,16 +12,15 @@
#define SYSCLK_FREQ_NORMAL CLK_SOURCE_PLL_48MHz // CLK_SOURCE_HSE_16MHz
#define SYSCLK_FREQ_NORMAL CLK_SOURCE_HSE_16MHz
#define SYSCLK_FREQ_USEI2C CLK_SOURCE_PLL_32MHz
#define SYSCLK_FREQ_IDLE CLK_SOURCE_HSE_8MHz
extern const uint8_t vers[];
extern uint16_t cpu_pct;
extern uint16_t cpu_pct_max;
extern uint8_t cpu_use;
extern uint8_t cpu_max;
extern uint32_t uptime;
extern uint16_t uptime_hour;

View File

@ -68,7 +68,11 @@ void aw20x_init(struct AW20x *aw, uint8_t addr, uint8_t cols, uint8_t rows, uint
aw->rows = rows;
aw->config = imax & AW20X_CONF_IMAX_MASK;
// wake up (and set page to config page)
// ensure we are on page 0 to start
aw20x_page(aw, 0);
while (AW20X_I2C_busy());
// wake up
aw20x_sleep(aw, 0);
// enabled columns
@ -180,10 +184,9 @@ void aw20x_led_on(struct AW20x *aw, uint8_t first, uint8_t last, uint8_t on_bit)
}
/*
* enables LEDs based on user LED count, zero-indexed
* assumes AW20X_MAX_LEDON_BITS per row but will only turn on active defined rows
* AW20036 would be 0-35, but AW20054 would be 0-71 and so on
* for example, LEDs 8-12 on AW20054 with 9 roww enabled
* would enable C0R8, C1R0, C1R1, C1R2. all other LEDs are disabled
* AW20036 would be 0-35, AW00054 would be 0-53, and so on
* for example, LEDs 8-12 on AW20054 would enable C0R8, C1R0, C1R1, C1R2
* all other LEDs are disabled
*
* todo:
* - read current state, and apply bitfields to the currently active state
@ -193,7 +196,7 @@ void aw20x_led_on(struct AW20x *aw, uint8_t first, uint8_t last, uint8_t on_bit)
void aw20x_led_enable_range(struct AW20x *aw, uint8_t first, uint8_t last)
{
uint8_t c, r;
uint8_t idx;
uint8_t offset = 0;
uint8_t boff;
uint8_t *buf;
@ -205,25 +208,24 @@ void aw20x_led_enable_range(struct AW20x *aw, uint8_t first, uint8_t last)
// bits are stored 6 bits per byte, 2 bytes per column, one bit for each row
// for a maximum of the AW20X_MAX_ROWS of LED on bits
// we only want to touch bits that exist on the chip and in the correct order
idx = 0;
for (c = 0; c < aw->cols; c++) {
buf = &aw_buf[c*2];
buf[0] = buf[1] = 0;
boff = 0;
for (r = 0; r < AW20X_MAX_LEDON_BITS*2; r++) {
if (r + idx < first) continue; // only start at the first led
if (r + idx > last) break; // and stop at the last
if (r >= aw->rows) continue; // max bits to process per row
if (r >= aw->rows) break; // max bits to process
if (r == AW20X_MAX_LEDON_BITS) { // only this many bits per byte
boff += AW20X_MAX_LEDON_BITS;
buf++;
}
*buf |= (1 << r - boff);
if (r+offset >= first) {
if (r+offset <= last) {
*buf |= (1 << r - boff);
}
}
}
idx += AW20X_MAX_LEDON_BITS*2;
offset += aw->rows;
}
AW20X_I2C_writereg(aw->addr, AW20X_REG_LEDON0, aw_buf, c*2);

View File

@ -19,9 +19,9 @@
volatile uint8_t intr_pending = 0;
volatile uint8_t intr_flag = 0;
static void (*intr_cb[8])() = {
static void (*flag_cb[8])() = {
btn_intr,
0,
0,
@ -34,71 +34,38 @@ static void (*intr_cb[8])() = {
__HIGH_CODE
void ch32sub_read(uint16_t reg, uint8_t *dat, uint8_t len)
{
i2c_read_reg16(SUB_I2C_ADDR, reg, dat, len);
}
__HIGH_CODE
void ch32sub_write(uint16_t reg, uint8_t *dat, uint8_t len)
{
i2c_write_reg16(SUB_I2C_ADDR, reg, dat, len);
}
__HIGH_CODE
uint8_t ch32sub_read_1b(uint16_t reg)
{
uint8_t ret;
ch32sub_read(reg, &ret, 1);
return ret;
}
__HIGH_CODE
void ch32sub_write_1b(uint16_t reg, uint8_t dat)
{
i2c_addr(SUB_I2C_ADDR, 0);
i2c_wr(reg >> 8);
i2c_wr(reg & 0xff);
i2c_wr(dat);
i2c_stop();
}
void ch32sub_isr()
{
intr_pending = 1;
// we'll check what the MCU has to say when we're done processing
intr_flag = 1;
}
void ch32sub_process()
{
uint8_t flags;
uint8_t clear = 0;
uint8_t i;
if (intr_pending) {
intr_pending = 0;
if (intr_flag) {
intr_flag = 0;
flags = 1;
// get flags
flags = ch32sub_read_1b(REG_INTR_FLAGS);
// get interrupt flags
i2c_read_reg16(SUB_I2C_ADDR, REG_INTR_FLAGS, &flags, 1);
// process flags
for (i = 0; i < 8; i++) {
if (flags & (1 << i)) {
if (intr_cb[i]) {
clear |= (i << 1);
intr_cb[i]();
}
else {
// unhandled interrupt; clear it?
// ch32sub_write_1b(REG_INTR_FLAGS, i << 1);
while (flags) {
for (i = 0; i < 8; i++) {
if (intr_flag & (1 << i)) {
if (flag_cb[i]) flag_cb[i]();
else {
// unhandled interrupt; clear it
// ch32sub_write_1b(REG_INTR_FLAGS, i << 1);
}
}
}
}
// clear flags
ch32sub_write_1b(REG_INTR_FLAGS_CLEAR, clear);
// get interrupt flags (again)
i2c_read_reg16(SUB_I2C_ADDR, REG_INTR_FLAGS, &flags, 1);
}
}
}
@ -114,29 +81,31 @@ void ch32sub_init()
// note: this is handled as "high priority" within the interrupt handler now.
// port_intr_cb_register(PORT_INTR_GPIOB, SUB_INTR_PIN_NR, ch32sub_isr);
// clear any interrupts now, to start from clean slate
ch32sub_write_1b(REG_INTR_FLAGS_CLEAR, 0xff);
}
// things to do
void ch32sub_read(uint16_t reg, uint8_t *dat, uint8_t len)
{
i2c_read_reg16(SUB_I2C_ADDR, reg, dat, len);
}
void ch32sub_write(uint16_t reg, uint8_t *dat, uint8_t len)
{
i2c_write_reg16(SUB_I2C_ADDR, reg, dat, len);
}
void ch32sub_write_1b(uint16_t reg, uint8_t dat)
{
i2c_start();
i2c_addr(SUB_I2C_ADDR, 0);
i2c_wr(reg >> 8);
i2c_wr(reg & 0xff);
i2c_wr(dat);
i2c_stop();
}
void ch32sub_rgb_hwen(uint8_t en)
{
ch32sub_write_1b(REG_RGB_HWEN, en);
}
void ch32sub_intr_defaults()
{
int8_t i;
uint8_t dat[5];
// we want interrupted for all button events
for (i = 0; i < 5; i++) {
dat[i] = BTN_PUSH | BTN_HOLD | BTN_RELEASE;
}
// enable button interrupt sources
ch32sub_write(REG_BTN1_INT_ENABLE, dat, 5);
// enable all interrupt flags we care about
dat[0] = INT_BTN | INT_UTX_DONE | INT_UTX_TIMEOUT | INT_UTX_ERROR | INT_URX_RCVD;
ch32sub_write_1b(REG_INTR_ENABLE, dat[0]);
}

View File

@ -97,12 +97,6 @@ enum ch32sub_regmap {
};
#define BTN_PUSH (1 << 0)
#define BTN_HOLD (1 << 1)
#define BTN_RELEASE (1 << 2)
#define BTN_IGNORE (1 << 3)
void ch32sub_init();
void ch32sub_isr();
@ -112,7 +106,6 @@ void ch32sub_read(uint16_t reg, uint8_t *dat, uint8_t len);
void ch32sub_write(uint16_t reg, uint8_t *dat, uint8_t len);
void ch32sub_write_1b(uint16_t reg, uint8_t dat);
void ch32sub_intr_defaults();
void ch32sub_rgb_hwen(uint8_t en);

View File

@ -19,13 +19,14 @@ 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_wr(EEPROM_I2C_ADDR | 1);
i2c_addr(EEPROM_I2C_ADDR, 1);
while (len--) *dat++ = i2c_rd(len > 0);
while (len--) *dat++ = i2cm_rd(len > 0);
i2c_stop();
}
@ -41,16 +42,15 @@ void e16_write(uint16_t addr, uint8_t *dat, uint16_t len)
// 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 = i2c_wr(*dat++);
nack = i2cm_wr(*dat++);
if (nack) break;
}
i2c_stop();
}

View File

@ -8,11 +8,6 @@
* - GP1 has UART0 TX and PWM9.
* - GP2 has UART0 RX and PWM7.
*
* errata:
* - bottom board marked REV3 has addon header mirrored.
* to manufacture this, GAT GPIO is cut and inoperable.
* todo: add strapping GPIO check to determine board version.
*
*/

View File

@ -61,11 +61,10 @@ void rgbled_init()
{
volatile uint32_t x;
// make sure the hardware pin is on before calling.
ch32sub_rgb_hwen(1);
// wait a little while to ensure controller is awake
x = GetSysClock() / 131072;
x = GetSysClock() / 16384;
while (x--);
// clear fade
@ -77,7 +76,7 @@ void rgbled_init()
aw20x_set_dim_global(&awled, AW20X_DIM);
aw20x_set_fade(&awled);
aw20x_led_enable_range(&awled, 0, 47); // 9x4, but need to send 12x4
aw20x_led_enable_range(&awled, 0, 23);
}
void rgbled_flag_update()
@ -105,14 +104,8 @@ void rgbled_send()
void rgbled_runprog(uint8_t tick_ctr)
{
uint8_t idx = uconf.ledprog_rgb_idx;
// run program
if (rgb_pgm[idx].prog) {
// render
rgb_pgm[idx].prog(uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx], tick_ctr);
// and for now, always force an update
led_matrix_needs_update = 1;
if (rgb_pgm[uconf.ledprog_rgb_idx].prog) {
rgb_pgm[uconf.ledprog_rgb_idx].prog(uconf.ledprog_rgb_data[uconf.ledprog_rgb_idx], tick_ctr);
}
}

View File

@ -43,25 +43,20 @@
// global settings
#define OLED_UPDATE_RATE 13 // framerate of OLED; { (256*(8/8)) / OLED_UPDATE_RATE }; 13 = 19FPS
#define OLED_UPDATE_RATE 8 // framerate of OLED; (256*(6/8)) / OLED_UPDATE_RATE; 8 = 24FPS
// flags
#define FLAG_OLED_UPDATE (1 << 0)
#define FLAG_RGBLED_RUN_PROG (1 << 1)
#define FLAG_PROG_TICK_INTR (1 << 7)
#define FLAG_RESET_SYSTICK (1 << 6)
#define PROG_TICK_RATE ((32768 / 256) - 1)
#define PROG_TICK_RATE (32768 / 256)
const uint8_t vers[] = "241015a";
uint32_t cpu_use = 0;
uint32_t cpu_max = 0;
uint16_t cpu_pct = 0;
uint16_t cpu_pct_max = 0;
uint8_t cpu_use = 0;
uint8_t cpu_max = 0;
uint32_t uptime = 0;
uint16_t uptime_hour;
@ -72,10 +67,9 @@ uint32_t idle_time_menu;
uint32_t idle_time_still;
uint8_t idle_go_sleep;
static volatile uint8_t flags_lo = 0;
static uint8_t flags_hi = FLAG_RESET_SYSTICK;
static volatile uint8_t flags = 0;
static uint8_t st_tick = 0; // program tick counter
static uint8_t st_tick = 0; // systick loop counter
static uint8_t oled_tick = 0; // oled framerate counter
@ -113,22 +107,17 @@ void rtc_reset_trig()
void rtcisr_init()
{
LClk32K_Cfg(Clk32K_LSI, ENABLE); // enable internal oscillator
Calibration_LSI(Level_128); // calibrate LSI fromm HSE
LClk32K_Cfg(Clk32K_LSI, ENABLE); // enable internal oscillator
Calibration_LSI(Level_128); // calibrate LSI fromm HSE
rtc_reset_trig();
PFIC_EnableIRQ(RTC_IRQn);
}
void systick_init(void)
{
SysTick->CNT = 0; // clear counter
SysTick->CTLR = SysTick_CTLR_STCLK | SysTick_CTLR_STE; // enable counter in /1 mode
}
__HIGH_CODE
void oled_update_done()
{
int16_t a;
int8_t rot;
// reset oled callback, clear screen, and set default pixel mode and font size
@ -164,7 +153,6 @@ void oled_update_done()
#ifdef MENU_TIMEOUT_TO_NAMETAG
// root menu idle counting
// note: untested.
if (menu == &menu_0) {
if (!idle_time_menu) {
idle_time_menu = uptime;
@ -179,37 +167,87 @@ void oled_update_done()
}
#endif
// render menu
// do menu operations
menu_tick();
// calculate CPU usage
cpu_pct = (cpu_use * 100) / cpu_max;
if (cpu_pct > cpu_pct_max) cpu_pct_max = cpu_pct;
// note: we just consider missed ticks a percent.
// it's actually more like a tenth. fuck it.
// a = missed;
// todo: implement this
a = 0;
if (uconf.framemod == UCONF_FRAMERATE_HALF) {
// the above calculation is tied to framerate.
// so this will compensate for half framerate mode...
a >>= 1;
}
if (a > cpu_max) {
cpu_max = a;
}
cpu_use = a;
// reset missed interrupt counter
// missed = 0;
}
__HIGH_CODE
void lowprio_task() {
uint32_t interrupt_flags;
while (1) {
int main()
{
// configure clock
ch59x_xtal_conf();
SetSysClock(SYSCLK_FREQ_USEI2C);
// note that system clock speed is decreased after every use of I2C.
// enable DC-DC converter; brings significant power saving
PWR_DCDCCfg(ENABLE);
// get i2c initialized since most stuff will need it
i2c_init();
// read the user config
uconf_load();
// initialize aux MCU
ch32sub_init();
// and enable RGBLED controller hardware pin so the controller can wake up
ch32sub_rgb_hwen(1);
// 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();
// start up the OLED and menu system
ssd1306fb_set_target(&oled);
ssd1306_init(1); // we'll try to init later too, since sometimes they fail
menu_stop(0); // lol. yes, this "starts" the "menu" in nametag mode
// configure main program tick interrupt
rtcisr_init();
while(1) {
// sleep when we're doing nothing
if (!flags_lo) {
__WFI();
}
__WFI();
// disable all IRQs when doing any I2C related stuff, as interrupts
// can corrupt transactions
SYS_DisableAllIrq(&interrupt_flags);
// temporary: enable sub interrupts
ch32sub_intr_defaults();
// process sub MCU interrupt, if pending
// only care about aux MCU when all other processing is done
ch32sub_process();
// send the last oled frame data
if (flags_lo & FLAG_OLED_UPDATE) {
flags_lo &= ~FLAG_OLED_UPDATE;
if (flags & FLAG_OLED_UPDATE) {
flags &= ~FLAG_OLED_UPDATE;
/*** oled ***/
if (oled.callback && !(oled.state & SSD1306_STATE_BUSY)) {
@ -229,90 +267,24 @@ void lowprio_task() {
}
}
// send the RGBLED data
// todo
// capture CPU use
if (flags_lo & FLAG_PROG_TICK_INTR) {
flags_lo &= ~FLAG_PROG_TICK_INTR;
flags_hi |= FLAG_RESET_SYSTICK;
cpu_use = SysTick->CNT;
}
// re-enable IRQs
SYS_RecoverIrq(interrupt_flags);
// render new rgbled frame
if (flags_lo & FLAG_RGBLED_RUN_PROG) {
flags_lo &= ~FLAG_RGBLED_RUN_PROG;
// render new OLED frame
if (flags & FLAG_RGBLED_RUN_PROG) {
flags &= ~FLAG_RGBLED_RUN_PROG;
rgbled_runprog(st_tick);
}
// drop into lower clock rate
SetSysClock(SYSCLK_FREQ_IDLE);
}
}
int main()
{
// configure clock
ch59x_xtal_conf();
SetSysClock(SYSCLK_FREQ_USEI2C);
// note that system clock speed is decreased after every use of I2C.
PWR_DCDCCfg(ENABLE); // enable DC-DC converter; brings significant power saving
i2c_init(); // get i2c initialized since most stuff will need it
uconf_load(); // read the user config
ch32sub_init(); // initialize aux MCU
ch32sub_rgb_hwen(1); // and enable RGBLED controller hardware pin so the controller can wake up
accel_init(); // initialize accelerometer
rgbled_init(); // initialize RGBLED controller
gat_gpio_init(); // configure GAT aux GPIOs, get gat ID
// todo: implement // configure GAT i2c slave
ssd1306fb_set_target(&oled); // start up the OLED and menu system
ssd1306_init(1); // we'll try to init later too, since sometimes OLED fails to init
menu_stop(0); // lol. yes, this "starts" the "menu" in nametag mode
systick_init(); // start up the system tick, used for CPU percentage calculation
cpu_max = GetSysClock() / PROG_TICK_RATE;
port_intr_init(); // configure port-based interrupts (used for ch32sub interrupt)
ch32sub_intr_defaults(); // configure interrupt sources on sub MCU - buttons, etc
// configure main program tick interrupt
rtcisr_init();
// start the low priority task loop
lowprio_task();
}
__INTERRUPT
__HIGH_CODE
void RTC_IRQHandler(void)
{
// clear systick for CPU usage counting
if (flags_hi & FLAG_RESET_SYSTICK) {
SysTick->CNT = 0;
flags_hi &= ~FLAG_RESET_SYSTICK;
flags_lo |= FLAG_PROG_TICK_INTR;
}
// speed up
SetSysClock(SYSCLK_FREQ_NORMAL);
// clear interrupt flag and reset RTC
rtc_reset_trig();
// manual uptime counter
st_tick++;
if (!st_tick) {
uptime++;
uptime_hour = (uint16_t)(uptime / 3600);
@ -333,18 +305,24 @@ void RTC_IRQHandler(void)
rgbled_send();
// defer rendering
flags_lo |= FLAG_RGBLED_RUN_PROG;
flags |= FLAG_RGBLED_RUN_PROG;
break;
}
case 1: {
accel_poll();
// no break
}
default: {
oled_tick++;
if (oled_tick >= OLED_UPDATE_RATE) {
oled_tick = 0;
flags |= FLAG_OLED_UPDATE;
}
}
}
oled_tick++;
if (oled_tick >= OLED_UPDATE_RATE) {
oled_tick = 0;
flags_lo |= FLAG_OLED_UPDATE;
// read accelerometer data at 32Hz
if ((st_tick & 0x7) == 0x7) {
}
}

View File

@ -33,7 +33,7 @@ int32_t accel_i2c_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t
{
(void)(handle);
i2c_write_reg8(LIS2DW_I2C_ADDR_SDO_LOW, reg, bufp, len);
i2c_write_reg8(LIS2DW_I2C_ADDR, reg, bufp, len);
return 0;
}
@ -42,7 +42,7 @@ int32_t accel_i2c_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
(void)(handle);
i2c_read_reg8(LIS2DW_I2C_ADDR_SDO_LOW, reg, bufp, len);
i2c_read_reg8(LIS2DW_I2C_ADDR, reg, bufp, len);
return 0;
}
@ -72,7 +72,7 @@ void accel_init()
timeout = 0;
accel_found = 1;
}
} while (timeout--);
} while (timeout);
}
if (accel_found) {
@ -98,7 +98,7 @@ void accel_init()
void accel_poll()
{
uint8_t reg = 1;
int16_t xyz[3];
uint16_t xyz[3];
if (!accel_found) return;
@ -110,9 +110,6 @@ void accel_poll()
// read acceleration data
memset(xyz, 0x00, 3 * sizeof(int16_t));
lis2dw12_acceleration_raw_get(&dev_ctx, xyz);
accel.x = xyz[0] >>= 8;
accel.y = xyz[1] >>= 8;
accel.z = xyz[2] >>= 8;
}
}
}

View File

@ -7,8 +7,6 @@
#include <stdint.h>
#include "tinymt.h"
#include "CH59x_common.h"
static void tinymt32_next_state(tinymt32_t *s);
@ -93,8 +91,7 @@ const uint32_t TINYMT32_MASK = UINT32_C(0x7fffffff);
* This function changes the internal state of tinymt32.
* @param s pointer to tinymt internal state.
*/
__HIGH_CODE
void tinymt32_next_state (tinymt32_t* s)
static void tinymt32_next_state (tinymt32_t* s)
{
uint32_t x;
uint32_t y;
@ -131,8 +128,7 @@ void tinymt32_next_state (tinymt32_t* s)
* @param s pointer to tinymt internal state.
* @return 32-bit unsigned pseudorandom number.
*/
__HIGH_CODE
uint32_t tinymt32_temper (tinymt32_t* s)
static uint32_t tinymt32_temper (tinymt32_t* s)
{
uint32_t t0, t1;
t0 = s->status[3];

View File

@ -43,9 +43,7 @@ void port_intr_cb_register(uint8_t port, uint8_t idx, void (*fn)(void))
void port_intr_init()
{
// clear state then enable port interrupt
R16_PB_INT_IF = 0xff;
PFIC_EnableIRQ(GPIO_B_IRQn);
// enable port interrupt
}
@ -65,8 +63,8 @@ __INTERRUPT
__HIGH_CODE
void GPIOB_IRQHandler(void)
{
//uint8_t i;
//uint8_t offset;
uint8_t i;
uint8_t offset;
uint16_t flag = R16_PB_INT_IF;
// clear flags
@ -79,7 +77,6 @@ void GPIOB_IRQHandler(void)
}
// general purpose fallback
/*
for (i = 4; i < MAX_PIN; i++) {
offset = i - 4;
if (flag & (1 << i)) {
@ -88,5 +85,4 @@ void GPIOB_IRQHandler(void)
}
}
}
*/
}

View File

@ -21,21 +21,18 @@ uint8_t btn_held;
__HIGH_CODE
void btn_push_cb(uint8_t idx)
{
btn_pushed |= (1 << idx);
if (btn[idx].cb_push) btn[idx].cb_push(idx);
}
__HIGH_CODE
void btn_hold_cb(uint8_t idx)
{
btn_held |= (1 << idx);
if (btn[idx].cb_hold) btn[idx].cb_hold(idx);
}
__HIGH_CODE
void btn_release_cb(uint8_t idx)
{
btn_pushed &= ~(1 << idx);
@ -44,7 +41,6 @@ void btn_release_cb(uint8_t idx)
}
__HIGH_CODE
void btn_commit_hold()
{
uint8_t i, x;
@ -70,7 +66,6 @@ void btn_commit_hold()
}
__HIGH_CODE
void btn_intr()
{
uint8_t i;
@ -81,8 +76,7 @@ void btn_intr()
ch32sub_read(REG_BTN_PUSHED_LATCHED, btn_state, sizeof(btn_state));
// clear button interrupt flag
// this is actually handled by the main routine so not needed here
// ch32sub_write_1b(REG_INTR_FLAGS_CLEAR, INT_BTN);
ch32sub_write_1b(REG_INTR_FLAGS_CLEAR, INT_BTN);
// process callbacks for new events
for (i = 0; i < BTN_COUNT; i++) {

View File

@ -9,15 +9,12 @@
#include <string.h>
MenuItem *menu;
uint8_t menu_idx = 0;
uint8_t mtick;
__HIGH_CODE
void menu_tick()
{
if (menu) {
@ -152,7 +149,6 @@ void menu_btn_use_none()
}
__HIGH_CODE
void menu_draw_buttons(uint8_t mode, uint8_t mask)
{
uint8_t w;
@ -278,7 +274,6 @@ void menu_draw_buttons(uint8_t mode, uint8_t mask)
}
}
__HIGH_CODE
void menu_draw_tabs(uint8_t active_idx)
{
uint8_t h;

View File

@ -95,7 +95,6 @@ static void menu_none_print_error(uint8_t *err1, uint8_t *err2, uint8_t *err3)
return;
}
__HIGH_CODE
void menu_none_disp(uint8_t idx)
{
uint8_t i, j;
@ -240,7 +239,7 @@ MENU_0_DISP_CHAR_ROTATE:
}
if (uconf.flags & UCONF_FLAGS_SHOW_CPU_USAGE) {
sprintf(txt, "%3u%%", cpu_pct);
sprintf(txt, "%3u%%", cpu_use);
ssd1306fb_set_cursor(90, 20);
ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, txt, 1);
}
@ -248,7 +247,6 @@ MENU_0_DISP_CHAR_ROTATE:
oled.state &= ~SSD1306_STATE_STR_HALFWIDTH;
}
__HIGH_CODE
void menu_0_disp(uint8_t idx)
{
char txt[12];

View File

@ -205,7 +205,6 @@ void menu_1_font_next()
} while (!font_table[uconf.font_idx].tag_allowed);
}
__HIGH_CODE
void menu_1_disp(uint8_t idx)
{
int8_t w, x;

View File

@ -220,7 +220,6 @@ void menu_2_edit_use(uint8_t idx)
}
__HIGH_CODE
void menu_2_disp(uint8_t idx)
{
int i;

View File

@ -325,8 +325,6 @@ void snek_init()
gamemode = 17;
}
__HIGH_CODE
void snek_disp(uint8_t idx)
{
// uint8_t i;

View File

@ -27,7 +27,6 @@ const uint16_t sleep_times[] = {
};
__HIGH_CODE
void menu_5_disp(uint8_t idx)
{
int8_t w, x;

View File

@ -101,7 +101,6 @@ void menu_6_btn_use()
btn_commit_hold();
}
__HIGH_CODE
void menu_6_disp(uint8_t idx)
{
uint8_t i;
@ -221,11 +220,11 @@ void menu_6_disp(uint8_t idx)
break;
}
case 5: {
sprintf(txt, "CPU Load: %3u%%", cpu_pct);
sprintf(txt, "CPU Load: %3u%%", cpu_use);
ssd1306fb_set_cursor(10, -1);
ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, txt, 1);
sprintf(txt, "CPU Max: %3u%%", cpu_pct_max);
sprintf(txt, "CPU Max: %3u%%", cpu_max);
ssd1306fb_set_cursor(10, 9);
ssd1306fb_draw_str(font_DejaVu_Sans_Mono_Bold_11, txt, 1);

View File

@ -15,7 +15,7 @@
// some global options
#define FLASH_RSVD_PAGES 8 // how many FLASH_UCONF_BYTES to reserve/check
#define FLASH_RSVD_PAGES 16 // how many FLASH_UCONF_BYTES to reserve/check
#define FLASH_UCONF_BYTES 256 // basically assumed everywhere
#define MISC_WIGGLE_RATE (7 - 4);

View File

@ -31,7 +31,6 @@ void HardFault_Handler(void)
while (1);
}
__attribute__((interrupt("WCH-Interrupt-fast")))
void SysTick_Handler(void)
{
// ---- PROCESS UI AND COMMS

View File

@ -9,8 +9,7 @@
* some notes:
* - writing does not loop; if writing to the end then new writes will cause an error interrupt.
* - added write protection for first 16 bytes.
* - the code don't send NACKs on invalid writes.
* - write registers will only commit to action upon valid I2C stop received.
* - many registers will only commit to action upon valid I2C stop received.
*
*
* register map:
@ -130,8 +129,8 @@ void i2cs_write_cb(uint16_t initial_reg, uint16_t last_reg)
// error - see i2c_slave.h for error types
void i2cs_werr_cb(uint16_t reg, uint8_t data, uint8_t error)
{
i2cs_reg[REG_WERR_LO]++;
if (!i2cs_reg[REG_WERR_LO]) i2cs_reg[REG_WERR_HI]++;
i2cs_reg[0x0d]++;
if (!i2cs_reg[0x0d]) i2cs_reg[0x0c]++;
}
// called upon every register read
@ -209,7 +208,7 @@ void I2C1_EV_IRQHandler(void)
i2cs_state.position = i2cs_state.offset; // Reset position
}
if (STAR1 & I2C_STAR1_RXNE) { // Write from master event
if (STAR1 & I2C_STAR1_RXNE) { // Write event
if (i2cs_state.first_write == 2) { // low address byte written; set the offset
i2cs_state.offset = i2cs_state.offset | I2C1->DATAR;
i2cs_state.position = i2cs_state.offset;
@ -241,7 +240,7 @@ void I2C1_EV_IRQHandler(void)
}
}
if (STAR1 & I2C_STAR1_TXE) { // Read to master event
if (STAR1 & I2C_STAR1_TXE) { // Read event
i2cs_state.writing = 0;
if (i2cs_state.position < i2cs_state.reg_len) {
I2C1->DATAR = i2cs_state.reg_file[i2cs_state.position];
@ -263,7 +262,6 @@ void I2C1_EV_IRQHandler(void)
}
}
__attribute__((interrupt("WCH-Interrupt-fast")))
void I2C1_ER_IRQHandler(void)
{
uint16_t STAR1 = I2C1->STAR1;

View File

@ -140,7 +140,6 @@ int main(void)
exti_nvic_init();
// configure systick
systick_init();
while (1) {
__WFI();