From 3c526f3d0b30e200462290651f7c6a5eb30710a2 Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Wed, 3 Apr 2019 17:14:01 +0200 Subject: Added STM32WB support. --- build_rules | 8 +++ gpio/gpio.h | 23 ++++--- ipc/ipcc.h | 23 +++++++ ld_scripts/stm32_wb_g.ld | 8 +++ pwr/pwr.h | 30 +++++++++ rcc/flash.h | 26 ++++++++ rcc/rcc.h | 154 ++++++++++++++++++++++++++++++++++++++++++++++- usb/usb.h | 5 ++ 8 files changed, 268 insertions(+), 9 deletions(-) create mode 100644 ipc/ipcc.h create mode 100644 ld_scripts/stm32_wb_g.ld create mode 100644 pwr/pwr.h diff --git a/build_rules b/build_rules index 81547eb..fc7fd75 100644 --- a/build_rules +++ b/build_rules @@ -97,6 +97,14 @@ def select_stm32(env, variant): '8': 'stm32_l0_8.ld', }[flash] + elif family == 'wb55': + select_arm(env, 'cortex-m4f') + env.Append(CPPDEFINES = ['STM32WB']) + + env['LINK_SCRIPT'] = { + 'g': 'stm32_wb_g.ld', + }[flash] + else: print 'Unknown stm32 family: %s' % family Exit(1) diff --git a/gpio/gpio.h b/gpio/gpio.h index d764194..392b2f7 100644 --- a/gpio/gpio.h +++ b/gpio/gpio.h @@ -12,7 +12,7 @@ struct GPIO_reg_t { volatile uint32_t BSRR; volatile uint32_t BRR; volatile uint32_t LCKR; - #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) volatile uint32_t MODER; volatile uint32_t OTYPER; volatile uint32_t OSPEEDR; @@ -45,7 +45,7 @@ class GPIO_t { Output = 0x3, AF = 0xb, Analog = 0x0, - #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) Input, Output, AF, @@ -78,7 +78,7 @@ class GPIO_t { } else { g.reg.CRH = (g.reg.CRH & ~(0xf << (n * 4 - 32))) | m << (n * 4 - 32); } - #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) g.reg.MODER = (g.reg.MODER & ~(3 << (n * 2))) | m << (n * 2); #endif } @@ -86,7 +86,7 @@ class GPIO_t { void set_type(Type t) { #if defined(STM32F1) // TODO: Unified configure() method? - #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) if(t) { g.reg.OTYPER |= 1 << n; } else { @@ -98,13 +98,13 @@ class GPIO_t { void set_pull(Pull p) { #if defined(STM32F1) // TODO: Unified configure() method? - #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) + #elif defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) g.reg.PUPDR = (g.reg.PUPDR & ~(3 << (n * 2))) | p << (n * 2); #endif } void set_af(int af) { - #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) + #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) if(n < 8) { g.reg.AFRL = (g.reg.AFRL & ~(0xf << (n * 4))) | af << (n * 4); } else { @@ -114,7 +114,7 @@ class GPIO_t { } void set_speed(Speed s) { - #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) + #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) g.reg.OSPEEDR = (g.reg.OSPEEDR & ~(3 << (n * 2))) | s << (n * 2); #endif } @@ -161,7 +161,7 @@ class GPIO_t { public: constexpr PinArray(const GPIO_t& gpio, int first, int last) : g(gpio), f(first), l(last) {} - #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) + #if defined(STM32F3) || defined(STM32F4) || defined(STM32L0) || defined(STM32WB) void set_mode(Pin::Mode m) { g.reg.MODER = (g.reg.MODER & ~mask2()) | ((0x55555555 * m) & mask2()); } @@ -228,6 +228,13 @@ static GPIO_t GPIOB(0x50000400); static GPIO_t GPIOC(0x50000800); static GPIO_t GPIOD(0x50000c00); static GPIO_t GPIOH(0x50001c00); +#elif defined(STM32WB) +static GPIO_t GPIOA(0x48000000); +static GPIO_t GPIOB(0x48000400); +static GPIO_t GPIOC(0x48000800); +static GPIO_t GPIOD(0x48000c00); +static GPIO_t GPIOE(0x48001000); +static GPIO_t GPIOH(0x48001c00); #endif #endif diff --git a/ipc/ipcc.h b/ipc/ipcc.h new file mode 100644 index 0000000..f49d465 --- /dev/null +++ b/ipc/ipcc.h @@ -0,0 +1,23 @@ +#ifndef IPCC_H +#define IPCC_H + +#include + +#if defined(STM32WB) + +struct IPCC_t { + volatile uint32_t C1CR; + volatile uint32_t C1MR; + volatile uint32_t C1SCR; + volatile uint32_t C1TOC2SR; + volatile uint32_t C2CR; + volatile uint32_t C2MR; + volatile uint32_t C2SCR; + volatile uint32_t C2TOC1SR; +}; + +static IPCC_t& IPCC = *(IPCC_t*)0x58000c00; + +#endif + +#endif diff --git a/ld_scripts/stm32_wb_g.ld b/ld_scripts/stm32_wb_g.ld new file mode 100644 index 0000000..0d3b0ee --- /dev/null +++ b/ld_scripts/stm32_wb_g.ld @@ -0,0 +1,8 @@ +MEMORY { + flash (rx) : org = 0x08000000, len = 1024k + ram (rwx) : org = 0x20000000, len = 192k + sram2a (rwx) : org = 0x20030000, len = 32k + sram2b (rwx) : org = 0x20038000, len = 32k +} + +INCLUDE "arm_flash_ram.ld" diff --git a/pwr/pwr.h b/pwr/pwr.h new file mode 100644 index 0000000..15ff8d2 --- /dev/null +++ b/pwr/pwr.h @@ -0,0 +1,30 @@ +#ifndef PWR_H +#define PWR_H + +#include + +#if defined(STM32WB) + +struct PWR_t { + volatile uint32_t CR1; + volatile uint32_t CR2; + volatile uint32_t CR3; + volatile uint32_t CR4; + volatile uint32_t SR1; + volatile uint32_t SR2; + volatile uint32_t SCR; + volatile uint32_t CR5; + struct { + volatile uint32_t PU; + volatile uint32_t PD; + } PCR[12]; + volatile uint32_t C2CR1; + volatile uint32_t C2CR2; + volatile uint32_t EXTSCR; +}; + +static PWR_t& PWR = *(PWR_t*)0x58000400; + +#endif + +#endif diff --git a/rcc/flash.h b/rcc/flash.h index c1f7c1c..97875c6 100644 --- a/rcc/flash.h +++ b/rcc/flash.h @@ -31,6 +31,30 @@ struct FLASH_t { volatile uint32_t SR; volatile uint32_t OPTR; volatile uint32_t WRPROT; + #elif defined(STM32WB) + volatile uint32_t ACR; + uint32_t _reserved; + volatile uint32_t KEYR; + volatile uint32_t OPTKEYR; + volatile uint32_t SR; + volatile uint32_t CR; + volatile uint32_t ECCR; + uint32_t _reserved_1; + volatile uint32_t OPTR; + volatile uint32_t PCROP1ASR; + volatile uint32_t PCROP1AER; + volatile uint32_t WRP1AR; + volatile uint32_t WRP1BR; + volatile uint32_t PCROP1BSR; + volatile uint32_t PCROP1BER; + volatile uint32_t IPCCBR; + uint32_t _reserved_2[7]; + volatile uint32_t C2ACR; + volatile uint32_t C2SR; + volatile uint32_t C2CR; + uint32_t _reserved_3[6]; + volatile uint32_t SFR; + volatile uint32_t SRRVR; #endif }; @@ -40,6 +64,8 @@ static FLASH_t& FLASH = *(FLASH_t*)0x40022000; static FLASH_t& FLASH = *(FLASH_t*)0x40023c00; #elif defined(STM32L0) static FLASH_t& FLASH = *(FLASH_t*)0x40022000; +#elif defined(STM32WB) +static FLASH_t& FLASH = *(FLASH_t*)0x58004000; #endif void flash_init(); diff --git a/rcc/rcc.h b/rcc/rcc.h index fec5aa1..9b9331e 100644 --- a/rcc/rcc.h +++ b/rcc/rcc.h @@ -86,6 +86,67 @@ struct RCC_t { volatile uint32_t APB1SMENR; volatile uint32_t CCIPR; volatile uint32_t CSR; + #elif defined(STM32WB) + volatile uint32_t CR; + volatile uint32_t ICSCR; + volatile uint32_t CFGR; + volatile uint32_t PLLCFGR; + volatile uint32_t PLLSAI1CFGR; + uint32_t _reserved; + volatile uint32_t CIER; + volatile uint32_t CIFR; + volatile uint32_t CICR; + volatile uint32_t SMPSCR; + volatile uint32_t AHB1RSTR; + volatile uint32_t AHB2RSTR; + volatile uint32_t AHB3RSTR; + uint32_t _reserved_1; + volatile uint32_t APB1RSTR1; + volatile uint32_t APB1RSTR2; + volatile uint32_t APB2RSTR; + volatile uint32_t APB3RSTR; + volatile uint32_t AHB1ENR; + volatile uint32_t AHB2ENR; + volatile uint32_t AHB3ENR; + uint32_t _reserved_2; + volatile uint32_t APB1ENR1; + volatile uint32_t APB1ENR2; + volatile uint32_t APB2ENR; + uint32_t _reserved_3; + volatile uint32_t AHB1SMENR; + volatile uint32_t AHB2SMENR; + volatile uint32_t AHB3SMENR; + uint32_t _reserved_4; + volatile uint32_t APB1SMENR1; + volatile uint32_t APB1SMENR2; + volatile uint32_t APB2SMENR; + uint32_t _reserved_5; + volatile uint32_t CCIPR; + uint32_t _reserved_6; + volatile uint32_t BDCR; + volatile uint32_t CSR; + volatile uint32_t CRRCR; + volatile uint32_t HSECR; + uint32_t _reserved_7[26]; + volatile uint32_t EXTCFGR; + uint32_t _reserved_8[15]; + // TODO: more + volatile uint32_t C2AHB1ENR; + volatile uint32_t C2AHB2ENR; + volatile uint32_t C2AHB3ENR; + uint32_t _reserved_9; + volatile uint32_t C2APB1ENR1; + volatile uint32_t C2APB1ENR2; + volatile uint32_t C2APB2ENR; + volatile uint32_t C2APB3ENR; + volatile uint32_t C2AHB1SMENR; + volatile uint32_t C2AHB2SMENR; + volatile uint32_t C2AHB3SMENR; + uint32_t _reserved_10; + volatile uint32_t C2APB1SMENR1; + volatile uint32_t C2APB1SMENR2; + volatile uint32_t C2APB2SMENR; + volatile uint32_t C2APB3SMENR; #endif #if defined(STM32F1) @@ -311,12 +372,76 @@ struct RCC_t { GPIOD = 1 << 3, GPIOH = 1 << 7, }; + #elif defined(STM32WB) + enum AHB1_dev { + DMA1 = 1 << 0, + DMA2 = 1 << 1, + DMAMUX1 = 1 << 2, + CRC = 1 << 12, + TSC = 1 << 16, + }; + + enum AHB2_dev { + GPIOA = 1 << 0, + GPIOB = 1 << 1, + GPIOC = 1 << 2, + GPIOD = 1 << 3, + GPIOE = 1 << 4, + GPIOH = 1 << 7, + ADC = 1 << 13, + AES1 = 1 << 16, + }; + + enum AHB3_dev { + QUADSPI = 1 << 8, + PKA = 1 << 16, + AES2 = 1 << 17, + RNG = 1 << 18, + HSEM = 1 << 19, + IPCC = 1 << 20, + FLASH = 1 << 25, + }; + + enum APB1_dev { + TIM2 = 1 << 0, + LCD = 1 << 9, + RTCAPB = 1 << 10, + WWDG = 1 << 11, + SPI2 = 1 << 14, + I2C1 = 1 << 21, + I2C3 = 1 << 23, + CRS = 1 << 24, + USB = 1 << 26, + LPTIM1 = 1 << 31, + }; + + enum APB1_2_dev { + LPUART1 = 1 << 0, + LPTIM2 = 1 << 5, + }; + + enum APB2_dev { + TIM1 = 1 << 11, + SPI1 = 1 << 12, + USART1 = 1 << 14, + TIM16 = 1 << 17, + TIM17 = 1 << 18, + SAI1 = 1 << 21, + }; #endif #if defined(STM32F1) || defined(STM32F3) || defined(STM32L0) inline void enable(AHB_dev dev) { AHBENR |= dev; } + + inline void enable(APB1_dev dev) { + APB1ENR |= dev; + } + + inline void enable(APB2_dev dev) { + APB2ENR |= dev; + } #elif defined(STM32F4) inline void enable(AHB1_dev dev) { AHB1ENR |= dev; @@ -329,7 +454,7 @@ struct RCC_t { inline void enable(AHB3_dev dev) { AHB3ENR |= dev; } - #endif + inline void enable(APB1_dev dev) { APB1ENR |= dev; } @@ -337,6 +462,31 @@ struct RCC_t { inline void enable(APB2_dev dev) { APB2ENR |= dev; } + #elif defined(STM32WB) + inline void enable(AHB1_dev dev) { + AHB1ENR |= dev; + } + + inline void enable(AHB2_dev dev) { + AHB2ENR |= dev; + } + + inline void enable(AHB3_dev dev) { + AHB3ENR |= dev; + } + + inline void enable(APB1_dev dev) { + APB1ENR1 |= dev; + } + + inline void enable(APB1_2_dev dev) { + APB1ENR2 |= dev; + } + + inline void enable(APB2_dev dev) { + APB2ENR |= dev; + } + #endif #if defined(STM32L0) inline void enable(IOP_dev dev) { IOPENR |= dev; @@ -348,6 +498,8 @@ struct RCC_t { static RCC_t& RCC = *(RCC_t*)0x40021000; #elif defined(STM32F4) static RCC_t& RCC = *(RCC_t*)0x40023800; +#elif defined(STM32WB) +static RCC_t& RCC = *(RCC_t*)0x58000000; #endif void rcc_init(); diff --git a/usb/usb.h b/usb/usb.h index f37f4a1..e57867c 100644 --- a/usb/usb.h +++ b/usb/usb.h @@ -17,6 +17,11 @@ static DWC_OTG_t OTG_HS(0x40040000); static L0_USB_t USB(0x40005c00, 0x40006000); +#elif defined(STM32WB) +#include "l0_usb.h" + +static L0_USB_t USB(0x40006800, 0x40006c00); + #endif #endif -- cgit v1.2.3