[ion] Timing: decrease AHB clock frequency in msleep to save power

y	modified:   scripts/device/openocd.n0100.cfg
This commit is contained in:
Émilie Feral
2019-03-18 11:20:05 +01:00
parent 5ec4fb5486
commit 1aef86cedb
5 changed files with 29 additions and 0 deletions

View File

@@ -8,6 +8,8 @@ namespace Device {
namespace Timing {
namespace Config {
#warning N100-calibration
//TODO: calibrate LoopsPerMillisecond now that we decrease AHB clock while msleeping
constexpr static int LoopsPerMillisecond = 8852;
constexpr static int LoopsPerMicrosecond = 9;
// CPU clock is 96 MHz, and systick clock source is divided by 8

View File

@@ -8,6 +8,7 @@ namespace Device {
namespace Timing {
namespace Config {
// TODO: calibrate msleep
constexpr static int LoopsPerMillisecond = 8852;
constexpr static int LoopsPerMicrosecond = 9;
// CPU clock is 96 MHz, and systick clock source is divided by 8

View File

@@ -57,6 +57,21 @@ void shutdownPeripherals(bool keepLEDAwake) {
Display::shutdown();
}
void setClockFrequency(Frequency f) {
switch (f) {
case Frequency::High:
RCC.CFGR()->setHPRE(RCC::CFGR::AHBPrescaler::SysClk);
return;
default:
assert(f == Frequency::Low);
/* 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.5MHz. */
RCC.CFGR()->setHPRE(RCC::CFGR::AHBPrescaler::SysClkDividedBy8);
return;
}
}
}
}
}

View File

@@ -15,6 +15,13 @@ void shutdownClocks(bool keepLEDAwake = false);
void initPeripherals();
void shutdownPeripherals(bool keepLEDAwake = false);
enum class Frequency {
Low = 0,
High = 1
};
void setClockFrequency(Frequency f);
}
}
}

View File

@@ -1,4 +1,5 @@
#include "timing.h"
#include "board.h"
#include <ion/timing.h>
#include <drivers/config/timing.h>
@@ -12,9 +13,12 @@ using namespace Device::Timing;
* precision, we could use the controller cycle counter (Systick). */
void msleep(uint32_t ms) {
// We decrease the AHB clock frequency to save power while sleeping.
Device::Board::setClockFrequency(Device::Board::Frequency::Low);
for (volatile uint32_t i=0; i<Config::LoopsPerMillisecond*ms; i++) {
__asm volatile("nop");
}
Device::Board::setClockFrequency(Device::Board::Frequency::High);
}
void usleep(uint32_t us) {
for (volatile uint32_t i=0; i<Config::LoopsPerMicrosecond*us; i++) {