Merge "Merge arm branch into master"
This commit is contained in:
commit
110df98619
58 changed files with 1532 additions and 2977 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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_ */
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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];
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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_ */
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
|
||||||
}
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
BIN
boards/arm/hexiwear_k64/doc/hexiwear_k64.jpg
Normal file
BIN
boards/arm/hexiwear_k64/doc/hexiwear_k64.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 493 KiB |
273
boards/arm/hexiwear_k64/doc/hexiwear_k64.rst
Normal file
273
boards/arm/hexiwear_k64/doc/hexiwear_k64.rst
Normal 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 sensor’s 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
|
|
@ -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
|
||||||
|
|
BIN
boards/arm/nucleo_l476rg/doc/img/nucleo64_ulp_logo_1024.jpg
Normal file
BIN
boards/arm/nucleo_l476rg/doc/img/nucleo64_ulp_logo_1024.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_arduino.png
Normal file
BIN
boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_arduino.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 551 KiB |
BIN
boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_morpho.png
Normal file
BIN
boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_morpho.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 474 KiB |
239
boards/arm/nucleo_l476rg/doc/nucleol476rg.rst
Normal file
239
boards/arm/nucleo_l476rg/doc/nucleol476rg.rst
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
186
drivers/clock_control/Kconfig.stm32
Normal file
186
drivers/clock_control/Kconfig.stm32
Normal 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
|
|
@ -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
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
295
drivers/clock_control/stm32_ll_clock.c
Normal file
295
drivers/clock_control/stm32_ll_clock.c
Normal 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);
|
16
drivers/clock_control/stm32_ll_clock.h
Normal file
16
drivers/clock_control/stm32_ll_clock.h
Normal 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_ */
|
|
@ -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);
|
|
73
drivers/clock_control/stm32f3x_ll_clock.c
Normal file
73
drivers/clock_control/stm32f3x_ll_clock.c
Normal 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 */
|
||||||
|
}
|
|
@ -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);
|
|
35
drivers/clock_control/stm32l4x_ll_clock.c
Normal file
35
drivers/clock_control/stm32l4x_ll_clock.c
Normal 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 */
|
|
@ -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 = {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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_ */
|
|
|
@ -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_ */
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue