Browse Source

cpu: initial import of stm32f1

dev/timer
Thomas Eichinger 8 years ago
parent
commit
37611db41c
  1. 5
      boards/iot-lab_M3/Makefile
  2. 3
      boards/iot-lab_M3/Makefile.dep
  3. 50
      boards/iot-lab_M3/Makefile.include
  4. 65
      boards/iot-lab_M3/board.c
  5. 1067
      boards/iot-lab_M3/board_init.c
  6. 13
      boards/iot-lab_M3/dist/agilefox_jtag.cfg
  7. 17
      boards/iot-lab_M3/dist/debug.sh
  8. 20
      boards/iot-lab_M3/dist/flash.sh
  9. 13
      boards/iot-lab_M3/dist/iot-lab_M3_jtag.cfg
  10. 15
      boards/iot-lab_M3/dist/reset.sh
  11. 34
      boards/iot-lab_M3/drivers/Makefile
  12. 212
      boards/iot-lab_M3/drivers/at86rf231_driver.c
  13. 70
      boards/iot-lab_M3/drivers/at86rf231_spi1.c
  14. 22
      boards/iot-lab_M3/drivers/iot-lab_M3-uart.c
  15. 6
      boards/iot-lab_M3/include/at86rf231_spi1.h
  16. 89
      boards/iot-lab_M3/include/board.h
  17. 207
      boards/iot-lab_M3/include/periph_conf.h
  18. 4
      boards/iot-lab_M3/tools/openocd.cfg
  19. 44
      cpu/cortex-m3_common/include/cmsis_system.h
  20. 38
      cpu/cortex-m3_common/thread_arch.c
  21. 67
      cpu/cortexm_common/crash.c
  22. 7
      cpu/stm32f1/Makefile
  23. 26
      cpu/stm32f1/Makefile.include
  24. 30
      cpu/stm32f1/cpu.c
  25. 76
      cpu/stm32f1/hwtimer_arch.c
  26. 73
      cpu/stm32f1/include/cpu-conf.h
  27. 32
      cpu/stm32f1/include/hwtimer_cpu.h
  28. 176
      cpu/stm32f1/include/spi.h
  29. 8337
      cpu/stm32f1/include/stm32f10x.h
  30. 32
      cpu/stm32f1/io_arch.c
  31. 55
      cpu/stm32f1/lpm_arch.c
  32. 5
      cpu/stm32f1/periph/Makefile
  33. 736
      cpu/stm32f1/periph/gpio.c
  34. 109
      cpu/stm32f1/periph/spi.c
  35. 345
      cpu/stm32f1/periph/timer.c
  36. 307
      cpu/stm32f1/periph/uart.c
  37. 34
      cpu/stm32f1/reboot_arch.c
  38. 271
      cpu/stm32f1/startup.c
  39. 142
      cpu/stm32f1/stm32f103re_linkerscript.ld
  40. 276
      cpu/stm32f1/syscalls.c
  41. 2
      drivers/include/periph/timer.h
  42. 3
      examples/hello-world/Makefile
  43. 3
      examples/ipc_pingpong/Makefile
  44. 3
      tests/thread_basic/Makefile
  45. 3
      tests/thread_exit/Makefile

5
boards/iot-lab_M3/Makefile

@ -0,0 +1,5 @@
MODULE =$(BOARD)_base
DIRS = drivers
include $(RIOTBASE)/Makefile.base

3
boards/iot-lab_M3/Makefile.dep

@ -0,0 +1,3 @@
ifneq (,$(findstring at86rf231,$(USEMODULE)))
USEMODULE += at86rf231
endif

50
boards/iot-lab_M3/Makefile.include

@ -0,0 +1,50 @@
## the cpu to build for
export CPU = stm32f1
export CPU_MODEL = stm32f103re
# set the default port
export PORT ?= /dev/ttyUSB2
# 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 = $(RIOTBOARD)/$(BOARD)/dist/flash.sh
export DEBUGGER = $(RIOTBOARD)/$(BOARD)/dist/debug.sh
# define build specific options
export CPU_USAGE = -mcpu=cortex-m3
export FPU_USAGE =
export CFLAGS += -ggdb -g3 -std=gnu99 -Os -Wall -Wstrict-prototypes $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian -mthumb -mthumb-interwork -nostartfiles
export CFLAGS += -flto -ffunction-sections -fdata-sections -fno-builtin
export ASFLAGS += -ggdb -g3 $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian
export LINKFLAGS += -ggdb -g3 -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 ihex
export FFLAGS = $(BINDIR)/$(APPLICATION).hex
export DEBUGGER_FLAGS = $(BINDIR)/$(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/
# TODO -> move this to the appropriate Makefile.dep!!!
ifneq (,$(filter defaulttransceiver,$(USEMODULE)))
USEMODULE += at86rf231
USEMODULE += transceiver
endif
# TODO -> is this needed?
TERM = miniterm.py -b 115200

65
boards/iot-lab_M3/board.c

@ -0,0 +1,65 @@
/*
* 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_iot-lab_M3
* @{
*
* @file board.c
* @brief Board specific implementations for the iot-lab_M3 board
*
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de
*
* @}
*/
#include "cmsis_system.h"
#include "board.h"
#include "cpu.h"
static void leds_init(void);
void board_init(void)
{
/* initialize core clocks via CMSIS function provided by ST */
SystemInit();
/* initialize the CPU */
cpu_init();
/* initialize the boards LEDs */
leds_init();
}
/**
* @brief Initialize the boards on-board LEDs
*
* The LEDs initialization is hard-coded in this function. As the LED is soldered
* onto the board it is fixed to its CPU pins.
*
* The LEDs are connected to the following pin:
* - Green: PB5
* - Orange: PC10
* - Red: PD2
*/
static void leds_init(void)
{
/* green pin */
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
GPIOB->CRL = (0x3 << (5*4));
/* orange pin */
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC->CRH = (0x3 << ((10-8)*4));
/* red pin */
RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;
GPIOD->CRL = (0x3 << (2*4));
}

1067
boards/iot-lab_M3/board_init.c

File diff suppressed because it is too large Load Diff

13
boards/iot-lab_M3/dist/agilefox_jtag.cfg vendored

@ -0,0 +1,13 @@
jtag_khz 1000
# comstick ftdi device
interface ft2232
ft2232_layout "usbjtag"
ft2232_device_desc "HiKoB FOX JTAG"
ft2232_vid_pid 0x0403 0x6010
jtag_nsrst_delay 100
jtag_ntrst_delay 100
# use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst

17
boards/iot-lab_M3/dist/debug.sh vendored

@ -0,0 +1,17 @@
#!/bin/bash
if [ -L "$0" ]; then
FILE=$(readlink "$0")
else
FILE="$0"
fi
BIN_FOLDER=$(dirname "${FILE}")
openocd -f "${BIN_FOLDER}/${BOARD}_jtag.cfg" \
-f "target/stm32f1x.cfg" \
-c "tcl_port 6333"
-c "telnet_port 4444"
-c "init" \
-c "targets" \
-c "reset halt"

20
boards/iot-lab_M3/dist/flash.sh vendored

@ -0,0 +1,20 @@
#!/bin/bash
if [ -L "$0" ]; then
FILE=$(readlink "$0")
else
FILE="$0"
fi
BIN_FOLDER=$(dirname "${FILE}")
openocd -f "${BIN_FOLDER}/${BOARD}_jtag.cfg" \
-f "target/stm32f1x.cfg" \
-c "init" \
-c "targets" \
-c "reset halt" \
-c "reset init" \
-c "flash write_image erase $1" \
-c "verify_image $1" \
-c "reset run"\
-c "shutdown"

13
boards/iot-lab_M3/dist/iot-lab_M3_jtag.cfg vendored

@ -0,0 +1,13 @@
jtag_khz 1000
# comstick ftdi device
interface ft2232
ft2232_layout "usbjtag"
ft2232_device_desc "FITECO M3"
ft2232_vid_pid 0x0403 0x6010
jtag_nsrst_delay 100
jtag_ntrst_delay 100
# use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst

15
boards/iot-lab_M3/dist/reset.sh vendored

@ -0,0 +1,15 @@
#!/bin/bash
if [ -L "$0" ]; then
FILE=$(readlink "$0")
else
FILE="$0"
fi
BIN_FOLDER=$(dirname "${FILE}")
openocd -f "${BIN_FOLDER}/iot-lab_m3_jtag.cfg" \
-f "target/stm32f1x.cfg" \
-c "init" \
-c "reset run" \
-c "shutdown"

34
boards/iot-lab_M3/drivers/Makefile

@ -0,0 +1,34 @@
SRC = $(wildcard *.c)
#BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
OBJ = $(SRC:%.c=$(BINDIR)%.o)
DEP = $(SRC:%.c=$(BINDIR)%.d)
INCLUDES += -I../include
INCLUDES += -I$(RIOTCPU)/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/Include
INCLUDES += -I$(RIOTCPU)/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x
INCLUDES += -I$(RIOTCPU)/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc
INCLUDES += -I$(RIOTCPU)/stm32f103rey6/include
INCLUDES += -I$(RIOTBASE)/drivers/at86rf231/include
INCLUDES += -I$(RIOTBASE)/sys/include
INCLUDES += -I$(RIOTBASE)/sys/net/include
.PHONY: $(BINDIR)iot-lab_M3_drivers.a
$(BINDIR)iot-lab_M3_drivers.a: $(OBJ)
$(AD) $(AR) rcs $(BINDIR)iot-lab_M3_base.a $(OBJ)
# pull in dependency info for *existing* .o files
-include $(OBJ:.o=.d)
# compile and generate dependency info
$(BINDIR)%.o: %.c
$(AD) $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(APPLICATIONINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
$(AD) $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(APPLICATIONINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
@printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/fw_out && mv /tmp/fw_out $(BINDIR)$*.d
# remove compilation products
clean:
rm -f $(OBJ) $(DEP)

212
boards/iot-lab_M3/drivers/at86rf231_driver.c

@ -0,0 +1,212 @@
#include <stdio.h>
#include <stddef.h>
#include "cpu.h"
#include "sched.h"
#include "vtimer.h"
#include "periph/gpio.h"
#include "periph_conf.h"
#include "board.h"
#include "at86rf231.h"
#include "at86rf231_spi.h"
#include "at86rf231_spi1.h"
extern volatile unsigned int sched_context_switch_request;
/*
SPI1
SCLK : PA5
MISO : PA6
MOSI : PA7
CS : PA4
GPIO
IRQ0 : PC4 : Frame buff empty indicator
DIG2 : ? : RX Frame Time stamping XXX : NOT USED
Reset : PC1 : active low, enable chip
SLEEP : PA2 : control sleep, tx & rx state
*/
inline static void RESET_CLR(void)
{
GPIOC->BRR = 1 << 1;
}
inline static void RESET_SET(void)
{
GPIOC->BSRR = 1 << 1;
}
inline static void CSn_SET(void)
{
GPIOA->BSRR = 1 << 4;
}
inline static void CSn_CLR(void)
{
GPIOA->BRR = 1 << 4;
}
inline static void SLEEP_CLR(void)
{
GPIOA->BRR = 1 << 2;
}
uint8_t at86rf231_get_status(void)
{
return at86rf231_reg_read(AT86RF231_REG__TRX_STATUS)
& AT86RF231_TRX_STATUS_MASK__TRX_STATUS;
}
extern void at86rf231_rx_irq(void);
static
void enable_exti_interrupt(void)
{
// EXTI_InitTypeDef EXTI_InitStructure;
// EXTI_InitStructure.EXTI_Line = EXTI_Line4;
// EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
// EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
// EXTI_InitStructure.EXTI_LineCmd = ENABLE;
// EXTI_Init(&EXTI_InitStructure);
gpio_init_int(GPIO_6, GPIO_NOPULL, GPIO_RISING, at86rf231_rx_irq);
}
static
void disable_exti_interrupt(void)
{
// EXTI_InitTypeDef EXTI_InitStructure;
// EXTI_InitStructure.EXTI_Line = EXTI_Line4;
// EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
// EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
// EXTI_InitStructure.EXTI_LineCmd = DISABLE;
// EXTI_Init(&EXTI_InitStructure);
#warning not implemented yet
}
void at86rf231_gpio_spi_interrupts_init(void)
{
/* SPI1 init */
at86rf231_spi1_init();
/* IRQ0 : PC4, INPUT and IRQ */
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_Init(GPIOC, &GPIO_InitStructure);
gpio_init_in(GPIO_4, GPIO_NOPULL);
/* Enable AFIO clock */
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* Connect EXTI4 Line to PC4 pin */
// GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4);
/* Configure EXTI4 line */
enable_exti_interrupt();
/* Enable and set EXTI4 Interrupt to the lowest priority */
// NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
/* Init GPIOs */
/* CS & SLEEP */
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_4;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
gpio_init_out(GPIO_2, GPIO_NOPULL);
gpio_init_out(GPIO_4, GPIO_NOPULL);
/* RESET */
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_Init(GPIOC, &GPIO_InitStructure);
gpio_init_out(GPIO_1, GPIO_NOPULL);
}
void at86rf231_reset(void)
{
/* force reset */
RESET_CLR();
CSn_SET();
SLEEP_CLR();
vtimer_usleep(AT86RF231_TIMING__RESET);
RESET_SET();
/* Wait until TRX_OFF is entered */
vtimer_usleep(AT86RF231_TIMING__RESET_TO_TRX_OFF);
/* Send a FORCE TRX OFF command */
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__FORCE_TRX_OFF);
/* Wait until TRX_OFF state is entered from P_ON */
vtimer_usleep(AT86RF231_TIMING__SLEEP_TO_TRX_OFF);
/* busy wait for TRX_OFF state */
uint8_t status;
uint8_t max_wait = 100; // TODO : move elsewhere, this is in 10us
do {
status = at86rf231_get_status();
vtimer_usleep(10);
if (!--max_wait) {
printf("at86rf231 : ERROR : could not enter TRX_OFF mode");
break;
}
}
while ((status & AT86RF231_TRX_STATUS_MASK__TRX_STATUS) != AT86RF231_TRX_STATUS__TRX_OFF);
}
void at86rf231_spi_select(void)
{
CSn_CLR();
}
void at86rf231_spi_unselect(void)
{
CSn_SET();
}
void at86rf231_enable_interrupts(void)
{
enable_exti_interrupt();
}
void at86rf231_disable_interrupts(void)
{
disable_exti_interrupt();
}
// extern void at86rf231_rx_irq(void);
// __attribute__((naked))
// void EXTI4_IRQHandler(void)
// {
// save_context();
// if (EXTI_GetITStatus(EXTI_Line4) != RESET) {
// /* IRQ_3 (TRX_END), read Frame Buffer */
// EXTI_ClearITPendingBit(EXTI_Line4);
// at86rf231_rx_irq();
// if (sched_context_switch_request) {
// /* scheduler */
// thread_yield();
// }
// }
// restore_context();
// }

70
boards/iot-lab_M3/drivers/at86rf231_spi1.c

@ -0,0 +1,70 @@
#include <stdio.h>
#include <stddef.h>
#include "cpu.h"
#include "periph/gpio.h"
#include "spi.h"
#include "periph_conf.h"
#include "at86rf231_spi1.h"
void at86rf231_spi1_init(void)
{
// SPI_InitTypeDef SPI_InitStructure;
/* RCC */
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
// RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
/* GPIO */
/* Configure SPI MASTER pins */
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIOA->CRL &= ~(0xf << (5 * 4));
GPIOA->CRL |= (0xB << (5 * 4));
GPIOA->CRL &= ~(0xf << (7 * 4));
GPIOA->CRL |= (0xB << (7 * 4));
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
gpio_init_in(GPIO_6, GPIO_NOPULL);
/* SPI
* NOTE: APB2 is 72MHz, prescaler 16 => SPI @ 4.5 MHz, radio spi max is 7.5MHz
* Clock idle low, rising edge
*/
// SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
// SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
// SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
// SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
// SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
// SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
// SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
// SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
// SPI_InitStructure.SPI_CRCPolynomial = 7;
//SPI_Init(SPI1, &SPI_InitStructure);
#warning implement spi
/* Enable interrupt */
//SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);
/* Enable SPI */
// SPI_Cmd(SPI1, ENABLE);
}
uint8_t at86rf231_spi_transfer_byte(uint8_t byte)
{
char ret;
spi_transfer_byte(SPI_0, byte?byte:0, byte?0:&ret );
return ret;
}
void at86rf231_spi_transfer(const uint8_t *data_out, uint8_t *data_in, uint16_t length)
{
spi_transfer_bytes(SPI_0, (char*)data_out, (char*)data_in, length);
}

22
boards/iot-lab_M3/drivers/iot-lab_M3-uart.c

@ -0,0 +1,22 @@
/**
* Copyright (C) 2014 Oliver Hahm <oliver.hahm@inria.fr>
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @file iot-lab_M3-uart.c
* @author Oliver Hahm <oliver.hahm@inria.fr>
*/
#include "stm32f10x.h"
#include "periph/uart.h"
int fw_puts(char *astring, int length)
{
for (int i = 0; i < length; i++) {
uart_write_blocking(UART_0, astring[i]);
}
return length;
}

6
boards/iot-lab_M3/include/at86rf231_spi1.h

@ -0,0 +1,6 @@
#ifndef AT86RF231_SPI1_H_
#define AT86RF231_SPI1_H_
void at86rf231_spi1_init(void);
#endif

89
boards/iot-lab_M3/include/board.h

@ -0,0 +1,89 @@
/*
* Copyright (C) 2014 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup board_iot-lab_M3 iot-lab_M3
* @ingroup boards
* @brief Board specific files for the iot-lab_M3 board.
* @{
*
* @file
* @brief Board specific definitions for the iot-lab_M3 board.
*
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef BOARD_H_
#define BOARD_H_
#include <stdint.h>
#include "cpu.h"
/**
* Define the nominal CPU core clock in this board
*/
#define F_CPU (72000000UL)
/**
* @name Define the UART to be used as stdio and its baudrate
* @{
*/
#define STDIO UART_0
#define STDIO_BAUDRATE (115200)
/** @} */
/**
* Assign the hardware timer
*/
#define HW_TIMER TIMER_0
/**
* @name LED pin definitions
* @{
*/
#define LED_RED_PORT (GPIOD->ODR)
#define LED_RED_PIN (1<<2)
#define LED_GREEN_PORT (GPIOB->ODR)
#define LED_GREEN_PIN (1<<5)
#define LED_ORANGE_PORT (GPIOC->ODR)
#define LED_ORANGE_PIN (1<<10)
/** @} */
/**
* @name Macros for controlling the on-board LEDs.
* @{
*/
#define LED_RED_ON (LED_RED_PORT &= ~LED_RED_PIN)
#define LED_RED_OFF (LED_RED_PORT |= LED_RED_PIN)
#define LED_RED_TOGGLE (LED_RED_PORT ^= LED_RED_PIN)
#define LED_GREEN_ON (LED_GREEN_PORT &= ~LED_GREEN_PIN)
#define LED_GREEN_OFF (LED_GREEN_PORT |= LED_GREEN_PIN)
#define LED_GREEN_TOGGLE (LED_GREEN_PORT ^= LED_GREEN_PIN)
#define LED_ORANGE_ON (LED_ORANGE_PORT &= ~LED_ORANGE_PIN)
#define LED_ORANGE_OFF (LED_ORANGE_PORT |= LED_ORANGE_PIN)
#define LED_ORANGE_TOGGLE (LED_ORANGE_PORT ^= LED_ORANGE_PIN)
/** @} */
/**
* Define the type for the radio packet length for the transceiver
*/
typedef uint8_t radio_packet_length_t;
/**
* @brief Initialize board specific hardware, including clock, LEDs and std-IO
*/
void board_init(void);
#endif /* BOARD_H_ */
/** @} */

207
boards/iot-lab_M3/include/periph_conf.h

@ -0,0 +1,207 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup board_iot-lab_M3
* @{
*
* @file periph_conf.h
* @brief Peripheral MCU configuration for the iot-lab_M3 board
*
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*/
#ifndef __PERIPH_CONF_H
#define __PERIPH_CONF_H
/**
* @brief Timer configuration
* @{
*/
#define TIMER_NUMOF (2U)
#define TIMER_0_EN 1
#define TIMER_1_EN 2
/* Timer 0 configuration */
#define TIMER_0_DEV TIM2
#define TIMER_0_CHANNELS 4
#define TIMER_0_PRESCALER (36000U)
#define TIMER_0_MAX_VALUE (0xffff)
#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 TIM3
#define TIMER_1_CHANNELS 2
#define TIMER_1_PRESCALER (36000U)
#define TIMER_1_MAX_VALUE (0xffff)
#define TIMER_1_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_TIM3EN)
#define TIMER_1_ISR isr_tim3
#define TIMER_1_IRQ_CHAN TIM3_IRQn
#define TIMER_1_IRQ_PRIO 1
/** @} */
/**
* @brief UART configuration
*/
#define UART_NUMOF (2U)
#define UART_0_EN 1
#define UART_1_EN 0
#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 GPIOA
#define UART_0_PORT_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPAEN)
#define UART_0_RX_PIN 10
#define UART_0_TX_PIN 9
#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->APB2ENR |= RCC_APB2ENR_IOPAEN)
#define UART_1_RX_PIN 3
#define UART_1_TX_PIN 2
#define UART_1_AF 1
/**
* @brief 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->APB2ENR |= RCC_APB2ENR_IOPAEN)
#define GPIO_0_EXTI_CFG() (AFIO->EXTICR[GPIO_0_PIN>>0x02] |= (((uint32_t)0x00) << (0x04 * (GPIO_0_PIN & (uint8_t)0x03))))
#define GPIO_0_IRQ EXTI0_IRQn
/* GPIO channel 1 config */
#define GPIO_1_PORT GPIOA
#define GPIO_1_PIN 1
#define GPIO_1_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPAEN)
#define GPIO_1_EXTI_CFG() (AFIO->EXTICR[GPIO_1_PIN>>0x02] |= (((uint32_t)0x00) << (0x04 * (GPIO_1_PIN & (uint8_t)0x03))))
#define GPIO_1_IRQ EXTI0_IRQn
/* GPIO channel 2 config */
#define GPIO_2_PORT GPIOF
#define GPIO_2_PIN 4
#define GPIO_2_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPFEN)
#define GPIO_2_EXTI_CFG() (AFIO->EXTICR[GPIO_2_PIN>>0x02] |= (((uint32_t)0x05) << (0x04 * (GPIO_2_PIN & (uint8_t)0x03))))
#define GPIO_2_IRQ EXTI4_IRQn
/* GPIO channel 3 config */
#define GPIO_3_PORT GPIOF
#define GPIO_3_PIN 5
#define GPIO_3_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPFEN)
#define GPIO_3_EXTI_CFG() (AFIO->EXTICR[GPIO_3_PIN>>0x02] |= (((uint32_t)0x05) << (0x04 * (GPIO_3_PIN & (uint8_t)0x03))))
#define GPIO_3_IRQ EXTI4_IRQn
/* GPIO channel 4 config */
#define GPIO_4_PORT GPIOF
#define GPIO_4_PIN 6
#define GPIO_4_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPFEN)
#define GPIO_4_EXTI_CFG() (AFIO->EXTICR[GPIO_3_PIN>>0x02] |= (((uint32_t)0x05) << (0x04 * (GPIO_3_PIN & (uint8_t)0x03))))
#define GPIO_4_IRQ EXTI4_IRQn
/* GPIO channel 5 config */
#define GPIO_5_PORT GPIOF
#define GPIO_5_PIN 7
#define GPIO_5_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPFEN)
#define GPIO_5_EXTI_CFG() (AFIO->EXTICR[GPIO_5_PIN>>0x02] |= (((uint32_t)0x05) << (0x04 * (GPIO_5_PIN & (uint8_t)0x03))))
#define GPIO_5_IRQ EXTI4_IRQn
/* GPIO channel 6 config */
#define GPIO_6_PORT GPIOC
#define GPIO_6_PIN 4
#define GPIO_6_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPCEN)
#define GPIO_6_EXTI_CFG() (AFIO->EXTICR[GPIO_6_PIN>>0x02] |= (((uint32_t)0x02) << (0x04 * (GPIO_6_PIN & (uint8_t)0x03))))
#define GPIO_6_IRQ EXTI3_IRQn
/* GPIO channel 7 config */
#define GPIO_7_PORT GPIOC
#define GPIO_7_PIN 11
#define GPIO_7_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPCEN)
#define GPIO_7_EXTI_CFG() (AFIO->EXTICR[GPIO_7_PIN>>0x02] |= (((uint32_t)0x02) << (0x04 * (GPIO_7_PIN & (uint8_t)0x03))))
#define GPIO_7_IRQ EXTI3_IRQn
/* GPIO channel 8 config */
#define GPIO_8_PORT GPIOC
#define GPIO_8_PIN 12
#define GPIO_8_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPCEN)
#define GPIO_8_EXTI_CFG() (AFIO->EXTICR[GPIO_8_PIN>>0x02] |= (((uint32_t)0x02) << (0x04 * (GPIO_8_PIN & (uint8_t)0x03))))
#define GPIO_8_IRQ EXTI3_IRQn
/* GPIO channel 9 config */
#define GPIO_9_PORT GPIOC
#define GPIO_9_PIN 13
#define GPIO_9_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPCEN)
#define GPIO_9_EXTI_CFG() (AFIO->EXTICR[GPIO_9_PIN>>0x02] |= (((uint32_t)0x02) << (0x04 * (GPIO_9_PIN & (uint8_t)0x03))))
#define GPIO_9_IRQ EXTI3_IRQn
/* GPIO channel 10 config */
#define GPIO_10_PORT GPIOC
#define GPIO_10_PIN 14
#define GPIO_10_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPCEN)
#define GPIO_10_EXTI_CFG() (AFIO->EXTICR[GPIO_10_PIN>>0x02] |= (((uint32_t)0x02) << (0x04 * (GPIO_10_PIN & (uint8_t)0x03))))
#define GPIO_10_IRQ EXTI3_IRQn
/* GPIO channel 11 config */
#define GPIO_11_PORT GPIOC
#define GPIO_11_PIN 15
#define GPIO_11_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPCEN)
#define GPIO_11_EXTI_CFG() (AFIO->EXTICR[GPIO_11_PIN>>0x02] |= (((uint32_t)0x02) << (0x04 * (GPIO_11_PIN & (uint8_t)0x03))))
#define GPIO_11_IRQ EXTI3_IRQn
/**
* @brief SPI configuration
*/
#define SPI_NUM_OF 1
#define SPI_0_EN 1
#define SPI_IRQ_0 SPI_0
#define SPI_0_BR_PRESC 16
#define SPI_0_SCLK GPIO_5_PIN
#define SPI_0_MISO GPIO_6_PIN
#define SPI_0_MOSI GPIO_7_PIN
#define SPI_0_CS GPIO_4_PIN
#endif /* __PERIPH_CONF_H */
/** @} */

4
boards/iot-lab_M3/tools/openocd.cfg

@ -0,0 +1,4 @@
# openocd.cfg file for STM32F4Discovery board via integrated ST-Link/V2.
source [find interface/stlink-v2.cfg]
source [find target/stm32f4x_stlink.cfg]
reset_config srst_only srst_nogate

44
cpu/cortex-m3_common/include/cmsis_system.h

@ -0,0 +1,44 @@
/*
* 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_cortexm3_common
* @{
*
* @file
* @brief CMSIS system header definitions for the Cortex-M0
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __CMSIS_SYSTEM_H
#define __CMSIS_SYSTEM_H
#include <stdint.h>
/**
* @brief This variable holds the current CPU core clock frequency in Hz
*/
extern uint32_t SystemCoreClock;
/**
* @brief Initialize the system's clock system
*
* This function sets up the system's clock tree, concerning all options
* regarding PLL setup, external clock source configuration and prescaler
* setup for peripheral buses.
*/
void SystemInit(void);
/**
* @brief Update the `SystemCoreClock` variable with the current core clock value
*/
void SystemCoreClockUpdate(void);
#endif /* __CMSIS_SYSTEM_H */

38
cpu/cortex-m3_common/thread_arch.c

@ -7,10 +7,10 @@
*/
/**
* @ingroup cpu_cortex-m3
* @ingroup cpu_cortexm4_common
* @{
*
* @file thread_arch.c
* @file
* @brief Implementation of the kernel's architecture dependent thread interface
*
* @author Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
@ -25,6 +25,7 @@
#include "arch/thread_arch.h"
#include "thread.h"
#include "sched.h"
#include "thread.h"
#include "irq.h"
#include "cpu.h"
#include "kernel_internal.h"
@ -46,7 +47,14 @@ static void context_save(void);
static void context_restore(void) NORETURN;
/**
* Cortex-M3 knows stacks and handles register backups, so use different stack frame layout
* Cortex-M knows stacks and handles register backups, so use different stack frame layout
*
* TODO: How to handle different Cortex-Ms? Code is so far valid for M3 and M4 without FPU
*
* Layout with storage of floating point registers (applicable for Cortex-M4):
* ------------------------------------------------------------------------------------------------------------------------------------
* | R0 | R1 | R2 | R3 | LR | PC | xPSR | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 | S9 | S10 | S11 | S12 | S13 | S14 | S15 | FPSCR |
* ------------------------------------------------------------------------------------------------------------------------------------
*
* Layout without floating point registers:
* --------------------------------------
@ -61,23 +69,37 @@ char *thread_arch_stack_init(void *(*task_func)(void *), void *arg, void *stack_
/* marker */
stk--;
*stk = (uint32_t)STACK_MARKER;
*stk = STACK_MARKER;
/* TODO: fix FPU handling for Cortex-M4 */
/*
stk--;
*stk = (unsigned int) 0;
*/
/* S0 - S15 */
/*
for (int i = 15; i >= 0; i--) {
stk--;
*stk = i;
}
*/
/* FIXME xPSR */
stk--;
*stk = (uint32_t)0x01000200;
*stk = (unsigned int) 0x01000200;
/* program counter */
stk--;
*stk = (uint32_t)task_func;
*stk = (unsigned int) task_func;
/* link register, jumped to when thread exits */
stk--;
*stk = (uint32_t)sched_task_exit;
*stk = (unsigned int) sched_task_exit;
/* r12 */
stk--;
*stk = (uint32_t) 0;
*stk = (unsigned int) 0;
/* r1 - r3 */
for (int i = 3; i >= 1; i--) {

67
cpu/cortexm_common/crash.c

@ -0,0 +1,67 @@
/*
* Copyright (C) 2014 INRIA
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup core_util
* @{
*
* @file crash.c
* @brief Crash handling functions implementation for ARM Cortex-based MCUs
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
*/
#include "cpu.h"
#include "lpm.h"
#include "crash.h"
#include <string.h>
#include <stdio.h>
/* "public" variables holding the crash data */
char panic_str[80];
int panic_code;
/* flag preventing "recursive crash printing loop" */
static int crashed = 0;
/* WARNING: this function NEVER returns! */
NORETURN void core_panic(int crash_code, const char *message)
{
/* copy panic datas to "public" global variables */
panic_code = crash_code;
strncpy(panic_str, message, 80);
/* print panic message to console (if possible) */
if (crashed == 0) {
crashed = 1;
puts("******** SYSTEM FAILURE ********\n");
puts(message);
#if DEVELHELP
puts("******** RIOT HALTS HERE ********\n");
#else
puts("******** RIOT WILL REBOOT ********\n");
#endif
puts("\n\n");
}
/* disable watchdog and all possible sources of interrupts */
//TODO
dINT();
#if DEVELHELP
/* enter infinite loop, into deepest possible sleep mode */
while (1) {
lpm_set(LPM_OFF);
}
#else
/* DEVELHELP not set => reboot system */
(void) reboot(RB_AUTOBOOT);
#endif
/* tell the compiler that we won't return from this function
(even if we actually won't even get here...) */
UNREACHABLE();
}

7
cpu/stm32f1/Makefile

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

26
cpu/stm32f1/Makefile.include

@ -0,0 +1,26 @@
# 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-m3_common
# define path to cortex-m common module, which is needed for this CPU
export CORTEXM_COMMON = $(RIOTCPU)/cortex-m3_common/
# define the linker script to use for this CPU
export LINKERSCRIPT = $(RIOTCPU)/$(CPU)/$(CPU_MODEL)_linkerscript.ld
# include CPU specific includes
export INCLUDES += -I$(RIOTCPU)/$(CPU)/include/components
export INCLUDES += -I$(RIOTCPU)/$(CPU)/include
# explicitly tell the linker to link the syscalls and startup code.
# Without this the interrupt vectors will not be linked correctly!
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 $(CORTEXM_COMMON)Makefile.include

30
cpu/stm32f1/cpu.c

@ -0,0 +1,30 @@
/*
* Copyright (C) 2013 INRIA
* 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_stm32f1
* @{
*
* @file
* @brief Implementation of the kernel cpu functions
*
* @author Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* @}
*/
#include "cpu.h"
void cpu_init(void)
{
/* set PendSV priority to the lowest possible priority */
NVIC_SetPriority(PendSV_IRQn, 0xff);
}

76
cpu/stm32f1/hwtimer_arch.c

@ -0,0 +1,76 @@
/*
* 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_stm32f1
* @{
*
* @file
* @brief Implementation of the kernels hwtimer interface
*
* The hardware timer implementation uses the Coretex build-in system timer as backend.
*
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*
* @}
*/
#include "hwtimer_arch.h"
#include "thread.h"
#include "board.h"
#include "periph/timer.h"
#define ENABLE_DEBUG (0)
#include "debug.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();
}

73
cpu/stm32f1/include/cpu-conf.h

@ -0,0 +1,73 @@
/*
* Copyright (C) 2013 INRIA
* 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_stm32f1 STM32F1
* @addtogroup cpu
* @brief CPU specific implementations for the STM32F1
* @{
*
* @file
* @brief Implementation specific CPU configuration options
*
* @author Alaeddine Weslati <alaeddine.weslati@intia.fr>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef CPUCONF_H_
#define CPUCONF_H_
#include "stm32f10x.h"
/**
* @name Kernel configuration
*
* TODO: measure and adjust for the cortex-m3
* @{
*/
#define KERNEL_CONF_STACKSIZE_PRINTF (2500)
#ifndef KERNEL_CONF_STACKSIZE_DEFAULT
#define KERNEL_CONF_STACKSIZE_DEFAULT (2500)
#endif
#define KERNEL_CONF_STACKSIZE_IDLE (512)
/** @} */
/**
* @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
/** @} */
/**
* @name Macro for reading CPU_ID
*/
#define GET_CPU_ID(id) memcpy(&id, (void *)(0x1ffff7e8), CPU_ID_LEN)
/**
* @name Definition of different panic modes
*/
typedef enum {
HARD_FAULT,
WATCHDOG,
BUS_FAULT,
USAGE_FAULT,
DUMMY_HANDLER
} panic_t;
void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t *prescale);
#endif /* __CPU_CONF_H */
/** @} */

32
cpu/stm32f1/include/hwtimer_cpu.h

@ -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. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32f0
* @{
*
* @file hwtimer_cpu.h
* @brief CPU specific hwtimer configuration options
*
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
*/
#ifndef HWTIMER_CPU_H_
#define HWTIMER_CPU_H_
/**
* @name Hardware timer configuration
* @{
*/
#define HWTIMER_MAXTIMERS (4) /**< the CPU implementation supports 3 HW timers */
#define HWTIMER_SPEED (2000U) /**< the HW timer runs with 2KHz */
#define HWTIMER_MAXTICKS (0xFFFF) /**< 16-bit timer */
/** @} */
#endif /* HWTIMER_CPU_H_ */
/** @} */

176
cpu/stm32f1/include/spi.h

@ -0,0 +1,176 @@
/*
* 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 driver_periph
* @brief Low-level SPI peripheral driver
* @{
*
* @file
* @brief Low-level SPI peripheral driver interface definitions
*
* TODO: optimize interface for master AND slave usage, interface is focused on master mode so far...
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __SPI_H
#define __SPI_H
#include "periph_conf.h"
/**
* @brief Definition available SPI devices
*/
typedef enum {
#if SPI_0_EN
SPI_0 = 0, /**< SPI device 0 */
#endif
#if SPI_1_EN
SPI_1, /**< SPI device 1 */
#endif
#if SPI_2_EN
SPI_2, /**< SPI device 2 */
#endif
#if SPI_3_EN
SPI_3, /**< SPI device 3 */
#endif
SPI_UNDEFINED
} spi_t;
/**
* @brief The SPI mode is defined by the four possible combinations of clock polarity and
* clock phase.
*/
typedef enum {
SPI_CONF_FIRST_RISING = 0, /**< first data bit is transacted on the first rising SCK edge */
SPI_CONF_SECOND_RISING, /**< first data bit is transacted on the second rising SCK edge */
SPI_CONF_FIRST_FALLING, /**< first data bit is transacted on the first falling SCK edge */
SPI_CONF_SECOND_FALLING /**< first data bit is transacted on the second falling SCK edge */
} spi_conf_t;
/**
* @brief Initialize the given SPI device to work in master mode
*
* In master mode the SPI device is configured to control the SPI bus. This means the device
* will start and end all communication on the bus and control the CLK line. For transferring
* data on the bus the below defined transfer functions should be used.
*
* @param[in] dev SPI device to initialize
* @param[in] conf Mode of clock phase and clock polarity
* @param[in] speed SPI bus speed in Hz
*
* @return 0 on success
* @return -1 on undefined SPI device
* @return -2 on unavailable speed value
*/
int spi_init_master(spi_t dev, spi_conf_t conf, uint32_t speed);
/**
* @brief Initialize the given SPI device to work in slave mode
*
* In slave mode the SPI device is purely reacting to the bus. Transaction will be started and
* ended by a connected SPI master. When a byte is received, the callback is called in interrupt
* context with this byte as argument. The return byte of the callback is transferred to the
* master in the next transmission cycle. This interface enables easy implementation of a register
* based access paradigm for the SPI slave.
*
* @param[in] dev The SPI device to initialize as SPI slave
* @param[in] conf Mode of clock phase and polarity
* @param[in] cb callback on received byte
*
* @return 0 on success
* @return -1 on undefined SPI device
* @return -2 on unavailable speed value
*/
int spi_init_slave(spi_t dev, spi_conf_t conf, char (*cb)(char));
/**
* @brief Transfer one byte on the given SPI bus
*
* @param[in] dev SPI device to use
* @param[in] out Byte to send out, set NULL if only receiving
* @param[out] in Byte to read, set NULL if only sending
*
* @return Number of bytes that were transfered
* @return -1 on error
*/
int spi_transfer_byte(spi_t dev, char out, char *in);
/**
* @brief Transfer a number bytes on the given SPI bus
*
* @param[in] dev SPI device to use