mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #20609 from Enoch247/improve-stm32-periph-enable.2
cpu/stm32: de-duplicate ifdefs
This commit is contained in:
commit
fb4e0ccf10
@ -14,16 +14,43 @@
|
||||
* @brief Shared CPU specific function for the STM32 CPU family
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Joshua DeWeese <jdeweese@primecontrols.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "periph/cpu_common.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "compiler_hints.h"
|
||||
#include "modules.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if defined(CPU_FAM_STM32F2) || \
|
||||
defined(CPU_FAM_STM32F4) || \
|
||||
defined(CPU_FAM_STM32F7) || \
|
||||
defined(CPU_FAM_STM32L1)
|
||||
#define APB1_PERIPH_LP_EN RCC->APB1LPENR
|
||||
#define APB2_PERIPH_LP_EN RCC->APB2LPENR
|
||||
#ifdef AHB_PERIPH_EN
|
||||
#define AHB_PERIPH_LP_EN RCC->AHBLPENR
|
||||
#endif
|
||||
#ifdef AHB1_PERIPH_EN
|
||||
#define AHB1_PERIPH_LP_EN RCC->AHB1LPENR
|
||||
#endif
|
||||
#ifdef AHB2_PERIPH_EN
|
||||
#define AHB2_PERIPH_LP_EN RCC->AHB2LPENR
|
||||
#endif
|
||||
#ifdef AHB3_PERIPH_EN
|
||||
#define AHB3_PERIPH_LP_EN RCC->AHB3LPENR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Timer specific additional bus clock prescaler
|
||||
*
|
||||
@ -51,13 +78,291 @@ static const uint8_t apbmul[] = {
|
||||
[APB12] = 1,
|
||||
#endif
|
||||
#endif
|
||||
#if defined(APB2_PERIPH_EN)
|
||||
#if (CLOCK_APB2 < CLOCK_CORECLOCK)
|
||||
[APB2] = 2
|
||||
#else
|
||||
[APB2] = 1
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
static volatile uint32_t* _rcc_en_reg(bus_t bus)
|
||||
{
|
||||
switch (bus) {
|
||||
#ifdef APB1_PERIPH_EN
|
||||
case APB1:
|
||||
return &APB1_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef APB12_PERIPH_EN
|
||||
case APB12:
|
||||
return &APB12_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef APB2_PERIPH_EN
|
||||
case APB2:
|
||||
return &APB2_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef APB22_PERIPH_EN
|
||||
case APB22:
|
||||
return &APB22_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef APB3_PERIPH_EN
|
||||
case APB3:
|
||||
return &APB3_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef APB4_PERIPH_EN
|
||||
case APB4:
|
||||
return &APB4_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef AHB_PERIPH_EN
|
||||
case AHB:
|
||||
return &AHB_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef AHB1_PERIPH_EN
|
||||
case AHB1:
|
||||
return &AHB1_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef AHB2_PERIPH_EN
|
||||
case AHB2:
|
||||
return &AHB2_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef AHB22_PERIPH_EN
|
||||
case AHB22:
|
||||
return &AHB22_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef AHB3_PERIPH_EN
|
||||
case AHB3:
|
||||
return &AHB3_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef AHB4_PERIPH_EN
|
||||
case AHB4:
|
||||
return &AHB4_PERIPH_EN;
|
||||
#endif
|
||||
#ifdef IOP_PERIPH_EN
|
||||
case IOP:
|
||||
return &IOP_PERIPH_EN;
|
||||
#endif
|
||||
|
||||
case BUS_NUMOF:
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static volatile uint32_t* _rcc_dis_reg(bus_t bus)
|
||||
{
|
||||
/* Note this switch case is designed in such a way that a default is only
|
||||
provided when all other cases are *not* provided. This is to ensure that
|
||||
either all cases or no cases are provided. Anything else will cause the
|
||||
compiler to emit a warning. */
|
||||
switch (bus) {
|
||||
#ifdef APB1_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case APB1:
|
||||
return &APB1_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef APB12_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case APB12:
|
||||
return &APB12_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef APB2_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case APB2:
|
||||
return &APB2_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef APB22_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case APB22:
|
||||
return &APB22_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef APB3_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case APB3:
|
||||
return &APB3_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef APB4_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case APB4:
|
||||
return &APB4_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef AHB_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case AHB:
|
||||
return &AHB_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef AHB1_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case AHB1:
|
||||
return &AHB1_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef AHB2_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case AHB2:
|
||||
return &AHB2_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef AHB22_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case AHB22:
|
||||
return &AHB22_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef AHB3_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case AHB3:
|
||||
return &AHB3_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef AHB4_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case AHB4:
|
||||
return &AHB4_PERIPH_DIS;
|
||||
#endif
|
||||
#ifdef IOP_PERIPH_DIS
|
||||
#define RCC_REG_IS_ATOMIC 1
|
||||
case IOP:
|
||||
return &IOP_PERIPH_DIS;
|
||||
#endif
|
||||
|
||||
/* If MCU does not have separate set/clear bits. */
|
||||
#if RCC_REG_IS_ATOMIC == 0
|
||||
default:
|
||||
return _rcc_en_reg(bus);
|
||||
#else
|
||||
case BUS_NUMOF:
|
||||
assert(false);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static volatile uint32_t* _rcc_lp_en_reg(bus_t bus)
|
||||
{
|
||||
/* Note this switch case is designed in such a way that a default is only
|
||||
provided when all other cases are *not* provided. This is to ensure that
|
||||
either all cases or no cases are provided. Anything else will cause the
|
||||
compiler to emit a warning. */
|
||||
switch (bus) {
|
||||
#ifdef APB1_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case APB1:
|
||||
return &APB1_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef APB12_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case APB12:
|
||||
return &APB12_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef APB2_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case APB2:
|
||||
return &APB2_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef APB22_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case APB22:
|
||||
return &APB22_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef APB3_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case APB3:
|
||||
return &APB3_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef APB4_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case APB4:
|
||||
return &APB4_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef AHB_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case AHB:
|
||||
return &AHB_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef AHB1_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case AHB1:
|
||||
return &AHB1_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef AHB2_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case AHB2:
|
||||
return &AHB2_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef AHB22_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case AHB22:
|
||||
return &AHB22_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef AHB3_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case AHB3:
|
||||
return &AHB3_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef AHB4_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case AHB4:
|
||||
return &AHB4_PERIPH_LP_EN;
|
||||
#endif
|
||||
#ifdef IOP_PERIPH_LP_EN
|
||||
#define HAS_LP_MODE 1
|
||||
case IOP:
|
||||
return &IOP_PERIPH_LP_EN;
|
||||
#endif
|
||||
|
||||
#if HAS_LP_MODE == 0
|
||||
default:
|
||||
/* fall through */
|
||||
#endif
|
||||
case BUS_NUMOF:
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static volatile uint32_t* _rcc_lp_dis_reg(bus_t bus)
|
||||
{
|
||||
#if RCC_REG_IS_ATOMIC && HAS_LP_MODE
|
||||
#error "Atomic disable of periph-in-low-power-mode not implemented yet."
|
||||
#endif
|
||||
|
||||
return _rcc_lp_en_reg(bus);
|
||||
}
|
||||
|
||||
static void _rcc_reg_set(volatile uint32_t *reg, uint32_t mask)
|
||||
{
|
||||
assert(reg);
|
||||
|
||||
if (IS_ACTIVE(RCC_REG_IS_ATOMIC)) {
|
||||
*reg = mask;
|
||||
}
|
||||
else {
|
||||
const int irq_state = irq_disable();
|
||||
*reg |= mask;
|
||||
irq_restore(irq_state);
|
||||
}
|
||||
}
|
||||
|
||||
static void _rcc_reg_clr(volatile uint32_t *reg, uint32_t mask)
|
||||
{
|
||||
assert(reg);
|
||||
|
||||
if (IS_ACTIVE(RCC_REG_IS_ATOMIC)) {
|
||||
*reg = mask;
|
||||
}
|
||||
else {
|
||||
const int irq_state = irq_disable();
|
||||
*reg &= ~(mask);
|
||||
irq_restore(irq_state);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t periph_apb_clk(bus_t bus)
|
||||
{
|
||||
#ifdef CLOCK_APB2
|
||||
@ -77,317 +382,46 @@ uint32_t periph_timer_clk(bus_t bus)
|
||||
|
||||
void periph_clk_en(bus_t bus, uint32_t mask)
|
||||
{
|
||||
switch (bus) {
|
||||
case APB1:
|
||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32L5) || \
|
||||
defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL)
|
||||
RCC->APB1ENR1 |= mask;
|
||||
#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32C0)
|
||||
RCC->APBENR1 |= mask;
|
||||
#elif defined(CPU_FAM_STM32MP1)
|
||||
RCC->MC_APB1ENSETR |= mask;
|
||||
#else
|
||||
RCC->APB1ENR |= mask;
|
||||
#endif
|
||||
break;
|
||||
#if !defined(CPU_FAM_STM32G0) && !defined(CPU_FAM_STM32C0)
|
||||
case APB2:
|
||||
#if defined(CPU_FAM_STM32MP1)
|
||||
RCC->MC_APB2ENSETR |= mask;
|
||||
#else
|
||||
RCC->APB2ENR |= mask;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32WL) || defined(CPU_FAM_STM32U5)
|
||||
case APB3:
|
||||
RCC->APB3ENR |= mask;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32L5) || \
|
||||
defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL)
|
||||
case APB12:
|
||||
RCC->APB1ENR2 |= mask;
|
||||
break;
|
||||
#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32C0)
|
||||
case APB12:
|
||||
RCC->APBENR2 |= mask;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32G0) || \
|
||||
defined(CPU_FAM_STM32C0)
|
||||
case AHB:
|
||||
RCC->AHBENR |= mask;
|
||||
break;
|
||||
case IOP:
|
||||
RCC->IOPENR |= mask;
|
||||
break;
|
||||
#elif defined(CPU_FAM_STM32L1) || defined(CPU_FAM_STM32F1) || \
|
||||
defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
case AHB:
|
||||
RCC->AHBENR |= mask;
|
||||
break;
|
||||
#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \
|
||||
defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32F7) || \
|
||||
defined(CPU_FAM_STM32WB) || defined(CPU_FAM_STM32G4) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) || \
|
||||
defined(CPU_FAM_STM32WL)
|
||||
case AHB1:
|
||||
RCC->AHB1ENR |= mask;
|
||||
break;
|
||||
/* STM32F410 RCC doesn't provide AHB2 and AHB3 */
|
||||
#if !defined(CPU_LINE_STM32F410Rx)
|
||||
case AHB2:
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
RCC->AHB2ENR1 |= mask;
|
||||
#else
|
||||
RCC->AHB2ENR |= mask;
|
||||
#endif
|
||||
break;
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
case AHB22:
|
||||
RCC->AHB2ENR2 |= mask;
|
||||
break;
|
||||
#endif
|
||||
case AHB3:
|
||||
RCC->AHB3ENR |= mask;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32MP1)
|
||||
case AHB4:
|
||||
RCC->MC_AHB4ENSETR |= mask;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DEBUG("unsupported bus %d\n", (int)bus);
|
||||
break;
|
||||
}
|
||||
assert(bus < BUS_NUMOF);
|
||||
|
||||
_rcc_reg_set(_rcc_en_reg(bus), mask);
|
||||
|
||||
/* stm32xx-errata: Delay after a RCC peripheral clock enable */
|
||||
__DSB();
|
||||
}
|
||||
|
||||
void periph_clk_dis(bus_t bus, uint32_t mask)
|
||||
{
|
||||
switch (bus) {
|
||||
case APB1:
|
||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32L5) || \
|
||||
defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL)
|
||||
RCC->APB1ENR1 &= ~(mask);
|
||||
#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32C0)
|
||||
RCC->APBENR1 &= ~(mask);
|
||||
#elif defined(CPU_FAM_STM32MP1)
|
||||
/* Write 1 to clear */
|
||||
RCC->MC_APB1ENCLRR |= mask;
|
||||
#else
|
||||
RCC->APB1ENR &= ~(mask);
|
||||
#endif
|
||||
break;
|
||||
#if !defined(CPU_FAM_STM32G0) && !defined(CPU_FAM_STM32C0)
|
||||
case APB2:
|
||||
#if defined(CPU_FAM_STM32MP1)
|
||||
RCC->MC_APB2ENCLRR |= mask;
|
||||
#else
|
||||
RCC->APB2ENR &= ~(mask);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32WL) || defined(CPU_FAM_STM32U5)
|
||||
case APB3:
|
||||
RCC->APB3ENR &= ~(mask);
|
||||
break;
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32L5) || \
|
||||
defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL)
|
||||
case APB12:
|
||||
RCC->APB1ENR2 &= ~(mask);
|
||||
break;
|
||||
#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32C0)
|
||||
case APB12:
|
||||
RCC->APBENR2 &= ~(mask);
|
||||
break;
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32L0)
|
||||
case AHB:
|
||||
RCC->AHBENR &= ~(mask);
|
||||
break;
|
||||
case IOP:
|
||||
RCC->IOPENR &= ~(mask);
|
||||
break;
|
||||
#elif defined(CPU_FAM_STM32L1) || defined(CPU_FAM_STM32F1) || \
|
||||
defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
case AHB:
|
||||
RCC->AHBENR &= ~(mask);
|
||||
break;
|
||||
#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \
|
||||
defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32F7) || \
|
||||
defined(CPU_FAM_STM32WB) || defined(CPU_FAM_STM32G4) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) || \
|
||||
defined(CPU_FAM_STM32WL)
|
||||
case AHB1:
|
||||
RCC->AHB1ENR &= ~(mask);
|
||||
break;
|
||||
/* STM32F410 RCC doesn't provide AHB2 and AHB3 */
|
||||
#if !defined(CPU_LINE_STM32F410Rx)
|
||||
case AHB2:
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
RCC->AHB2ENR1 &= ~(mask);
|
||||
#else
|
||||
RCC->AHB2ENR &= ~(mask);
|
||||
#endif
|
||||
break;
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
case AHB22:
|
||||
RCC->AHB2ENR2 &= ~(mask);
|
||||
break;
|
||||
#endif
|
||||
case AHB3:
|
||||
RCC->AHB3ENR &= ~(mask);
|
||||
break;
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32WB)
|
||||
case AHB4:
|
||||
RCC->AHB3ENR &= ~(mask);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
DEBUG("unsupported bus %d\n", (int)bus);
|
||||
break;
|
||||
}
|
||||
assert(bus < BUS_NUMOF);
|
||||
_rcc_reg_clr(_rcc_dis_reg(bus), mask);
|
||||
}
|
||||
|
||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32G4) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5)
|
||||
MAYBE_UNUSED static inline
|
||||
void _periph_lpclk_en(bus_t bus, uint32_t mask)
|
||||
{
|
||||
assert(bus < BUS_NUMOF);
|
||||
_rcc_reg_set(_rcc_lp_en_reg(bus), mask);
|
||||
}
|
||||
|
||||
MAYBE_UNUSED static inline
|
||||
void _periph_lpclk_dis(bus_t bus, uint32_t mask)
|
||||
{
|
||||
assert(bus < BUS_NUMOF);
|
||||
_rcc_reg_clr(_rcc_lp_dis_reg(bus), mask);
|
||||
}
|
||||
|
||||
#if HAS_LP_MODE
|
||||
void periph_lpclk_en(bus_t bus, uint32_t mask)
|
||||
{
|
||||
switch (bus) {
|
||||
case APB1:
|
||||
RCC->APB1SMENR1 |= mask;
|
||||
break;
|
||||
case APB12:
|
||||
RCC->APB1SMENR2 |= mask;
|
||||
break;
|
||||
case APB2:
|
||||
RCC->APB2SMENR |= mask;
|
||||
break;
|
||||
case AHB1:
|
||||
RCC->AHB1SMENR |= mask;
|
||||
break;
|
||||
case AHB2:
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
RCC->AHB2SMENR1 |= mask;
|
||||
#else
|
||||
RCC->AHB2SMENR |= mask;
|
||||
#endif
|
||||
break;
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
case AHB22:
|
||||
RCC->AHB2SMENR2 |= mask;
|
||||
break;
|
||||
#endif
|
||||
case AHB3:
|
||||
RCC->AHB3SMENR |= mask;
|
||||
break;
|
||||
default:
|
||||
DEBUG("unsupported bus %d\n", (int)bus);
|
||||
break;
|
||||
}
|
||||
/* call the function's implementation, which is outside the ifdef */
|
||||
_periph_lpclk_en(bus, mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_LP_MODE
|
||||
void periph_lpclk_dis(bus_t bus, uint32_t mask)
|
||||
{
|
||||
switch (bus) {
|
||||
case APB1:
|
||||
RCC->APB1SMENR1 &= ~(mask);
|
||||
break;
|
||||
case APB12:
|
||||
RCC->APB1SMENR2 &= ~(mask);
|
||||
break;
|
||||
case APB2:
|
||||
RCC->APB2SMENR &= ~(mask);
|
||||
break;
|
||||
case AHB1:
|
||||
RCC->AHB1SMENR &= ~(mask);
|
||||
break;
|
||||
case AHB2:
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
RCC->AHB2SMENR1 &= ~(mask);
|
||||
#else
|
||||
RCC->AHB2SMENR &= ~(mask);
|
||||
#endif
|
||||
break;
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
case AHB22:
|
||||
RCC->AHB2SMENR2 &= ~(mask);
|
||||
break;
|
||||
#endif
|
||||
case AHB3:
|
||||
RCC->AHB3SMENR &= ~(mask);
|
||||
break;
|
||||
default:
|
||||
DEBUG("unsupported bus %d\n", (int)bus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#elif defined(CPU_FAM_STM32F2) || \
|
||||
defined(CPU_FAM_STM32F4) || \
|
||||
defined(CPU_FAM_STM32F7)
|
||||
void periph_lpclk_en(bus_t bus, uint32_t mask)
|
||||
{
|
||||
switch (bus) {
|
||||
case APB1:
|
||||
RCC->APB1LPENR |= mask;
|
||||
break;
|
||||
case APB2:
|
||||
RCC->APB2LPENR |= mask;
|
||||
break;
|
||||
case AHB1:
|
||||
RCC->AHB1LPENR |= mask;
|
||||
break;
|
||||
/* STM32F410 RCC doesn't provide AHB2 and AHB3 */
|
||||
#if !defined(CPU_LINE_STM32F410Rx)
|
||||
case AHB2:
|
||||
RCC->AHB2LPENR |= mask;
|
||||
break;
|
||||
case AHB3:
|
||||
RCC->AHB3LPENR |= mask;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DEBUG("unsupported bus %d\n", (int)bus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void periph_lpclk_dis(bus_t bus, uint32_t mask)
|
||||
{
|
||||
switch (bus) {
|
||||
case APB1:
|
||||
RCC->APB1LPENR &= ~(mask);
|
||||
break;
|
||||
case APB2:
|
||||
RCC->APB2LPENR &= ~(mask);
|
||||
break;
|
||||
case AHB1:
|
||||
RCC->AHB1LPENR &= ~(mask);
|
||||
break;
|
||||
/* STM32F410 RCC doesn't provide AHB2 and AHB3 */
|
||||
#if !defined(CPU_LINE_STM32F410Rx)
|
||||
case AHB2:
|
||||
RCC->AHB2LPENR &= ~(mask);
|
||||
break;
|
||||
case AHB3:
|
||||
RCC->AHB3LPENR &= ~(mask);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DEBUG("unsupported bus %d\n", (int)bus);
|
||||
break;
|
||||
}
|
||||
/* call the function's implementation, which is outside the ifdef */
|
||||
_periph_lpclk_dis(bus, mask);
|
||||
}
|
||||
#endif
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cpu_conf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -68,49 +70,148 @@ extern "C" {
|
||||
#error "error: LSI clock speed not defined for your target CPU"
|
||||
#endif
|
||||
|
||||
/* if CPU has APB1 bus */
|
||||
#if defined(CPU_FAM_STM32G4) || \
|
||||
defined(CPU_FAM_STM32L4) || \
|
||||
defined(CPU_FAM_STM32L5) || \
|
||||
defined(CPU_FAM_STM32U5) || \
|
||||
defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32WL)
|
||||
#define APB1_PERIPH_EN RCC->APB1ENR1
|
||||
#define APB12_PERIPH_EN RCC->APB1ENR2
|
||||
#elif defined(CPU_FAM_STM32C0) || \
|
||||
defined(CPU_FAM_STM32G0)
|
||||
#define APB1_PERIPH_EN RCC->APBENR1
|
||||
#define APB12_PERIPH_EN RCC->APBENR2
|
||||
#elif defined(CPU_FAM_STM32MP1)
|
||||
#define APB1_PERIPH_EN RCC->MC_APB1ENSETR
|
||||
#define APB1_PERIPH_DIS RCC->MC_APB1ENCLRR
|
||||
#elif defined(APB1PERIPH_BASE) || \
|
||||
defined(CPU_FAM_STM32F0) || \
|
||||
defined(CPU_FAM_STM32L0)
|
||||
#define APB1_PERIPH_EN RCC->APB1ENR
|
||||
#endif
|
||||
|
||||
/* if CPU has APB2 bus */
|
||||
#if defined(CPU_FAM_STM32MP1)
|
||||
#define APB2_PERIPH_EN RCC->MC_APB2ENSETR
|
||||
#define APB2_PERIPH_DIS RCC->MC_APB2ENCLRR
|
||||
#elif defined(APB2PERIPH_BASE) || \
|
||||
defined(CPU_FAM_STM32F0) || \
|
||||
defined(CPU_FAM_STM32L0)
|
||||
#define APB2_PERIPH_EN RCC->APB2ENR
|
||||
#endif
|
||||
|
||||
/* if CPU has APB3 bus */
|
||||
#if defined(CPU_FAM_STM32WB)
|
||||
/* CPU has APB3, but no periph enable registers for the bus. */
|
||||
#undef APB3_PERIPH_EN /* not defined */
|
||||
#elif defined(APB3PERIPH_BASE) || \
|
||||
defined(APB3PERIPH_BASE_S)
|
||||
#define APB3_PERIPH_EN RCC->APB3ENR
|
||||
#endif
|
||||
|
||||
/* if CPU has AHB/AHB1 bus */
|
||||
#if defined(AHBPERIPH_BASE) || \
|
||||
defined(CPU_FAM_STM32F3)
|
||||
#define AHB_PERIPH_EN RCC->AHBENR
|
||||
#elif defined(CPU_FAM_STM32MP1)
|
||||
/* CPU has AHB1, but no periph enable registers for the bus. */
|
||||
#undef AHB1_PERIPH_EN /* not defined */
|
||||
#undef AHB1_PERIPH_DIS /* not defined */
|
||||
#elif defined(AHB1PERIPH_BASE)
|
||||
#define AHB1_PERIPH_EN RCC->AHB1ENR
|
||||
#endif
|
||||
|
||||
/* if CPU has AHB2 bus */
|
||||
#if defined(CPU_FAM_STM32F0) || \
|
||||
defined(CPU_FAM_STM32F3)
|
||||
/* CPU has AHB2, but no periph enable registers for the bus. */
|
||||
#undef AHB2_PERIPH_EN /* not defined */
|
||||
#elif defined(CPU_FAM_STM32U5)
|
||||
#define AHB2_PERIPH_EN RCC->AHB2ENR1
|
||||
#define AHB22_PERIPH_EN RCC->AHB2ENR2
|
||||
#elif defined(CPU_FAM_STM32F4) && defined(RCC_AHB2_SUPPORT)
|
||||
#define AHB2_PERIPH_EN RCC->AHB2ENR
|
||||
#elif defined(CPU_FAM_STM32MP1)
|
||||
#define AHB2_PERIPH_EN RCC->MC_AHB2ENSETR
|
||||
#define AHB2_PERIPH_DIS RCC->MC_AHB2ENCLRR
|
||||
#elif defined(AHB2PERIPH_BASE)
|
||||
#define AHB2_PERIPH_EN RCC->AHB2ENR
|
||||
#endif
|
||||
|
||||
/* if CPU has AHB3 bus */
|
||||
#if defined(CPU_FAM_STM32F3)
|
||||
/* CPU has AHB3, but no periph enable registers for the bus. */
|
||||
#undef AHB3_PERIPH_EN /* not defined */
|
||||
#elif defined(CPU_FAM_STM32F4) && defined(RCC_AHB3_SUPPORT)
|
||||
#define AHB3_PERIPH_EN RCC->AHB3ENR
|
||||
#elif defined(CPU_FAM_STM32MP1)
|
||||
#define AHB3_PERIPH_EN RCC->MC_AHB3ENSETR
|
||||
#define AHB3_PERIPH_DIS RCC->MC_AHB3ENCLRR
|
||||
#elif defined(AHB3PERIPH_BASE) || \
|
||||
defined(AHB3PERIPH_BASE_S) || \
|
||||
defined(CPU_FAM_STM32F2) || \
|
||||
defined(CPU_FAM_STM32F7) || \
|
||||
defined(CPU_FAM_STM32G4) || \
|
||||
defined(CPU_FAM_STM32L4)
|
||||
#define AHB3_PERIPH_EN RCC->AHB3ENR
|
||||
#endif
|
||||
|
||||
/* if CPU has AHB4 bus */
|
||||
#if defined(CPU_FAM_STM32MP1)
|
||||
#define AHB4_PERIPH_EN RCC->MC_AHB4ENSETR
|
||||
#define AHB4_PERIPH_DIS RCC->MC_AHB4ENCLRR
|
||||
#elif defined(AHB4PERIPH_BASE)
|
||||
/* AHB3ENR is not a typo here. It controls both AHB3 and AHB4. */
|
||||
#define AHB4_PERIPH_EN RCC->AHB3ENR
|
||||
#endif
|
||||
|
||||
/* if CPU has IOP bus */
|
||||
#if defined(IOPPERIPH_BASE) || \
|
||||
defined(RCC_IOPENR_GPIOAEN) || \
|
||||
defined(RCC_IOPENR_IOPAEN)
|
||||
#define IOP_PERIPH_EN RCC->IOPENR
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Available peripheral buses
|
||||
*/
|
||||
typedef enum {
|
||||
#if defined(APB1_PERIPH_EN)
|
||||
APB1, /**< APB1 bus */
|
||||
APB2, /**< APB2 bus */
|
||||
#if defined(CPU_FAM_STM32WL) || defined(CPU_FAM_STM32U5)
|
||||
APB3,
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) || \
|
||||
defined(CPU_FAM_STM32WL) || defined(CPU_FAM_STM32C0)
|
||||
#if defined(APB12_PERIPH_EN)
|
||||
APB12, /**< AHB1 bus, second register */
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32G0) || \
|
||||
defined(CPU_FAM_STM32C0)
|
||||
#if defined(APB2_PERIPH_EN)
|
||||
APB2, /**< APB2 bus */
|
||||
#endif
|
||||
#if defined(APB3_PERIPH_EN)
|
||||
APB3, /**< APB3 bus */
|
||||
#endif
|
||||
#if defined(AHB_PERIPH_EN)
|
||||
AHB, /**< AHB bus */
|
||||
IOP, /**< IOP bus */
|
||||
#elif defined(CPU_FAM_STM32L1) || defined(CPU_FAM_STM32F1) || \
|
||||
defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
AHB, /**< AHB bus */
|
||||
#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \
|
||||
defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32F7) || \
|
||||
defined(CPU_FAM_STM32WB) || defined(CPU_FAM_STM32G4) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) || \
|
||||
defined(CPU_FAM_STM32WL)
|
||||
#endif
|
||||
#if defined(AHB1_PERIPH_EN)
|
||||
AHB1, /**< AHB1 bus */
|
||||
#endif
|
||||
#if defined(AHB2_PERIPH_EN)
|
||||
AHB2, /**< AHB2 bus */
|
||||
#if defined(CPU_FAM_STM32U5)
|
||||
#endif
|
||||
#if defined(AHB22_PERIPH_EN)
|
||||
AHB22, /**< AHB2 bus, second register */
|
||||
#endif
|
||||
#if defined(AHB3_PERIPH_EN)
|
||||
AHB3, /**< AHB3 bus */
|
||||
#elif defined(CPU_FAM_STM32MP1)
|
||||
AHB1, /**< AHB1 bus */
|
||||
AHB2, /**< AHB2 bus */
|
||||
AHB3, /**< AHB3 bus */
|
||||
#else
|
||||
#warning "unsupported stm32XX family"
|
||||
#endif
|
||||
#if defined(CPU_FAM_STM32WB) || defined(CPU_FAM_STM32MP1)
|
||||
#if defined(AHB4_PERIPH_EN)
|
||||
AHB4, /**< AHB4 bus */
|
||||
#endif
|
||||
#if defined(IOP_PERIPH_EN)
|
||||
IOP, /**< IOP bus */
|
||||
#endif
|
||||
BUS_NUMOF /**< number of buses */
|
||||
} bus_t;
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user