From 18c4d299c1f3509e7a56691f7a81b1c458d12236 Mon Sep 17 00:00:00 2001 From: BuFran Date: Mon, 8 Jul 2013 14:44:21 +0200 Subject: [PATCH] [STM32F0] Add preliminary support for the family --- Makefile | 2 +- include/libopencm3/dispatch/nvic.h | 4 +- include/libopencm3/stm32/crc.h | 4 +- include/libopencm3/stm32/f0/crc.h | 47 ++ include/libopencm3/stm32/f0/flash.h | 114 +++++ include/libopencm3/stm32/f0/gpio.h | 52 ++ include/libopencm3/stm32/f0/irq.yaml | 36 ++ include/libopencm3/stm32/f0/memorymap.h | 101 ++++ include/libopencm3/stm32/f0/pwr.h | 44 ++ include/libopencm3/stm32/f0/rcc.h | 459 +++++++++++++++++ include/libopencm3/stm32/flash.h | 5 +- include/libopencm3/stm32/gpio.h | 4 +- include/libopencm3/stm32/memorymap.h | 4 +- include/libopencm3/stm32/pwr.h | 5 +- include/libopencm3/stm32/rcc.h | 4 +- lib/dispatch/vector_nvic.c | 4 +- lib/stm32/f0/Makefile | 44 ++ lib/stm32/f0/flash.c | 93 ++++ lib/stm32/f0/libopencm3_stm32f0.ld | 106 ++++ lib/stm32/f0/rcc.c | 637 ++++++++++++++++++++++++ 20 files changed, 1758 insertions(+), 11 deletions(-) create mode 100644 include/libopencm3/stm32/f0/crc.h create mode 100644 include/libopencm3/stm32/f0/flash.h create mode 100644 include/libopencm3/stm32/f0/gpio.h create mode 100644 include/libopencm3/stm32/f0/irq.yaml create mode 100644 include/libopencm3/stm32/f0/memorymap.h create mode 100644 include/libopencm3/stm32/f0/pwr.h create mode 100644 include/libopencm3/stm32/f0/rcc.h create mode 100644 lib/stm32/f0/Makefile create mode 100644 lib/stm32/f0/flash.c create mode 100644 lib/stm32/f0/libopencm3_stm32f0.ld create mode 100644 lib/stm32/f0/rcc.c diff --git a/Makefile b/Makefile index 1531d7af..fc311fe2 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ INSTALL := install SRCLIBDIR:= $(realpath lib) -TARGETS:= stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/l1 lpc13xx lpc17xx \ +TARGETS:= stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/l1 lpc13xx lpc17xx \ lpc43xx/m4 lpc43xx/m0 lm3s lm4f \ efm32/efm32tg efm32/efm32g efm32/efm32lg efm32/efm32gg sam/3x sam/3n diff --git a/include/libopencm3/dispatch/nvic.h b/include/libopencm3/dispatch/nvic.h index d7bf4795..d4e57167 100644 --- a/include/libopencm3/dispatch/nvic.h +++ b/include/libopencm3/dispatch/nvic.h @@ -1,4 +1,6 @@ -#if defined(STM32F1) +#if defined(STM32F0) +# include +#elif defined(STM32F1) # include #elif defined(STM32F2) # include diff --git a/include/libopencm3/stm32/crc.h b/include/libopencm3/stm32/crc.h index ad48cac1..a75546ef 100644 --- a/include/libopencm3/stm32/crc.h +++ b/include/libopencm3/stm32/crc.h @@ -17,7 +17,9 @@ * along with this library. If not, see . */ -#if defined(STM32F1) +#if defined(STM32F0) +# include +#elif defined(STM32F1) # include #elif defined(STM32F2) # include diff --git a/include/libopencm3/stm32/f0/crc.h b/include/libopencm3/stm32/f0/crc.h new file mode 100644 index 00000000..fc8cabac --- /dev/null +++ b/include/libopencm3/stm32/f0/crc.h @@ -0,0 +1,47 @@ +/** @defgroup crc_defines CRC Defines + * + * @brief libopencm3 Defined Constants and Types for the STM32F1xx CRC + * Generator + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 29 Jun 2013 + * + *LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_CRC_H +#define LIBOPENCM3_CRC_H + +#include +#include + +#define CRC_CR_REV_OUT (1 << 7) +#define CRC_CR_REV_IN_SHIFT 5 +#define CRC_CR_REV_IN (3 << CRC_CR_REV_IN_SHIFT) +#define CRC_CR_REV_IN_NONE (0 << CRC_CR_REV_IN_SHIFT) +#define CRC_CR_REV_IN_BYTE (1 << CRC_CR_REV_IN_SHIFT) +#define CRC_CR_REV_IN_HALF (2 << CRC_CR_REV_IN_SHIFT) +#define CRC_CR_REV_IN_WORD (3 << CRC_CR_REV_IN_SHIFT) + +#endif diff --git a/include/libopencm3/stm32/f0/flash.h b/include/libopencm3/stm32/f0/flash.h new file mode 100644 index 00000000..a75bedb7 --- /dev/null +++ b/include/libopencm3/stm32/f0/flash.h @@ -0,0 +1,114 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FLASH_H +#define LIBOPENCM3_FLASH_H + +#include +#include + +/* --- FLASH registers ----------------------------------------------------- */ + +#define FLASH_ACR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x00) +#define FLASH_KEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x04) +#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) +#define FLASH_SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) +#define FLASH_CR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) +#define FLASH_AR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) +#define FLASH_OBR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x1C) +#define FLASH_WRPR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x20) + +/* --- FLASH_ACR values ---------------------------------------------------- */ + +#define FLASH_ACR_PRFTBS (1 << 5) +#define FLASH_ACR_PRFTBE (1 << 4) +#define FLASH_ACR_LATENCY_SHIFT 0 +#define FLASH_ACR_LATENCY 7 +#define FLASH_ACR_LATENCY_000_024MHZ 0 +#define FLASH_ACR_LATENCY_024_048MHZ 1 +#define FLASH_ACR_LATENCY_0WS 0 +#define FLASH_ACR_LATENCY_1WS 1 + + +/* --- FLASH_SR values ----------------------------------------------------- */ + +#define FLASH_SR_EOP (1 << 5) +#define FLASH_SR_WRPRTERR (1 << 4) +#define FLASH_SR_PGERR (1 << 2) +#define FLASH_SR_BSY (1 << 0) + +/* --- FLASH_CR values ----------------------------------------------------- */ + +#define FLASH_CR_OBL_LAUNCH (1 << 13) +#define FLASH_CR_EOPIE (1 << 12) +#define FLASH_CR_ERRIE (1 << 10) +#define FLASH_CR_OPTWRE (1 << 9) +#define FLASH_CR_LOCK (1 << 7) +#define FLASH_CR_STRT (1 << 6) +#define FLASH_CR_OPTER (1 << 5) +#define FLASH_CR_OPTPG (1 << 4) +#define FLASH_CR_MER (1 << 2) +#define FLASH_CR_PER (1 << 1) +#define FLASH_CR_PG (1 << 0) + +/* --- FLASH_OBR values ---------------------------------------------------- */ + +#define FLASH_OBR_DATA1_SHIFT 24 +#define FLASH_OBR_DATA1 (0xFF << FLASH_OBR_DATA1_SHIFT) +#define FLASH_OBR_DATA0_SHIFT 16 +#define FLASH_OBR_DATA0 (0xFF << FLASH_OBR_DATA0_SHIFT) + +#define FLASH_OBR_RAM_PARITY_CHECK (1 << 14) +#define FLASH_OBR_VDDA_MONITOR (1 << 13) +#define FLASH_OBR_NBOOT1 (1 << 12) +#define FLASH_OBR_NRST_STDBY (1 << 10) +#define FLASH_OBR_NRST_STOP (1 << 9) +#define FLASH_OBR_WDG_SW (1 << 8) +#define FLASH_OBR_RDPRT_SHIFT 1 +#define FLASH_OBR_RDPRT (3 << FLASH_OBR_RDPRT_SHIFT) +#define FLASH_OBR_RDPRT_L0 (0 << FLASH_OBR_RDPRT_SHIFT) +#define FLASH_OBR_RDPRT_L1 (1 << FLASH_OBR_RDPRT_SHIFT) +#define FLASH_OBR_RDPRT_L2 (2 << FLASH_OBR_RDPRT_SHIFT) + +#define FLASH_OBR_OPTERR (1 << 0) + +/* --- FLASH Keys -----------------------------------------------------------*/ + +#define FLASH_RDP_L0 ((uint8_t)0xaa) +#define FLASH_RDP_L1 ((uint8_t)0xf0) /* any value */ +#define FLASH_RDP_L2 ((uint8_t)0xcc) +#define FLASH_KEYR_KEY1 ((uint32_t)0x45670123) +#define FLASH_KEYR_KEY2 ((uint32_t)0xcdef89ab) + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void flash_prefetch_buffer_enable(void); +void flash_prefetch_buffer_disable(void); +void flash_set_ws(uint32_t ws); +void flash_wait_busy(void); +void flash_program_u32(uint32_t address, uint32_t data); +void flash_program_u16(uint32_t address, uint16_t data); +void flash_erase_page(uint32_t page_address); +void flash_erase_all_pages(void); + +END_DECLS + +#endif diff --git a/include/libopencm3/stm32/f0/gpio.h b/include/libopencm3/stm32/f0/gpio.h new file mode 100644 index 00000000..c6221a5f --- /dev/null +++ b/include/libopencm3/stm32/f0/gpio.h @@ -0,0 +1,52 @@ +/** @defgroup gpio_defines GPIO Defines + * + * @brief Defined Constants and Types for the STM32F0xx General Purpose I/O + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 1 July 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_GPIO_H +#define LIBOPENCM3_GPIO_H + +#include +#include + +#define GPIO_BRR(port) MMIO32(port + 0x24) +#define GPIOA_BRR GPIO_BRR(GPIOA) +#define GPIOB_BRR GPIO_BRR(GPIOB) +#define GPIOC_BRR GPIO_BRR(GPIOC) +#define GPIOD_BRR GPIO_BRR(GPIOD) +#define GPIOF_BRR GPIO_BRR(GPIOF) + +/** @defgroup gpio_speed GPIO Output Pin Speed +@ingroup gpio_defines +@{*/ +#define GPIO_OSPEED_LOW 0x0 +#define GPIO_OSPEED_MED 0x1 +#define GPIO_OSPEED_HIGH 0x3 +/**@}*/ + +#endif diff --git a/include/libopencm3/stm32/f0/irq.yaml b/include/libopencm3/stm32/f0/irq.yaml new file mode 100644 index 00000000..90013b7c --- /dev/null +++ b/include/libopencm3/stm32/f0/irq.yaml @@ -0,0 +1,36 @@ +includeguard: LIBOPENCM3_STM32_F0_NVIC_H +partname_humanreadable: STM32 F0 series +partname_doxygen: STM32F0 +irqs: + - wwdg + - pvd + - rtc + - flash + - rcc + - exti0_1 + - exti2_3 + - exti4_15 + - tsc + - dma1_channel1 + - dma1_channel2_3 + - dma1_channel4_5 + - adc_comp + - tim1_brk_up_trg_com + - tim1_cc + - tim2 + - tim3 + - tim6_dac + - reserved0 + - tim14 + - tim15 + - tim16 + - tim17 + - i2c1 + - i2c2 + - spi1 + - spi2 + - usart1 + - usart2 + - reserved1 + - cec + - reserved2 diff --git a/include/libopencm3/stm32/f0/memorymap.h b/include/libopencm3/stm32/f0/memorymap.h new file mode 100644 index 00000000..5122a23c --- /dev/null +++ b/include/libopencm3/stm32/f0/memorymap.h @@ -0,0 +1,101 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * .. based on file from F4. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_MEMORYMAP_H +#define LIBOPENCM3_MEMORYMAP_H + +#include + +/* --- STM32 specific peripheral definitions ------------------------------- */ + +/* Memory map for all buses */ +#define FLASH_BASE ((uint32_t)0x08000000) +#define PERIPH_BASE ((uint32_t)0x40000000) +#define INFO_BASE ((uint32_t)0x1ffff000) +#define PERIPH_BASE_APB (PERIPH_BASE + 0x00000000) +#define PERIPH_BASE_AHB1 (PERIPH_BASE + 0x00020000) +#define PERIPH_BASE_AHB2 (PERIPH_BASE + 0x08000000) + +/* Register boundary addresses */ + +/* APB1 */ +#define TIM2_BASE (PERIPH_BASE_APB + 0x0000) +#define TIM3_BASE (PERIPH_BASE_APB + 0x0400) + +#define TIM6_BASE (PERIPH_BASE_APB + 0x1000) + +#define TIM14_BASE (PERIPH_BASE_APB + 0x2000) +/* PERIPH_BASE_APB1 + 0x2400 (0x4000 2400 - 0x4000 27FF): Reserved */ +#define RTC_BASE (PERIPH_BASE_APB + 0x2800) +#define WWDG_BASE (PERIPH_BASE_APB + 0x2c00) +#define IWDG_BASE (PERIPH_BASE_APB + 0x3000) +/* PERIPH_BASE_APB + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ +#define SPI2_BASE (PERIPH_BASE_APB + 0x3800) +/* PERIPH_BASE_APB + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */ +#define USART2_BASE (PERIPH_BASE_APB + 0x4400) + +#define I2C1_BASE (PERIPH_BASE_APB + 0x5400) +#define I2C2_BASE (PERIPH_BASE_APB + 0x5800) + +#define POWER_CONTROL_BASE (PERIPH_BASE_APB + 0x7000) +#define DAC_BASE (PERIPH_BASE_APB + 0x7400) +#define CEC_BASE (PERIPH_BASE_APB + 0x7800) + +#define SYSCFG_COMP_BASE (PERIPH_BASE_APB + 0x10000) +#define EXTI_BASE (PERIPH_BASE_APB + 0x10400) + +#define ADC_BASE (PERIPH_BASE_APB + 0x12400) +#define TIM1_BASE (PERIPH_BASE_APB + 0x12C00) +#define SPI1_I2S1_BASE (PERIPH_BASE_APB + 0x13000) + +#define USART1_BASE (PERIPH_BASE_APB + 0x13800) +#define TIM15_BASE (PERIPH_BASE_APB + 0x14000) +#define TIM16_BASE (PERIPH_BASE_APB + 0x14400) +#define TIM17_BASE (PERIPH_BASE_APB + 0x14800) + +#define DBGMCU_BASE (PERIPH_BASE_APB + 0x15800) + +/* AHB1 */ +#define DMA_BASE (PERIPH_BASE_AHB1 + 0x0000) + +#define RCC_BASE (PERIPH_BASE_AHB1 + 0x1000) + +#define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB1 + 0x2000) + +#define CRC_BASE (PERIPH_BASE_AHB1 + 0x3000) + +#define TSC_BASE (PERIPH_BASE_AHB1 + 0x4000) + +/* AHB2 */ +#define GPIO_PORT_A_BASE (PERIPH_BASE_AHB2 + 0x0000) +#define GPIO_PORT_B_BASE (PERIPH_BASE_AHB2 + 0x0400) +#define GPIO_PORT_C_BASE (PERIPH_BASE_AHB2 + 0x0800) +#define GPIO_PORT_D_BASE (PERIPH_BASE_AHB2 + 0x0C00) + +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB2 + 0x1400) + + +/* Device Electronic Signature */ +/* ??? +#define DESIG_FLASH_SIZE_BASE (INFO_BASE + 0x7e0) +#define DESIG_UNIQUE_ID_BASE (INFO_BASE + 0x7e8) +*/ +#endif diff --git a/include/libopencm3/stm32/f0/pwr.h b/include/libopencm3/stm32/f0/pwr.h new file mode 100644 index 00000000..ee1ac9fb --- /dev/null +++ b/include/libopencm3/stm32/f0/pwr.h @@ -0,0 +1,44 @@ +/** @defgroup pwr_defines PWR Defines + * + * @brief Defined Constants and Types for the STM32F1xx PWR Control + * + * @ingroup STM32F1xx_defines + * + * @version 1.0.0 + * + * @date 5 December 2012 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include +#include + +/* EWUP: Enable WKUP2 pin */ +#define PWR_CSR_EWUP2 (1 << 9) + +/* EWUP: Enable WKUP1 pin */ +#define PWR_CSR_EWUP1 (1 << 8) + +#endif + diff --git a/include/libopencm3/stm32/f0/rcc.h b/include/libopencm3/stm32/f0/rcc.h new file mode 100644 index 00000000..2f3e9a31 --- /dev/null +++ b/include/libopencm3/stm32/f0/rcc.h @@ -0,0 +1,459 @@ +/** @defgroup STM32F0xx_rcc_defines RCC Defines + * + * @brief libopencm3 STM32F0xx Reset and Clock Control + * + * @ingroup STM32F0xx_defines + * + * @version 1.0.0 + * + * @date 29 Jun 2013 + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ +/**@{*/ + +#ifndef LIBOPENCM3_RCC_H +#define LIBOPENCM3_RCC_H + +#include +#include + +/* --- RCC registers ------------------------------------------------------- */ + +#define RCC_CR MMIO32(RCC_BASE + 0x00) +#define RCC_CFGR MMIO32(RCC_BASE + 0x04) +#define RCC_CIR MMIO32(RCC_BASE + 0x08) +#define RCC_APB2RSTR MMIO32(RCC_BASE + 0x0c) +#define RCC_APB1RSTR MMIO32(RCC_BASE + 0x10) +#define RCC_AHBENR MMIO32(RCC_BASE + 0x14) +#define RCC_APB2ENR MMIO32(RCC_BASE + 0x18) +#define RCC_APB1ENR MMIO32(RCC_BASE + 0x1c) +#define RCC_BDCR MMIO32(RCC_BASE + 0x20) +#define RCC_CSR MMIO32(RCC_BASE + 0x24) +#define RCC_AHBRSTR MMIO32(RCC_BASE + 0x28) +#define RCC_CFGR2 MMIO32(RCC_BASE + 0x2c) +#define RCC_CFGR3 MMIO32(RCC_BASE + 0x30) +#define RCC_CR2 MMIO32(RCC_BASE + 0x32) + +/* --- RCC_CR values ------------------------------------------------------- */ + +#define RCC_CR_PLLRDY (1 << 25) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSICAL_SHIFT 8 +#define RCC_CR_HSICAL (0xFF << RCC_CR_HSICAL_SHIFT) +#define RCC_CR_HSITRIM_SHIFT 3 +#define RCC_CR_HSITRIM (0x1F << RCC_CR_HSITRIM_SHIFT) +#define RCC_CR_HSIRDY (1 << 1) +#define RCC_CR_HSION (1 << 0) + +/* --- RCC_CFGR values ----------------------------------------------------- */ + +#define RCC_CFGR_PLLNODIV (1 << 31) + +#define RCC_CFGR_MCOPRE_SHIFT 28 +#define RCC_CFGR_MCOPRE (7 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV1 (0 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV2 (1 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV4 (2 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV8 (3 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV16 (4 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV32 (5 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV64 (6 << RCC_CFGR_MCOPRE_SHIFT) +#define RCC_CFGR_MCOPRE_DIV128 (7 << RCC_CFGR_MCOPRE_SHIFT) + +#define RCC_CFGR_MCO_SHIFT 24 +#define RCC_CFGR_MCO (7 << RCC_CFGR_MCO_SHIFT) +#define RCC_CFGR_MCO_NOCLK (0 << RCC_CFGR_MCO_SHIFT) +#define RCC_CFGR_MCO_HSI14 (1 << RCC_CFGR_MCO_SHIFT) +#define RCC_CFGR_MCO_LSI (2 << RCC_CFGR_MCO_SHIFT) +#define RCC_CFGR_MCO_LSE (3 << RCC_CFGR_MCO_SHIFT) +#define RCC_CFGR_MCO_SYSCLK (4 << RCC_CFGR_MCO_SHIFT) +#define RCC_CFGR_MCO_HSI (5 << RCC_CFGR_MCO_SHIFT) +#define RCC_CFGR_MCO_HSE (6 << RCC_CFGR_MCO_SHIFT) +#define RCC_CFGR_MCO_PLL (7 << RCC_CFGR_MCO_SHIFT) + +#define RCC_CFGR_PLLMUL_SHIFT 18 +#define RCC_CFGR_PLLMUL (0x0F << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL2 (0x00 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL3 (0x01 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL4 (0x02 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL5 (0x03 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL6 (0x04 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL7 (0x05 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL8 (0x06 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL9 (0x06 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL10 (0x07 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL11 (0x08 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL12 (0x09 << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL13 (0x0A << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL14 (0x0B << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL15 (0x0C << RCC_CFGR_PLLMUL_SHIFT) +#define RCC_CFGR_PLLMUL_MUL16 (0x0D << RCC_CFGR_PLLMUL_SHIFT) + +#define RCC_CFGR_PLLXTPRE (1<<17) +#define RCC_CFGR_PLLSRC (1<<16) +#define RCC_CFGR_ADCPRE (1<<14) + +#define RCC_CFGR_PPRE_SHIFT 8 +#define RCC_CFGR_PPRE (7 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_NODIV (0 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_DIV2 (4 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_DIV4 (5 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_DIV8 (6 << RCC_CFGR_PPRE_SHIFT) +#define RCC_CFGR_PPRE_DIV16 (7 << RCC_CFGR_PPRE_SHIFT) + +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_HPRE (0xf << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_NODIV (0x0 << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV2 (0x8 << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV4 (0x9 << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV8 (0xa << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV16 (0xb << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV64 (0xc << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV128 (0xd << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV256 (0xe << RCC_CFGR_HPRE_SHIFT) +#define RCC_CFGR_HPRE_DIV512 (0xf << RCC_CFGR_HPRE_SHIFT) + +#define RCC_CFGR_SWS_SHIFT 2 +#define RCC_CFGR_SWS (3 << RCC_CFGR_SWS_SHIFT) +#define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) +#define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) +#define RCC_CFGR_SWS_PLL (2 << RCC_CFGR_SWS_SHIFT) + +#define RCC_CFGR_SW_SHIFT 0 +#define RCC_CFGR_SW (3 << RCC_CFGR_SW_SHIFT) +#define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) +#define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) +#define RCC_CFGR_SW_PLL (2 << RCC_CFGR_SW_SHIFT) + +/* --- RCC_CIR values ------------------------------------------------------ */ + +#define RCC_CIR_CSSC (1 << 23) +#define RCC_CIR_HSI14RDYC (1 << 21) +#define RCC_CIR_PLLRDYC (1 << 20) +#define RCC_CIR_HSERDYC (1 << 19) +#define RCC_CIR_HSIRDYC (1 << 18) +#define RCC_CIR_LSERDYC (1 << 17) +#define RCC_CIR_LSIRDYC (1 << 16) +#define RCC_CIR_HSI14RDYIE (1 << 13) +#define RCC_CIR_PLLRDYIE (1 << 12) +#define RCC_CIR_HSERDYIE (1 << 11) +#define RCC_CIR_HSIRDYIE (1 << 10) +#define RCC_CIR_LSERDYIE (1 << 9) +#define RCC_CIR_LSIRDYIE (1 << 8) +#define RCC_CIR_CSSF (1 << 7) +#define RCC_CIR_HSI14RDYF (1 << 5) +#define RCC_CIR_PLLRDYF (1 << 4) +#define RCC_CIR_HSERDYF (1 << 3) +#define RCC_CIR_HSIRDYF (1 << 2) +#define RCC_CIR_LSERDYF (1 << 1) +#define RCC_CIR_LSIRDYF (1 << 0) + +/* --- RCC_APB2RSTR values ------------------------------------------------- */ + +#define RCC_APB2RSTR_DBGMCURST (1 << 22) +#define RCC_APB2RSTR_TIM17RST (1 << 18) +#define RCC_APB2RSTR_TIM16RST (1 << 17) +#define RCC_APB2RSTR_TIM15RST (1 << 16) +#define RCC_APB2RSTR_USART1RST (1 << 14) +#define RCC_APB2RSTR_SPI1RST (1 << 12) +#define RCC_APB2RSTR_TIM1RST (1 << 11) +#define RCC_APB2RSTR_ADCRST (1 << 9) +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) + +/* --- RCC_APB1RSTR values ------------------------------------------------- */ + +#define RCC_APB1RSTR_CECRST (1 << 30) +#define RCC_APB1RSTR_DACRST (1 << 29) +#define RCC_APB1RSTR_PWRRST (1 << 28) +#define RCC_APB1RSTR_I2C2RST (1 << 22) +#define RCC_APB1RSTR_I2C1RST (1 << 21) +#define RCC_APB1RSTR_USART2RST (1 << 17) +#define RCC_APB1RSTR_SPI2RST (1 << 14) +#define RCC_APB1RSTR_WWDGRST (1 << 11) +#define RCC_APB1RSTR_TIM14RST (1 << 8) +#define RCC_APB1RSTR_TIM6RST (1 << 4) +#define RCC_APB1RSTR_TIM3RST (1 << 1) +#define RCC_APB1RSTR_TIM2RST (1 << 0) + +/* --- RCC_AHBENR values --------------------------------------------------- */ + +#define RCC_AHBENR_TSCEN (1 << 24) +#define RCC_AHBENR_GPIOFEN (1 << 22) +#define RCC_AHBENR_GPIODEN (1 << 20) +#define RCC_AHBENR_GPIOCEN (1 << 19) +#define RCC_AHBENR_GPIOBEN (1 << 18) +#define RCC_AHBENR_GPIOAEN (1 << 17) +#define RCC_AHBENR_CRCEN (1 << 6) +#define RCC_AHBENR_FLTFEN (1 << 4) +#define RCC_AHBENR_SRAMEN (1 << 2) +#define RCC_AHBENR_DMAEN (1 << 0) + +/* --- RCC_APB2ENR values -------------------------------------------------- */ + +#define RCC_APB2ENR_DBGMCUEN (1 << 22) +#define RCC_APB2ENR_TIM17EN (1 << 18) +#define RCC_APB2ENR_TIM16EN (1 << 17) +#define RCC_APB2ENR_TIM15EN (1 << 16) +#define RCC_APB2ENR_USART1EN (1 << 14) +#define RCC_APB2ENR_SPI1EN (1 << 12) +#define RCC_APB2ENR_TIM1EN (1 << 11) +#define RCC_APB2ENR_ADCEN (1 << 9) +#define RCC_APB2ENR_SYSCFGCOMPEN (1 << 0) + +/* --- RCC_APB1ENR values -------------------------------------------------- */ + +#define RCC_APB1ENR_CECEN (1 << 30) +#define RCC_APB1ENR_DACEN (1 << 29) +#define RCC_APB1ENR_PWREN (1 << 28) +#define RCC_APB1ENR_I2C2EN (1 << 22) +#define RCC_APB1ENR_I2C1EN (1 << 21) +#define RCC_APB1ENR_USART2EN (1 << 17) +#define RCC_APB1ENR_SPI2EN (1 << 14) +#define RCC_APB1ENR_WWDGEN (1 << 11) +#define RCC_APB1ENR_TIM14EN (1 << 8) +#define RCC_APB1ENR_TIM6EN (1 << 4) +#define RCC_APB1ENR_TIM3EN (1 << 1) +#define RCC_APB1ENR_TIM2EN (1 << 0) + +/* --- RCC_BDCR values ----------------------------------------------------- */ + +#define RCC_BDCR_BDRST (1 << 16) +#define RCC_BDCR_RTCEN (1 << 15) +#define RCC_BDCR_RTCSEL_SHIFT 8 +#define RCC_BDCR_RTCSEL (3 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) +#define RCC_BDCR_LSEDRV_SHIFT 3 +#define RCC_BDCR_LSEDRV (3 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEDRV_LOW (0 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEDRV_MEDLO (1 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEDRV_MEDHI (2 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEDRV_HIGH (3 << RCC_BDCR_LSEDRV_SHIFT) +#define RCC_BDCR_LSEBYP (1 << 2) +#define RCC_BDCR_LSERDY (1 << 1) +#define RCC_BDCR_LSEON (1 << 0) + +/* --- RCC_CSR values ------------------------------------------------------ */ + +#define RCC_CSR_LPWRRSTF (1 << 31) +#define RCC_CSR_WWDGRSTF (1 << 30) +#define RCC_CSR_IWDGRSTF (1 << 29) +#define RCC_CSR_SFTRSTF (1 << 28) +#define RCC_CSR_PORRSTF (1 << 27) +#define RCC_CSR_PINRSTF (1 << 26) +#define RCC_CSR_OBLRSTF (1 << 25) +#define RCC_CSR_RMVF (1 << 24) +#define RCC_CSR_V18PWRRSTF (1 << 23) +#define RCC_CSR_LSIRDY (1 << 1) +#define RCC_CSR_LSION (1 << 0) + +/* --- RCC_AHBRSTR values -------------------------------------------------- */ + +#define RCC_AHBRSTR_TSCRST (1 << 24) +#define RCC_AHBRSTR_IOPFRST (1 << 22) +#define RCC_AHBRSTR_IOPDRST (1 << 20) +#define RCC_AHBRSTR_IOPCRST (1 << 19) +#define RCC_AHBRSTR_IOPBRST (1 << 18) +#define RCC_AHBRSTR_IOPARST (1 << 17) + + +/* --- RCC_CFGR2 values ---------------------------------------------------- */ + +#define RCC_CFGR2_PREDIV 0xf +#define RCC_CFGR2_PREDIV_NODIV 0x0 +#define RCC_CFGR2_PREDIV_DIV2 0x1 +#define RCC_CFGR2_PREDIV_DIV3 0x2 +#define RCC_CFGR2_PREDIV_DIV4 0x3 +#define RCC_CFGR2_PREDIV_DIV5 0x4 +#define RCC_CFGR2_PREDIV_DIV6 0x5 +#define RCC_CFGR2_PREDIV_DIV7 0x6 +#define RCC_CFGR2_PREDIV_DIV8 0x7 +#define RCC_CFGR2_PREDIV_DIV9 0x8 +#define RCC_CFGR2_PREDIV_DIV10 0x9 +#define RCC_CFGR2_PREDIV_DIV11 0xa +#define RCC_CFGR2_PREDIV_DIV12 0xb +#define RCC_CFGR2_PREDIV_DIV13 0xc +#define RCC_CFGR2_PREDIV_DIV14 0xd +#define RCC_CFGR2_PREDIV_DIV15 0xe +#define RCC_CFGR2_PREDIV_DIV16 0xf + +/* --- RCC_CFGR3 values ---------------------------------------------------- */ + +#define RCC_CFGR3_ADCSW (1 << 8) +#define RCC_CFGR3_CECSW (1 << 6) +#define RCC_CFGR3_I2C1SW (1 << 4) +#define RCC_CFGR3_USART1SW_SHIFT 0 +#define RCC_CFGR3_USART1SW (3 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USART1SW_PCLK (0 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USART1SW_SYSCLK (1 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USART1SW_LSE (2 << RCC_CFGR3_USART1SW_SHIFT) +#define RCC_CFGR3_USART1SW_HSI (3 << RCC_CFGR3_USART1SW_SHIFT) + +/* --- RCC_CFGR3 values ---------------------------------------------------- */ + +#define RCC_CR2_HSI14CAL_SHIFT 8 +#define RCC_CR2_HSI14CAL (0xFF << RCC_CR2_HSI14CAL_SHIFT) +#define RCC_CR2_HSI14TRIM_SHIFT 3 +#define RCC_CR2_HSI14TRIM (31 << RCC_CR2_HSI14TRIM_SHIFT) +#define RCC_CR2_HSI14DIS (1 << 2) +#define RCC_CR2_HSI14RDY (1 << 1) +#define RCC_CR2_HSI14ON (1 << 0) + +/* --- Variable definitions ------------------------------------------------ */ +extern uint32_t rcc_core_frequency; +extern uint32_t rcc_ppre_frequency; + + +/* --- Function prototypes ------------------------------------------------- */ + +enum rcc_osc { + HSI14, HSI, HSE, PLL, LSI, LSE +}; + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum rcc_periph_clken { + /* AHB peripherals */ + RCC_DMA = _REG_BIT(0x14, 0), + RCC_SRAM = _REG_BIT(0x14, 2), + RCC_FLTIF = _REG_BIT(0x14, 4), + RCC_CRC = _REG_BIT(0x14, 6), + RCC_GPIOA = _REG_BIT(0x14, 17), + RCC_GPIOB = _REG_BIT(0x14, 18), + RCC_GPIOC = _REG_BIT(0x14, 19), + RCC_GPIOD = _REG_BIT(0x14, 20), + RCC_GPIOF = _REG_BIT(0x14, 22), + RCC_TSC = _REG_BIT(0x14, 24), + + /* APB2 peripherals */ + RCC_SYSCFG_COMP = _REG_BIT(0x18, 0), + RCC_ADC = _REG_BIT(0x18, 9), + RCC_TIM1 = _REG_BIT(0x18, 11), + RCC_SPI1 = _REG_BIT(0x18, 12), + RCC_USART1 = _REG_BIT(0x18, 14), + RCC_TIM15 = _REG_BIT(0x18, 16), + RCC_TIM16 = _REG_BIT(0x18, 17), + RCC_TIM17 = _REG_BIT(0x18, 18), + RCC_DBGMCU = _REG_BIT(0x18, 22), + + /* APB1 peripherals */ + RCC_TIM2 = _REG_BIT(0x1C, 0), + RCC_TIM3 = _REG_BIT(0x1C, 1), + RCC_TIM6 = _REG_BIT(0x1C, 4), + RCC_TIM14 = _REG_BIT(0x1C, 8), + RCC_WWDG = _REG_BIT(0x1C, 11), + RCC_SPI2 = _REG_BIT(0x1C, 14), + RCC_USART2 = _REG_BIT(0x1C, 17), + RCC_I2C1 = _REG_BIT(0x1C, 21), + RCC_I2C2 = _REG_BIT(0x1C, 22), + RCC_PWR = _REG_BIT(0x1C, 28), + RCC_DAC = _REG_BIT(0x1C, 29), + RCC_CEC = _REG_BIT(0x1C, 30), + + /* Advanced peripherals */ + RCC_RTC = _REG_BIT(0x20, 15),/* BDCR[15] */ +}; + +enum rcc_periph_rst { + /* APB2 peripherals */ + RST_SYSCFG = _REG_BIT(0x0C, 0), + RST_ADC = _REG_BIT(0x0C, 9), + RST_TIM1 = _REG_BIT(0x0C, 11), + RST_SPI1 = _REG_BIT(0x0C, 12), + RST_USART1 = _REG_BIT(0x0C, 14), + RST_TIM15 = _REG_BIT(0x0C, 16), + RST_TIM16 = _REG_BIT(0x0C, 17), + RST_TIM17 = _REG_BIT(0x0C, 18), + RST_DBGMCU = _REG_BIT(0x0C, 22), + + /* APB1 peripherals */ + RST_TIM2 = _REG_BIT(0x10, 0), + RST_TIM3 = _REG_BIT(0x10, 1), + RST_TIM6 = _REG_BIT(0x10, 4), + RST_TIM14 = _REG_BIT(0x10, 8), + RST_WWDG = _REG_BIT(0x10, 11), + RST_SPI2 = _REG_BIT(0x10, 14), + RST_USART2 = _REG_BIT(0x10, 17), + RST_I2C1 = _REG_BIT(0x10, 21), + RST_I2C2 = _REG_BIT(0x10, 22), + RST_PWR = _REG_BIT(0x10, 28), + RST_DAC = _REG_BIT(0x10, 29), + RST_CEC = _REG_BIT(0x10, 30), + + /* Advanced peripherals */ + RST_BACKUPDOMAIN = _REG_BIT(0x20, 16),/* BDCR[16] */ + + /* AHB peripherals */ + RST_GPIOA = _REG_BIT(0x28, 17), + RST_GPIOB = _REG_BIT(0x28, 18), + RST_GPIOC = _REG_BIT(0x28, 19), + RST_GPIOD = _REG_BIT(0x28, 20), + RST_GPIOF = _REG_BIT(0x28, 22), + RST_TSC = _REG_BIT(0x28, 24), +}; +#undef _REG_BIT + +BEGIN_DECLS + +void rcc_osc_ready_int_clear(enum rcc_osc osc); +void rcc_osc_ready_int_enable(enum rcc_osc osc); +void rcc_osc_ready_int_disable(enum rcc_osc osc); +int rcc_osc_ready_int_flag(enum rcc_osc osc); +void rcc_wait_for_osc_ready(enum rcc_osc osc); +void rcc_osc_on(enum rcc_osc osc); +void rcc_osc_off(enum rcc_osc osc); +void rcc_osc_bypass_enable(enum rcc_osc osc); +void rcc_osc_bypass_disable(enum rcc_osc osc); +void rcc_css_enable(void); +void rcc_css_disable(void); +void rcc_css_int_clear(void); +int rcc_css_int_flag(void); +void rcc_set_sysclk_source(enum rcc_osc clk); +void rcc_set_pll_multiplication_factor(uint32_t mul); +void rcc_set_ppre(uint32_t ppre); +void rcc_set_hpre(uint32_t hpre); +void rcc_set_prediv(uint32_t prediv); +void rcc_set_mco(uint32_t mcosrc); +enum rcc_osc rcc_system_clock_source(void); +void rcc_clock_setup_in_hsi_out_8mhz(void); +void rcc_clock_setup_in_hsi_out_16mhz(void); +void rcc_clock_setup_in_hsi_out_24mhz(void); +void rcc_clock_setup_in_hsi_out_32mhz(void); +void rcc_clock_setup_in_hsi_out_40mhz(void); +void rcc_clock_setup_in_hsi_out_48mhz(void); +void rcc_periph_clock_enable(enum rcc_periph_clken periph); +void rcc_periph_clock_disable(enum rcc_periph_clken periph); +void rcc_periph_reset_pulse(enum rcc_periph_rst periph); +void rcc_periph_reset_hold(enum rcc_periph_rst periph); +void rcc_periph_reset_release(enum rcc_periph_rst periph); + +END_DECLS + +#endif +/**@}*/ + diff --git a/include/libopencm3/stm32/flash.h b/include/libopencm3/stm32/flash.h index 704685ff..33a3d205 100644 --- a/include/libopencm3/stm32/flash.h +++ b/include/libopencm3/stm32/flash.h @@ -16,8 +16,9 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ - -#if defined(STM32F1) +#if defined(STM32F0) +# include +#elif defined(STM32F1) # include #elif defined(STM32F2) # include diff --git a/include/libopencm3/stm32/gpio.h b/include/libopencm3/stm32/gpio.h index d387d6e1..fd163411 100644 --- a/include/libopencm3/stm32/gpio.h +++ b/include/libopencm3/stm32/gpio.h @@ -17,7 +17,9 @@ * along with this library. If not, see . */ -#if defined(STM32F1) +#if defined(STM32F0) +# include +#elif defined(STM32F1) # include #elif defined(STM32F2) # include diff --git a/include/libopencm3/stm32/memorymap.h b/include/libopencm3/stm32/memorymap.h index 44ca6ae2..cf4a580d 100644 --- a/include/libopencm3/stm32/memorymap.h +++ b/include/libopencm3/stm32/memorymap.h @@ -20,7 +20,9 @@ #ifndef LIBOPENCM3_MEMORYMAP_COMMON_H #define LIBOPENCM3_MEMORYMAP_COMMON_H -#if defined(STM32F1) +#if defined(STM32F0) +# include +#elif defined(STM32F1) # include #elif defined(STM32F2) # include diff --git a/include/libopencm3/stm32/pwr.h b/include/libopencm3/stm32/pwr.h index 2b1c2478..ca2d69fc 100644 --- a/include/libopencm3/stm32/pwr.h +++ b/include/libopencm3/stm32/pwr.h @@ -16,8 +16,9 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ - -#if defined(STM32F1) +#if defined(STM32F0) +# include +#elif defined(STM32F1) # include #elif defined(STM32F2) # include diff --git a/include/libopencm3/stm32/rcc.h b/include/libopencm3/stm32/rcc.h index bbb2f394..fd708c70 100644 --- a/include/libopencm3/stm32/rcc.h +++ b/include/libopencm3/stm32/rcc.h @@ -17,7 +17,9 @@ * along with this library. If not, see . */ -#if defined(STM32F1) +#if defined(STM32F0) +# include +#elif defined(STM32F1) # include #elif defined(STM32F2) # include diff --git a/lib/dispatch/vector_nvic.c b/lib/dispatch/vector_nvic.c index edc92094..25acf50b 100644 --- a/lib/dispatch/vector_nvic.c +++ b/lib/dispatch/vector_nvic.c @@ -1,4 +1,6 @@ -#if defined(STM32F1) +#if defined(STM32F0) +# include "../stm32/f0/vector_nvic.c" +#elif defined(STM32F1) # include "../stm32/f1/vector_nvic.c" #elif defined(STM32F2) # include "../stm32/f2/vector_nvic.c" diff --git a/lib/stm32/f0/Makefile b/lib/stm32/f0/Makefile new file mode 100644 index 00000000..fbe918b7 --- /dev/null +++ b/lib/stm32/f0/Makefile @@ -0,0 +1,44 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2013 Frantisek Burian +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_stm32f0 + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m0 -msoft-float -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F0 + +ARFLAGS = rcs + +OBJS = flash.o rcc.o + +OBJS += gpio_common_all.o gpio_common_f234.o crc_common_all.o \ + pwr_common_all.o + +VPATH += ../../usb:../:../../cm3:../common + +include ../../Makefile.include + diff --git a/lib/stm32/f0/flash.c b/lib/stm32/f0/flash.c new file mode 100644 index 00000000..83e17ba3 --- /dev/null +++ b/lib/stm32/f0/flash.c @@ -0,0 +1,93 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Frantisek Burian + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +void flash_prefetch_buffer_enable(void) +{ + FLASH_ACR |= FLASH_ACR_PRFTBE; +} + +void flash_prefetch_buffer_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_PRFTBE; +} + +void flash_set_ws(uint32_t ws) +{ + FLASH_ACR = (FLASH_ACR & ~FLASH_ACR_LATENCY) | ws; +} + +void flash_wait_busy(void) +{ + while ((FLASH_SR & FLASH_SR_BSY) != 0); +} + +void flash_program_u32(uint32_t address, uint32_t data) +{ + flash_wait_busy(); + + FLASH_CR |= FLASH_CR_PG; + + MMIO16(address) = (uint16_t)data; + + flash_wait_busy(); + + MMIO16(address + 2) = data >> 16; + + flash_wait_busy(); + + FLASH_CR &= ~FLASH_CR_PG; +} + +void flash_program_u16(uint32_t address, uint16_t data) +{ + flash_wait_busy(); + + FLASH_CR |= FLASH_CR_PG; + + MMIO16(address) = data; + + flash_wait_busy(); + + FLASH_CR &= ~FLASH_CR_PG; +} + +void flash_erase_page(uint32_t page_address) +{ + flash_wait_busy(); + + FLASH_CR |= FLASH_CR_PER; + FLASH_AR = page_address; + FLASH_CR |= FLASH_CR_STRT; + + flash_wait_busy(); + FLASH_CR &= ~FLASH_CR_PER; +} + +void flash_erase_all_pages(void) +{ + flash_wait_busy(); + + FLASH_CR |= FLASH_CR_MER; /* Enable mass erase. */ + FLASH_CR |= FLASH_CR_STRT; /* Trigger the erase. */ + + flash_wait_busy(); + FLASH_CR &= ~FLASH_CR_MER; /* Disable mass erase. */ +} diff --git a/lib/stm32/f0/libopencm3_stm32f0.ld b/lib/stm32/f0/libopencm3_stm32f0.ld new file mode 100644 index 00000000..3fc2ccb6 --- /dev/null +++ b/lib/stm32/f0/libopencm3_stm32f0.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/lib/stm32/f0/rcc.c b/lib/stm32/f0/rcc.c new file mode 100644 index 00000000..f570b263 --- /dev/null +++ b/lib/stm32/f0/rcc.c @@ -0,0 +1,637 @@ +/** @defgroup STM32F0xx-rcc-file RCC + * + * @ingroup STM32F1xx + * + * @brief libopencm3 STM32F0xx Reset and Clock Control + * + * @version 1.0.0 + * + * @date 29 Jun 2013 + * + * This library supports the Reset and Clock Control System in the STM32F0xx + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include +#include +#include + +uint32_t rcc_core_frequency = 8000000; /* 8MHz after reset */ +uint32_t rcc_ppre_frequency = 8000000; /* 8MHz after reset */ + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Clear the Oscillator Ready Interrupt Flag + * + * Clear the interrupt flag that was set when a clock oscillator became ready + * to use. + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case HSI14: + RCC_CIR |= RCC_CIR_HSI14RDYC; + break; + case HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the Oscillator Ready Interrupt + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case HSI14: + RCC_CIR |= RCC_CIR_HSI14RDYIE; + break; + case HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable the Oscillator Ready Interrupt + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case HSI14: + RCC_CIR &= ~RCC_CIR_HSI14RDYC; + break; + case HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYC; + break; + case HSE: + RCC_CIR &= ~RCC_CIR_HSERDYC; + break; + case PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYC; + break; + case LSE: + RCC_CIR &= ~RCC_CIR_LSERDYC; + break; + case LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYC; + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Read the Oscillator Ready Interrupt Flag + * + * @param[in] osc enum ::osc_t. Oscillator ID + * @returns int. Boolean value for flag set. + */ + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case HSI14: + return (RCC_CIR & RCC_CIR_HSI14RDYF) != 0; + break; + case HSI: + return (RCC_CIR & RCC_CIR_HSIRDYF) != 0; + break; + case HSE: + return (RCC_CIR & RCC_CIR_HSERDYF) != 0; + break; + case PLL: + return (RCC_CIR & RCC_CIR_PLLRDYF) != 0; + break; + case LSE: + return (RCC_CIR & RCC_CIR_LSERDYF) != 0; + break; + case LSI: + return (RCC_CIR & RCC_CIR_LSIRDYF) != 0; + break; + } + + cm3_assert_not_reached(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Clear the Clock Security System Interrupt Flag +*/ + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Read the Clock Security System Interrupt Flag + * + * @returns int. Boolean value for flag set. + */ + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Wait for Oscillator Ready. + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case HSI14: + while ((RCC_CIR & RCC_CIR_HSI14RDYF) != 0); + break; + case HSI: + while ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + break; + case HSE: + while ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + break; + case PLL: + while ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + break; + case LSE: + while ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + break; + case LSI: + while ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Turn on an Oscillator. + * + * Enable an oscillator and power on. Each oscillator requires an amount of + * time to settle to a usable state. Refer to datasheets for time delay + * information. A status flag is available to indicate when the oscillator + * becomes ready (see @ref rcc_osc_ready_int_flag and @ref + * rcc_wait_for_osc_ready). + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case HSI14: + RCC_CR2 |= RCC_CR2_HSI14ON; + break; + case HSI: + RCC_CR |= RCC_CR_HSION; + break; + case HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + case PLL: + /* don't do anything */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Turn off an Oscillator. + * + * Disable an oscillator and power off. + * + * @note An oscillator cannot be turned off if it is selected as the system + * clock. + * + * @param[in] osc enum ::osc_t. Oscillator ID + */ + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case HSI14: + RCC_CR2 &= ~RCC_CR2_HSI14ON; + break; + case HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + case PLL: + /* don't do anything */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable the Clock Security System. + */ + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable the Clock Security System. + */ + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Enable Bypass. + * + * Enable an external clock to bypass the internal clock (high speed and low + * speed clocks only). The external clock must be enabled (see @ref rcc_osc_on) + * and the internal clock must be disabled (see @ref rcc_osc_off) for this to + * have effect. + * + * @param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect. + */ + +void rcc_osc_bypass_enable(enum rcc_osc osc) +{ + switch (osc) { + case HSE: + RCC_CR |= RCC_CR_HSEBYP; + break; + case LSE: + RCC_BDCR |= RCC_BDCR_LSEBYP; + break; + case HSI14: + case HSI: + case LSI: + case PLL: + /* Do nothing */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Disable Bypass. + * + * Re-enable the internal clock (high speed and low speed clocks only). The + * internal clock must be disabled (see @ref rcc_osc_off) for this to have + * effect. + * + * + * @param[in] osc enum ::osc_t. Oscillator ID. Only HSE and LSE have effect. + */ + +void rcc_osc_bypass_disable(enum rcc_osc osc) +{ + switch (osc) { + case HSE: + RCC_CR &= ~RCC_CR_HSEBYP; + break; + case LSE: + RCC_BDCR &= ~RCC_BDCR_LSEBYP; + break; + case HSI14: + case PLL: + case HSI: + case LSI: + /* Do nothing */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the Source for the System Clock. + * + * @param[in] osc enum ::osc_t. Oscillator ID. Only HSE, LSE and PLL have + * effect. + */ + +void rcc_set_sysclk_source(enum rcc_osc clk) +{ + switch (clk) { + case HSI: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSI; + break; + case HSE: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_HSE; + break; + case PLL: + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL; + break; + case LSI: + case LSE: + case HSI14: + /* do nothing */ + break; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the PLL Multiplication Factor. + * + * @note This only has effect when the PLL is disabled. + * + * @param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf + */ + +void rcc_set_pll_multiplication_factor(uint32_t mul) +{ + RCC_CFGR = (RCC_CFGR & RCC_CFGR_PLLMUL) | mul; +} + + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the APB Prescale Factor. + * + * @note The APB1 clock frequency must not exceed 36MHz. + * + * @param[in] ppre1 Unsigned int32. APB prescale factor @ref rcc_cfgr_apb1pre + */ + +void rcc_set_ppre(uint32_t ppre) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_PPRE) | ppre; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Set the AHB Prescale Factor. + * + * @param[in] hpre Unsigned int32. AHB prescale factor @ref rcc_cfgr_ahbpre + */ + +void rcc_set_hpre(uint32_t hpre) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_HPRE) | hpre; +} + + +void rcc_set_prediv(uint32_t prediv) +{ + RCC_CFGR2 = (RCC_CFGR2 & ~RCC_CFGR2_PREDIV) | prediv; +} + + +void rcc_set_mco(uint32_t mcosrc) +{ + RCC_CFGR = (RCC_CFGR & ~RCC_CFGR_MCO) | mcosrc; +} + +/*---------------------------------------------------------------------------*/ +/** @brief RCC Get the System Clock Source. + * + * @returns ::osc_t System clock source: + */ + +enum rcc_osc rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + switch (RCC_CFGR & RCC_CFGR_SWS) { + case RCC_CFGR_SWS_HSI: + return HSI; + case RCC_CFGR_SWS_HSE: + return HSE; + case RCC_CFGR_SWS_PLL: + return PLL; + } + + cm3_assert_not_reached(); +} + +void rcc_clock_setup_in_hsi_out_8mhz(void) +{ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + rcc_set_sysclk_source(HSI); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_000_024MHZ); + + rcc_ppre_frequency = 8000000; + rcc_core_frequency = 8000000; +} + +void rcc_clock_setup_in_hsi_out_16mhz(void) +{ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + rcc_set_sysclk_source(HSI); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_000_024MHZ); + + /* 8MHz * 4 / 2 = 16MHz */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL4); + + RCC_CFGR &= RCC_CFGR_PLLSRC; + + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + rcc_set_sysclk_source(PLL); + + rcc_ppre_frequency = 16000000; + rcc_core_frequency = 16000000; +} + + +void rcc_clock_setup_in_hsi_out_24mhz(void) +{ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + rcc_set_sysclk_source(HSI); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_000_024MHZ); + + /* 8MHz * 6 / 2 = 24MHz */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL6); + + RCC_CFGR &= RCC_CFGR_PLLSRC; + + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + rcc_set_sysclk_source(PLL); + + rcc_ppre_frequency = 24000000; + rcc_core_frequency = 24000000; +} + +void rcc_clock_setup_in_hsi_out_32mhz(void) +{ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + rcc_set_sysclk_source(HSI); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ); + + /* 8MHz * 8 / 2 = 32MHz */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL8); + + RCC_CFGR &= RCC_CFGR_PLLSRC; + + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + rcc_set_sysclk_source(PLL); + + rcc_ppre_frequency = 32000000; + rcc_core_frequency = 32000000; +} + +void rcc_clock_setup_in_hsi_out_40mhz(void) +{ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + rcc_set_sysclk_source(HSI); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ); + + /* 8MHz * 10 / 2 = 40MHz */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL10); + + RCC_CFGR &= RCC_CFGR_PLLSRC; + + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + rcc_set_sysclk_source(PLL); + + rcc_ppre_frequency = 32000000; + rcc_core_frequency = 32000000; +} + +void rcc_clock_setup_in_hsi_out_48mhz(void) +{ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + rcc_set_sysclk_source(HSI); + + rcc_set_hpre(RCC_CFGR_HPRE_NODIV); + rcc_set_ppre(RCC_CFGR_PPRE_NODIV); + + flash_set_ws(FLASH_ACR_LATENCY_024_048MHZ); + + /* 8MHz * 12 / 2 = 24MHz */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_MUL16); + + RCC_CFGR &= RCC_CFGR_PLLSRC; + + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + rcc_set_sysclk_source(PLL); + + rcc_ppre_frequency = 48000000; + rcc_core_frequency = 48000000; +} + + +#define _RCC_REG(i) MMIO32(RCC_BASE + ((i) >> 5)) +#define _RCC_BIT(i) (1 << ((i) & 0x1f)) + +void rcc_periph_clock_enable(enum rcc_periph_clken periph) +{ + _RCC_REG(periph) |= _RCC_BIT(periph); +} + +void rcc_periph_clock_disable(enum rcc_periph_clken periph) +{ + _RCC_REG(periph) &= ~_RCC_BIT(periph); +} + +void rcc_periph_reset_pulse(enum rcc_periph_rst periph) +{ + _RCC_REG(periph) |= _RCC_BIT(periph); + _RCC_REG(periph) &= ~_RCC_BIT(periph); +} + +void rcc_periph_reset_hold(enum rcc_periph_rst periph) +{ + _RCC_REG(periph) |= _RCC_BIT(periph); +} + +void rcc_periph_reset_release(enum rcc_periph_rst periph) +{ + _RCC_REG(periph) &= ~_RCC_BIT(periph); +} + +#undef _RCC_REG +#undef _RCC_BIT + +/**@}*/ +