[ion] Provision to clock the CPU at 96 MHz

Change-Id: I397ff23941dfff3ea3c2e217c0fb1ba242326cfb
This commit is contained in:
Romain Goyet
2016-09-28 14:42:20 +02:00
parent 97541b170c
commit 6077a72ae3
4 changed files with 96 additions and 0 deletions

View File

@@ -35,6 +35,36 @@ void Ion::Device::init() {
}
void Ion::Device::initClocks() {
#define USE_96MHZ_SYSTEM_CLOCK 0
#if USE_96MHZ_SYSTEM_CLOCK
/* System clock
* Configure the CPU at 96 MHz, APB2 and USB at 48 MHz. */
/* After reset the Flash runs as fast as the CPU. When we clock the CPU faster
* the flash memory cannot follow and therefore flash memory accesses need to
* wait a little bit.
* The spec tells us that at 2.8V and over 90MHz the flash expects 3 WS. */
FLASH.ACR()->setLATENCY(3);
/* We're using the high-speed internal oscillator as a clock source. It runs
* at a fixed 16 MHz frequency, but by piping it through the PLL we can derive
* faster oscillations. Combining default values and a PLLQ of 4 can provide
* us with a 96 MHz frequency for SYSCLK. */
RCC.PLLCFGR()->setPLLQ(4);
RCC.PLLCFGR()->setPLLSRC(RCC::PLLCFGR::PLLSRC::HSI);
// 96 MHz is too fast for APB1. Divide it by two to reach 48 MHz
RCC.CFGR()->setPPRE1(RCC::CFGR::AHBRatio::DivideBy2);
// Enable the PLL and wait for it to be ready
RCC.CR()->setPLLON(true);
while(!RCC.CR()->getPLLRDY()) {
}
// Last but not least, use the PLL output as a SYSCLK source
RCC.CFGR()->setSW(RCC::CFGR::SW::PLL);
while (RCC.CFGR()->getSWS() != RCC::CFGR::SW::PLL) {
}
#endif
// Peripheral clocks

View File

@@ -0,0 +1,23 @@
#ifndef REGS_FLASH_H
#define REGS_FLASH_H
#include "register.h"
class FLASH {
public:
class ACR : public Register32 {
public:
REGS_FIELD(LATENCY, uint8_t, 3, 0);
};
constexpr FLASH() {};
REGS_REGISTER_AT(ACR, 0x00);
private:
constexpr uint32_t Base() const {
return 0x40023C00;
}
};
constexpr FLASH FLASH;
#endif

View File

@@ -5,6 +5,45 @@
class RCC {
public:
class CR : public Register32 {
public:
REGS_BOOL_FIELD(PLLRDY, 25);
REGS_BOOL_FIELD(PLLON, 24);
};
class PLLCFGR : public Register32 {
public:
REGS_FIELD(PLLM, uint8_t, 5, 0);
REGS_FIELD(PLLN, uint16_t, 14, 6);
REGS_FIELD(PLLP, uint8_t, 17, 16);
enum class PLLSRC {
HSI = 0,
HSE = 1
};
void setPLLSRC(PLLSRC s) volatile { setBitRange(22, 22, (uint8_t)s); }
REGS_FIELD(PLLQ, uint8_t, 27, 24);
REGS_FIELD(PLLR, uint8_t, 30, 28);
};
class CFGR : public Register32 {
public:
enum class SW {
HSI = 0,
HSE = 1,
PLL = 2
};
void setSW(SW s) volatile { setBitRange(1, 0, (uint8_t)s); }
SW getSWS() volatile { return (SW)getBitRange(3,2); }
enum class AHBRatio {
One = 0,
DivideBy2 = 4,
DivideBy4 = 5,
DivideBy8 = 6,
DivideBy16 = 7
};
void setPPRE1(AHBRatio r) volatile { setBitRange(12, 10, (uint32_t)r); }
};
class AHB1ENR : public Register32 {
public:
AHB1ENR(uint32_t v) : Register32(v) {}
@@ -40,6 +79,9 @@ public:
};
constexpr RCC() {};
REGS_REGISTER_AT(CR, 0x00);
REGS_REGISTER_AT(PLLCFGR, 0x04);
REGS_REGISTER_AT(CFGR, 0x08);
REGS_REGISTER_AT(AHB1ENR, 0x30);
REGS_REGISTER_AT(AHB3ENR, 0x38);
REGS_REGISTER_AT(APB1ENR, 0x40);

View File

@@ -5,6 +5,7 @@
#include "exti.h"
#include "cm4.h"
#include "fsmc.h"
#include "flash.h"
#include "rcc.h"
#include "gpio.h"
#include "syscfg.h"