summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript2
-rw-r--r--platforms/stm32/f4.yaml73
-rw-r--r--rcc/SConscript29
-rw-r--r--rcc/rcc.cpp88
-rw-r--r--rcc/rcc.h428
-rw-r--r--rcc/rcc_enums.h.j217
-rw-r--r--rcc/rcc_reg.h123
7 files changed, 287 insertions, 473 deletions
diff --git a/SConscript b/SConscript
index 846a01f..26a0bda 100644
--- a/SConscript
+++ b/SConscript
@@ -8,10 +8,10 @@ env.SConscript('ld_scripts/SConscript')
env.Append(
LIB_SOURCES = [
env.SConscript('interrupt/SConscript'),
+ env.SConscript('rcc/SConscript'),
env.SConscript('usb/SConscript'),
Glob('startup/*.cpp'),
Glob('i2c/*.cpp'),
Glob('os/*.cpp'),
- Glob('rcc/*.cpp'),
],
)
diff --git a/platforms/stm32/f4.yaml b/platforms/stm32/f4.yaml
index 8a632f1..dc5717d 100644
--- a/platforms/stm32/f4.yaml
+++ b/platforms/stm32/f4.yaml
@@ -34,6 +34,79 @@
OTG_HS:
offset: 0x40040000
+ rcc:
+ RCC:
+ offset: 0x40023800
+ type: f4
+ bus:
+ AHB1:
+ 0: GPIOA
+ 1: GPIOB
+ 2: GPIOC
+ 3: GPIOD
+ 4: GPIOE
+ 5: GPIOF
+ 6: GPIOG
+ 7: GPIOH
+ 8: GPIOI
+ 12: CRC
+ 21: DMA1
+ 22: DMA2
+ 25: ETHMAC
+ 26: ETHMACTX
+ 27: ETHMACRX
+ 28: ETHMACPTP
+ 29: OTGHS
+ 30: OTGHSULPI
+
+ AHB2:
+ 0: DCMI
+ 4: CRYP
+ 5: HASH
+ 6: RNG
+ 7: OTGFS
+
+ AHB3:
+ 0: FSMC
+
+ APB1:
+ 0: TIM2
+ 1: TIM3
+ 2: TIM4
+ 3: TIM5
+ 4: TIM6
+ 5: TIM7
+ 6: TIM12
+ 7: TIM13
+ 8: TIM14
+ 11: WWDG
+ 14: SPI2
+ 15: SPI3
+ 17: USART2
+ 18: USART3
+ 19: UART4
+ 20: UART5
+ 21: I2C1
+ 22: I2C2
+ 23: I2C3
+ 25: CAN1
+ 26: CAN2
+ 28: PWR
+ 29: DAC
+
+ APB2:
+ 0: TIM1
+ 1: TIM8
+ 4: USART1
+ 5: USART6
+ 8: ADC
+ 11: SDIO
+ 12: SPI1
+ 14: SYSCFG
+ 16: TIM9
+ 17: TIM10
+ 18: TIM11
+
interrupt:
irq:
0: WWDG
diff --git a/rcc/SConscript b/rcc/SConscript
new file mode 100644
index 0000000..c7c384b
--- /dev/null
+++ b/rcc/SConscript
@@ -0,0 +1,29 @@
+Import('env')
+
+headers = []
+instances = []
+sources = []
+aliases = {}
+
+periph = env['PLATFORM_SPEC'].get('periph', {})
+
+if 'rcc' in periph:
+ buses = env['PLATFORM_SPEC']['periph']['rcc']['RCC']['bus']
+ env.Jinja2('rcc_enums.h', 'rcc_enums.h.j2', buses = buses)
+
+ headers.append('rcc_reg.h')
+ for name, data in periph['rcc'].items():
+ instances.append({
+ 'type': 'RCC_t<RCC_reg_%s_t>' % data['type'],
+ 'name': name,
+ 'args': [data['offset']],
+ })
+
+ sources.extend([
+ File('rcc.cpp'),
+ File('flash.cpp'),
+ ])
+
+env.Jinja2('rcc.h', '../templates/periph_instances.h.j2', headers = headers, instances = instances, aliases = aliases)
+
+Return('sources')
diff --git a/rcc/rcc.cpp b/rcc/rcc.cpp
index 65faf33..5a7e29e 100644
--- a/rcc/rcc.cpp
+++ b/rcc/rcc.cpp
@@ -9,83 +9,83 @@ void rcc_init() {
#if defined(STM32F1) || defined(STM32F3)
// Enable HSE.
- RCC.CR |= 0x10000;
- while(!(RCC.CR & 0x20000));
+ RCC->CR |= 0x10000;
+ while(!(RCC->CR & 0x20000));
// Configure and enable PLL.
- RCC.CFGR = 0x1d0000;
- RCC.CR |= 0x1000000;
- while(!(RCC.CR & 0x2000000));
+ RCC->CFGR = 0x1d0000;
+ RCC->CR |= 0x1000000;
+ while(!(RCC->CR & 0x2000000));
// Switch to PLL.
- RCC.CFGR |= 0x2;
- while(!(RCC.CFGR & 0x8));
+ RCC->CFGR |= 0x2;
+ while(!(RCC->CFGR & 0x8));
// Set APB1 prescaler to /2.
- RCC.CFGR |= 0x400;
+ RCC->CFGR |= 0x400;
// Set ADCCLK prescaler to /6.
- RCC.CFGR |= 0x8000;
+ RCC->CFGR |= 0x8000;
#elif defined(STM32F4)
// Enable HSE.
- RCC.CR |= 0x10000;
- while(!(RCC.CR & 0x20000));
+ RCC->CR |= 0x10000;
+ while(!(RCC->CR & 0x20000));
// Configure and enable PLL.
- RCC.PLLCFGR = 0x20400000 | (7 << 24) | (2 * 168 << 6) | 8;
- RCC.CR |= 0x1000000;
- while(!(RCC.CR & 0x2000000));
+ RCC->PLLCFGR = 0x20400000 | (7 << 24) | (2 * 168 << 6) | 8;
+ RCC->CR |= 0x1000000;
+ while(!(RCC->CR & 0x2000000));
// Switch to PLL.
- RCC.CFGR |= 0x2;
- while(!(RCC.CFGR & 0x8));
+ RCC->CFGR |= 0x2;
+ while(!(RCC->CFGR & 0x8));
// Set APB1 prescaler to /4.
- RCC.CFGR |= 5 << 10;
+ RCC->CFGR |= 5 << 10;
// Set APB2 prescaler to /2.
- RCC.CFGR |= 4 << 13;
+ RCC->CFGR |= 4 << 13;
#elif defined(STM32F0)
// Enable HSI48.
- RCC.CR2 |= 1 << 16; // HSI48ON
- while(!(RCC.CR2 & (1 << 17))); // HSI48RDY
+ RCC->CR2 |= 1 << 16; // HSI48ON
+ while(!(RCC->CR2 & (1 << 17))); // HSI48RDY
// Switch to HSI48.
- RCC.CFGR |= 3 << 0; // SW = HSI48
- while((RCC.CFGR & (3 << 2)) != (3 << 2)); // SWS = HSI48
+ RCC->CFGR |= 3 << 0; // SW = HSI48
+ while((RCC->CFGR & (3 << 2)) != (3 << 2)); // SWS = HSI48
#elif defined(STM32L0)
// Enable HSI16.
- RCC.CR |= 1 << 0; // HSI16ON
- while(!(RCC.CR & (1 << 2))); // HSI16RDYF
+ RCC->CR |= 1 << 0; // HSI16ON
+ while(!(RCC->CR & (1 << 2))); // HSI16RDYF
// Configure PLL.
- RCC.CFGR |= (1 << 22) | (1 << 18) | (0 << 16); // PLLDIV = /2, PLLMUL = 4x, PLLSRC = HSI16
+ RCC->CFGR |= (1 << 22) | (1 << 18) | (0 << 16); // PLLDIV = /2, PLLMUL = 4x, PLLSRC = HSI16
// Enable PLL.
- RCC.CR |= 1 << 24; // PLLON
- while(!(RCC.CR & (1 << 25))); // PLLRDY
+ RCC->CR |= 1 << 24; // PLLON
+ while(!(RCC->CR & (1 << 25))); // PLLRDY
// Switch to PLL.
- RCC.CFGR |= 3 << 0; // SW = PLL
- while((RCC.CFGR & (3 << 2)) != (3 << 2)); // SWS = PLL
+ RCC->CFGR |= 3 << 0; // SW = PLL
+ while((RCC->CFGR & (3 << 2)) != (3 << 2)); // SWS = PLL
// Enable VREFINT for HSI48.
- RCC.enable(RCC.SYSCFG);
+ RCC->enable(RCC->SYSCFG);
SYSCFG.CFGR3 |= (1 << 13) | (1 << 0); // ENREF_HSI48, EN_VREFINT
while(!(SYSCFG.CFGR3 & (1 << 26))); // REF_HSI48_RDYF
// Enable HSI48.
- RCC.CRRCR |= 1 << 0; // HSI48ON
- while(!(RCC.CRRCR & (1 << 1))); // HSI48RDY
+ RCC->CRRCR |= 1 << 0; // HSI48ON
+ while(!(RCC->CRRCR & (1 << 1))); // HSI48RDY
// Select HSI48 for USB.
- RCC.CCIPR |= 1 << 26;
+ RCC->CCIPR |= 1 << 26;
#endif
}
@@ -99,30 +99,30 @@ void rcc_init(uint32_t osc_mhz, uint32_t sysclk_mhz) {
uint32_t pllp = sysclk_mhz > 192 / 2 ? 0 : 1;
// Enable HSE.
- RCC.CR |= 0x10000;
- while(!(RCC.CR & 0x20000));
+ RCC->CR |= 0x10000;
+ while(!(RCC->CR & 0x20000));
// Configure and enable PLL.
- RCC.PLLCFGR = 0x20400000 | ((pll_mhz / 48) << 24) | (pllp << 16) | (pll_mhz << 6) | osc_mhz;
- RCC.CR |= 0x1000000;
- while(!(RCC.CR & 0x2000000));
+ RCC->PLLCFGR = 0x20400000 | ((pll_mhz / 48) << 24) | (pllp << 16) | (pll_mhz << 6) | osc_mhz;
+ RCC->CR |= 0x1000000;
+ while(!(RCC->CR & 0x2000000));
// Switch to PLL.
- RCC.CFGR |= 0x2;
- while(!(RCC.CFGR & 0x8));
+ RCC->CFGR |= 0x2;
+ while(!(RCC->CFGR & 0x8));
if(sysclk_mhz > 84) {
// Set APB1 prescaler to /4.
- RCC.CFGR |= 5 << 10; // PPRE1
+ RCC->CFGR |= 5 << 10; // PPRE1
// Set APB2 prescaler to /2.
- RCC.CFGR |= 4 << 13; // PPRE2
+ RCC->CFGR |= 4 << 13; // PPRE2
} else {
// Set APB1 prescaler to /2.
- RCC.CFGR |= 4 << 10; // PPRE1
+ RCC->CFGR |= 4 << 10; // PPRE1
// Set APB2 prescaler to /1.
- RCC.CFGR |= 0 << 13; // PPRE2
+ RCC->CFGR |= 0 << 13; // PPRE2
}
}
diff --git a/rcc/rcc.h b/rcc/rcc.h
deleted file mode 100644
index a4616f5..0000000
--- a/rcc/rcc.h
+++ /dev/null
@@ -1,428 +0,0 @@
-#ifndef RCC_H
-#define RCC_H
-
-#include <stdint.h>
-
-struct RCC_t {
- #if defined(STM32F0)
- volatile uint32_t CR;
- volatile uint32_t CFGR;
- volatile uint32_t CIR;
- volatile uint32_t APB2RSTR;
- volatile uint32_t APB1RSTR;
- volatile uint32_t AHBENR;
- volatile uint32_t APB2ENR;
- volatile uint32_t APB1ENR;
- volatile uint32_t BDCR;
- volatile uint32_t CSR;
- volatile uint32_t AHBRSTR;
- volatile uint32_t CFGR2;
- volatile uint32_t CFGR3;
- volatile uint32_t CR2;
- #elif defined(STM32F1)
- volatile uint32_t CR;
- volatile uint32_t CFGR;
- volatile uint32_t CIR;
- volatile uint32_t APB2RSTR;
- volatile uint32_t APB1RSTR;
- volatile uint32_t AHBENR;
- volatile uint32_t APB2ENR;
- volatile uint32_t APB1ENR;
- volatile uint32_t BDCR;
- volatile uint32_t CSR;
- #elif defined(STM32F3)
- volatile uint32_t CR;
- volatile uint32_t CFGR;
- volatile uint32_t CIR;
- volatile uint32_t APB2RSTR;
- volatile uint32_t APB1RSTR;
- volatile uint32_t AHBENR;
- volatile uint32_t APB2ENR;
- volatile uint32_t APB1ENR;
- volatile uint32_t BDCR;
- volatile uint32_t CSR;
- volatile uint32_t AHBRSTR;
- volatile uint32_t CFGR2;
- volatile uint32_t CFGR3;
- #elif defined(STM32F4)
- volatile uint32_t CR;
- volatile uint32_t PLLCFGR;
- volatile uint32_t CFGR;
- volatile uint32_t CIR;
- volatile uint32_t AHB1RSTR;
- volatile uint32_t AHB2RSTR;
- volatile uint32_t AHB3RSTR;
- volatile uint32_t AHB4RSTR; // Reserved
- volatile uint32_t APB1RSTR;
- volatile uint32_t APB2RSTR;
- volatile uint32_t APB3RSTR; // Reserved
- volatile uint32_t APB4RSTR; // Reserved
- volatile uint32_t AHB1ENR;
- volatile uint32_t AHB2ENR;
- volatile uint32_t AHB3ENR;
- volatile uint32_t AHB4ENR; // Reserved
- volatile uint32_t APB1ENR;
- volatile uint32_t APB2ENR;
- volatile uint32_t APB3ENR; // Reserved
- volatile uint32_t APB4ENR; // Reserved
- volatile uint32_t AHB1LPENR;
- volatile uint32_t AHB2LPENR;
- volatile uint32_t AHB3LPENR;
- volatile uint32_t AHB4LPENR; // Reserved
- volatile uint32_t APB1LPENR;
- volatile uint32_t APB2LPENR;
- volatile uint32_t APB3LPENR; // Reserved
- volatile uint32_t APB4LPENR; // Reserved
- volatile uint32_t BDCR;
- volatile uint32_t CSR;
- volatile uint32_t _1;
- volatile uint32_t _2;
- volatile uint32_t SSCGR;
- volatile uint32_t PLLI2SCFGR;
- #elif defined(STM32L0)
- volatile uint32_t CR;
- volatile uint32_t ICSCR;
- volatile uint32_t CRRCR;
- volatile uint32_t CFGR;
- volatile uint32_t CIER;
- volatile uint32_t CIFR;
- volatile uint32_t CICR;
- volatile uint32_t IOPRSTR;
- volatile uint32_t AHBRSTR;
- volatile uint32_t APB2RSTR;
- volatile uint32_t APB1RSTR;
- volatile uint32_t IOPENR;
- volatile uint32_t AHBENR;
- volatile uint32_t APB2ENR;
- volatile uint32_t APB1ENR;
- volatile uint32_t IOPSMENR;
- volatile uint32_t AHBSMENR;
- volatile uint32_t APB2SMENR;
- volatile uint32_t APB1SMENR;
- volatile uint32_t CCIPR;
- volatile uint32_t CSR;
- #endif
-
- #if defined(STM32F0)
- enum AHB_dev {
- DMA1 = 1 << 0,
- DMA2 = 1 << 1,
- SRAM = 1 << 2,
- FLITF = 1 << 4,
- CRC = 1 << 6,
- GPIOA = 1 << 17,
- GPIOB = 1 << 18,
- GPIOC = 1 << 19,
- GPIOD = 1 << 20,
- GPIOE = 1 << 21,
- GPIOF = 1 << 22,
- TSC = 1 << 24,
- };
-
- enum APB1_dev {
- TIM2 = 1 << 0,
- TIM3 = 1 << 1,
- TIM6 = 1 << 4,
- TIM7 = 1 << 5,
- TIM14 = 1 << 8,
- WWDG = 1 << 11,
- SPI2 = 1 << 14,
- USART2 = 1 << 17,
- USART3 = 1 << 18,
- USART4 = 1 << 19,
- USART5 = 1 << 20,
- I2C1 = 1 << 21,
- I2C2 = 1 << 22,
- USB = 1 << 23,
- CAN = 1 << 25,
- CRS = 1 << 27,
- PWR = 1 << 28,
- DAC = 1 << 29,
- CEC = 1 << 30,
- };
-
- enum APB2_dev {
- SYSCFG = 1 << 0,
- USART6 = 1 << 5,
- USART7 = 1 << 6,
- USART8 = 1 << 7,
- ADC = 1 << 9,
- TIM1 = 1 << 11,
- SPI1 = 1 << 12,
- USART1 = 1 << 14,
- TIM15 = 1 << 16,
- TIM16 = 1 << 17,
- TIM17 = 1 << 18,
- DBGMCU = 1 << 22,
- };
-
- #elif defined(STM32F1)
- enum AHB_dev {
- DMA1 = 1 << 0,
- DMA2 = 1 << 1,
- SRAM = 1 << 2,
- FLITF = 1 << 4,
- CRC = 1 << 6,
- FSMC = 1 << 8,
- SDIO = 1 << 10
- };
-
- enum APB1_dev {
- TIM2 = 1 << 0,
- TIM3 = 1 << 1,
- TIM4 = 1 << 2,
- TIM5 = 1 << 3,
- TIM6 = 1 << 4,
- TIM7 = 1 << 5,
- TIM12 = 1 << 6,
- TIM13 = 1 << 7,
- TIM14 = 1 << 8,
- WWDG = 1 << 11,
- SPI2 = 1 << 14,
- SPI3 = 1 << 15,
- USART2 = 1 << 17,
- USART3 = 1 << 18,
- UART4 = 1 << 19,
- UART5 = 1 << 20,
- I2C1 = 1 << 21,
- I2C2 = 1 << 22,
- USB = 1 << 23,
- CAN = 1 << 25,
- BKP = 1 << 27,
- PWR = 1 << 28,
- DAC = 1 << 29
- };
-
- enum APB2_dev {
- AFIO = 1 << 0,
- GPIOA = 1 << 2,
- GPIOB = 1 << 3,
- GPIOC = 1 << 4,
- GPIOD = 1 << 5,
- GPIOE = 1 << 6,
- GPIOF = 1 << 7,
- GPIOG = 1 << 8,
- ADC1 = 1 << 9,
- ADC2 = 1 << 10,
- TIM1 = 1 << 11,
- SPI1 = 1 << 12,
- TIM8 = 1 << 13,
- USART1 = 1 << 14,
- ADC3 = 1 << 15,
- TIM9 = 1 << 19,
- TIM10 = 1 << 20,
- TIM11 = 1 << 21
- };
- #elif defined(STM32F3)
- enum AHB_dev {
- DMA1 = 1 << 0,
- DMA2 = 1 << 1,
- SRAM = 1 << 2,
- FLITF = 1 << 4,
- CRC = 1 << 6,
- GPIOA = 1 << 17,
- GPIOB = 1 << 18,
- GPIOC = 1 << 19,
- GPIOD = 1 << 20,
- GPIOE = 1 << 21,
- GPIOF = 1 << 22,
- TSC = 1 << 24,
- ADC12 = 1 << 28,
- ADC34 = 1 << 29,
- };
-
- enum APB1_dev {
- TIM2 = 1 << 0,
- TIM3 = 1 << 1,
- TIM4 = 1 << 2,
- TIM6 = 1 << 4,
- TIM7 = 1 << 5,
- WWDG = 1 << 11,
- SPI2 = 1 << 14,
- SPI3 = 1 << 15,
- USART2 = 1 << 17,
- USART3 = 1 << 18,
- UART4 = 1 << 19,
- UART5 = 1 << 20,
- I2C1 = 1 << 21,
- I2C2 = 1 << 22,
- USB = 1 << 23,
- CAN = 1 << 25,
- PWR = 1 << 28,
- DAC = 1 << 29,
- };
-
- enum APB2_dev {
- SYSCFG = 1 << 0,
- TIM1 = 1 << 11,
- SPI1 = 1 << 12,
- TIM8 = 1 << 13,
- USART1 = 1 << 14,
- TIM15 = 1 << 16,
- TIM16 = 1 << 17,
- TIM17 = 1 << 18,
- };
- #elif defined(STM32F4)
- enum AHB1_dev {
- GPIOA = 1 << 0,
- GPIOB = 1 << 1,
- GPIOC = 1 << 2,
- GPIOD = 1 << 3,
- GPIOE = 1 << 4,
- GPIOF = 1 << 5,
- GPIOG = 1 << 6,
- GPIOH = 1 << 7,
- GPIOI = 1 << 8,
- CRC = 1 << 12,
- DMA1 = 1 << 21,
- DMA2 = 1 << 22,
- ETHMAC = 1 << 25,
- ETHMACTX = 1 << 26,
- ETHMACRX = 1 << 27,
- ETHMACPTP = 1 << 28,
- OTGHS = 1 << 29,
- OTGHSULPI = 1 << 30,
- };
-
- enum AHB2_dev {
- DCMI = 1 << 0,
- CRYP = 1 << 4,
- HASH = 1 << 5,
- RNG = 1 << 6,
- OTGFS = 1 << 7,
- };
-
- enum AHB3_dev {
- FSMC = 1 << 0,
- };
-
- enum APB1_dev {
- TIM2 = 1 << 0,
- TIM3 = 1 << 1,
- TIM4 = 1 << 2,
- TIM5 = 1 << 3,
- TIM6 = 1 << 4,
- TIM7 = 1 << 5,
- TIM12 = 1 << 6,
- TIM13 = 1 << 7,
- TIM14 = 1 << 8,
- WWDG = 1 << 11,
- SPI2 = 1 << 14,
- SPI3 = 1 << 15,
- USART2 = 1 << 17,
- USART3 = 1 << 18,
- UART4 = 1 << 19,
- UART5 = 1 << 20,
- I2C1 = 1 << 21,
- I2C2 = 1 << 22,
- I2C3 = 1 << 23,
- CAN1 = 1 << 25,
- CAN2 = 1 << 26,
- PWR = 1 << 28,
- DAC = 1 << 29,
- };
-
- enum APB2_dev {
- TIM1 = 1 << 0,
- TIM8 = 1 << 1,
- USART1 = 1 << 4,
- USART6 = 1 << 5,
- ADC = 1 << 8,
- SDIO = 1 << 11,
- SPI1 = 1 << 12,
- SYSCFG = 1 << 14,
- TIM9 = 1 << 16,
- TIM10 = 1 << 17,
- TIM11 = 1 << 18,
- };
- #elif defined(STM32L0)
- enum AHB_dev {
- DMA = 1 << 0,
- MIF = 1 << 8,
- CRC = 1 << 12,
- TOUCH = 1 << 16,
- RNG = 1 << 20,
- CRYP = 1 << 24,
- };
-
- enum APB1_dev {
- TIM2 = 1 << 0,
- TIM6 = 1 << 4,
- WWDG = 1 << 11,
- SPI2 = 1 << 14,
- USART2 = 1 << 17,
- LPUART1 = 1 << 18,
- I2C1 = 1 << 21,
- I2C2 = 1 << 22,
- USB = 1 << 23,
- CRS = 1 << 27,
- PWR = 1 << 28,
- DAC = 1 << 29,
- LPTIM1 = 1 << 31,
- };
-
- enum APB2_dev {
- SYSCFG = 1 << 0,
- TIM21 = 1 << 2,
- TIM22 = 1 << 5,
- MIFI = 1 << 7,
- ADC = 1 << 9,
- SPI1 = 1 << 12,
- USART1 = 1 << 14,
- DBG = 1 << 22,
- };
-
- enum IOP_dev {
- GPIOA = 1 << 0,
- GPIOB = 1 << 1,
- GPIOC = 1 << 2,
- GPIOD = 1 << 3,
- GPIOH = 1 << 7,
- };
- #endif
-
- #if defined(STM32F0) || defined(STM32F1) || defined(STM32F3) || defined(STM32L0)
- inline void enable(AHB_dev dev) {
- AHBENR |= dev;
- }
- #elif defined(STM32F4)
- inline void enable(AHB1_dev dev) {
- AHB1ENR |= dev;
- }
-
- inline void enable(AHB2_dev dev) {
- AHB2ENR |= dev;
- }
-
- inline void enable(AHB3_dev dev) {
- AHB3ENR |= dev;
- }
- #endif
- inline void enable(APB1_dev dev) {
- APB1ENR |= dev;
- }
-
- inline void enable(APB2_dev dev) {
- APB2ENR |= dev;
- }
- #if defined(STM32L0)
- inline void enable(IOP_dev dev) {
- IOPENR |= dev;
- }
- #endif
-};
-
-#if defined(STM32F0) || defined(STM32F1) || defined(STM32F3) || defined(STM32L0)
-static RCC_t& RCC = *(RCC_t*)0x40021000;
-#elif defined(STM32F4)
-static RCC_t& RCC = *(RCC_t*)0x40023800;
-#endif
-
-void rcc_init();
-
-#if defined(STM32F4)
-void rcc_init(uint32_t osc_mhz, uint32_t sysclk_mhz);
-#endif
-
-
-#endif
diff --git a/rcc/rcc_enums.h.j2 b/rcc/rcc_enums.h.j2
new file mode 100644
index 0000000..1d8bed8
--- /dev/null
+++ b/rcc/rcc_enums.h.j2
@@ -0,0 +1,17 @@
+#pragma once
+
+namespace rcc {
+ {% for bus, devices in buses.items() %}
+ enum {{ bus }}_dev {
+ {% for num, name in devices.items() %}
+ {{ name }} = 1 << {{ num }},
+ {% endfor %}
+ };
+
+ template <typename T>
+ void enable(const T& rcc, {{ bus }}_dev dev) {
+ rcc->{{ bus }}ENR |= dev;
+ }
+
+ {% endfor %}
+}
diff --git a/rcc/rcc_reg.h b/rcc/rcc_reg.h
new file mode 100644
index 0000000..f9f3735
--- /dev/null
+++ b/rcc/rcc_reg.h
@@ -0,0 +1,123 @@
+#pragma once
+
+#include <mmio/mmio.h>
+
+#include "rcc_enums.h"
+
+struct RCC_reg_f0_t {
+ volatile uint32_t CR;
+ volatile uint32_t CFGR;
+ volatile uint32_t CIR;
+ volatile uint32_t APB2RSTR;
+ volatile uint32_t APB1RSTR;
+ volatile uint32_t AHBENR;
+ volatile uint32_t APB2ENR;
+ volatile uint32_t APB1ENR;
+ volatile uint32_t BDCR;
+ volatile uint32_t CSR;
+ volatile uint32_t AHBRSTR;
+ volatile uint32_t CFGR2;
+ volatile uint32_t CFGR3;
+ volatile uint32_t CR2;
+};
+
+struct RCC_reg_f1_t {
+ volatile uint32_t CR;
+ volatile uint32_t CFGR;
+ volatile uint32_t CIR;
+ volatile uint32_t APB2RSTR;
+ volatile uint32_t APB1RSTR;
+ volatile uint32_t AHBENR;
+ volatile uint32_t APB2ENR;
+ volatile uint32_t APB1ENR;
+ volatile uint32_t BDCR;
+ volatile uint32_t CSR;
+};
+
+struct RCC_reg_f3_t {
+ volatile uint32_t CR;
+ volatile uint32_t CFGR;
+ volatile uint32_t CIR;
+ volatile uint32_t APB2RSTR;
+ volatile uint32_t APB1RSTR;
+ volatile uint32_t AHBENR;
+ volatile uint32_t APB2ENR;
+ volatile uint32_t APB1ENR;
+ volatile uint32_t BDCR;
+ volatile uint32_t CSR;
+ volatile uint32_t AHBRSTR;
+ volatile uint32_t CFGR2;
+ volatile uint32_t CFGR3;
+};
+
+struct RCC_reg_f4_t {
+ volatile uint32_t CR;
+ volatile uint32_t PLLCFGR;
+ volatile uint32_t CFGR;
+ volatile uint32_t CIR;
+ volatile uint32_t AHB1RSTR;
+ volatile uint32_t AHB2RSTR;
+ volatile uint32_t AHB3RSTR;
+ volatile uint32_t AHB4RSTR; // Reserved
+ volatile uint32_t APB1RSTR;
+ volatile uint32_t APB2RSTR;
+ volatile uint32_t APB3RSTR; // Reserved
+ volatile uint32_t APB4RSTR; // Reserved
+ volatile uint32_t AHB1ENR;
+ volatile uint32_t AHB2ENR;
+ volatile uint32_t AHB3ENR;
+ volatile uint32_t AHB4ENR; // Reserved
+ volatile uint32_t APB1ENR;
+ volatile uint32_t APB2ENR;
+ volatile uint32_t APB3ENR; // Reserved
+ volatile uint32_t APB4ENR; // Reserved
+ volatile uint32_t AHB1LPENR;
+ volatile uint32_t AHB2LPENR;
+ volatile uint32_t AHB3LPENR;
+ volatile uint32_t AHB4LPENR; // Reserved
+ volatile uint32_t APB1LPENR;
+ volatile uint32_t APB2LPENR;
+ volatile uint32_t APB3LPENR; // Reserved
+ volatile uint32_t APB4LPENR; // Reserved
+ volatile uint32_t BDCR;
+ volatile uint32_t CSR;
+ volatile uint32_t _1;
+ volatile uint32_t _2;
+ volatile uint32_t SSCGR;
+ volatile uint32_t PLLI2SCFGR;
+};
+
+struct RCC_reg_l0_t {
+ volatile uint32_t CR;
+ volatile uint32_t ICSCR;
+ volatile uint32_t CRRCR;
+ volatile uint32_t CFGR;
+ volatile uint32_t CIER;
+ volatile uint32_t CIFR;
+ volatile uint32_t CICR;
+ volatile uint32_t IOPRSTR;
+ volatile uint32_t AHBRSTR;
+ volatile uint32_t APB2RSTR;
+ volatile uint32_t APB1RSTR;
+ volatile uint32_t IOPENR;
+ volatile uint32_t AHBENR;
+ volatile uint32_t APB2ENR;
+ volatile uint32_t APB1ENR;
+ volatile uint32_t IOPSMENR;
+ volatile uint32_t AHBSMENR;
+ volatile uint32_t APB2SMENR;
+ volatile uint32_t APB1SMENR;
+ volatile uint32_t CCIPR;
+ volatile uint32_t CSR;
+};
+
+template <typename T>
+class RCC_t : public mmio_ptr<T> {
+ public:
+ using mmio_ptr<T>::ptr;
+
+ template <typename Bus>
+ void enable(Bus dev) const {
+ rcc::enable(*this, dev);
+ }
+};