arch/arm/stm32l5: Use common Cortex-M33 core support

Enable STM32_COMMON_M33 for STM32L5 and drop the family reset, NVIC,
SysTick, idle, and heap sources in favor of the common Cortex-M33 v1
implementation.

Rename the family RCC header to stm32_rcc_m33.h for the common RCC
dispatch and define STM32_PRIMARY_SRAM_SIZE for the common heap
allocator.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
This commit is contained in:
raiden00pl 2026-08-26 10:05:27 +02:00 • committed by Alan C. Assis
parent cc8c7d0769
commit 6e7ea6019e
21 changed files with 21 additions and 1408 deletions

View file

@ -40,6 +40,8 @@
# error "Unsupported STM32L5 chip"
#endif
#define STM32_PRIMARY_SRAM_SIZE STM32_SRAM1_SIZE
#if defined(CONFIG_STM32_STM32L562XX)
# define STM32_NFSMC 1 /* Have FSMC memory controller */
# define STM32_NATIM 2 /* Two advanced timers TIM1 and 8 */

View file

@ -56,6 +56,7 @@ config STM32_COMMON_L4_H5_L5_U5
config STM32_COMMON_M33
bool
default y if ARCH_CHIP_STM32C5
default y if ARCH_CHIP_STM32L5
default y if ARCH_CHIP_STM32U3
default y if ARCH_CHIP_STM32U5

View file

@ -25,23 +25,15 @@
list(
APPEND
SRCS
stm32l5_allocateheap.c
stm32l5_irq.c
stm32l5_lowputc.c
stm32l5_rcc.c
stm32l5_serial.c
stm32l5_start.c
stm32l5_spi.c
stm32l5_lse.c
stm32l5_lsi.c
stm32l5_pwr.c
stm32l5_tim.c
stm32l5_flash.c
stm32l5_timerisr.c)
if(NOT CONFIG_ARCH_IDLE_CUSTOM)
list(APPEND SRCS stm32l5_idle.c)
endif()
stm32l5_flash.c)
if(CONFIG_TIMER)
list(APPEND SRCS stm32l5_tim_lowerhalf.c)

View file

@ -33,15 +33,10 @@ include common/stm32/Make.defs
# Required STM32L5 files
CHIP_ASRCS =
CHIP_CSRCS += stm32l5_allocateheap.c
CHIP_CSRCS += stm32l5_irq.c stm32l5_lowputc.c stm32l5_rcc.c
CHIP_CSRCS += stm32l5_serial.c stm32l5_start.c
CHIP_CSRCS += stm32l5_lowputc.c stm32l5_rcc.c
CHIP_CSRCS += stm32l5_serial.c
CHIP_CSRCS += stm32l5_spi.c stm32l5_lse.c stm32l5_lsi.c
CHIP_CSRCS += stm32l5_pwr.c stm32l5_tim.c stm32l5_flash.c stm32l5_timerisr.c
ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y)
CHIP_CSRCS += stm32l5_idle.c
endif
CHIP_CSRCS += stm32l5_pwr.c stm32l5_tim.c stm32l5_flash.c
ifeq ($(CONFIG_TIMER),y)
CHIP_CSRCS += stm32l5_tim_lowerhalf.c

View file

@ -41,7 +41,7 @@
#include "stm32l5_flash.h"
#include "stm32_gpio.h"
#include "stm32l5_pwr.h"
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
#include "stm32l5_spi.h"
#include "stm32l5_tim.h"
#include "stm32l5_uart.h"

View file

@ -1,5 +1,5 @@
/****************************************************************************
* arch/arm/src/stm32l5/stm32l5_rcc.h
* arch/arm/src/stm32l5/stm32_rcc_m33.h
*
* SPDX-License-Identifier: Apache-2.0
*
@ -20,8 +20,8 @@
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_STM32L5_STM32L5_RCC_H
#define __ARCH_ARM_SRC_STM32L5_STM32L5_RCC_H
#ifndef __ARCH_ARM_SRC_STM32L5_STM32_RCC_M33_H
#define __ARCH_ARM_SRC_STM32L5_STM32_RCC_M33_H
/****************************************************************************
* Included Files
@ -224,4 +224,4 @@ void stm32_rcc_enableperipherals(void);
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_STM32L5_STM32L5_RCC_H */
#endif /* __ARCH_ARM_SRC_STM32L5_STM32_RCC_M33_H */

View file

@ -32,7 +32,7 @@
#include "stm32l5_pwr.h"
#include "stm32l5_flash.h"
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
/****************************************************************************
* Pre-processor Definitions

View file

@ -1,373 +0,0 @@
/****************************************************************************
* arch/arm/src/stm32l5/stm32l5_allocateheap.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/debug.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <nuttx/kmalloc.h>
#include <nuttx/userspace.h>
#include <arch/board/board.h>
#include "chip.h"
#include "mpu.h"
#include "arm_internal.h"
#include "stm32l5_mpuinit.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Internal SRAM is available in all members of the STM32L5 family. The
* following definitions must be provided to specify the size and
* location of internal (system) SRAM1 and SRAM2:
*
* SRAM1_START 0x20000000
* SRAM1_END
* SRAM2_START 0x10000000
* SRAM2_END
*
* In addition to internal SRAM, memory may also be available through the
* FSMC. In order to use FSMC SRAM, the following additional things need to
* be present in the NuttX configuration file:
*
* CONFIG_STM32_FSMC=y : Enables the FSMC
* CONFIG_STM32_FSMC_SRAM=y : Indicates that SRAM is available via the
* FSMC (as opposed to an LCD or FLASH).
* CONFIG_HEAP2_BASE : The base address of the SRAM in the FSMC
* address space
* CONFIG_HEAP2_SIZE : The size of the SRAM in the FSMC
* address space
* CONFIG_MM_REGIONS : Must be set to a large enough value to
* include the additional regions.
*/
#ifndef CONFIG_STM32_FSMC
# undef CONFIG_STM32_FSMC_SRAM
#endif
/* STM32L5[7,8]6xx have 128 Kib in two banks, both accessible to DMA:
*
* 1) 96 KiB of System SRAM beginning at address 0x2000:0000 - 0x2001:8000
* 2) 32 KiB of System SRAM beginning at address 0x1000:0000 - 0x1000:8000
*
* STM32L596xx have 320 Kib in two banks, both accessible to DMA:
*
* 1) 256 KiB of System SRAM beginning at address 0x2000:0000 - 0x2004:0000
* 2) 64 KiB of System SRAM beginning at address 0x1000:0000 - 0x1001:0000
*
* STM32L5Rxxx have 640 Kib in three banks:
*
* 1) 192 KiB of System SRAM beginning at address 0x2000:0000 - 0x2003:0000
* 2) 64 KiB of System SRAM beginning at address 0x1000:0000 - 0x1001:0000
* 3) 384 KiB of System SRAM beginning at address 0x2004:0000 - 0x200A:0000
*
* In addition, external FSMC SRAM may be available.
*/
/* Set the range of system SRAM */
#define SRAM1_START STM32_SRAM_BASE
#define SRAM1_END (SRAM1_START + STM32_SRAM1_SIZE)
/* Set the range of SRAM2 as well, requires a second memory region */
#define SRAM2_START STM32_SRAM2_BASE
#define SRAM2_END (SRAM2_START + STM32_SRAM2_SIZE)
/* Set the range of SRAM3, requiring a third memory region */
#ifdef STM32_SRAM3_SIZE
# define SRAM3_START STM32_SRAM3_BASE
# define SRAM3_END (SRAM3_START + STM32_SRAM3_SIZE)
#endif
/* Some sanity checking. If multiple memory regions are defined, verify
* that CONFIG_MM_REGIONS is set to match the number of memory regions
* that we have been asked to add to the heap.
*/
#if CONFIG_MM_REGIONS < defined(CONFIG_STM32_SRAM2_HEAP) + \
defined(CONFIG_STM32_SRAM3_HEAP) + \
defined(CONFIG_STM32_FSMC_SRAM_HEAP) + 1
# error "You need more memory manager regions to support selected heap components"
#endif
#if CONFIG_MM_REGIONS > defined(CONFIG_STM32_SRAM2_HEAP) + \
defined(CONFIG_STM32_SRAM3_HEAP) + \
defined(CONFIG_STM32_FSMC_SRAM_HEAP) + 1
# warning "CONFIG_MM_REGIONS large enough but I do not know what some of the region(s) are"
#endif
/* If FSMC SRAM is going to be used as heap, then verify that the starting
* address and size of the external SRAM region has been provided in the
* configuration (as CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE).
*/
#ifdef CONFIG_STM32_FSMC_SRAM
# if !defined(CONFIG_HEAP2_BASE) || !defined(CONFIG_HEAP2_SIZE)
# error "CONFIG_HEAP2_BASE and CONFIG_HEAP2_SIZE must be provided"
# undef CONFIG_STM32_FSMC_SRAM
# endif
#endif
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: up_heap_color
*
* Description:
* Set heap memory to a known, non-zero state to checking heap usage.
*
****************************************************************************/
#ifdef CONFIG_HEAP_COLORATION
static inline void up_heap_color(void *start, size_t size)
{
memset(start, HEAP_COLOR, size);
}
#else
# define up_heap_color(start,size)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_allocate_heap
*
* Description:
* This function will be called to dynamically set aside the heap region.
*
* For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and
* user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the
* size of the unprotected, user-space heap.
*
* If a protected kernel-space heap is provided, the kernel heap must be
* allocated (and protected) by an analogous up_allocate_kheap().
*
* The following memory map is assumed for the flat build:
*
* .data region. Size determined at link time.
* .bss region Size determined at link time.
* IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE.
* Heap. Extends to the end of SRAM.
*
* The following memory map is assumed for the kernel build:
*
* Kernel .data region. Size determined at link time.
* Kernel .bss region Size determined at link time.
* Kernel IDLE thread stack. Size given by CONFIG_IDLETHREAD_STACKSIZE.
* Padding for alignment
* User .data region. Size determined at link time.
* User .bss region Size determined at link time.
* Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE.
* User heap. Extends to the end of SRAM.
*
****************************************************************************/
void up_allocate_heap(void **heap_start, size_t *heap_size)
{
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
/* Get the unaligned size and position of the user-space heap.
* This heap begins after the user-space .bss section at an offset
* of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
*/
uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend +
CONFIG_MM_KERNEL_HEAPSIZE;
size_t usize = SRAM1_END - ubase;
int log2;
DEBUGASSERT(ubase < (uintptr_t)SRAM1_END);
/* Adjust that size to account for MPU alignment requirements.
* NOTE that there is an implicit assumption that the SRAM1_END
* is aligned to the MPU requirement.
*/
log2 = (int)mpu_log2regionfloor(usize);
DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0);
usize = (1 << log2);
ubase = SRAM1_END - usize;
/* Return the user-space heap settings */
board_autoled_on(LED_HEAPALLOCATE);
*heap_start = (void *)ubase;
*heap_size = usize;
/* Colorize the heap for debug */
up_heap_color((void *)ubase, usize);
/* Allow user-mode access to the user heap memory */
stm32_mpu_uheap((uintptr_t)ubase, usize);
#else
/* Return the heap settings */
board_autoled_on(LED_HEAPALLOCATE);
*heap_start = (void *)g_idle_topstack;
*heap_size = SRAM1_END - g_idle_topstack;
/* Colorize the heap for debug */
up_heap_color(*heap_start, *heap_size);
#endif
}
/****************************************************************************
* Name: up_allocate_kheap
*
* Description:
* For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and
* user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates
* (and protects) the kernel-space heap.
*
****************************************************************************/
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
void up_allocate_kheap(void **heap_start, size_t *heap_size)
{
/* Get the unaligned size and position of the user-space heap.
* This heap begins after the user-space .bss section at an offset
* of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
*/
uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend +
CONFIG_MM_KERNEL_HEAPSIZE;
size_t usize = SRAM1_END - ubase;
int log2;
DEBUGASSERT(ubase < (uintptr_t)SRAM1_END);
/* Adjust that size to account for MPU alignment requirements.
* NOTE that there is an implicit assumption that the SRAM1_END
* is aligned to the MPU requirement.
*/
log2 = (int)mpu_log2regionfloor(usize);
DEBUGASSERT((SRAM1_END & ((1 << log2) - 1)) == 0);
usize = (1 << log2);
ubase = SRAM1_END - usize;
/* Return the kernel heap settings (i.e., the part of the heap region
* that was not dedicated to the user heap).
*/
*heap_start = (void *)USERSPACE->us_bssend;
*heap_size = ubase - (uintptr_t)USERSPACE->us_bssend;
}
#endif
/****************************************************************************
* Name: arm_addregion
*
* Description:
* Memory may be added in non-contiguous chunks. Additional chunks are
* added by calling this function.
*
****************************************************************************/
#if CONFIG_MM_REGIONS > 1
void arm_addregion(void)
{
#ifdef CONFIG_STM32_SRAM2_HEAP
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the SRAM2 heap */
stm32_mpu_uheap((uintptr_t)SRAM2_START, SRAM2_END - SRAM2_START);
#endif
/* Colorize the heap for debug */
up_heap_color((void *)SRAM2_START, SRAM2_END - SRAM2_START);
/* Add the SRAM2 user heap region. */
kumm_addregion((void *)SRAM2_START, SRAM2_END - SRAM2_START);
#endif /* SRAM2 */
#ifdef CONFIG_STM32_SRAM3_HEAP
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the SRAM3 heap */
stm32_mpu_uheap((uintptr_t)SRAM3_START, SRAM3_END - SRAM3_START);
#endif
/* Colorize the heap for debug */
up_heap_color((void *)SRAM3_START, SRAM3_END - SRAM3_START);
/* Add the SRAM3 user heap region. */
kumm_addregion((void *)SRAM3_START, SRAM3_END - SRAM3_START);
#endif /* SRAM3 */
#ifdef CONFIG_STM32_FSMC_SRAM_HEAP
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the FSMC SRAM user heap memory */
stm32_mpu_uheap((uintptr_t)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
#endif
/* Colorize the heap for debug */
up_heap_color((void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
/* Add the external FSMC SRAM user heap region. */
kumm_addregion((void *)CONFIG_HEAP2_BASE, CONFIG_HEAP2_SIZE);
#endif
}
#endif

View file

@ -40,7 +40,7 @@
#include "arm_internal.h"
#include "chip.h"
#include "stm32_gpio.h"
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
#ifdef CONFIG_DEBUG_FEATURES

View file

@ -45,7 +45,7 @@
#include <sys/param.h>
#include <nuttx/mutex.h>
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
#include "stm32_waste.h"
#include "stm32l5_flash.h"
#include "arm_internal.h"

View file

@ -1,102 +0,0 @@
/****************************************************************************
* arch/arm/src/stm32l5/stm32l5_idle.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <arch/board/board.h>
#include <nuttx/config.h>
#include <nuttx/debug.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/board.h>
#include <nuttx/power/pm.h>
#include "chip.h"
#include "stm32l5_rcc.h"
#include "arm_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Does the board support an IDLE LED to indicate that the board is in the
* IDLE state?
*/
#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE)
# define BEGIN_IDLE() board_autoled_on(LED_IDLE)
# define END_IDLE() board_autoled_off(LED_IDLE)
#else
# define BEGIN_IDLE()
# define END_IDLE()
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
#define up_idlepm()
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_idle
*
* Description:
* up_idle() is the logic that will be executed when their is no other
* ready-to-run task. This is processor idle time and will continue until
* some interrupt occurs to cause a context switch from the idle task.
*
* Processing in this state may be processor-specific. e.g., this is where
* power management operations might be performed.
*
****************************************************************************/
void up_idle(void)
{
#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
/* If the system is idle and there are no timer interrupts, then process
* "fake" timer interrupts. Hopefully, something will wake up.
*/
nxsched_process_timer();
#else
/* Perform IDLE mode power management */
up_idlepm();
/* Sleep until an interrupt occurs to save power. */
#if !(defined(CONFIG_DEBUG_SYMBOLS) && defined(CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG))
BEGIN_IDLE();
asm("WFI");
END_IDLE();
#endif
#endif
}

View file

@ -1,478 +0,0 @@
/****************************************************************************
* arch/arm/src/stm32l5/stm32l5_irq.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <arch/irq.h>
#include <arch/armv8-m/nvicpri.h>
#include "nvic.h"
#include "ram_vectors.h"
#include "arm_internal.h"
#include "stm32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Get a 32-bit version of the default priority */
#define DEFPRIORITY32 \
(NVIC_SYSH_PRIORITY_DEFAULT << 24 | \
NVIC_SYSH_PRIORITY_DEFAULT << 16 | \
NVIC_SYSH_PRIORITY_DEFAULT << 8 | \
NVIC_SYSH_PRIORITY_DEFAULT)
/* Given the address of a NVIC ENABLE register, this is the offset to
* the corresponding CLEAR ENABLE register.
*/
#define NVIC_ENA_OFFSET (0)
#define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE)
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_dumpnvic
*
* Description:
* Dump some interesting NVIC registers
*
****************************************************************************/
#if defined(CONFIG_DEBUG_IRQ_INFO)
static void stm32_dumpnvic(const char *msg, int irq)
{
irqstate_t flags;
flags = enter_critical_section();
irqinfo("NVIC (%s, irq=%d):\n", msg, irq);
irqinfo(" INTCTRL: %08" PRIx32 " VECTAB: %08" PRIx32 "\n",
getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB));
irqinfo(" IRQ ENABLE: %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n",
getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE),
getreg32(NVIC_IRQ64_95_ENABLE));
irqinfo(" SYSH_PRIO: %08" PRIx32 " %08" PRIx32 " %08" PRIx32 "\n",
getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY),
getreg32(NVIC_SYSH12_15_PRIORITY));
irqinfo(" IRQ PRIO: %08" PRIx32 " %08" PRIx32
" %08" PRIx32 " %08" PRIx32 "\n",
getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY),
getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY));
irqinfo(" %08" PRIx32 " %08" PRIx32
" %08" PRIx32 " %08" PRIx32 "\n",
getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY),
getreg32(NVIC_IRQ24_27_PRIORITY),
getreg32(NVIC_IRQ28_31_PRIORITY));
irqinfo(" %08" PRIx32 " %08" PRIx32
" %08" PRIx32 " %08" PRIx32 "\n",
getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY),
getreg32(NVIC_IRQ40_43_PRIORITY),
getreg32(NVIC_IRQ44_47_PRIORITY));
irqinfo(" %08" PRIx32 " %08" PRIx32
" %08" PRIx32 " %08" PRIx32 "\n",
getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY),
getreg32(NVIC_IRQ56_59_PRIORITY),
getreg32(NVIC_IRQ60_63_PRIORITY));
irqinfo(" %08" PRIx32 "\n",
getreg32(NVIC_IRQ64_67_PRIORITY));
leave_critical_section(flags);
}
#else
# define stm32_dumpnvic(msg, irq)
#endif
/****************************************************************************
* Name: stm32_nmi, stm32_pendsv, stm32_pendsv, stm32_reserved
*
* Description:
* Handlers for various exceptions. None are handled and all are fatal
* error conditions. The only advantage these provide over the default
* unexpected interrupt handler is that they provide a diagnostic output.
*
****************************************************************************/
#ifdef CONFIG_DEBUG_FEATURES
static int stm32_nmi(int irq, void *context, void *arg)
{
up_irq_save();
_err("PANIC!!! NMI received\n");
PANIC();
return 0;
}
static int stm32_pendsv(int irq, void *context, void *arg)
{
up_irq_save();
_err("PANIC!!! PendSV received\n");
PANIC();
return 0;
}
static int stm32_reserved(int irq, void *context, void *arg)
{
up_irq_save();
_err("PANIC!!! Reserved interrupt\n");
PANIC();
return 0;
}
#endif
/****************************************************************************
* Name: stm32_prioritize_syscall
*
* Description:
* Set the priority of an exception. This function may be needed
* internally even if support for prioritized interrupts is not enabled.
*
****************************************************************************/
static inline void stm32_prioritize_syscall(int priority)
{
uint32_t regval;
/* SVCALL is system handler 11 */
regval = getreg32(NVIC_SYSH8_11_PRIORITY);
regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK;
regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT);
putreg32(regval, NVIC_SYSH8_11_PRIORITY);
}
/****************************************************************************
* Name: stm32_irqinfo
*
* Description:
* Given an IRQ number, provide the register and bit setting to enable or
* disable the irq.
*
****************************************************************************/
static int stm32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit,
uintptr_t offset)
{
int n;
DEBUGASSERT(irq >= STM32_IRQ_NMI && irq < NR_IRQS);
/* Check for external interrupt */
if (irq >= STM32_IRQ_FIRST)
{
n = irq - STM32_IRQ_FIRST;
*regaddr = NVIC_IRQ_ENABLE(n) + offset;
*bit = (uint32_t)1 << (n & 0x1f);
}
/* Handle processor exceptions. Only a few can be disabled */
else
{
*regaddr = NVIC_SYSHCON;
if (irq == STM32_IRQ_MEMFAULT)
{
*bit = NVIC_SYSHCON_MEMFAULTENA;
}
else if (irq == STM32_IRQ_BUSFAULT)
{
*bit = NVIC_SYSHCON_BUSFAULTENA;
}
else if (irq == STM32_IRQ_USAGEFAULT)
{
*bit = NVIC_SYSHCON_USGFAULTENA;
}
else if (irq == STM32_IRQ_SYSTICK)
{
*regaddr = NVIC_SYSTICK_CTRL;
*bit = NVIC_SYSTICK_CTRL_ENABLE;
}
else
{
return ERROR; /* Invalid or unsupported exception */
}
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_irqinitialize
****************************************************************************/
void up_irqinitialize(void)
{
uint32_t regaddr;
int num_priority_registers;
int i;
/* Disable all interrupts */
for (i = 0; i < NR_IRQS - STM32_IRQ_FIRST; i += 32)
{
putreg32(0xffffffff, NVIC_IRQ_CLEAR(i));
}
/* The standard location for the vector table is at the beginning of FLASH
* at address 0x0800:0000. If we are using the STMicro DFU bootloader,
* then the vector table will be offset to a different location in FLASH
* and we will need to set the NVIC vector location to this alternative
* location.
*/
putreg32((uint32_t)_vectors, NVIC_VECTAB);
#ifdef CONFIG_ARCH_RAMVECTORS
/* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
* vector table that requires special initialization.
*/
up_ramvec_initialize();
#endif
/* Set all interrupts (and exceptions) to the default priority */
putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);
/* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
* lines that the NVIC supports:
*
* 0 -> 32 interrupt lines, 8 priority registers
* 1 -> 64 " " " ", 16 priority registers
* 2 -> 96 " " " ", 32 priority registers
* ...
*/
num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;
/* Now set all of the interrupt lines to the default priority */
regaddr = NVIC_IRQ0_3_PRIORITY;
while (num_priority_registers--)
{
putreg32(DEFPRIORITY32, regaddr);
regaddr += 4;
}
/* Attach the SVCall and Hard Fault exception handlers. The SVCall
* exception is used for performing context switches; The Hard Fault
* must also be caught because a SVCall may show up as a Hard Fault
* under certain conditions.
*/
irq_attach(STM32_IRQ_SVCALL, arm_svcall, NULL);
irq_attach(STM32_IRQ_HARDFAULT, arm_hardfault, NULL);
/* Set the priority of the SVCall interrupt */
#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
/* If the MPU is enabled, then attach and enable the Memory Management
* Fault handler.
*/
#ifdef CONFIG_ARM_MPU
irq_attach(STM32_IRQ_MEMFAULT, arm_memfault, NULL);
up_enable_irq(STM32_IRQ_MEMFAULT);
#endif
/* Attach all other processor exceptions (except reset and sys tick) */
#ifdef CONFIG_DEBUG_FEATURES
irq_attach(STM32_IRQ_NMI, stm32_nmi, NULL);
#ifndef CONFIG_ARM_MPU
irq_attach(STM32_IRQ_MEMFAULT, arm_memfault, NULL);
#endif
irq_attach(STM32_IRQ_BUSFAULT, arm_busfault, NULL);
irq_attach(STM32_IRQ_USAGEFAULT, arm_usagefault, NULL);
irq_attach(STM32_IRQ_PENDSV, stm32_pendsv, NULL);
arm_enable_dbgmonitor();
irq_attach(STM32_IRQ_DBGMONITOR, arm_dbgmonitor, NULL);
irq_attach(STM32_IRQ_RESERVED, stm32_reserved, NULL);
#endif
stm32_dumpnvic("initial", NR_IRQS);
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* And finally, enable interrupts */
arm_color_intstack();
up_irq_enable();
#endif
}
/****************************************************************************
* Name: up_disable_irq
*
* Description:
* Disable the IRQ specified by 'irq'
*
****************************************************************************/
void up_disable_irq(int irq)
{
uintptr_t regaddr;
uint32_t regval;
uint32_t bit;
if (stm32_irqinfo(irq, &regaddr, &bit, NVIC_CLRENA_OFFSET) == 0)
{
/* Modify the appropriate bit in the register to disable the interrupt.
* For normal interrupts, we need to set the bit in the associated
* Interrupt Clear Enable register. For other exceptions, we need to
* clear the bit in the System Handler Control and State Register.
*/
if (irq >= STM32_IRQ_FIRST)
{
putreg32(bit, regaddr);
}
else
{
regval = getreg32(regaddr);
regval &= ~bit;
putreg32(regval, regaddr);
}
}
}
/****************************************************************************
* Name: up_enable_irq
*
* Description:
* Enable the IRQ specified by 'irq'
*
****************************************************************************/
void up_enable_irq(int irq)
{
uintptr_t regaddr;
uint32_t regval;
uint32_t bit;
if (stm32_irqinfo(irq, &regaddr, &bit, NVIC_ENA_OFFSET) == 0)
{
/* Modify the appropriate bit in the register to enable the interrupt.
* For normal interrupts, we need to set the bit in the associated
* Interrupt Set Enable register. For other exceptions, we need to
* set the bit in the System Handler Control and State Register.
*/
if (irq >= STM32_IRQ_FIRST)
{
putreg32(bit, regaddr);
}
else
{
regval = getreg32(regaddr);
regval |= bit;
putreg32(regval, regaddr);
}
}
}
/****************************************************************************
* Name: arm_ack_irq
*
* Description:
* Acknowledge the IRQ
*
****************************************************************************/
void arm_ack_irq(int irq)
{
}
/****************************************************************************
* Name: up_prioritize_irq
*
* Description:
* Set the priority of an IRQ.
*
* Since this API is not supported on all architectures, it should be
* avoided in common implementations where possible.
*
****************************************************************************/
#ifdef CONFIG_ARCH_IRQPRIO
int up_prioritize_irq(int irq, int priority)
{
uint32_t regaddr;
uint32_t regval;
int shift;
DEBUGASSERT(irq >= STM32_IRQ_MEMFAULT && irq < NR_IRQS &&
(unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
if (irq < STM32_IRQ_FIRST)
{
/* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority
* registers (0-3 are invalid)
*/
regaddr = NVIC_SYSH_PRIORITY(irq);
irq -= 4;
}
else
{
/* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */
irq -= STM32_IRQ_FIRST;
regaddr = NVIC_IRQ_PRIORITY(irq);
}
regval = getreg32(regaddr);
shift = ((irq & 3) << 3);
regval &= ~(0xff << shift);
regval |= (priority << shift);
putreg32(regval, regaddr);
stm32_dumpnvic("prioritize", irq);
return OK;
}
#endif

View file

@ -34,7 +34,7 @@
#include "chip.h"
#include "stm32.h"
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
#include "stm32_gpio.h"
#include "stm32l5_uart.h"

View file

@ -30,7 +30,7 @@
#include "arm_internal.h"
#include "stm32l5_pwr.h"
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
#include "stm32_waste.h"
/****************************************************************************

View file

@ -26,7 +26,7 @@
#include <nuttx/config.h>
#include "arm_internal.h"
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
/****************************************************************************
* Public Functions

View file

@ -33,7 +33,7 @@
#include "arm_internal.h"
#include "stm32l5_pwr.h"
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
/****************************************************************************
* Private Functions

View file

@ -35,7 +35,7 @@
#include "arm_internal.h"
#include "chip.h"
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
#include "stm32l5_flash.h"
#include "stm32.h"
#include "stm32_waste.h"

View file

@ -55,7 +55,7 @@
#ifdef SERIAL_HAVE_DMA
# include "stm32l5_dma.h"
#endif
#include "stm32l5_rcc.h"
#include "stm32_rcc.h"
#include "arm_internal.h"
/****************************************************************************

View file

@ -1,227 +0,0 @@
/****************************************************************************
* arch/arm/src/stm32l5/stm32l5_start.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/debug.h>
#include <nuttx/init.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "nvic.h"
#include "stm32.h"
#include "stm32_gpio.h"
#include "stm32l5_userspace.h"
#include "stm32l5_start.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Memory Map ***************************************************************/
/* 0x0800:0000 - Beginning of the internal FLASH. Address of vectors.
* Mapped as boot memory address 0x0000:0000 at reset.
* 0x080f:ffff - End of flash region (assuming the max of 2MiB of FLASH).
* 0x2000:0000 - Start of internal SRAM1 and start of .data (_sdata)
* - End of .data (_edata) and start of .bss (_sbss)
* - End of .bss (_ebss) and bottom of idle stack
* - _ebss + CONFIG_IDLETHREAD_STACKSIZE = end of idle stack,
* start of heap. NOTE that the ARM uses a decrement before
* store stack so that the correct initial value is the end of
* the stack + 4;
* 0x2002:ffff - End of internal SRAM1
* 0x2003:0000 - Start of internal SRAM2
* 0x2003:ffff - End of internal SRAM2
*/
#define SRAM2_START STM32_SRAM2_BASE
#define SRAM2_END (SRAM2_START + STM32_SRAM2_SIZE)
#define HEAP_BASE ((uintptr_t)_ebss + CONFIG_IDLETHREAD_STACKSIZE)
/* g_idle_topstack: _sbss is the start of the BSS region as defined by the
* linker script. _ebss lies at the end of the BSS region. The idle task
* stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE.
* The IDLE thread is the thread that the system boots on and, eventually,
* becomes the IDLE, do nothing task that runs only when there is nothing
* else to run. The heap continues from there until the end of memory.
* g_idle_topstack is a read-only variable the provides this computed
* address.
*/
const uintptr_t g_idle_topstack = HEAP_BASE;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: showprogress
*
* Description:
* Print a character on the UART to show boot status.
*
****************************************************************************/
#ifdef CONFIG_DEBUG_FEATURES
# define showprogress(c) arm_lowputc(c)
#else
# define showprogress(c)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef CONFIG_ARMV8M_STACKCHECK
/* we need to get r10 set before we can allow instrumentation calls */
void __start(void) noinstrument_function;
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: __start
*
* Description:
* This is the reset entry point.
*
****************************************************************************/
void __start(void)
{
const uint32_t *src;
uint32_t *dest;
#ifdef CONFIG_ARMV8M_STACKCHECK
/* Set the stack limit before we attempt to call any functions */
__asm__ volatile
("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) :);
#endif
#ifdef CONFIG_STM32_SRAM2_INIT
/* The SRAM2 region is parity checked, but upon power up, it will be in
* a random state and probably invalid with respect to parity, potentially
* generating faults if accessed. If elected, we will write zeros to the
* memory, forcing the parity to be set to a valid state.
* NOTE: this is optional because this may be inappropriate, especially
* if the memory is being used for it's battery backed purpose. In that
* case, the first-time initialization needs to be performed by the board
* under application-specific circumstances. On the other hand, if we're
* using this memory for, say, additional heap space, then this is handy.
*/
for (dest = (uint32_t *)SRAM2_START; dest < (uint32_t *)SRAM2_END; )
{
*dest++ = 0;
}
#endif
/* Configure the UART so that we can get debug output as soon as possible */
stm32_clockconfig();
arm_fpuconfig();
stm32_lowsetup();
stm32_gpioinit();
showprogress('A');
/* Clear .bss. We'll do this inline (vs. calling memset) just to be
* certain that there are no issues with the state of global variables.
*/
for (dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; )
{
*dest++ = 0;
}
showprogress('B');
/* Move the initialized data section from his temporary holding spot in
* FLASH into the correct place in SRAM. The correct place in SRAM is
* give by _sdata and _edata. The temporary location is in FLASH at the
* end of all of the other read-only data (.text, .rodata) at _eronly.
*/
for (src = (const uint32_t *)_eronly,
dest = (uint32_t *)_sdata; dest < (uint32_t *)_edata;
)
{
*dest++ = *src++;
}
showprogress('C');
#ifdef CONFIG_ARMV8M_STACKCHECK
arm_stack_check_init();
#endif
#ifdef CONFIG_ARCH_PERF_EVENTS
up_perf_init((void *)STM32_SYSCLK_FREQUENCY);
#endif
/* Perform early serial initialization */
#ifdef USE_EARLYSERIALINIT
arm_earlyserialinit();
#endif
showprogress('D');
/* For the case of the separate user-/kernel-space build, perform whatever
* platform specific initialization of the user memory is required.
* Normally this just means initializing the user space .data and .bss
* segments.
*/
#ifdef CONFIG_BUILD_PROTECTED
stm32_userspace();
showprogress('E');
#endif
/* Initialize onboard resources */
stm32_board_initialize();
showprogress('F');
/* Then start NuttX */
showprogress('\r');
showprogress('\n');
nx_start();
/* Shoulnd't get here */
for (; ; );
}

View file

@ -1,47 +0,0 @@
/****************************************************************************
* arch/arm/src/stm32l5/stm32l5_start.h
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_STM32L5_STM32L5_START_H
#define __ARCH_ARM_SRC_STM32L5_STM32L5_START_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: stm32_board_initialize
*
* Description:
* All STM32L5 architectures must provide the following entry point. This
* entry point is called early in the initialization -- after all memory
* has been configured and mapped but before any devices have been
* initialized.
*
****************************************************************************/
void stm32_board_initialize(void);
#endif /* __ARCH_ARM_SRC_STM32L5_STM32L5_START_H */

View file

@ -1,150 +0,0 @@
/****************************************************************************
* arch/arm/src/stm32l5/stm32l5_timerisr.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <time.h>
#include <nuttx/debug.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include "nvic.h"
#include "clock/clock.h"
#include "arm_internal.h"
#include "chip.h"
#include "stm32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* The desired timer interrupt frequency is provided by the definition
* CLK_TCK (see include/time.h). CLK_TCK defines the desired number of
* system clock ticks per second. That value is a user configurable setting
* that defaults to 100 (100 ticks per second = 10 MS interval).
*
* The RCC feeds the Cortex System Timer (SysTick) with the AHB clock (HCLK)
* divided by 8. The SysTick can work either with this clock or with the
* Cortex clock (HCLK), configurable in the SysTick Control and Status
* register.
*/
/* Power up default is HCLK, not HCLK/8.
* And I don't know now to re-configure it yet
*/
#undef CONFIG_STM32_SYSTICK_HCLKd8
#ifdef CONFIG_STM32_SYSTICK_HCLKd8
# define SYSTICK_RELOAD ((STM32_HCLK_FREQUENCY / 8 / CLK_TCK) - 1)
#else
# define SYSTICK_RELOAD ((STM32_HCLK_FREQUENCY / CLK_TCK) - 1)
#endif
/* The size of the reload field is 24 bits. Verify that the reload value
* will fit in the reload register.
*/
#if SYSTICK_RELOAD > 0x00ffffff
# error SYSTICK_RELOAD exceeds the range of the RELOAD register
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Function: stm32_timerisr
*
* Description:
* The timer ISR will perform a variety of services for various portions
* of the systems.
*
****************************************************************************/
static int stm32_timerisr(int irq, uint32_t *regs, void *arg)
{
/* Process timer interrupt */
nxsched_process_timer();
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: up_timer_initialize
*
* Description:
* This function is called during start-up to initialize
* the timer interrupt.
*
****************************************************************************/
void up_timer_initialize(void)
{
uint32_t regval;
/* Set the SysTick interrupt to the default priority */
regval = getreg32(NVIC_SYSH12_15_PRIORITY);
regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK;
regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT);
putreg32(regval, NVIC_SYSH12_15_PRIORITY);
/* Make sure that the SYSTICK clock source is set correctly */
#if 0 /* Does not work. Comes up with HCLK source and I can't change it */
regval = getreg32(NVIC_SYSTICK_CTRL);
#ifdef CONFIG_STM32_SYSTICK_HCLKd8
regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE;
#else
regval |= NVIC_SYSTICK_CTRL_CLKSOURCE;
#endif
putreg32(regval, NVIC_SYSTICK_CTRL);
#endif
/* Configure SysTick to interrupt at the requested rate */
putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD);
/* Attach the timer interrupt vector */
irq_attach(STM32_IRQ_SYSTICK, (xcpt_t)stm32_timerisr, NULL);
/* Enable SysTick interrupts */
putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE | NVIC_SYSTICK_CTRL_TICKINT |
NVIC_SYSTICK_CTRL_ENABLE), NVIC_SYSTICK_CTRL);
/* And enable the timer interrupt */
up_enable_irq(STM32_IRQ_SYSTICK);
}