mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-27 01:29:58 +01:00
[ion] LED: start fixing the blinking frequency
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "led.h"
|
||||
#include <ion/led.h>
|
||||
#include <drivers/config/led.h>
|
||||
#include <drivers/config/clocks.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user