1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #1291 from haukepetersen/board_stm32f0discovery

Board stm32f0discovery
This commit is contained in:
Hauke Petersen 2014-07-16 15:41:17 +02:00
commit 9b88a9e6ec
55 changed files with 9180 additions and 31 deletions

View File

@ -0,0 +1,4 @@
# tell the Makefile.base which module to build
MODULE = $(BOARD)_base
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,48 @@
# define the cpu used by the stm32f0-discovery board
export CPU = stm32f0
export CPU_MODEL = stm32f051r8
#define the default port depending on the host OS
OS := $(shell uname)
ifeq ($(OS),Linux)
PORT ?= /dev/ttyUSB0
else ifeq ($(OS),Darwin)
PORT ?= $(shell ls -1 /dev/tty.SLAB_USBtoUART* | head -n 1)
else
$(info CAUTION: No flash tool for your host system found!)
# TODO: add support for windows as host platform
endif
export PORT
# define tools used for building the project
export PREFIX = arm-none-eabi-
export CC = $(PREFIX)gcc
export AR = $(PREFIX)ar
export AS = $(PREFIX)as
export LINK = $(PREFIX)gcc
export SIZE = $(PREFIX)size
export OBJCOPY = $(PREFIX)objcopy
export TERMPROG = $(RIOTBASE)/dist/tools/pyterm/pyterm.py
export FLASHER = st-flash
export DEBUGGER = $(RIOTBOARD)/$(BOARD)/dist/debug.sh
# define build specific options
CPU_USAGE = -mcpu=cortex-m0
FPU_USAGE =
export CFLAGS += -ggdb -g3 -std=gnu99 -Os -Wall -Wstrict-prototypes $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian -mthumb -mthumb-interwork -nostartfiles
export CFLAGS += -ffunction-sections -fdata-sections -fno-builtin
export ASFLAGS += -ggdb -g3 $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian
export LINKFLAGS += -g3 -ggdb -std=gnu99 $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian -static -lgcc -mthumb -mthumb-interwork -nostartfiles
# $(LINKERSCRIPT) is specified in cpu/Makefile.include
export LINKFLAGS += -T$(LINKERSCRIPT)
export OFLAGS = -O binary
export FFLAGS = write bin/$(BOARD)/$(APPLICATION).hex 0x08000000
export DEBUGGER_FLAGS = $(RIOTBOARD)/$(BOARD)/dist/gdb.conf bin/$(BOARD)/$(APPLICATION).elf
# use the nano-specs of the NewLib when available
ifeq ($(shell $(LINK) -specs=nano.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
export LINKFLAGS += -specs=nano.specs -lc -lnosys
endif
# export board specific includes to the global includes-listing
export INCLUDES += -I$(RIOTBOARD)/$(BOARD)/include

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup board_stm32f0discovery
* @{
*
* @file
* @brief Board specific implementations for the STM32F0Discovery evaluation board
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "board.h"
#include "periph/uart.h"
static void leds_init(void);
void board_init(void)
{
/* initialize the boards LEDs */
leds_init();
/* initialize the CPU */
cpu_init();
}
/**
* @brief Initialize the boards on-board LEDs (LD3 and LD4)
*
* The LED initialization is hard-coded in this function. As the LEDs are soldered
* onto the board they are fixed to their CPU pins.
*
* The LEDs are connected to the following pins:
* - LD3: PC8
* - LD4: PC9
*/
void leds_init(void)
{
/* enable clock for port GPIOC */
RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
/* set output speed to 50MHz */
LED_PORT->OSPEEDR |= 0x000f0000;
/* set output type to push-pull */
LED_PORT->OTYPER &= ~(0x00000300);
/* configure pins as general outputs */
LED_PORT->MODER &= ~(0x000f0000);
LED_PORT->MODER |= 0x00050000;
/* disable pull resistors */
LED_PORT->PUPDR &= ~(0x000f0000);
/* turn all LEDs off */
LED_PORT->BRR = 0x0300;
}

4
boards/stm32f0discovery/dist/debug.sh vendored Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
echo "Debugging $1"
arm-none-eabi-gdb -tui -command=$1 $2

1
boards/stm32f0discovery/dist/gdb.conf vendored Normal file
View File

@ -0,0 +1 @@
tar extended-remote :4242

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup board_stm32f0discovery STM32F0Discovery
* @ingroup boards
* @brief Support for the STM32F0Discovery board
* @{
*
* @file
* @brief Board specific definitions for the STM32F0Discovery evaluation board.
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __BOARD_H
#define __BOARD_H
#include "cpu.h"
/**
* @name The nominal CPU core clock in this board
*/
#define F_CPU (48000000UL)
/**
* @name Assign the peripheral timer to be used as hardware timer
*/
#define HW_TIMER TIMER_0
/**
* @name Assign the UART interface to be used for stdio
*/
#define STDIO UART_0
/**
* @name LED pin definitions
* @{
*/
#define LED_PORT GPIOC
#define LD3_PIN (1 << 9)
#define LD4_PIN (1 << 8)
/** @} */
/**
* @name Macros for controlling the on-board LEDs.
* @{
*/
#define LD3_ON (LED_PORT->BSRR = LD3_PIN)
#define LD3_OFF (LED_PORT->BRR = LD3_PIN)
#define LD3_TOGGLE (LED_PORT->ODR ^= LD3_PIN)
#define LD4_ON (LED_PORT->BSRR = LD4_PIN)
#define LD4_OFF (LED_PORT->BRR = LD4_PIN)
#define LD4_TOGGLE (LED_PORT->ODR ^= LD4_PIN)
/* for compatibility to other boards */
#define LED_GREEN_ON LD4_ON
#define LED_GREEN_OFF LD4_OFF
#define LED_GREEN_TOGGLE LD4_TOGGLE
#define LED_RED_ON LD3_ON
#define LED_RED_OFF LD3_OFF
#define LED_RED_TOGGLE LD3_TOGGLE
/** @} */
/**
* @brief Initialize board specific hardware, including clock, LEDs and std-IO
*/
void board_init(void);
#endif /** __BOARD_H */
/** @} */

View File

@ -0,0 +1,376 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup board_stm32f0discovery
* @{
*
* @file
* @brief Peripheral MCU configuration for the STM32F0discovery board
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __PERIPH_CONF_H
#define __PERIPH_CONF_H
/**
* @name Clock system configuration
* @{
*/
#define CLOCK_HSE (8000000U) /* external oscillator */
#define CLOCK_CORECLOCK (48000000U) /* desired core clock frequency */
/* the actual PLL values are automatically generated */
#define CLOCK_PLL_MUL (CLOCK_CORECLOCK / CLOCK_HSE)
/** @} */
/**
* @name Timer configuration
* @{
*/
#define TIMER_NUMOF (1U)
#define TIMER_0_EN 1
#define TIMER_1_EN 0
/* Timer 0 configuration */
#define TIMER_0_DEV TIM2
#define TIMER_0_CHANNELS 4
#define TIMER_0_PRESCALER (47U)
#define TIMER_0_MAX_VALUE (0xffffffff)
#define TIMER_0_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_TIM2EN)
#define TIMER_0_ISR isr_tim2
#define TIMER_0_IRQ_CHAN TIM2_IRQn
#define TIMER_0_IRQ_PRIO 1
/* Timer 1 configuration */
#define TIMER_1_DEV TIMx /* TODO */
#define TIMER_1_CHANNELS
#define TIMER_1_PRESCALER (47U)
#define TIMER_1_MAX_VALUE (0xffff)
#define TIMER_1_CLKEN()
#define TIMER_1_ISR
#define TIMER_1_IRQCHAN
#define TIMER_1_IRQ_PRIO
/** @} */
/**
* @name UART configuration
* @{
*/
#define UART_NUMOF (2U)
#define UART_0_EN 1
#define UART_1_EN 1
#define UART_IRQ_PRIO 1
/* UART 0 device configuration */
#define UART_0_DEV USART1
#define UART_0_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_USART1EN)
#define UART_0_IRQ USART1_IRQn
#define UART_0_ISR isr_usart1
/* UART 0 pin configuration */
#define UART_0_PORT GPIOB
#define UART_0_PORT_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOBEN)
#define UART_0_RX_PIN 7
#define UART_0_TX_PIN 6
#define UART_0_AF 0
/* UART 1 device configuration */
#define UART_1_DEV USART2
#define UART_1_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_USART2EN)
#define UART_1_IRQ USART2_IRQn
#define UART_1_ISR isr_usart2
/* UART 1 pin configuration */
#define UART_1_PORT GPIOA
#define UART_1_PORT_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOAEN)
#define UART_1_RX_PIN 3
#define UART_1_TX_PIN 2
#define UART_1_AF 1
/** @} */
/**
* @name ADC configuration
* @{
*/
#define ADC_NUMOF (0U)
#define ADC_0_EN 0
#define ADC_1_EN 0
/* ADC 0 configuration */
#define ADC_0_DEV ADC1 /* TODO */
#define ADC_0_SAMPLE_TIMER
/* ADC 0 channel 0 pin config */
#define ADC_0_C0_PORT
#define ADC_0_C0_PIN
#define ADC_0_C0_CLKEN()
#define ADC_0_C0_AFCFG()
/* ADC 0 channel 1 pin config */
#define ADC_0_C1_PORT
#define ADC_0_C1_PIN
#define ADC_0_C1_CLKEN()
#define ADC_0_C1_AFCFG()
/* ADC 0 channel 2 pin config */
#define ADC_0_C2_PORT
#define ADC_0_C2_PIN
#define ADC_0_C2_CLKEN()
#define ADC_0_C2_AFCFG()
/* ADC 0 channel 3 pin config */
#define ADC_0_C3_PORT
#define ADC_0_C3_PIN
#define ADC_0_C3_CLKEN()
#define ADC_0_C3_AFCFG()
/* ADC 0 configuration */
#define ADC_1_DEV ADC2 /* TODO */
#define ADC_1_SAMPLE_TIMER
/* ADC 0 channel 0 pin config */
#define ADC_1_C0_PORT
#define ADC_1_C0_PIN
#define ADC_1_C0_CLKEN()
#define ADC_1_C0_AFCFG()
/* ADC 0 channel 1 pin config */
#define ADC_1_C1_PORT
#define ADC_1_C1_PIN
#define ADC_1_C1_CLKEN()
#define ADC_1_C1_AFCFG()
/* ADC 0 channel 2 pin config */
#define ADC_1_C2_PORT
#define ADC_1_C2_PIN
#define ADC_1_C2_CLKEN()
#define ADC_1_C2_AFCFG()
/* ADC 0 channel 3 pin config */
#define ADC_1_C3_PORT
#define ADC_1_C3_PIN
#define ADC_1_C3_CLKEN()
#define ADC_1_C3_AFCFG()
/** @} */
/**
* @name PWM configuration
* @{
*/
#define PWM_NUMOF (0U) /* TODO */
#define PWM_0_EN 0
#define PWM_1_EN 0
/* PWM 0 device configuration */
#define PWM_0_DEV
#define PWM_0_CHANNELS
/* PWM 0 pin configuration */
#define PWM_0_PORT
#define PWM_0_PINS
#define PWM_0_PORT_CLKEN()
#define PWM_0_CH1_AFCFG()
#define PWM_0_CH2_AFCFG()
#define PWM_0_CH3_AFCFG()
#define PWM_0_CH4_AFCFG()
/* PWM 1 device configuration */
#define PWM_1_DEV
#define PWM_1_CHANNELS
/* PWM 1 pin configuration */
#define PWM_1_PORT
#define PWM_1_PINS
#define PWM_1_PORT_CLKEN()
#define PWM_1_CH1_AFCFG()
#define PWM_1_CH2_AFCFG()
#define PWM_1_CH3_AFCFG()
#define PWM_1_CH4_AFCFG()
/** @} */
/**
* @name SPI configuration
* @{
*/
#define SPI_NUMOF (0U) /* TODO */
#define SPI_0_EN 0
#define SPI_1_EN 0
/* SPI 0 device config */
#define SPI_0_DEV
#define SPI_0_CLKEN()
#define SPI_0_IRQ SPI1_IRQn
#define SPI_0_IRQ_HANDLER
#define SPI_0_IRQ_PRIO 1
/* SPI 1 pin configuration */
#define SPI_0_PORT
#define SPI_0_PINS
#define SPI_1_PORT_CLKEN()
#define SPI_1_SCK_AFCFG()
#define SPI_1_MISO_AFCFG()
#define SPI_1_MOSI_AFCFG()
/* SPI 1 device config */
#define SPI_1_DEV SPI2
#define SPI_1_CLKEN()
#define SPI_1_IRQ SPI2_IRQn
#define SPI_1_IRQ_HANDLER
#define SPI_1_IRQ_PRIO 1
/* SPI 1 pin configuration */
#define SPI_1_PORT
#define SPI_1_PINS
#define SPI_1_PORT_CLKEN()
#define SPI_1_SCK_AFCFG()
#define SPI_1_MISO_AFCFG()
#define SPI_1_MOSI_AFCFG()
/** @} */
/**
* @name I2C configuration
* @{
*/
#define I2C_NUMOF (0U) /* TODO */
#define I2C_0_EN 0
#define I2C_0_EN 0
/* SPI 0 device configuration */
#define I2C_0_DEV I2C1
#define I2C_0_CLKEN()
#define I2C_0_ISR isr_i2c1
#define I2C_0_IRQ I2C1_IRQn
#define I2C_0_IRQ_PRIO 1
/* SPI 0 pin configuration */
#define I2C_0_PORT
#define I2C_0_PINS
#define I2C_0_PORT_CLKEN()
#define I2C_0_SCL_AFCFG()
#define I2C_0_SDA_AFCFG()
/* SPI 1 device configuration */
#define I2C_1_DEV I2C2
#define I2C_1_CLKEN()
#define I2C_1_ISR isr_i2c2
#define I2C_1_IRQ I2C2_IRQn
#define I2C_1_IRQ_PRIO 1
/* SPI 1 pin configuration */
#define I2C_1_PORT
#define I2C_1_PINS
#define I2C_1_PORT_CLKEN()
#define I2C_1_SCL_AFCFG()
#define I2C_1_SDA_AFCFG()
/** @} */
/**
* @name GPIO configuration
* @{
*/
#define GPIO_NUMOF 12
#define GPIO_0_EN 1
#define GPIO_1_EN 1
#define GPIO_2_EN 1
#define GPIO_3_EN 1
#define GPIO_4_EN 1
#define GPIO_5_EN 1
#define GPIO_6_EN 1
#define GPIO_7_EN 1
#define GPIO_8_EN 1
#define GPIO_9_EN 1
#define GPIO_10_EN 1
#define GPIO_11_EN 1
#define GPIO_IRQ_PRIO 1
/* IRQ config */
#define GPIO_IRQ_0 GPIO_0
#define GPIO_IRQ_1 GPIO_1
#define GPIO_IRQ_2 GPIO_0 /* not configured */
#define GPIO_IRQ_3 GPIO_0 /* not configured */
#define GPIO_IRQ_4 GPIO_2
#define GPIO_IRQ_5 GPIO_3
#define GPIO_IRQ_6 GPIO_4
#define GPIO_IRQ_7 GPIO_5
#define GPIO_IRQ_8 GPIO_0 /* not configured */
#define GPIO_IRQ_9 GPIO_0 /* not configured */
#define GPIO_IRQ_10 GPIO_6
#define GPIO_IRQ_11 GPIO_7
#define GPIO_IRQ_12 GPIO_8
#define GPIO_IRQ_13 GPIO_9
#define GPIO_IRQ_14 GPIO_10
#define GPIO_IRQ_15 GPIO_11
/* GPIO channel 0 config */
#define GPIO_0_PORT GPIOA /* Used for user button 1 */
#define GPIO_0_PIN 0
#define GPIO_0_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOAEN)
#define GPIO_0_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA)
#define GPIO_0_IRQ EXTI0_1_IRQn
/* GPIO channel 1 config */
#define GPIO_1_PORT GPIOA
#define GPIO_1_PIN 1
#define GPIO_1_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOAEN)
#define GPIO_1_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI1_PA)
#define GPIO_1_IRQ EXTI0_1_IRQn
/* GPIO channel 2 config */
#define GPIO_2_PORT GPIOF
#define GPIO_2_PIN 4
#define GPIO_2_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOFEN)
#define GPIO_2_EXTI_CFG() (SYSCFG->EXTICR[1] |= SYSCFG_EXTICR2_EXTI4_PF)
#define GPIO_2_IRQ EXTI4_15_IRQn
/* GPIO channel 3 config */
#define GPIO_3_PORT GPIOF
#define GPIO_3_PIN 5
#define GPIO_3_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOFEN)
#define GPIO_3_EXTI_CFG() (SYSCFG->EXTICR[1] |= SYSCFG_EXTICR2_EXTI5_PF)
#define GPIO_3_IRQ EXTI4_15_IRQn
/* GPIO channel 4 config */
#define GPIO_4_PORT GPIOF
#define GPIO_4_PIN 6
#define GPIO_4_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOFEN)
#define GPIO_4_EXTI_CFG() (SYSCFG->EXTICR[1] |= SYSCFG_EXTICR2_EXTI6_PF)
#define GPIO_4_IRQ EXTI4_15_IRQn
/* GPIO channel 5 config */
#define GPIO_5_PORT GPIOF
#define GPIO_5_PIN 7
#define GPIO_5_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOFEN)
#define GPIO_5_EXTI_CFG() (SYSCFG->EXTICR[1] |= SYSCFG_EXTICR2_EXTI7_PF)
#define GPIO_5_IRQ EXTI4_15_IRQn
/* GPIO channel 6 config */
#define GPIO_6_PORT GPIOC
#define GPIO_6_PIN 10
#define GPIO_6_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOCEN)
#define GPIO_6_EXTI_CFG() (SYSCFG->EXTICR[2] |= SYSCFG_EXTICR3_EXTI10_PC)
#define GPIO_6_IRQ EXTI4_15_IRQn
/* GPIO channel 7 config */
#define GPIO_7_PORT GPIOC
#define GPIO_7_PIN 11
#define GPIO_7_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOCEN)
#define GPIO_7_EXTI_CFG() (SYSCFG->EXTICR[2] |= SYSCFG_EXTICR3_EXTI11_PC)
#define GPIO_7_IRQ EXTI4_15_IRQn
/* GPIO channel 8 config */
#define GPIO_8_PORT GPIOC
#define GPIO_8_PIN 12
#define GPIO_8_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOCEN)
#define GPIO_8_EXTI_CFG() (SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI12_PC)
#define GPIO_8_IRQ EXTI4_15_IRQn
/* GPIO channel 9 config */
#define GPIO_9_PORT GPIOC
#define GPIO_9_PIN 13
#define GPIO_9_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOCEN)
#define GPIO_9_EXTI_CFG() (SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI13_PC)
#define GPIO_9_IRQ EXTI4_15_IRQn
/* GPIO channel 10 config */
#define GPIO_10_PORT GPIOC
#define GPIO_10_PIN 14
#define GPIO_10_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOCEN)
#define GPIO_10_EXTI_CFG() (SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI14_PC)
#define GPIO_10_IRQ EXTI4_15_IRQn
/* GPIO channel 11 config */
#define GPIO_11_PORT GPIOC
#define GPIO_11_PIN 15
#define GPIO_11_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOCEN)
#define GPIO_11_EXTI_CFG() (SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI15_PC)
#define GPIO_11_IRQ EXTI4_15_IRQn
/** @} */
#endif /* __PERIPH_CONF_H */

View File

@ -0,0 +1,4 @@
# define the module that is build
MODULE = cortex-m0_common
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,2 @@
# include module specific includes
export INCLUDES += -I$(RIOTCPU)/cortex-m0_common/include

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_cortexm0_common
* @{
*
* @file
* @brief Implementation of the kernels atomic interface
*
* @author Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "arch/atomic_arch.h"
#include "irq.h"
unsigned int atomic_arch_set_return(unsigned int *to_set, unsigned int value)
{
disableIRQ();
unsigned int old = *to_set;
*to_set = value;
enableIRQ();
return old;
}

View File

@ -0,0 +1,682 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V3.20
* @date 25. February 2013
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex_M0
@{
*/
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00) /*!< Cortex-M Core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#define __STATIC_INLINE static __inline
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
#define __STATIC_INLINE static inline
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#define __STATIC_INLINE static inline
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#define __STATIC_INLINE static inline
#endif
/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all
*/
#define __FPU_USED 0
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0_REV
#define __CM0_REV 0x0000
#warning "__CM0_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/*@} end of group Cortex_M0 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/** \defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
#else
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
#endif
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
#else
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
#endif
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/** \brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/*@} end of group CMSIS_CORE */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR)
are only accessible over DAP and not via processor. Therefore
they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Cortex-M0 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \brief Enable External Interrupt
The function enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Disable External Interrupt
The function disables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Get Pending Interrupt
The function reads the pending register in the NVIC and returns the pending bit
for the specified interrupt.
\param [in] IRQn Interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/** \brief Set Pending Interrupt
The function sets the pending bit of an external interrupt.
\param [in] IRQn Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Clear Pending Interrupt
The function clears the pending bit of an external interrupt.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \brief Set Interrupt Priority
The function sets the priority of an interrupt.
\note The priority cannot be set for every core interrupt.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \brief Get Interrupt Priority
The function reads the priority of an interrupt. The interrupt
number can be positive to specify an external (device specific)
interrupt, or negative to specify an internal (core) interrupt.
\param [in] IRQn Interrupt number.
\return Interrupt Priority. Value is aligned automatically to the implemented
priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
else {
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \brief System Reset
The function initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if (__Vendor_SysTickConfig == 0)
/** \brief System Tick Configuration
The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#endif /* __CORE_CM0_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,609 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V2.10
* @date 26. July 2011
*
* @note
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
static __INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
static __INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
static __INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
static __INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
static __INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
static __INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
static __INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
static __INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
static __INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
static __INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
static __INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
static __INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@ -0,0 +1,585 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V2.10
* @date 19. July 2011
*
* @note
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
static __INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
static __INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) static __INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) static __INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup cpu_cortexm0_common ARM Cortex-M0 common
* @ingroup cpu
* @brief Common implementations and headers for Cortex-M0 family based micro-controllers
* @{
*
* @file
* @brief Basic definitions for the Cortex-M0 common module
*
* When ever you want to do something hardware related, that is accessing MCUs registers directly,
* just include this file. It will then make sure that the MCU specific headers are included.
*
* @author Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __CPU_H
#define __CPU_H
#include "cpu-conf.h"
/**
* For downwards compatibility with old RIOT code.
* TODO: remove once core was adjusted
*/
#include "irq.h"
#define eINT enableIRQ
#define dINT disableIRQ
/**
* @brief Macro has to be called in the beginning of each ISR
*/
#define ISR_ENTER() asm("push {LR}")
/**
* @brief Macro has to be called on each exit of an ISR
*/
#define ISR_EXIT() asm("pop {r0} \n bx r0")
/**
* @brief Initialization of the CPU
*/
void cpu_init(void);
#endif /* __CPU_H */
/** @} */

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_cortexm0_common
* @{
*
* @file
* @brief Implementation of the kernels irq interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdint.h>
#include "arch/irq_arch.h"
#include "cpu.h"
/**
* @brief Disable all maskable interrupts
*/
unsigned int irq_arch_disable(void)
{
uint32_t mask = __get_PRIMASK();
__disable_irq();
return mask;
}
/**
* @brief Enable all maskable interrupts
*/
unsigned int irq_arch_enable(void)
{
__enable_irq();
return __get_PRIMASK();
}
/**
* @brief Restore the state of the IRQ flags
*/
void irq_arch_restore(unsigned int state)
{
__set_PRIMASK(state);
}
/**
* @brief See if the current context is inside an ISR
*/
int irq_arch_in(void)
{
return (__get_IPSR() & 0xFF);
}

View File

@ -0,0 +1,263 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_cortexm0_common
* @{
*
* @file
* @brief Implementation of the kernel's architecture dependent thread interface
*
* @author Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdio.h>
#include "arch/thread_arch.h"
#include "sched.h"
#include "thread.h"
#include "irq.h"
#include "cpu.h"
#include "kernel_internal.h"
/**
* @name noticeable marker marking the beginning of a stack segment
*
* This marker is used e.g. by *thread_arch_start_threading* to identify the stacks start.
*/
#define STACK_MARKER (0x77777777)
/**
* @name Initial program status register value for a newly created thread
*/
#define INITIAL_XPSR (0x01000000)
/**
* @name ARM Cortex-M specific exception return value, that triggers the return to the task mode
* stack pointer
*/
#define EXCEPT_RET_TASK_MODE (0xfffffffd)
static void context_save(void);
static void context_restore(void);
/**
* THe cortex-M0 knows stacks and handles register backups, so use the following layout:
*
* ----------------------------------------------------------------------------------------------------
* | LR | R8 | R9 | R10 | R11 | R4 | R5 | R6 | R7 | R0 | R1 | R2 | R3 | R12 | LR | PC | xPSR | MARKER |
* ----------------------------------------------------------------------------------------------------
* | |
* lowest address highest address
*
*/
char *thread_arch_stack_init(void *(*task_func)(void *),
void *arg,
void *stack_start,
int stack_size)
{
uint32_t *stk;
stk = (uint32_t *)(stack_start + stack_size);
/* marker */
stk--;
*stk = (uint32_t)STACK_MARKER;
/* FIXME xPSR */
stk--;
*stk = (uint32_t)INITIAL_XPSR;
/* program counter */
stk--;
*stk = (uint32_t)task_func;
/* link register, jumped to when thread exits */
stk--;
*stk = (uint32_t)sched_task_exit;
/* r12 */
stk--;
*stk = (uint32_t)0;
/* r3 - r1 */
for (int i = 3; i >= 1; i--) {
stk--;
*stk = i;
}
/* r0 -> thread function parameter */
stk--;
*stk = (uint32_t)arg;
/* r7 - r4 */
for (int i = 7; i >= 4; i--) {
stk--;
*stk = i;
}
/* r11 - r8 */
for (int i = 11; i >= 8; i--) {
stk--;
*stk = i;
}
/* lr means exception return code */
stk--;
*stk = (uint32_t)EXCEPT_RET_TASK_MODE; /*return to task-mode main stack pointer */
return (char*) stk;
}
void thread_arch_stack_print(void)
{
int count = 0;
uint32_t *sp = (uint32_t *)sched_active_thread->sp;
printf("printing the current stack of thread %u\n", thread_getpid());
printf(" address: data:\n");
do {
printf(" 0x%08x: 0x%08x\n", (unsigned int)sp, (unsigned int)*sp);
sp++;
count++;
} while (*sp != STACK_MARKER);
printf("current stack size: %i byte\n", count);
}
__attribute__((naked)) void NORETURN thread_arch_start_threading(void)
{
/* enable IRQs to make sure the SVC interrupt can be triggered */
enableIRQ();
/* trigger the SVC interrupt that will schedule and load the next thread */
asm("svc 0x01");
UNREACHABLE();
}
void thread_arch_yield(void)
{
/* trigger the PENDSV interrupt, which runs the scheduler */
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
}
/**
* @brief save the current thread's context to the current thread's stack
*
* This function is always called in interrupt context. For this the initial state is the following:
*
* active stack-pointer: MSP
*
* top of application stack:
* -------- highest address
* | xPSR |
* --------
* | PC |
* --------
* | LR |
* --------
* | R12 |
* --------
* | R3 |
* --------
* | R2 |
* --------
* | R1 |
* --------
* | R0 | <- current value of PSP
* -------- lowest address
*
* With other words, registers R0-R3, R12, LR, PC and xPSR are already saved to the thread's stack.
* This leaves registers R4-R11 to be pushed to the thread's stack for a complete context save.
*
* This function now further pushes the remaining registers to the application stack (PSP)
*/
__attribute__((always_inline)) static __INLINE void context_save(void)
{
/* {r0-r3,r12,LR,PC,xPSR} were saved automatically on exception entry */
/* set stack pointer to PSP while keeping the MSP value */
asm("mrs r0, psp");
asm("mov r12, sp");
asm("mov sp, r0");
/* save registers R11-R4 */
asm("mov r0, r8");
asm("mov r1, r9");
asm("mov r2, r10");
asm("mov r3, r11");
asm("push {r0-r7}");
/* save link register */
asm("mov r0, lr");
asm("push {r0}");
/* switch back stack pointers */
asm("mov r0, sp");
asm("mov sp, r12");
/* store the new psp to the tcb->sp */
asm("ldr r1, =sched_active_thread" );
asm("ldr r1, [r1]");
asm("str r0, [r1]");
}
__attribute__((always_inline)) static __INLINE void context_restore(void)
{
/* save MSR stack pointer for later restore */
asm("mov lr, sp");
/* get the PSP stack pointer of the current thread */
asm("ldr r0, =sched_active_thread");
asm("ldr r0, [r0]");
asm("ldr r0, [r0]");
asm("mov sp, r0");
/* restore exception return value (LR) from stack */
asm("pop {r0}");
asm("mov r12, r0");
/* restore registers R4-R11 from the PSP stack */
asm("pop {r0-r7}");
asm("mov r8, r0");
asm("mov r9, r1");
asm("mov r10, r2");
asm("mov r11, r3");
/* restore the application mode stack pointer PSP */
asm("mov r0, sp");
asm("msr psp, r0");
asm("mov sp, lr");
/* return from exception mode to application mode */
asm("bx r12");
/* {r0-r3,r12,LR,PC,xPSR} are restored automatically on exception return */
}
/**
* @brief The SVC interrupt is used for dispatching a thread if no context exists.
*
* Starting a thread from non-existing context is needed in two situations:
* 1) after system initialization for running the main thread
* 2) after exiting from a thread
*/
__attribute__((naked)) void isr_svc(void)
{
sched_run();
context_restore();
}
/**
* @brief The PENDSV interrupt is used for context switching
*
* This interrupt saves the context, runs the scheduler and restores the context of the thread
* that is run next.
*/
__attribute__((naked)) void isr_pendsv(void)
{
context_save();
sched_run();
context_restore();
}

7
cpu/stm32f0/Makefile Normal file
View File

@ -0,0 +1,7 @@
# define the module that is build
MODULE = cpu
# add a list of subdirectories, that should also be build
DIRS = periph $(CORTEX_COMMON)
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,30 @@
# this CPU implementation is using the new core/CPU interface
export CFLAGS += -DCOREIF_NG=1
# tell the build system that the CPU depends on the Cortex-M common files
export USEMODULE += cortex-m0_common
# define path to cortex-m common module, which is needed for this CPU
export CORTEX_COMMON = $(RIOTCPU)/cortex-m0_common/
# define the linker script to use for this CPU. The CPU_MODEL variable is defined in the
# board's Makefile.include. This enables multiple STMF0 controllers with different memory to
# use the same code-base.
export LINKERSCRIPT = $(RIOTCPU)/$(CPU)/$(CPU_MODEL)_linkerscript.ld
#export the CPU model
MODEL = $(shell echo $(CPU_MODEL)|tr 'a-z' 'A-Z')
export CFLAGS += -DCPU_MODEL_$(MODEL)
# include CPU specific includes
export INCLUDES += -I$(RIOTCPU)/$(CPU)/include
# add the CPU specific system calls implementations for the linker
export UNDEF += $(BINDIR)cpu/syscalls.o
export UNDEF += $(BINDIR)cpu/startup.o
# export the peripheral drivers to be linked into the final binary
export USEMODULE += periph
# CPU depends on the cortex-m common module, so include it
include $(CORTEX_COMMON)Makefile.include

111
cpu/stm32f0/cpu.c Normal file
View File

@ -0,0 +1,111 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Implementation of the CPU initialization
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @}
*/
#include "cpu.h"
#include "periph_conf.h"
static void clock_init(void);
/**
* @brief Initialize the CPU, set IRQ priorities
*/
void cpu_init(void)
{
/* initialize the clock system */
clock_init();
/* set pendSV interrupt to lowest possible priority */
NVIC_SetPriority(PendSV_IRQn, 0xff);
}
/**
* @brief Configure the controllers clock system
*
* The clock initialization make the following assumptions:
* - the external HSE clock from an external oscillator is used as base clock
* - the internal PLL circuit is used for clock refinement
*
* Use the following formulas to calculate the needed values:
*
* SYSCLK = ((HSE_VALUE / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_P
* USB, SDIO and RNG Clock = ((HSE_VALUE / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_Q
*
* The actual used values are specified in the board's `periph_conf.h` file.
*
* NOTE: currently there is not timeout for initialization of PLL and other locks
* -> when wrong values are chosen, the initialization could stall
*/
static void clock_init(void)
{
/* configure the HSE clock */
/* enable the HSI clock */
RCC->CR |= RCC_CR_HSION;
/* reset clock configuration register */
RCC->CFGR = 0;
RCC->CFGR2 = 0;
/* disable HSE, CSS and PLL */
RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON | RCC_CR_PLLON);
/* disable all clock interrupts */
RCC->CIR = 0;
/* enable the HSE clock */
RCC->CR |= RCC_CR_HSEON;
/* wait for HSE to be ready */
while (!(RCC->CR & RCC_CR_HSERDY));
/* setup the peripheral bus prescalers */
/* set HCLK = SYSCLK, so no clock division here */
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* set PCLK = HCLK, so its not divided */
RCC->CFGR |= RCC_CFGR_PPRE_DIV1;
/* configure the PLL */
/* reset PLL configuration bits */
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL);
/* set PLL configuration */
RCC->CFGR |= RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV1 |
(((CLOCK_PLL_MUL - 2) & 0xf) << 18);
/* enable PLL again */
RCC->CR |= RCC_CR_PLLON;
/* wait until PLL is stable */
while(!(RCC->CR & RCC_CR_PLLRDY));
/* configure flash latency */
/* enable pre-fetch buffer and set flash latency to 1 cycle*/
FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
/* configure the sysclock and the peripheral clocks */
/* set sysclock to be driven by the PLL clock */
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* wait for sysclock to be stable */
while (!(RCC->CFGR & RCC_CFGR_SWS_PLL));
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Implementation of the kernel's hwtimer interface
*
* The hardware timer implementation uses the Cortex build-in system timer as back-end.
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "arch/hwtimer_arch.h"
#include "periph/timer.h"
#include "board.h"
#include "thread.h"
void irq_handler(int channel);
void (*timeout_handler)(int);
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu)
{
timeout_handler = handler;
timer_init(HW_TIMER, 1, &irq_handler);
}
void hwtimer_arch_enable_interrupt(void)
{
timer_irq_enable(HW_TIMER);
}
void hwtimer_arch_disable_interrupt(void)
{
timer_irq_disable(HW_TIMER);
}
void hwtimer_arch_set(unsigned long offset, short timer)
{
timer_set(HW_TIMER, timer, offset);
}
void hwtimer_arch_set_absolute(unsigned long value, short timer)
{
timer_set_absolute(HW_TIMER, timer, value);
}
void hwtimer_arch_unset(short timer)
{
timer_clear(HW_TIMER, timer);
}
unsigned long hwtimer_arch_now(void)
{
return timer_read(HW_TIMER);
}
void irq_handler(int channel)
{
timeout_handler((short)(channel));
thread_yield();
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup cpu_stm32f0 STM32F0
* @brief STM32F0 specific code
* @ingroup cpu
* @{
*
* @file
* @brief Implementation specific CPU configuration options
*
* @author Hauke Petersen <hauke.peterse@fu-berlin.de>
*/
#ifndef __CPU_CONF_H
#define __CPU_CONF_H
#ifdef CPU_MODEL_STM32F051R8
#include "stm32f051x8.h"
#endif
/**
* @name Kernel configuration
*
* The absolute minimum stack size is 140 byte (68 byte for the tcb + 72 byte
* for a complete context save).
*
* TODO: measure and adjust for the Cortex-M0
* @{
*/
#define KERNEL_CONF_STACKSIZE_PRINTF (512)
#ifndef KERNEL_CONF_STACKSIZE_DEFAULT
#define KERNEL_CONF_STACKSIZE_DEFAULT (512)
#endif
#define KERNEL_CONF_STACKSIZE_IDLE (192)
/** @} */
/**
* @name UART0 buffer size definition for compatibility reasons
*
* TODO: remove once the remodeling of the uart0 driver is done
* @{
*/
#ifndef UART0_BUFSIZE
#define UART0_BUFSIZE (128)
#endif
/** @} */
#endif /* __CPU_CONF_H */
/** @} */

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief CPU specific hwtimer configuration options
*
* @author Hauke Petersen <hauke.peterse@fu-berlin.de>
*/
#ifndef __HWTIMER_CPU_H
#define __HWTIMER_CPU_H
/**
* @name Hardware timer configuration
* @{
*/
#define HWTIMER_MAXTIMERS 4 /**< the CPU implementation supports 4 HW timers */
#define HWTIMER_SPEED 1000000 /**< the HW timer runs with 1MHz */
#define HWTIMER_MAXTICKS (0xFFFFFFFF) /**< 32-bit timer */
/** @} */
#endif /* __HWTIMER_CPU_H */
/** @} */

File diff suppressed because it is too large Load Diff

33
cpu/stm32f0/io_arch.c Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Implementation of the kernel's architecture dependent IO interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "board.h"
#include "arch/io_arch.h"
#include "periph/uart.h"
int io_arch_puts(char *data, int size)
{
int i = 0;
for (; i < size; i++) {
uart_write_blocking(STDIO, data[i]);
}
return i;
}

54
cpu/stm32f0/lpm_arch.c Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Implementation of the kernels power management interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "arch/lpm_arch.h"
void lpm_arch_init(void)
{
/* TODO */
}
enum lpm_mode lpm_arch_set(enum lpm_mode target)
{
/* TODO */
return 0;
}
enum lpm_mode lpm_arch_get(void)
{
/* TODO */
return 0;
}
void lpm_arch_awake(void)
{
/* TODO*/
}
void lpm_arch_begin_awake(void)
{
/* TODO */
}
void lpm_arch_end_awake(void)
{
/* TODO */
}

View File

@ -0,0 +1,3 @@
MODULE = periph
include $(RIOTBASE)/Makefile.base

716
cpu/stm32f0/periph/gpio.c Normal file
View File

@ -0,0 +1,716 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Low-level GPIO driver implementation
*
* @author Hauke Petersen <mail@haukepetersen.de>
*
* @}
*/
#include "cpu.h"
#include "periph/gpio.h"
#include "periph_conf.h"
typedef struct {
void (*cb)(void);
} gpio_state_t;
static gpio_state_t config[GPIO_NUMOF];
int gpio_init_out(gpio_t dev, gpio_pp_t pullup)
{
GPIO_TypeDef *port;
uint32_t pin;
switch (dev) {
#ifdef GPIO_0_EN
case GPIO_0:
GPIO_0_CLKEN();
port = GPIO_0_PORT;
pin = GPIO_0_PIN;
break;
#endif
#ifdef GPIO_1_EN
case GPIO_1:
GPIO_1_CLKEN();
port = GPIO_1_PORT;
pin = GPIO_1_PIN;
break;
#endif
#ifdef GPIO_2_EN
case GPIO_2:
GPIO_2_CLKEN();
port = GPIO_2_PORT;
pin = GPIO_2_PIN;
break;
#endif
#ifdef GPIO_3_EN
case GPIO_3:
GPIO_3_CLKEN();
port = GPIO_3_PORT;
pin = GPIO_3_PIN;
break;
#endif
#ifdef GPIO_4_EN
case GPIO_4:
GPIO_4_CLKEN();
port = GPIO_4_PORT;
pin = GPIO_4_PIN;
break;
#endif
#ifdef GPIO_5_EN
case GPIO_5:
GPIO_5_CLKEN();
port = GPIO_5_PORT;
pin = GPIO_5_PIN;
break;
#endif
#ifdef GPIO_6_EN
case GPIO_6:
GPIO_6_CLKEN();
port = GPIO_6_PORT;
pin = GPIO_6_PIN;
break;
#endif
#ifdef GPIO_7_EN
case GPIO_7:
GPIO_7_CLKEN();
port = GPIO_7_PORT;
pin = GPIO_7_PIN;
break;
#endif
#ifdef GPIO_8_EN
case GPIO_8:
GPIO_8_CLKEN();
port = GPIO_8_PORT;
pin = GPIO_8_PIN;
break;
#endif
#ifdef GPIO_9_EN
case GPIO_9:
GPIO_9_CLKEN();
port = GPIO_9_PORT;
pin = GPIO_9_PIN;
break;
#endif
#ifdef GPIO_10_EN
case GPIO_10:
GPIO_10_CLKEN();
port = GPIO_10_PORT;
pin = GPIO_10_PIN;
break;
#endif
#ifdef GPIO_11_EN
case GPIO_11:
GPIO_11_CLKEN();
port = GPIO_11_PORT;
pin = GPIO_11_PIN;
break;
#endif
case GPIO_UNDEFINED:
default:
return -1;
}
port->MODER &= ~(2 << (2 * pin)); /* set pin to output mode */
port->MODER |= (1 << (2 * pin));
port->OTYPER &= ~(1 << pin); /* set to push-pull configuration */
port->OSPEEDR |= (3 << (2 * pin)); /* set to high speed */
port->PUPDR &= ~(3 << (2 * pin)); /* configure push-pull resistors */
port->PUPDR |= (pullup << (2 * pin));
port->ODR &= ~(1 << pin); /* set pin to low signal */
return 0; /* all OK */
}
int gpio_init_in(gpio_t dev, gpio_pp_t pullup)
{
GPIO_TypeDef *port;
uint32_t pin;
switch (dev) {
#ifdef GPIO_0_EN
case GPIO_0:
GPIO_0_CLKEN();
port = GPIO_0_PORT;
pin = GPIO_0_PIN;
break;
#endif
#ifdef GPIO_1_EN
case GPIO_1:
GPIO_1_CLKEN();
port = GPIO_1_PORT;
pin = GPIO_1_PIN;
break;
#endif
#ifdef GPIO_2_EN
case GPIO_2:
GPIO_2_CLKEN();
port = GPIO_2_PORT;
pin = GPIO_2_PIN;
break;
#endif
#ifdef GPIO_3_EN
case GPIO_3:
GPIO_3_CLKEN();
port = GPIO_3_PORT;
pin = GPIO_3_PIN;
break;
#endif
#ifdef GPIO_4_EN
case GPIO_4:
GPIO_4_CLKEN();
port = GPIO_4_PORT;
pin = GPIO_4_PIN;
break;
#endif
#ifdef GPIO_5_EN
case GPIO_5:
GPIO_5_CLKEN();
port = GPIO_5_PORT;
pin = GPIO_5_PIN;
break;
#endif
#ifdef GPIO_6_EN
case GPIO_6:
GPIO_6_CLKEN();
port = GPIO_6_PORT;
pin = GPIO_6_PIN;
break;
#endif
#ifdef GPIO_7_EN
case GPIO_7:
GPIO_7_CLKEN();
port = GPIO_7_PORT;
pin = GPIO_7_PIN;
break;
#endif
#ifdef GPIO_8_EN
case GPIO_8:
GPIO_8_CLKEN();
port = GPIO_8_PORT;
pin = GPIO_8_PIN;
break;
#endif
#ifdef GPIO_9_EN
case GPIO_9:
GPIO_9_CLKEN();
port = GPIO_9_PORT;
pin = GPIO_9_PIN;
break;
#endif
#ifdef GPIO_10_EN
case GPIO_10:
GPIO_10_CLKEN();
port = GPIO_10_PORT;
pin = GPIO_10_PIN;
break;
#endif
#ifdef GPIO_11_EN
case GPIO_11:
GPIO_11_CLKEN();
port = GPIO_11_PORT;
pin = GPIO_11_PIN;
break;
#endif
case GPIO_UNDEFINED:
default:
return -1;
}
port->MODER &= ~(3 << (2 * pin)); /* configure pin as input */
port->PUPDR &= ~(3 << (2 * pin)); /* configure push-pull resistors */
port->PUPDR |= (pullup << (2 * pin));
return 0; /* everything alright here */
}
int gpio_init_int(gpio_t dev, gpio_pp_t pullup, gpio_flank_t flank, void (*cb)(void))
{
int res;
uint32_t pin;
/* configure pin as input */
res = gpio_init_in(dev, pullup);
if (res < 0) {
return res;
}
/* set interrupt priority (its the same for all EXTI interrupts) */
NVIC_SetPriority(EXTI0_1_IRQn, GPIO_IRQ_PRIO);
NVIC_SetPriority(EXTI2_3_IRQn, GPIO_IRQ_PRIO);
NVIC_SetPriority(EXTI4_15_IRQn, GPIO_IRQ_PRIO);
/* enable clock of the SYSCFG module for EXTI configuration */
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN;
/* read pin number, set EXIT channel and enable global interrupt for EXTI channel */
switch (dev) {
#ifdef GPIO_0_EN
case GPIO_0:
pin = GPIO_0_PIN;
GPIO_0_EXTI_CFG();
NVIC_SetPriority(GPIO_0_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_0_IRQ);
break;
#endif
#ifdef GPIO_1_EN
case GPIO_1:
pin = GPIO_1_PIN;
GPIO_1_EXTI_CFG();
NVIC_SetPriority(GPIO_1_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_1_IRQ);
break;
#endif
#ifdef GPIO_2_EN
case GPIO_2:
pin = GPIO_2_PIN;
GPIO_2_EXTI_CFG();
NVIC_SetPriority(GPIO_2_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_2_IRQ);
break;
#endif
#ifdef GPIO_3_EN
case GPIO_3:
pin = GPIO_3_PIN;
GPIO_3_EXTI_CFG();
NVIC_SetPriority(GPIO_3_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_3_IRQ);
break;
#endif
#ifdef GPIO_4_EN
case GPIO_4:
pin = GPIO_4_PIN;
GPIO_4_EXTI_CFG();
NVIC_SetPriority(GPIO_4_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_4_IRQ);
break;
#endif
#ifdef GPIO_5_EN
case GPIO_5:
pin = GPIO_5_PIN;
GPIO_5_EXTI_CFG();
NVIC_SetPriority(GPIO_5_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_5_IRQ);
break;
#endif
#ifdef GPIO_6_EN
case GPIO_6:
pin = GPIO_6_PIN;
GPIO_6_EXTI_CFG();
NVIC_SetPriority(GPIO_6_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_6_IRQ);
break;
#endif
#ifdef GPIO_7_EN
case GPIO_7:
pin = GPIO_7_PIN;
GPIO_7_EXTI_CFG();
NVIC_SetPriority(GPIO_7_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_7_IRQ);
break;
#endif
#ifdef GPIO_8_EN
case GPIO_8:
pin = GPIO_8_PIN;
GPIO_8_EXTI_CFG();
NVIC_SetPriority(GPIO_8_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_8_IRQ);
break;
#endif
#ifdef GPIO_9_EN
case GPIO_9:
pin = GPIO_9_PIN;
GPIO_9_EXTI_CFG();
NVIC_SetPriority(GPIO_9_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_9_IRQ);
break;
#endif
#ifdef GPIO_10_EN
case GPIO_10:
pin = GPIO_10_PIN;
GPIO_10_EXTI_CFG();
NVIC_SetPriority(GPIO_10_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_10_IRQ);
break;
#endif
#ifdef GPIO_11_EN
case GPIO_11:
pin = GPIO_11_PIN;
GPIO_11_EXTI_CFG();
NVIC_SetPriority(GPIO_11_IRQ, GPIO_IRQ_PRIO);
NVIC_EnableIRQ(GPIO_11_IRQ);
break;
#endif
case GPIO_UNDEFINED:
default:
return -1;
}
/* set callback */
config[dev].cb = cb;
/* configure the event that triggers an interrupt */
switch (flank) {
case GPIO_RISING:
EXTI->RTSR |= (1 << pin);
EXTI->FTSR &= ~(1 << pin);
break;
case GPIO_FALLING:
EXTI->RTSR &= ~(1 << pin);
EXTI->FTSR |= (1 << pin);
break;
case GPIO_BOTH:
EXTI->RTSR |= (1 << pin);
EXTI->FTSR |= (1 << pin);
break;
}
/* unmask the pins interrupt channel */
EXTI->IMR |= (1 << pin);
return 0;
}
int gpio_read(gpio_t dev)
{
GPIO_TypeDef *port;
uint32_t pin;
switch (dev) {
#ifdef GPIO_0_EN
case GPIO_0:
port = GPIO_0_PORT;
pin = GPIO_0_PIN;
break;
#endif
#ifdef GPIO_1_EN
case GPIO_1:
port = GPIO_1_PORT;
pin = GPIO_1_PIN;
break;
#endif
#ifdef GPIO_2_EN
case GPIO_2:
port = GPIO_2_PORT;
pin = GPIO_2_PIN;
break;
#endif
#ifdef GPIO_3_EN
case GPIO_3:
port = GPIO_3_PORT;
pin = GPIO_3_PIN;
break;
#endif
#ifdef GPIO_4_EN
case GPIO_4:
port = GPIO_4_PORT;
pin = GPIO_4_PIN;
break;
#endif
#ifdef GPIO_5_EN
case GPIO_5:
port = GPIO_5_PORT;
pin = GPIO_5_PIN;
break;
#endif
#ifdef GPIO_6_EN
case GPIO_6:
port = GPIO_6_PORT;
pin = GPIO_6_PIN;
break;
#endif
#ifdef GPIO_7_EN
case GPIO_7:
port = GPIO_7_PORT;
pin = GPIO_7_PIN;
break;
#endif
#ifdef GPIO_8_EN
case GPIO_8:
port = GPIO_8_PORT;
pin = GPIO_8_PIN;
break;
#endif
#ifdef GPIO_9_EN
case GPIO_9:
port = GPIO_9_PORT;
pin = GPIO_9_PIN;
break;
#endif
#ifdef GPIO_10_EN
case GPIO_10:
port = GPIO_10_PORT;
pin = GPIO_10_PIN;
break;
#endif
#ifdef GPIO_11_EN
case GPIO_11:
port = GPIO_11_PORT;
pin = GPIO_11_PIN;
break;
#endif
case GPIO_UNDEFINED:
default:
return -1;
}
if (port->MODER & (1 << (pin * 2))) { /* if configured as output */
return port->ODR & (1 << pin); /* read output data register */
} else {
return port->IDR & (1 << pin); /* else read input data register */
}
}
int gpio_set(gpio_t dev)
{
switch (dev) {
#ifdef GPIO_0_EN
case GPIO_0:
GPIO_0_PORT->ODR |= (1 << GPIO_0_PIN);
break;
#endif
#ifdef GPIO_1_EN
case GPIO_1:
GPIO_1_PORT->ODR |= (1 << GPIO_1_PIN);
break;
#endif
#ifdef GPIO_2_EN
case GPIO_2:
GPIO_2_PORT->ODR |= (1 << GPIO_2_PIN);
break;
#endif
#ifdef GPIO_3_EN
case GPIO_3:
GPIO_3_PORT->ODR |= (1 << GPIO_3_PIN);
break;
#endif
#ifdef GPIO_4_EN
case GPIO_4:
GPIO_4_PORT->ODR |= (1 << GPIO_4_PIN);
break;
#endif
#ifdef GPIO_5_EN
case GPIO_5:
GPIO_5_PORT->ODR |= (1 << GPIO_5_PIN);
break;
#endif
#ifdef GPIO_6_EN
case GPIO_6:
GPIO_6_PORT->ODR |= (1 << GPIO_6_PIN);
break;
#endif
#ifdef GPIO_7_EN
case GPIO_7:
GPIO_7_PORT->ODR |= (1 << GPIO_7_PIN);
break;
#endif
#ifdef GPIO_8_EN
case GPIO_8:
GPIO_8_PORT->ODR |= (1 << GPIO_8_PIN);
break;
#endif
#ifdef GPIO_9_EN
case GPIO_9:
GPIO_9_PORT->ODR |= (1 << GPIO_9_PIN);
break;
#endif
#ifdef GPIO_10_EN
case GPIO_10:
GPIO_10_PORT->ODR |= (1 << GPIO_10_PIN);
break;
#endif
#ifdef GPIO_11_EN
case GPIO_11:
GPIO_11_PORT->ODR |= (1 << GPIO_11_PIN);
break;
#endif
case GPIO_UNDEFINED:
default:
return -1;
}
return 0;
}
int gpio_clear(gpio_t dev)
{
switch (dev) {
#ifdef GPIO_0_EN
case GPIO_0:
GPIO_0_PORT->ODR &= ~(1 << GPIO_0_PIN);
break;
#endif
#ifdef GPIO_1_EN
case GPIO_1:
GPIO_1_PORT->ODR &= ~(1 << GPIO_1_PIN);
break;
#endif
#ifdef GPIO_2_EN
case GPIO_2:
GPIO_2_PORT->ODR &= ~(1 << GPIO_2_PIN);
break;
#endif
#ifdef GPIO_3_EN
case GPIO_3:
GPIO_3_PORT->ODR &= ~(1 << GPIO_3_PIN);
break;
#endif
#ifdef GPIO_4_EN
case GPIO_4:
GPIO_4_PORT->ODR &= ~(1 << GPIO_4_PIN);
break;
#endif
#ifdef GPIO_5_EN
case GPIO_5:
GPIO_5_PORT->ODR &= ~(1 << GPIO_5_PIN);
break;
#endif
#ifdef GPIO_6_EN
case GPIO_6:
GPIO_6_PORT->ODR &= ~(1 << GPIO_6_PIN);
break;
#endif
#ifdef GPIO_7_EN
case GPIO_7:
GPIO_7_PORT->ODR &= ~(1 << GPIO_7_PIN);
break;
#endif
#ifdef GPIO_8_EN
case GPIO_8:
GPIO_8_PORT->ODR &= ~(1 << GPIO_8_PIN);
break;
#endif
#ifdef GPIO_9_EN
case GPIO_9:
GPIO_9_PORT->ODR &= ~(1 << GPIO_9_PIN);
break;
#endif
#ifdef GPIO_10_EN
case GPIO_10:
GPIO_10_PORT->ODR &= ~(1 << GPIO_10_PIN);
break;
#endif
#ifdef GPIO_11_EN
case GPIO_11:
GPIO_11_PORT->ODR &= ~(1 << GPIO_11_PIN);
break;
#endif
case GPIO_UNDEFINED:
default:
return -1;
}
return 0;
}
int gpio_toggle(gpio_t dev)
{
if (gpio_read(dev)) {
return gpio_clear(dev);
} else {
return gpio_set(dev);
}
}
int gpio_write(gpio_t dev, int value)
{
if (value) {
return gpio_set(dev);
} else {
return gpio_clear(dev);
}
}
__attribute__((naked)) void isr_exti0_1(void)
{
ISR_ENTER();
if (EXTI->PR & EXTI_PR_PR0) {
EXTI->PR |= EXTI_PR_PR0; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_0].cb();
}
else if (EXTI->PR & EXTI_PR_PR1) {
EXTI->PR |= EXTI_PR_PR1; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_1].cb();
}
ISR_EXIT();
}
__attribute__((naked)) void isr_exti2_3(void)
{
ISR_ENTER();
if (EXTI->PR & EXTI_PR_PR2) {
EXTI->PR |= EXTI_PR_PR2; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_2].cb();
}
else if (EXTI->PR & EXTI_PR_PR3) {
EXTI->PR |= EXTI_PR_PR3; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_3].cb();
}
ISR_EXIT();
}
__attribute__((naked)) void isr_exti4_15(void)
{
ISR_ENTER();
if (EXTI->PR & EXTI_PR_PR4) {
EXTI->PR |= EXTI_PR_PR4; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_4].cb();
}
else if (EXTI->PR & EXTI_PR_PR5) {
EXTI->PR |= EXTI_PR_PR5; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_5].cb();
}
else if (EXTI->PR & EXTI_PR_PR6) {
EXTI->PR |= EXTI_PR_PR6; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_6].cb();
}
else if (EXTI->PR & EXTI_PR_PR7) {
EXTI->PR |= EXTI_PR_PR7; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_7].cb();
}
else if (EXTI->PR & EXTI_PR_PR8) {
EXTI->PR |= EXTI_PR_PR8; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_8].cb();
}
else if (EXTI->PR & EXTI_PR_PR9) {
EXTI->PR |= EXTI_PR_PR9; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_9].cb();
}
else if (EXTI->PR & EXTI_PR_PR10) {
EXTI->PR |= EXTI_PR_PR10; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_10].cb();
}
else if (EXTI->PR & EXTI_PR_PR11) {
EXTI->PR |= EXTI_PR_PR11; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_11].cb();
}
else if (EXTI->PR & EXTI_PR_PR12) {
EXTI->PR |= EXTI_PR_PR12; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_12].cb();
}
else if (EXTI->PR & EXTI_PR_PR13) {
EXTI->PR |= EXTI_PR_PR13; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_13].cb();
}
else if (EXTI->PR & EXTI_PR_PR14) {
EXTI->PR |= EXTI_PR_PR14; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_14].cb();
}
else if (EXTI->PR & EXTI_PR_PR15) {
EXTI->PR |= EXTI_PR_PR15; /* clear status bit by writing a 1 to it */
config[GPIO_IRQ_15].cb();
}
ISR_EXIT();
}

330
cpu/stm32f0/periph/timer.c Normal file
View File

@ -0,0 +1,330 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Low-level timer driver implementation
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdlib.h>
#include "cpu.h"
#include "board.h"
#include "periph_conf.h"
#include "periph/timer.h"
static inline void irq_handler(tim_t timer, TIM_TypeDef *dev);
typedef struct {
void (*cb)(int);
} timer_conf_t;
/**
* Timer state memory
*/
timer_conf_t config[TIMER_NUMOF];
int timer_init(tim_t dev, unsigned int ticks_per_us, void (*callback)(int))
{
TIM_TypeDef *timer;
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
/* enable timer peripheral clock */
TIMER_0_CLKEN();
/* set timer's IRQ priority */
NVIC_SetPriority(TIMER_0_IRQ_CHAN, TIMER_0_IRQ_PRIO);
/* select timer */
timer = TIMER_0_DEV;
break;
#endif
#if TIMER_1_EN
case TIMER_1:
/* enable timer peripheral clock */
TIMER_1_CLKEN();
/* set timer's IRQ priority */
NVIC_SetPriority(TIMER_1_IRQ_CHAN, TIMER_1_IRQ_PRIO);
/* select timer */
timer = TIMER_1_DEV;
break;
#endif
case TIMER_UNDEFINED:
default:
return -1;
}
/* set callback function */
config[dev].cb = callback;
/* set timer to run in counter mode */
timer->CR1 |= TIM_CR1_URS;
/* set auto-reload and prescaler values and load new values */
timer->ARR = TIMER_0_MAX_VALUE;
timer->PSC = TIMER_0_PRESCALER * ticks_per_us;
timer->EGR |= TIM_EGR_UG;
/* enable the timer's interrupt */
timer_irq_enable(dev);
/* start the timer */
timer_start(dev);
return 0;
}
int timer_set(tim_t dev, int channel, unsigned int timeout)
{
int now = timer_read(dev);
return timer_set_absolute(dev, channel, now + timeout - 1);
}
int timer_set_absolute(tim_t dev, int channel, unsigned int value)
{
TIM_TypeDef *timer = NULL;
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
timer = TIMER_0_DEV;
break;
#endif
#if TIMER_1_EN
case TIMER_1:
timer = TIMER_1_DEV;
break;
#endif
case TIMER_UNDEFINED:
default:
return -1;
}
switch (channel) {
case 0:
timer->CCR1 = value;
timer->SR &= ~TIM_SR_CC1IF;
timer->DIER |= TIM_DIER_CC1IE;
break;
case 1:
timer->CCR2 = value;
timer->SR &= ~TIM_SR_CC2IF;
timer->DIER |= TIM_DIER_CC2IE;
break;
case 2:
timer->CCR3 = value;
timer->SR &= ~TIM_SR_CC3IF;
timer->DIER |= TIM_DIER_CC3IE;
break;
case 3:
timer->CCR4 = value;
timer->SR &= ~TIM_SR_CC4IF;
timer->DIER |= TIM_DIER_CC4IE;
break;
default:
return -1;
}
return 0;
}
int timer_clear(tim_t dev, int channel)
{
TIM_TypeDef *timer;
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
timer = TIMER_0_DEV;
break;
#endif
#if TIMER_1_EN
case TIMER_1:
timer = TIMER_1_DEV;
break;
#endif
case TIMER_UNDEFINED:
default:
return -1;
}
switch (channel) {
case 0:
timer->DIER &= ~TIM_DIER_CC1IE;
break;
case 1:
timer->DIER &= ~TIM_DIER_CC2IE;
break;
case 2:
timer->DIER &= ~TIM_DIER_CC3IE;
break;
case 3:
timer->DIER &= ~TIM_DIER_CC4IE;
break;
default:
return -1;
}
return 0;
}
unsigned int timer_read(tim_t dev)
{
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
return TIMER_0_DEV->CNT;
break;
#endif
#if TIMER_1_EN
case TIMER_1:
return TIMER_1_DEV->CNT;
break;
#endif
case TIMER_UNDEFINED:
default:
return 0;
}
}
void timer_start(tim_t dev)
{
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
TIMER_0_DEV->CR1 |= TIM_CR1_CEN;
break;
#endif
#if TIMER_1_EN
case TIMER_1:
TIMER_1_DEV->CR1 |= TIM_CR1_CEN;
break;
#endif
case TIMER_UNDEFINED:
break;
}
}
void timer_stop(tim_t dev)
{
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
TIMER_0_DEV->CR1 &= ~TIM_CR1_CEN;
break;
#endif
#if TIMER_1_EN
case TIMER_1:
TIMER_1_DEV->CR1 &= ~TIM_CR1_CEN;
break;
#endif
case TIMER_UNDEFINED:
break;
}
}
void timer_irq_enable(tim_t dev)
{
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
NVIC_EnableIRQ(TIMER_0_IRQ_CHAN);
break;
#endif
#if TIMER_1_EN
case TIMER_1:
NVIC_EnableIRQ(TIMER_1_IRQ_CHAN);
break;
#endif
case TIMER_UNDEFINED:
break;
}
}
void timer_irq_disable(tim_t dev)
{
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
NVIC_DisableIRQ(TIMER_0_IRQ_CHAN);
break;
#endif
#if TIMER_1_EN
case TIMER_1:
NVIC_DisableIRQ(TIMER_1_IRQ_CHAN);
break;
#endif
case TIMER_UNDEFINED:
break;
}
}
void timer_reset(tim_t dev)
{
switch (dev) {
#if TIMER_0_EN
case TIMER_0:
TIMER_0_DEV->CNT = 0;
break;
#endif
#if TIMER_1_EN
case TIMER_1:
TIMER_1_DEV->CNT = 0;
break;
#endif
case TIMER_UNDEFINED:
break;
}
}
#if TIMER_0_EN
__attribute__ ((naked)) void TIMER_0_ISR(void)
{
ISR_ENTER();
irq_handler(TIMER_0, TIMER_0_DEV);
ISR_EXIT();
}
#endif
#if TIMER_1_EN
__attribute__ ((naked)) void TIMER_1_ISR(void)
{
ISR_ENTER();
irq_handler(TIMER_1, TIMER_1_DEV);
ISR_EXIT();
}
#endif
static inline void irq_handler(tim_t timer, TIM_TypeDef *dev)
{
if (dev->SR & TIM_SR_CC1IF) {
dev->DIER &= ~TIM_DIER_CC1IE;
dev->SR &= ~TIM_SR_CC1IF;
config[timer].cb(0);
}
else if (dev->SR & TIM_SR_CC2IF) {
dev->DIER &= ~TIM_DIER_CC2IE;
dev->SR &= ~TIM_SR_CC2IF;
config[timer].cb(1);
}
else if (dev->SR & TIM_SR_CC3IF) {
dev->DIER &= ~TIM_DIER_CC3IE;
dev->SR &= ~TIM_SR_CC3IF;
config[timer].cb(2);
}
else if (dev->SR & TIM_SR_CC4IF) {
dev->DIER &= ~TIM_DIER_CC4IE;
dev->SR &= ~TIM_SR_CC4IF;
config[timer].cb(3);
}
}

309
cpu/stm32f0/periph/uart.c Normal file
View File

@ -0,0 +1,309 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Low-level UART driver implementation
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <math.h>
#include "cpu.h"
#include "board.h"
#include "periph_conf.h"
#include "periph/uart.h"
/**
* @brief Each UART device has to store two callbacks.
*/
typedef struct {
void (*rx_cb)(char);
void (*tx_cb)(void);
} uart_conf_t;
/**
* @brief Unified interrupt handler for all UART devices
*
* @param uartnum the number of the UART that triggered the ISR
* @param uart the UART device that triggered the ISR
*/
static inline void irq_handler(uart_t uartnum, USART_TypeDef *uart);
/**
* @brief Allocate memory to store the callback functions.
*/
static uart_conf_t config[UART_NUMOF];
int uart_init(uart_t uart, uint32_t baudrate, void (*rx_cb)(char), void (*tx_cb)(void))
{
int res;
/* initialize UART in blocking mode first */
res = uart_init_blocking(uart, baudrate);
if (res < 0) {
return res;
}
/* enable global interrupt and configure the interrupts priority */
switch (uart) {
#if UART_0_EN
case UART_0:
NVIC_SetPriority(UART_0_IRQ, UART_IRQ_PRIO);
NVIC_EnableIRQ(UART_0_IRQ);
UART_0_DEV->CR1 |= USART_CR1_RXNEIE;
break;
#endif
#if UART_1_EN
case UART_1:
NVIC_SetPriority(UART_1_IRQ, UART_IRQ_PRIO);
NVIC_EnableIRQ(UART_1_IRQ);
UART_1_DEV->CR1 |= USART_CR1_RXNEIE;
break;
#endif
case UART_UNDEFINED:
default:
return -2;
}
/* register callbacks */
config[uart].rx_cb = rx_cb;
config[uart].tx_cb = tx_cb;
return 0;
}
int uart_init_blocking(uart_t uart, uint32_t baudrate)
{
USART_TypeDef *dev;
GPIO_TypeDef *port;
uint32_t rx_pin, tx_pin;
uint8_t af;
float divider;
uint16_t mantissa;
uint8_t fraction;
/* enable UART and port clocks and select devices */
switch (uart) {
#if UART_0_EN
case UART_0:
dev = UART_0_DEV;
port = UART_0_PORT;
rx_pin = UART_0_RX_PIN;
tx_pin = UART_0_TX_PIN;
af = UART_0_AF;
/* enable clocks */
UART_0_CLKEN();
UART_0_PORT_CLKEN();
break;
#endif
#if UART_1_EN
case UART_1:
dev = UART_1_DEV;
port = UART_1_PORT;
tx_pin = UART_1_TX_PIN;
rx_pin = UART_1_RX_PIN;
af = UART_1_AF;
/* enable clocks */
UART_1_CLKEN();
UART_1_PORT_CLKEN();
break;
#endif
case UART_UNDEFINED:
default:
return -2;
}
/* configure RX and TX pins, set pin to use alternative function mode */
port->MODER &= ~(3 << (rx_pin * 2) | 3 << (tx_pin * 2));
port->MODER |= 2 << (rx_pin * 2) | 2 << (tx_pin * 2);
/* and assign alternative function */
if (rx_pin < 8) {
port->AFR[0] &= ~(0xf << (rx_pin * 4));
port->AFR[0] |= af << (rx_pin * 4);
}
else {
port->AFR[1] &= ~(0xf << ((rx_pin - 16) * 4));
port->AFR[1] |= af << ((rx_pin - 16) * 4);
}
if (tx_pin < 8) {
port->AFR[0] &= ~(0xf << (tx_pin * 4));
port->AFR[0] |= af << (tx_pin * 4);
}
else {
port->AFR[1] &= ~(0xf << ((tx_pin - 16) * 4));
port->AFR[1] |= af << ((tx_pin - 16) * 4);
}
/* configure UART to mode 8N1 with given baudrate */
divider = ((float)F_CPU) / (16 * baudrate);
mantissa = (uint16_t)floorf(divider);
fraction = (uint8_t)floorf((divider - mantissa) * 16);
dev->BRR = 0;
dev->BRR |= ((mantissa & 0x0fff) << 4) | (0x0f & fraction);
/* enable receive and transmit mode */
dev->CR1 |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
return 0;
}
void uart_tx_begin(uart_t uart)
{
switch (uart) {
#if UART_1_EN
case UART_0:
UART_0_DEV->CR1 |= USART_CR1_TXEIE;
break;
#endif
#if UART_0_EN
case UART_1:
UART_1_DEV->CR1 |= USART_CR1_TXEIE;
break;
#endif
case UART_UNDEFINED:
break;
}
}
#include <stdio.h>
void uart_tx_end(uart_t uart)
{
switch (uart) {
#if UART_0_EN
case UART_0:
UART_0_DEV->CR1 &= ~USART_CR1_TXEIE;
break;
#endif
#if UART_1_EN
case UART_1:
UART_1_DEV->CR1 &= ~USART_CR1_TXEIE;
break;
#endif
case UART_UNDEFINED:
break;
}
}
int uart_write(uart_t uart, char data)
{
USART_TypeDef *dev;
switch (uart) {
#if UART_0_EN
case UART_0:
dev = UART_0_DEV;
break;
#endif
#if UART_1_EN
case UART_1:
dev = UART_1_DEV;
break;
#endif
case UART_UNDEFINED:
default:
return -1;
}
if (dev->ISR & USART_ISR_TXE) {
dev->TDR = (uint8_t)data;
}
return 0;
}
int uart_read_blocking(uart_t uart, char *data)
{
USART_TypeDef *dev;
switch (uart) {
#if UART_0_EN
case UART_0:
dev = UART_0_DEV;
break;
#endif
#if UART_1_EN
case UART_1:
dev = UART_1_DEV;
break;
#endif
case UART_UNDEFINED:
default:
return -1;
}
while (!(dev->ISR & USART_ISR_RXNE));
*data = (char)dev->RDR;
return 1;
}
int uart_write_blocking(uart_t uart, char data)
{
USART_TypeDef *dev;
switch (uart) {
#if UART_0_EN
case UART_0:
dev = UART_0_DEV;
break;
#endif
#if UART_1_EN
case UART_1:
dev = UART_1_DEV;
break;
#endif
case UART_UNDEFINED:
default:
return -1;
}
while (!(dev->ISR & USART_ISR_TXE));
dev->TDR = (uint8_t)data;
return 1;
}
__attribute__((naked)) void UART_0_ISR(void)
{
ISR_ENTER();
irq_handler(UART_0, UART_0_DEV);
ISR_EXIT();
}
__attribute__((naked)) void UART_1_ISR(void)
{
ISR_ENTER();
irq_handler(UART_1, UART_1_DEV);
ISR_EXIT();
}
static inline void irq_handler(uint8_t uartnum, USART_TypeDef *dev)
{
if (dev->ISR & USART_ISR_RXNE) {
char data = (char)dev->RDR;
config[uartnum].rx_cb(data);
}
else if (dev->ISR & USART_ISR_ORE) {
/* do nothing on overrun */
dev->ICR |= USART_ICR_ORECF;
}
else if (dev->ISR & USART_ISR_TXE) {
config[uartnum].tx_cb();
}
}

34
cpu/stm32f0/reboot_arch.c Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Implementation of the kernels reboot interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdio.h>
#include "arch/reboot_arch.h"
#include "cpu.h"
int reboot_arch(int mode)
{
printf("Going into reboot, mode %i\n", mode);
NVIC_SystemReset();
return 0;
}

205
cpu/stm32f0/startup.c Normal file
View File

@ -0,0 +1,205 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief Startup code and interrupt vector definition
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdint.h>
/**
* memory markers as defined in the linker script
*/
extern uint32_t _sfixed;
extern uint32_t _efixed;
extern uint32_t _etext;
extern uint32_t _srelocate;
extern uint32_t _erelocate;
extern uint32_t _szero;
extern uint32_t _ezero;
extern uint32_t _sstack;
extern uint32_t _estack;
/**
* @brief functions for initializing the board, std-lib and kernel
*/
extern void board_init(void);
extern void kernel_init(void);
extern void __libc_init_array(void);
/**
* @brief This function is the entry point after a system reset
*
* After a system reset, the following steps are necessary and carried out:
* 1. load data section from flash to ram
* 2. overwrite uninitialized data section (BSS) with zeros
* 3. initialize the newlib
* 4. initialize the board (sync clock, setup std-IO)
* 5. initialize and start RIOTs kernel
*/
void reset_handler(void)
{
uint32_t *dst;
uint32_t *src = &_etext;
/* load data section from flash to ram */
for (dst = &_srelocate; dst < &_erelocate; ) {
*(dst++) = *(src++);
}
/* default bss section to zero */
for (dst = &_szero; dst < &_ezero; ) {
*(dst++) = 0;
}
/* initialize the board and startup the kernel */
board_init();
/* initialize std-c library (this should be done after board_init) */
__libc_init_array();
/* startup the kernel */
kernel_init();
}
/**
* @brief Default handler is called in case no interrupt handler was defined
*/
void dummy_handler(void)
{
while (1) {asm ("nop");}
}
void isr_nmi(void)
{
while (1) {asm ("nop");}
}
void isr_mem_manage(void)
{
while (1) {asm ("nop");}
}
void isr_debug_mon(void)
{
while (1) {asm ("nop");}
}
void isr_hard_fault(void)
{
while (1) {asm ("nop");}
}
void isr_bus_fault(void)
{
while (1) {asm ("nop");}
}
void isr_usage_fault(void)
{
while (1) {asm ("nop");}
}
/* Cortex-M specific interrupt vectors */
void isr_svc(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_pendsv(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_systick(void) __attribute__ ((weak, alias("dummy_handler")));
/* STM32F051R8 specific interrupt vector */
void isr_wwdg(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_pvd(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_rtc(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_flash(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_rcc(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_exti0_1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_exti2_3(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_exti4_15(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_ts(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_dma1_ch1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_dma1_ch2_3(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_dma1_ch4_5(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_adc1_comp(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim1_brk_up_trg_com(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim1_cc(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim2(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim3(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim6_dac(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim14(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim15(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim16(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_tim17(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_i2c1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_i2c2(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_spi1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_spi2(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_usart1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_usart2(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_cec(void) __attribute__ ((weak, alias("dummy_handler")));
/* interrupt vector table */
__attribute__ ((section(".vectors")))
const void *interrupt_vector[] = {
/* Stack pointer */
(void*) (&_estack), /* pointer to the top of the empty stack */
/* Cortex-M handlers */
(void*) reset_handler, /* entry point of the program */
(void*) isr_nmi, /* non maskable interrupt handler */
(void*) isr_hard_fault, /* if you end up here its not good */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) isr_svc, /* system call interrupt */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) isr_pendsv, /* pendSV interrupt, used for task switching in RIOT */
(void*) isr_systick, /* SysTick interrupt, not used in RIOT */
/* STM specific peripheral handlers */
(void*) isr_wwdg, /* windowed watchdog */
(void*) isr_pvd, /* power control */
(void*) isr_rtc, /* real time clock */
(void*) isr_flash, /* flash memory controller */
(void*) isr_rcc, /* reset and clock control */
(void*) isr_exti0_1, /* external interrupt lines 0 and 1 */
(void*) isr_exti2_3, /* external interrupt lines 2 and 3 */
(void*) isr_exti4_15, /* external interrupt lines 4 to 15 */
(void*) isr_ts, /* touch sensing input*/
(void*) isr_dma1_ch1, /* direct memory access controller 1, channel 1*/
(void*) isr_dma1_ch2_3, /* direct memory access controller 1, channel 2 and 3*/
(void*) isr_dma1_ch4_5, /* direct memory access controller 1, channel 4 and 5*/
(void*) isr_adc1_comp, /* analog digital converter */
(void*) isr_tim1_brk_up_trg_com, /* timer 1 break, update, trigger and communication */
(void*) isr_tim1_cc, /* timer 1 capture compare */
(void*) isr_tim2, /* timer 2 */
(void*) isr_tim3, /* timer 3 */
(void*) isr_tim6_dac, /* timer 6 and digital to analog converter */
(void*) (0UL), /* reserved */
(void*) isr_tim14, /* timer 14 */
(void*) isr_tim15, /* timer 15 */
(void*) isr_tim16, /* timer 16 */
(void*) isr_tim17, /* timer 17 */
(void*) isr_i2c1, /* I2C 1 */
(void*) isr_i2c2, /* I2C 2 */
(void*) isr_spi1, /* SPI 1 */
(void*) isr_spi2, /* SPI 2 */
(void*) isr_usart1, /* USART 1 */
(void*) isr_usart2, /* USART 2 */
(void*) (0UL), /* reserved */
(void*) isr_cec, /* consumer electronics control */
(void*) (0UL) /* reserved */
};

View File

@ -0,0 +1,142 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
}
/* The stack size used by the application. NOTE: you need to adjust */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0xa00 ;
/* Section Definitions */
SECTIONS
{
.text :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
/* Support C constructors, and C destructors in both user code
and the C library. This also provides support for C++ code. */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
_efixed = .; /* End of text section */
} > rom
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
PROVIDE_HIDDEN (__exidx_end = .);
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + STACK_SIZE;
. = ALIGN(8);
_estack = .;
} > ram
. = ALIGN(4);
_end = . ;
}

277
cpu/stm32f0/syscalls.c Normal file
View File

@ -0,0 +1,277 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file
* @brief NewLib system calls implementations for STM32F0
*
* @author Michael Baar <michael.baar@fu-berlin.de>
* @author Stefan Pfeiffer <pfeiffer@inf.fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/unistd.h>
#include <stdint.h>
#include "thread.h"
#include "kernel.h"
#include "irq.h"
#include "board.h"
#include "periph/uart.h"
/**
* manage the heap
*/
extern uint32_t _end; /* address of last used memory cell */
caddr_t heap_top = (caddr_t)&_end + 4;
/**
* @brief Initialize NewLib, called by __libc_init_array() from the startup script
*/
void _init(void)
{
uart_init_blocking(STDIO, 115200);
}
/**
* @brief Free resources on NewLib de-initialization, not used for RIOT
*/
void _fini(void)
{
// nothing to do here
}
/**
* @brief Exit a program without cleaning up files
*
* If your system doesn't provide this, it is best to avoid linking with subroutines that
* require it (exit, system).
*
* @param n the exit code, 0 for all OK, >0 for not OK
*/
void _exit(int n)
{
printf("#! exit %i: resetting\n", n);
NVIC_SystemReset();
while(1);
}
/**
* @brief Allocate memory from the heap.
*
* The current heap implementation is very rudimentary, it is only able to allocate
* memory. But it does not
* - check if the returned address is valid (no check if the memory very exists)
* - have any means to free memory again
*
* TODO: check if the requested memory is really available
*
* @return [description]
*/
caddr_t _sbrk_r(struct _reent *r, size_t incr)
{
unsigned int state = disableIRQ();
caddr_t res = heap_top;
heap_top += incr;
restoreIRQ(state);
return res;
}
/**
* @brief Get the process-ID of the current thread
*
* @return the process ID of the current thread
*/
int _getpid(void)
{
return sched_active_thread->pid;
}
/**
* @brief Send a signal to a given thread
*
* @param r TODO
* @param pid TODO
* @param sig TODO
*
* @return TODO
*/
int _kill_r(struct _reent *r, int pid, int sig)
{
r->_errno = ESRCH; /* not implemented yet */
return -1;
}
/**
* @brief Open a file
*
* @param r TODO
* @param name TODO
* @param mode TODO
*
* @return TODO
*/
int _open_r(struct _reent *r, const char *name, int mode)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Read from a file
*
* All input is read from STDIO. The function will block until a byte is actually read.
*
* Note: the read function does not buffer - data will be lost if the function is not
* called fast enough.
*
* TODO: implement more sophisticated read call.
*
* @param r TODO
* @param fd TODO
* @param buffer TODO
* @param int TODO
*
* @return TODO
*/
int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
{
char c;
char *buff = (char*)buffer;
uart_read_blocking(STDIO, &c);
buff[0] = c;
return 1;
}
/**
* @brief Write characters to a file
*
* All output is currently directed to STDIO, independent of the given file descriptor.
* The write call will further block until the byte is actually written to the UART.
*
* TODO: implement more sophisticated write call.
*
* @param r TODO
* @param fd TODO
* @param data TODO
* @param int TODO
*
* @return TODO
*/
int _write_r(struct _reent *r, int fd, const void *data, unsigned int count)
{
char *c = (char*)data;
for (int i = 0; i < count; i++) {
uart_write_blocking(STDIO, c[i]);
}
return count;
}
/**
* @brief Close a file
*
* @param r TODO
* @param fd TODO
*
* @return TODO
*/
int _close_r(struct _reent *r, int fd)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Set position in a file
*
* @param r TODO
* @param fd TODO
* @param pos TODO
* @param dir TODO
*
* @return TODO
*/
_off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int dir)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Status of an open file
*
* @param r TODO
* @param fd TODO
* @param stat TODO
*
* @return TODO
*/
int _fstat_r(struct _reent *r, int fd, struct stat * st)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Status of a file (by name)
*
* @param r TODO
* @param name TODO
* @param stat TODO
*
* @return TODO
*/
int _stat_r(struct _reent *r, char *name, struct stat *st)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Query whether output stream is a terminal
*
* @param r TODO
* @param fd TODO
*
* @return TODO
*/
int _isatty_r(struct _reent *r, int fd)
{
r->_errno = 0;
if(fd == STDOUT_FILENO || fd == STDERR_FILENO) {
return 1;
}
else {
return 0;
}
}
/**
* @brief Remove a file's directory entry
*
* @param r TODO
* @param path TODO
*
* @return TODO
*/
int _unlink_r(struct _reent *r, char* path)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}

View File

@ -28,13 +28,15 @@ RIOTBASE ?= $(CURDIR)/../..
QUIET ?= 1
BOARD_INSUFFICIENT_RAM := chronos msb-430h telosb wsn430-v1_3b wsn430-v1_4
BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 pttu redbee-econotag udoo z1 qemu-i386
# mbed_lpc1768: see https://github.com/RIOT-OS/RIOT/issues/675
# msb-430: see https://github.com/RIOT-OS/RIOT/issues/658
# pttu: see https://github.com/RIOT-OS/RIOT/issues/659
# redbee-econotag: see https://github.com/RIOT-OS/RIOT/issues/676
# z1: lacks RTC features
# qemu-i386: no tranceiver, yet
BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 pttu redbee-econotag udoo z1 qemu-i386 \
stm32f0discovery
# mbed_lpc1768: see https://github.com/RIOT-OS/RIOT/issues/675
# msb-430: see https://github.com/RIOT-OS/RIOT/issues/658
# pttu: see https://github.com/RIOT-OS/RIOT/issues/659
# redbee-econotag: see https://github.com/RIOT-OS/RIOT/issues/676
# z1: lacks RTC features
# qemu-i386: no transceiver, yet
# stm32f0discovery: no transceiver, yet
# Modules to include:

View File

@ -28,13 +28,15 @@ RIOTBASE ?= $(CURDIR)/../..
QUIET ?= 1
BOARD_INSUFFICIENT_RAM := chronos msb-430h telosb wsn430-v1_3b wsn430-v1_4
BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 pttu redbee-econotag udoo z1 qemu-i386
# mbed_lpc1768: see https://github.com/RIOT-OS/RIOT/issues/675
# msb-430: see https://github.com/RIOT-OS/RIOT/issues/658
# pttu: see https://github.com/RIOT-OS/RIOT/issues/659
# redbee-econotag: see https://github.com/RIOT-OS/RIOT/issues/676
# z1: lacks RTC features
# qemu-i386: no tranceiver, yet
BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 pttu redbee-econotag udoo z1 qemu-i386 \
stm32f0discovery
# mbed_lpc1768: see https://github.com/RIOT-OS/RIOT/issues/675
# msb-430: see https://github.com/RIOT-OS/RIOT/issues/658
# pttu: see https://github.com/RIOT-OS/RIOT/issues/659
# redbee-econotag: see https://github.com/RIOT-OS/RIOT/issues/676
# z1: lacks RTC features
# qemu-i386: no transceiver, yet
# stm32f0discovery: no transceiver, yet
# Modules to include:

View File

@ -28,11 +28,13 @@ RIOTBASE ?= $(CURDIR)/../..
QUIET ?= 1
# Blacklist boards
BOARD_BLACKLIST := arduino-due avsextrem chronos mbed_lpc1768 msb-430h msba2 redbee-econotag telosb wsn430-v1_3b wsn430-v1_4 msb-430 pttu udoo qemu-i386 z1
BOARD_BLACKLIST := arduino-due avsextrem chronos mbed_lpc1768 msb-430h msba2 redbee-econotag telosb wsn430-v1_3b wsn430-v1_4 msb-430 pttu udoo qemu-i386 z1 \
stm32f0discovery
# This example only works with native for now.
# msb430-based boards: msp430-g++ is not provided in mspgcc.
# (People who want use c++ can build c++ compiler from source, or get binaries from Energia http://energia.nu/)
# msba2: some changes should be applied to successfully compile c++. (_kill_r, _kill, __dso_handle)
# stm32f0discovery: g++ does not support some used flags (e.g. -mthumb...)
# others: untested.
# If you want to add some extra flags when compile c++ files, add these flags

View File

@ -35,11 +35,12 @@ ifeq ($(shell $(CC) -Wno-cpp -E - 2>/dev/null >/dev/null dev/null ; echo $$?),0)
endif
BOARD_INSUFFICIENT_RAM := chronos msb-430h redbee-econotag telosb wsn430-v1_3b wsn430-v1_4 z1
BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 pttu udoo qemu-i386
# mbed_lpc1768: see https://github.com/RIOT-OS/RIOT/issues/675
# msb-430: see https://github.com/RIOT-OS/RIOT/issues/658
# pttu: see https://github.com/RIOT-OS/RIOT/issues/659
# qemu-i386: no tranceiver, yet
BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 pttu udoo qemu-i386 stm32f0discovery
# mbed_lpc1768: see https://github.com/RIOT-OS/RIOT/issues/675
# msb-430: see https://github.com/RIOT-OS/RIOT/issues/658
# pttu: see https://github.com/RIOT-OS/RIOT/issues/659
# qemu-i386: no transceiver, yet
# stm32f0discovery: no transceiver, yet
# Modules to include:

View File

@ -2,7 +2,7 @@ APPLICATION = test_bloom
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := chronos mbed_lpc1768 msb-430 msb-430h redbee-econotag \
telosb wsn430-v1_3b wsn430-v1_4 z1
telosb wsn430-v1_3b wsn430-v1_4 z1 stm32f0discovery
USEMODULE += hashes
USEMODULE += bloom

View File

@ -1,6 +1,8 @@
APPLICATION = test_bloom_bytes
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := stm32f0discovery
USEMODULE += hashes
USEMODULE += bloom
USEMODULE += random

View File

@ -1,7 +1,8 @@
APPLICATION = test_coap
include ../Makefile.tests_common
BOARD_BLACKLIST := arduino-due chronos mbed_lpc1768 msb-430 msb-430h qemu-i386 telosb wsn430-v1_3b wsn430-v1_4 udoo z1
BOARD_BLACKLIST := arduino-due chronos mbed_lpc1768 msb-430 msb-430h qemu-i386 stm32f0discovery \
telosb wsn430-v1_3b wsn430-v1_4 udoo z1
BOARD_INSUFFICIENT_RAM := redbee-econotag
#MSP boards: no assert.h
#rest: no radio

View File

@ -1,6 +1,8 @@
APPLICATION = test_ipc_pingpong
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := stm32f0discovery
DISABLE_MODULE += auto_init
include $(RIOTBASE)/Makefile.include

View File

@ -1,7 +1,8 @@
APPLICATION = test_net_if
BOARD_BLACKLIST = mbed_lpc1768 arduino-due udoo qemu-i386
# qemu-i386: no tranceiver, yet
BOARD_BLACKLIST = mbed_lpc1768 arduino-due udoo qemu-i386 stm32f0discovery
# qemu-i386: no transceiver, yet
# stm32f0discovery: no transceiver, yet
include ../Makefile.tests_common

View File

@ -2,10 +2,11 @@ APPLICATION = test_pnet
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := chronos msb-430h redbee-econotag telosb wsn430-v1_3b wsn430-v1_4 z1
BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 udoo qemu-i386
BOARD_BLACKLIST := arduino-due mbed_lpc1768 msb-430 udoo qemu-i386 stm32f0discovery
# mbed_lpc1768: see https://github.com/RIOT-OS/RIOT/issues/675
# msb-430: see https://github.com/RIOT-OS/RIOT/issues/658
# qemu-i386: no tranceiver, yet
# qemu-i386: no transceiver, yet
# stm32f0discovery: no transceiver, yet
USEMODULE += posix
USEMODULE += pnet

View File

@ -1,7 +1,7 @@
APPLICATION = test_posix_semaphore
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := msb-430 msb-430h mbed_lpc1768 redbee-econotag chronos
BOARD_INSUFFICIENT_RAM := msb-430 msb-430h mbed_lpc1768 redbee-econotag chronos stm32f0discovery
USEMODULE += posix

View File

@ -2,6 +2,9 @@
APPLICATION = test_pthread_barrier
include ../Makefile.tests_common
# exclude boards with insufficient RAM
BOARD_INSUFFICIENT_RAM := stm32f0discovery
## Modules to include.
USEMODULE += pthread
USEMODULE += random

View File

@ -1,6 +1,8 @@
APPLICATION = test_condition_variable
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := stm32f0discovery
USEMODULE += posix
USEMODULE += pthread
USEMODULE += vtimer

View File

@ -9,6 +9,6 @@ DISABLE_MODULE += auto_init
CFLAGS += -DNATIVE_AUTO_EXIT
BOARD_INSUFFICIENT_RAM += chronos mbed_lpc1768 msb-430 msb-430h
BOARD_INSUFFICIENT_RAM += chronos mbed_lpc1768 msb-430 msb-430h stm32f0discovery
include $(RIOTBASE)/Makefile.include

View File

@ -1,7 +1,7 @@
APPLICATION = test_queue_fairness
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := mbed_lpc1768
BOARD_INSUFFICIENT_RAM := mbed_lpc1768 stm32f0discovery
USEMODULE += vtimer

View File

@ -1,6 +1,8 @@
APPLICATION = test_struct_tm_utility
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := stm32f0discovery
DISABLE_MODULE += auto_init
USEMODULE += shell

View File

@ -1,7 +1,7 @@
APPLICATION = test_thread_cooperation
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := chronos msb-430 msb-430h mbed_lpc1768 redbee-econotag
BOARD_INSUFFICIENT_RAM := chronos msb-430 msb-430h mbed_lpc1768 redbee-econotag stm32f0discovery
DISABLE_MODULE += auto_init

View File

@ -1,6 +1,8 @@
APPLICATION = test_thread_exit
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := stm32f0discovery
DISABLE_MODULE += auto_init
include $(RIOTBASE)/Makefile.include

View File

@ -1,6 +1,8 @@
APPLICATION = test_thread_msg
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := stm32f0discovery
DISABLE_MODULE += auto_init
include $(RIOTBASE)/Makefile.include

View File

@ -1,6 +1,8 @@
APPLICATION = test_thread_msg_seq
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := stm32f0discovery
DISABLE_MODULE += auto_init
include $(RIOTBASE)/Makefile.include

View File

@ -1,6 +1,8 @@
APPLICATION = test_vtimer_msg
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := stm32f0discovery
USEMODULE += vtimer
include $(RIOTBASE)/Makefile.include

View File

@ -1,7 +1,7 @@
APPLICATION = test_vtimer_msg_diff
include ../Makefile.tests_common
BOARD_INSUFFICIENT_RAM := mbed_lpc1768
BOARD_INSUFFICIENT_RAM := mbed_lpc1768 stm32f0discovery
USEMODULE += vtimer