diff --git a/nametag8_CH592/StdPeriphDriver/CH59x_clk.c b/nametag8_CH592/StdPeriphDriver/CH59x_clk.c index b588663..cc88507 100644 --- a/nametag8_CH592/StdPeriphDriver/CH59x_clk.c +++ b/nametag8_CH592/StdPeriphDriver/CH59x_clk.c @@ -562,7 +562,7 @@ void RTC_TRIGFunCfg(uint32_t cyc) * * @return none */ -void RTC_ModeFunDisable(RTC_MODETypeDef m) +void RTC_TRIGFunDisable(RTC_MODETypeDef m) { uint8_t i = 0; diff --git a/nametag8_CH592/StdPeriphDriver/inc/CH59x_clk.h b/nametag8_CH592/StdPeriphDriver/inc/CH59x_clk.h index d70593f..c2a8e1b 100644 --- a/nametag8_CH592/StdPeriphDriver/inc/CH59x_clk.h +++ b/nametag8_CH592/StdPeriphDriver/inc/CH59x_clk.h @@ -260,7 +260,7 @@ void RTC_TMRFunCfg(RTC_TMRCycTypeDef t); * * @param m - 需要关闭的当前模式 */ -void RTC_ModeFunDisable(RTC_MODETypeDef m); +void RTC_TRIGFunDisable(RTC_MODETypeDef m); /** * @brief 获取RTC中断标志 diff --git a/nametag8_CH592/user/main.c b/nametag8_CH592/user/main.c index 243a2a7..df91198 100644 --- a/nametag8_CH592/user/main.c +++ b/nametag8_CH592/user/main.c @@ -49,6 +49,8 @@ #define FLAG_OLED_UPDATE (1 << 0) #define FLAG_RGBLED_RUN_PROG (1 << 1) +#define PROG_TICK_RATE (32768 / 256) + const uint8_t vers[] = "241015a"; @@ -72,17 +74,43 @@ static uint8_t oled_tick = 0; // oled framerate counter - - void ch59x_xtal_conf() { HSECFG_Current(HSE_RCur_125); HSECFG_Capacitance(HSECap_14p); } -void systick_init() +/* + * the CPU will change clockspeed depending on what it is doing. + * all timers are tied to system clock and cannot be derived from the crystal directly, + * except for RTC which can use the LSI. RTC also has a neat feature where it can + * trigger an interrupt when bits match a mask. at this time we're not using the RTC + * for anything else so putting RTC should suffice for our main tick interrupt. + */ +void rtc_reset_trig() { + sys_safe_access_enable(); + R8_RTC_FLAG_CTRL |= RB_RTC_TRIG_CLR; + R32_RTC_TRIG = 0; + R8_RTC_MODE_CTRL |= RB_RTC_LOAD_HI; + sys_safe_access_disable(); + while((R32_RTC_TRIG & 0x3FFF) != (R32_RTC_CNT_DAY & 0x3FFF)); + sys_safe_access_enable(); + R32_RTC_TRIG = 0; + R8_RTC_MODE_CTRL |= RB_RTC_LOAD_LO; + sys_safe_access_disable(); + + RTC_TRIGFunCfg(PROG_TICK_RATE); +} + +void rtcisr_init() +{ + LClk32K_Cfg(Clk32K_LSI, ENABLE); // enable internal oscillator + Calibration_LSI(Level_128); // calibrate LSI fromm HSE + + rtc_reset_trig(); + PFIC_EnableIRQ(RTC_IRQn); } void oled_update_done() @@ -170,6 +198,7 @@ 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); @@ -199,10 +228,12 @@ int main() // configure port-based interrupts (used for ch32sub interrupt) port_intr_init(); - // note that system clock speed is decreased after every use of I2C. + // start up the OLED + ssd1306fb_set_target(&oled); + ssd1306_init(1); // we'll try to init later too, since sometimes they fail - // configure system tick - systick_init(); + // configure main program tick interrupt + rtcisr_init(); while(1) { // sleep when we're doing nothing @@ -242,8 +273,13 @@ int main() } -void SysTick_Handler(void) +__INTERRUPT +__HIGH_CODE +void RTC_IRQHandler(void) { + // clear interrupt flag and reset RTC + rtc_reset_trig(); + st_tick++; if (!st_tick) { @@ -276,7 +312,7 @@ void SysTick_Handler(void) } } - // read accelerometer data + // read accelerometer data at 32Hz if ((st_tick & 0x7) == 0x7) { accel_poll(); }