git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4777 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2012-10-23 20:51:36 +00:00
parent efbd7db978
commit 7112dfa32e
8 changed files with 605 additions and 112 deletions

View File

@ -29,6 +29,10 @@
#include "ch.h"
#include "hal.h"
/* TODO: LSEBYP like in F3.*/
/* TODO: LSEDRV like in F3.*/
/* TODO: PREDIV like in F3.*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@ -142,7 +146,13 @@ void stm32_clock_init(void) {
#if STM32_HSE_ENABLED
/* HSE activation.*/
#if defined(STM32_HSE_BYPASS)
/* HSE Bypass.*/
RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP;
#else
/* No HSE Bypass.*/
RCC->CR |= RCC_CR_HSEON;
#endif
while (!(RCC->CR & RCC_CR_HSERDY))
; /* Waits until HSE is stable. */
#endif

View File

@ -792,7 +792,7 @@
#elif (STM32_SW == STM32_SW_HSE)
#define STM32_SYSCLK STM32_HSECLK
#else
#error "invalid STM32_SYSCLK_SW value specified"
#error "invalid STM32_SW value specified"
#endif
/* Check on the system clock.*/

View File

@ -801,7 +801,7 @@
#elif (STM32_SW == STM32_SW_HSE)
#define STM32_SYSCLK STM32_HSECLK
#else
#error "invalid STM32_SYSCLK_SW value specified"
#error "invalid STM32_SW value specified"
#endif
/* Check on the system clock.*/

View File

@ -1137,7 +1137,7 @@
#elif (STM32_SW == STM32_SW_HSE)
#define STM32_SYSCLK STM32_HSECLK
#else
#error "invalid STM32_SYSCLK_SW value specified"
#error "invalid STM32_SW value specified"
#endif
/* Check on the system clock.*/

View File

@ -886,7 +886,7 @@
#elif (STM32_SW == STM32_SW_HSE)
#define STM32_SYSCLK STM32_HSECLK
#else
#error "invalid STM32_SYSCLK_SW value specified"
#error "invalid STM32_SW value specified"
#endif
/* Check on the system clock.*/

View File

@ -0,0 +1,203 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file STM32F3xx/hal_lld.c
* @brief STM32F3xx HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Initializes the backup domain.
* @note WARNING! Changing clock source impossible without resetting
* of the whole BKP domain.
*/
static void hal_lld_backup_domain_init(void) {
/* Backup domain access enabled and left open.*/
PWR->CR |= PWR_CR_DBP;
/* Reset BKP domain if different clock source selected.*/
if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL){
/* Backup domain reset.*/
RCC->BDCR = RCC_BDCR_BDRST;
RCC->BDCR = 0;
}
/* If enabled then the LSE is started.*/
#if STM32_LSE_ENABLED
#if defined(STM32_LSE_BYPASS)
/* LSE Bypass.*/
RCC->BDCR = STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP;
#else
/* No LSE Bypass.*/
RCC->BDCR = STM32_LSEDRV | RCC_BDCR_LSEON;
#endif
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
; /* Waits until LSE is stable. */
#endif
#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK
/* If the backup domain hasn't been initialized yet then proceed with
initialization.*/
if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) {
/* Selects clock source.*/
RCC->BDCR |= STM32_RTCSEL;
/* RTC clock enabled.*/
RCC->BDCR |= RCC_BDCR_RTCEN;
}
#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*
* @notapi
*/
void hal_lld_init(void) {
/* Reset of all peripherals.*/
rccResetAPB1(0xFFFFFFFF);
rccResetAPB2(!RCC_APB2RSTR_DBGMCURST);
/* SysTick initialization using the system clock.*/
SysTick->LOAD = STM32_HCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
/* PWR and BD clocks enabled.*/
rccEnablePWRInterface(FALSE);
/* Initializes the backup domain.*/
hal_lld_backup_domain_init();
#if defined(STM32_DMA_REQUIRED)
dmaInit();
#endif
/* Programmable voltage detector enable.*/
#if STM32_PVD_ENABLE
PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
#endif /* STM32_PVD_ENABLE */
}
/**
* @brief STM32 clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
* @note This function should be invoked just after the system reset.
*
* @special
*/
void stm32_clock_init(void) {
#if !STM32_NO_INIT
/* HSI setup, it enforces the reset situation in order to handle possible
problems with JTAG probes and re-initializations.*/
RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */
while (!(RCC->CR & RCC_CR_HSIRDY))
; /* Wait until HSI is stable. */
RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */
RCC->CFGR = 0; /* CFGR reset value. */
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
; /* Waits until HSI is selected. */
#if STM32_HSE_ENABLED
/* HSE activation.*/
#if defined(STM32_HSE_BYPASS)
/* HSE Bypass.*/
RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP;
#else
/* No HSE Bypass.*/
RCC->CR |= RCC_CR_HSEON;
#endif
while (!(RCC->CR & RCC_CR_HSERDY))
; /* Waits until HSE is stable. */
#endif
#if STM32_LSI_ENABLED
/* LSI activation.*/
RCC->CSR |= RCC_CSR_LSION;
while ((RCC->CSR & RCC_CSR_LSIRDY) == 0)
; /* Waits until LSI is stable. */
#endif
#if STM32_ACTIVATE_PLL
/* PLL activation.*/
RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
; /* Waits until PLL is stable. */
#endif
/* Clock settings.*/
RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL |
STM32_PLLSRC | STM32_PPRE1 | STM32_PPRE1 |
STM32_HPRE;
RCC->CFGR = STM32_ADC43PRES | STM32_ADC12PRES | STM32_PREDIV;
RCC->CFGR3 = STM32_UART5SW | STM32_UART4SW | STM32_USART3SW |
STM32_USART2SW | STM32_TIM8SW | STM32_TIM1SW |
STM32_I2C2SW | STM32_I2C1SW | STM32_USART1SW;
/* Flash setup and final clock selection. */
FLASH->ACR = STM32_FLASHBITS;
/* Switching to the configured clock source if it is different from HSI.*/
#if (STM32_SW != STM32_SW_HSI)
/* Switches clock source.*/
RCC->CFGR |= STM32_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
; /* Waits selection complete. */
#endif
/* SYSCFG clock enabled here because it is a multi-functional unit shared
among multiple drivers.*/
rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, TRUE);
#endif /* !STM32_NO_INIT */
}
/** @} */

View File

@ -24,6 +24,8 @@
* @pre This module requires the following macros to be defined in the
* @p board.h file:
* - STM32_LSECLK.
* - STM32_LSEDRV.
* - STM32_LSEBYP (optionally).
* - STM32_HSECLK.
* - STM32_HSE_BYPASS (optionally).
* .
@ -178,8 +180,8 @@
#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is
HSE/PREDIV. */
#define STM32_PLLXTPRE_DIV1 (0 << 17) /**< HSE divided by 1. */
#define STM32_PLLXTPRE_DIV2 (1 << 17) /**< HSE divided by 2. */
#define STM32_USBPRE_DIV1 (0 << 22) /**< USB clock is PLLCLK/1. */
#define STM32_USBPRE_DIV1P5 (1 << 22) /**< USB clock is PLLCLK/1.5. */
#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */
#define STM32_MCOSEL_LSI (2 << 24) /**< LSI clock on MCO pin. */
@ -207,9 +209,8 @@
* @{
*/
#define STM32_PREDIV_MASK (15 << 0) /**< PREDIV divisor mask. */
#define STM32_PREDIV_DIV(n) (((n)-1) << 0)/**< PREDIV divisor. */
#define STM32_ADC12PRES_MASK (31 << 4) /**< ADC12 clock source mask. */
#define STM32_ADC12PRES_AHB (0 << 4) /**< ADC12 clock is AHB. */
#define STM32_ADC12PRES_NOCLOCK (0 << 4) /**< ADC12 clock is disabled. */
#define STM32_ADC12PRES_DIV1 (16 << 4) /**< ADC12 clock is PLL/1. */
#define STM32_ADC12PRES_DIV2 (17 << 4) /**< ADC12 clock is PLL/2. */
#define STM32_ADC12PRES_DIV4 (18 << 4) /**< ADC12 clock is PLL/4. */
@ -223,7 +224,7 @@
#define STM32_ADC12PRES_DIV128 (26 << 4) /**< ADC12 clock is PLL/128. */
#define STM32_ADC12PRES_DIV256 (27 << 4) /**< ADC12 clock is PLL/256. */
#define STM32_ADC34PRES_MASK (31 << 4) /**< ADC34 clock source mask. */
#define STM32_ADC34PRES_AHB (0 << 4) /**< ADC34 clock is AHB. */
#define STM32_ADC34PRES_NOCLOCK (0 << 4) /**< ADC34 clock is disabled. */
#define STM32_ADC34PRES_DIV1 (16 << 4) /**< ADC34 clock is PLL/1. */
#define STM32_ADC34PRES_DIV2 (17 << 4) /**< ADC34 clock is PLL/2. */
#define STM32_ADC34PRES_DIV4 (18 << 4) /**< ADC34 clock is PLL/4. */
@ -247,9 +248,12 @@
#define STM32_USART1SW_SYSCLK (1 << 0) /**< USART1 clock is SYSCLK. */
#define STM32_USART1SW_LSE (2 << 0) /**< USART1 clock is LSE. */
#define STM32_USART1SW_HSI (3 << 0) /**< USART1 clock is HSI. */
#define STM32_I2C1SW_MASK (1 << 4) /**< I2C clock source mask. */
#define STM32_I2C1SW_HSI (0 << 4) /**< I2C clock is HSI. */
#define STM32_I2C1SW_SYSCLK (1 << 4) /**< I2C clock is SYSCLK. */
#define STM32_I2C1SW_MASK (1 << 4) /**< I2C1 clock source mask. */
#define STM32_I2C1SW_HSI (0 << 4) /**< I2C1 clock is HSI. */
#define STM32_I2C1SW_SYSCLK (1 << 4) /**< I2C1 clock is SYSCLK. */
#define STM32_I2C2SW_MASK (1 << 5) /**< I2C2 clock source mask. */
#define STM32_I2C2SW_HSI (0 << 5) /**< I2C2 clock is HSI. */
#define STM32_I2C2SW_SYSCLK (1 << 5) /**< I2C2 clock is SYSCLK. */
#define STM32_TIM1SW_MASK (1 << 8) /**< TIM1 clock source mask. */
#define STM32_TIM1SW_PCLK2 (0 << 8) /**< TIM1 clock is PCLK2. */
#define STM32_TIM1SW_PLLX2 (1 << 10) /**< TIM1 clock is PLL*2. */
@ -529,8 +533,8 @@
* @note The default value is calculated for a 72MHz system clock from
* a 8MHz crystal using the PLL.
*/
#if !defined(STM32_PREDIV) || defined(__DOXYGEN__)
#define STM32_PREDIV STM32_PREDIV_DIV(1)
#if !defined(STM32_PREDIV_VALUE) || defined(__DOXYGEN__)
#define STM32_PREDIV_VALUE 1
#endif
/**
@ -587,13 +591,6 @@
#define STM32_ADC34PRES STM32_ADC34PRES_DIV1
#endif
/**
* @brief I2C1 clock source.
*/
#if !defined(STM32_I2C1SW) || defined(__DOXYGEN__)
#define STM32_I2C1SW STM32_I2C1SW_HSI
#endif
/**
* @brief USART1 clock source.
*/
@ -601,12 +598,82 @@
#define STM32_USART1SW STM32_USART1SW_PCLK
#endif
/**
* @brief USART2 clock source.
*/
#if !defined(STM32_USART2SW) || defined(__DOXYGEN__)
#define STM32_USART2SW STM32_USART2SW_PCLK
#endif
/**
* @brief USART3 clock source.
*/
#if !defined(STM32_USART3SW) || defined(__DOXYGEN__)
#define STM32_USART3SW STM32_USART3SW_PCLK
#endif
/**
* @brief UART4 clock source.
*/
#if !defined(STM32_UART4SW) || defined(__DOXYGEN__)
#define STM32_UART4SW STM32_UART4SW_PCLK
#endif
/**
* @brief UART5 clock source.
*/
#if !defined(STM32_UART5SW) || defined(__DOXYGEN__)
#define STM32_UART5SW STM32_UART5SW_PCLK
#endif
/**
* @brief I2C1 clock source.
*/
#if !defined(STM32_I2C1SW) || defined(__DOXYGEN__)
#define STM32_I2C1SW STM32_I2C1SW_SYSCLK
#endif
/**
* @brief I2C2 clock source.
*/
#if !defined(STM32_I2C2SW) || defined(__DOXYGEN__)
#define STM32_I2C2SW STM32_I2C2SW_SYSCLK
#endif
/**
* @brief TIM1 clock source.
*/
#if !defined(STM32_TIM1SW) || defined(__DOXYGEN__)
#define STM32_TIM1SW STM32_TIM1SW_PCLK2
#endif
/**
* @brief TIM8 clock source.
*/
#if !defined(STM32_TIM8SW) || defined(__DOXYGEN__)
#define STM32_TIM8SW STM32_TIM8SW_PCLK2
#endif
/**
* @brief RTC clock source.
*/
#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__)
#define STM32_RTCSEL STM32_RTCSEL_LSI
#endif
/**
* @brief USB clock setting.
*/
#if !defined(STM32_USB_CLOCK_REQUIRED) || defined(__DOXYGEN__)
#define STM32_USB_CLOCK_REQUIRED TRUE
#endif
/**
* @brief USB prescaler initialization.
*/
#if !defined(STM32_USBPRE) || defined(__DOXYGEN__)
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#endif
/** @} */
/*===========================================================================*/
@ -616,8 +683,8 @@
/*
* Configuration-related checks.
*/
#if !defined(STM32F0xx_MCUCONF)
#error "Using a wrong mcuconf.h file, STM32F0xx_MCUCONF not defined"
#if !defined(STM32F3xx_MCUCONF)
#error "Using a wrong mcuconf.h file, STM32F3xx_MCUCONF not defined"
#endif
/*
@ -630,16 +697,40 @@
#error "HSI not enabled, required by STM32_SW"
#endif
#if STM32_CECSW == STM32_CECSW_HSI
#error "HSI not enabled, required by STM32_CECSW"
#if STM32_USART1SW == STM32_USART1SW_HSI
#error "HSI not enabled, required by STM32_USART1SW"
#endif
#if STM32_USART2SW == STM32_USART2SW_HSI
#error "HSI not enabled, required by STM32_USART2SW"
#endif
#if STM32_USART3SW == STM32_USART3SW_HSI
#error "HSI not enabled, required by STM32_USART3SW"
#endif
#if STM32_UART4SW == STM32_UART4SW_HSI
#error "HSI not enabled, required by STM32_UART4SW"
#endif
#if STM32_UART5SW == STM32_UART5SW_HSI
#error "HSI not enabled, required by STM32_UART5SW"
#endif
#if STM32_I2C1SW == STM32_I2C1SW_HSI
#error "HSI not enabled, required by STM32_I2C1SW"
#endif
#if STM32_USART1SW == STM32_USART1SW_HSI
#error "HSI not enabled, required by STM32_USART1SW"
#if STM32_I2C2SW == STM32_I2C2SW_HSI
#error "HSI not enabled, required by STM32_I2C2SW"
#endif
#if STM32_TIM1SW == STM32_TIM1SW_HSI
#error "HSI not enabled, required by STM32_TIM1SW"
#endif
#if STM32_TIM8SW == STM32_TIM8SW_HSI
#error "HSI not enabled, required by STM32_TIM8SW"
#endif
#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI)
@ -654,22 +745,6 @@
#endif /* !STM32_HSI_ENABLED */
/*
* HSI14 related checks.
*/
#if STM32_HSI14_ENABLED
#else /* !STM32_HSI14_ENABLED */
#if STM32_MCOSEL == STM32_MCOSEL_HSI14
#error "HSI14 not enabled, required by STM32_MCOSEL"
#endif
#if STM32_ADCSW == STM32_ADCSW_HSI14
#error "HSI14 not enabled, required by STM32_ADCSW"
#endif
#endif /* !STM32_HSI14_ENABLED */
/*
* HSE related checks.
*/
@ -720,20 +795,40 @@
*/
#if STM32_LSE_ENABLED
#if (STM32_LSECLK == 0)
#error "LSE frequency not defined"
#if !defined(STM32_LSECLK) || (STM32_LSECLK == 0)
#error "STM32_LSECLK not defined"
#endif
#if STM32_CECSW == STM32_CECSW_LSE
#error "LSE not enabled, required by STM32_CECSW"
#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX)
#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)"
#endif
#if !defined(STM32_LSEDRV)
#error "STM32_LSEDRV not defined"
#endif
#if (STM32_LSEDRV >> 3) > 3
#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))"
#endif
#if STM32_USART1SW == STM32_USART1SW_LSE
#error "LSE not enabled, required by STM32_USART1SW"
#endif
#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX)
#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)"
#if STM32_USART2SW == STM32_USART2SW_LSE
#error "LSE not enabled, required by STM32_USART2SW"
#endif
#if STM32_USART3SW == STM32_USART3SW_LSE
#error "LSE not enabled, required by STM32_USART3SW"
#endif
#if STM32_UART4SW == STM32_UART4SW_LSE
#error "LSE not enabled, required by STM32_UART4SW"
#endif
#if STM32_UART5SW == STM32_UART5SW_LSE
#error "LSE not enabled, required by STM32_UART5SW"
#endif
#else /* !STM32_LSE_ENABLED */
@ -747,6 +842,11 @@
/* PLL activation conditions.*/
#if (STM32_SW == STM32_SW_PLL) || \
(STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \
(STM32_TIM1SW == STM32_TIM1SW_PLLX2) || \
(STM32_TIM8SW == STM32_TIM8SW_PLLX2) || \
(STM32_ADC12PRES != STM32_ADC12PRES_NOCLOCK) || \
(STM32_ADC34PRES != STM32_ADC34PRES_NOCLOCK) || \
STM32_USB_CLOCK_REQUIRED || \
defined(__DOXYGEN__)
/**
* @brief PLL activation flag.
@ -757,9 +857,10 @@
#endif
/* HSE prescaler setting check.*/
#if (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV1) && \
(STM32_PLLXTPRE != STM32_PLLXTPRE_DIV2)
#error "invalid STM32_PLLXTPRE value specified"
#if ((STM32_PREDIV_VALUE >= 1) || (STM32_PREDIV_VALUE <= 16))
#define STM32_PREDIV ((STM32_PREDIV_VALUE - 1) << 0)
#else
#error "invalid STM32_PREDIV value specified"
#endif
/**
@ -776,11 +877,7 @@
* @brief PLL input clock frequency.
*/
#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__)
#if STM32_PLLXTPRE == STM32_PLLXTPRE_DIV1
#define STM32_PLLCLKIN (STM32_HSECLK / 1)
#else
#define STM32_PLLCLKIN (STM32_HSECLK / 2)
#endif
#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PREDIV_VALUE)
#elif STM32_PLLSRC == STM32_PLLSRC_HSI
#define STM32_PLLCLKIN (STM32_HSICLK / 2)
#else
@ -812,7 +909,7 @@
#elif (STM32_SW == STM32_SW_HSE)
#define STM32_SYSCLK STM32_HSECLK
#else
#error "invalid STM32_SYSCLK_SW value specified"
#error "invalid STM32_SW value specified"
#endif
/* Check on the system clock.*/
@ -851,25 +948,47 @@
#endif
/**
* @brief APB frequency.
* @brief APB1 frequency.
*/
#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__)
#define STM32_PCLK (STM32_HCLK / 1)
#elif STM32_PPRE == STM32_PPRE_DIV2
#define STM32_PCLK (STM32_HCLK / 2)
#elif STM32_PPRE == STM32_PPRE_DIV4
#define STM32_PCLK (STM32_HCLK / 4)
#elif STM32_PPRE == STM32_PPRE_DIV8
#define STM32_PCLK (STM32_HCLK / 8)
#elif STM32_PPRE == STM32_PPRE_DIV16
#define STM32_PCLK (STM32_HCLK / 16)
#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__)
#define STM32_PCLK1 (STM32_HCLK / 1)
#elif STM32_PPRE1 == STM32_PPRE1_DIV2
#define STM32_PCLK1 (STM32_HCLK / 2)
#elif STM32_PPRE1 == STM32_PPRE1_DIV4
#define STM32_PCLK1 (STM32_HCLK / 4)
#elif STM32_PPRE1 == STM32_PPRE1_DIV8
#define STM32_PCLK1 (STM32_HCLK / 8)
#elif STM32_PPRE1 == STM32_PPRE1_DIV16
#define STM32_PCLK1 (STM32_HCLK / 16)
#else
#error "invalid STM32_PPRE value specified"
#error "invalid STM32_PPRE1 value specified"
#endif
/* APB frequency check.*/
#if STM32_PCLK > STM32_PCLK_MAX
#error "STM32_PCLK exceeding maximum frequency (STM32_PCLK_MAX)"
/* APB1 frequency check.*/
#if STM32_PCLK1 > STM32_PCLK1_MAX
#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)"
#endif
/**
* @brief APB2 frequency.
*/
#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__)
#define STM32_PCLK2 (STM32_HCLK / 1)
#elif STM32_PPRE2 == STM32_PPRE2_DIV2
#define STM32_PCLK2 (STM32_HCLK / 2)
#elif STM32_PPRE2 == STM32_PPRE2_DIV4
#define STM32_PCLK2 (STM32_HCLK / 4)
#elif STM32_PPRE2 == STM32_PPRE2_DIV8
#define STM32_PCLK2 (STM32_HCLK / 8)
#elif STM32_PPRE2 == STM32_PPRE2_DIV16
#define STM32_PCLK2 (STM32_HCLK / 16)
#else
#error "invalid STM32_PPRE2 value specified"
#endif
/* APB2 frequency check.*/
#if STM32_PCLK2 > STM32_PCLK2_MAX
#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)"
#endif
/**
@ -888,54 +1007,108 @@
#endif
/**
* @brief ADC frequency.
* @brief ADC12 frequency.
*/
#if STM32_ADCSW == STM32_ADCSW_HSI14
#define STM32_ADCCLK STM32_HSI14CLK
#elif STM32_ADCSW == STM32_ADCSW_PCLK
#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__)
#define STM32_ADCCLK (STM32_PCLK / 2)
#elif STM32_ADCPRE == STM32_ADCPRE_DIV4
#define STM32_ADCCLK (STM32_PCLK / 4)
#if (STM32_ADC12PRES == STM32_ADC12PRES_NOCLOCK) || defined(__DOXYGEN__)
#define STM32ADC12CLK 0
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV1
#define STM32ADC12CLK (STM32_PLLCLKOUT / 1)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV2
#define STM32ADC12CLK (STM32_PLLCLKOUT / 2)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV4
#define STM32ADC12CLK (STM32_PLLCLKOUT / 4)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV6
#define STM32ADC12CLK (STM32_PLLCLKOUT / 6)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV8
#define STM32ADC12CLK (STM32_PLLCLKOUT / 8)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV10
#define STM32ADC12CLK (STM32_PLLCLKOUT / 10)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV12
#define STM32ADC12CLK (STM32_PLLCLKOUT / 12)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV16
#define STM32ADC12CLK (STM32_PLLCLKOUT / 16)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV32
#define STM32ADC12CLK (STM32_PLLCLKOUT / 32)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV64
#define STM32ADC12CLK (STM32_PLLCLKOUT / 64)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV128
#define STM32ADC12CLK (STM32_PLLCLKOUT / 128)
#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV256
#define STM32ADC12CLK (STM32_PLLCLKOUT / 256)
#else
#error "invalid STM32_ADCPRE value specified"
#endif
#else
#error "invalid source selected for ADC clock"
#endif
/* ADC frequency check.*/
#if STM32_ADCCLK > STM32_ADCCLK_MAX
#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)"
#error "invalid STM32_ADC12PRES value specified"
#endif
/**
* @brief CEC frequency.
* @brief ADC34 frequency.
*/
#if STM32_CECSW == STM32_CECSW_HSI
#define STM32_CECCLK STM32_HSICLK
#elif STM32_CECSW == STM32_CECSW_LSE
#define STM32_CECCLK STM32_LSECLK
#if (STM32_ADC43PRES == STM32_ADC34PRES_NOCLOCK) || defined(__DOXYGEN__)
#define STM32ADC34CLK 0
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV1
#define STM32ADC34CLK (STM32_PLLCLKOUT / 1)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV2
#define STM32ADC34CLK (STM32_PLLCLKOUT / 2)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV4
#define STM32ADC34CLK (STM32_PLLCLKOUT / 4)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV6
#define STM32ADC34CLK (STM32_PLLCLKOUT / 6)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV8
#define STM32ADC34CLK (STM32_PLLCLKOUT / 8)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV10
#define STM32ADC34CLK (STM32_PLLCLKOUT / 10)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV12
#define STM32ADC34CLK (STM32_PLLCLKOUT / 12)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV16
#define STM32ADC34CLK (STM32_PLLCLKOUT / 16)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV32
#define STM32ADC34CLK (STM32_PLLCLKOUT / 32)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV64
#define STM32ADC34CLK (STM32_PLLCLKOUT / 64)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV128
#define STM32ADC34CLK (STM32_PLLCLKOUT / 128)
#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV256
#define STM32ADC34CLK (STM32_PLLCLKOUT / 256)
#else
#error "invalid source selected for CEC clock"
#error "invalid STM32_ADC34PRES value specified"
#endif
/* ADC12 frequency check.*/
#if STM32ADC12CLK > STM32_ADCCLK_MAX
#error "STM32ADC12CLK exceeding maximum frequency (STM32_ADCCLK_MAX)"
#endif
/* ADC34 frequency check.*/
#if STM32ADC34CLK > STM32_ADCCLK_MAX
#error "STM32ADC34CLK exceeding maximum frequency (STM32_ADCCLK_MAX)"
#endif
/**
* @brief I2C1 frequency.
*/
#if STM32_I2CSW == STM32_I2C1SW_HSI
#if STM32_I2C1SW == STM32_I2C1SW_HSI
#define STM32_I2C1CLK STM32_HSICLK
#elif STM32_I2CSW == STM32_I2C1SW_SYSCLK
#elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK
#define STM32_I2C1CLK STM32_SYSCLK
#else
#error "invalid source selected for I2C1 clock"
#endif
/**
* @brief I2C2 frequency.
*/
#if STM32_I2C2SW == STM32_I2C2SW_HSI
#define STM32_I2C2CLK STM32_HSICLK
#elif STM32_I2C2SW == STM32_I2C2SW_SYSCLK
#define STM32_I2C2CLK STM32_SYSCLK
#else
#error "invalid source selected for I2C2 clock"
#endif
/**
* @brief USART1 frequency.
*/
#if STM32_USART1SW == STM32_USART1SW_PCLK
#define STM32_USART1CLK STM32_PCLK
#define STM32_USART1CLK STM32_PCLK2
#elif STM32_USART1SW == STM32_USART1SW_SYSCLK
#define STM32_USART1CLK STM32_SYSCLK
#elif STM32_USART1SW == STM32_USART1SW_LSECLK
@ -947,14 +1120,114 @@
#endif
/**
* @brief Timers clock.
* @brief USART2 frequency.
*/
#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__)
#define STM32_TIMCLK1 (STM32_PCLK * 1)
#define STM32_TIMCLK2 (STM32_PCLK * 1)
#if STM32_USART2SW == STM32_USART2SW_PCLK
#define STM32_USART2CLK STM32_PCLK1
#elif STM32_USART2SW == STM32_USART2SW_SYSCLK
#define STM32_USART2CLK STM32_SYSCLK
#elif STM32_USART2SW == STM32_USART2SW_LSECLK
#define STM32_USART2CLK STM32_LSECLK
#elif STM32_USART2SW == STM32_USART2SW_HSICLK
#define STM32_USART2CLK STM32_HSICLK
#else
#define STM32_TIMCLK1 (STM32_PCLK * 2)
#define STM32_TIMCLK2 (STM32_PCLK * 2)
#error "invalid source selected for USART2 clock"
#endif
/**
* @brief USART3 frequency.
*/
#if STM32_USART3SW == STM32_USART3SW_PCLK
#define STM32_USART3CLK STM32_PCLK1
#elif STM32_USART3SW == STM32_USART3SW_SYSCLK
#define STM32_USART3CLK STM32_SYSCLK
#elif STM32_USART3SW == STM32_USART3SW_LSECLK
#define STM32_USART3CLK STM32_LSECLK
#elif STM32_USART3SW == STM32_USART3SW_HSICLK
#define STM32_USART3CLK STM32_HSICLK
#else
#error "invalid source selected for USART3 clock"
#endif
/**
* @brief UART4 frequency.
*/
#if STM32_UART4SW == STM32_UART4SW_PCLK
#define STM32_UART4CLK STM32_PCLK1
#elif STM32_UART4SW == STM32_UART4SW_SYSCLK
#define STM32_UART4CLK STM32_SYSCLK
#elif STM32_UART4SW == STM32_UART4SW_LSECLK
#define STM32_UART4CLK STM32_LSECLK
#elif STM32_UART4SW == STM32_UART4SW_HSICLK
#define STM32_UART4CLK STM32_HSICLK
#else
#error "invalid source selected for UART4 clock"
#endif
/**
* @brief UART5 frequency.
*/
#if STM32_UART5SW == STM32_UART5SW_PCLK
#define STM32_UART5CLK STM32_PCLK1
#elif STM32_UART5SW == STM32_UART5SW_SYSCLK
#define STM32_UART5CLK STM32_SYSCLK
#elif STM32_UART5SW == STM32_UART5SW_LSECLK
#define STM32_UART5CLK STM32_LSECLK
#elif STM32_UART5SW == STM32_UART5SW_HSICLK
#define STM32_UART5CLK STM32_HSICLK
#else
#error "invalid source selected for UART5 clock"
#endif
/**
* @brief TIM1 frequency.
*/
#if STM32_TIM1SW == STM32_TIM1SW_PCLK2
#define STM32_TIM1CLK STM32_PCLK2
#elif STM32_TIM1SW == STM32_TIM1SW_PLLX2
#define STM32_TIM1CLK (STM32_PLLCLKOUT * 2)
#else
#error "invalid source selected for TIM1 clock"
#endif
/**
* @brief TIM8 frequency.
*/
#if STM32_TIM8SW == STM32_TIM8SW_PCLK2
#define STM32_TIM8CLK STM32_PCLK2
#elif STM32_TIM8SW == STM32_TIM8SW_PLLX2
#define STM32_TIM8CLK (STM32_PLLCLKOUT * 2)
#else
#error "invalid source selected for TIM8 clock"
#endif
/**
* @brief Timers 2, 3, 4, 5, 6, 7, 12, 13, 14 frequency.
*/
#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__)
#define STM32_TIMCLK1 (STM32_PCLK1 * 1)
#else
#define STM32_TIMCLK1 (STM32_PCLK1 * 2)
#endif
/**
* @brief Timers 1, 8, 9, 10, 11 frequency.
*/
#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__)
#define STM32_TIMCLK2 (STM32_PCLK2 * 1)
#else
#define STM32_TIMCLK2 (STM32_PCLK2 * 2)
#endif
/**
* @brief USB frequency.
*/
#if (STM32_USBPRE == STM32_USBPRE_DIV1P5) || defined(__DOXYGEN__)
#define STM32_USBCLK ((STM32_PLLCLKOUT * 2) / 3)
#elif (STM32_USBPRE == STM32_USBPRE_DIV1)
#define STM32_USBCLK STM32_PLLCLKOUT
#else
#error "invalid STM32_USBPRE value specified"
#endif
/**
@ -962,8 +1235,10 @@
*/
#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__)
#define STM32_FLASHBITS 0x00000010
#else
#elif STM32_HCLK <= 48000000
#define STM32_FLASHBITS 0x00000011
#else
#define STM32_FLASHBITS 0x00000012
#endif
/*===========================================================================*/
@ -979,9 +1254,9 @@
/*===========================================================================*/
/* STM32 ISR, DMA and RCC helpers.*/
#include "stm32_isr.h"
/*#include "stm32_isr.h"
#include "stm32_dma.h"
#include "stm32_rcc.h"
#include "stm32_rcc.h"*/
#ifdef __cplusplus
extern "C" {

View File

@ -26,6 +26,8 @@
* @{
*/
/* TODO: LSEBYP like in F3.*/
#include "ch.h"
#include "hal.h"
@ -155,12 +157,14 @@ void stm32_clock_init(void) {
; /* Waits until HSI is stable. */
#if STM32_HSE_ENABLED
/* HSE activation.*/
#if defined(STM32_HSE_BYPASS)
/* HSE Bypass.*/
RCC->CR |= RCC_CR_HSEBYP;
#endif
/* HSE activation.*/
RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP;
#else
/* No HSE Bypass.*/
RCC->CR |= RCC_CR_HSEON;
#endif
while ((RCC->CR & RCC_CR_HSERDY) == 0)
; /* Waits until HSE is stable. */
#endif
@ -185,7 +189,8 @@ void stm32_clock_init(void) {
#if STM32_ACTIVATE_PLL
/* PLL activation.*/
RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN | STM32_PLLM;
RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN |
STM32_PLLM;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY))
; /* Waits until PLL is stable. */