diff --git a/nametag8_CH592/user/comm/soft_i2c_master.c b/nametag8_CH592/user/comm/soft_i2c_master.c index 08cf317..befa36b 100644 --- a/nametag8_CH592/user/comm/soft_i2c_master.c +++ b/nametag8_CH592/user/comm/soft_i2c_master.c @@ -9,20 +9,25 @@ * even in interrupt mode would result in higher speeds and less * power consumption, living without debug is worse. * - * quirks and features: + * quirks, features and limitations: * - this implementation is blocking. * - clock stretching is supported, and somewhat tested + * - any slave stuck clock stretching will lock everything until released; + * there is no timeout or cancel operation implemented * - * known good settings: + * known good settings at 32MHz: * CYCLES_TO_HI = 5, CYCLES_TO_LOW = 2: ~400-500kHz * CYCLES_TO_HI = 2, CYCLES_TO_LOW = 0: ~650KHz + * CYCLES_TO_HI = 1, bit_delay_lo = __nop: ~900KHz, but sub MCU fails to respond + * */ #include #include -#define CYCLES_TO_HI 2 + +#define CYCLES_TO_HI 3 #define CYCLES_TO_LO 0 //#define CYCLES_RD 2 // cycles spent in read routine @@ -66,8 +71,6 @@ static uint16_t delay_hi, delay_lo; - - static volatile uint16_t spin; @@ -108,6 +111,8 @@ void i2cm_restart() SDA_IN_HI(); bit_delay_hi(); SCL_IN_HI(); while (!SCL_GET()); // clock stretch + bit_delay_hi(); // wait a little bit + bit_delay_hi(); // sub MCU can corrupt data if we don't wait i2cm_start(); } @@ -122,6 +127,8 @@ void i2cm_stop() bit_delay_hi(); bit_delay_hi(); bit_delay_hi(); + bit_delay_hi(); + bit_delay_hi(); } // returns: data byte diff --git a/nametag8_CH592/user/main.c b/nametag8_CH592/user/main.c index 9cd2389..2f12138 100644 --- a/nametag8_CH592/user/main.c +++ b/nametag8_CH592/user/main.c @@ -33,6 +33,7 @@ #include "led/rgbled.h" #include "misc/accel.h" +#include "misc/tinymt.h" #include "ui/menu.h" #include "ui/oled.h" @@ -43,18 +44,17 @@ // global settings -#define OLED_UPDATE_RATE 13 // framerate of OLED; { (256*(8/8)) / OLED_UPDATE_RATE }; 13 = 19FPS +#define OLED_UPDATE_RATE 13 // framerate of OLED; { (256*(8/8)) / OLED_UPDATE_RATE }; 13 = 19FPS, 15 = 17FPS // 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 FLAG_RGBLED_RUN (1 << 1) +#define FLAG_ACCEL_POLL (1 << 2) +#define FLAG_RGBLED_SEND (1 << 5) +#define PROG_TICK_RATE ((32768-8192-4096) / 256) // not sure why this value can't be 32768/256 + // this was checked with a stopwatch and is close enough + // this value IS FRAMERATE DEPENDENT for some reason... figure it out later const uint8_t vers[] = "241015a"; @@ -73,7 +73,7 @@ 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 uint8_t flags_hi = FLAG_RESET_SYSTICK; static uint8_t st_tick = 0; // program tick counter static uint8_t oled_tick = 0; // oled framerate counter @@ -83,7 +83,7 @@ static uint8_t oled_tick = 0; // oled framerate counter void ch59x_xtal_conf() { HSECFG_Current(HSE_RCur_125); - HSECFG_Capacitance(HSECap_14p); + HSECFG_Capacitance(HSECap_12p); } /* @@ -117,6 +117,8 @@ void rtcisr_init() Calibration_LSI(Level_128); // calibrate LSI fromm HSE rtc_reset_trig(); + + PFIC_SetPriority(RTC_IRQn, 0x00); // rtc is highest priority interrupt PFIC_EnableIRQ(RTC_IRQn); } @@ -183,7 +185,7 @@ void oled_update_done() menu_tick(); // calculate CPU usage - cpu_pct = (cpu_use * 100) / cpu_max; + cpu_pct = ((cpu_use * 100) / OLED_UPDATE_RATE) / cpu_max; if (cpu_pct > cpu_pct_max) cpu_pct_max = cpu_pct; } @@ -202,11 +204,23 @@ void lowprio_task() { // can corrupt transactions SYS_DisableAllIrq(&interrupt_flags); - // temporary: enable sub interrupts + // temporary: re-send sub interrupts, sub button holds, enable rgb_hwen ch32sub_intr_defaults(); + btn_commit_hold(); + ch32sub_rgb_hwen(1); // process sub MCU interrupt, if pending ch32sub_process(); + if (flags_lo & FLAG_RGBLED_SEND) { + flags_lo &= ~FLAG_RGBLED_SEND; + // rgbled_send(); + } + + if (flags_lo & FLAG_ACCEL_POLL) { + flags_lo &= ~FLAG_ACCEL_POLL; + // accel_poll(); + } + // send the last oled frame data if (flags_lo & FLAG_OLED_UPDATE) { flags_lo &= ~FLAG_OLED_UPDATE; @@ -227,15 +241,7 @@ void lowprio_task() { } ssd1306_update(); } - } - // 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; } @@ -243,8 +249,9 @@ void lowprio_task() { SYS_RecoverIrq(interrupt_flags); // render new rgbled frame - if (flags_lo & FLAG_RGBLED_RUN_PROG) { - flags_lo &= ~FLAG_RGBLED_RUN_PROG; + // this is not included in cpu calcs :/ + if (flags_lo & FLAG_RGBLED_RUN) { + flags_lo &= ~FLAG_RGBLED_RUN; rgbled_runprog(st_tick); } @@ -261,36 +268,36 @@ int main() 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 + PWR_DCDCCfg(ENABLE); // enable DC-DC converter; brings significant power saving - i2c_init(); // get i2c initialized since most stuff will need it + i2c_init(); // get i2c initialized since most stuff will need it - uconf_load(); // read the user config + 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 + 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 + tinymt32_init(&tinymt32_s, 1337); // let's get random - gat_gpio_init(); // configure GAT aux GPIOs, get gat ID - // todo: implement // configure GAT i2c slave + accel_init(); // initialize accelerometer + rgbled_init(); // initialize RGBLED controller - 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 + gat_gpio_init(); // configure GAT aux GPIOs, get gat ID + // todo: implement // configure GAT i2c slave - systick_init(); // start up the system tick, used for CPU percentage calculation + 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 + 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(); + rtcisr_init(); // configure main program tick interrupt - // start the low priority task loop - lowprio_task(); + lowprio_task(); // start the low priority task loop } @@ -298,19 +305,12 @@ __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; - } + // clear interrupt flag and reset RTC + rtc_reset_trig(); // speed up SetSysClock(SYSCLK_FREQ_NORMAL); - // clear interrupt flag and reset RTC - rtc_reset_trig(); - // manual uptime counter st_tick++; if (!st_tick) { @@ -320,6 +320,13 @@ void RTC_IRQHandler(void) uptime_sec = (uint8_t)((uptime ) % 60); } + oled_tick++; + if (oled_tick >= OLED_UPDATE_RATE) { + oled_tick = 0; + SysTick->CNT = 0; + flags_lo |= FLAG_OLED_UPDATE; + } + // operations switch (st_tick & 0x7) { case 0: @@ -329,22 +336,14 @@ void RTC_IRQHandler(void) uconf.ledprog_rgb_idx = 0; } - // send any rendered data now - rgbled_send(); - - // defer rendering - flags_lo |= FLAG_RGBLED_RUN_PROG; + // send RGBLEDs, render new program + flags_lo |= FLAG_RGBLED_SEND; + flags_lo |= FLAG_RGBLED_RUN; break; } case 1: { - accel_poll(); + flags_lo |= FLAG_ACCEL_POLL; // no break } } - - oled_tick++; - if (oled_tick >= OLED_UPDATE_RATE) { - oled_tick = 0; - flags_lo |= FLAG_OLED_UPDATE; - } } diff --git a/nametag8_CH592/user/port_intr.c b/nametag8_CH592/user/port_intr.c index 081c9de..5e821d6 100644 --- a/nametag8_CH592/user/port_intr.c +++ b/nametag8_CH592/user/port_intr.c @@ -43,8 +43,11 @@ void port_intr_cb_register(uint8_t port, uint8_t idx, void (*fn)(void)) void port_intr_init() { - // clear state then enable port interrupt + // clear state R16_PB_INT_IF = 0xff; + + // then enable interrupt as low priority + PFIC_SetPriority(RTC_IRQn, 0x30); PFIC_EnableIRQ(GPIO_B_IRQn); } diff --git a/nametag8_CH592/user/ui/btn.c b/nametag8_CH592/user/ui/btn.c index 9dff031..c279f9d 100644 --- a/nametag8_CH592/user/ui/btn.c +++ b/nametag8_CH592/user/ui/btn.c @@ -21,11 +21,17 @@ uint8_t btn_held; +static uint8_t btn_map[BTN_COUNT] = {2, 1, 3, 0, 4}; // bot left, top left, bot right, top right + + + __HIGH_CODE void btn_push_cb(uint8_t idx) { - btn_pushed |= (1 << idx); - if (btn[idx].cb_push) btn[idx].cb_push(idx); + if (!(btn_pushed & (1 << idx))) { + btn_pushed |= (1 << idx); + if (btn[idx].cb_push) btn[idx].cb_push(idx); + } } __HIGH_CODE @@ -52,8 +58,8 @@ void btn_commit_hold() x = 0; for (i = 0; i < BTN_COUNT; i++) { - val[x + 0x00] = btn[i].hold >> 8; - val[x + 0x01] = btn[i].hold & 0xff; + val[x + 0x00] = btn[btn_map[i]].hold >> 8; + val[x + 0x01] = btn[btn_map[i]].hold & 0xff; x += 2; } @@ -61,8 +67,8 @@ void btn_commit_hold() x = 0; for (i = 0; i < BTN_COUNT; i++) { - val[x + 0x00] = btn[i].repeat >> 8; - val[x + 0x01] = btn[i].repeat & 0xff; + val[x + 0x00] = btn[btn_map[i]].repeat >> 8; + val[x + 0x01] = btn[btn_map[i]].repeat & 0xff; x += 2; } @@ -87,13 +93,13 @@ void btn_intr() // process callbacks for new events for (i = 0; i < BTN_COUNT; i++) { if (btn_state[1] & (1 << i)) { - btn_push_cb(i); + btn_push_cb(btn_map[i]); } if (btn_state[2] & (1 << i)) { - btn_hold_cb(i); + btn_hold_cb(btn_map[i]); } if (btn_state[3] & (1 << i)) { - btn_release_cb(i); + btn_release_cb(btn_map[i]); } } } diff --git a/nametag8_CH592/user/ui/btn.h b/nametag8_CH592/user/ui/btn.h index df8c017..fc7a0f2 100644 --- a/nametag8_CH592/user/ui/btn.h +++ b/nametag8_CH592/user/ui/btn.h @@ -13,7 +13,8 @@ -#define BTN_COUNT 5 +#define BTN_COUNT 5 // total buttons in system +#define MENU_BTN_COUNT 4 // buttons used for menu, must be the first buttons #define HOLD_PERIOD 5 // period in milliseconds for each "hold" tick internally diff --git a/nametag8_V003/user/ch32v00x_it.c b/nametag8_V003/user/ch32v00x_it.c index d3b2240..6bbbaec 100644 --- a/nametag8_V003/user/ch32v00x_it.c +++ b/nametag8_V003/user/ch32v00x_it.c @@ -15,19 +15,24 @@ - -void NMI_Handler(void); //__attribute__((interrupt("WCH-Interrupt-fast"))); -void HardFault_Handler(void); //__attribute__((interrupt("WCH-Interrupt-fast"))); +#define SYSTICK_COOLDOWN 3 +uint8_t systick_timeout; +__attribute__((interrupt())) void NMI_Handler(void) { while (1); } +__attribute__((interrupt())) void HardFault_Handler(void) { + // hopefully we're running well enough to isolate the i2c bus + + // then reboot, because we shouldn't really be here + while (1); } @@ -36,31 +41,31 @@ void SysTick_Handler(void) { // ---- PROCESS UI AND COMMS - // button handler - btn_poll(); + btn_poll(); // button handler + irda_process(); // irda timeout and retry - // irda timeout and retry - irda_process(); - - // clear comparison flag - SysTick->SR = 0; + SysTick->SR = 0; // clear comparison flag // ---- DISABLE INTERRUPT // see if any buttons are currently pushed if ((BTN_PORT->INDR & BTN_PIN_MASK) != BTN_PIN_MASK) { - // yup, something is pushed, so keep the interrupt on + // something is pushed, so keep the tick interrupt enabled + systick_timeout = SYSTICK_COOLDOWN; return; } // see if irda is active - // nothing is active, so shut down this interrupt - NVIC_DisableIRQ(SysTicK_IRQn); + // nothing is active, so shut down this interrupt source + systick_timeout--; + if (!systick_timeout) { + NVIC_DisableIRQ(SysTicK_IRQn); + } } -__attribute__((interrupt("WCH-Interrupt-fast"))) +__attribute__((interrupt())) void EXTI7_0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line3)) { @@ -75,6 +80,7 @@ void EXTI7_0_IRQHandler(void) // enable main tick handler on button push. // tick handler will sense when it isn't needed and shut itself off. SysTick->SR = 0; + systick_timeout = SYSTICK_COOLDOWN; NVIC_EnableIRQ(SysTicK_IRQn); EXTI_ClearITPendingBit(EXTI_Line0 | EXTI_Line4 | EXTI_Line5 | EXTI_Line6 | EXTI_Line7); } diff --git a/nametag8_V003/user/device/btn.c b/nametag8_V003/user/device/btn.c index d97efb7..211dbad 100644 --- a/nametag8_V003/user/device/btn.c +++ b/nametag8_V003/user/device/btn.c @@ -140,6 +140,8 @@ void btn_poll() uint8_t pushed; + set_interrupt = 0; + for (i = 0; i < BTN_COUNT; i++) { pushed = 0; @@ -161,20 +163,21 @@ void btn_poll() // first push? if (!(btn[i]._mask & BTN_PUSH)) { btn[i]._mask = BTN_PUSH | ignore; - if (btn[i].cb_push && !ignore) { - btn[i].cb_push(i); + if (!ignore) { + if (btn[i].cb_push) btn[i].cb_push(i); btn[i]._mask |= (BTN_PUSH << 4); } - } else if (btn[i]._count >= btn[i].hold) { - // held to count limit + } else + // held to count limit + if (btn[i].hold && (btn[i]._count >= btn[i].hold)) { // if button is not repeatable, do not retrigger if ((btn[i]._mask & BTN_HOLD) && !btn[i].repeat) continue; btn[i]._mask |= BTN_HOLD; // call callback only if not in ignore state - if (btn[i].cb_hold && !ignore) { - btn[i].cb_hold(i); + if (!ignore) { + if (btn[i].cb_hold) btn[i].cb_hold(i); btn[i]._mask |= (BTN_HOLD << 4); } @@ -188,19 +191,18 @@ void btn_poll() if (!(btn[i]._mask & BTN_RELEASE)) { // note: release will remove ignore status btn[i]._mask = BTN_RELEASE; - btn[i]._count = 0; // call callback only if not in ignore state if (btn[i].cb_release && !ignore) { btn[i].cb_release(i); btn[i]._mask |= (BTN_RELEASE << 4); } } + btn[i]._count = 0; } } // any button event with enabled interrupt flags will set button interrupt flag if (set_interrupt) { i2cs_append_flag(INT_BTN); - set_interrupt = 0; } } diff --git a/nametag8_V003/user/i2c_slave.c b/nametag8_V003/user/i2c_slave.c index 8a05747..0427e95 100644 --- a/nametag8_V003/user/i2c_slave.c +++ b/nametag8_V003/user/i2c_slave.c @@ -63,7 +63,7 @@ static void i2cs_int_check() void i2cs_write_cb(uint16_t initial_reg, uint16_t last_reg) { uint8_t i; - uint8_t trig = 0; + uint8_t trig; uint16_t w; // nothing written? @@ -73,7 +73,7 @@ void i2cs_write_cb(uint16_t initial_reg, uint16_t last_reg) for (i = 0; i < sizeof(write_cb_trig); i++) { if ((initial_reg <= write_cb_trig[i]) && (last_reg >= write_cb_trig[i])) { trig = write_cb_trig[i]; - } + } else continue; switch (trig) { case REG_INTR_FLAGS_CLEAR: { @@ -151,9 +151,6 @@ void i2cs_init(uint8_t address, uint8_t read_only_mode) { I2C_InitTypeDef i2c = {0}; - i2cs_state.first_write = 1; - i2cs_state.offset = 0; - i2cs_state.position = 0; i2cs_state.reg_file = i2cs_reg; i2cs_state.reg_len = sizeof(i2cs_reg); i2cs_state.write_callback = i2cs_write_cb; @@ -161,7 +158,7 @@ void i2cs_init(uint8_t address, uint8_t read_only_mode) i2cs_state.read_callback = i2cs_read_cb; i2cs_state.read_only = read_only_mode; - i2c.I2C_ClockSpeed = 500000; + i2c.I2C_ClockSpeed = 600000; i2c.I2C_Mode = I2C_Mode_I2C; i2c.I2C_DutyCycle = I2C_DutyCycle_2; i2c.I2C_OwnAddress1 = address; @@ -195,6 +192,7 @@ void i2cs_poll() } +//__attribute__((section(".ramfunc"))) __attribute__((interrupt("WCH-Interrupt-fast"))) void I2C1_EV_IRQHandler(void) { @@ -205,21 +203,23 @@ void I2C1_EV_IRQHandler(void) STAR2 = I2C1->STAR2; if (STAR1 & I2C_STAR1_ADDR) { // Start event - i2cs_state.first_write = 1; // Next write will be the offset - i2cs_state.position = i2cs_state.offset; // Reset position + i2cs_state.addr_write = 1; // Next write will be the 16-bit register address + i2cs_state.addr_req = 0; // reset this address + i2cs_state.writing = 0; // not yet writing data from master } if (STAR1 & I2C_STAR1_RXNE) { // Write from master 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; - i2cs_state.first_write = 0; - i2cs_state.writing = 0; - } else if (i2cs_state.first_write == 1) { // high address byte written - i2cs_state.offset = I2C1->DATAR << 8; - i2cs_state.first_write++; + if (i2cs_state.addr_write == 2) { // low address byte written + i2cs_state.addr_req |= I2C1->DATAR; + + i2cs_state.position = i2cs_state.addr_req; // position set to requested index + i2cs_state.addr_write = 0; // not writing the address anymore } else - { // Normal register write + if (i2cs_state.addr_write == 1) { // high address byte written + i2cs_state.addr_req = I2C1->DATAR << 8; + i2cs_state.addr_write++; + } else + { // Normal register write i2cs_state.writing = 1; if (i2cs_state.position < i2cs_state.reg_len && !i2cs_state.read_only) { @@ -242,7 +242,6 @@ void I2C1_EV_IRQHandler(void) } if (STAR1 & I2C_STAR1_TXE) { // Read to master event - i2cs_state.writing = 0; if (i2cs_state.position < i2cs_state.reg_len) { I2C1->DATAR = i2cs_state.reg_file[i2cs_state.position]; if (i2cs_state.read_callback != 0) { @@ -258,25 +257,33 @@ void I2C1_EV_IRQHandler(void) I2C1->CTLR1 &= ~(I2C_CTLR1_STOP); // Clear stop if (i2cs_state.write_callback != 0 && i2cs_state.writing) { - i2cs_state.write_callback(i2cs_state.offset, i2cs_state.position - 1); + i2cs_state.write_callback(i2cs_state.addr_req, i2cs_state.position - 1); } } } -__attribute__((interrupt("WCH-Interrupt-fast"))) +__attribute__((interrupt())) void I2C1_ER_IRQHandler(void) { + uint8_t err = 0; uint16_t STAR1 = I2C1->STAR1; if (STAR1 & I2C_STAR1_BERR) { // Bus error + err++; I2C1->STAR1 &= ~(I2C_STAR1_BERR); // Clear error } if (STAR1 & I2C_STAR1_ARLO) { // Arbitration lost error + err++; I2C1->STAR1 &= ~(I2C_STAR1_ARLO); // Clear error } if (STAR1 & I2C_STAR1_AF) { // Acknowledge failure + err++; I2C1->STAR1 &= ~(I2C_STAR1_AF); // Clear error } + + if (err) { + I2C1->CTLR1 &= ~(I2C_CTLR1_STOP); // Clear stop + } } diff --git a/nametag8_V003/user/i2c_slave.h b/nametag8_V003/user/i2c_slave.h index 7a93eb3..4e8816c 100644 --- a/nametag8_V003/user/i2c_slave.h +++ b/nametag8_V003/user/i2c_slave.h @@ -87,9 +87,9 @@ typedef void (*i2c_werr_callback_t)(uint16_t reg, uint8_t data, uint8_t error); typedef void (*i2c_read_callback_t)(uint16_t reg); typedef struct i2c_slave_state { - uint8_t first_write; // first 2 bytes address the register file - uint16_t offset; // offset within the register file as sent by the master - uint16_t position; // current read/write position within the register file + uint8_t addr_write; // first 2 bytes address the register file + uint16_t addr_req; // requested read/write index as sent by the master + uint16_t position; // current read/write index within the register file volatile uint8_t* volatile reg_file; // register file pointer uint16_t reg_len; // register file max length i2c_write_callback_t write_callback; diff --git a/nametag8_V003/user/main.c b/nametag8_V003/user/main.c index 3f3a7b8..577eb21 100644 --- a/nametag8_V003/user/main.c +++ b/nametag8_V003/user/main.c @@ -96,9 +96,9 @@ static inline void exti_nvic_init() void systick_init(void) { - SysTick->CMP = (SystemCoreClock / 200 / 8) - 1; // we want a 200Hz interrupt + SysTick->CMP = (SystemCoreClock / 200) - 1; // we want a 200Hz interrupt SysTick->CNT = 0; // clear counter - SysTick->CTLR = 0xB; // start counter in /8 mode, enable interrupts, auto-reset counter + SysTick->CTLR = 0xF; // start counter in /1 mode, enable interrupts, auto-reset counter SysTick->SR = 0; // clear count comparison flag NVIC_EnableIRQ(SysTicK_IRQn); // enable interrupt @@ -121,9 +121,10 @@ int main(void) // enable peripheral clocks used in this program RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); - RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_I2C1, ENABLE); - RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | - RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE); + RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_I2C1, ENABLE); + RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO | + RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | + RCC_APB2Periph_GPIOD, ENABLE); // configure gpio @@ -143,6 +144,8 @@ int main(void) systick_init(); while (1) { - __WFI(); + // todo: determine why we HardFault with user button interrupts + // randomly but only with __WFI being used + // __WFI(); } }