From fefa5beac4bdee5f0dce5f86651a95b9b7d4eb08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Wed, 10 Apr 2019 10:24:59 +0200 Subject: [PATCH] [ion] LED: start fixing the blinking frequency --- ion/src/device/n0100/drivers/config/clocks.h | 21 ++++++++++++-------- ion/src/device/n0101/drivers/board.cpp | 4 ++-- ion/src/device/n0101/drivers/config/clocks.h | 20 ++++++++++++------- ion/src/device/shared/drivers/board.cpp | 3 ++- ion/src/device/shared/drivers/led.cpp | 11 +++++----- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/ion/src/device/n0100/drivers/config/clocks.h b/ion/src/device/n0100/drivers/config/clocks.h index d883a9d22..552b7bb55 100644 --- a/ion/src/device/n0100/drivers/config/clocks.h +++ b/ion/src/device/n0100/drivers/config/clocks.h @@ -27,18 +27,23 @@ constexpr static int PLL_N = 192; constexpr static Regs::RCC::PLLCFGR::PLLP PLL_P_Reg = Regs::RCC::PLLCFGR::PLLP::PLLP2; constexpr static int PLL_P = ((int)PLL_P_Reg | 1) << 1; constexpr static int SYSCLKFrequency = ((HSE/PLL_M)*PLL_N)/PLL_P; -constexpr static int AHB_prescaler = 1; -constexpr static int HCLKFrequency = SYSCLKFrequency/AHB_prescaler; -constexpr static int AHBFrequency = HCLKFrequency; -constexpr static Regs::RCC::CFGR::APBPrescaler APB1PrescalerRegs = Regs::RCC::CFGR::APBPrescaler::AHBDividedBy2; -constexpr static int APB1Prescaler = 2; -constexpr static int APB1Frequency = HCLKFrequency/APB1Prescaler; -constexpr static int APB1TimerFrequency = 2*APB1Frequency; +constexpr static int AHBPrescaler = 1; /* To slow down the whole system, we prescale the AHB clock. * We could divide the system clock by 512. However, the HCLK clock * frequency must be >= 14.2MHz and <=216 MHz which forces the * AHBPrescaler to be below 96MHz/14.2MHz~6.7. */ -constexpr static Regs::RCC::CFGR::AHBPrescaler AHBLowFrequencyPrescaler = Regs::RCC::CFGR::AHBPrescaler::SysClkDividedBy4; +constexpr static Regs::RCC::CFGR::AHBPrescaler AHBLowFrequencyPrescalerReg = Regs::RCC::CFGR::AHBPrescaler::SysClkDividedBy4; +constexpr static int AHBLowFrequencyPrescaler = 4; +constexpr static int HCLKFrequency = SYSCLKFrequency/AHBPrescaler; +constexpr static int HCLKLowFrequency = SYSCLKFrequency/AHBLowFrequencyPrescaler; +constexpr static int AHBFrequency = HCLKFrequency; +//constexpr static int AHBLowFrequency = HCLKLowFrequency; +constexpr static Regs::RCC::CFGR::APBPrescaler APB1PrescalerRegs = Regs::RCC::CFGR::APBPrescaler::AHBDividedBy2; +constexpr static int APB1Prescaler = 2; +//constexpr static int APB1Frequency = HCLKFrequency/APB1Prescaler; +constexpr static int APB1LowFrequency = HCLKLowFrequency/APB1Prescaler; +//constexpr static int APB1TimerFrequency = 2*APB1Frequency; +constexpr static int APB1TimerLowFrequency = 2*APB1LowFrequency; } } diff --git a/ion/src/device/n0101/drivers/board.cpp b/ion/src/device/n0101/drivers/board.cpp index 4efd95ee0..df32de649 100644 --- a/ion/src/device/n0101/drivers/board.cpp +++ b/ion/src/device/n0101/drivers/board.cpp @@ -176,9 +176,9 @@ void initClocks() { FLASH.ACR()->setARTEN(true); // 192 MHz is too fast for APB1. Divide it by four to reach 48 MHz - RCC.CFGR()->setPPRE1(RCC::CFGR::APBPrescaler::AHBDividedBy4); + RCC.CFGR()->setPPRE1(Clocks::Config::APB1PrescalerReg); // 192 MHz is too fast for APB2. Divide it by two to reach 96 MHz - RCC.CFGR()->setPPRE2(RCC::CFGR::APBPrescaler::AHBDividedBy2); + RCC.CFGR()->setPPRE2(Clocks::Config::APB2PrescalerReg); while(!RCC.CR()->getPLLRDY()) { } diff --git a/ion/src/device/n0101/drivers/config/clocks.h b/ion/src/device/n0101/drivers/config/clocks.h index 1317d3af7..488f32a72 100644 --- a/ion/src/device/n0101/drivers/config/clocks.h +++ b/ion/src/device/n0101/drivers/config/clocks.h @@ -28,18 +28,24 @@ constexpr static int PLL_P = ((int)PLL_P_Reg | 1) << 1; constexpr static int PLL_Q = 8; constexpr static int SYSCLKFrequency = ((HSE/PLL_M)*PLL_N)/PLL_P; constexpr static int AHBPrescaler = 1; -constexpr static int HCLKFrequency = SYSCLKFrequency/AHBPrescaler; -constexpr static int AHBFrequency = HCLKFrequency; -constexpr static int APB1Prescaler = 4; -constexpr static int APB1Frequency = HCLKFrequency/APB1Prescaler; -constexpr static int APB1TimerFrequency = 2*APB1Frequency; - /* To slow down the whole system, we prescale the AHB clock. * We could divide the system clock by 512. However, the HCLK clock * frequency must be >= 14.2MHz and <=216 MHz which forces the * AHBPrescaler to be below 192MHz/14.2MHz~13.5. */ -constexpr static Regs::RCC::CFGR::AHBPrescaler AHBLowFrequencyPrescaler = Regs::RCC::CFGR::AHBPrescaler::SysClkDividedBy8; +constexpr static Regs::RCC::CFGR::AHBPrescaler AHBLowFrequencyPrescalerReg = Regs::RCC::CFGR::AHBPrescaler::SysClkDividedBy8; +constexpr static int AHBLowFrequencyPrescaler = 8; +constexpr static int HCLKFrequency = SYSCLKFrequency/AHBPrescaler; +constexpr static int HCLKLowFrequency = SYSCLKFrequency/AHBLowFrequencyPrescaler; +constexpr static int AHBFrequency = HCLKFrequency; +//constexpr static int AHBLowFrequency = HCLKLowFrequency; +constexpr static Regs::RCC::CFGR::APBPrescaler APB1PrescalerReg = Regs::RCC::CFGR::APBPrescaler::AHBDividedBy4; +constexpr static int APB1Prescaler = 4; +//constexpr static int APB1Frequency = HCLKFrequency/APB1Prescaler; +constexpr static int APB1LowFrequency = HCLKLowFrequency/APB1Prescaler; +//constexpr static int APB1TimerFrequency = 2*APB1Frequency; +constexpr static int APB1TimerLowFrequency = 2*APB1LowFrequency; +constexpr static Regs::RCC::CFGR::APBPrescaler APB2PrescalerReg = Regs::RCC::CFGR::APBPrescaler::AHBDividedBy2; } } } diff --git a/ion/src/device/shared/drivers/board.cpp b/ion/src/device/shared/drivers/board.cpp index 2947aaef3..8ecb588d9 100644 --- a/ion/src/device/shared/drivers/board.cpp +++ b/ion/src/device/shared/drivers/board.cpp @@ -61,13 +61,14 @@ void shutdownPeripherals(bool keepLEDAwake) { } void setClockFrequency(Frequency f) { + // TODO: Update TIM3 prescaler or ARR to avoid irregular LED blinking switch (f) { case Frequency::High: RCC.CFGR()->setHPRE(RCC::CFGR::AHBPrescaler::SysClk); return; default: assert(f == Frequency::Low); - RCC.CFGR()->setHPRE(Clocks::Config::AHBLowFrequencyPrescaler); + RCC.CFGR()->setHPRE(Clocks::Config::AHBLowFrequencyPrescalerReg); return; } } diff --git a/ion/src/device/shared/drivers/led.cpp b/ion/src/device/shared/drivers/led.cpp index c49ffda4f..da867fd3c 100644 --- a/ion/src/device/shared/drivers/led.cpp +++ b/ion/src/device/shared/drivers/led.cpp @@ -1,6 +1,7 @@ #include "led.h" #include #include +#include static KDColor sLedColor = KDColorBlack; @@ -113,15 +114,15 @@ void setPeriodAndDutyCycles(Mode mode, float dutyCycleRed, float dutyCycleGreen, period = PWMPeriod; break; case Mode::Blink: - int systemClockFreq = 96; /* We still want to do PWM, but at a rate slow enough to blink. Ideally, * we want to pre-scale the period to be able to set it in milliseconds; * however, as the prescaler is cap by 2^16-1, we divide it by a factor * and correct the period consequently. */ - int factor = 2; - // TODO: explain the 2 ? - TIM3.PSC()->set(systemClockFreq*1000/factor); - period *= factor; + int prescalerFactor = 4; + /* Most of the time AP1TimerFrequency is the 'low' one as most of the time + * is spent in Timing::msleep. */ + TIM3.PSC()->set(Clocks::Config::APB1TimerLowFrequency*1000/prescalerFactor-1); + period *= prescalerFactor; TIM3.ARR()->set(period); break; }