Merge "Merge arm branch into master"

This commit is contained in:
Anas Nashif 2017-02-11 04:00:58 +00:00
commit 110df98619
58 changed files with 1532 additions and 2977 deletions

View file

@ -6,6 +6,6 @@ ccflags-y +=-I$(srctree)/include/
asflags-y = $(ccflags-y) asflags-y = $(ccflags-y)
obj-y = vector_table.o reset.o \ obj-y = vector_table.o reset.o \
nmi_on_reset.o prep_c.o scs.o scb.o nmi.o \ nmi_on_reset.o prep_c.o scb.o nmi.o \
exc_manage.o exc_manage.o

View file

@ -1,22 +0,0 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARM CORTEX-M Series System Control Space
*
* Most of the SCS interface consists of simple bit-flipping methods, and is
* implemented as inline functions in scs.h. This module thus contains only data
* definitions and more complex routines, if needed.
*/
#include <kernel.h>
#include <arch/cpu.h>
#include <toolchain.h>
#include <sections.h>
/* the linker always puts this object at 0xe000e000 */
volatile struct __scs __scs_section __scs;

View file

@ -64,33 +64,32 @@ void _FaultDump(const NANO_ESF *esf, int fault)
int escalation = 0; int escalation = 0;
if (3 == fault) { /* hard fault */ if (3 == fault) { /* hard fault */
escalation = _ScbHardFaultIsForced(); escalation = SCB->HFSR & SCB_HFSR_FORCED_Msk;
PR_EXC("HARD FAULT: %s\n", PR_EXC("HARD FAULT: %s\n",
escalation ? "Escalation (see below)!" escalation ? "Escalation (see below)!"
: "Bus fault on vector table read\n"); : "Bus fault on vector table read\n");
} }
PR_EXC("MMFSR: 0x%" PRIx32 ", BFSR: 0x%" PRIx32 ", UFSR: 0x%" PR_EXC("MMFSR: 0x%" PRIx32 ", BFSR: 0x%" PRIx32 ", UFSR: 0x%"
PRIx32 "\n", PRIx32 "\n", SCB_MMFSR, SCB_BFSR, SCB_MMFSR);
__scs.scb.cfsr.byte.mmfsr.val,
__scs.scb.cfsr.byte.bfsr.val,
__scs.scb.cfsr.byte.ufsr.val);
if (_ScbMemFaultIsMmfarValid()) { if (SCB->CFSR & CFSR_MMARVALID_Msk) {
PR_EXC("MMFAR: 0x%" PRIx32 "\n", _ScbMemFaultAddrGet()); PR_EXC("MMFAR: 0x%" PRIx32 "\n", SCB->MMFAR);
if (escalation) { if (escalation) {
_ScbMemFaultMmfarReset(); /* clear MMAR[VALID] to reset */
SCB->CFSR &= ~CFSR_MMARVALID_Msk;
} }
} }
if (_ScbBusFaultIsBfarValid()) { if (SCB->CFSR & CFSR_BFARVALID_Msk) {
PR_EXC("BFAR: 0x%" PRIx32 "\n", _ScbBusFaultAddrGet()); PR_EXC("BFAR: 0x%" PRIx32 "\n", SCB->BFAR);
if (escalation) { if (escalation) {
_ScbBusFaultBfarReset(); /* clear CFSR_BFAR[VALID] to reset */
SCB->CFSR &= ~CFSR_BFARVALID_Msk;
} }
} }
/* clear USFR sticky bits */ /* clear USFR sticky bits */
_ScbUsageFaultAllFaultsReset(); SCB->CFSR |= SCB_CFSR_USGFAULTSR_Msk;
#else #else
#error Unknown ARM architecture #error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */ #endif /* CONFIG_ARMV6_M */
@ -130,20 +129,20 @@ static void _MpuFault(const NANO_ESF *esf, int fromHardFault)
_FaultThreadShow(esf); _FaultThreadShow(esf);
if (_ScbMemFaultIsStacking()) { if (SCB->CFSR & CFSR_MSTKERR_Msk) {
PR_EXC(" Stacking error\n"); PR_EXC(" Stacking error\n");
} else if (_ScbMemFaultIsUnstacking()) { } else if (SCB->CFSR & CFSR_MUNSTKERR_Msk) {
PR_EXC(" Unstacking error\n"); PR_EXC(" Unstacking error\n");
} else if (_ScbMemFaultIsDataAccessViolation()) { } else if (SCB->CFSR & CFSR_DACCVIOL_Msk) {
PR_EXC(" Data Access Violation\n"); PR_EXC(" Data Access Violation\n");
if (_ScbMemFaultIsMmfarValid()) { if (SCB->CFSR & CFSR_MMARVALID_Msk) {
PR_EXC(" Address: 0x%" PRIx32 "\n", PR_EXC(" Address: 0x%" PRIx32 "\n", SCB->MMFAR);
_ScbMemFaultAddrGet());
if (fromHardFault) { if (fromHardFault) {
_ScbMemFaultMmfarReset(); /* clear MMAR[VALID] to reset */
SCB->CFSR &= ~CFSR_MMARVALID_Msk;
} }
} }
} else if (_ScbMemFaultIsInstrAccessViolation()) { } else if (SCB->CFSR & CFSR_IACCVIOL_Msk) {
PR_EXC(" Instruction Access Violation\n"); PR_EXC(" Instruction Access Violation\n");
} }
} }
@ -162,26 +161,26 @@ static void _BusFault(const NANO_ESF *esf, int fromHardFault)
_FaultThreadShow(esf); _FaultThreadShow(esf);
if (_ScbBusFaultIsStacking()) { if (SCB->CFSR & CFSR_STKERR_Msk) {
PR_EXC(" Stacking error\n"); PR_EXC(" Stacking error\n");
} else if (_ScbBusFaultIsUnstacking()) { } else if (SCB->CFSR & CFSR_UNSTKERR_Msk) {
PR_EXC(" Unstacking error\n"); PR_EXC(" Unstacking error\n");
} else if (_ScbBusFaultIsPrecise()) { } else if (SCB->CFSR & CFSR_PRECISERR_Msk) {
PR_EXC(" Precise data bus error\n"); PR_EXC(" Precise data bus error\n");
if (_ScbBusFaultIsBfarValid()) { if (SCB->CFSR & CFSR_BFARVALID_Msk) {
PR_EXC(" Address: 0x%" PRIx32 "\n", PR_EXC(" Address: 0x%" PRIx32 "\n", SCB->BFAR);
_ScbBusFaultAddrGet());
if (fromHardFault) { if (fromHardFault) {
_ScbBusFaultBfarReset(); /* clear CFSR_BFAR[VALID] to reset */
SCB->CFSR &= ~CFSR_BFARVALID_Msk;
} }
} }
/* it's possible to have both a precise and imprecise fault */ /* it's possible to have both a precise and imprecise fault */
if (_ScbBusFaultIsImprecise()) { if (SCB->CFSR & CFSR_IMPRECISERR_Msk) {
PR_EXC(" Imprecise data bus error\n"); PR_EXC(" Imprecise data bus error\n");
} }
} else if (_ScbBusFaultIsImprecise()) { } else if (SCB->CFSR & CFSR_IMPRECISERR_Msk) {
PR_EXC(" Imprecise data bus error\n"); PR_EXC(" Imprecise data bus error\n");
} else if (_ScbBusFaultIsInstrBusErr()) { } else if (SCB->CFSR & CFSR_IBUSERR_Msk) {
PR_EXC(" Instruction bus error\n"); PR_EXC(" Instruction bus error\n");
} }
} }
@ -201,26 +200,27 @@ static void _UsageFault(const NANO_ESF *esf)
_FaultThreadShow(esf); _FaultThreadShow(esf);
/* bits are sticky: they stack and must be reset */ /* bits are sticky: they stack and must be reset */
if (_ScbUsageFaultIsDivByZero()) { if (SCB->CFSR & CFSR_DIVBYZERO_Msk) {
PR_EXC(" Division by zero\n"); PR_EXC(" Division by zero\n");
} }
if (_ScbUsageFaultIsUnaligned()) { if (SCB->CFSR & CFSR_UNALIGNED_Msk) {
PR_EXC(" Unaligned memory access\n"); PR_EXC(" Unaligned memory access\n");
} }
if (_ScbUsageFaultIsNoCp()) { if (SCB->CFSR & CFSR_NOCP_Msk) {
PR_EXC(" No coprocessor instructions\n"); PR_EXC(" No coprocessor instructions\n");
} }
if (_ScbUsageFaultIsInvalidPcLoad()) { if (SCB->CFSR & CFSR_INVPC_Msk) {
PR_EXC(" Illegal load of EXC_RETURN into PC\n"); PR_EXC(" Illegal load of EXC_RETURN into PC\n");
} }
if (_ScbUsageFaultIsInvalidState()) { if (SCB->CFSR & CFSR_INVSTATE_Msk) {
PR_EXC(" Illegal use of the EPSR\n"); PR_EXC(" Illegal use of the EPSR\n");
} }
if (_ScbUsageFaultIsUndefinedInstr()) { if (SCB->CFSR & CFSR_UNDEFINSTR_Msk) {
PR_EXC(" Attempt to execute undefined instruction\n"); PR_EXC(" Attempt to execute undefined instruction\n");
} }
_ScbUsageFaultAllFaultsReset(); /* clear USFR sticky bits */
SCB->CFSR |= SCB_CFSR_USGFAULTSR_Msk;
} }
/** /**
@ -257,15 +257,15 @@ static void _HardFault(const NANO_ESF *esf)
#if defined(CONFIG_ARMV6_M) #if defined(CONFIG_ARMV6_M)
_FaultThreadShow(esf); _FaultThreadShow(esf);
#elif defined(CONFIG_ARMV7_M) #elif defined(CONFIG_ARMV7_M)
if (_ScbHardFaultIsBusErrOnVectorRead()) { if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk) {
PR_EXC(" Bus fault on vector table read\n"); PR_EXC(" Bus fault on vector table read\n");
} else if (_ScbHardFaultIsForced()) { } else if (SCB->HFSR & SCB_HFSR_FORCED_Msk) {
PR_EXC(" Fault escalation (see below)\n"); PR_EXC(" Fault escalation (see below)\n");
if (_ScbIsMemFault()) { if (SCB_MMFSR) {
_MpuFault(esf, 1); _MpuFault(esf, 1);
} else if (_ScbIsBusFault()) { } else if (SCB_BFSR) {
_BusFault(esf, 1); _BusFault(esf, 1);
} else if (_ScbIsUsageFault()) { } else if (SCB_UFSR) {
_UsageFault(esf); _UsageFault(esf);
} }
} }
@ -360,7 +360,7 @@ static void _FaultDump(const NANO_ESF *esf, int fault)
*/ */
void _Fault(const NANO_ESF *esf) void _Fault(const NANO_ESF *esf)
{ {
int fault = _ScbActiveVectorGet(); int fault = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk;
FAULT_DUMP(esf, fault); FAULT_DUMP(esf, fault);
@ -379,7 +379,7 @@ void _FaultInit(void)
{ {
#if defined(CONFIG_ARMV6_M) #if defined(CONFIG_ARMV6_M)
#elif defined(CONFIG_ARMV7_M) #elif defined(CONFIG_ARMV7_M)
_ScbDivByZeroFaultEnable(); SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk;
#else #else
#error Unknown ARM architecture #error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */ #endif /* CONFIG_ARMV6_M */

View file

@ -88,7 +88,7 @@ _stack_frame_endif:
eors.n r0, r0 eors.n r0, r0
msr BASEPRI, r0 msr BASEPRI, r0
/* this reimplements _ScbIsNestedExc() */ /* this checks to see if we are in a nested exception */
ldr ip, =_SCS_ICSR ldr ip, =_SCS_ICSR
ldr ip, [ip] ldr ip, [ip]
ands.w ip, #_SCS_ICSR_RETTOBASE ands.w ip, #_SCS_ICSR_RETTOBASE

View file

@ -53,7 +53,8 @@ static ALWAYS_INLINE int _IsInIsr(void)
#if defined(CONFIG_ARMV6_M) #if defined(CONFIG_ARMV6_M)
return (vector > 10) || (vector == 3); return (vector > 10) || (vector == 3);
#elif defined(CONFIG_ARMV7_M) #elif defined(CONFIG_ARMV7_M)
return (vector > 10) || (vector && _ScbIsNestedExc()); return (vector > 10) ||
(vector && !(SCB->ICSR & SCB_ICSR_RETTOBASE_Msk));
#else #else
#error Unknown ARM architecture #error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */ #endif /* CONFIG_ARMV6_M */
@ -84,9 +85,9 @@ static ALWAYS_INLINE void _ExcSetup(void)
NVIC_SetPriority(BusFault_IRQn, _EXC_FAULT_PRIO); NVIC_SetPriority(BusFault_IRQn, _EXC_FAULT_PRIO);
NVIC_SetPriority(UsageFault_IRQn, _EXC_FAULT_PRIO); NVIC_SetPriority(UsageFault_IRQn, _EXC_FAULT_PRIO);
_ScbUsageFaultEnable(); /* Enable Usage, Mem, & Bus Faults */
_ScbBusFaultEnable(); SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk |
_ScbMemFaultEnable(); SCB_SHCSR_BUSFAULTENA_Msk;
#endif #endif
} }
@ -102,11 +103,12 @@ static ALWAYS_INLINE void _ClearFaults(void)
#if defined(CONFIG_ARMV6_M) #if defined(CONFIG_ARMV6_M)
#elif defined(CONFIG_ARMV7_M) #elif defined(CONFIG_ARMV7_M)
/* Reset all faults */ /* Reset all faults */
_ScbMemFaultAllFaultsReset(); SCB->CFSR = SCB_CFSR_USGFAULTSR_Msk |
_ScbBusFaultAllFaultsReset(); SCB_CFSR_MEMFAULTSR_Msk |
_ScbUsageFaultAllFaultsReset(); SCB_CFSR_BUSFAULTSR_Msk;
_ScbHardFaultAllFaultsReset(); /* Clear all Hard Faults - HFSR is write-one-to-clear */
SCB->HFSR = 0xffffffff;
#else #else
#error Unknown ARM architecture #error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */ #endif /* CONFIG_ARMV6_M */

View file

@ -1,89 +0,0 @@
/*
* Copyright (c) 2016 RnDity Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32F3X_CLOCK_H_
#define _STM32F3X_CLOCK_H_
/**
* @brief Driver for Reset & Clock Control of STM32F3x family processor.
*
* Based on reference manual:
* STM32F303xB.C.D.E advanced ARM ® -based 32-bit MCU
* STM32F334xx advanced ARM ® -based 32-bit MCU
* STM32F37xx advanced ARM ® -based 32-bit MCU
*
* Chapter 8: Reset and clock control (RCC)
*/
/**
* @brief Reset and Clock Control
*/
union __rcc_cr {
uint32_t val;
struct {
uint32_t hsion :1 __packed;
uint32_t hsirdy :1 __packed;
uint32_t rsvd__2 :1 __packed;
uint32_t hsitrim :5 __packed;
uint32_t hsical :8 __packed;
uint32_t hseon :1 __packed;
uint32_t hserdy :1 __packed;
uint32_t hsebyp :1 __packed;
uint32_t csson :1 __packed;
uint32_t rsvd__20_23 :4 __packed;
uint32_t pllon :1 __packed;
uint32_t pllrdy :1 __packed;
uint32_t rsvd__26_31 :6 __packed;
} bit;
};
union __rcc_cfgr {
uint32_t val;
struct {
uint32_t sw :2 __packed;
uint32_t sws :2 __packed;
uint32_t hpre :4 __packed;
uint32_t ppre1 :3 __packed;
uint32_t ppre2 :3 __packed;
uint32_t rsvd__14_15 :2 __packed;
uint32_t pllsrc :1 __packed;
uint32_t pllxtpre :1 __packed;
uint32_t pllmul :4 __packed;
uint32_t rsvd__22_23 :2 __packed;
uint32_t mco :3 __packed;
uint32_t rsvd__27 :1 __packed;
uint32_t mcopre :3 __packed;
uint32_t pllnodiv :1 __packed;
} bit;
};
union __rcc_cfgr2 {
uint32_t val;
struct {
uint32_t prediv :4 __packed;
uint32_t adc12pres : 5 __packed;
uint32_t rsvd__9_31 :23 __packed;
} bit;
};
struct stm32f3x_rcc {
union __rcc_cr cr;
union __rcc_cfgr cfgr;
uint32_t cir;
uint32_t apb2rstr;
uint32_t apb1rstr;
uint32_t ahbenr;
uint32_t apb2enr;
uint32_t apb1enr;
uint32_t bdcr;
uint32_t csr;
uint32_t ahbrstr;
union __rcc_cfgr2 cfgr2;
uint32_t cfgr3;
};
#endif /* _STM32F3X_CLOCK_H_ */

View file

@ -42,7 +42,8 @@ static int stm32f3_init(struct device *arg)
irq_unlock(key); irq_unlock(key);
/* Update CMSIS SystemCoreClock variable (HCLK) */ /* Update CMSIS SystemCoreClock variable (HCLK) */
SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; /* At reset, System core clock is set to 4MHz */
SystemCoreClock = 4000000;
return 0; return 0;
} }

View file

@ -52,6 +52,13 @@ enum stm32f3x_pin_config_mode {
#include <stm32f3xx_ll_usart.h> #include <stm32f3xx_ll_usart.h>
#endif #endif
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
#include <stm32f3xx_ll_utils.h>
#include <stm32f3xx_ll_bus.h>
#include <stm32f3xx_ll_rcc.h>
#include <stm32f3xx_ll_system.h>
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
#endif /* !_ASMLANGUAGE */ #endif /* !_ASMLANGUAGE */
#endif /* _STM32F3_SOC_H_ */ #endif /* _STM32F3_SOC_H_ */

View file

@ -29,25 +29,3 @@ int stm32_get_pin_config(int pin, int func)
/* encode and return the 'real' alternate function number */ /* encode and return the 'real' alternate function number */
return STM32_PINFUNC(func, STM32F3X_PIN_CONFIG_AF); return STM32_PINFUNC(func, STM32F3X_PIN_CONFIG_AF);
} }
clock_control_subsys_t stm32_get_port_clock(int port)
{
const clock_control_subsys_t ports_to_clock[STM32_PORTS_MAX] = {
UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPA),
UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPB),
UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPC),
UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPD),
#ifdef CONFIG_SOC_STM32F334X8
UINT_TO_POINTER(0),
#else
UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPE),
#endif
UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_IOPF),
};
if (port > STM32_PORTF) {
return NULL;
}
return ports_to_clock[port];
}

View file

@ -117,7 +117,7 @@ int stm32_gpio_configure(uint32_t *base_addr, int pin, int conf, int altf)
if (crpin > 7) { if (crpin > 7) {
afr = &gpio->afrh; afr = &gpio->afrh;
crpin -= 7; crpin -= 8;
} }
/* clear AF bits */ /* clear AF bits */
@ -188,7 +188,12 @@ int stm32_gpio_enable_int(int port, int pin)
struct device *clk = struct device *clk =
device_get_binding(STM32_CLOCK_CONTROL_NAME); device_get_binding(STM32_CLOCK_CONTROL_NAME);
clock_control_on(clk, UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_SYSCFG)); struct stm32_pclken pclken = {
.bus = STM32_CLOCK_BUS_APB2,
.enr = LL_APB2_GRP1_PERIPH_SYSCFG
};
clock_control_on(clk, (clock_control_subsys_t *) &pclken);
int shift = 0; int shift = 0;

View file

@ -8,7 +8,6 @@
#define _STM32F3X_SOC_REGISTERS_H_ #define _STM32F3X_SOC_REGISTERS_H_
/* include register mapping headers */ /* include register mapping headers */
#include "rcc_registers.h"
#include "flash_registers.h" #include "flash_registers.h"
#include "gpio_registers.h" #include "gpio_registers.h"

View file

@ -1,176 +0,0 @@
/*
* Copyright (c) 2016 Open-RnD Sp. z o.o.
* Copyright (c) 2016 BayLibre, SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32L4X_CLOCK_H_
#define _STM32L4X_CLOCK_H_
/**
* @brief Driver for Reset & Clock Control of STM32L4x6 family processor.
*/
enum {
STM32L4X_RCC_CFG_PLL_SRC_MSI = 0x1,
STM32L4X_RCC_CFG_PLL_SRC_HSI = 0x2,
STM32L4X_RCC_CFG_PLL_SRC_HSE = 0x3,
};
enum {
STM32L4X_RCC_CFG_PLL_Q_R_0 = 0x1,
STM32L4X_RCC_CFG_PLL_Q_R_2 = 0x2,
};
enum {
STM32L4X_RCC_CFG_SYSCLK_SRC_MSI = 0x0,
STM32L4X_RCC_CFG_SYSCLK_SRC_HSI = 0x1,
STM32L4X_RCC_CFG_SYSCLK_SRC_HSE = 0x2,
STM32L4X_RCC_CFG_SYSCLK_SRC_PLL = 0x3,
};
enum {
STM32L4X_RCC_CFG_HCLK_DIV_0 = 0x0,
STM32L4X_RCC_CFG_HCLK_DIV_2 = 0x4,
STM32L4X_RCC_CFG_HCLK_DIV_4 = 0x5,
STM32L4X_RCC_CFG_HCLK_DIV_8 = 0x6,
STM32L4X_RCC_CFG_HCLK_DIV_16 = 0x7,
};
enum {
STM32L4X_RCC_CFG_SYSCLK_DIV_0 = 0x0,
STM32L4X_RCC_CFG_SYSCLK_DIV_2 = 0x8,
STM32L4X_RCC_CFG_SYSCLK_DIV_4 = 0x9,
STM32L4X_RCC_CFG_SYSCLK_DIV_8 = 0xa,
STM32L4X_RCC_CFG_SYSCLK_DIV_16 = 0xb,
STM32L4X_RCC_CFG_SYSCLK_DIV_64 = 0xc,
STM32L4X_RCC_CFG_SYSCLK_DIV_128 = 0xd,
STM32L4X_RCC_CFG_SYSCLK_DIV_256 = 0xe,
STM32L4X_RCC_CFG_SYSCLK_DIV_512 = 0xf,
};
enum {
STM32L4X_RCC_CFG_MCO_DIV_0 = 0x0,
STM32L4X_RCC_CFG_MCO_DIV_2 = 0x1,
STM32L4X_RCC_CFG_MCO_DIV_4 = 0x2,
STM32L4X_RCC_CFG_MCO_DIV_8 = 0x3,
STM32L4X_RCC_CFG_MCO_DIV_16 = 0x4,
};
/**
* @brief Reset and Clock Control
*/
union __rcc_cr {
uint32_t val;
struct {
uint32_t msion :1 __packed;
uint32_t msirdy :1 __packed;
uint32_t msipllen :1 __packed;
uint32_t msirgsel :1 __packed;
uint32_t msirange :4 __packed;
uint32_t hsion :1 __packed;
uint32_t hsikeron :1 __packed;
uint32_t hsirdy :1 __packed;
uint32_t hsiasfs :1 __packed;
uint32_t rsvd__12_15 :4 __packed;
uint32_t hseon :1 __packed;
uint32_t hserdy :1 __packed;
uint32_t hsebyp :1 __packed;
uint32_t csson :1 __packed;
uint32_t rsvd__20_23 :4 __packed;
uint32_t pllon :1 __packed;
uint32_t pllrdy :1 __packed;
uint32_t pllsai1on :1 __packed;
uint32_t pllsai1rdy :1 __packed;
/*
* SAI2 not present on L4x2, L431xx, STM32L433xx,
* and STM32L443xx.
*/
uint32_t pllsai2on :1 __packed;
uint32_t pllsai2rdy :1 __packed;
uint32_t rsvd__30_31 :2 __packed;
} bit;
};
union __rcc_cfgr {
uint32_t val;
struct {
uint32_t sw :2 __packed;
uint32_t sws :2 __packed;
uint32_t hpre :4 __packed;
uint32_t ppre1 :3 __packed;
uint32_t ppre2 :3 __packed;
uint32_t stopwuck :1 __packed;
uint32_t rsvd__16_23 :8 __packed;
uint32_t mcosel :3 __packed; /* 2 bits long on L4x{1,5,6} */
uint32_t mcopre :3 __packed;
uint32_t rsvd__31 :1 __packed;
} bit;
};
union __rcc_pllcfgr {
uint32_t val;
struct {
uint32_t pllsrc :2 __packed;
uint32_t rsvd__2_3 :2 __packed;
uint32_t pllm :3 __packed;
uint32_t rsvd__7 :1 __packed;
uint32_t plln :7 __packed;
uint32_t rsvd__15 :1 __packed;
uint32_t pllpen :1 __packed;
uint32_t pllp :1 __packed;
uint32_t rsvd__18_19 :2 __packed;
uint32_t pllqen :1 __packed;
uint32_t pllq :2 __packed;
uint32_t rsvd__23 :1 __packed;
uint32_t pllren :1 __packed;
uint32_t pllr :2 __packed;
uint32_t pllpdiv :5 __packed; /* Not present on L4x{1,5,6} */
} bit;
};
struct stm32l4x_rcc {
union __rcc_cr cr;
uint32_t icscr;
union __rcc_cfgr cfgr;
union __rcc_pllcfgr pllcfgr;
uint32_t pllsai1cfgr;
uint32_t pllsai2cfgr;
uint32_t cier;
uint32_t cifr;
uint32_t cicr;
uint32_t rsvd_0;
uint32_t ahb1rstr;
uint32_t ahb2rstr;
uint32_t ahb3rstr;
uint32_t rsvd_1;
uint32_t apb1rstr1;
uint32_t apb1rstr2;
uint32_t apb2rstr;
uint32_t rsvd_2;
uint32_t ahb1enr;
uint32_t ahb2enr;
uint32_t ahb3enr;
uint32_t rsvd_3;
uint32_t apb1enr1;
uint32_t apb1enr2;
uint32_t apb2enr;
uint32_t rsvd_4;
uint32_t ahb1smenr;
uint32_t ahb2smenr;
uint32_t ahb3smenr;
uint32_t rsvd_5;
uint32_t apb1smenr1;
uint32_t apb1smenr2;
uint32_t apb2smenr;
uint32_t rsvd_6;
uint32_t ccipr;
uint32_t rsvd_7;
uint32_t bdcr;
uint32_t csr;
};
#endif /* _STM32L4X_CLOCK_H_ */

View file

@ -43,7 +43,8 @@ static int stm32l4_init(struct device *arg)
irq_unlock(key); irq_unlock(key);
/* Update CMSIS SystemCoreClock variable (HCLK) */ /* Update CMSIS SystemCoreClock variable (HCLK) */
SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; /* At reset, System core clock is set to 4MHz */
SystemCoreClock = 4000000;
return 0; return 0;
} }

View file

@ -35,6 +35,13 @@
#include <stm32l4xx_ll_usart.h> #include <stm32l4xx_ll_usart.h>
#endif #endif
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
#include <stm32l4xx_ll_utils.h>
#include <stm32l4xx_ll_bus.h>
#include <stm32l4xx_ll_rcc.h>
#include <stm32l4xx_ll_system.h>
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
#endif /* !_ASMLANGUAGE */ #endif /* !_ASMLANGUAGE */
#endif /* _STM32L4X_SOC_H_ */ #endif /* _STM32L4X_SOC_H_ */

View file

@ -214,8 +214,12 @@ int stm32_gpio_enable_int(int port, int pin)
struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME);
uint32_t *reg; uint32_t *reg;
clock_control_on(clk, (clock_control_subsys_t *) /* Enable SYSCFG clock */
STM32L4X_CLOCK_SUBSYS_SYSCFG); struct stm32_pclken pclken = {
.bus = STM32_CLOCK_BUS_APB2,
.enr = LL_APB2_GRP1_PERIPH_SYSCFG
};
clock_control_on(clk, (clock_control_subsys_t *) &pclken);
if (pin <= STM32L4X_PIN3) { if (pin <= STM32L4X_PIN3) {
reg = &syscfg->exticr1; reg = &syscfg->exticr1;

View file

@ -99,23 +99,3 @@ int stm32_get_pin_config(int pin, int func)
} }
return -EINVAL; return -EINVAL;
} }
clock_control_subsys_t stm32_get_port_clock(int port)
{
const clock_control_subsys_t ports_to_clock[STM32_PORTS_MAX] = {
UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_GPIOA),
UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_GPIOB),
UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_GPIOC),
UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_GPIOD),
UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_GPIOE),
UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_GPIOF),
UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_GPIOG),
UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_GPIOH),
};
if (port > STM32_PORTH) {
return NULL;
}
return ports_to_clock[port];
}

View file

@ -9,7 +9,6 @@
#define _STM32L4X_SOC_REGISTERS_H_ #define _STM32L4X_SOC_REGISTERS_H_
/* include register mapping headers */ /* include register mapping headers */
#include "rcc_registers.h"
#include "flash_registers.h" #include "flash_registers.h"
#include "syscfg_registers.h" #include "syscfg_registers.h"

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 KiB

View file

@ -0,0 +1,273 @@
.. _hexiwear_k64:
Hexiwear
########
Overview
********
Hexiwear is powered by a Kinetis K64 microcontroller based on the ARM Cortex-M4
core. Another Kinetis wireless MCU, the KW40Z, provides Bluetooth Low Energy
connectivity. Hexiwear also integrates a wide variety of sensors, as well as a
user interface consisting of a 1.1” 96px x 96px full color OLED display and six
capacitive buttons with haptic feedback.
- Eye-catching Smart Watch form factor with powerful, low power Kinetis K6x MCU
and 6 on-board sensors.
- Designed for wearable applications with the onboard rechargeable battery,
OLED screen and onboard sensors such as optical heart rate, accelerometer,
magnetometer and gyroscope.
- Designed for IoT end node applications with the onboard sensors such as
temperature, pressure, humidity and ambient light.
- Flexibility to let you add the sensors of your choice nearly 200 additional
sensors through click boards.
.. image:: hexiwear_k64.jpg
:width: 442px
:align: center
:alt: Hexiwear
Hardware
********
- Main MCU: NXP Kinetis K64x (ARM Cortex-M4, 120 MHz, 1M Flash, 256K SRAM)
- Wireless MCU: NXP Kinetis KW4x (ARM Cortex-M0+, Bluetooth Low Energy &
802.15.4 radio)
- 6-axis combo Accelerometer and Magnetometer NXP FXOS8700
- 3-Axis Gyroscope: NXP FXAS21002
- Absolute Pressure sensor NXP MPL3115
- Li-Ion/Li-Po Battery Charger NXP MC34671
- Optical heart rate sensor Maxim MAX30101
- Ambient Light sensor, Humidity and Temperature sensor
- 1.1” full color OLED display
- Haptic feedback engine
- 190 mAh 2C Li-Po battery
- Capacitive touch interface
- RGB LED
For more information about the K64F SoC and Hexiwear board:
- `K64F Website`_
- `K64F Datasheet`_
- `K64F Reference Manual`_
- `Hexiwear Website`_
- `Hexiwear Fact Sheet`_
- `Hexiwear Schematics`_
Supported Features
==================
The hexiwear_k64 board configuration supports the following hardware features:
+-----------+------------+-------------------------------------+
| Interface | Controller | Driver/Component |
+===========+============+=====================================+
| NVIC | on-chip | nested vector interrupt controller |
+-----------+------------+-------------------------------------+
| SYSTICK | on-chip | systick |
+-----------+------------+-------------------------------------+
| PINMUX | on-chip | pinmux |
+-----------+------------+-------------------------------------+
| GPIO | on-chip | gpio |
+-----------+------------+-------------------------------------+
| I2C | on-chip | i2c |
+-----------+------------+-------------------------------------+
| UART | on-chip | serial port-polling; |
| | | serial port-interrupt |
+-----------+------------+-------------------------------------+
| FLASH | on-chip | soc flash |
+-----------+------------+-------------------------------------+
| SENSOR | off-chip | fxos8700 polling; |
| | | fxos8700 trigger |
+-----------+------------+-------------------------------------+
The default configuration can be found in the defconfig file:
``boards/arm/hexiwear_k64/hexiwear_k64_defconfig``
Other hardware features are not currently supported by the port.
Connections and IOs
===================
The K64F SoC has five pairs of pinmux/gpio controllers.
+-------+-----------------+---------------------------+
| Name | Function | Usage |
+=======+=================+===========================+
| PTC8 | GPIO | Red LED |
+-------+-----------------+---------------------------+
| PTC9 | GPIO | Green LED |
+-------+-----------------+---------------------------+
| PTD0 | GPIO | Blue LED |
+-------+-----------------+---------------------------+
| PTD13 | GPIO | FXOS8700 INT2 |
+-------+-----------------+---------------------------+
| PTB16 | UART0_RX | UART Console |
+-------+-----------------+---------------------------+
| PTB17 | UART0_TX | UART Console |
+-------+-----------------+---------------------------+
| PTE24 | UART4_RX | UART BT HCI |
+-------+-----------------+---------------------------+
| PTE25 | UART4_TX | UART BT HCI |
+-------+-----------------+---------------------------+
| PTC10 | I2C1_SCL | I2C / FXOS8700 |
+-------+-----------------+---------------------------+
| PTC11 | I2C1_SDA | I2C / FXOS8700 |
+-------+-----------------+---------------------------+
System Clock
============
The K64F SoC is configured to use the 12 MHz external oscillator on the board
with the on-chip PLL to generate a 120 MHz system clock.
Serial Port
===========
The K64F SoC has six UARTs. One is configured for the console, another for BT
HCI, and the remaining are not used.
Programming and Debugging
*************************
Flashing
========
The Hexiwear docking station includes an `OpenSDA`_ serial and debug adaptor
built into the board. The adaptor provides:
- A USB connection to the host computer, which exposes a Mass Storage and an
USB Serial Port.
- A Serial Flash device, which implements the USB flash disk file storage.
- A physical UART connection which is relayed over interface USB Serial port.
.. note::
The OpenSDA is shared between the K64 and the KW40Z via switches, therefore
only one SoC can be flashed, debugged, or have an open console at a time.
Flashing an application to Hexiwear
-----------------------------------
#. Build the Zephyr kernel and application:
.. code-block:: console
$ cd $ZEPHYR_BASE
$ . zephyr-env.sh
$ cd $ZEPHYR_BASE/samples/hello_world/
$ make BOARD=hexiwear_k64
#. Make sure the docking station USB cable is unplugged.
#. Attach the Hexiwear board to the docking station.
#. Configure the docking station switches to route the desired SoC signals to
the OpenSDA circuit:
+--------+-------------+-------+-----+
| Switch | Signal | KW40Z | K64 |
+========+=============+=======+=====+
| 1 | MK64 SWDIO | OFF | ON |
+--------+-------------+-------+-----+
| 2 | MK64 RST | OFF | ON |
+--------+-------------+-------+-----+
| 3 | MKW40 RST | ON | OFF |
+--------+-------------+-------+-----+
| 4 | MKW40 SWDIO | ON | OFF |
+--------+-------------+-------+-----+
| 5 | OSDA | ON | ON |
+--------+-------------+-------+-----+
| 6 | LED1 | OFF | OFF |
+--------+-------------+-------+-----+
| 7 | LED2 | OFF | OFF |
+--------+-------------+-------+-----+
| 8 | LED3 | OFF | OFF |
+--------+-------------+-------+-----+
#. Attach the USB cable and make sure the power switch is ON. A USB Mass
Storage Device called DAPLINK will enumerate.
#. Copy the application binary ``zephyr.bin`` to the DAPLINK drive. The drive
will temporarily disappear, then reappear after several seconds.
#. Open a serial terminal (minicom, putty, etc.) with the following settings:
- Speed: 115200
- Data: 8 bits
- Parity: None
- Stop bits: 1
#. Reset the SoC. Each SoC has a reset button on docking station. You should
see the following message on the Serial Port:
.. code-block:: console
Hello World! arm
Using Bluetooth
***************
Configure the KW40Z as a Bluetooth controller
=============================================
The K64 can support Zephyr Bluetooth host applications when you configure the
KW40Z as a Bluetooth controller.
#. Download and install the `KW40Z Connectivity Software`_. This package
contains Bluetooth controller application for the KW40Z.
#. Flash the file ``tools/binaries/BLE_HCI_Modem.bin`` to the KW40Z.
Now you can build and run the sample Zephyr Bluetooth host applications on the
K64. You do not need to repeat this step each time you flash a new Bluetooth
host application to the K64.
Peripheral Heart Rate Sensor
============================
Navigate to the Zephyr sample application and build it for the Hexiwear K64.
.. code-block:: console
$ cd samples/bluetooth/peripheral_hr
$ make BOARD=hexiwear_k64
Flash the application to the Hexiwear K64. Make sure the OpenSDA switches on
the docking station are configured for the K64.
Reset the KW40Z and the K64 using the push buttons on the docking station.
Install the Kinetis BLE Toolbox on your smartphone:
- `Kinetis BLE Toolbox for iOS`_
- `Kinetis BLE Toolbox for Android`_
Open the app, tap the **Heart Rate** feature, and you should see a **Zephyr
Heartrate Sensor** device. Tap the **Zephyr Heartrate Sensor** device and you
will then see a plot of the heart rate data that updates once per second.
.. _Hexiwear Website:
http://www.nxp.com/hexiwear
.. _Hexiwear Fact Sheet:
http://www.nxp.com/assets/documents/data/en/fact-sheets/HEXIWEAR-FS.pdf
.. _Hexiwear Schematics:
http://cdn-docs.mikroe.com/images/c/c0/Sch_Hexiwear_MainBoard_v106c.pdf
.. _OpenSDA:
http://www.nxp.com/products/software-and-tools/hardware-development-tools/startertrak-development-boards/opensda-serial-and-debug-adapter:OPENSDA
.. _K64F Website:
http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/kinetis-cortex-m-mcus/k-series-performance-m4/k6x-ethernet/kinetis-k64-120-mhz-256kb-sram-microcontrollers-mcus-based-on-arm-cortex-m4-core:K64_120
.. _K64F Datasheet:
http://www.nxp.com/assets/documents/data/en/data-sheets/K64P144M120SF5.pdf
.. _K64F Reference Manual:
http://www.nxp.com/assets/documents/data/en/reference-manuals/K64P144M120SF5RM.pdf
.. _KW40Z Connectivity Software:
https://www.nxp.com/webapp/Download?colCode=KW40Z-CONNECTIVITY-SOFTWARE&appType=license&location=null&fpsp=1&WT_TYPE=Protocol%20Stacks&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=exe&WT_ASSET=Downloads&fileExt=.exe&Parent_nodeId=1432854896956716810497&Parent_pageType=product
.. _Kinetis BLE Toolbox for iOS:
https://itunes.apple.com/us/app/kinetis-ble-toolbox/id1049036961?mt=8
.. _Kinetis BLE Toolbox for Android:
https://play.google.com/store/apps/details?id=com.freescale.kinetisbletoolbox

View file

@ -40,14 +40,18 @@ CONFIG_GPIO_STM32_PORTA=y
CONFIG_GPIO_STM32_PORTB=y CONFIG_GPIO_STM32_PORTB=y
CONFIG_GPIO_STM32_PORTC=y CONFIG_GPIO_STM32_PORTC=y
# RCC configuration # Clock configuration
CONFIG_CLOCK_CONTROL=y CONFIG_CLOCK_CONTROL=y
CONFIG_CLOCK_CONTROL_STM32F3X=y CONFIG_CLOCK_CONTROL_STM32_CUBE=y
CONFIG_CLOCK_CONTROL_STM32F3X_DEVICE_INIT_PRIORITY=1 # SYSCLK selection
CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_PLL=y CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y
CONFIG_CLOCK_STM32F3X_PLL_SRC_HSE=y # HSE configuration
CONFIG_CLOCK_STM32F3X_PLL_PREDIV=0 CONFIG_CLOCK_STM32_HSE_CLOCK=8000000
CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER=9 # PLL configuration
CONFIG_CLOCK_STM32F3X_AHB_PRESCALER=0 CONFIG_CLOCK_STM32_PLL_SRC_HSE=y
CONFIG_CLOCK_STM32F3X_APB1_PRESCALER=2 # produce 72MHz clock at PLL output
CONFIG_CLOCK_STM32F3X_APB2_PRESCALER=0 CONFIG_CLOCK_STM32_PLL_PREDIV=1
CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9
CONFIG_CLOCK_STM32_AHB_PRESCALER=1
CONFIG_CLOCK_STM32_APB1_PRESCALER=2
CONFIG_CLOCK_STM32_APB2_PRESCALER=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 KiB

View file

@ -0,0 +1,239 @@
.. _nucleo_l476rg_board:
ST Nucleo L476RG
################
Overview
********
The Nucleo L476RG board features an ARM Cortex-M4 based STM32L476RG MCU
with a wide range of connectivity support and configurations. Here are
some highlights of the Nucleo L476RG board:
- STM32 microcontroller in QFP64 package
- Two types of extension resources:
- Arduino Uno V3 connectivity
- ST morpho extension pin headers for full access to all STM32 I/Os
- On-board ST-LINK/V2-1 debugger/programmer with SWD connector
- Flexible board power supply:
- USB VBUS or external source(3.3V, 5V, 7 - 12V)
- Power management access point
- Three LEDs: USB communication (LD1), user LED (LD2), power LED (LD3)
- Two push-buttons: USER and RESET
.. image:: img/nucleo64_ulp_logo_1024.jpg
:width: 250px
:align: center
:height: 250px
:alt: Nucleo L476RG
More information about the board can be found at the `Nucleo L476RG website`_.
Hardware
********
The STM32L476RG SoC provides the following hardware IPs:
- Ultra-low-power with FlexPowerControl (down to 130 nA Standby mode and 100 μA/MHz run mode)
- Core: ARM® 32-bit Cortex®-M4 CPU with FPU, frequency up to 80 MHz, 100DMIPS/1.25DMIPS/MHz (Dhrystone 2.1)
- Clock Sources:
- 4 to 48 MHz crystal oscillator
- 32 kHz crystal oscillator for RTC (LSE)
- Internal 16 MHz factory-trimmed RC (±1%)
- Internal low-power 32 kHz RC (±5%)
- Internal multispeed 100 kHz to 48 MHz oscillator, auto-trimmed by LSE (better than ±0.25 % accuracy)
- 3 PLLs for system clock, USB, audio, ADC
- RTC with HW calendar, alarms and calibration
- LCD 8 × 40 or 4 × 44 with step-up converter
- Up to 24 capacitive sensing channels: support touchkey, linear and rotary touch sensors
- 16x timers:
- 2x 16-bit advanced motor-control
- 2x 32-bit and 5x 16-bit general purpose
- 2x 16-bit basic
- 2x low-power 16-bit timers (available in Stop mode)
- 2x watchdogs
- SysTick timer
- Up to 114 fast I/Os, most 5 V-tolerant, up to 14 I/Os with independent supply down to 1.08 V
- Memories
- Up to 1 MB Flash, 2 banks read-while-write, proprietary code readout protection
- Up to 128 KB of SRAM including 32 KB with hardware parity check
- External memory interface for static memories supporting SRAM, PSRAM, NOR and NAND memories
- Quad SPI memory interface
- 4x digital filters for sigma delta modulator
- Rich analog peripherals (independent supply)
- 3× 12-bit ADC 5 MSPS, up to 16-bit with hardware oversampling, 200 μA/MSPS
- 2x 12-bit DAC, low-power sample and hold
- 2x operational amplifiers with built-in PGA
- 2x ultra-low-power comparators
- 18x communication interfaces
- USB OTG 2.0 full-speed, LPM and BCD
- 2x SAIs (serial audio interface)
- 3x I2C FM+(1 Mbit/s), SMBus/PMBus
- 6x USARTs (ISO 7816, LIN, IrDA, modem)
- 3x SPIs (4x SPIs with the Quad SPI)
- CAN (2.0B Active) and SDMMC interface
- SWPMI single wire protocol master I/F
- 14-channel DMA controller
- True random number generator
- CRC calculation unit, 96-bit unique ID
- Development support: serial wire debug (SWD), JTAG, Embedded Trace Macrocell™
More information about STM32L476RG can be found here:
- `STM32L476RG on www.st.com`_
- `STM32L476 reference manual`_
Supported Features
==================
The Zephyr nucleo_l476rg board configuration supports the following hardware features:
+-----------+------------+-------------------------------------+
| Interface | Controller | Driver/Component |
+===========+============+=====================================+
| NVIC | on-chip | nested vector interrupt controller |
+-----------+------------+-------------------------------------+
| UART | on-chip | serial port-polling; |
| | | serial port-interrupt |
+-----------+------------+-------------------------------------+
| PINMUX | on-chip | pinmux |
+-----------+------------+-------------------------------------+
| GPIO | on-chip | gpio |
+-----------+------------+-------------------------------------+
| I2C | on-chip | i2c |
+-----------+------------+-------------------------------------+
| PWM | on-chip | pwm |
+-----------+------------+-------------------------------------+
Other hardware features are not yet supported on this Zephyr port.
The default configuration can be found in the defconfig file:
``boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig``
Connections and IOs
===================
Nucleo L476RG Board has 8 GPIO controllers. These controllers are responsible for pin muxing,
input/output, pull-up, etc.
Available pins:
---------------
.. image:: img/nucleo_l476rg_arduino.png
:width: 720px
:align: center
:height: 540px
:alt: Nucleo L476RG Arduino connectors
.. image:: img/nucleo_l476rg_morpho.png
:width: 720px
:align: center
:height: 540px
:alt: Nucleo L476RG Morpho connectors
For mode details please refer to `STM32 Nucleo-64 board User Manual`_.
Default Zephyr Peripheral Mapping:
----------------------------------
- UART_1_TX : PA9
- UART_1_RX : PA10
- UART_2_TX : PA2
- UART_2_RX : PA3
- UART_3_TX : PB10
- UART_3_RX : PB11
- I2C_0_SCL : PB6
- I2C_0_SDA : PB7
- PWM_2_CH1 : PA0
- USER_PB : PC13
- LD2 : PA5
System Clock
------------
Nucleo L476RG System Clock could be driven by internal or external oscillator,
as well as main PLL clock. By default System clock is driven by PLL clock at 80MHz,
driven by 16MHz high speed internal oscillator.
Serial Port
-----------
Nucleo L476RG board has 6 U(S)ARTs. The Zephyr console output is assigned to UART2.
Default settings are 115200 8N1.
Programming and Debugging
*************************
Flashing
========
Nucleo L476RG board includes an ST-LINK/V2-1 embedded debug tool interface.
This interface is not supported by the openocd version 0.9 included by the Zephyr SDK v0.9.
Until we update the Zephyr SDK, use openocd v0.10.0 from the openocd-stm32 project on GitHub
to get the minimum set of scripts needed to flash and debug STM32 development boards.
.. code-block:: console
$ git clone https://github.com/erwango/openocd-stm32.git
Then follow instructions in README.md
Flashing an application to Nucleo L476RG
----------------------------------------
The sample application :ref:'hello_world` is being used in this tutorial:
To build the Zephyr kernel and application, enter:
.. code-block:: console
$ cd <zephyr_root_path>
$ source zephyr-env.sh
$ cd $ZEPHYR_BASE/samples/hello_world/
$ make BOARD=nucleo_l476rg
Connect the Nucleo L476RG to your host computer using the USB port.
Then, enter the following command:
.. code-block:: console
$ cd <openocd-stm32_path>
$ stm32_flsh l4 $ZEPHYR_BASE/samples/hello_world/outdir/nucleo_l476rg/zephyr.bin
Run a serial host program to connect with your Nucleo board.
.. code-block:: console
$ minicom -D /dev/ttyACM0
You should see the following message:
.. code-block:: console
$ Hello World! arm
Debugging
=========
Access gdb with the following make command:
.. code-block:: console
$ cd <openocd-stm32_path>
$ stm32_dbg l4 $ZEPHYR_BASE/samples/hello_world/outdir/nucleo_l476rg/zephyr.elf
.. _Nucleo L476RG website:
http://www.st.com/en/evaluation-tools/nucleo-l476rg.html
.. _STM32 Nucleo-64 board User Manual:
http://www.st.com/resource/en/user_manual/dm00105823.pdf
.. _STM32L476RG on www.st.com:
http://www.st.com/en/microcontrollers/stm32l476rg.html
.. _STM32L476 reference manual:
http://www.st.com/resource/en/reference_manual/DM00083560.pdf

View file

@ -31,19 +31,20 @@ CONFIG_GPIO_STM32_PORTH=y
# clock configuration # clock configuration
CONFIG_CLOCK_CONTROL=y CONFIG_CLOCK_CONTROL=y
CONFIG_CLOCK_CONTROL_STM32L4X=y CONFIG_CLOCK_CONTROL_STM32_CUBE=y
CONFIG_CLOCK_STM32L4X_SYSCLK_SRC_PLL=y # SYSCLK selection
# use 16MHz oscillator CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y
CONFIG_CLOCK_STM32F10X_PLL_SRC_HSI=y # PLL configuration
CONFIG_CLOCK_STM32_PLL_SRC_HSI
# produce 80MHz clock at PLL output # produce 80MHz clock at PLL output
CONFIG_CLOCK_STM32L4X_PLL_DIVISOR=1 CONFIG_CLOCK_STM32_PLL_M_DIVISOR=1
CONFIG_CLOCK_STM32L4X_PLL_MULTIPLIER=20 CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=20
CONFIG_CLOCK_STM32L4X_PLL_P_DIVISOR=7 CONFIG_CLOCK_STM32_PLL_P_DIVISOR=7
CONFIG_CLOCK_STM32L4X_PLL_Q_DIVISOR=2 CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2
CONFIG_CLOCK_STM32L4X_PLL_R_DIVISOR=4 CONFIG_CLOCK_STM32_PLL_R_DIVISOR=4
CONFIG_CLOCK_STM32L4X_AHB_PRESCALER=0 CONFIG_CLOCK_STM32_AHB_PRESCALER=1
CONFIG_CLOCK_STM32L4X_APB1_PRESCALER=0 CONFIG_CLOCK_STM32_APB1_PRESCALER=1
CONFIG_CLOCK_STM32L4X_APB2_PRESCALER=0 CONFIG_CLOCK_STM32_APB2_PRESCALER=1
# console # console
CONFIG_CONSOLE=y CONFIG_CONSOLE=y

View file

@ -49,14 +49,18 @@ CONFIG_GPIO_STM32_PORTC=y
CONFIG_GPIO_STM32_PORTD=y CONFIG_GPIO_STM32_PORTD=y
CONFIG_GPIO_STM32_PORTE=y CONFIG_GPIO_STM32_PORTE=y
# RCC configuration # Clock configuration
CONFIG_CLOCK_CONTROL=y CONFIG_CLOCK_CONTROL=y
CONFIG_CLOCK_CONTROL_STM32F3X=y CONFIG_CLOCK_CONTROL_STM32_CUBE=y
CONFIG_CLOCK_CONTROL_STM32F3X_DEVICE_INIT_PRIORITY=1 # SYSCLK selection
CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_PLL=y CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y
CONFIG_CLOCK_STM32F3X_PLL_SRC_HSE=y # HSE configuration
CONFIG_CLOCK_STM32F3X_PLL_PREDIV=0 CONFIG_CLOCK_STM32_HSE_CLOCK=8000000
CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER=9 # PLL configuration
CONFIG_CLOCK_STM32F3X_AHB_PRESCALER=0 CONFIG_CLOCK_STM32_PLL_SRC_HSE=y
CONFIG_CLOCK_STM32F3X_APB1_PRESCALER=2 # produce 72MHz clock at PLL output
CONFIG_CLOCK_STM32F3X_APB2_PRESCALER=2 CONFIG_CLOCK_STM32_PLL_PREDIV=1
CONFIG_CLOCK_STM32_PLL_MULTIPLIER=9
CONFIG_CLOCK_STM32_AHB_PRESCALER=1
CONFIG_CLOCK_STM32_APB1_PRESCALER=2
CONFIG_CLOCK_STM32_APB2_PRESCALER=2

View file

@ -44,16 +44,14 @@ source "drivers/clock_control/Kconfig.nrf5"
source "drivers/clock_control/Kconfig.quark_se" source "drivers/clock_control/Kconfig.quark_se"
source "drivers/clock_control/Kconfig.stm32"
source "drivers/clock_control/Kconfig.stm32f10x" source "drivers/clock_control/Kconfig.stm32f10x"
source "drivers/clock_control/Kconfig.stm32f107xx" source "drivers/clock_control/Kconfig.stm32f107xx"
source "drivers/clock_control/Kconfig.stm32f3x"
source "drivers/clock_control/Kconfig.stm32f4x" source "drivers/clock_control/Kconfig.stm32f4x"
source "drivers/clock_control/Kconfig.stm32l4x"
source "drivers/clock_control/Kconfig.beetle" source "drivers/clock_control/Kconfig.beetle"
endif # CLOCK_CONTROL endif # CLOCK_CONTROL

View file

@ -0,0 +1,186 @@
# Kconfig - STM32 MCU clock control driver config
#
# Copyright (c) 2017 Linaro
#
# SPDX-License-Identifier: Apache-2.0
#
if SOC_FAMILY_STM32
menuconfig CLOCK_CONTROL_STM32_CUBE
bool
prompt "STM32 Reset & Clock Control"
depends on CLOCK_CONTROL
default n if SOC_SERIES_STM32
help
Enable driver for Reset & Clock Control subsystem found
in STM32 family of MCUs
config CLOCK_CONTROL_STM32_DEVICE_INIT_PRIORITY
int "Clock Control Device Priority"
default 1
depends on CLOCK_CONTROL_STM32_CUBE
help
This option controls the priority of clock control
device initialization. Higher priority ensures that the device
is initialized earlier in the startup cycle. If unsure, leave
at default value 1
choice
prompt "STM32 System Clock Source"
depends on CLOCK_CONTROL_STM32_CUBE
default CLOCK_STM32_SYSCLK_SRC_PLL
config CLOCK_STM32_SYSCLK_SRC_HSE
bool "HSE"
help
Use HSE as source of SYSCLK
config CLOCK_STM32_SYSCLK_SRC_HSI
bool "HSI"
help
Use HSI as source of SYSCLK
config CLOCK_STM32_SYSCLK_SRC_PLL
bool "PLL"
help
Use PLL as source of SYSCLK
endchoice
config CLOCK_STM32_HSE_BYPASS
bool "HSE bypass"
depends on CLOCK_CONTROL_STM32_CUBE && (CLOCK_STM32_SYSCLK_SRC_HSE || CLOCK_STM32_PLL_SRC_HSE)
help
Enable this option to bypass external high-speed clock (HSE).
config CLOCK_STM32_HSE_CLOCK
int "HSE clock value"
depends on CLOCK_CONTROL_STM32_CUBE && (CLOCK_STM32_SYSCLK_SRC_HSE || CLOCK_STM32_PLL_SRC_HSE)
help
Value of external high-speed clock (HSE).
choice
prompt "STM32 PLL Clock Source"
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
default CLOCK_STM32_PLL_SRC_HSI
config CLOCK_STM32_PLL_SRC_MSI
bool "MSI"
help
Use MSI as source of PLL
config CLOCK_STM32_PLL_SRC_HSI
bool "HSI"
help
Use HSI as source of PLL
config CLOCK_STM32_PLL_SRC_HSE
bool "HSE"
help
Use HSE as source of PLL
endchoice
if SOC_SERIES_STM32F3X
config CLOCK_STM32_PLL_PREDIV
int "PREDIV Prescaler"
depends on CLOCK_CONTROL_STM32_CUBE
default 1
range 1 16
help
PREDIV is PLLSCR clock signal prescaler, allowed values: 1 - 16.
config CLOCK_STM32_PLL_PREDIV1
int "PREDIV1 Prescaler"
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_PLL_SRC_HSE && (SOC_STM32F302XE || SOC_STM32F303XE || SOC_STM32F398XX)
default 1
range 1 16
help
PREDIV is PLLSCR clock signal prescaler, present on STM32F302xE, STM32F303xE and STM32F39xx SoCs.
Allowed values: 1 - 16.
config CLOCK_STM32_PLL_MULTIPLIER
int "PLL multiplier"
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
default 9
range 2 16
help
PLL multiplier, allowed values: 2-16. PLL output must not exceed 72MHz.
endif # SOC_SERIES_STM32F3X
if SOC_SERIES_STM32L4X
config CLOCK_STM32_PLL_M_DIVISOR
int "PLL divisor"
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
default 1
range 1 8
help
PLL divisor, allowed values: 1-8. With this ensure that the PLL
VCO input frequency ranges from 4 to 16MHz.
config CLOCK_STM32_PLL_N_MULTIPLIER
int "PLL multiplier"
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
default 20
range 8 86
help
PLL multiplier, allowed values: 2-16. PLL output must not
exceed 344MHz.
config CLOCK_STM32_PLL_P_DIVISOR
int "PLL P Divisor"
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
default 7
range 0 17
help
PLL P Output divisor, allowed values: 0, 7, 17.
config CLOCK_STM32_PLL_Q_DIVISOR
int "PLL Q Divisor"
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
default 2
range 0 8
help
PLL Q Output divisor, allowed values: 0, 2, 4, 6, 8.
config CLOCK_STM32_PLL_R_DIVISOR
int "PLL R Divisor"
depends on CLOCK_CONTROL_STM32_CUBE && CLOCK_STM32_SYSCLK_SRC_PLL
default 4
range 0 8
help
PLL R Output divisor, allowed values: 0, 2, 4, 6, 8.
endif # SOC_SERIES_STM32L4X
config CLOCK_STM32_AHB_PRESCALER
int "AHB prescaler"
depends on CLOCK_CONTROL_STM32_CUBE
default 0
range 0 512
help
AHB prescaler, allowed values: 1, 2, 4, 8, 16, 64, 128,
256, 512.
config CLOCK_STM32_APB1_PRESCALER
int "APB1 prescaler"
depends on CLOCK_CONTROL_STM32_CUBE
default 1
range 1 16
help
APB1 Low speed clock (PCLK1) prescaler, allowed values:
1, 2, 4, 8, 16
config CLOCK_STM32_APB2_PRESCALER
int "APB2 prescaler"
depends on CLOCK_CONTROL_STM32_CUBE
default 1
range 1 16
help
APB2 High speed clock (PCLK2) prescaler, allowed values:
1, 2, 4, 8, 16
endif # SOC_FAMILY_STM32

View file

@ -1,115 +0,0 @@
# Kconfig - STM32F3 MCU clock control driver config
#
# Copyright (c) 2016 RnDity Sp. z o.o.
#
# SPDX-License-Identifier: Apache-2.0
#
if SOC_SERIES_STM32F3X
menuconfig CLOCK_CONTROL_STM32F3X
bool
prompt "STM32F3x Reset & Clock Control"
depends on CLOCK_CONTROL && SOC_SERIES_STM32F3X
default y if SOC_SERIES_STM32F3X
help
Enable driver for Reset & Clock Control subsystem found
in STM32F3 family of MCUs
config CLOCK_CONTROL_STM32F3X_DEVICE_INIT_PRIORITY
int "Clock Control Device Priority"
default 1
depends on CLOCK_CONTROL_STM32F3X
help
This option controls the priority of clock control
device initialization. Higher priority ensures that the device
is initialized earlier in the startup cycle. If unsure, leave
at default value 1
choice
prompt "STM32F3x System Clock Source"
depends on CLOCK_CONTROL_STM32F3X
config CLOCK_STM32F3X_SYSCLK_SRC_HSI
bool "HSI"
help
Use HSI as source of SYSCLK
config CLOCK_STM32F3X_SYSCLK_SRC_HSE
bool "HSE"
help
Use HSE as source of SYSCLK
config CLOCK_STM32F3X_SYSCLK_SRC_PLL
bool "PLL"
help
Use PLL as source of SYSCLK
endchoice
choice
prompt "STM32F3x PLL Clock Source"
depends on CLOCK_CONTROL_STM32F3X && CLOCK_STM32F3X_SYSCLK_SRC_PLL
config CLOCK_STM32F3X_PLL_SRC_HSI
bool "HSI"
help
Use HSI/2 as source of PLL
config CLOCK_STM32F3X_PLL_SRC_HSE
bool "HSE"
help
Use HSE as source of PLL
endchoice
config CLOCK_STM32F3X_HSE_BYPASS
bool "HSE bypass"
depends on CLOCK_CONTROL_STM32F3X && (CLOCK_STM32F3X_PLL_SRC_HSE || CLOCK_STM32F3X_SYSCLK_SRC_HSE)
help
Enable this option to bypass external high-speed clock (HSE).
config CLOCK_STM32F3X_PLL_PREDIV
int "PREDIV1 Prescler"
depends on CLOCK_CONTROL_STM32F3X && CLOCK_STM32F3X_PLL_SRC_HSE
default 0
range 0 16
help
PREDIV is PLLSCR clock signal prescaler, allowed values: 0 - 16.
config CLOCK_STM32F3X_PLL_MULTIPLIER
int "PLL multiplier"
depends on CLOCK_CONTROL_STM32F3X && CLOCK_STM32F3X_SYSCLK_SRC_PLL
default 9
range 2 16
help
PLL multiplier, allowed values: 2-16. PLL output must not exceed 72MHz.
config CLOCK_STM32F3X_AHB_PRESCALER
int "AHB prescaler"
depends on CLOCK_CONTROL_STM32F3X
default 0
range 0 512
help
AHB prescaler, allowed values: 0, 2, 4, 8, 16, 64, 128,
256, 512.
config CLOCK_STM32F3X_APB1_PRESCALER
int "APB1 prescaler"
depends on CLOCK_CONTROL_STM32F3X
default 0
range 0 16
help
APB1 Low speed clock (PCLK1) prescaler, allowed values:
0, 2, 4, 8, 16. The APB1 clock must not exceed 36MHz.
config CLOCK_STM32F3X_APB2_PRESCALER
int "APB2 prescaler"
depends on CLOCK_CONTROL_STM32F3X
default 0
range 0 16
help
APB2 High speed clock (PCLK2) prescaler, allowed values:
0, 2, 4, 8, 16
endif

View file

@ -1,140 +0,0 @@
# Kconfig - STM32L4 MCU clock control driver config
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 BayLibre, SAS
#
# SPDX-License-Identifier: Apache-2.0
#
if SOC_SERIES_STM32L4X
menuconfig CLOCK_CONTROL_STM32L4X
bool
prompt "STM32L4x Reset & Clock Control"
depends on CLOCK_CONTROL && SOC_SERIES_STM32L4X
default y if SOC_SERIES_STM32L4X
help
Enable driver for Reset & Clock Control subsystem found
in STM32L4 family of MCUs
config CLOCK_CONTROL_STM32L4X_DEVICE_INIT_PRIORITY
int "Clock Control Device Priority"
default 1
depends on CLOCK_CONTROL_STM32L4X
help
This option controls the priority of clock control
device initialization. Higher priority ensures that the device
is initialized earlier in the startup cycle. If unsure, leave
at default value 1
choice
prompt "STM32L4X System Clock Source"
depends on CLOCK_CONTROL_STM32L4X
default CLOCK_STM32L4X_SYSCLK_SRC_PLL
config CLOCK_STM32L4X_SYSCLK_SRC_HSE
bool "HSE"
help
Use HSE as source of SYSCLK
config CLOCK_STM32L4X_SYSCLK_SRC_PLL
bool "PLL"
help
Use PLL as source of SYSCLK
endchoice
choice
prompt "STM32L4X PLL Clock Source"
depends on CLOCK_CONTROL_STM32L4X && CLOCK_STM32L4X_SYSCLK_SRC_PLL
default CLOCK_STM32L4X_PLL_SRC_HSI
config CLOCK_STM32L4X_PLL_SRC_MSI
bool "MSI"
help
Use MSI as source of PLL
config CLOCK_STM32L4X_PLL_SRC_HSI
bool "HSI"
help
Use HSI as source of PLL
endchoice
config CLOCK_STM32L4X_HSE_BYPASS
bool "HSE bypass"
depends on CLOCK_CONTROL_STM32L4X && CLOCK_STM32L4X_SYSCLK_SRC_HSE
help
Enable this option to bypass external high-speed clock (HSE).
config CLOCK_STM32L4X_PLL_DIVISOR
int "PLL divisor"
depends on CLOCK_CONTROL_STM32L4X && CLOCK_STM32L4X_SYSCLK_SRC_PLL
default 1
range 1 8
help
PLL divisor, allowed values: 1-8. With this ensure that the PLL
VCO input frequency ranges from 4 to 16MHz.
config CLOCK_STM32L4X_PLL_MULTIPLIER
int "PLL multiplier"
depends on CLOCK_CONTROL_STM32L4X && CLOCK_STM32L4X_SYSCLK_SRC_PLL
default 20
range 8 86
help
PLL multiplier, allowed values: 2-16. PLL output must not
exceed 344MHz.
config CLOCK_STM32L4X_PLL_P_DIVISOR
int "PLL P Divisor"
depends on CLOCK_CONTROL_STM32L4X
default 7
range 0 17
help
PLL P Output divisor, allowed values: 0, 7, 17.
config CLOCK_STM32L4X_PLL_Q_DIVISOR
int "PLL Q Divisor"
depends on CLOCK_CONTROL_STM32L4X
default 2
range 0 8
help
PLL Q Output divisor, allowed values: 0, 2, 4, 6, 8.
config CLOCK_STM32L4X_PLL_R_DIVISOR
int "PLL R Divisor"
depends on CLOCK_CONTROL_STM32L4X
default 4
range 0 8
help
PLL R Output divisor, allowed values: 0, 2, 4, 6, 8.
config CLOCK_STM32L4X_AHB_PRESCALER
int "AHB prescaler"
depends on CLOCK_CONTROL_STM32L4X
default 0
range 0 512
help
AHB prescaler, allowed values: 0, 2, 4, 8, 16, 64, 128,
256, 512.
config CLOCK_STM32L4X_APB1_PRESCALER
int "APB1 prescaler"
depends on CLOCK_CONTROL_STM32L4X
default 0
range 0 16
help
APB1 Low speed clock (PCLK1) prescaler, allowed values:
0, 2, 4, 8, 16
config CLOCK_STM32L4X_APB2_PRESCALER
int "APB2 prescaler"
depends on CLOCK_CONTROL_STM32L4X
default 0
range 0 16
help
APB2 High speed clock (PCLK2) prescaler, allowed values:
0, 2, 4, 8, 16
endif

View file

@ -1,8 +1,12 @@
obj-$(CONFIG_CLOCK_CONTROL_NRF5) += nrf5_power_clock.o obj-$(CONFIG_CLOCK_CONTROL_NRF5) += nrf5_power_clock.o
obj-$(CONFIG_CLOCK_CONTROL_QUARK_SE) += quark_se_clock_control.o obj-$(CONFIG_CLOCK_CONTROL_QUARK_SE) += quark_se_clock_control.o
ifeq ($(CONFIG_CLOCK_CONTROL_STM32_CUBE),y)
obj-y += stm32_ll_clock.o
obj-$(CONFIG_SOC_SERIES_STM32L4X) += stm32l4x_ll_clock.o
obj-$(CONFIG_SOC_SERIES_STM32F3X) += stm32f3x_ll_clock.o
else
obj-$(CONFIG_CLOCK_CONTROL_STM32F10X) += stm32f10x_clock.o obj-$(CONFIG_CLOCK_CONTROL_STM32F10X) += stm32f10x_clock.o
obj-$(CONFIG_CLOCK_CONTROL_STM32F10X_CONN_LINE) += stm32f107xx_clock.o obj-$(CONFIG_CLOCK_CONTROL_STM32F10X_CONN_LINE) += stm32f107xx_clock.o
obj-$(CONFIG_CLOCK_CONTROL_STM32F3X) += stm32f3x_clock.o
obj-$(CONFIG_CLOCK_CONTROL_STM32F4X) += stm32f4x_clock.o obj-$(CONFIG_CLOCK_CONTROL_STM32F4X) += stm32f4x_clock.o
obj-$(CONFIG_CLOCK_CONTROL_STM32L4X) += stm32l4x_clock.o endif
obj-$(CONFIG_CLOCK_CONTROL_BEETLE) += beetle_clock_control.o obj-$(CONFIG_CLOCK_CONTROL_BEETLE) += beetle_clock_control.o

View file

@ -0,0 +1,295 @@
/*
*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc.h>
#include <soc_registers.h>
#include <clock_control.h>
#include <misc/util.h>
#include <clock_control/stm32_clock_control.h>
#include "stm32_ll_clock.h"
/* Macros to fill up prescaler values */
#define _ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v
#define ahb_prescaler(v) _ahb_prescaler(v)
#define _apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v
#define apb1_prescaler(v) _apb1_prescaler(v)
#define _apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v
#define apb2_prescaler(v) _apb2_prescaler(v)
/**
* @brief fill in AHB/APB buses configuration structure
*/
static void config_bus_clk_init(LL_UTILS_ClkInitTypeDef *clk_init)
{
clk_init->AHBCLKDivider = ahb_prescaler(
CONFIG_CLOCK_STM32_AHB_PRESCALER);
clk_init->APB1CLKDivider = apb1_prescaler(
CONFIG_CLOCK_STM32_APB1_PRESCALER);
clk_init->APB2CLKDivider = apb2_prescaler(
CONFIG_CLOCK_STM32_APB2_PRESCALER);
}
static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler)
{
return clock / prescaler;
}
static inline int stm32_clock_control_on(struct device *dev,
clock_control_subsys_t sub_system)
{
struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
ARG_UNUSED(dev);
switch (pclken->bus) {
case STM32_CLOCK_BUS_AHB1:
LL_AHB1_GRP1_EnableClock(pclken->enr);
break;
#ifdef CONFIG_SOC_SERIES_STM32L4X
case STM32_CLOCK_BUS_AHB2:
LL_AHB2_GRP1_EnableClock(pclken->enr);
break;
#endif /* CONFIG_SOC_SERIES_STM32L4X */
case STM32_CLOCK_BUS_APB1:
LL_APB1_GRP1_EnableClock(pclken->enr);
break;
#ifdef CONFIG_SOC_SERIES_STM32L4X
case STM32_CLOCK_BUS_APB1_2:
LL_APB1_GRP2_EnableClock(pclken->enr);
break;
#endif /* CONFIG_SOC_SERIES_STM32L4X */
case STM32_CLOCK_BUS_APB2:
LL_APB2_GRP1_EnableClock(pclken->enr);
break;
}
return 0;
}
static inline int stm32_clock_control_off(struct device *dev,
clock_control_subsys_t sub_system)
{
struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
ARG_UNUSED(dev);
switch (pclken->bus) {
case STM32_CLOCK_BUS_AHB1:
LL_AHB1_GRP1_DisableClock(pclken->enr);
break;
#ifdef CONFIG_SOC_SERIES_STM32L4X
case STM32_CLOCK_BUS_AHB2:
LL_AHB2_GRP1_DisableClock(pclken->enr);
break;
#endif /* CONFIG_SOC_SERIES_STM32L4X */
case STM32_CLOCK_BUS_APB1:
LL_APB1_GRP1_DisableClock(pclken->enr);
break;
#ifdef CONFIG_SOC_SERIES_STM32L4X
case STM32_CLOCK_BUS_APB1_2:
LL_APB1_GRP2_DisableClock(pclken->enr);
break;
#endif
case STM32_CLOCK_BUS_APB2:
LL_APB2_GRP1_DisableClock(pclken->enr);
break;
}
return 0;
}
static int stm32_clock_control_get_subsys_rate(struct device *clock,
clock_control_subsys_t sub_system,
uint32_t *rate)
{
struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
/*
* Get AHB Clock (= SystemCoreClock = SYSCLK/prescaler)
* SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
* since it will be updated after clock configuration and hence
* more likely to contain actual clock speed
*/
uint32_t ahb_clock = SystemCoreClock;
uint32_t apb1_clock = get_bus_clock(ahb_clock,
CONFIG_CLOCK_STM32_APB1_PRESCALER);
uint32_t apb2_clock = get_bus_clock(ahb_clock,
CONFIG_CLOCK_STM32_APB2_PRESCALER);
ARG_UNUSED(clock);
switch (pclken->bus) {
case STM32_CLOCK_BUS_AHB1:
case STM32_CLOCK_BUS_AHB2:
*rate = ahb_clock;
break;
case STM32_CLOCK_BUS_APB1:
#ifdef CONFIG_SOC_SERIES_STM32L4X
case STM32_CLOCK_BUS_APB1_2:
#endif
*rate = apb1_clock;
break;
case STM32_CLOCK_BUS_APB2:
*rate = apb2_clock;
break;
}
return 0;
}
static struct clock_control_driver_api stm32_clock_control_api = {
.on = stm32_clock_control_on,
.off = stm32_clock_control_off,
.get_rate = stm32_clock_control_get_subsys_rate,
};
static int stm32_clock_control_init(struct device *dev)
{
LL_UTILS_ClkInitTypeDef s_ClkInitStruct;
ARG_UNUSED(dev);
/* configure clock for AHB/APB buses */
config_bus_clk_init((LL_UTILS_ClkInitTypeDef *)&s_ClkInitStruct);
#ifdef CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL
LL_UTILS_PLLInitTypeDef s_PLLInitStruct;
/* configure PLL input settings */
config_pll_init(&s_PLLInitStruct);
/* Disable PLL before configuration */
LL_RCC_PLL_Disable();
#ifdef CONFIG_CLOCK_STM32_PLL_SRC_MSI
/* Switch to PLL with MSI as clock source */
LL_PLL_ConfigSystemClock_MSI(&s_PLLInitStruct, &s_ClkInitStruct);
/* Disable other clocks */
LL_RCC_HSI_Disable();
LL_RCC_HSE_Disable();
#elif CONFIG_CLOCK_STM32_PLL_SRC_HSI
/* Switch to PLL with HSI as clock source */
LL_PLL_ConfigSystemClock_HSI(&s_PLLInitStruct, &s_ClkInitStruct);
/* Disable other clocks */
LL_RCC_HSE_Disable();
LL_RCC_MSI_Disable();
#elif CONFIG_CLOCK_STM32_PLL_SRC_HSE
int hse_bypass = LL_UTILS_HSEBYPASS_OFF;
#ifdef CONFIG_CLOCK_STM32_HSE_BYPASS
hse_bypass = LL_UTILS_HSEBYPASS_ON;
#endif /* CONFIG_CLOCK_STM32_HSE_BYPASS */
/* Switch to PLL with HSE as clock source */
LL_PLL_ConfigSystemClock_HSE(CONFIG_CLOCK_STM32_HSE_CLOCK, hse_bypass,
&s_PLLInitStruct,
&s_ClkInitStruct);
/* Disable other clocks */
LL_RCC_HSI_Disable();
LL_RCC_MSI_Disable();
#endif /* CONFIG_CLOCK_STM32_PLL_SRC_... */
#elif CONFIG_CLOCK_STM32_SYSCLK_SRC_HSE
/* Enable HSE if not enabled */
if (LL_RCC_HSE_IsReady() != 1) {
/* Check if need to enable HSE bypass feature or not */
#ifdef CONFIG_CLOCK_STM32_HSE_BYPASS
LL_RCC_HSE_EnableBypass();
#else
LL_RCC_HSE_DisableBypass();
#endif /* CONFIG_CLOCK_STM32_HSE_BYPASS */
/* Enable HSE */
LL_RCC_HSE_Enable();
while (LL_RCC_HSE_IsReady() != 1) {
/* Wait for HSE ready */
}
}
/* Set HSE as SYSCLCK source */
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
LL_RCC_SetAHBPrescaler(s_ClkInitStruct.AHBCLKDivider);
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
}
/* Update SystemCoreClock variable */
LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(
CONFIG_CLOCK_STM32_HSE_CLOCK,
s_ClkInitStruct.AHBCLKDivider));
/* Set APB1 & APB2 prescaler*/
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
LL_RCC_SetAPB2Prescaler(s_ClkInitStruct.APB2CLKDivider);
/* Set flash latency */
/* HSI used as SYSCLK, set latency to 0 */
LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
/* Disable other clocks */
LL_RCC_HSI_Disable();
LL_RCC_MSI_Disable();
LL_RCC_PLL_Disable();
#elif CONFIG_CLOCK_STM32_SYSCLK_SRC_HSI
/* Enable HSI if not enabled */
if (LL_RCC_HSI_IsReady() != 1) {
/* Enable HSI */
LL_RCC_HSI_Enable();
while (LL_RCC_HSI_IsReady() != 1) {
/* Wait for HSI ready */
}
}
/* Set HSI as SYSCLCK source */
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
LL_RCC_SetAHBPrescaler(s_ClkInitStruct.AHBCLKDivider);
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
}
/* Update SystemCoreClock variable */
LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(HSI_VALUE,
s_ClkInitStruct.AHBCLKDivider));
/* Set APB1 & APB2 prescaler*/
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
LL_RCC_SetAPB2Prescaler(s_ClkInitStruct.APB2CLKDivider);
/* Set flash latency */
/* HSI used as SYSCLK, set latency to 0 */
LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
/* Disable other clocks */
LL_RCC_HSE_Disable();
LL_RCC_MSI_Disable();
LL_RCC_PLL_Disable();
#endif /* CONFIG_CLOCK_STM32_SYSCLK_SRC_... */
return 0;
}
/**
* @brief RCC device, note that priority is intentionally set to 1 so
* that the device init runs just after SOC init
*/
DEVICE_AND_API_INIT(rcc_stm32, STM32_CLOCK_CONTROL_NAME,
&stm32_clock_control_init,
NULL, NULL,
PRE_KERNEL_1,
CONFIG_CLOCK_CONTROL_STM32_DEVICE_INIT_PRIORITY,
&stm32_clock_control_api);

View file

@ -0,0 +1,16 @@
/*
*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32_LL_CLOCK_H_
#define _STM32_LL_CLOCK_H_
void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit);
/* Section for functions not available in every Cube packages */
void LL_RCC_MSI_Disable(void);
#endif /* _STM32_LL_CLOCK_H_ */

View file

@ -1,398 +0,0 @@
/*
* Copyright (c) 2016 RnDity Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief Driver for Reset & Clock Control of STM32F3x family processor.
*
* Based on reference manual:
* STM32F303xB.C.D.E advanced ARM-based 32-bit MCU
* advanced ARM ® -based 32-bit MCUs
*
* Chapter 9: Reset and clock control (RCC)
*
* STM32F334xx advanced ARM ® -based 32-bit MCUs
*
* Chapter 8: Reset and clock control (RCC)
*/
#include <soc.h>
#include <soc_registers.h>
#include <clock_control.h>
#include <misc/util.h>
#include <misc/__assert.h>
#include <clock_control/stm32_clock_control.h>
struct stm32f3x_rcc_data {
uint8_t *base;
};
static int stm32f3x_clock_control_on(struct device *dev,
clock_control_subsys_t sub_system)
{
struct stm32f3x_rcc_data *data = dev->driver_data;
volatile struct stm32f3x_rcc *rcc =
(struct stm32f3x_rcc *)(data->base);
uint32_t subsys = POINTER_TO_UINT(sub_system);
if (subsys > STM32F3X_CLOCK_AHB_BASE) {
subsys &= ~(STM32F3X_CLOCK_AHB_BASE);
rcc->ahbenr |= subsys;
} else if (subsys > STM32F3X_CLOCK_APB2_BASE) {
subsys &= ~(STM32F3X_CLOCK_APB2_BASE);
rcc->apb2enr |= subsys;
} else {
rcc->apb1enr |= subsys;
}
return 0;
}
static int stm32f3x_clock_control_off(struct device *dev,
clock_control_subsys_t sub_system)
{
struct stm32f3x_rcc_data *data = dev->driver_data;
volatile struct stm32f3x_rcc *rcc =
(struct stm32f3x_rcc *)(data->base);
uint32_t subsys = POINTER_TO_UINT(sub_system);
if (subsys > STM32F3X_CLOCK_AHB_BASE) {
subsys &= ~(STM32F3X_CLOCK_AHB_BASE);
rcc->ahbenr &= ~subsys;
} else if (subsys > STM32F3X_CLOCK_APB2_BASE) {
subsys &= ~(STM32F3X_CLOCK_APB2_BASE);
rcc->apb2enr &= ~subsys;
} else {
rcc->apb1enr &= ~subsys;
}
return 0;
}
/**
* @brief helper for mapping a setting to register value
*/
struct regval_map {
int val;
int reg;
};
static int map_reg_val(const struct regval_map *map,
size_t cnt, int val, uint8_t normalize)
{
for (int i = 0; i < cnt; i++) {
if (map[i].val == val) {
return (map[i].reg >> normalize);
}
}
return 0;
}
/**
* @brief map APB prescaler setting to register value
*/
static int apb_prescaler(int prescaler)
{
if (prescaler == 0) {
return RCC_HCLK_DIV1;
}
const struct regval_map map[] = {
{0, RCC_HCLK_DIV1},
{2, RCC_HCLK_DIV2},
{4, RCC_HCLK_DIV4},
{8, RCC_HCLK_DIV8},
{16, RCC_HCLK_DIV16},
};
return map_reg_val(map, ARRAY_SIZE(map),
prescaler, RCC_CFGR_PPRE1_Pos);
}
/**
* @brief map AHB prescaler setting to register value
*/
static int ahb_prescaler(int prescaler)
{
if (prescaler == 0) {
return RCC_SYSCLK_DIV1;
}
const struct regval_map map[] = {
{0, RCC_SYSCLK_DIV1},
{2, RCC_SYSCLK_DIV2},
{4, RCC_SYSCLK_DIV4},
{8, RCC_SYSCLK_DIV8},
{16, RCC_SYSCLK_DIV16},
{64, RCC_SYSCLK_DIV64},
{128, RCC_SYSCLK_DIV128},
{256, RCC_SYSCLK_DIV256},
{512, RCC_SYSCLK_DIV512},
};
return map_reg_val(map, ARRAY_SIZE(map),
prescaler, RCC_CFGR_HPRE_Pos);
}
/**
* @brief map PLL multiplier setting to register value
*/
static int pllmul(int mul)
{
/* x2 -> 0x0
* x3 -> 0x1
* x4 -> 0x2
* ...
* x15 -> 0xd
* x16 -> 0xe
* x16 -> 0xf
*/
return mul - 2;
}
/**
* @brief select PREDIV division factor
*/
static int prediv_prescaler(int prescaler)
{
if (prescaler == 0) {
return RCC_HSE_PREDIV_DIV1;
}
const struct regval_map map[] = {
{0, RCC_HSE_PREDIV_DIV1},
{2, RCC_HSE_PREDIV_DIV2},
{3, RCC_HSE_PREDIV_DIV3},
{4, RCC_HSE_PREDIV_DIV4},
{5, RCC_HSE_PREDIV_DIV5},
{6, RCC_HSE_PREDIV_DIV6},
{7, RCC_HSE_PREDIV_DIV7},
{8, RCC_HSE_PREDIV_DIV8},
{9, RCC_HSE_PREDIV_DIV9},
{10, RCC_HSE_PREDIV_DIV10},
{11, RCC_HSE_PREDIV_DIV11},
{12, RCC_HSE_PREDIV_DIV12},
{13, RCC_HSE_PREDIV_DIV13},
{14, RCC_HSE_PREDIV_DIV14},
{15, RCC_HSE_PREDIV_DIV15},
{16, RCC_HSE_PREDIV_DIV16},
};
return map_reg_val(map, ARRAY_SIZE(map), prescaler, 0);
}
/**
* @brief select System Clock Source
*/
static int system_clock(int source)
{
__ASSERT_NO_MSG(IS_RCC_SYSCLKSOURCE(source));
return (source >> RCC_CFGR_SW_Pos);
}
/**
* @brief select PLL Clock Source
*/
static int pll_source(int source)
{
__ASSERT_NO_MSG(IS_RCC_PLLSOURCE(source));
return (source >> RCC_CFGR_PLLSRC_Pos);
}
static uint32_t get_ahb_clock(uint32_t sysclk)
{
/* AHB clock is generated based on SYSCLK */
uint32_t sysclk_div = CONFIG_CLOCK_STM32F3X_AHB_PRESCALER;
if (sysclk_div == 0) {
sysclk_div = 1;
}
return sysclk / sysclk_div;
}
static uint32_t get_apb_clock(uint32_t ahb_clock, uint32_t prescaler)
{
if (prescaler == 0) {
prescaler = 1;
}
return ahb_clock / prescaler;
}
static
int stm32f3x_clock_control_get_subsys_rate(struct device *clock,
clock_control_subsys_t sub_system,
uint32_t *rate)
{
ARG_UNUSED(clock);
uint32_t subsys = POINTER_TO_UINT(sub_system);
uint32_t prescaler = CONFIG_CLOCK_STM32F3X_APB1_PRESCALER;
/* assumes SYSCLK is SYS_CLOCK_HW_CYCLES_PER_SEC */
uint32_t ahb_clock =
get_ahb_clock(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
if (subsys > STM32F3X_CLOCK_AHB_BASE) {
prescaler = CONFIG_CLOCK_STM32F3X_AHB_PRESCALER;
} else if (subsys > STM32F3X_CLOCK_APB2_BASE) {
prescaler = CONFIG_CLOCK_STM32F3X_APB2_PRESCALER;
}
*rate = get_apb_clock(ahb_clock, prescaler);
return 0;
}
static const struct clock_control_driver_api stm32f3x_clock_control_api = {
.on = stm32f3x_clock_control_on,
.off = stm32f3x_clock_control_off,
.get_rate = stm32f3x_clock_control_get_subsys_rate,
};
/**
* @brief setup embedded flash controller
*
* Configure flash access time latency depending on SYSCLK.
*/
static void setup_flash(void)
{
volatile struct stm32_flash *flash =
(struct stm32_flash *)(FLASH_R_BASE);
if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 24000000) {
flash->acr.bit.latency = STM32_FLASH_LATENCY_0;
} else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 48000000) {
flash->acr.bit.latency = STM32_FLASH_LATENCY_1;
} else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 72000000) {
flash->acr.bit.latency = STM32_FLASH_LATENCY_2;
}
}
static int stm32f3x_clock_control_init(struct device *dev)
{
struct stm32f3x_rcc_data *data = dev->driver_data;
volatile struct stm32f3x_rcc *rcc =
(struct stm32f3x_rcc *)(data->base);
/* SYSCLK source defaults to HSI */
int sysclk_src = system_clock(RCC_SYSCLKSOURCE_HSI);
uint32_t hpre = ahb_prescaler(CONFIG_CLOCK_STM32F3X_AHB_PRESCALER);
uint32_t ppre1 = apb_prescaler(CONFIG_CLOCK_STM32F3X_APB1_PRESCALER);
uint32_t ppre2 = apb_prescaler(CONFIG_CLOCK_STM32F3X_APB2_PRESCALER);
#ifdef CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER
uint32_t pll_mul = pllmul(CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER);
#endif /* CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER */
#ifdef CONFIG_CLOCK_STM32F3X_PLL_PREDIV
uint32_t prediv =
prediv_prescaler(CONFIG_CLOCK_STM32F3X_PLL_PREDIV);
#endif /* CONFIG_CLOCK_STM32F3X_PLL_PREDIV */
/* disable PLL */
rcc->cr.bit.pllon = 0;
/* disable HSE */
rcc->cr.bit.hseon = 0;
#ifdef CONFIG_CLOCK_STM32F3X_HSE_BYPASS
/* HSE is disabled, HSE bypass can be enabled*/
rcc->cr.bit.hsebyp = 1;
#endif
#ifdef CONFIG_CLOCK_STM32F3X_PLL_SRC_HSI
/* enable HSI clock */
rcc->cr.bit.hsion = 1;
/* this should end after one test */
while (rcc->cr.bit.hsirdy != 1) {
}
/* HSI clock divided by 2 selected as PLL entry clock source. */
rcc->cfgr.bit.pllsrc = pll_source(RCC_PLLSOURCE_HSI);
#endif /* CONFIG_CLOCK_STM32F3X_PLL_SRC_HSI */
#ifdef CONFIG_CLOCK_STM32F3X_PLL_SRC_HSE
/* wait for to become ready */
rcc->cr.bit.hseon = 1;
while (rcc->cr.bit.hserdy != 1) {
}
#ifdef CONFIG_CLOCK_STM32F3X_PLL_PREDIV
rcc->cfgr2.bit.prediv = prediv;
#endif /* CONFIG_CLOCK_STM32F3X_PLL_PREDIV */
/* HSE clock selected as PLL entry clock source. */
rcc->cfgr.bit.pllsrc = pll_source(RCC_PLLSOURCE_HSE);
#endif /* CONFIG_CLOCK_STM32F3X_PLL_SRC_HSE */
/* setup AHB prescaler */
rcc->cfgr.bit.hpre = hpre;
/* setup APB1, must not exceed 36MHz */
rcc->cfgr.bit.ppre1 = ppre1;
/* setup APB2 */
rcc->cfgr.bit.ppre2 = ppre2;
#ifdef CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_HSI
/* enable HSI clock */
rcc->cr.bit.hsion = 1;
/* this should end after one test */
while (rcc->cr.bit.hsirdy != 1) {
}
sysclk_src = system_clock(RCC_SYSCLKSOURCE_HSI);
#elif defined(CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_PLL)
/* setup PLL multiplication (PLL must be disabled) */
rcc->cfgr.bit.pllmul = pll_mul;
/* enable PLL */
rcc->cr.bit.pllon = 1;
/* wait for PLL to become ready */
while (rcc->cr.bit.pllrdy != 1) {
}
sysclk_src = system_clock(RCC_SYSCLKSOURCE_PLLCLK);
#elif defined(CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_HSE)
/* wait for to become ready */
rcc->cr.bit.hseon = 1;
while (rcc->cr.bit.hserdy != 1) {
}
sysclk_src = system_clock(RCC_SYSCLKSOURCE_HSE);
#endif
/* configure flash access latency before SYSCLK source
* switch
*/
setup_flash();
/* set SYSCLK clock value */
rcc->cfgr.bit.sw = sysclk_src;
/* wait for SYSCLK to switch the source */
while (rcc->cfgr.bit.sws != sysclk_src) {
}
dev->driver_api = &stm32f3x_clock_control_api;
return 0;
}
static struct stm32f3x_rcc_data stm32f3x_rcc_data = {
.base = (uint8_t *)RCC_BASE,
};
/* FIXME: move prescaler/multiplier defines into device config */
/**
* @brief RCC device, note that priority is intentionally set to 1 so
* that the device init runs just after SOC init
*/
DEVICE_INIT(rcc_stm32f3x, STM32_CLOCK_CONTROL_NAME,
&stm32f3x_clock_control_init,
&stm32f3x_rcc_data, NULL,
PRE_KERNEL_1,
CONFIG_CLOCK_CONTROL_STM32F3X_DEVICE_INIT_PRIORITY);

View file

@ -0,0 +1,73 @@
/*
*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc.h>
#include <soc_registers.h>
#include <clock_control.h>
#include <misc/util.h>
#include <clock_control/stm32_clock_control.h>
#include "stm32_ll_clock.h"
#ifdef CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL
/**
* @brief fill in pll configuration structure
*/
void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit)
{
/*
* PLL MUL
* 2 -> LL_RCC_PLL_MUL_2 -> 0x00000000
* 3 -> LL_RCC_PLL_MUL_3 -> 0x00040000
* 4 -> LL_RCC_PLL_MUL_4 -> 0x00080000
* ...
* 16 -> LL_RCC_PLL_MUL_16 -> 0x00380000
*/
pllinit->PLLMul = ((CONFIG_CLOCK_STM32_PLL_MULTIPLIER - 2)
<< RCC_CFGR_PLLMUL_Pos);
#if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
/* PREDIV support is a specific RCC configuration present on */
/* following SoCs: STM32F302XE, STM32F303xE and STM32F398xx */
/* cf Reference manual for more details */
#if defined(CONFIG_CLOCK_STM32_PLL_SRC_HSI)
pllinit->PLLDiv = LL_RCC_PLLSOURCE_HSI_DIV_2;
#else
/*
* PLL DIV
* 1 -> LL_RCC_PLLSOURCE_HSE_DIV_1 -> 0x00010000
* 2 -> LL_RCC_PLLSOURCE_HSE_DIV_2 -> 0x00010001
* 3 -> LL_RCC_PLLSOURCE_HSE_DIV_3 -> 0x00010002
* ...
* 16 -> LL_RCC_PLLSOURCE_HSE_DIV_16 -> 0x0001000F
*/
pllinit->PLLDiv = (RCC_CFGR_PLLSRC_HSE_PREDIV |
(CONFIG_CLOCK_STM32_PLL_PREDIV1 - 1));
#endif /* CONFIG_CLOCK_STM32_PLL_SRC_HSI */
#else
/*
* PLL Prediv
* 1 -> LL_RCC_PREDIV_DIV_1 -> 0x00000000
* 2 -> LL_RCC_PREDIV_DIV_2 -> 0x00000001
* 3 -> LL_RCC_PREDIV_DIV_3 -> 0x00000002
* ...
* 16 -> LL_RCC_PREDIV_DIV_16 -> 0x0000000F
*/
pllinit->Prediv = CONFIG_CLOCK_STM32_PLL_PREDIV - 1;
#endif /* RCC_PLLSRC_PREDIV1_SUPPORT */
}
#endif /* CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL */
/**
* @brief Function kept for driver genericity
*/
void LL_RCC_MSI_Disable(void)
{
/* Do nothing */
}

View file

@ -1,383 +0,0 @@
/*
* Copyright (c) 2016 Open-RnD Sp. z o.o.
* Copyright (c) 2016 BayLibre, SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief Driver for Reset & Clock Control of STM32F10x family processor.
*
* Based on reference manual:
* STM32L4x1, STM32L4x2, STM32L431xx STM32L443xx STM32L433xx, STM32L4x5,
* STM32l4x6
* advanced ARM ® -based 32-bit MCUs
*
* Chapter 7: Low-, medium-, high- and XL-density reset and
* clock control
*/
#include <soc.h>
#include <errno.h>
#include <soc_registers.h>
#include <clock_control.h>
#include <misc/util.h>
#include <clock_control/stm32_clock_control.h>
struct stm32l4x_rcc_data {
uint8_t *base;
};
static inline int stm32l4x_clock_control_on(struct device *dev,
clock_control_subsys_t sub_system)
{
struct stm32l4x_rcc_data *data = dev->driver_data;
volatile struct stm32l4x_rcc *rcc = (struct stm32l4x_rcc *)(data->base);
uint32_t subsys = POINTER_TO_UINT(sub_system);
uint32_t base = STM32L4X_CLOCK_BASE(subsys);
uint32_t bit = 1 << STM32L4X_CLOCK_BIT(subsys);
switch (base) {
case STM32L4X_CLOCK_AHB1_BASE:
rcc->ahb1enr |= bit;
break;
case STM32L4X_CLOCK_AHB2_BASE:
rcc->ahb2enr |= bit;
break;
case STM32L4X_CLOCK_AHB3_BASE:
rcc->ahb3enr |= bit;
break;
case STM32L4X_CLOCK_APB1_1_BASE:
rcc->apb1enr1 |= bit;
break;
case STM32L4X_CLOCK_APB1_2_BASE:
rcc->apb1enr2 |= bit;
break;
case STM32L4X_CLOCK_APB2_BASE:
rcc->apb2enr |= bit;
break;
default:
return -EINVAL;
}
return 0;
}
static inline int stm32l4x_clock_control_off(struct device *dev,
clock_control_subsys_t sub_system)
{
struct stm32l4x_rcc_data *data = dev->driver_data;
volatile struct stm32l4x_rcc *rcc =
(struct stm32l4x_rcc *)(data->base);
uint32_t subsys = POINTER_TO_UINT(sub_system);
uint32_t base = STM32L4X_CLOCK_BASE(subsys);
uint32_t bit = 1 << STM32L4X_CLOCK_BIT(subsys);
switch (base) {
case STM32L4X_CLOCK_AHB1_BASE:
rcc->ahb1enr &= bit;
break;
case STM32L4X_CLOCK_AHB2_BASE:
rcc->ahb2enr &= bit;
break;
case STM32L4X_CLOCK_AHB3_BASE:
rcc->ahb3enr &= bit;
break;
case STM32L4X_CLOCK_APB1_1_BASE:
rcc->apb1enr1 &= bit;
break;
case STM32L4X_CLOCK_APB1_2_BASE:
rcc->apb1enr2 &= bit;
break;
case STM32L4X_CLOCK_APB2_BASE:
rcc->apb2enr &= bit;
break;
default:
return -EINVAL;
}
return 0;
}
/**
* @brief helper for mapping a setting to register value
*/
struct regval_map {
int val;
int reg;
};
static int map_reg_val(const struct regval_map *map, size_t cnt, int val)
{
size_t i;
for (i = 0; i < cnt; i++) {
if (map[i].val == val) {
return map[i].reg;
}
}
return 0;
}
/**
* @brief map APB prescaler setting to register value
*/
static int apb_prescaler(int prescaler)
{
if (prescaler == 0) {
return STM32L4X_RCC_CFG_HCLK_DIV_0;
}
const struct regval_map map[] = {
{0, STM32L4X_RCC_CFG_HCLK_DIV_0},
{2, STM32L4X_RCC_CFG_HCLK_DIV_2},
{4, STM32L4X_RCC_CFG_HCLK_DIV_4},
{8, STM32L4X_RCC_CFG_HCLK_DIV_8},
{16, STM32L4X_RCC_CFG_HCLK_DIV_16},
};
return map_reg_val(map, ARRAY_SIZE(map), prescaler);
}
/**
* @brief map AHB prescaler setting to register value
*/
static int ahb_prescaler(int prescaler)
{
if (prescaler == 0)
return STM32L4X_RCC_CFG_SYSCLK_DIV_0;
const struct regval_map map[] = {
{0, STM32L4X_RCC_CFG_SYSCLK_DIV_0},
{2, STM32L4X_RCC_CFG_SYSCLK_DIV_2},
{4, STM32L4X_RCC_CFG_SYSCLK_DIV_4},
{8, STM32L4X_RCC_CFG_SYSCLK_DIV_8},
{16, STM32L4X_RCC_CFG_SYSCLK_DIV_16},
{64, STM32L4X_RCC_CFG_SYSCLK_DIV_64},
{128, STM32L4X_RCC_CFG_SYSCLK_DIV_128},
{256, STM32L4X_RCC_CFG_SYSCLK_DIV_256},
{512, STM32L4X_RCC_CFG_SYSCLK_DIV_512},
};
return map_reg_val(map, ARRAY_SIZE(map), prescaler);
}
static uint32_t get_ahb_clock(uint32_t sysclk)
{
/* AHB clock is generated based on SYSCLK */
uint32_t sysclk_div = CONFIG_CLOCK_STM32L4X_AHB_PRESCALER;
if (sysclk_div == 0) {
sysclk_div = 1;
}
return sysclk / sysclk_div;
}
static uint32_t get_apb_clock(uint32_t ahb_clock, uint32_t prescaler)
{
if (prescaler == 0) {
prescaler = 1;
}
return ahb_clock / prescaler;
}
static
int stm32l4x_clock_control_get_subsys_rate(struct device *clock,
clock_control_subsys_t sub_system,
uint32_t *rate)
{
ARG_UNUSED(clock);
uint32_t subsys = POINTER_TO_UINT(sub_system);
uint32_t base = STM32L4X_CLOCK_BASE(subsys);
/* assumes SYSCLK is SYS_CLOCK_HW_CYCLES_PER_SEC */
uint32_t ahb_clock =
get_ahb_clock(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
switch (base) {
case STM32L4X_CLOCK_AHB1_BASE:
case STM32L4X_CLOCK_AHB2_BASE:
case STM32L4X_CLOCK_AHB3_BASE:
*rate = ahb_clock;
break;
case STM32L4X_CLOCK_APB1_1_BASE:
case STM32L4X_CLOCK_APB1_2_BASE:
*rate = get_apb_clock(ahb_clock,
CONFIG_CLOCK_STM32L4X_APB1_PRESCALER);
break;
case STM32L4X_CLOCK_APB2_BASE:
*rate = get_apb_clock(ahb_clock,
CONFIG_CLOCK_STM32L4X_APB2_PRESCALER);
break;
default:
return -EINVAL;
}
return 0;
}
static const struct clock_control_driver_api stm32l4x_clock_control_api = {
.on = stm32l4x_clock_control_on,
.off = stm32l4x_clock_control_off,
.get_rate = stm32l4x_clock_control_get_subsys_rate,
};
/**
* @brief setup embedded flash controller
*
* Configure flash access time latency depending on SYSCLK.
*/
static inline void setup_flash(void)
{
volatile struct stm32l4x_flash *flash =
(struct stm32l4x_flash *)(FLASH_R_BASE);
if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 16000000) {
flash->acr.bit.latency = STM32L4X_FLASH_LATENCY_0;
} else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 32000000) {
flash->acr.bit.latency = STM32L4X_FLASH_LATENCY_1;
} else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 48000000) {
flash->acr.bit.latency = STM32L4X_FLASH_LATENCY_2;
} else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 64000000) {
flash->acr.bit.latency = STM32L4X_FLASH_LATENCY_3;
} else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 80000000) {
flash->acr.bit.latency = STM32L4X_FLASH_LATENCY_4;
}
}
static int pllqrdiv(int val)
{
switch (val) {
case 2:
return 0;
case 4:
return 1;
case 6:
return 2;
case 8:
return 3;
}
return 0;
}
static int stm32l4x_clock_control_init(struct device *dev)
{
struct stm32l4x_rcc_data *data = dev->driver_data;
volatile struct stm32l4x_rcc *rcc;
/* SYSCLK source defaults to MSI */
int sysclk_src = STM32L4X_RCC_CFG_SYSCLK_SRC_MSI;
uint32_t hpre = ahb_prescaler(CONFIG_CLOCK_STM32L4X_AHB_PRESCALER);
uint32_t ppre1 = apb_prescaler(CONFIG_CLOCK_STM32L4X_APB1_PRESCALER);
uint32_t ppre2 = apb_prescaler(CONFIG_CLOCK_STM32L4X_APB2_PRESCALER);
#ifdef CONFIG_CLOCK_STM32L4X_SYSCLK_SRC_PLL
uint32_t pllm = CONFIG_CLOCK_STM32L4X_PLL_DIVISOR-1;
uint32_t plln = CONFIG_CLOCK_STM32L4X_PLL_MULTIPLIER;
uint32_t pllpdiv = CONFIG_CLOCK_STM32L4X_PLL_P_DIVISOR;
uint32_t pllqdiv = pllqrdiv(CONFIG_CLOCK_STM32L4X_PLL_Q_DIVISOR);
uint32_t pllrdiv = pllqrdiv(CONFIG_CLOCK_STM32L4X_PLL_R_DIVISOR);
#endif /* CONFIG_CLOCK_STM32L4X_PLL_MULTIPLIER */
rcc = (struct stm32l4x_rcc *)(data->base);
/* disable PLL */
rcc->cr.bit.pllon = 0;
/* disable HSE */
rcc->cr.bit.hseon = 0;
#ifdef CONFIG_CLOCK_STM32L4X_HSE_BYPASS
/* HSE is disabled, HSE bypass can be enabled*/
rcc->cr.bit.hsebyp = 1;
#endif
#ifdef CONFIG_CLOCK_STM32L4X_PLL_SRC_MSI
/* enable MSI clock */
rcc->cr.bit.msion = 1;
/* this should end after one test */
while (rcc->cr.bit.msirdy != 1) {
}
/* PLL input from HSI/2 = 4MHz */
rcc->pllcfgr.bit.pllsrc = STM32L4X_RCC_CFG_PLL_SRC_MSI;
#endif /* CONFIG_CLOCK_STM32L4X_PLL_SRC_MSI */
#ifdef CONFIG_CLOCK_STM32L4X_PLL_SRC_HSI
/* wait for to become ready */
rcc->cr.bit.hsion = 1;
while (rcc->cr.bit.hsirdy != 1) {
}
rcc->pllcfgr.bit.pllsrc = STM32L4X_RCC_CFG_PLL_SRC_HSI;
#endif /* CONFIG_CLOCK_STM32L4X_PLL_SRC_HSI */
/* setup AHB prescaler */
rcc->cfgr.bit.hpre = hpre;
/* setup APB1, must not exceed 36MHz */
rcc->cfgr.bit.ppre1 = ppre1;
/* setup APB2 */
rcc->cfgr.bit.ppre2 = ppre2;
#ifdef CONFIG_CLOCK_STM32L4X_SYSCLK_SRC_PLL
/* setup PLL multiplication and divisor (PLL must be disabled) */
rcc->pllcfgr.bit.pllm = pllm;
rcc->pllcfgr.bit.plln = plln;
/* Setup PLL output divisors */
rcc->pllcfgr.bit.pllp = pllpdiv == 17 ? 1 : 0;
rcc->pllcfgr.bit.pllpen = !!pllpdiv;
rcc->pllcfgr.bit.pllq = pllqdiv;
rcc->pllcfgr.bit.pllqen = !!CONFIG_CLOCK_STM32L4X_PLL_Q_DIVISOR;
rcc->pllcfgr.bit.pllr = pllrdiv;
rcc->pllcfgr.bit.pllren = !!CONFIG_CLOCK_STM32L4X_PLL_R_DIVISOR;
/* enable PLL */
rcc->cr.bit.pllon = 1;
/* wait for PLL to become ready */
while (rcc->cr.bit.pllrdy != 1) {
}
sysclk_src = STM32L4X_RCC_CFG_SYSCLK_SRC_PLL;
#elif defined(CONFIG_CLOCK_STM32L4X_SYSCLK_SRC_HSE)
/* wait for to become ready */
rcc->cr.bit.hseon = 1;
while (rcc->cr.bit.hserdy != 1) {
}
sysclk_src = STM32L4X_RCC_CFG_SYSCLK_SRC_HSE;
#else
#error "Need to select or implement support for this STM32L4X SYSCLK source"
#endif
/* configure flash access latency before SYSCLK source
* switch
*/
setup_flash();
/* set SYSCLK clock value */
rcc->cfgr.bit.sw = sysclk_src;
/* wait for SYSCLK to switch the source */
while (rcc->cfgr.bit.sws != sysclk_src) {
}
return 0;
}
static struct stm32l4x_rcc_data stm32l4x_rcc_data = {
.base = (uint8_t *)RCC_BASE,
};
/**
* @brief RCC device, note that priority is intentionally set to 1 so
* that the device init runs just after SOC init
*/
DEVICE_AND_API_INIT(rcc_stm32l4x, STM32_CLOCK_CONTROL_NAME,
&stm32l4x_clock_control_init,
&stm32l4x_rcc_data, NULL,
PRE_KERNEL_1,
CONFIG_CLOCK_CONTROL_STM32L4X_DEVICE_INIT_PRIORITY,
&stm32l4x_clock_control_api);

View file

@ -0,0 +1,35 @@
/*
*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc.h>
#include <soc_registers.h>
#include <clock_control.h>
#include <misc/util.h>
#include <clock_control/stm32_clock_control.h>
#include "stm32_ll_clock.h"
#ifdef CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL
/* Macros to fill up division factors values */
#define _pllm(v) LL_RCC_PLLM_DIV_ ## v
#define pllm(v) _pllm(v)
#define _pllr(v) LL_RCC_PLLR_DIV_ ## v
#define pllr(v) _pllr(v)
/**
* @brief fill in pll configuration structure
*/
void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit)
{
pllinit->PLLM = pllm(CONFIG_CLOCK_STM32_PLL_M_DIVISOR);
pllinit->PLLN = CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER;
pllinit->PLLR = pllr(CONFIG_CLOCK_STM32_PLL_R_DIVISOR);
}
#endif /* CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL */

View file

@ -4,12 +4,12 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "flash_stm32f3x.h"
#include <errno.h> #include <errno.h>
#include <misc/__assert.h> #include <misc/__assert.h>
#include <clock_control/stm32_clock_control.h> #include <clock_control/stm32_clock_control.h>
#include "flash_stm32f3x.h"
static int flash_stm32_erase(struct device *dev, off_t offset, size_t size) static int flash_stm32_erase(struct device *dev, off_t offset, size_t size)
{ {
uint32_t first_page_addr = 0; uint32_t first_page_addr = 0;
@ -118,7 +118,7 @@ static int flash_stm32_init(struct device *dev)
struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME);
if (clock_control_on(clk, cfg->clock_subsys) != 0) if (clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken) != 0)
return -ENODEV; return -ENODEV;
return 0; return 0;
@ -133,7 +133,8 @@ static const struct flash_driver_api flash_stm32_api = {
static const struct flash_stm32_dev_config flash_device_config = { static const struct flash_stm32_dev_config flash_device_config = {
.base = (uint32_t *)FLASH_R_BASE, .base = (uint32_t *)FLASH_R_BASE,
.clock_subsys = UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_FLITF), .pclken = { .bus = STM32_CLOCK_BUS_APB1,
.enr = LL_AHB1_GRP1_PERIPH_FLASH},
}; };
static struct flash_stm32_dev_data flash_device_data = { static struct flash_stm32_dev_data flash_device_data = {

View file

@ -14,7 +14,7 @@
struct flash_stm32_dev_config { struct flash_stm32_dev_config {
uint32_t *base; uint32_t *base;
clock_control_subsys_t clock_subsys; struct stm32_pclken pclken;
}; };
struct flash_stm32_dev_data { struct flash_stm32_dev_data {

View file

@ -4,10 +4,12 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "flash_stm32f3x.h" #include <clock_control/stm32_clock_control.h>
#include <misc/__assert.h> #include <misc/__assert.h>
#include <string.h> #include <string.h>
#include "flash_stm32f3x.h"
void flash_stm32_unlock(struct device *flash) void flash_stm32_unlock(struct device *flash)
{ {
const struct flash_stm32_dev_config *config = FLASH_CFG(flash); const struct flash_stm32_dev_config *config = FLASH_CFG(flash);

View file

@ -188,7 +188,9 @@ static int gpio_stm32_init(struct device *device)
struct device *clk = struct device *clk =
device_get_binding(STM32_CLOCK_CONTROL_NAME); device_get_binding(STM32_CLOCK_CONTROL_NAME);
#ifdef CONFIG_SOC_SERIES_STM32F4X
#if defined(CONFIG_SOC_SERIES_STM32F4X) || \
defined(CONFIG_CLOCK_CONTROL_STM32_CUBE)
clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken); clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken);
#else #else
clock_control_on(clk, cfg->clock_subsys); clock_control_on(clk, cfg->clock_subsys);
@ -196,6 +198,27 @@ static int gpio_stm32_init(struct device *device)
return 0; return 0;
} }
#if defined(CONFIG_CLOCK_CONTROL_STM32_CUBE)
#define GPIO_DEVICE_INIT(__name, __suffix, __base_addr, __port, __cenr, __bus) \
static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \
.base = (uint32_t *)__base_addr, \
.port = __port, \
.pclken = { .bus = __bus, .enr = __cenr } \
}; \
static struct gpio_stm32_data gpio_stm32_data_## __suffix; \
DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \
__name, \
gpio_stm32_init, \
&gpio_stm32_data_## __suffix, \
&gpio_stm32_cfg_## __suffix, \
POST_KERNEL, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
&gpio_stm32_driver);
#else
#ifndef CONFIG_SOC_SERIES_STM32F4X #ifndef CONFIG_SOC_SERIES_STM32F4X
/* TODO: Change F1 to work similarly to F4 */ /* TODO: Change F1 to work similarly to F4 */
@ -203,7 +226,7 @@ static int gpio_stm32_init(struct device *device)
static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \ static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \
.base = (uint32_t *)__base_addr, \ .base = (uint32_t *)__base_addr, \
.port = __port, \ .port = __port, \
.clock_subsys = UINT_TO_POINTER(__clock), \ .clock_subsys = UINT_TO_POINTER(__clock) \
}; \ }; \
static struct gpio_stm32_data gpio_stm32_data_## __suffix; \ static struct gpio_stm32_data gpio_stm32_data_## __suffix; \
DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \
@ -211,14 +234,14 @@ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \
gpio_stm32_init, \ gpio_stm32_init, \
&gpio_stm32_data_## __suffix, \ &gpio_stm32_data_## __suffix, \
&gpio_stm32_cfg_## __suffix, \ &gpio_stm32_cfg_## __suffix, \
POST_KERNEL, \ POST_KERNEL, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
&gpio_stm32_driver); &gpio_stm32_driver);
#else /* CONFIG_SOC_SERIES_STM32F4X */ #else /* CONFIG_SOC_SERIES_STM32F4X */
#define GPIO_DEVICE_INIT(__name, __suffix, __base_addr, __port, __cenr) \ #define GPIO_DEVICE_INIT(__name, __suffix, __base_addr, __port, __cenr) \
static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \ static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \
.base = (uint32_t *)__base_addr, \ .base = (uint32_t *)__base_addr, \
.port = __port, \ .port = __port, \
.pclken = { .bus = STM32F4X_CLOCK_BUS_AHB1, .enr = __cenr }, \ .pclken = { .bus = STM32F4X_CLOCK_BUS_AHB1, .enr = __cenr }, \
@ -229,112 +252,98 @@ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \
gpio_stm32_init, \ gpio_stm32_init, \
&gpio_stm32_data_## __suffix, \ &gpio_stm32_data_## __suffix, \
&gpio_stm32_cfg_## __suffix, \ &gpio_stm32_cfg_## __suffix, \
POST_KERNEL, \ POST_KERNEL, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
&gpio_stm32_driver); &gpio_stm32_driver);
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
#ifdef CONFIG_GPIO_STM32_PORTA #ifdef CONFIG_GPIO_STM32_PORTA
GPIO_DEVICE_INIT("GPIOA", a, GPIOA_BASE, STM32_PORTA, GPIO_DEVICE_INIT("GPIOA", a, GPIOA_BASE, STM32_PORTA,
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
STM32_PERIPH_GPIOA, STM32_CLOCK_BUS_GPIO
#else
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
STM32F10X_CLOCK_SUBSYS_IOPA STM32F10X_CLOCK_SUBSYS_IOPA
| STM32F10X_CLOCK_SUBSYS_AFIO | STM32F10X_CLOCK_SUBSYS_AFIO
#elif CONFIG_SOC_SERIES_STM32F3X
STM32F3X_CLOCK_SUBSYS_IOPA
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
STM32F4X_CLOCK_ENABLE_GPIOA STM32F4X_CLOCK_ENABLE_GPIOA
#elif CONFIG_SOC_SERIES_STM32L4X
STM32L4X_CLOCK_SUBSYS_GPIOA
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
); );
#endif /* CONFIG_GPIO_STM32_PORTA */ #endif /* CONFIG_GPIO_STM32_PORTA */
#ifdef CONFIG_GPIO_STM32_PORTB #ifdef CONFIG_GPIO_STM32_PORTB
GPIO_DEVICE_INIT("GPIOB", b, GPIOB_BASE, STM32_PORTB, GPIO_DEVICE_INIT("GPIOB", b, GPIOB_BASE, STM32_PORTB,
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
STM32_PERIPH_GPIOB, STM32_CLOCK_BUS_GPIO
#else
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
STM32F10X_CLOCK_SUBSYS_IOPB STM32F10X_CLOCK_SUBSYS_IOPB
| STM32F10X_CLOCK_SUBSYS_AFIO | STM32F10X_CLOCK_SUBSYS_AFIO
#elif CONFIG_SOC_SERIES_STM32F3X
STM32F3X_CLOCK_SUBSYS_IOPB
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
STM32F4X_CLOCK_ENABLE_GPIOB STM32F4X_CLOCK_ENABLE_GPIOB
#elif CONFIG_SOC_SERIES_STM32L4X
STM32L4X_CLOCK_SUBSYS_GPIOB
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
); );
#endif /* CONFIG_GPIO_STM32_PORTB */ #endif /* CONFIG_GPIO_STM32_PORTB */
#ifdef CONFIG_GPIO_STM32_PORTC #ifdef CONFIG_GPIO_STM32_PORTC
GPIO_DEVICE_INIT("GPIOC", c, GPIOC_BASE, STM32_PORTC, GPIO_DEVICE_INIT("GPIOC", c, GPIOC_BASE, STM32_PORTC,
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
STM32_PERIPH_GPIOC, STM32_CLOCK_BUS_GPIO
#else
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
STM32F10X_CLOCK_SUBSYS_IOPC STM32F10X_CLOCK_SUBSYS_IOPC
| STM32F10X_CLOCK_SUBSYS_AFIO | STM32F10X_CLOCK_SUBSYS_AFIO
#elif CONFIG_SOC_SERIES_STM32F3X
STM32F3X_CLOCK_SUBSYS_IOPC
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
STM32F4X_CLOCK_ENABLE_GPIOC STM32F4X_CLOCK_ENABLE_GPIOC
#elif CONFIG_SOC_SERIES_STM32L4X
STM32L4X_CLOCK_SUBSYS_GPIOC
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
); );
#endif /* CONFIG_GPIO_STM32_PORTC */ #endif /* CONFIG_GPIO_STM32_PORTC */
#ifdef CONFIG_GPIO_STM32_PORTD #ifdef CONFIG_GPIO_STM32_PORTD
GPIO_DEVICE_INIT("GPIOD", d, GPIOD_BASE, STM32_PORTD, GPIO_DEVICE_INIT("GPIOD", d, GPIOD_BASE, STM32_PORTD,
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
STM32_PERIPH_GPIOD, STM32_CLOCK_BUS_GPIO
#else
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
STM32F10X_CLOCK_SUBSYS_IOPD STM32F10X_CLOCK_SUBSYS_IOPD
| STM32F10X_CLOCK_SUBSYS_AFIO | STM32F10X_CLOCK_SUBSYS_AFIO
#elif CONFIG_SOC_SERIES_STM32F3X
STM32F3X_CLOCK_SUBSYS_IOPD
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
STM32F4X_CLOCK_ENABLE_GPIOD STM32F4X_CLOCK_ENABLE_GPIOD
#elif CONFIG_SOC_SERIES_STM32L4X
STM32L4X_CLOCK_SUBSYS_GPIOD
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
); );
#endif /* CONFIG_GPIO_STM32_PORTD */ #endif /* CONFIG_GPIO_STM32_PORTD */
#ifdef CONFIG_GPIO_STM32_PORTE #ifdef CONFIG_GPIO_STM32_PORTE
GPIO_DEVICE_INIT("GPIOE", e, GPIOE_BASE, STM32_PORTE, GPIO_DEVICE_INIT("GPIOE", e, GPIOE_BASE, STM32_PORTE,
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
STM32_PERIPH_GPIOE, STM32_CLOCK_BUS_GPIO
#else
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
STM32F10X_CLOCK_SUBSYS_IOPE STM32F10X_CLOCK_SUBSYS_IOPE
| STM32F10X_CLOCK_SUBSYS_AFIO | STM32F10X_CLOCK_SUBSYS_AFIO
#elif CONFIG_SOC_SERIES_STM32F3X
STM32F3X_CLOCK_SUBSYS_IOPE
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
STM32F4X_CLOCK_ENABLE_GPIOE STM32F4X_CLOCK_ENABLE_GPIOE
#elif CONFIG_SOC_SERIES_STM32L4X
STM32L4X_CLOCK_SUBSYS_GPIOE
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
); );
#endif /* CONFIG_GPIO_STM32_PORTE */ #endif /* CONFIG_GPIO_STM32_PORTE */
#ifdef CONFIG_GPIO_STM32_PORTF #ifdef CONFIG_GPIO_STM32_PORTF
GPIO_DEVICE_INIT("GPIOF", f, GPIOF_BASE, STM32_PORTF, GPIO_DEVICE_INIT("GPIOF", f, GPIOF_BASE, STM32_PORTF,
#ifdef CONFIG_SOC_SERIES_STM32F3X STM32_PERIPH_GPIOF, STM32_CLOCK_BUS_GPIO);
STM32F3X_CLOCK_SUBSYS_IOPF
#elif CONFIG_SOC_SERIES_STM32L4X
STM32L4X_CLOCK_SUBSYS_GPIOF
#endif
);
#endif /* CONFIG_GPIO_STM32_PORTF */ #endif /* CONFIG_GPIO_STM32_PORTF */
#ifdef CONFIG_GPIO_STM32_PORTG #ifdef CONFIG_GPIO_STM32_PORTG
GPIO_DEVICE_INIT("GPIOG", g, GPIOG_BASE, STM32_PORTG, GPIO_DEVICE_INIT("GPIOG", g, GPIOG_BASE, STM32_PORTG,
#ifdef CONFIG_SOC_SERIES_STM32F3X STM32_PERIPH_GPIOG, STM32_CLOCK_BUS_GPIO);
STM32F3X_CLOCK_SUBSYS_IOPG
#elif CONFIG_SOC_SERIES_STM32L4X
STM32L4X_CLOCK_SUBSYS_GPIOG
#endif
);
#endif /* CONFIG_GPIO_STM32_PORTG */ #endif /* CONFIG_GPIO_STM32_PORTG */
#ifdef CONFIG_GPIO_STM32_PORTH #ifdef CONFIG_GPIO_STM32_PORTH
GPIO_DEVICE_INIT("GPIOH", h, GPIOH_BASE, STM32_PORTH, GPIO_DEVICE_INIT("GPIOH", h, GPIOH_BASE, STM32_PORTH,
#ifdef CONFIG_SOC_SERIES_STM32F3X STM32_PERIPH_GPIOH, STM32_CLOCK_BUS_GPIO);
STM32F3X_CLOCK_SUBSYS_IOPH
#elif CONFIG_SOC_SERIES_STM32L4X
STM32L4X_CLOCK_SUBSYS_GPIOH
#endif
);
#endif /* CONFIG_GPIO_STM32_PORTH */ #endif /* CONFIG_GPIO_STM32_PORTH */

View file

@ -15,6 +15,34 @@
#include <pinmux/stm32/pinmux_stm32.h> #include <pinmux/stm32/pinmux_stm32.h>
#include <gpio.h> #include <gpio.h>
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
/* GPIO buses definitions */
#ifdef CONFIG_SOC_SERIES_STM32F3X
#define STM32_CLOCK_BUS_GPIO STM32_CLOCK_BUS_AHB1
#define STM32_PERIPH_GPIOA LL_AHB1_GRP1_PERIPH_GPIOA
#define STM32_PERIPH_GPIOB LL_AHB1_GRP1_PERIPH_GPIOB
#define STM32_PERIPH_GPIOC LL_AHB1_GRP1_PERIPH_GPIOC
#define STM32_PERIPH_GPIOD LL_AHB1_GRP1_PERIPH_GPIOD
#define STM32_PERIPH_GPIOE LL_AHB1_GRP1_PERIPH_GPIOE
#define STM32_PERIPH_GPIOF LL_AHB1_GRP1_PERIPH_GPIOF
#define STM32_PERIPH_GPIOG LL_AHB1_GRP1_PERIPH_GPIOG
#define STM32_PERIPH_GPIOH LL_AHB1_GRP1_PERIPH_GPIOH
#elif CONFIG_SOC_SERIES_STM32L4X
#define STM32_CLOCK_BUS_GPIO STM32_CLOCK_BUS_AHB2
#define STM32_PERIPH_GPIOA LL_AHB2_GRP1_PERIPH_GPIOA
#define STM32_PERIPH_GPIOB LL_AHB2_GRP1_PERIPH_GPIOB
#define STM32_PERIPH_GPIOC LL_AHB2_GRP1_PERIPH_GPIOC
#define STM32_PERIPH_GPIOD LL_AHB2_GRP1_PERIPH_GPIOD
#define STM32_PERIPH_GPIOE LL_AHB2_GRP1_PERIPH_GPIOE
#define STM32_PERIPH_GPIOF LL_AHB2_GRP1_PERIPH_GPIOF
#define STM32_PERIPH_GPIOG LL_AHB2_GRP1_PERIPH_GPIOG
#define STM32_PERIPH_GPIOH LL_AHB2_GRP1_PERIPH_GPIOH
#endif /* CONFIG_SOC_SERIES_.. */
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
/** /**
* @brief configuration of GPIO device * @brief configuration of GPIO device
*/ */
@ -23,7 +51,9 @@ struct gpio_stm32_config {
uint32_t *base; uint32_t *base;
/* IO port */ /* IO port */
enum stm32_pin_port port; enum stm32_pin_port port;
#ifdef CONFIG_SOC_SERIES_STM32F4X #ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
struct stm32_pclken pclken;
#elif CONFIG_SOC_SERIES_STM32F4X
struct stm32f4x_pclken pclken; struct stm32f4x_pclken pclken;
#else /* SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32L4X */ #else /* SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32L4X */
/* clock subsystem */ /* clock subsystem */

View file

@ -40,7 +40,8 @@ static int i2c_stm32lx_runtime_configure(struct device *dev, uint32_t config)
data->dev_config.raw = config; data->dev_config.raw = config;
clock_control_get_rate(data->clock, cfg->clock_subsys, &clock); clock_control_get_rate(data->clock,
(clock_control_subsys_t *)&cfg->pclken, &clock);
if (data->dev_config.bits.is_slave_read) if (data->dev_config.bits.is_slave_read)
return -EINVAL; return -EINVAL;
@ -408,7 +409,8 @@ static int i2c_stm32lx_init(struct device *dev)
__i2c_stm32lx_get_clock(dev); __i2c_stm32lx_get_clock(dev);
/* enable clock */ /* enable clock */
clock_control_on(data->clock, cfg->clock_subsys); clock_control_on(data->clock,
(clock_control_subsys_t *)&cfg->pclken);
/* Reset config */ /* Reset config */
i2c->cr1.val = 0; i2c->cr1.val = 0;
@ -438,9 +440,8 @@ static void i2c_stm32lx_irq_config_func_0(struct device *port);
static const struct i2c_stm32lx_config i2c_stm32lx_cfg_0 = { static const struct i2c_stm32lx_config i2c_stm32lx_cfg_0 = {
.base = (uint8_t *)I2C1_BASE, .base = (uint8_t *)I2C1_BASE,
#ifdef CONFIG_SOC_SERIES_STM32L4X .pclken = { .bus = STM32_CLOCK_BUS_APB1,
.clock_subsys = UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_I2C1), .enr = LL_APB1_GRP1_PERIPH_I2C1 },
#endif
#ifdef CONFIG_I2C_STM32LX_INTERRUPT #ifdef CONFIG_I2C_STM32LX_INTERRUPT
.irq_config_func = i2c_stm32lx_irq_config_func_0, .irq_config_func = i2c_stm32lx_irq_config_func_0,
#endif #endif
@ -452,7 +453,7 @@ static struct i2c_stm32lx_data i2c_stm32lx_dev_data_0 = {
DEVICE_AND_API_INIT(i2c_stm32lx_0, CONFIG_I2C_0_NAME, &i2c_stm32lx_init, DEVICE_AND_API_INIT(i2c_stm32lx_0, CONFIG_I2C_0_NAME, &i2c_stm32lx_init,
&i2c_stm32lx_dev_data_0, &i2c_stm32lx_cfg_0, &i2c_stm32lx_dev_data_0, &i2c_stm32lx_cfg_0,
SECONDARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&api_funcs); &api_funcs);
#ifdef CONFIG_I2C_STM32LX_INTERRUPT #ifdef CONFIG_I2C_STM32LX_INTERRUPT

View file

@ -184,7 +184,7 @@ struct i2c_stm32lx_config {
void *base; void *base;
irq_config_func_t irq_config_func; irq_config_func_t irq_config_func;
/* clock subsystem driving this peripheral */ /* clock subsystem driving this peripheral */
clock_control_subsys_t clock_subsys; struct stm32_pclken pclken;
}; };
/* driver data */ /* driver data */

View file

@ -16,13 +16,33 @@
#include <kernel.h> #include <kernel.h>
#include <device.h> #include <device.h>
#include <soc.h> #include <soc.h>
#include "pinmux.h"
#include <pinmux.h> #include <pinmux.h>
#include <gpio/gpio_stm32.h> #include <gpio/gpio_stm32.h>
#include <clock_control/stm32_clock_control.h> #include <clock_control/stm32_clock_control.h>
#include <pinmux/stm32/pinmux_stm32.h> #include <pinmux/stm32/pinmux_stm32.h>
#ifdef CONFIG_SOC_SERIES_STM32F4X #include "pinmux.h"
#if defined(CONFIG_CLOCK_CONTROL_STM32_CUBE)
static const uint32_t ports_enable[STM32_PORTS_MAX] = {
STM32_PERIPH_GPIOA,
STM32_PERIPH_GPIOB,
STM32_PERIPH_GPIOC,
STM32_PERIPH_GPIOD,
#ifdef GPIOE_BASE
STM32_PERIPH_GPIOE,
#endif
#ifdef GPIOF_BASE
STM32_PERIPH_GPIOF,
#endif
#ifdef GPIOG_BASE
STM32_PERIPH_GPIOG,
#endif
#ifdef GPIOH_BASE
STM32_PERIPH_GPIOH,
#endif
};
#elif defined(CONFIG_SOC_SERIES_STM32F4X)
static const uint32_t ports_enable[STM32_PORTS_MAX] = { static const uint32_t ports_enable[STM32_PORTS_MAX] = {
STM32F4X_CLOCK_ENABLE_GPIOA, STM32F4X_CLOCK_ENABLE_GPIOA,
STM32F4X_CLOCK_ENABLE_GPIOB, STM32F4X_CLOCK_ENABLE_GPIOB,
@ -51,20 +71,27 @@ static int enable_port(uint32_t port, struct device *clk)
} }
/* TODO: Merge this and move the port clock to the soc file */ /* TODO: Merge this and move the port clock to the soc file */
#ifdef CONFIG_SOC_SERIES_STM32F4X #if defined(CONFIG_CLOCK_CONTROL_STM32_CUBE)
struct stm32f4x_pclken pclken; struct stm32_pclken pclken;
pclken.bus = STM32_CLOCK_BUS_GPIO;
pclken.enr = ports_enable[port];
return clock_control_on(clk, (clock_control_subsys_t *) &pclken);
#else
#if defined(CONFIG_SOC_SERIES_STM32F1X)
clock_control_subsys_t subsys = stm32_get_port_clock(port);
return clock_control_on(clk, subsys);
#elif CONFIG_SOC_SERIES_STM32F4X
struct stm32f4x_pclken pclken;
/* AHB1 bus for all the GPIO ports */ /* AHB1 bus for all the GPIO ports */
pclken.bus = STM32F4X_CLOCK_BUS_AHB1; pclken.bus = STM32F4X_CLOCK_BUS_AHB1;
pclken.enr = ports_enable[port]; pclken.enr = ports_enable[port];
return clock_control_on(clk, (clock_control_subsys_t *) &pclken); return clock_control_on(clk, (clock_control_subsys_t *) &pclken);
#else /* SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32L4X */
clock_control_subsys_t subsys = stm32_get_port_clock(port);
return clock_control_on(clk, subsys);
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
} }
static int stm32_pin_configure(int pin, int func, int altf) static int stm32_pin_configure(int pin, int func, int altf)

View file

@ -27,13 +27,32 @@
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
#define CLOCK_SUBSYS_TIM1 STM32F10X_CLOCK_SUBSYS_TIM1 #define CLOCK_SUBSYS_TIM1 STM32F10X_CLOCK_SUBSYS_TIM1
#define CLOCK_SUBSYS_TIM2 STM32F10X_CLOCK_SUBSYS_TIM2 #define CLOCK_SUBSYS_TIM2 STM32F10X_CLOCK_SUBSYS_TIM2
#elif CONFIG_SOC_SERIES_STM32L4X
#define CLOCK_SUBSYS_TIM1 STM32L4X_CLOCK_SUBSYS_TIM1
#define CLOCK_SUBSYS_TIM2 STM32L4X_CLOCK_SUBSYS_TIM2
#endif #endif
#define CHANNEL_LENGTH 4 #define CHANNEL_LENGTH 4
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
static uint32_t __get_tim_clk(uint32_t bus_clk,
clock_control_subsys_t *sub_system)
{
struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
uint32_t tim_clk, apb_psc;
if (pclken->bus == STM32_CLOCK_BUS_APB1) {
apb_psc = CONFIG_CLOCK_STM32_APB1_PRESCALER;
} else {
apb_psc = CONFIG_CLOCK_STM32_APB2_PRESCALER;
}
if (apb_psc == RCC_HCLK_DIV1) {
tim_clk = bus_clk;
} else {
tim_clk = 2 * bus_clk;
}
return tim_clk;
}
#else
#ifdef CONFIG_SOC_SERIES_STM32F4X #ifdef CONFIG_SOC_SERIES_STM32F4X
static uint32_t __get_tim_clk(uint32_t bus_clk, static uint32_t __get_tim_clk(uint32_t bus_clk,
clock_control_subsys_t *sub_system) clock_control_subsys_t *sub_system)
@ -64,19 +83,11 @@ static uint32_t __get_tim_clk(uint32_t bus_clk,
uint32_t tim_clk, apb_psc; uint32_t tim_clk, apb_psc;
uint32_t subsys = POINTER_TO_UINT(sub_system); uint32_t subsys = POINTER_TO_UINT(sub_system);
#ifdef CONFIG_SOC_SERIES_STM32L4X
if (STM32L4X_CLOCK_BASE(subsys) == STM32L4X_CLOCK_APB2_BASE) {
apb_psc = CONFIG_CLOCK_STM32L4X_APB2_PRESCALER;
} else {
apb_psc = CONFIG_CLOCK_STM32L4X_APB1_PRESCALER;
}
#elif CONFIG_SOC_SERIES_STM32F1X
if (subsys > STM32F10X_CLOCK_APB2_BASE) { if (subsys > STM32F10X_CLOCK_APB2_BASE) {
apb_psc = CONFIG_CLOCK_STM32F10X_APB2_PRESCALER; apb_psc = CONFIG_CLOCK_STM32F10X_APB2_PRESCALER;
} else { } else {
apb_psc = CONFIG_CLOCK_STM32F10X_APB1_PRESCALER; apb_psc = CONFIG_CLOCK_STM32F10X_APB1_PRESCALER;
} }
#endif
if (apb_psc == RCC_HCLK_DIV1) { if (apb_psc == RCC_HCLK_DIV1) {
tim_clk = bus_clk; tim_clk = bus_clk;
@ -87,6 +98,7 @@ static uint32_t __get_tim_clk(uint32_t bus_clk,
return tim_clk; return tim_clk;
} }
#endif /* CONFIG_SOC_SERIES_STM32F4X */ #endif /* CONFIG_SOC_SERIES_STM32F4X */
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
/* /*
* Set the period and pulse width for a PWM pin. * Set the period and pulse width for a PWM pin.
@ -188,7 +200,8 @@ static int pwm_stm32_get_cycles_per_sec(struct device *dev, uint32_t pwm,
} }
/* Timer clock depends on APB prescaler */ /* Timer clock depends on APB prescaler */
#ifdef CONFIG_SOC_SERIES_STM32F4X #if defined(CONFIG_SOC_SERIES_STM32F4X) || \
defined(CONFIG_CLOCK_CONTROL_STM32_CUBE)
clock_control_get_rate(data->clock, clock_control_get_rate(data->clock,
(clock_control_subsys_t *)&cfg->pclken, &bus_clk); (clock_control_subsys_t *)&cfg->pclken, &bus_clk);
@ -230,7 +243,8 @@ static int pwm_stm32_init(struct device *dev)
__pwm_stm32_get_clock(dev); __pwm_stm32_get_clock(dev);
/* enable clock */ /* enable clock */
#ifdef CONFIG_SOC_SERIES_STM32F4X #if defined(CONFIG_SOC_SERIES_STM32F4X) || \
defined(CONFIG_CLOCK_CONTROL_STM32_CUBE)
clock_control_on(data->clock, clock_control_on(data->clock,
(clock_control_subsys_t *)&config->pclken); (clock_control_subsys_t *)&config->pclken);
#else #else
@ -249,12 +263,17 @@ static struct pwm_stm32_data pwm_stm32_dev_data_1 = {
static const struct pwm_stm32_config pwm_stm32_dev_cfg_1 = { static const struct pwm_stm32_config pwm_stm32_dev_cfg_1 = {
.pwm_base = TIM1_BASE, .pwm_base = TIM1_BASE,
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
.pclken = { .bus = STM32_CLOCK_BUS_APB2,
.enr = LL_APB2_GRP1_PERIPH_TIM1 },
#else
#ifdef CONFIG_SOC_SERIES_STM32F4X #ifdef CONFIG_SOC_SERIES_STM32F4X
.pclken = { .bus = STM32F4X_CLOCK_BUS_APB2, .pclken = { .bus = STM32F4X_CLOCK_BUS_APB2,
.enr = STM32F4X_CLOCK_ENABLE_TIM1 }, .enr = STM32F4X_CLOCK_ENABLE_TIM1 },
#else #else
.clock_subsys = UINT_TO_POINTER(CLOCK_SUBSYS_TIM1), .clock_subsys = UINT_TO_POINTER(CLOCK_SUBSYS_TIM1),
#endif /* CONFIG_SOC_SERIES_STM32F4X */ #endif /* CONFIG_SOC_SERIES_STM32F4X */
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
}; };
DEVICE_AND_API_INIT(pwm_stm32_1, CONFIG_PWM_STM32_1_DEV_NAME, DEVICE_AND_API_INIT(pwm_stm32_1, CONFIG_PWM_STM32_1_DEV_NAME,
@ -273,12 +292,17 @@ static struct pwm_stm32_data pwm_stm32_dev_data_2 = {
static const struct pwm_stm32_config pwm_stm32_dev_cfg_2 = { static const struct pwm_stm32_config pwm_stm32_dev_cfg_2 = {
.pwm_base = TIM2_BASE, .pwm_base = TIM2_BASE,
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
.pclken = { .bus = STM32_CLOCK_BUS_APB1,
.enr = LL_APB1_GRP1_PERIPH_TIM2 },
#else
#ifdef CONFIG_SOC_SERIES_STM32F4X #ifdef CONFIG_SOC_SERIES_STM32F4X
.pclken = { .bus = STM32F4X_CLOCK_BUS_APB1, .pclken = { .bus = STM32F4X_CLOCK_BUS_APB1,
.enr = STM32F4X_CLOCK_ENABLE_TIM2 }, .enr = STM32F4X_CLOCK_ENABLE_TIM2 },
#else #else
.clock_subsys = UINT_TO_POINTER(CLOCK_SUBSYS_TIM2), .clock_subsys = UINT_TO_POINTER(CLOCK_SUBSYS_TIM2),
#endif /* CONFIG_SOC_SERIES_STM32F4X */ #endif /* CONFIG_SOC_SERIES_STM32F4X */
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
}; };
DEVICE_AND_API_INIT(pwm_stm32_2, CONFIG_PWM_STM32_2_DEV_NAME, DEVICE_AND_API_INIT(pwm_stm32_2, CONFIG_PWM_STM32_2_DEV_NAME,

View file

@ -19,11 +19,15 @@ extern "C" {
struct pwm_stm32_config { struct pwm_stm32_config {
uint32_t pwm_base; uint32_t pwm_base;
/* clock subsystem driving this peripheral */ /* clock subsystem driving this peripheral */
#if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32L4X) #ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
struct stm32_pclken pclken;
#else
#if defined(CONFIG_SOC_SERIES_STM32F1X)
clock_control_subsys_t clock_subsys; clock_control_subsys_t clock_subsys;
#elif defined(CONFIG_SOC_SERIES_STM32F4X) #elif defined(CONFIG_SOC_SERIES_STM32F4X)
struct stm32f4x_pclken pclken; struct stm32f4x_pclken pclken;
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
}; };
/** Runtime driver data */ /** Runtime driver data */

View file

@ -291,11 +291,10 @@ static int uart_stm32_init(struct device *dev)
__uart_stm32_get_clock(dev); __uart_stm32_get_clock(dev);
/* enable clock */ /* enable clock */
#if defined(CONFIG_SOC_SERIES_STM32F1X) || \ #if defined(CONFIG_SOC_SERIES_STM32F1X)
defined(CONFIG_SOC_SERIES_STM32F3X) || \
defined(CONFIG_SOC_SERIES_STM32L4X)
clock_control_on(data->clock, config->clock_subsys); clock_control_on(data->clock, config->clock_subsys);
#elif defined(CONFIG_SOC_SERIES_STM32F4X) #elif defined(CONFIG_SOC_SERIES_STM32F4X) || \
defined(CONFIG_CLOCK_CONTROL_STM32_CUBE)
clock_control_on(data->clock, clock_control_on(data->clock,
(clock_control_subsys_t *)&config->pclken); (clock_control_subsys_t *)&config->pclken);
#endif #endif
@ -330,16 +329,17 @@ static const struct uart_stm32_config uart_stm32_dev_cfg_1 = {
.irq_config_func = uart_stm32_irq_config_func_1, .irq_config_func = uart_stm32_irq_config_func_1,
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
}, },
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
.pclken = { .bus = STM32_CLOCK_BUS_APB2,
.enr = LL_APB2_GRP1_PERIPH_USART1 },
#else
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
.clock_subsys = UINT_TO_POINTER(STM32F10X_CLOCK_SUBSYS_USART1), .clock_subsys = UINT_TO_POINTER(STM32F10X_CLOCK_SUBSYS_USART1),
#elif CONFIG_SOC_SERIES_STM32F3X
.clock_subsys = UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_USART1),
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
.pclken = { .bus = STM32F4X_CLOCK_BUS_APB2, .pclken = { .bus = STM32F4X_CLOCK_BUS_APB2,
.enr = STM32F4X_CLOCK_ENABLE_USART1 }, .enr = STM32F4X_CLOCK_ENABLE_USART1 },
#elif CONFIG_SOC_SERIES_STM32L4X
.clock_subsys = UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_USART1),
#endif /* CONFIG_SOC_SERIES_STM32FX */ #endif /* CONFIG_SOC_SERIES_STM32FX */
#endif /* CLOCK_CONTROL_STM32_CUBE */
}; };
static struct uart_stm32_data uart_stm32_dev_data_1 = { static struct uart_stm32_data uart_stm32_dev_data_1 = {
@ -393,16 +393,17 @@ static const struct uart_stm32_config uart_stm32_dev_cfg_2 = {
.irq_config_func = uart_stm32_irq_config_func_2, .irq_config_func = uart_stm32_irq_config_func_2,
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
}, },
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
.pclken = { .bus = STM32_CLOCK_BUS_APB1,
.enr = LL_APB1_GRP1_PERIPH_USART2 },
#else
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
.clock_subsys = UINT_TO_POINTER(STM32F10X_CLOCK_SUBSYS_USART2), .clock_subsys = UINT_TO_POINTER(STM32F10X_CLOCK_SUBSYS_USART2),
#elif CONFIG_SOC_SERIES_STM32F3X
.clock_subsys = UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_USART2),
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
.pclken = { .bus = STM32F4X_CLOCK_BUS_APB1, .pclken = { .bus = STM32F4X_CLOCK_BUS_APB1,
.enr = STM32F4X_CLOCK_ENABLE_USART2 }, .enr = STM32F4X_CLOCK_ENABLE_USART2 },
#elif CONFIG_SOC_SERIES_STM32L4X
.clock_subsys = UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_USART2),
#endif /* CONFIG_SOC_SERIES_STM32FX */ #endif /* CONFIG_SOC_SERIES_STM32FX */
#endif /* CLOCK_CONTROL_STM32_CUBE */
}; };
static struct uart_stm32_data uart_stm32_dev_data_2 = { static struct uart_stm32_data uart_stm32_dev_data_2 = {
@ -456,15 +457,16 @@ static const struct uart_stm32_config uart_stm32_dev_cfg_3 = {
.irq_config_func = uart_stm32_irq_config_func_3, .irq_config_func = uart_stm32_irq_config_func_3,
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
}, },
#ifdef CONFIG_CLOCK_CONTROL_STM32_CUBE
.pclken = { .bus = STM32_CLOCK_BUS_APB1,
.enr = LL_APB1_GRP1_PERIPH_USART3 },
#else
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
.clock_subsys = UINT_TO_POINTER(STM32F10X_CLOCK_SUBSYS_USART3), .clock_subsys = UINT_TO_POINTER(STM32F10X_CLOCK_SUBSYS_USART3),
#elif CONFIG_SOC_SERIES_STM32F3X
.clock_subsys = UINT_TO_POINTER(STM32F3X_CLOCK_SUBSYS_USART3),
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
.clock_subsys = UINT_TO_POINTER(STM32F40X_CLOCK_SUBSYS_USART3), .clock_subsys = UINT_TO_POINTER(STM32F40X_CLOCK_SUBSYS_USART3),
#elif CONFIG_SOC_SERIES_STM32L4X
.clock_subsys = UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_USART3),
#endif /* CONFIG_SOC_SERIES_STM32F4X */ #endif /* CONFIG_SOC_SERIES_STM32F4X */
#endif /* CLOCK_CONTROL_STM32_CUBE */
}; };
static struct uart_stm32_data uart_stm32_dev_data_3 = { static struct uart_stm32_data uart_stm32_dev_data_3 = {

View file

@ -16,13 +16,15 @@
struct uart_stm32_config { struct uart_stm32_config {
struct uart_device_config uconf; struct uart_device_config uconf;
/* clock subsystem driving this peripheral */ /* clock subsystem driving this peripheral */
#if defined(CONFIG_SOC_SERIES_STM32F1X) || \ #if defined(CONFIG_CLOCK_CONTROL_STM32_CUBE)
defined(CONFIG_SOC_SERIES_STM32F3X) || \ struct stm32_pclken pclken;
defined(CONFIG_SOC_SERIES_STM32L4X) #else
#if defined(CONFIG_SOC_SERIES_STM32F1X)
clock_control_subsys_t clock_subsys; clock_control_subsys_t clock_subsys;
#elif defined(CONFIG_SOC_SERIES_STM32F4X) #elif defined(CONFIG_SOC_SERIES_STM32F4X)
struct stm32f4x_pclken pclken; struct stm32f4x_pclken pclken;
#endif #endif
#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */
}; };
/* driver data */ /* driver data */

View file

@ -11,6 +11,7 @@ endif
ifdef CONFIG_SOC_SERIES_STM32F3X ifdef CONFIG_SOC_SERIES_STM32F3X
obj-y += stm32f3xx/drivers/src/stm32f3xx_hal.o obj-y += stm32f3xx/drivers/src/stm32f3xx_hal.o
obj-y += stm32f3xx/drivers/src/stm32f3xx_hal_rcc.o obj-y += stm32f3xx/drivers/src/stm32f3xx_hal_rcc.o
obj-$(CONFIG_CLOCK_CONTROL_STM32_CUBE) += stm32f3xx/drivers/src/stm32f3xx_ll_utils.o
obj-$(CONFIG_SERIAL_HAS_DRIVER) += stm32f3xx/drivers/src/stm32f3xx_hal_uart.o obj-$(CONFIG_SERIAL_HAS_DRIVER) += stm32f3xx/drivers/src/stm32f3xx_hal_uart.o
obj-y += stm32f3xx/soc/system_stm32f3xx.o obj-y += stm32f3xx/soc/system_stm32f3xx.o
endif endif
@ -31,6 +32,7 @@ endif
ifdef CONFIG_SOC_SERIES_STM32L4X ifdef CONFIG_SOC_SERIES_STM32L4X
obj-y += stm32l4xx/drivers/src/stm32l4xx_hal.o obj-y += stm32l4xx/drivers/src/stm32l4xx_hal.o
obj-y += stm32l4xx/drivers/src/stm32l4xx_hal_rcc.o obj-y += stm32l4xx/drivers/src/stm32l4xx_hal_rcc.o
obj-$(CONFIG_CLOCK_CONTROL_STM32_CUBE) += stm32l4xx/drivers/src/stm32l4xx_ll_utils.o
obj-$(CONFIG_PWM) += stm32l4xx/drivers/src/stm32l4xx_hal_tim.o obj-$(CONFIG_PWM) += stm32l4xx/drivers/src/stm32l4xx_hal_tim.o
obj-$(CONFIG_SERIAL_HAS_DRIVER) += stm32l4xx/drivers/src/stm32l4xx_hal_uart.o obj-$(CONFIG_SERIAL_HAS_DRIVER) += stm32l4xx/drivers/src/stm32l4xx_hal_uart.o
obj-y += stm32l4xx/soc/system_stm32l4xx.o obj-y += stm32l4xx/soc/system_stm32l4xx.o

View file

@ -36,8 +36,6 @@ extern "C" {
#include <arch/arm/cortex_m/irq.h> #include <arch/arm/cortex_m/irq.h>
#include <arch/arm/cortex_m/error.h> #include <arch/arm/cortex_m/error.h>
#include <arch/arm/cortex_m/misc.h> #include <arch/arm/cortex_m/misc.h>
#include <arch/arm/cortex_m/scs.h>
#include <arch/arm/cortex_m/scb.h>
#include <arch/arm/cortex_m/memory_map.h> #include <arch/arm/cortex_m/memory_map.h>
#include <arch/arm/cortex_m/asm_inline.h> #include <arch/arm/cortex_m/asm_inline.h>
#include <arch/arm/cortex_m/addr_types.h> #include <arch/arm/cortex_m/addr_types.h>

View file

@ -22,19 +22,68 @@ extern "C" {
/* CP10 Access Bits */ /* CP10 Access Bits */
#define CPACR_CP10_Pos 20U #define CPACR_CP10_Pos 20U
#define CPACR_CP10_Msk (3UL << _SCS_CPACR_CP10_Pos) #define CPACR_CP10_Msk (3UL << CPACR_CP10_Pos)
#define CPACR_CP10_NO_ACCESS (0UL << _SCS_CPACR_CP10_Pos) #define CPACR_CP10_NO_ACCESS (0UL << CPACR_CP10_Pos)
#define CPACR_CP10_PRIV_ACCESS (1UL << _SCS_CPACR_CP10_Pos) #define CPACR_CP10_PRIV_ACCESS (1UL << CPACR_CP10_Pos)
#define CPACR_CP10_RESERVED (2UL << _SCS_CPACR_CP10_Pos) #define CPACR_CP10_RESERVED (2UL << CPACR_CP10_Pos)
#define CPACR_CP10_FULL_ACCESS (3UL << _SCS_CPACR_CP10_Pos) #define CPACR_CP10_FULL_ACCESS (3UL << CPACR_CP10_Pos)
/* CP11 Access Bits */ /* CP11 Access Bits */
#define CPACR_CP11_Pos 22U #define CPACR_CP11_Pos 22U
#define CPACR_CP11_Msk (3UL << _SCS_CPACR_CP11_Pos) #define CPACR_CP11_Msk (3UL << CPACR_CP11_Pos)
#define CPACR_CP11_NO_ACCESS (0UL << _SCS_CPACR_CP11_Pos) #define CPACR_CP11_NO_ACCESS (0UL << CPACR_CP11_Pos)
#define CPACR_CP11_PRIV_ACCESS (1UL << _SCS_CPACR_CP11_Pos) #define CPACR_CP11_PRIV_ACCESS (1UL << CPACR_CP11_Pos)
#define CPACR_CP11_RESERVED (2UL << _SCS_CPACR_CP11_Pos) #define CPACR_CP11_RESERVED (2UL << CPACR_CP11_Pos)
#define CPACR_CP11_FULL_ACCESS (3UL << _SCS_CPACR_CP11_Pos) #define CPACR_CP11_FULL_ACCESS (3UL << CPACR_CP11_Pos)
#define SCB_UFSR (*((__IOM uint16_t *) &SCB->CFSR + 2))
#define SCB_BFSR (*((__IOM uint8_t *) &SCB->CFSR + 1))
#define SCB_MMFSR (*((__IOM uint8_t *) &SCB->CFSR))
/* CFSR[UFSR] */
#define CFSR_DIVBYZERO_Pos (25U)
#define CFSR_DIVBYZERO_Msk (0x1U << CFSR_DIVBYZERO_Pos)
#define CFSR_UNALIGNED_Pos (24U)
#define CFSR_UNALIGNED_Msk (0x1U << CFSR_UNALIGNED_Pos)
#define CFSR_NOCP_Pos (19U)
#define CFSR_NOCP_Msk (0x1U << CFSR_NOCP_Pos)
#define CFSR_INVPC_Pos (18U)
#define CFSR_INVPC_Msk (0x1U << CFSR_INVPC_Pos)
#define CFSR_INVSTATE_Pos (17U)
#define CFSR_INVSTATE_Msk (0x1U << CFSR_INVSTATE_Pos)
#define CFSR_UNDEFINSTR_Pos (16U)
#define CFSR_UNDEFINSTR_Msk (0x1U << CFSR_UNDEFINSTR_Pos)
/* CFSR[BFSR] */
#define CFSR_BFARVALID_Pos (15U)
#define CFSR_BFARVALID_Msk (0x1U << CFSR_BFARVALID_Pos)
#define CFSR_LSPERR_Pos (13U)
#define CFSR_LSPERR_Msk (0x1U << CFSR_LSPERR_Pos)
#define CFSR_STKERR_Pos (12U)
#define CFSR_STKERR_Msk (0x1U << CFSR_STKERR_Pos)
#define CFSR_UNSTKERR_Pos (11U)
#define CFSR_UNSTKERR_Msk (0x1U << CFSR_UNSTKERR_Pos)
#define CFSR_IMPRECISERR_Pos (10U)
#define CFSR_IMPRECISERR_Msk (0x1U << CFSR_IMPRECISERR_Pos)
#define CFSR_PRECISERR_Pos (9U)
#define CFSR_PRECISERR_Msk (0x1U << CFSR_PRECISERR_Pos)
#define CFSR_IBUSERR_Pos (8U)
#define CFSR_IBUSERR_Msk (0x1U << CFSR_IBUSERR_Pos)
/* CFSR[MMFSR] */
#define CFSR_MMARVALID_Pos (7U)
#define CFSR_MMARVALID_Msk (0x1U << CFSR_MMARVALID_Pos)
#define CFSR_MLSPERR_Pos (5U)
#define CFSR_MLSPERR_Msk (0x1U << CFSR_MLSPERR_Pos)
#define CFSR_MSTKERR_Pos (4U)
#define CFSR_MSTKERR_Msk (0x1U << CFSR_MSTKERR_Pos)
#define CFSR_MUNSTKERR_Pos (3U)
#define CFSR_MUNSTKERR_Msk (0x1U << CFSR_MUNSTKERR_Pos)
#define CFSR_DACCVIOL_Pos (1U)
#define CFSR_DACCVIOL_Msk (0x1U << CFSR_DACCVIOL_Pos)
#define CFSR_IACCVIOL_Pos (0U)
#define CFSR_IACCVIOL_Msk (0x1U << CFSR_IACCVIOL_Pos)
/* Fill in CMSIS required values for non-CMSIS compliant SoCs. /* Fill in CMSIS required values for non-CMSIS compliant SoCs.
* Use __NVIC_PRIO_BITS as it is required and simple to check, but * Use __NVIC_PRIO_BITS as it is required and simple to check, but

View file

@ -1,583 +0,0 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARM CORTEX-M System Control Block interface
*
* Provide an interface to the System Control Block found on ARM Cortex-M
* processors.
*
* The API does not account for all possible usages of the SCB, only the
* functionalities needed by the kernel. It does not contain NVIC
* functionalities either: these can be found in nvic.h. MPU functionalities
* are not implemented.
*
* The same effect can be achieved by directly writing in the registers of the
* SCB, with the layout available from scs.h, using the __scs.scb data
* structure (or hardcoded values), but the APIs found here are less
* error-prone, especially for registers with multiple instances to account
* for 16 exceptions.
*
* If access to a missing functionality is needed, directly writing to the
* registers is the way to implement it.
*/
#ifndef _SCB__H_
#define _SCB__H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASMLANGUAGE
#else
#include <kernel.h>
#include <arch/cpu.h>
#include <misc/__assert.h>
#include <arch/arm/cortex_m/scs.h>
#include <misc/util.h>
#include <stdint.h>
/**
*
* @brief Obtain the currently executing vector
*
* If currently handling an exception/interrupt, return the executing vector
* number. If not, return 0.
*
* @return the currently executing vector number, 0 if in thread mode.
*/
static inline uint32_t _ScbActiveVectorGet(void)
{
return __scs.scb.icsr.bit.vectactive;
}
#if defined(CONFIG_ARMV6_M)
#elif defined(CONFIG_ARMV7_M)
/**
*
* @brief Find out if the currently executing exception is nested
*
* This routine determines if the currently executing exception is nested.
*
* @return 1 if nested, 0 otherwise
*/
static inline int _ScbIsNestedExc(void)
{
/* !bit == preempted exceptions */
return !__scs.scb.icsr.bit.rettobase;
}
/**
*
* @brief Enable faulting on division by zero
*
* This routine enables the divide by zero fault.
* By default, the CPU ignores the error.
*
* @return N/A
*/
static inline void _ScbDivByZeroFaultEnable(void)
{
__scs.scb.ccr.bit.div_0_trp = 1;
}
/**
*
* @brief Enable usage fault exceptions
*
* This routine enables usage faults.
* By default, the CPU does not raise usage fault exceptions.
*
* @return N/A
*/
static inline void _ScbUsageFaultEnable(void)
{
__scs.scb.shcsr.bit.usgfaultena = 1;
}
/**
*
* @brief Enable bus fault exceptions
*
* This routine enables bus faults.
* By default, the CPU does not raise bus fault exceptions.
*
* @return N/A
*/
static inline void _ScbBusFaultEnable(void)
{
__scs.scb.shcsr.bit.busfaultena = 1;
}
/**
*
* @brief Enable MPU faults exceptions
*
* This routine enables the MPU faults.
* By default, the CPU does not raise MPU fault exceptions.
*
* @return N/A
*/
static inline void _ScbMemFaultEnable(void)
{
__scs.scb.shcsr.bit.memfaultena = 1;
}
/**
*
* @brief Find out if a hard fault is caused by a bus error on vector read
*
* This routine determines if a hard fault is caused by a bus error during
* a vector table read operation.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbHardFaultIsBusErrOnVectorRead(void)
{
return __scs.scb.hfsr.bit.vecttbl;
}
/**
*
* @brief Find out if a fault was escalated to hard fault
*
* Happens if a fault cannot be triggered because of priority or because it was
* disabled.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbHardFaultIsForced(void)
{
return __scs.scb.hfsr.bit.forced;
}
/**
*
* @brief Clear all hard faults (HFSR register)
*
* HFSR register is a 'write-one-to-clear' (W1C) register.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbHardFaultAllFaultsReset(void)
{
return __scs.scb.hfsr.val = 0xffff;
}
/**
*
* @brief Find out if a hard fault is an MPU fault
*
* This routine determines if a hard fault is an MPU fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbIsMemFault(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.val;
}
/**
*
* @brief Find out if the MMFAR register contains a valid value
*
* The MMFAR register contains the faulting address on an MPU fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsMmfarValid(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.mmarvalid;
}
/**
*
* @brief Invalid the value in MMFAR
*
* This routine invalidates the MMFAR value. This should be done after
* processing an MPU fault.
*
* @return N/A
*/
static inline void _ScbMemFaultMmfarReset(void)
{
__scs.scb.cfsr.byte.mmfsr.bit.mmarvalid = 0;
}
/**
*
* @brief Clear all MPU faults (MMFSR register)
*
* CFSR/MMFSR register is a 'write-one-to-clear' (W1C) register.
*
* @return 1 if so, 0 otherwise
*/
static inline void _ScbMemFaultAllFaultsReset(void)
{
__scs.scb.cfsr.byte.mmfsr.val = 0xfe;
}
/**
*
* @brief Find out if an MPU fault is a stacking fault
*
* This routine determines if an MPU fault is a stacking fault.
* This may occur upon exception entry.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsStacking(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.mstkerr;
}
/**
*
* @brief Find out if an MPU fault is an unstacking fault
*
* This routine determines if an MPU fault is an unstacking fault.
* This may occur upon exception exit.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsUnstacking(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.munstkerr;
}
/**
*
* @brief Find out if an MPU fault is a data access violation
*
* If this routine returns 1, read the MMFAR register via _ScbMemFaultAddrGet()
* to get the faulting address.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsDataAccessViolation(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.daccviol;
}
/**
*
* @brief Find out if an MPU fault is an instruction access violation
*
* This routine determines if an MPU fault is due to an instruction access
* violation.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbMemFaultIsInstrAccessViolation(void)
{
return !!__scs.scb.cfsr.byte.mmfsr.bit.iaccviol;
}
/**
*
* @brief Find out the faulting address on an MPU fault
*
* @return the faulting address
*/
static inline uint32_t _ScbMemFaultAddrGet(void)
{
return __scs.scb.mmfar;
}
/**
*
* @brief Find out if a hard fault is a bus fault
*
* This routine determines if a hard fault is a bus fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbIsBusFault(void)
{
return !!__scs.scb.cfsr.byte.bfsr.val;
}
/**
*
* @brief Find out if the BFAR register contains a valid value
*
* The BFAR register contains the faulting address on bus fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsBfarValid(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.bfarvalid;
}
/**
*
* @brief Invalid the value in BFAR
*
* This routine clears/invalidates the Bus Fault Address Register.
* It should be done after processing a bus fault.
*
* @return N/A
*/
static inline void _ScbBusFaultBfarReset(void)
{
__scs.scb.cfsr.byte.bfsr.bit.bfarvalid = 0;
}
/**
*
* @brief Clear all bus faults (BFSR register)
*
* CFSR/BFSR register is a 'write-one-to-clear' (W1C) register.
*
* @return N/A
*/
static inline void _ScbBusFaultAllFaultsReset(void)
{
__scs.scb.cfsr.byte.bfsr.val = 0xfe;
}
/**
*
* @brief Find out if a bus fault is a stacking fault
*
* This routine determines if a bus fault is a stacking fault.
* This may occurs upon exception entry.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsStacking(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.stkerr;
}
/**
*
* @brief Find out if a bus fault is an unstacking fault
*
* This routine determines if a bus fault is an unstacking fault.
* This may occur upon exception exit.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsUnstacking(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.unstkerr;
}
/**
*
* @brief Find out if a bus fault is an imprecise error
*
* This routine determines if a bus fault is an imprecise error.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsImprecise(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.impreciserr;
}
/**
*
* @brief Find out if a bus fault is an precise error
*
* Read the BFAR register via _ScbBusFaultAddrGet() if this routine returns 1,
* as it will contain the faulting address.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsPrecise(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.preciserr;
}
/**
*
* @brief Find out if a bus fault is an instruction bus error
*
* This routine determines if a bus fault is an instruction bus error.
* It is signalled only if the instruction is issued.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbBusFaultIsInstrBusErr(void)
{
return !!__scs.scb.cfsr.byte.bfsr.bit.ibuserr;
}
/**
*
* @brief Get the faulting address on a precise bus fault
*
* This routine returns the faulting address for a precise bus fault.
*
* @return the faulting address
*/
static inline uint32_t _ScbBusFaultAddrGet(void)
{
return __scs.scb.bfar;
}
/**
*
* @brief Find out if a hard fault is a usage fault
*
* This routine determines if a hard fault is a usage fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbIsUsageFault(void)
{
return !!__scs.scb.cfsr.byte.ufsr.val;
}
/**
*
* @brief Find out if a usage fault is a 'divide by zero' fault
*
* This routine determines if a usage fault is a 'divide by zero' fault.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsDivByZero(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.divbyzero;
}
/**
*
* @brief Find out if a usage fault is a unaligned access error
*
* This routine determines if a usage fault is an unaligned access error.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsUnaligned(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.unaligned;
}
/**
*
* @brief Find out if a usage fault is a co-processor access error
*
* This routine determines if a usage fault is caused by a co-processor access.
* This happens if the co-processor is either absent or disabled.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsNoCp(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.nocp;
}
/**
*
* @brief Find out if a usage fault is a invalid PC load error
*
* Happens if the the instruction address on an exception return is not
* halfword-aligned.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsInvalidPcLoad(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.invpc;
}
/**
*
* @brief Find out if a usage fault is a invalid state error
*
* Happens if the the instruction address loaded in the PC via a branch, LDR or
* POP, or if the instruction address installed in a exception vector, does not
* have bit 0 set; i.e, is not halfword-aligned.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsInvalidState(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.invstate;
}
/**
*
* @brief Find out if a usage fault is a undefined instruction error
*
* The processor tried to execute an invalid opcode.
*
* @return 1 if so, 0 otherwise
*/
static inline int _ScbUsageFaultIsUndefinedInstr(void)
{
return !!__scs.scb.cfsr.byte.ufsr.bit.undefinstr;
}
/**
*
* @brief Clear all usage faults (UFSR register)
*
* CFSR/UFSR register is a 'write-one-to-clear' (W1C) register.
*
* @return N/A
*/
static inline void _ScbUsageFaultAllFaultsReset(void)
{
__scs.scb.cfsr.byte.ufsr.val = 0xffff;
}
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* _SCB__H_ */

View file

@ -1,598 +0,0 @@
/*
* Copyright (c) 2013-2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ARM CORTEX-M System Control Space
*
* Define the System Control Space for the CORTEX-M series of processors and
* provide an interface for miscellaneous SCS functionalities.
*
* All register and bit-field names come from the
*
* Cortex-M3 Devices
* Generic User Guide
* ARM DUI 0552A (ID121610)
*
* and
*
* Cortex-M3
* Revision r2p1
* Technical Reference Manual
* ARM DDI 0337I (ID072410)
*
* documents from ARM.
*
* The API does not account for all possible usages of the SCS, only the
* functionalities needed by the kernel. It does not contain NVIC and
* SCB functionalities either: these can be found in nvic.h and scb.h.
*
* MPU functionalities are not implemented.
*
* The same effect can be achieved by directly writing in the registers of the
* SCS, using the __scs data structure (or hardcoded values), but the APIs found
* here are less error-prone, especially for registers with multiple instances
* to account for 16 exceptions.
*
* If access to a missing functionality is needed, directly writing to the
* registers is the way to implement it.
*
* Note that the 'stir' register, even if not in the 'nvic' part of the SCB, is
* still considered part of the NVIC and an API for it is provided in nvic.h.
*/
#ifndef _SCS__H_
#define _SCS__H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASMLANGUAGE
#include <arch/arm/cortex_m/memory_map.h>
#else /* _ASMLANGUAGE */
#include <kernel.h>
#include <arch/cpu.h>
#include <stdint.h>
union __ictr {
uint32_t val;
struct {
uint32_t intlinesnum : 4 __packed;
uint32_t rsvd__4_31 : 28 __packed;
} bit;
};
union __actlr {
uint32_t val;
struct {
uint32_t dismcycint : 1 __packed;
uint32_t disdefwbuf : 1 __packed;
uint32_t disfold : 1 __packed;
uint32_t rsvd__3_31 : 28 __packed;
} bit;
};
union __stcsr {
uint32_t val;
struct {
uint8_t enable : 1 __packed;
uint8_t tickint : 1 __packed;
uint8_t clksource : 1 __packed;
uint16_t rsvd__3_15 : 13 __packed;
uint16_t countflag : 1 __packed;
uint16_t rsvd__17_31 : 15 __packed;
} bit;
};
union __cpuid {
uint32_t val;
struct {
uint32_t revision : 4 __packed;
uint32_t partno : 12 __packed;
uint32_t constant : 4 __packed;
uint32_t variant : 4 __packed;
uint32_t implementer : 8 __packed;
} bit;
};
union __icsr {
uint32_t val;
struct {
#if defined(CONFIG_ARMV6_M)
uint32_t vectactive : 9 __packed;
uint32_t rsvd__9_10_11 : 3 __packed;
uint32_t vectpending : 9 __packed;
uint32_t rsvd__21 : 1 __packed;
#elif defined(CONFIG_ARMV7_M)
uint32_t vectactive : 10 __packed;
uint32_t rsvd__10 : 1 __packed;
uint32_t rettobase : 1 __packed;
uint32_t vectpending : 10 __packed;
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
uint32_t isrpending : 1 __packed;
uint32_t rsvd__23 : 1 __packed;
uint32_t rsvd__24 : 1 __packed;
uint32_t pendstclr : 1 __packed;
uint32_t pendstset : 1 __packed;
uint32_t pendsvclr : 1 __packed;
uint32_t pendsvset : 1 __packed;
uint32_t rsvd__29_30 : 2 __packed;
uint32_t nmipendset : 1 __packed;
} bit;
};
union __vtor {
uint32_t val;
struct {
uint32_t rsvd__0_6 : 7 __packed;
uint32_t tbloff : 22 __packed;
uint32_t tblbase : 1 __packed;
uint32_t rsvd__30_31 : 2 __packed;
} bit;
};
union __aircr {
uint32_t val;
struct {
#if defined(CONFIG_ARMV6_M)
uint32_t rsvd__0 : 1 __packed;
#elif defined(CONFIG_ARMV7_M)
uint32_t vecreset : 1 __packed; /* WO */
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
uint32_t vectclractive : 1 __packed; /* WO */
uint32_t sysresetreq : 1 __packed; /* WO */
#if defined(CONFIG_ARMV6_M)
uint32_t rsvd__3_14 : 12 __packed;
#elif defined(CONFIG_ARMV7_M)
uint32_t rsvd__3_7 : 5 __packed;
uint32_t prigroup : 3 __packed;
uint32_t rsvd__11_14 : 4 __packed;
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
uint32_t endianness : 1 __packed; /* RO */
uint32_t vectkey : 16 __packed;
} bit;
};
union __scr {
uint32_t val;
struct {
uint32_t rsvd__0 : 1 __packed;
uint32_t sleeponexit : 1 __packed;
uint32_t sleepdeep : 1 __packed;
uint32_t rsvd__3 : 1 __packed;
uint32_t sevonpend : 1 __packed;
uint32_t rsvd__5_31 : 27 __packed;
} bit;
};
#define _SCB_CCR_DIV_0_TRP (1 << 4)
#define _SCB_CCR_UNALIGN_TRP (1 << 3)
union __ccr {
uint32_t val;
struct {
#if defined(CONFIG_ARMV6_M)
uint32_t rsvd_0_2 : 3 __packed;
#elif defined(CONFIG_ARMV7_M)
uint32_t nonbasethrdena : 1 __packed;
uint32_t usersetmpend : 1 __packed;
uint32_t rsvd__2 : 1 __packed;
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
uint32_t unalign_trp : 1 __packed;
#if defined(CONFIG_ARMV6_M)
uint32_t rsvd_4_8 : 5 __packed;
#elif defined(CONFIG_ARMV7_M)
uint32_t div_0_trp : 1 __packed;
uint32_t rsvd__5_7 : 3 __packed;
uint32_t bfhfnmign : 1 __packed;
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
uint32_t stkalign : 1 __packed;
uint32_t rsvd__10_31 : 22 __packed;
} bit;
};
union __shcsr {
uint32_t val;
struct {
uint32_t memfaultact : 1 __packed;
uint32_t busfaultact : 1 __packed;
uint32_t rsvd__2 : 1 __packed;
uint32_t usgfaultact : 1 __packed;
uint32_t rsvd__4_6 : 3 __packed;
uint32_t svcallact : 1 __packed;
uint32_t monitoract : 1 __packed;
uint32_t rsvd__9 : 1 __packed;
uint32_t pendsvact : 1 __packed;
uint32_t systickact : 1 __packed;
uint32_t usgfaultpended : 1 __packed;
uint32_t memfaultpended : 1 __packed;
uint32_t busfaultpended : 1 __packed;
uint32_t svcallpended : 1 __packed;
uint32_t memfaultena : 1 __packed;
uint32_t busfaultena : 1 __packed;
uint32_t usgfaultena : 1 __packed;
uint32_t rsvd__19_31 : 13 __packed;
} bit;
};
union __cfsr {
uint32_t val;
struct {
union {
uint8_t val;
struct {
uint8_t iaccviol : 1 __packed;
uint8_t daccviol : 1 __packed;
uint8_t rsvd__2 : 1 __packed;
uint8_t munstkerr : 1 __packed;
uint8_t mstkerr : 1 __packed;
uint8_t rsvd__5_6 : 2 __packed;
uint8_t mmarvalid : 1 __packed;
} bit;
} mmfsr;
union {
uint8_t val;
struct {
uint8_t ibuserr : 1 __packed;
uint8_t preciserr : 1 __packed;
uint8_t impreciserr : 1 __packed;
uint8_t unstkerr : 1 __packed;
uint8_t stkerr : 1 __packed;
uint8_t rsvd__5_6 : 2 __packed;
uint8_t bfarvalid : 1 __packed;
} bit;
} bfsr;
union {
uint16_t val;
struct {
uint16_t undefinstr : 1 __packed;
uint16_t invstate : 1 __packed;
uint16_t invpc : 1 __packed;
uint16_t nocp : 1 __packed;
uint16_t rsvd__4_7 : 4 __packed;
uint16_t unaligned : 1 __packed;
uint16_t divbyzero : 1 __packed;
uint16_t rsvd__10_15 : 6 __packed;
} bit;
} ufsr;
} byte;
};
union __hfsr {
uint32_t val;
struct {
uint32_t rsvd__0 : 1 __packed;
uint32_t vecttbl : 1 __packed;
uint32_t rsvd__2_29 : 28 __packed;
uint32_t forced : 1 __packed;
uint32_t debugevt : 1 __packed;
} bit;
};
union __mpu_type {
uint32_t val;
struct {
uint32_t separate : 1 __packed;
uint32_t rsvd__1_7 : 7 __packed;
uint32_t dregion : 8 __packed;
uint32_t iregion : 8 __packed;
uint32_t rsvd__24_31 : 8 __packed;
} bit;
};
union __mpu_ctrl {
uint32_t val;
struct {
uint32_t enable : 1 __packed;
uint32_t hfnmiena : 1 __packed;
uint32_t privdefena : 1 __packed;
uint32_t rsvd__24_31 : 29 __packed;
} bit;
};
union __mpu_rnr {
uint32_t val;
struct {
uint32_t region : 8 __packed;
uint32_t rsvd__24_31 : 24 __packed;
} bit;
};
union __mpu_rbar {
uint32_t val;
struct {
uint8_t region : 4 __packed;
uint8_t valid : 1 __packed;
uint32_t addr : 27 __packed;
} bit;
};
union __mpu_rasr {
uint32_t val;
struct {
uint32_t enable : 1 __packed;
uint32_t size : 5 __packed;
uint32_t rsvd__6_7 : 2 __packed;
uint32_t srd : 8 __packed;
uint32_t b : 1 __packed;
uint32_t c : 1 __packed;
uint32_t s : 1 __packed;
uint32_t tex : 3 __packed;
uint32_t rsvd__22_23 : 2 __packed;
uint32_t ap : 3 __packed;
uint32_t rsvd__27 : 1 __packed;
uint32_t xn : 1 __packed;
uint32_t rsvd__29_31 : 3 __packed;
} bit;
};
union __cpacr { /* Coprocessor Access Control Register */
uint32_t val;
struct {
uint32_t rsvd__0_19 : 20 __packed;
uint32_t cp10 : 2 __packed;
uint32_t cp11 : 2 __packed;
uint32_t rsvd__24_31 : 8 __packed;
} bit;
};
/* CP10 Access Bits */
#define _SCS_CPACR_CP10_Pos 20U
#define _SCS_CPACR_CP10_Msk (3UL << _SCS_CPACR_CP10_Pos)
#define _SCS_CPACR_CP10_NO_ACCESS (0UL << _SCS_CPACR_CP10_Pos)
#define _SCS_CPACR_CP10_PRIV_ACCESS (1UL << _SCS_CPACR_CP10_Pos)
#define _SCS_CPACR_CP10_RESERVED (2UL << _SCS_CPACR_CP10_Pos)
#define _SCS_CPACR_CP10_FULL_ACCESS (3UL << _SCS_CPACR_CP10_Pos)
/* CP11 Access Bits */
#define _SCS_CPACR_CP11_Pos 22U
#define _SCS_CPACR_CP11_Msk (3UL << _SCS_CPACR_CP11_Pos)
#define _SCS_CPACR_CP11_NO_ACCESS (0UL << _SCS_CPACR_CP11_Pos)
#define _SCS_CPACR_CP11_PRIV_ACCESS (1UL << _SCS_CPACR_CP11_Pos)
#define _SCS_CPACR_CP11_RESERVED (2UL << _SCS_CPACR_CP11_Pos)
#define _SCS_CPACR_CP11_FULL_ACCESS (3UL << _SCS_CPACR_CP11_Pos)
union __fpu_ccr { /* FPU Context Control Register */
uint32_t val;
struct {
uint32_t lspact : 1 __packed;
uint32_t user : 1 __packed;
uint32_t rsvd__2 : 1 __packed;
uint32_t thread : 1 __packed;
uint32_t hfrdy : 1 __packed;
uint32_t mmrdy : 1 __packed;
uint32_t bfrdy : 1 __packed;
uint32_t rsvd__7 : 1 __packed;
uint32_t monrdy : 1 __packed;
uint32_t rsvd__9_29 : 21 __packed;
uint32_t lspen : 1 __packed;
uint32_t aspen : 1 __packed;
} bit;
};
#define _SCS_FPU_CCR_ASPEN_Pos 31U
#define _SCS_FPU_CCR_ASPEN_Msk (1UL << _SCS_FPU_CCR_ASPEN_Pos)
#define _SCS_FPU_CCR_ASPEN_ENABLE (1UL << _SCS_FPU_CCR_ASPEN_Pos)
#define _SCS_FPU_CCR_ASPEN_DISABLE (0UL << _SCS_FPU_CCR_ASPEN_Pos)
#define _SCS_FPU_CCR_LSPEN_Pos 30U
#define _SCS_FPU_CCR_LSPEN_Msk (1UL << _SCS_FPU_CCR_LSPEN_Pos)
#define _SCS_FPU_CCR_LSPEN_ENABLE (1UL << _SCS_FPU_CCR_LSPEN_Pos)
#define _SCS_FPU_CCR_LSPEN_DISABLE (0UL << _SCS_FPU_CCR_LSPEN_Pos)
union __fpu_car { /* FPU Context Address Register */
uint32_t val;
struct {
uint32_t rsvd__0_2 : 3 __packed;
uint32_t address : 29 __packed;
} bit;
};
union __fpu_scr { /* FPU Status Control Register */
uint32_t val;
struct {
uint32_t ioc : 1 __packed;
uint32_t dzc : 1 __packed;
uint32_t ofc : 1 __packed;
uint32_t ufc : 1 __packed;
uint32_t ixc : 1 __packed;
uint32_t rsvd__5_6 : 2 __packed;
uint32_t idc : 1 __packed;
uint32_t rsvd__8_21 : 14 __packed;
uint32_t rmode : 2 __packed;
uint32_t fz : 1 __packed;
uint32_t dn : 1 __packed;
uint32_t ahp : 1 __packed;
uint32_t rsvd__27 : 1 __packed;
uint32_t v : 1 __packed;
uint32_t c : 1 __packed;
uint32_t z : 1 __packed;
uint32_t n : 1 __packed;
} bit;
};
union __fpu_dscr { /* FPU Default Status Control Register */
uint32_t val;
struct {
uint32_t rsvd__0_21 : 22 __packed;
uint32_t rmode : 2 __packed;
uint32_t fz : 1 __packed;
uint32_t dn : 1 __packed;
uint32_t ahp : 1 __packed;
uint32_t rsvd__27_31 : 5 __packed;
} bit;
};
struct __scs {
uint32_t rsvd__MasterControlRegister;
union __ictr ictr; /* 0x004 Interrupt Controller Type Register */
union __actlr actlr; /* 0x008 Auxiliary ConTroL Register */
uint32_t rsvd__00c_00f;
/* system ticker (SYSTICK) */
struct {
union __stcsr stcsr; /* 0x10 Control and Status Register */
uint32_t strvr; /* 0x14 Reload Value Register (low 24 bits) */
uint32_t stcvr; /* 0x18 Current Value Register (low 24 bits) */
uint32_t stcr; /* 0x1c Calibration value Register */
} systick; /* offset: 0x010, size 0x10 */
uint32_t rsvd__020_0ff[(0x100 - 0x20) / 4];
/* Nested Vector Interrupt Controller (NVIC)
*
* Each block of 8 32-bit words could in theory support 256 IRQs, but
* the architecture only supports IRQs 0 -> 239.
*/
struct {
uint32_t iser[8]; /* 0x100 Interrupt Set-Enable Registers */
uint32_t rsvd__120_17f[24];
uint32_t icer[8]; /* 0x180 Interrupt Clear-Enable Registers */
uint32_t rsvd__1a0_1ff[24];
uint32_t ispr[8]; /* 0x200 Interrupt Set-Pending Registers */
uint32_t rsvd__220_27f[24];
uint32_t icpr[8]; /* 0x280 Interrupt Clear-Pending Registers */
uint32_t rsvd__2a0_2ff[24];
uint32_t iabr[8]; /* 0x300 Interrupt Active-Bit Registers */
uint32_t rsvd__320_37f[24];
uint32_t rsvd__380_3ff[32];
#if defined(CONFIG_ARMV6_M)
uint32_t ipr[8];
uint32_t rsvd__420_4ff[56];
#elif defined(CONFIG_ARMV7_M)
uint8_t ipr[240]; /* 0x400 Interrupt Priority Registers */
uint32_t rsvd__4f0_4ff[4];
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
} nvic; /* offset: 0x100, size 0x400 */
uint32_t rsvd__500_cff[(0xd00 - 0x500) / 4];
/* System Control Block (SCB) */
struct {
union __cpuid cpuid; /* 0xd00 CPUID register */
union __icsr icsr; /* 0xd04 IRQ Control and Start Register */
#if defined(CONFIG_ARMV6_M)
uint32_t rsvd_9_12;
#elif defined(CONFIG_ARMV7_M)
union __vtor vtor; /* 0xd08 Vector Table Offset Register */
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
union __aircr
aircr; /* 0xd0c App IRQ and Reset Control Register */
union __scr scr; /* 0xd10 System Control Register */
union __ccr ccr; /* 0xd14 Configuration and Control Register */
#if defined(CONFIG_ARMV6_M)
uint32_t rsvd_24_27;
uint32_t shpr[2];
#elif defined(CONFIG_ARMV7_M)
uint8_t shpr[12]; /* 0xd18 System Handler Priority Registers
* Use ('exception number' - 4) to
* get index into array
*/
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
union __shcsr
shcsr; /* 0xd24 Sys Handler Control and State Reg */
#if defined(CONFIG_ARMV6_M)
uint32_t rsvd_40_63[6];
#elif defined(CONFIG_ARMV7_M)
union __cfsr cfsr; /* 0xd28 Configurable Fault Status Register
*/
union __hfsr hfsr; /* 0xd2C Hard Fault Status Register */
uint32_t dfsr; /* 0xd30 Debug Fault Status Register */
uint32_t mmfar; /* 0xd34 MemManage Fault Address Register */
uint32_t bfar; /* 0xd38 BusFault Address Register */
uint32_t afsr; /* 0xd3C Aux Fault Status Register */
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
} scb; /* offset: 0xd00, size 0x040 */
/*
* d40 -> d7f: processor feature ID registers (pp.778-779 in DDI0403D)
*/
uint32_t rsvd__d40_d87[(0xd88 - 0xd40) / 4];
union __cpacr cpacr; /* 0xd88 Coprocessor Access Control Reg */
uint32_t rsvd__d8c_d8f;
/* Memory Protection Unit (MPU) */
struct { /* 0xD90-0xDA3 */
union __mpu_type mpu_type; /* 0xd90 RO TYPE register */
union __mpu_ctrl mpu_ctrl; /* 0xd94 RW ConTRoL register */
union __mpu_rnr mpu_rnr; /* 0xd98 RW Region Number Register */
union __mpu_rbar mpu_rbar; /* 0xd9c RW Region Base Addr Reg. */
union __mpu_rasr mpu_rasr; /* 0xda0 RW Region Attr and Size
* Reg.
*/
union __mpu_rbar mpu_rbar_a1; /* 0xda4 RW alias of mpu_rbar */
union __mpu_rasr mpu_rasr_a1; /* 0xda8 RW alias of mpu_rasr */
union __mpu_rbar mpu_rbar_a2; /* 0xdac RW alias of mpu_rbar */
union __mpu_rasr mpu_rasr_a2; /* 0xdb0 RW alias of mpu_rasr */
union __mpu_rbar mpu_rbar_a3; /* 0xdb4 RW alias of mpu_rbar */
union __mpu_rasr mpu_rasr_a3; /* 0xdb8 RW alias of mpu_rasr */
} mpu; /* offset: 0xd90, size: 0x02c */
uint32_t rsvd__da4_eff[(0xf00 - 0xdbc) / 4];
/* 0xf00 WO SW Trigger IRQ Reg. (bit 0-8/IRQ 0-239 only) */
uint32_t stir;
uint32_t rsvd__f04_f33[(0xf34 - 0xF04) / 4];
struct { /* 0xF34-F3F */
union __fpu_ccr ccr; /* 0xf34 Context Control Reg */
union __fpu_car car; /* 0xf38 Context Address Reg */
union __fpu_dscr dscr; /* 0xf3c Default Status Control Reg */
} fpu; /* offset: 0xf34, size: 0x0c */
uint32_t rsvd__f40_fff[(0x1000 - 0xf40) / 4];
};
/* the linker always puts this object at 0xe000e000 */
extern volatile struct __scs __scs;
#if defined(CONFIG_ARMV6_M)
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and masks */
#define _PRIO_BIT_SHIFT(IRQn) (((((uint32_t)(IRQn))) & 0x03UL) * 8UL)
#define _PRIO_SHP_IDX(IRQn) ((((((uint32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL))
#define _PRIO_IP_IDX(IRQn) ((((uint32_t)(IRQn)) >> 2UL))
#elif defined(CONFIG_ARMV7_M)
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M */
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* _SCS__H_ */

View file

@ -2,6 +2,7 @@
* Copyright (c) 2016 Open-RnD Sp. z o.o. * Copyright (c) 2016 Open-RnD Sp. z o.o.
* Copyright (c) 2016 BayLibre, SAS * Copyright (c) 2016 BayLibre, SAS
* Copyright (c) 2016 RnDity Sp. z o.o. * Copyright (c) 2016 RnDity Sp. z o.o.
* Copyright (c) 2017 Linaro Limited.
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -15,12 +16,24 @@
#ifdef CONFIG_SOC_SERIES_STM32F1X #ifdef CONFIG_SOC_SERIES_STM32F1X
#include "stm32f1_clock_control.h" #include "stm32f1_clock_control.h"
#elif CONFIG_SOC_SERIES_STM32F3X
#include "stm32f3_clock_control.h"
#elif CONFIG_SOC_SERIES_STM32F4X #elif CONFIG_SOC_SERIES_STM32F4X
#include "stm32f4_clock_control.h" #include "stm32f4_clock_control.h"
#elif CONFIG_SOC_SERIES_STM32L4X
#include "stm32l4x_clock_control.h"
#endif #endif
/* Bus */
enum {
STM32_CLOCK_BUS_AHB1,
STM32_CLOCK_BUS_AHB2,
STM32_CLOCK_BUS_APB1,
#ifdef CONFIG_SOC_SERIES_STM32L4X
STM32_CLOCK_BUS_APB1_2,
#endif
STM32_CLOCK_BUS_APB2,
};
struct stm32_pclken {
uint32_t bus;
uint32_t enr;
};
#endif /* _STM32_CLOCK_CONTROL_H_ */ #endif /* _STM32_CLOCK_CONTROL_H_ */

View file

@ -1,114 +0,0 @@
/*
* Copyright (c) 2016 RnDity Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32F3_CLOCK_CONTROL_H_
#define _STM32F3_CLOCK_CONTROL_H_
/**
* @file
*
* @brief Clock subsystem IDs for STM32F3 family
*/
/* APB1 */
#define STM32F3X_CLOCK_SUBSYS_TIM2 (1 << 0)
#define STM32F3X_CLOCK_SUBSYS_TIM3 (1 << 1)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_TIM4 (1 << 2)
#endif
#ifdef CONFIG_SOC_STM32F373XC
#define STM32F3X_CLOCK_SUBSYS_TIM5 (1 << 3)
#endif
#define STM32F3X_CLOCK_SUBSYS_TIM6 (1 << 4)
#define STM32F3X_CLOCK_SUBSYS_TIM7 (1 << 5)
#ifdef CONFIG_SOC_STM32F373XC
#define STM32F3X_CLOCK_SUBSYS_TIM12 (1 << 6)
#define STM32F3X_CLOCK_SUBSYS_TIM13 (1 << 7)
#define STM32F3X_CLOCK_SUBSYS_TIM14 (1 << 8)
#define STM32F3X_CLOCK_SUBSYS_TIM18 (1 << 9)
#endif
#define STM32F3X_CLOCK_SUBSYS_WWDG (1 << 11)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_SPI2 (1 << 14)
#define STM32F3X_CLOCK_SUBSYS_SPI3 (1 << 15)
#endif
#define STM32F3X_CLOCK_SUBSYS_USART2 (1 << 17)
#define STM32F3X_CLOCK_SUBSYS_USART3 (1 << 18)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_UART4 (1 << 19)
#define STM32F3X_CLOCK_SUBSYS_UART5 (1 << 20)
#endif
#define STM32F3X_CLOCK_SUBSYS_I2C1 (1 << 21)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_I2C2 (1 << 22)
#define STM32F3X_CLOCK_SUBSYS_USB (1 << 23)
#endif
#define STM32F3X_CLOCK_SUBSYS_CAN (1 << 25)
#define STM32F3X_CLOCK_SUBSYS_DAC2 (1 << 26)
#define STM32F3X_CLOCK_SUBSYS_PWR (1 << 28)
#define STM32F3X_CLOCK_SUBSYS_DAC1 (1 << 29)
#define STM32F3X_CLOCK_APB2_BASE (1 << 30)
/* APB2 */
#define STM32F3X_CLOCK_SUBSYS_SYSCFG (STM32F3X_CLOCK_APB2_BASE | 1 << 0)
#ifndef CONFIG_SOC_STM32F373XC
#define STM32F3X_CLOCK_SUBSYS_TIM1 (STM32F3X_CLOCK_APB2_BASE | 1 << 11)
#endif
#define STM32F3X_CLOCK_SUBSYS_SPI1 (STM32F3X_CLOCK_APB2_BASE | 1 << 12)
#ifdef CONFIG_SOC_STM32F303XC
#define STM32F3X_CLOCK_SUBSYS_TIM8 (STM32F3X_CLOCK_APB2_BASE | 1 << 13)
#endif
#define STM32F3X_CLOCK_SUBSYS_USART1 (STM32F3X_CLOCK_APB2_BASE | 1 << 14)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_SPI4 (STM32F3X_CLOCK_APB2_BASE | 1 << 15)
#endif
#define STM32F3X_CLOCK_SUBSYS_TIM15 (STM32F3X_CLOCK_APB2_BASE | 1 << 16)
#define STM32F3X_CLOCK_SUBSYS_TIM16 (STM32F3X_CLOCK_APB2_BASE | 1 << 17)
#define STM32F3X_CLOCK_SUBSYS_TIM17 (STM32F3X_CLOCK_APB2_BASE | 1 << 18)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_TIM19 (STM32F3X_CLOCK_APB2_BASE | 1 << 19)
#endif
#ifdef CONFIG_SOC_STM32F303XC
#define STM32F3X_CLOCK_SUBSYS_TIM20 (STM32F3X_CLOCK_APB2_BASE | 1 << 20)
#endif
#ifdef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_HRTIMER1 (STM32F3X_CLOCK_APB2_BASE | 1 << 29)
#endif
#define STM32F3X_CLOCK_AHB_BASE (1 << 31)
/* AHB */
#define STM32F3X_CLOCK_SUBSYS_DMA1 (STM32F3X_CLOCK_AHB_BASE | 1 << 0)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_DMA2 (STM32F3X_CLOCK_AHB_BASE | 1 << 1)
#endif
#define STM32F3X_CLOCK_SUBSYS_SRAM (STM32F3X_CLOCK_AHB_BASE | 1 << 2)
#define STM32F3X_CLOCK_SUBSYS_FLITF (STM32F3X_CLOCK_AHB_BASE | 1 << 4)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_FMC (STM32F3X_CLOCK_AHB_BASE | 1 << 5)
#endif
#define STM32F3X_CLOCK_SUBSYS_CRC (STM32F3X_CLOCK_AHB_BASE | 1 << 6)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_IOPH (STM32F3X_CLOCK_AHB_BASE | 1 << 16)
#endif
#define STM32F3X_CLOCK_SUBSYS_IOPA (STM32F3X_CLOCK_AHB_BASE | 1 << 17)
#define STM32F3X_CLOCK_SUBSYS_IOPB (STM32F3X_CLOCK_AHB_BASE | 1 << 18)
#define STM32F3X_CLOCK_SUBSYS_IOPC (STM32F3X_CLOCK_AHB_BASE | 1 << 19)
#define STM32F3X_CLOCK_SUBSYS_IOPD (STM32F3X_CLOCK_AHB_BASE | 1 << 20)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_IOPE (STM32F3X_CLOCK_AHB_BASE | 1 << 21)
#endif
#define STM32F3X_CLOCK_SUBSYS_IOPF (STM32F3X_CLOCK_AHB_BASE | 1 << 22)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_IOPG (STM32F3X_CLOCK_AHB_BASE | 1 << 23)
#endif
#define STM32F3X_CLOCK_SUBSYS_TSC (STM32F3X_CLOCK_AHB_BASE | 1 << 24)
#define STM32F3X_CLOCK_SUBSYS_ADC12 (STM32F3X_CLOCK_AHB_BASE | 1 << 28)
#ifndef CONFIG_SOC_STM32F334X8
#define STM32F3X_CLOCK_SUBSYS_ADC34 (STM32F3X_CLOCK_AHB_BASE | 1 << 29)
#endif
#endif /* _STM32F3_CLOCK_CONTROL_H_ */

View file

@ -1,101 +0,0 @@
/*
* Copyright (c) 2016 Open-RnD Sp. z o.o.
* Copyright (c) 2016 BayLibre, SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _STM32L4X_CLOCK_CONTROL_H_
#define _STM32L4X_CLOCK_CONTROL_H_
/**
* @file
*
* @brief Clock subsystem IDs for STM32L4 family
*/
enum {
STM32L4X_CLOCK_AHB1_BASE = 0,
STM32L4X_CLOCK_AHB2_BASE,
STM32L4X_CLOCK_AHB3_BASE,
STM32L4X_CLOCK_APB1_1_BASE,
STM32L4X_CLOCK_APB1_2_BASE,
STM32L4X_CLOCK_APB2_BASE,
STM32L4X_CLOCK_BASE_COUNT,
};
#define STM32L4X_CLOCK_ID(_base, id) \
((STM32L4X_CLOCK_##_base##_BASE << 16) + id)
#define STM32L4X_CLOCK_BASE(num) ((num) >> 16)
#define STM32L4X_CLOCK_BIT(num) ((num) & 0xFFFF)
enum {
/* AHB1 */
STM32L4X_CLOCK_SUBSYS_DMA1 = STM32L4X_CLOCK_ID(AHB1, 0),
STM32L4X_CLOCK_SUBSYS_DMA2 = STM32L4X_CLOCK_ID(AHB1, 1),
STM32L4X_CLOCK_SUBSYS_FLASH = STM32L4X_CLOCK_ID(AHB1, 8),
STM32L4X_CLOCK_SUBSYS_CRC = STM32L4X_CLOCK_ID(AHB1, 12),
STM32L4X_CLOCK_SUBSYS_TSC = STM32L4X_CLOCK_ID(AHB1, 16),
/* AHB2 */
STM32L4X_CLOCK_SUBSYS_GPIOA = STM32L4X_CLOCK_ID(AHB2, 0),
STM32L4X_CLOCK_SUBSYS_GPIOB = STM32L4X_CLOCK_ID(AHB2, 1),
STM32L4X_CLOCK_SUBSYS_GPIOC = STM32L4X_CLOCK_ID(AHB2, 2),
STM32L4X_CLOCK_SUBSYS_GPIOD = STM32L4X_CLOCK_ID(AHB2, 3),
STM32L4X_CLOCK_SUBSYS_GPIOE = STM32L4X_CLOCK_ID(AHB2, 4),
STM32L4X_CLOCK_SUBSYS_GPIOF = STM32L4X_CLOCK_ID(AHB2, 5),
STM32L4X_CLOCK_SUBSYS_GPIOG = STM32L4X_CLOCK_ID(AHB2, 6),
STM32L4X_CLOCK_SUBSYS_GPIOH = STM32L4X_CLOCK_ID(AHB2, 7),
STM32L4X_CLOCK_SUBSYS_OTGFS = STM32L4X_CLOCK_ID(AHB2, 12),
STM32L4X_CLOCK_SUBSYS_ADC = STM32L4X_CLOCK_ID(AHB2, 13),
STM32L4X_CLOCK_SUBSYS_AES = STM32L4X_CLOCK_ID(AHB2, 16),
STM32L4X_CLOCK_SUBSYS_RNG = STM32L4X_CLOCK_ID(AHB2, 18),
/* AHB3 */
STM32L4X_CLOCK_SUBSYS_FMC = STM32L4X_CLOCK_ID(AHB3, 0),
STM32L4X_CLOCK_SUBSYS_QSPI = STM32L4X_CLOCK_ID(AHB3, 0),
/* APB1 */
STM32L4X_CLOCK_SUBSYS_TIM2 = STM32L4X_CLOCK_ID(APB1_1, 0),
STM32L4X_CLOCK_SUBSYS_TIM3 = STM32L4X_CLOCK_ID(APB1_1, 1),
STM32L4X_CLOCK_SUBSYS_TIM4 = STM32L4X_CLOCK_ID(APB1_1, 2),
STM32L4X_CLOCK_SUBSYS_TIM5 = STM32L4X_CLOCK_ID(APB1_1, 3),
STM32L4X_CLOCK_SUBSYS_TIM6 = STM32L4X_CLOCK_ID(APB1_1, 4),
STM32L4X_CLOCK_SUBSYS_TIM7 = STM32L4X_CLOCK_ID(APB1_1, 5),
STM32L4X_CLOCK_SUBSYS_LCD = STM32L4X_CLOCK_ID(APB1_1, 9),
STM32L4X_CLOCK_SUBSYS_WWDG = STM32L4X_CLOCK_ID(APB1_1, 11),
STM32L4X_CLOCK_SUBSYS_SPI2 = STM32L4X_CLOCK_ID(APB1_1, 14),
STM32L4X_CLOCK_SUBSYS_SPI3 = STM32L4X_CLOCK_ID(APB1_1, 15),
STM32L4X_CLOCK_SUBSYS_USART2 = STM32L4X_CLOCK_ID(APB1_1, 17),
STM32L4X_CLOCK_SUBSYS_USART3 = STM32L4X_CLOCK_ID(APB1_1, 18),
STM32L4X_CLOCK_SUBSYS_UART4 = STM32L4X_CLOCK_ID(APB1_1, 19),
STM32L4X_CLOCK_SUBSYS_UART5 = STM32L4X_CLOCK_ID(APB1_1, 20),
STM32L4X_CLOCK_SUBSYS_I2C1 = STM32L4X_CLOCK_ID(APB1_1, 21),
STM32L4X_CLOCK_SUBSYS_I2C2 = STM32L4X_CLOCK_ID(APB1_1, 22),
STM32L4X_CLOCK_SUBSYS_I2C3 = STM32L4X_CLOCK_ID(APB1_1, 23),
STM32L4X_CLOCK_SUBSYS_PWR = STM32L4X_CLOCK_ID(APB1_1, 28),
STM32L4X_CLOCK_SUBSYS_DAC = STM32L4X_CLOCK_ID(APB1_1, 29),
STM32L4X_CLOCK_SUBSYS_OPAMP = STM32L4X_CLOCK_ID(APB1_1, 30),
STM32L4X_CLOCK_SUBSYS_LPTIM1 = STM32L4X_CLOCK_ID(APB1_1, 31),
STM32L4X_CLOCK_SUBSYS_LPUART1 = STM32L4X_CLOCK_ID(APB1_2, 0),
STM32L4X_CLOCK_SUBSYS_SWPMI1 = STM32L4X_CLOCK_ID(APB1_2, 2),
STM32L4X_CLOCK_SUBSYS_LPTIM2 = STM32L4X_CLOCK_ID(APB1_2, 5),
/* APB2 */
STM32L4X_CLOCK_SUBSYS_SYSCFG = STM32L4X_CLOCK_ID(APB2, 0),
STM32L4X_CLOCK_SUBSYS_FW = STM32L4X_CLOCK_ID(APB2, 7),
STM32L4X_CLOCK_SUBSYS_SDMMC1 = STM32L4X_CLOCK_ID(APB2, 10),
STM32L4X_CLOCK_SUBSYS_TIM1 = STM32L4X_CLOCK_ID(APB2, 11),
STM32L4X_CLOCK_SUBSYS_SPI1 = STM32L4X_CLOCK_ID(APB2, 12),
STM32L4X_CLOCK_SUBSYS_TIM8 = STM32L4X_CLOCK_ID(APB2, 13),
STM32L4X_CLOCK_SUBSYS_USART1 = STM32L4X_CLOCK_ID(APB2, 14),
STM32L4X_CLOCK_SUBSYS_TIM15 = STM32L4X_CLOCK_ID(APB2, 16),
STM32L4X_CLOCK_SUBSYS_TIM16 = STM32L4X_CLOCK_ID(APB2, 17),
STM32L4X_CLOCK_SUBSYS_TIM17 = STM32L4X_CLOCK_ID(APB2, 18),
STM32L4X_CLOCK_SUBSYS_SAI1 = STM32L4X_CLOCK_ID(APB2, 21),
STM32L4X_CLOCK_SUBSYS_SAI2 = STM32L4X_CLOCK_ID(APB2, 22),
STM32L4X_CLOCK_SUBSYS_DFSDM1 = STM32L4X_CLOCK_ID(APB2, 24),
};
#endif /* _STM32L4_CLOCK_CONTROL_H_ */

View file

@ -18,7 +18,6 @@
#define __sw_isr_table _GENERIC_SECTION(SW_ISR_TABLE) #define __sw_isr_table _GENERIC_SECTION(SW_ISR_TABLE)
#if defined(CONFIG_ARM) #if defined(CONFIG_ARM)
#define __scs_section __in_section_unique(SCS_SECTION)
#define __scp_section __in_section_unique(SCP_SECTION) #define __scp_section __in_section_unique(SCP_SECTION)
#define __security_frdm_k64f_section __in_section_unique(SECURITY_FRDM_K64F) #define __security_frdm_k64f_section __in_section_unique(SECURITY_FRDM_K64F)
#define __kinetis_flash_config_section __in_section_unique(KINETIS_FLASH_CONFIG) #define __kinetis_flash_config_section __in_section_unique(KINETIS_FLASH_CONFIG)