diff options
author | Maureen Helm <maureen.helm@nxp.com> | 2017-02-10 15:21:38 -0600 |
---|---|---|
committer | Maureen Helm <maureen.helm@nxp.com> | 2017-02-10 15:38:11 -0600 |
commit | 3f4f9fa60faa46fa3a3b951316bc64c81fecf78c (patch) | |
tree | e37a2d78e3736a4e738516445320203eedf8ed1c | |
parent | b4b395845a5c4de1a4c3c675df0f14cc777f43ee (diff) | |
parent | 6ca87b576ee3ebb4cca4d20c19332f8d6f9329bc (diff) |
Merge arm branch into master
Main changes:
- Refactor stm32 to use Cube LL clock driver
- Convert arm scb to use direct CMSIS register access
- Add board documentation
----------------------------------------------------------------
Adam Podogrocki (1):
gpio/stm32: fix in setting alternative function
Erwan Gouriou (19):
clock control:stm32: provide STM32Cube LL based driver
gpio: update stm32 gpio to support LL clock control driver
pinmux: update stm32 pinmux to support LL clock control driver
uart: update stm32 uart to support LL clock control driver
i2c: stm32: change deprecated constant
i2c: update stm32 i2c_lx to support LL clock control driver
pwm: update stm32 pwm to support LL clock control driver
flash: update stm32 flash_f3x to support LL clock control driver
soc: stm32l4xx: support of Cube LL Clock driver
soc: stm32f3xx: support of Cube LL Clock driver
board: nucleo_f334r8: enable support of LL Cube clock control driver
board: stm32373c_eval: enable support of LL Cube clock control driver
boards: nucleo_l476rg: enable support of LL Cube clock control driver
soc: stm32l4x: clean up after Cube LL clock control
soc: stm32f3x: clean up after Cube LL clock control
clock control: clean up after stm32cube LL driver
drivers: stm32: clean up after stm23cube based clock control
clock_control: stm32: code optimization
board: add nucleo_l476rg documentation
Kumar Gala (12):
arm: cmsis: Convert _ScbIsNestedExc to use direct CMSIS register access
arm: cmsis: Convert FaultEnable to use direct CMSIS register access
arm: cmsis: Convert _ScbActiveVectorGet to use direct CMSIS register access
arm: cmsis: Convert _ScbHardFaultIsForced to use direct CMSIS register access
arm: cmsis: Convert _ScbDivByZeroFaultEnable to use direct CMSIS register access
arm: cmsis: Convert _Scb*FaultIs* & _ScbIs*Fault to use CMSIS register access
arm: cmsis: Convert _Scb*FaultAddrGet to use direct CMSIS register access
arm: cmsis: Convert printing of MMFSR, BFSR, and UFSR to CMSIS
arm: cmsis: Convert _ClearFaults to use direct CMSIS register access
arm: cmsis: Convert _Scb*Fault*Reset to use direct CMSIS register access
arm: cmsis: cleanup use of _SCS_CPACR_CP1{0,1}_Pos define
arm: cmsis: Remove last bits of scs/scb as we've converted to CMSIS
Maureen Helm (1):
hexiwear_k64: Add RST board documentation
arch/arm/core/cortex_m/Makefile | 2 +-
arch/arm/core/cortex_m/scs.c | 22 --
arch/arm/core/fault.c | 88 +++---
arch/arm/core/fault_s.S | 2 +-
arch/arm/include/cortex_m/exc.h | 18 +-
arch/arm/soc/st_stm32/stm32f3/rcc_registers.h | 89 ------
arch/arm/soc/st_stm32/stm32f3/soc.c | 3 +-
arch/arm/soc/st_stm32/stm32f3/soc.h | 7 +
arch/arm/soc/st_stm32/stm32f3/soc_config.c | 22 --
arch/arm/soc/st_stm32/stm32f3/soc_gpio.c | 9 +-
arch/arm/soc/st_stm32/stm32f3/soc_registers.h | 1 -
arch/arm/soc/st_stm32/stm32l4/rcc_registers.h | 176 -----------
arch/arm/soc/st_stm32/stm32l4/soc.c | 3 +-
arch/arm/soc/st_stm32/stm32l4/soc.h | 7 +
arch/arm/soc/st_stm32/stm32l4/soc_gpio.c | 8 +-
arch/arm/soc/st_stm32/stm32l4/soc_pinmux.c | 20 --
arch/arm/soc/st_stm32/stm32l4/soc_registers.h | 1 -
boards/arm/hexiwear_k64/doc/hexiwear_k64.jpg | Bin 0 -> 504461 bytes
boards/arm/hexiwear_k64/doc/hexiwear_k64.rst | 273 ++++++++++++++++
boards/arm/nucleo_f334r8/nucleo_f334r8_defconfig | 24 +-
boards/arm/nucleo_l476rg/doc/img/nucleo64_ulp_logo_1024.jpg | Bin 0 -> 16731 bytes
boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_arduino.png | Bin 0 -> 564540 bytes
boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_morpho.png | Bin 0 -> 485284 bytes
boards/arm/nucleo_l476rg/doc/nucleol476rg.rst | 239 ++++++++++++++
boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig | 25 +-
boards/arm/stm32373c_eval/stm32373c_eval_defconfig | 24 +-
drivers/clock_control/Kconfig | 6 +-
drivers/clock_control/Kconfig.stm32 | 186 +++++++++++
drivers/clock_control/Kconfig.stm32f3x | 115 -------
drivers/clock_control/Kconfig.stm32l4x | 140 --------
drivers/clock_control/Makefile | 8 +-
drivers/clock_control/stm32_ll_clock.c | 295 +++++++++++++++++
drivers/clock_control/stm32_ll_clock.h | 16 +
drivers/clock_control/stm32f3x_clock.c | 398 -----------------------
drivers/clock_control/stm32f3x_ll_clock.c | 73 +++++
drivers/clock_control/stm32l4x_clock.c | 383 ----------------------
drivers/clock_control/stm32l4x_ll_clock.c | 35 ++
drivers/flash/flash_stm32f3x.c | 9 +-
drivers/flash/flash_stm32f3x.h | 2 +-
drivers/flash/flash_stm32f3x_priv.c | 4 +-
drivers/gpio/gpio_stm32.c | 95 +++---
drivers/gpio/gpio_stm32.h | 32 +-
drivers/i2c/i2c_stm32lx.c | 13 +-
drivers/i2c/i2c_stm32lx.h | 2 +-
drivers/pinmux/stm32/pinmux_stm32.c | 43 ++-
drivers/pwm/pwm_stm32.c | 50 ++-
drivers/pwm/pwm_stm32.h | 6 +-
drivers/serial/uart_stm32.c | 34 +-
drivers/serial/uart_stm32.h | 8 +-
ext/hal/st/stm32cube/Kbuild | 2 +
include/arch/arm/arch.h | 2 -
include/arch/arm/cortex_m/cmsis.h | 69 +++-
include/arch/arm/cortex_m/scb.h | 583 ----------------------------------
include/arch/arm/cortex_m/scs.h | 598 -----------------------------------
include/drivers/clock_control/stm32_clock_control.h | 21 +-
include/drivers/clock_control/stm32f3_clock_control.h | 114 -------
include/drivers/clock_control/stm32l4x_clock_control.h | 101 ------
include/section_tags.h | 1 -
58 files changed, 1531 insertions(+), 2976 deletions(-)
delete mode 100644 arch/arm/core/cortex_m/scs.c
delete mode 100644 arch/arm/soc/st_stm32/stm32f3/rcc_registers.h
delete mode 100644 arch/arm/soc/st_stm32/stm32l4/rcc_registers.h
create mode 100644 boards/arm/hexiwear_k64/doc/hexiwear_k64.jpg
create mode 100644 boards/arm/hexiwear_k64/doc/hexiwear_k64.rst
create mode 100644 boards/arm/nucleo_l476rg/doc/img/nucleo64_ulp_logo_1024.jpg
create mode 100644 boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_arduino.png
create mode 100644 boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_morpho.png
create mode 100644 boards/arm/nucleo_l476rg/doc/nucleol476rg.rst
create mode 100644 drivers/clock_control/Kconfig.stm32
delete mode 100644 drivers/clock_control/Kconfig.stm32f3x
delete mode 100644 drivers/clock_control/Kconfig.stm32l4x
create mode 100644 drivers/clock_control/stm32_ll_clock.c
create mode 100644 drivers/clock_control/stm32_ll_clock.h
delete mode 100644 drivers/clock_control/stm32f3x_clock.c
create mode 100644 drivers/clock_control/stm32f3x_ll_clock.c
delete mode 100644 drivers/clock_control/stm32l4x_clock.c
create mode 100644 drivers/clock_control/stm32l4x_ll_clock.c
delete mode 100644 include/arch/arm/cortex_m/scb.h
delete mode 100644 include/arch/arm/cortex_m/scs.h
delete mode 100644 include/drivers/clock_control/stm32f3_clock_control.h
delete mode 100644 include/drivers/clock_control/stm32l4x_clock_control.h
Change-Id: I0b64f0b663153088e4e16babbf60a546f7b5fbb5
Signed-off-by: Maureen Helm <maureen.helm@nxp.com>
58 files changed, 1531 insertions, 2976 deletions
diff --git a/arch/arm/core/cortex_m/Makefile b/arch/arm/core/cortex_m/Makefile index 8a7c080a7..f908cac07 100644 --- a/arch/arm/core/cortex_m/Makefile +++ b/arch/arm/core/cortex_m/Makefile @@ -6,7 +6,7 @@ ccflags-y +=-I$(srctree)/include/ asflags-y = $(ccflags-y) 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 obj-$(CONFIG_IRQ_VECTOR_TABLE_SOC) += irq_vector_table.o diff --git a/arch/arm/core/cortex_m/scs.c b/arch/arm/core/cortex_m/scs.c deleted file mode 100644 index 74d4bdf80..000000000 --- a/arch/arm/core/cortex_m/scs.c +++ /dev/null @@ -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; diff --git a/arch/arm/core/fault.c b/arch/arm/core/fault.c index 60ca5a0c6..7cc7234c1 100644 --- a/arch/arm/core/fault.c +++ b/arch/arm/core/fault.c @@ -64,33 +64,32 @@ void _FaultDump(const NANO_ESF *esf, int fault) int escalation = 0; if (3 == fault) { /* hard fault */ - escalation = _ScbHardFaultIsForced(); + escalation = SCB->HFSR & SCB_HFSR_FORCED_Msk; PR_EXC("HARD FAULT: %s\n", escalation ? "Escalation (see below)!" : "Bus fault on vector table read\n"); } PR_EXC("MMFSR: 0x%" PRIx32 ", BFSR: 0x%" PRIx32 ", UFSR: 0x%" - PRIx32 "\n", - __scs.scb.cfsr.byte.mmfsr.val, - __scs.scb.cfsr.byte.bfsr.val, - __scs.scb.cfsr.byte.ufsr.val); + PRIx32 "\n", SCB_MMFSR, SCB_BFSR, SCB_MMFSR); - if (_ScbMemFaultIsMmfarValid()) { - PR_EXC("MMFAR: 0x%" PRIx32 "\n", _ScbMemFaultAddrGet()); + if (SCB->CFSR & CFSR_MMARVALID_Msk) { + PR_EXC("MMFAR: 0x%" PRIx32 "\n", SCB->MMFAR); if (escalation) { - _ScbMemFaultMmfarReset(); + /* clear MMAR[VALID] to reset */ + SCB->CFSR &= ~CFSR_MMARVALID_Msk; } } - if (_ScbBusFaultIsBfarValid()) { - PR_EXC("BFAR: 0x%" PRIx32 "\n", _ScbBusFaultAddrGet()); + if (SCB->CFSR & CFSR_BFARVALID_Msk) { + PR_EXC("BFAR: 0x%" PRIx32 "\n", SCB->BFAR); if (escalation) { - _ScbBusFaultBfarReset(); + /* clear CFSR_BFAR[VALID] to reset */ + SCB->CFSR &= ~CFSR_BFARVALID_Msk; } } /* clear USFR sticky bits */ - _ScbUsageFaultAllFaultsReset(); + SCB->CFSR |= SCB_CFSR_USGFAULTSR_Msk; #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M */ @@ -130,20 +129,20 @@ static void _MpuFault(const NANO_ESF *esf, int fromHardFault) _FaultThreadShow(esf); - if (_ScbMemFaultIsStacking()) { + if (SCB->CFSR & CFSR_MSTKERR_Msk) { PR_EXC(" Stacking error\n"); - } else if (_ScbMemFaultIsUnstacking()) { + } else if (SCB->CFSR & CFSR_MUNSTKERR_Msk) { PR_EXC(" Unstacking error\n"); - } else if (_ScbMemFaultIsDataAccessViolation()) { + } else if (SCB->CFSR & CFSR_DACCVIOL_Msk) { PR_EXC(" Data Access Violation\n"); - if (_ScbMemFaultIsMmfarValid()) { - PR_EXC(" Address: 0x%" PRIx32 "\n", - _ScbMemFaultAddrGet()); + if (SCB->CFSR & CFSR_MMARVALID_Msk) { + PR_EXC(" Address: 0x%" PRIx32 "\n", SCB->MMFAR); 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"); } } @@ -162,26 +161,26 @@ static void _BusFault(const NANO_ESF *esf, int fromHardFault) _FaultThreadShow(esf); - if (_ScbBusFaultIsStacking()) { + if (SCB->CFSR & CFSR_STKERR_Msk) { PR_EXC(" Stacking error\n"); - } else if (_ScbBusFaultIsUnstacking()) { + } else if (SCB->CFSR & CFSR_UNSTKERR_Msk) { PR_EXC(" Unstacking error\n"); - } else if (_ScbBusFaultIsPrecise()) { + } else if (SCB->CFSR & CFSR_PRECISERR_Msk) { PR_EXC(" Precise data bus error\n"); - if (_ScbBusFaultIsBfarValid()) { - PR_EXC(" Address: 0x%" PRIx32 "\n", - _ScbBusFaultAddrGet()); + if (SCB->CFSR & CFSR_BFARVALID_Msk) { + PR_EXC(" Address: 0x%" PRIx32 "\n", SCB->BFAR); 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 */ - if (_ScbBusFaultIsImprecise()) { + if (SCB->CFSR & CFSR_IMPRECISERR_Msk) { PR_EXC(" Imprecise data bus error\n"); } - } else if (_ScbBusFaultIsImprecise()) { + } else if (SCB->CFSR & CFSR_IMPRECISERR_Msk) { PR_EXC(" Imprecise data bus error\n"); - } else if (_ScbBusFaultIsInstrBusErr()) { + } else if (SCB->CFSR & CFSR_IBUSERR_Msk) { PR_EXC(" Instruction bus error\n"); } } @@ -201,26 +200,27 @@ static void _UsageFault(const NANO_ESF *esf) _FaultThreadShow(esf); /* bits are sticky: they stack and must be reset */ - if (_ScbUsageFaultIsDivByZero()) { + if (SCB->CFSR & CFSR_DIVBYZERO_Msk) { PR_EXC(" Division by zero\n"); } - if (_ScbUsageFaultIsUnaligned()) { + if (SCB->CFSR & CFSR_UNALIGNED_Msk) { PR_EXC(" Unaligned memory access\n"); } - if (_ScbUsageFaultIsNoCp()) { + if (SCB->CFSR & CFSR_NOCP_Msk) { PR_EXC(" No coprocessor instructions\n"); } - if (_ScbUsageFaultIsInvalidPcLoad()) { + if (SCB->CFSR & CFSR_INVPC_Msk) { 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"); } - if (_ScbUsageFaultIsUndefinedInstr()) { + if (SCB->CFSR & CFSR_UNDEFINSTR_Msk) { 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) _FaultThreadShow(esf); #elif defined(CONFIG_ARMV7_M) - if (_ScbHardFaultIsBusErrOnVectorRead()) { + if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk) { 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"); - if (_ScbIsMemFault()) { + if (SCB_MMFSR) { _MpuFault(esf, 1); - } else if (_ScbIsBusFault()) { + } else if (SCB_BFSR) { _BusFault(esf, 1); - } else if (_ScbIsUsageFault()) { + } else if (SCB_UFSR) { _UsageFault(esf); } } @@ -360,7 +360,7 @@ static void _FaultDump(const NANO_ESF *esf, int fault) */ void _Fault(const NANO_ESF *esf) { - int fault = _ScbActiveVectorGet(); + int fault = SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk; FAULT_DUMP(esf, fault); @@ -379,7 +379,7 @@ void _FaultInit(void) { #if defined(CONFIG_ARMV6_M) #elif defined(CONFIG_ARMV7_M) - _ScbDivByZeroFaultEnable(); + SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk; #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M */ diff --git a/arch/arm/core/fault_s.S b/arch/arm/core/fault_s.S index 9109a792b..8a7d47b56 100644 --- a/arch/arm/core/fault_s.S +++ b/arch/arm/core/fault_s.S @@ -88,7 +88,7 @@ _stack_frame_endif: eors.n r0, r0 msr BASEPRI, r0 - /* this reimplements _ScbIsNestedExc() */ + /* this checks to see if we are in a nested exception */ ldr ip, =_SCS_ICSR ldr ip, [ip] ands.w ip, #_SCS_ICSR_RETTOBASE diff --git a/arch/arm/include/cortex_m/exc.h b/arch/arm/include/cortex_m/exc.h index dff2f845e..541f1b195 100644 --- a/arch/arm/include/cortex_m/exc.h +++ b/arch/arm/include/cortex_m/exc.h @@ -53,7 +53,8 @@ static ALWAYS_INLINE int _IsInIsr(void) #if defined(CONFIG_ARMV6_M) return (vector > 10) || (vector == 3); #elif defined(CONFIG_ARMV7_M) - return (vector > 10) || (vector && _ScbIsNestedExc()); + return (vector > 10) || + (vector && !(SCB->ICSR & SCB_ICSR_RETTOBASE_Msk)); #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M */ @@ -84,9 +85,9 @@ static ALWAYS_INLINE void _ExcSetup(void) NVIC_SetPriority(BusFault_IRQn, _EXC_FAULT_PRIO); NVIC_SetPriority(UsageFault_IRQn, _EXC_FAULT_PRIO); - _ScbUsageFaultEnable(); - _ScbBusFaultEnable(); - _ScbMemFaultEnable(); + /* Enable Usage, Mem, & Bus Faults */ + SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk | + SCB_SHCSR_BUSFAULTENA_Msk; #endif } @@ -102,11 +103,12 @@ static ALWAYS_INLINE void _ClearFaults(void) #if defined(CONFIG_ARMV6_M) #elif defined(CONFIG_ARMV7_M) /* Reset all faults */ - _ScbMemFaultAllFaultsReset(); - _ScbBusFaultAllFaultsReset(); - _ScbUsageFaultAllFaultsReset(); + SCB->CFSR = SCB_CFSR_USGFAULTSR_Msk | + SCB_CFSR_MEMFAULTSR_Msk | + SCB_CFSR_BUSFAULTSR_Msk; - _ScbHardFaultAllFaultsReset(); + /* Clear all Hard Faults - HFSR is write-one-to-clear */ + SCB->HFSR = 0xffffffff; #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M */ diff --git a/arch/arm/soc/st_stm32/stm32f3/rcc_registers.h b/arch/arm/soc/st_stm32/stm32f3/rcc_registers.h deleted file mode 100644 index ddaf629a7..000000000 --- a/arch/arm/soc/st_stm32/stm32f3/rcc_registers.h +++ /dev/null @@ -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_ */ diff --git a/arch/arm/soc/st_stm32/stm32f3/soc.c b/arch/arm/soc/st_stm32/stm32f3/soc.c index 27ebea9a4..9855ea0ff 100644 --- a/arch/arm/soc/st_stm32/stm32f3/soc.c +++ b/arch/arm/soc/st_stm32/stm32f3/soc.c @@ -42,7 +42,8 @@ static int stm32f3_init(struct device *arg) irq_unlock(key); /* 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; } diff --git a/arch/arm/soc/st_stm32/stm32f3/soc.h b/arch/arm/soc/st_stm32/stm32f3/soc.h index e6474735f..85bdd58cd 100644 --- a/arch/arm/soc/st_stm32/stm32f3/soc.h +++ b/arch/arm/soc/st_stm32/stm32f3/soc.h @@ -52,6 +52,13 @@ enum stm32f3x_pin_config_mode { #include <stm32f3xx_ll_usart.h> #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 /* _STM32F3_SOC_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f3/soc_config.c b/arch/arm/soc/st_stm32/stm32f3/soc_config.c index 60b0dae28..544709551 100644 --- a/arch/arm/soc/st_stm32/stm32f3/soc_config.c +++ b/arch/arm/soc/st_stm32/stm32f3/soc_config.c @@ -29,25 +29,3 @@ int stm32_get_pin_config(int pin, int func) /* encode and return the 'real' alternate function number */ 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]; -} diff --git a/arch/arm/soc/st_stm32/stm32f3/soc_gpio.c b/arch/arm/soc/st_stm32/stm32f3/soc_gpio.c index a30205c9c..bacf1f4eb 100644 --- a/arch/arm/soc/st_stm32/stm32f3/soc_gpio.c +++ b/arch/arm/soc/st_stm32/stm32f3/soc_gpio.c @@ -117,7 +117,7 @@ int stm32_gpio_configure(uint32_t *base_addr, int pin, int conf, int altf) if (crpin > 7) { afr = &gpio->afrh; - crpin -= 7; + crpin -= 8; } /* clear AF bits */ @@ -188,7 +188,12 @@ int stm32_gpio_enable_int(int port, int pin) struct device *clk = 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; diff --git a/arch/arm/soc/st_stm32/stm32f3/soc_registers.h b/arch/arm/soc/st_stm32/stm32f3/soc_registers.h index 5c68c6cf3..c5a7f6bf5 100644 --- a/arch/arm/soc/st_stm32/stm32f3/soc_registers.h +++ b/arch/arm/soc/st_stm32/stm32f3/soc_registers.h @@ -8,7 +8,6 @@ #define _STM32F3X_SOC_REGISTERS_H_ /* include register mapping headers */ -#include "rcc_registers.h" #include "flash_registers.h" #include "gpio_registers.h" diff --git a/arch/arm/soc/st_stm32/stm32l4/rcc_registers.h b/arch/arm/soc/st_stm32/stm32l4/rcc_registers.h deleted file mode 100644 index f89e9cab5..000000000 --- a/arch/arm/soc/st_stm32/stm32l4/rcc_registers.h +++ /dev/null @@ -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_ */ diff --git a/arch/arm/soc/st_stm32/stm32l4/soc.c b/arch/arm/soc/st_stm32/stm32l4/soc.c index f3498bdce..742960e46 100644 --- a/arch/arm/soc/st_stm32/stm32l4/soc.c +++ b/arch/arm/soc/st_stm32/stm32l4/soc.c @@ -43,7 +43,8 @@ static int stm32l4_init(struct device *arg) irq_unlock(key); /* 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; } diff --git a/arch/arm/soc/st_stm32/stm32l4/soc.h b/arch/arm/soc/st_stm32/stm32l4/soc.h index cb6c5639c..2b86ce753 100644 --- a/arch/arm/soc/st_stm32/stm32l4/soc.h +++ b/arch/arm/soc/st_stm32/stm32l4/soc.h @@ -35,6 +35,13 @@ #include <stm32l4xx_ll_usart.h> #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 /* _STM32L4X_SOC_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32l4/soc_gpio.c b/arch/arm/soc/st_stm32/stm32l4/soc_gpio.c index b7ea73dc0..e4b97c92a 100644 --- a/arch/arm/soc/st_stm32/stm32l4/soc_gpio.c +++ b/arch/arm/soc/st_stm32/stm32l4/soc_gpio.c @@ -214,8 +214,12 @@ int stm32_gpio_enable_int(int port, int pin) struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); uint32_t *reg; - clock_control_on(clk, (clock_control_subsys_t *) - STM32L4X_CLOCK_SUBSYS_SYSCFG); + /* Enable SYSCFG clock */ + 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) { reg = &syscfg->exticr1; diff --git a/arch/arm/soc/st_stm32/stm32l4/soc_pinmux.c b/arch/arm/soc/st_stm32/stm32l4/soc_pinmux.c index 81a610624..a6ec50a8e 100644 --- a/arch/arm/soc/st_stm32/stm32l4/soc_pinmux.c +++ b/arch/arm/soc/st_stm32/stm32l4/soc_pinmux.c @@ -99,23 +99,3 @@ int stm32_get_pin_config(int pin, int func) } 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]; -} diff --git a/arch/arm/soc/st_stm32/stm32l4/soc_registers.h b/arch/arm/soc/st_stm32/stm32l4/soc_registers.h index 733f96d66..e1fac23a2 100644 --- a/arch/arm/soc/st_stm32/stm32l4/soc_registers.h +++ b/arch/arm/soc/st_stm32/stm32l4/soc_registers.h @@ -9,7 +9,6 @@ #define _STM32L4X_SOC_REGISTERS_H_ /* include register mapping headers */ -#include "rcc_registers.h" #include "flash_registers.h" #include "syscfg_registers.h" diff --git a/boards/arm/hexiwear_k64/doc/hexiwear_k64.jpg b/boards/arm/hexiwear_k64/doc/hexiwear_k64.jpg Binary files differnew file mode 100644 index 000000000..243f737e9 --- /dev/null +++ b/boards/arm/hexiwear_k64/doc/hexiwear_k64.jpg diff --git a/boards/arm/hexiwear_k64/doc/hexiwear_k64.rst b/boards/arm/hexiwear_k64/doc/hexiwear_k64.rst new file mode 100644 index 000000000..79d60f44f --- /dev/null +++ b/boards/arm/hexiwear_k64/doc/hexiwear_k64.rst @@ -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 diff --git a/boards/arm/nucleo_f334r8/nucleo_f334r8_defconfig b/boards/arm/nucleo_f334r8/nucleo_f334r8_defconfig index 28c008158..948923d9f 100644 --- a/boards/arm/nucleo_f334r8/nucleo_f334r8_defconfig +++ b/boards/arm/nucleo_f334r8/nucleo_f334r8_defconfig @@ -40,14 +40,18 @@ CONFIG_GPIO_STM32_PORTA=y CONFIG_GPIO_STM32_PORTB=y CONFIG_GPIO_STM32_PORTC=y -# RCC configuration +# Clock configuration CONFIG_CLOCK_CONTROL=y -CONFIG_CLOCK_CONTROL_STM32F3X=y -CONFIG_CLOCK_CONTROL_STM32F3X_DEVICE_INIT_PRIORITY=1 -CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_PLL=y -CONFIG_CLOCK_STM32F3X_PLL_SRC_HSE=y -CONFIG_CLOCK_STM32F3X_PLL_PREDIV=0 -CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER=9 -CONFIG_CLOCK_STM32F3X_AHB_PRESCALER=0 -CONFIG_CLOCK_STM32F3X_APB1_PRESCALER=2 -CONFIG_CLOCK_STM32F3X_APB2_PRESCALER=0 +CONFIG_CLOCK_CONTROL_STM32_CUBE=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# HSE configuration +CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# produce 72MHz clock at PLL output +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 diff --git a/boards/arm/nucleo_l476rg/doc/img/nucleo64_ulp_logo_1024.jpg b/boards/arm/nucleo_l476rg/doc/img/nucleo64_ulp_logo_1024.jpg Binary files differnew file mode 100644 index 000000000..9ed44d599 --- /dev/null +++ b/boards/arm/nucleo_l476rg/doc/img/nucleo64_ulp_logo_1024.jpg diff --git a/boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_arduino.png b/boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_arduino.png Binary files differnew file mode 100644 index 000000000..c6723a3a2 --- /dev/null +++ b/boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_arduino.png diff --git a/boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_morpho.png b/boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_morpho.png Binary files differnew file mode 100644 index 000000000..9815c28fb --- /dev/null +++ b/boards/arm/nucleo_l476rg/doc/img/nucleo_l476rg_morpho.png diff --git a/boards/arm/nucleo_l476rg/doc/nucleol476rg.rst b/boards/arm/nucleo_l476rg/doc/nucleol476rg.rst new file mode 100644 index 000000000..a39be9e82 --- /dev/null +++ b/boards/arm/nucleo_l476rg/doc/nucleol476rg.rst @@ -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 diff --git a/boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig b/boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig index a4e230713..1d8dfd0bd 100644 --- a/boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig +++ b/boards/arm/nucleo_l476rg/nucleo_l476rg_defconfig @@ -31,19 +31,20 @@ CONFIG_GPIO_STM32_PORTH=y # clock configuration CONFIG_CLOCK_CONTROL=y -CONFIG_CLOCK_CONTROL_STM32L4X=y -CONFIG_CLOCK_STM32L4X_SYSCLK_SRC_PLL=y -# use 16MHz oscillator -CONFIG_CLOCK_STM32F10X_PLL_SRC_HSI=y +CONFIG_CLOCK_CONTROL_STM32_CUBE=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_HSI # produce 80MHz clock at PLL output -CONFIG_CLOCK_STM32L4X_PLL_DIVISOR=1 -CONFIG_CLOCK_STM32L4X_PLL_MULTIPLIER=20 -CONFIG_CLOCK_STM32L4X_PLL_P_DIVISOR=7 -CONFIG_CLOCK_STM32L4X_PLL_Q_DIVISOR=2 -CONFIG_CLOCK_STM32L4X_PLL_R_DIVISOR=4 -CONFIG_CLOCK_STM32L4X_AHB_PRESCALER=0 -CONFIG_CLOCK_STM32L4X_APB1_PRESCALER=0 -CONFIG_CLOCK_STM32L4X_APB2_PRESCALER=0 +CONFIG_CLOCK_STM32_PLL_M_DIVISOR=1 +CONFIG_CLOCK_STM32_PLL_N_MULTIPLIER=20 +CONFIG_CLOCK_STM32_PLL_P_DIVISOR=7 +CONFIG_CLOCK_STM32_PLL_Q_DIVISOR=2 +CONFIG_CLOCK_STM32_PLL_R_DIVISOR=4 +CONFIG_CLOCK_STM32_AHB_PRESCALER=1 +CONFIG_CLOCK_STM32_APB1_PRESCALER=1 +CONFIG_CLOCK_STM32_APB2_PRESCALER=1 # console CONFIG_CONSOLE=y diff --git a/boards/arm/stm32373c_eval/stm32373c_eval_defconfig b/boards/arm/stm32373c_eval/stm32373c_eval_defconfig index c673c6e4e..d881b4e61 100644 --- a/boards/arm/stm32373c_eval/stm32373c_eval_defconfig +++ b/boards/arm/stm32373c_eval/stm32373c_eval_defconfig @@ -49,14 +49,18 @@ CONFIG_GPIO_STM32_PORTC=y CONFIG_GPIO_STM32_PORTD=y CONFIG_GPIO_STM32_PORTE=y -# RCC configuration +# Clock configuration CONFIG_CLOCK_CONTROL=y -CONFIG_CLOCK_CONTROL_STM32F3X=y -CONFIG_CLOCK_CONTROL_STM32F3X_DEVICE_INIT_PRIORITY=1 -CONFIG_CLOCK_STM32F3X_SYSCLK_SRC_PLL=y -CONFIG_CLOCK_STM32F3X_PLL_SRC_HSE=y -CONFIG_CLOCK_STM32F3X_PLL_PREDIV=0 -CONFIG_CLOCK_STM32F3X_PLL_MULTIPLIER=9 -CONFIG_CLOCK_STM32F3X_AHB_PRESCALER=0 -CONFIG_CLOCK_STM32F3X_APB1_PRESCALER=2 -CONFIG_CLOCK_STM32F3X_APB2_PRESCALER=2 +CONFIG_CLOCK_CONTROL_STM32_CUBE=y +# SYSCLK selection +CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL=y +# HSE configuration +CONFIG_CLOCK_STM32_HSE_CLOCK=8000000 +# PLL configuration +CONFIG_CLOCK_STM32_PLL_SRC_HSE=y +# produce 72MHz clock at PLL output +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 diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index bb06baa8f..1db3a61c7 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -44,16 +44,14 @@ source "drivers/clock_control/Kconfig.nrf5" source "drivers/clock_control/Kconfig.quark_se" +source "drivers/clock_control/Kconfig.stm32" + source "drivers/clock_control/Kconfig.stm32f10x" source "drivers/clock_control/Kconfig.stm32f107xx" -source "drivers/clock_control/Kconfig.stm32f3x" - source "drivers/clock_control/Kconfig.stm32f4x" -source "drivers/clock_control/Kconfig.stm32l4x" - source "drivers/clock_control/Kconfig.beetle" endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.stm32 b/drivers/clock_control/Kconfig.stm32 new file mode 100644 index 000000000..293aaed01 --- /dev/null +++ b/drivers/clock_control/Kconfig.stm32 @@ -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 diff --git a/drivers/clock_control/Kconfig.stm32f3x b/drivers/clock_control/Kconfig.stm32f3x deleted file mode 100644 index e8fde609f..000000000 --- a/drivers/clock_control/Kconfig.stm32f3x +++ /dev/null @@ -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 diff --git a/drivers/clock_control/Kconfig.stm32l4x b/drivers/clock_control/Kconfig.stm32l4x deleted file mode 100644 index 8683308a9..000000000 --- a/drivers/clock_control/Kconfig.stm32l4x +++ /dev/null @@ -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 - diff --git a/drivers/clock_control/Makefile b/drivers/clock_control/Makefile index 2abf05add..5fdb1ec07 100644 --- a/drivers/clock_control/Makefile +++ b/drivers/clock_control/Makefile @@ -1,8 +1,12 @@ obj-$(CONFIG_CLOCK_CONTROL_NRF5) += nrf5_power_clock.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_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_STM32L4X) += stm32l4x_clock.o +endif obj-$(CONFIG_CLOCK_CONTROL_BEETLE) += beetle_clock_control.o diff --git a/drivers/clock_control/stm32_ll_clock.c b/drivers/clock_control/stm32_ll_clock.c new file mode 100644 index 000000000..b5b69041e --- /dev/null +++ b/drivers/clock_control/stm32_ll_clock.c @@ -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); diff --git a/drivers/clock_control/stm32_ll_clock.h b/drivers/clock_control/stm32_ll_clock.h new file mode 100644 index 000000000..73d090b24 --- /dev/null +++ b/drivers/clock_control/stm32_ll_clock.h @@ -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_ */ diff --git a/drivers/clock_control/stm32f3x_clock.c b/drivers/clock_control/stm32f3x_clock.c deleted file mode 100644 index 5b5221e5e..000000000 --- a/drivers/clock_control/stm32f3x_clock.c +++ /dev/null @@ -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); diff --git a/drivers/clock_control/stm32f3x_ll_clock.c b/drivers/clock_control/stm32f3x_ll_clock.c new file mode 100644 index 000000000..742bf636b --- /dev/null +++ b/drivers/clock_control/stm32f3x_ll_clock.c @@ -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 */ +} diff --git a/drivers/clock_control/stm32l4x_clock.c b/drivers/clock_control/stm32l4x_clock.c deleted file mode 100644 index 979051bdc..000000000 --- a/drivers/clock_control/stm32l4x_clock.c +++ /dev/null @@ -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); diff --git a/drivers/clock_control/stm32l4x_ll_clock.c b/drivers/clock_control/stm32l4x_ll_clock.c new file mode 100644 index 000000000..b97652359 --- /dev/null +++ b/drivers/clock_control/stm32l4x_ll_clock.c @@ -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 */ diff --git a/drivers/flash/flash_stm32f3x.c b/drivers/flash/flash_stm32f3x.c index 0b041c84b..54b5fc38f 100644 --- a/drivers/flash/flash_stm32f3x.c +++ b/drivers/flash/flash_stm32f3x.c @@ -4,12 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "flash_stm32f3x.h" - #include <errno.h> #include <misc/__assert.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) { 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); - if (clock_control_on(clk, cfg->clock_subsys) != 0) + if (clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken) != 0) return -ENODEV; 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 = { .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 = { diff --git a/drivers/flash/flash_stm32f3x.h b/drivers/flash/flash_stm32f3x.h index e215332d7..c0257cc75 100644 --- a/drivers/flash/flash_stm32f3x.h +++ b/drivers/flash/flash_stm32f3x.h @@ -14,7 +14,7 @@ struct flash_stm32_dev_config { uint32_t *base; - clock_control_subsys_t clock_subsys; + struct stm32_pclken pclken; }; struct flash_stm32_dev_data { diff --git a/drivers/flash/flash_stm32f3x_priv.c b/drivers/flash/flash_stm32f3x_priv.c index c11d54397..d34ffb564 100644 --- a/drivers/flash/flash_stm32f3x_priv.c +++ b/drivers/flash/flash_stm32f3x_priv.c @@ -4,10 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "flash_stm32f3x.h" +#include <clock_control/stm32_clock_control.h> #include <misc/__assert.h> #include <string.h> +#include "flash_stm32f3x.h" + void flash_stm32_unlock(struct device *flash) { const struct flash_stm32_dev_config *config = FLASH_CFG(flash); diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index 2cbee9d9f..0de0ea2ba 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -188,7 +188,9 @@ static int gpio_stm32_init(struct device *device) struct device *clk = 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); #else clock_control_on(clk, cfg->clock_subsys); @@ -196,6 +198,27 @@ static int gpio_stm32_init(struct device *device) 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 /* 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 = { \ .base = (uint32_t *)__base_addr, \ .port = __port, \ - .clock_subsys = UINT_TO_POINTER(__clock), \ + .clock_subsys = UINT_TO_POINTER(__clock) \ }; \ static struct gpio_stm32_data gpio_stm32_data_## __suffix; \ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \ @@ -211,14 +234,14 @@ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \ gpio_stm32_init, \ &gpio_stm32_data_## __suffix, \ &gpio_stm32_cfg_## __suffix, \ - POST_KERNEL, \ + POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ &gpio_stm32_driver); #else /* CONFIG_SOC_SERIES_STM32F4X */ #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, \ .port = __port, \ .pclken = { .bus = STM32F4X_CLOCK_BUS_AHB1, .enr = __cenr }, \ @@ -229,112 +252,98 @@ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \ gpio_stm32_init, \ &gpio_stm32_data_## __suffix, \ &gpio_stm32_cfg_## __suffix, \ - POST_KERNEL, \ + POST_KERNEL, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ &gpio_stm32_driver); #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ #ifdef CONFIG_GPIO_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 STM32F10X_CLOCK_SUBSYS_IOPA | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F3X - STM32F3X_CLOCK_SUBSYS_IOPA #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOA -#elif CONFIG_SOC_SERIES_STM32L4X - STM32L4X_CLOCK_SUBSYS_GPIOA #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ ); #endif /* CONFIG_GPIO_STM32_PORTA */ #ifdef CONFIG_GPIO_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 STM32F10X_CLOCK_SUBSYS_IOPB | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F3X - STM32F3X_CLOCK_SUBSYS_IOPB #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOB -#elif CONFIG_SOC_SERIES_STM32L4X - STM32L4X_CLOCK_SUBSYS_GPIOB #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ ); #endif /* CONFIG_GPIO_STM32_PORTB */ #ifdef CONFIG_GPIO_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 STM32F10X_CLOCK_SUBSYS_IOPC | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F3X - STM32F3X_CLOCK_SUBSYS_IOPC #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOC -#elif CONFIG_SOC_SERIES_STM32L4X - STM32L4X_CLOCK_SUBSYS_GPIOC #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ ); #endif /* CONFIG_GPIO_STM32_PORTC */ #ifdef CONFIG_GPIO_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 STM32F10X_CLOCK_SUBSYS_IOPD | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F3X - STM32F3X_CLOCK_SUBSYS_IOPD #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOD -#elif CONFIG_SOC_SERIES_STM32L4X - STM32L4X_CLOCK_SUBSYS_GPIOD #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ ); #endif /* CONFIG_GPIO_STM32_PORTD */ #ifdef CONFIG_GPIO_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 STM32F10X_CLOCK_SUBSYS_IOPE | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F3X - STM32F3X_CLOCK_SUBSYS_IOPE #elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOE -#elif CONFIG_SOC_SERIES_STM32L4X - STM32L4X_CLOCK_SUBSYS_GPIOE #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ ); #endif /* CONFIG_GPIO_STM32_PORTE */ #ifdef CONFIG_GPIO_STM32_PORTF GPIO_DEVICE_INIT("GPIOF", f, GPIOF_BASE, STM32_PORTF, -#ifdef CONFIG_SOC_SERIES_STM32F3X - STM32F3X_CLOCK_SUBSYS_IOPF -#elif CONFIG_SOC_SERIES_STM32L4X - STM32L4X_CLOCK_SUBSYS_GPIOF -#endif - ); + STM32_PERIPH_GPIOF, STM32_CLOCK_BUS_GPIO); #endif /* CONFIG_GPIO_STM32_PORTF */ #ifdef CONFIG_GPIO_STM32_PORTG GPIO_DEVICE_INIT("GPIOG", g, GPIOG_BASE, STM32_PORTG, -#ifdef CONFIG_SOC_SERIES_STM32F3X - STM32F3X_CLOCK_SUBSYS_IOPG -#elif CONFIG_SOC_SERIES_STM32L4X - STM32L4X_CLOCK_SUBSYS_GPIOG -#endif - ); + STM32_PERIPH_GPIOG, STM32_CLOCK_BUS_GPIO); #endif /* CONFIG_GPIO_STM32_PORTG */ #ifdef CONFIG_GPIO_STM32_PORTH GPIO_DEVICE_INIT("GPIOH", h, GPIOH_BASE, STM32_PORTH, -#ifdef CONFIG_SOC_SERIES_STM32F3X - STM32F3X_CLOCK_SUBSYS_IOPH -#elif CONFIG_SOC_SERIES_STM32L4X - STM32L4X_CLOCK_SUBSYS_GPIOH -#endif - ); + STM32_PERIPH_GPIOH, STM32_CLOCK_BUS_GPIO); #endif /* CONFIG_GPIO_STM32_PORTH */ diff --git a/drivers/gpio/gpio_stm32.h b/drivers/gpio/gpio_stm32.h index a0bdecae2..99f335d27 100644 --- a/drivers/gpio/gpio_stm32.h +++ b/drivers/gpio/gpio_stm32.h @@ -15,6 +15,34 @@ #include <pinmux/stm32/pinmux_stm32.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 */ @@ -23,7 +51,9 @@ struct gpio_stm32_config { uint32_t *base; /* IO 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; #else /* SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32L4X */ /* clock subsystem */ diff --git a/drivers/i2c/i2c_stm32lx.c b/drivers/i2c/i2c_stm32lx.c index fb6b1b6b2..d422afb40 100644 --- a/drivers/i2c/i2c_stm32lx.c +++ b/drivers/i2c/i2c_stm32lx.c @@ -40,7 +40,8 @@ static int i2c_stm32lx_runtime_configure(struct device *dev, uint32_t 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) return -EINVAL; @@ -408,7 +409,8 @@ static int i2c_stm32lx_init(struct device *dev) __i2c_stm32lx_get_clock(dev); /* enable clock */ - clock_control_on(data->clock, cfg->clock_subsys); + clock_control_on(data->clock, + (clock_control_subsys_t *)&cfg->pclken); /* Reset config */ 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 = { .base = (uint8_t *)I2C1_BASE, -#ifdef CONFIG_SOC_SERIES_STM32L4X - .clock_subsys = UINT_TO_POINTER(STM32L4X_CLOCK_SUBSYS_I2C1), -#endif + .pclken = { .bus = STM32_CLOCK_BUS_APB1, + .enr = LL_APB1_GRP1_PERIPH_I2C1 }, #ifdef CONFIG_I2C_STM32LX_INTERRUPT .irq_config_func = i2c_stm32lx_irq_config_func_0, #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, &i2c_stm32lx_dev_data_0, &i2c_stm32lx_cfg_0, - SECONDARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &api_funcs); #ifdef CONFIG_I2C_STM32LX_INTERRUPT diff --git a/drivers/i2c/i2c_stm32lx.h b/drivers/i2c/i2c_stm32lx.h index 84a6330e1..daeb773a4 100644 --- a/drivers/i2c/i2c_stm32lx.h +++ b/drivers/i2c/i2c_stm32lx.h @@ -184,7 +184,7 @@ struct i2c_stm32lx_config { void *base; irq_config_func_t irq_config_func; /* clock subsystem driving this peripheral */ - clock_control_subsys_t clock_subsys; + struct stm32_pclken pclken; }; /* driver data */ diff --git a/drivers/pinmux/stm32/pinmux_stm32.c b/drivers/pinmux/stm32/pinmux_stm32.c index 10d953b32..0877df561 100644 --- a/drivers/pinmux/stm32/pinmux_stm32.c +++ b/drivers/pinmux/stm32/pinmux_stm32.c @@ -16,13 +16,33 @@ #include <kernel.h> #include <device.h> #include <soc.h> -#include "pinmux.h" #include <pinmux.h> #include <gpio/gpio_stm32.h> #include <clock_control/stm32_clock_control.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] = { STM32F4X_CLOCK_ENABLE_GPIOA, 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 */ -#ifdef CONFIG_SOC_SERIES_STM32F4X - struct stm32f4x_pclken pclken; +#if defined(CONFIG_CLOCK_CONTROL_STM32_CUBE) + struct stm32_pclken pclken; - /* AHB1 bus for all the GPIO ports */ - pclken.bus = STM32F4X_CLOCK_BUS_AHB1; + pclken.bus = STM32_CLOCK_BUS_GPIO; pclken.enr = ports_enable[port]; return clock_control_on(clk, (clock_control_subsys_t *) &pclken); - -#else /* SOC_SERIES_STM32F1X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32L4X */ +#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 */ + pclken.bus = STM32F4X_CLOCK_BUS_AHB1; + pclken.enr = ports_enable[port]; + + return clock_control_on(clk, (clock_control_subsys_t *) &pclken); #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ } static int stm32_pin_configure(int pin, int func, int altf) diff --git a/drivers/pwm/pwm_stm32.c b/drivers/pwm/pwm_stm32.c index d7754a9bf..dcf0134f1 100644 --- a/drivers/pwm/pwm_stm32.c +++ b/drivers/pwm/pwm_stm32.c @@ -27,13 +27,32 @@ #ifdef CONFIG_SOC_SERIES_STM32F1X #define CLOCK_SUBSYS_TIM1 STM32F10X_CLOCK_SUBSYS_TIM1 #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 #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 static uint32_t __get_tim_clk(uint32_t bus_clk, 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 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) { apb_psc = CONFIG_CLOCK_STM32F10X_APB2_PRESCALER; } else { apb_psc = CONFIG_CLOCK_STM32F10X_APB1_PRESCALER; } -#endif if (apb_psc == RCC_HCLK_DIV1) { tim_clk = bus_clk; @@ -87,6 +98,7 @@ static uint32_t __get_tim_clk(uint32_t bus_clk, return tim_clk; } #endif /* CONFIG_SOC_SERIES_STM32F4X */ +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ /* * 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 */ -#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_subsys_t *)&cfg->pclken, &bus_clk); @@ -230,7 +243,8 @@ static int pwm_stm32_init(struct device *dev) __pwm_stm32_get_clock(dev); /* 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_subsys_t *)&config->pclken); #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 = { .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 .pclken = { .bus = STM32F4X_CLOCK_BUS_APB2, .enr = STM32F4X_CLOCK_ENABLE_TIM1 }, #else .clock_subsys = UINT_TO_POINTER(CLOCK_SUBSYS_TIM1), #endif /* CONFIG_SOC_SERIES_STM32F4X */ +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ }; 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 = { .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 .pclken = { .bus = STM32F4X_CLOCK_BUS_APB1, .enr = STM32F4X_CLOCK_ENABLE_TIM2 }, #else .clock_subsys = UINT_TO_POINTER(CLOCK_SUBSYS_TIM2), #endif /* CONFIG_SOC_SERIES_STM32F4X */ +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ }; DEVICE_AND_API_INIT(pwm_stm32_2, CONFIG_PWM_STM32_2_DEV_NAME, diff --git a/drivers/pwm/pwm_stm32.h b/drivers/pwm/pwm_stm32.h index 97762c138..779002ee8 100644 --- a/drivers/pwm/pwm_stm32.h +++ b/drivers/pwm/pwm_stm32.h @@ -19,11 +19,15 @@ extern "C" { struct pwm_stm32_config { uint32_t pwm_base; /* 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; #elif defined(CONFIG_SOC_SERIES_STM32F4X) struct stm32f4x_pclken pclken; #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ }; /** Runtime driver data */ diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index 9c8eaccb0..886606c1b 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -291,11 +291,10 @@ static int uart_stm32_init(struct device *dev) __uart_stm32_get_clock(dev); /* enable clock */ -#if defined(CONFIG_SOC_SERIES_STM32F1X) || \ - defined(CONFIG_SOC_SERIES_STM32F3X) || \ - defined(CONFIG_SOC_SERIES_STM32L4X) +#if defined(CONFIG_SOC_SERIES_STM32F1X) 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_subsys_t *)&config->pclken); #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, #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 .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 .pclken = { .bus = STM32F4X_CLOCK_BUS_APB2, .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 /* CLOCK_CONTROL_STM32_CUBE */ }; 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, #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 .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 .pclken = { .bus = STM32F4X_CLOCK_BUS_APB1, .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 /* CLOCK_CONTROL_STM32_CUBE */ }; 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, #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 .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 .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 /* CLOCK_CONTROL_STM32_CUBE */ }; static struct uart_stm32_data uart_stm32_dev_data_3 = { diff --git a/drivers/serial/uart_stm32.h b/drivers/serial/uart_stm32.h index 34f0c7352..160dc537e 100644 --- a/drivers/serial/uart_stm32.h +++ b/drivers/serial/uart_stm32.h @@ -16,13 +16,15 @@ struct uart_stm32_config { struct uart_device_config uconf; /* clock subsystem driving this peripheral */ -#if defined(CONFIG_SOC_SERIES_STM32F1X) || \ - defined(CONFIG_SOC_SERIES_STM32F3X) || \ - defined(CONFIG_SOC_SERIES_STM32L4X) +#if defined(CONFIG_CLOCK_CONTROL_STM32_CUBE) + struct stm32_pclken pclken; +#else +#if defined(CONFIG_SOC_SERIES_STM32F1X) clock_control_subsys_t clock_subsys; #elif defined(CONFIG_SOC_SERIES_STM32F4X) struct stm32f4x_pclken pclken; #endif +#endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ }; /* driver data */ diff --git a/ext/hal/st/stm32cube/Kbuild b/ext/hal/st/stm32cube/Kbuild index 7876be5de..b0c38c0bb 100644 --- a/ext/hal/st/stm32cube/Kbuild +++ b/ext/hal/st/stm32cube/Kbuild @@ -11,6 +11,7 @@ endif ifdef CONFIG_SOC_SERIES_STM32F3X obj-y += stm32f3xx/drivers/src/stm32f3xx_hal.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-y += stm32f3xx/soc/system_stm32f3xx.o endif @@ -31,6 +32,7 @@ endif ifdef CONFIG_SOC_SERIES_STM32L4X obj-y += stm32l4xx/drivers/src/stm32l4xx_hal.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_SERIAL_HAS_DRIVER) += stm32l4xx/drivers/src/stm32l4xx_hal_uart.o obj-y += stm32l4xx/soc/system_stm32l4xx.o diff --git a/include/arch/arm/arch.h b/include/arch/arm/arch.h index ec8a2e8da..c3dd42cc2 100644 --- a/include/arch/arm/arch.h +++ b/include/arch/arm/arch.h @@ -33,8 +33,6 @@ extern "C" { #include <arch/arm/cortex_m/irq.h> #include <arch/arm/cortex_m/error.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/asm_inline.h> #include <arch/arm/cortex_m/addr_types.h> diff --git a/include/arch/arm/cortex_m/cmsis.h b/include/arch/arm/cortex_m/cmsis.h index 097fe011e..0ae08197a 100644 --- a/include/arch/arm/cortex_m/cmsis.h +++ b/include/arch/arm/cortex_m/cmsis.h @@ -22,19 +22,68 @@ extern "C" { /* CP10 Access Bits */ #define CPACR_CP10_Pos 20U -#define CPACR_CP10_Msk (3UL << _SCS_CPACR_CP10_Pos) -#define CPACR_CP10_NO_ACCESS (0UL << _SCS_CPACR_CP10_Pos) -#define CPACR_CP10_PRIV_ACCESS (1UL << _SCS_CPACR_CP10_Pos) -#define CPACR_CP10_RESERVED (2UL << _SCS_CPACR_CP10_Pos) -#define CPACR_CP10_FULL_ACCESS (3UL << _SCS_CPACR_CP10_Pos) +#define CPACR_CP10_Msk (3UL << CPACR_CP10_Pos) +#define CPACR_CP10_NO_ACCESS (0UL << CPACR_CP10_Pos) +#define CPACR_CP10_PRIV_ACCESS (1UL << CPACR_CP10_Pos) +#define CPACR_CP10_RESERVED (2UL << CPACR_CP10_Pos) +#define CPACR_CP10_FULL_ACCESS (3UL << CPACR_CP10_Pos) /* CP11 Access Bits */ #define CPACR_CP11_Pos 22U -#define CPACR_CP11_Msk (3UL << _SCS_CPACR_CP11_Pos) -#define CPACR_CP11_NO_ACCESS (0UL << _SCS_CPACR_CP11_Pos) -#define CPACR_CP11_PRIV_ACCESS (1UL << _SCS_CPACR_CP11_Pos) -#define CPACR_CP11_RESERVED (2UL << _SCS_CPACR_CP11_Pos) -#define CPACR_CP11_FULL_ACCESS (3UL << _SCS_CPACR_CP11_Pos) +#define CPACR_CP11_Msk (3UL << CPACR_CP11_Pos) +#define CPACR_CP11_NO_ACCESS (0UL << CPACR_CP11_Pos) +#define CPACR_CP11_PRIV_ACCESS (1UL << CPACR_CP11_Pos) +#define CPACR_CP11_RESERVED (2UL << 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. * Use __NVIC_PRIO_BITS as it is required and simple to check, but diff --git a/include/arch/arm/cortex_m/scb.h b/include/arch/arm/cortex_m/scb.h deleted file mode 100644 index d2bbdf224..000000000 --- a/include/arch/arm/cortex_m/scb.h +++ /dev/null @@ -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_ */ diff --git a/include/arch/arm/cortex_m/scs.h b/include/arch/arm/cortex_m/scs.h deleted file mode 100644 index dd0e3de00..000000000 --- a/include/arch/arm/cortex_m/scs.h +++ /dev/null @@ -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_ */ diff --git a/include/drivers/clock_control/stm32_clock_control.h b/include/drivers/clock_control/stm32_clock_control.h index 45db18d0b..085efdf72 100644 --- a/include/drivers/clock_control/stm32_clock_control.h +++ b/include/drivers/clock_control/stm32_clock_control.h @@ -2,6 +2,7 @@ * Copyright (c) 2016 Open-RnD Sp. z o.o. * Copyright (c) 2016 BayLibre, SAS * Copyright (c) 2016 RnDity Sp. z o.o. + * Copyright (c) 2017 Linaro Limited. * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,12 +16,24 @@ #ifdef CONFIG_SOC_SERIES_STM32F1X #include "stm32f1_clock_control.h" -#elif CONFIG_SOC_SERIES_STM32F3X -#include "stm32f3_clock_control.h" #elif CONFIG_SOC_SERIES_STM32F4X #include "stm32f4_clock_control.h" -#elif CONFIG_SOC_SERIES_STM32L4X -#include "stm32l4x_clock_control.h" #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_ */ diff --git a/include/drivers/clock_control/stm32f3_clock_control.h b/include/drivers/clock_control/stm32f3_clock_control.h deleted file mode 100644 index 91103cc55..000000000 --- a/include/drivers/clock_control/stm32f3_clock_control.h +++ /dev/null @@ -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_ */ diff --git a/include/drivers/clock_control/stm32l4x_clock_control.h b/include/drivers/clock_control/stm32l4x_clock_control.h deleted file mode 100644 index 5f44712f4..000000000 --- a/include/drivers/clock_control/stm32l4x_clock_control.h +++ /dev/null @@ -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_ */ diff --git a/include/section_tags.h b/include/section_tags.h index 19d0b23eb..38877d384 100644 --- a/include/section_tags.h +++ b/include/section_tags.h @@ -17,7 +17,6 @@ #define __irq_vector_table _GENERIC_SECTION(IRQ_VECTOR_TABLE) #if defined(CONFIG_ARM) -#define __scs_section __in_section_unique(SCS_SECTION) #define __scp_section __in_section_unique(SCP_SECTION) #define __security_frdm_k64f_section __in_section_unique(SECURITY_FRDM_K64F) #define __kinetis_flash_config_section __in_section_unique(KINETIS_FLASH_CONFIG) |