main program tick interrupt now works

CH58x/CH59x only has one main system clock and all timers are referenced to this clock. Other than watchdog, there's only one timer that runs independently: RTC. Thankfully the RTC has a mode to interrupt at rates faster than one second. this is being used for the program tick interrupt.

Also added OLED initialization code since that was forgotten before.
This commit is contained in:
true 2024-10-24 17:22:20 -07:00
parent 58f357334a
commit bc300e522a
3 changed files with 46 additions and 10 deletions

View File

@ -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;

View File

@ -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中断标志

View File

@ -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();
}