diff --git a/boards/mulle/Makefile b/boards/mulle/Makefile new file mode 100644 index 0000000000..37891de8e6 --- /dev/null +++ b/boards/mulle/Makefile @@ -0,0 +1,4 @@ +# tell the Makefile.base which module to build +MODULE = $(BOARD)_base + +include $(RIOTBASE)/Makefile.base diff --git a/boards/mulle/Makefile.dep b/boards/mulle/Makefile.dep new file mode 100644 index 0000000000..2d2ca94d84 --- /dev/null +++ b/boards/mulle/Makefile.dep @@ -0,0 +1,9 @@ +ifneq (,$(filter defaulttransceiver,$(USEMODULE))) + USEMODULE += at86rf231 + ifeq (,$(filter netdev_base,$(USEMODULE))) + USEMODULE += transceiver + endif +endif +# The Mulle uses NVRAM to store persistent variables, such as boot count. +#~ USEMODULE += nvram_spi +# Uncomment above when #2353 is merged. diff --git a/boards/mulle/Makefile.features b/boards/mulle/Makefile.features new file mode 100644 index 0000000000..8beee67afb --- /dev/null +++ b/boards/mulle/Makefile.features @@ -0,0 +1,11 @@ +FEATURES_PROVIDED += cpp +FEATURES_PROVIDED += periph_adc +FEATURES_PROVIDED += periph_cpuid +FEATURES_PROVIDED += periph_gpio +FEATURES_PROVIDED += periph_i2c +FEATURES_PROVIDED += periph_random +FEATURES_PROVIDED += periph_rtc +FEATURES_PROVIDED += periph_rtt +FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_uart +FEATURES_PROVIDED += transceiver diff --git a/boards/mulle/Makefile.include b/boards/mulle/Makefile.include new file mode 100644 index 0000000000..b380990fa9 --- /dev/null +++ b/boards/mulle/Makefile.include @@ -0,0 +1,238 @@ +# define the cpu used by the Mulle board +export CPU = k60 + +# Default GDB port +export GDBPORT ?= 3333 + +# MULLE_SERIAL is used to select which specific Mulle board we are compiling for. +# This was called MULLE_BOARD_SERIAL_NUMBER previously, renamed because +# MULLE_BOARD_SERIAL_NUMBER is too long to type. +ifdef MULLE_SERIAL + ifeq "200" "$(word 1, $(sort 200 $(MULLE_SERIAL)))" + # >= 200 + ifneq "220" "$(word 1, $(sort 220 $(MULLE_SERIAL)))" + # < 220 + CPU_MODEL = K60DN256ZVLL10 + # It seems some of the MK60DZ10 devices have problems with JTAG speeds >= around 400 KHz + # when programming, we reduce the speed to 300 KHz with this command. + CPU_OOCD_FLAGS += -c 'adapter_khz 300' + else + # >= 220 + CPU_MODEL = K60DN512VLL10 + endif + endif + CFLAGS += -DMULLE_SERIAL=$(MULLE_SERIAL) +endif + +### CPU part number (must have a specific linker script for each part) +# Note that MK60DN256ZVLL10 (version 1.x) and MK60DN256VLL10 (version 2.x, no Z) +# only differ in some register locations etc, not in the actual memory layout, +# so it is safe to use the same linker script for both version 1.x and version +# 2.x silicon. +# The linker script needs to know the flash and RAM sizes of the device. + +ifeq ($(CPU_MODEL),) + CPU_MODEL = K60DN512VLL10 +endif + +export CPU_MODEL + +# Host OS name +OS := $(shell uname) + +# OpenOCD settings for Mulle board. +# Try to determine which version of the OpenOCD config file we should use. +# Specify PROGRAMMER_VERSION or PROGRAMMER_SERIAL to choose a specific programmer board. +ifeq ($(PROGRAMMER_VERSION),) + ifneq ($(PROGRAMMER_SERIAL),) + # Makefile-way of comparing numbers, using lexicographical sorting since we don't have any arithmetic comparisons. + # Programmers with serial 100 -- 148 are version 0.60 + # Programmers with serial 301 -- 330 are version 0.70 + ifeq "100" "$(word 1, $(sort 100 $(PROGRAMMER_SERIAL)))" + # >= 100 + ifneq "149" "$(word 1, $(sort 149 $(PROGRAMMER_SERIAL)))" + # < 149 + PROGRAMMER_VERSION = 0.60 + else + # >= 149 + PROGRAMMER_VERSION = 0.70 + endif + endif + endif + # Default to version 0.60 programmer for now. + PROGRAMMER_VERSION ?= 0.60 +endif + +export OPENOCD_CONFIG = $(RIOTBOARD)/$(BOARD)/dist/openocd/mulle-programmer-$(PROGRAMMER_VERSION).conf + +# Add serial matching command +ifneq ($(PROGRAMMER_SERIAL),) + OPENOCD_EXTRA_INIT += -c 'ftdi_serial $(PROGRAMMER_SERIAL)' +endif + +OPENOCD_EXTRA_INIT += $(CPU_OOCD_FLAGS) + +ifeq ($(PORT),) + # try to find tty name by serial number, only works on Linux currently. + ifeq ($(OS),Linux) + ifneq ($(PROGRAMMER_SERIAL),) + PORT := $(shell $(RIOTBASE)/dist/tools/usb-serial/find-tty.sh '^$(PROGRAMMER_SERIAL)$$') + else + # find-tty.sh will return the first USB tty if no serial is given. + PORT := $(shell $(RIOTBASE)/dist/tools/usb-serial/find-tty.sh) + endif + else ifeq ($(OS),Darwin) + PORT := $(shell ls -1 /dev/tty.usbserial* | head -n 1) + endif +endif + +# TODO: add support for windows as host platform +ifeq ($(PORT),) + # None of the above methods worked, set some sane default value for PORT. + $(info CAUTION: No terminal port for your host system found!) + PORT := /dev/ttyUSB0 +endif +export PORT + +# Default optimization level, possible to override from command line. +OPTIMIZATION ?= -Os + +# Default debug level +DEBUG_CFLAGS ?= -g3 -ggdb + +# Target triple for the build. Use arm-none-eabi if you are unsure. +export TARGET_TRIPLE ?= arm-none-eabi + +# Toolchain prefix, defaults to target triple followed by a dash, you will most likely not need to touch this. +export PREFIX ?= $(if $(TARGET_TRIPLE),$(TARGET_TRIPLE)-) +export GDBPREFIX ?= $(PREFIX) + +# define tools used for building the project +export CC = $(PREFIX)gcc +export CXX = $(PREFIX)g++ +export AR = $(PREFIX)ar +export AS = $(PREFIX)as +export LINK = $(PREFIX)gcc +export SIZE = $(PREFIX)size +export OBJCOPY = $(PREFIX)objcopy +export OPENOCD ?= openocd +export GDB ?= $(GDBPREFIX)gdb +export DBG = $(GDB) +export TERMPROG ?= $(RIOTBASE)/dist/tools/pyterm/pyterm +export FLASHER = $(RIOTBASE)/dist/tools/openocd/openocd.sh +export DEBUGGER = $(RIOTBASE)/dist/tools/openocd/openocd.sh +export DEBUGSERVER = $(RIOTBASE)/dist/tools/openocd/openocd.sh +export RESET = $(RIOTBASE)/dist/tools/openocd/openocd.sh +export TERMFLAGS += -p "$(PORT)" +export FFLAGS = flash $(OPENOCD_EXTRA_INIT) +export DEBUGGER_FLAGS = debug $(OPENOCD_EXTRA_INIT) +export DEBUGSERVER_FLAGS = debug-server $(OPENOCD_EXTRA_INIT) +export RESET_FLAGS = reset $(OPENOCD_EXTRA_INIT) + + +# define build specific options +CPU_USAGE = -mcpu=cortex-m4 +FPU_USAGE = -mfloat-abi=soft -msoft-float +export CFLAGS += \ + $(DEBUG_CFLAGS) \ + -std=gnu99 \ + $(OPTIMIZATION) \ + -Wall -Wstrict-prototypes -Werror=implicit-function-declaration \ + $(CPU_USAGE) \ + $(FPU_USAGE) \ + -mlittle-endian \ + -mthumb \ + -fno-common \ + -fshort-enums \ + -ffunction-sections \ + -fdata-sections \ + -fno-builtin \ + -fno-strict-aliasing \ + -fsigned-char \ + # +export CXXFLAGS += \ + -ffunction-sections \ + -fdata-sections \ + -fno-builtin \ + # +export ASFLAGS += \ + $(DEBUG_CFLAGS) \ + $(CPU_USAGE) \ + $(FPU_USAGE) \ + -mlittle-endian \ + # +export LINKFLAGS += \ + $(DEBUG_CFLAGS) \ + -std=gnu99 \ + $(CPU_USAGE) \ + $(FPU_USAGE) \ + -mlittle-endian \ + -static \ + -mthumb \ + -nostartfiles \ + -Wl,--fatal-warnings \ + # +export LINKFLAGS += -T$(LINKERSCRIPT) +export OFLAGS ?= -O ihex + +ifdef BUILD_WITH_CLANG +ifneq ($(BUILD_WITH_CLANG),0) +export CFLAGS += -target $(TARGET_TRIPLE) +export CXXFLAGS += -target $(TARGET_TRIPLE) +export LINKFLAGS += -target $(TARGET_TRIPLE) +export CC = clang +export CXX = clang++ +export LINK = clang +export LLVMPREFIX ?= llvm- +export AS = $(LLVMPREFIX)as +export AR = $(LLVMPREFIX)ar +export NM = $(LLVMPREFIX)nm +# There is no LLVM linker yet, use binutils. +#export LINKER = $(LLVMPREFIX)ld +# objcopy does not have a clear substitute in LLVM +#export OBJCOPY = $(LLVMPREFIX)objcopy +export OBJDUMP = $(LLVMPREFIX)objdump +# LLVM lacks a binutils strip tool as well... +#export STRIP = $(LLVMPREFIX)strip +export SIZE = $(LLVMPREFIX)size + +# Since Clang is not installed as a separate instance for each crossdev target +# we need to tell it where to look for platform specific includes (Newlib +# headers instead of Linux/Glibc headers.) +# On GCC this is done when building the cross compiler toolchain so we do not +# actually need to specify the include paths for system includes. +# Ubuntu gcc-arm-embedded toolchain (https://launchpad.net/gcc-arm-embedded) +# places newlib headers in several places, but the primary source seem to be +# /etc/alternatives/gcc-arm-none-eabi-include +# Gentoo crossdev places newlib headers in /usr/arm-none-eabi/include +# Ubuntu also seem to put a copy of the newlib headers in the same place as +# Gentoo crossdev, but we prefer to look at /etc/alternatives first. +# On OSX, newlib includes are possibly located in +# /usr/local/opt/arm-none-eabi*/arm-none-eabi/include +NEWLIB_INCLUDE_PATTERNS ?= \ + /etc/alternatives/gcc-$(TARGET_TRIPLE)-include \ + /usr/$(TARGET_TRIPLE)/include \ + /usr/local/opt/$(TARGET_TRIPLE)*/$(TARGET_TRIPLE)/include \ + # +# Use the wildcard Makefile function to search for existing directories matching +# the patterns above. We use the -isystem gcc/clang argument to add the include +# directories as system include directories. +NEWLIB_INCLUDES ?= \ + $(foreach dir, \ + $(foreach pat, $(NEWLIB_INCLUDE_PATTERNS), $(wildcard $(pat))), \ + -isystem $(dir)) + +endif +endif + +export INCLUDES += $(NEWLIB_INCLUDES) + +# use newlib nano-specs if available +ifeq ($(shell $(LINK) -specs=nano.specs -E - 2>/dev/null >/dev/null + * + * @} + */ + +#include /* for NULL */ +#include +#include "board.h" +#include "cpu.h" +#include "mcg.h" +#include "periph/gpio.h" +#include "periph/uart.h" +#include "periph/rtc.h" +#include "devicemap.h" + +/** + * @brief Initialize the boards on-board LEDs + * + * The LEDs are initialized here in order to be able to use them in the early + * boot for diagnostics. + * + */ +static inline void leds_init(void); + +/** @brief Initialize the GPIO pins controlling the power switches. */ +static inline void power_pins_init(void); + +/** + * @brief Set clock prescalers to safe values + * + * This should be done before switching to FLL/PLL as clock source to ensure + * that all clocks remain within the specified limits. + */ +static inline void set_safe_clock_dividers(void); + +/** @brief Set the FLL source clock to RTC32k */ +static inline void set_fll_source(void); + + +void board_init(void) +{ + /* initialize the boards LEDs, this is done first for debugging purposes */ + leds_init(); + + LED_RED_ON; + + /* Initialize RTC oscillator as early as possible since we are using it as a + * base clock for the FLL. + * It takes a while to stabilize the oscillator, therefore we do this as + * soon as possible during boot in order to let it stabilize while other + * stuff is initializing. */ + /* If the clock is not stable then the UART will have the wrong baud rate + * for debug prints as well */ + rtc_init(); + + /* Set up clocks */ + set_safe_clock_dividers(); + + set_fll_source(); + + kinetis_mcg_set_mode(KINETIS_MCG_FEE); + + /* At this point we need to wait for 1 ms until the clock is stable. + * Since the clock is not yet stable we can only guess how long we must + * wait. I have tried to make this as short as possible but still being able + * to read the initialization messages written on the UART. + * (If the clock is not stable all UART output is garbled until it has + * stabilized) */ + for (int i = 0; i < 100000; ++i) { + asm volatile("nop\n"); + } + + /* Update SystemCoreClock global var */ + SystemCoreClockUpdate(); + + /* initialize the CPU */ + cpu_init(); + + LED_YELLOW_ON; + + devicemap_init(); + + LED_GREEN_ON; + + /* Initialize power control pins */ + power_pins_init(); + + /* Turn on Vperiph for peripherals */ + gpio_set(MULLE_POWER_VPERIPH); + + /* Turn on AVDD for reading voltages */ + gpio_set(MULLE_POWER_AVDD); +} + +static inline void leds_init(void) +{ + /* The pin configuration can be found in board.h and periph_conf.h */ + gpio_init_out(LED_RED_GPIO, GPIO_NOPULL); + gpio_init_out(LED_YELLOW_GPIO, GPIO_NOPULL); + gpio_init_out(LED_GREEN_GPIO, GPIO_NOPULL); +} + +static inline void power_pins_init(void) +{ + gpio_init_out(MULLE_POWER_AVDD, GPIO_NOPULL); + gpio_init_out(MULLE_POWER_VPERIPH, GPIO_NOPULL); + gpio_init_out(MULLE_POWER_VSEC, GPIO_NOPULL); + gpio_clear(MULLE_POWER_AVDD); + gpio_clear(MULLE_POWER_VPERIPH); + gpio_clear(MULLE_POWER_VSEC); +} + +static inline void set_safe_clock_dividers(void) +{ + /* + * We want to achieve the following clocks: + * Core/system: <100MHz + * Bus: <50MHz + * FlexBus: <50MHz + * Flash: <25MHz + * + * using dividers 1-2-2-4 will obey the above limits when using a 96MHz FLL source. + */ + SIM->CLKDIV1 = ( + SIM_CLKDIV1_OUTDIV1(CONFIG_CLOCK_K60_SYS_DIV) | /* Core/System clock divider */ + SIM_CLKDIV1_OUTDIV2(CONFIG_CLOCK_K60_BUS_DIV) | /* Bus clock divider */ + SIM_CLKDIV1_OUTDIV3(CONFIG_CLOCK_K60_FB_DIV) | /* FlexBus divider, not used in Mulle */ + SIM_CLKDIV1_OUTDIV4(CONFIG_CLOCK_K60_FLASH_DIV)); /* Flash clock divider */ + +} + +static inline void set_fll_source(void) +{ + /* Select FLL as source (as opposed to PLL) */ + SIM->SOPT2 &= ~(SIM_SOPT2_PLLFLLSEL_MASK); + /* Use external 32kHz RTC clock as source for OSC32K */ + /* This is also done by hwtimer_arch, but we need it sooner than + * hwtimer_init. */ +#if K60_CPU_REV == 1 + SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK; +#elif K60_CPU_REV == 2 + SIM->SOPT1 = (SIM->SOPT1 & ~(SIM_SOPT1_OSC32KSEL_MASK)) | SIM_SOPT1_OSC32KSEL(2); +#else +#error Unknown K60 CPU revision +#endif + + /* Select RTC 32kHz clock as reference clock for the FLL */ +#if K60_CPU_REV == 1 + /* Rev 1 parts */ + SIM->SOPT2 |= SIM_SOPT2_MCGCLKSEL_MASK; +#elif K60_CPU_REV == 2 + /* Rev 2 parts */ + MCG->C7 = (MCG_C7_OSCSEL_MASK); +#else +#error Unknown K60 CPU revision +#endif +} diff --git a/boards/mulle/board_config.c b/boards/mulle/board_config.c new file mode 100644 index 0000000000..45cea4afbf --- /dev/null +++ b/boards/mulle/board_config.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 Eistec AB + * + * 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_mulle + * @{ + */ + +/** + * @file + * @brief Mulle config module implementation + * + * @author Joakim Gebart + * + * @note Waiting for PR #2353 (NVRAM API) before implementing this. + */ + +#include +#include +#include "config.h" + +void config_load(void) +{ + /* TODO: Implement */ +} + +uint8_t config_save(void) +{ + /* TODO: Implement */ + return 0; +} diff --git a/boards/mulle/devicemap.c b/boards/mulle/devicemap.c new file mode 100644 index 0000000000..bc9439bf2d --- /dev/null +++ b/boards/mulle/devicemap.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2014-2015 Eistec AB + * + * 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_mulle + * @{ + * + * @file + * @brief Device I/O mappings for the Mulle platform. + * + * @author Joakim Gebart + * + * @} + */ + +#include /* for NULL */ +#include "devopttab.h" +#include "devicemap.h" +#include "devio-uart.h" +#include "devio-null.h" +#include "cpu.h" +#include "periph_conf.h" +#include "periph/uart.h" + +#if UART_0_EN +static const devoptab_t dotab_uart0 = { + "UART0", /* name */ + 1, /* isatty */ + S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, /* Character device, 0777 perms (crwxrwxrwx) */ + devnull_open_r, + devnull_close_r, + uart0_write_r, + NULL, /* Not yet implemented */ + NULL, /* No seeking on UART */ + NULL, /* No fstat on UART */ +}; +#endif + +#if UART_1_EN +static const devoptab_t dotab_uart1 = { + "UART1", /* name */ + 1, /* isatty */ + S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, /* Character device, 0777 perms (crwxrwxrwx) */ + devnull_open_r, + devnull_close_r, + uart1_write_r, + NULL, /* Not yet implemented */ + NULL, /* No seeking on UART */ + NULL, /* No fstat on UART */ +}; +#endif + +#if UART_2_EN +static const devoptab_t dotab_uart2 = { + "UART2", /* name */ + 1, /* isatty */ + S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, /* Character device, 0777 perms (crwxrwxrwx) */ + devnull_open_r, + devnull_close_r, + uart2_write_r, + NULL, /* Not yet implemented */ + NULL, /* No seeking on UART */ + NULL, /* No fstat on UART */ +}; +#endif + +#if UART_3_EN +static const devoptab_t dotab_uart3 = { + "UART3", /* name */ + 1, /* isatty */ + S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, /* Character device, 0777 perms (crwxrwxrwx) */ + devnull_open_r, + devnull_close_r, + uart3_write_r, + NULL, /* Not yet implemented */ + NULL, /* No seeking on UART */ + NULL, /* No fstat on UART */ +}; +#endif + +#if UART_4_EN +static const devoptab_t dotab_uart4 = { + "UART4", /* name */ + 1, /* isatty */ + S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, /* Character device, 0777 perms (crwxrwxrwx) */ + devnull_open_r, + devnull_close_r, + uart4_write_r, + NULL, /* Not yet implemented */ + NULL, /* No seeking on UART */ + NULL, /* No fstat on UART */ +}; +#endif + +static const devoptab_t dotab_stdin = { + "stdin", /* name */ + 1, /* isatty */ + S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, /* Character device, 0444 perms (cr--r--r--) */ + devnull_open_r, + devnull_close_r, + NULL, + NULL, /* Not yet implemented */ + NULL, /* No seeking on UART */ + NULL, /* No fstat on UART */ +}; + +static const devoptab_t dotab_stdout = { + "stdout", /* name */ + 1, /* isatty */ + S_IFCHR | S_IWUSR | S_IWGRP | S_IWOTH, /* Character device, 0222 perms (c-w--w--w-) */ + devnull_open_r, + devnull_close_r, +#if UART_0_EN + uart0_write_r, +#else + NULL, /* No stdout */ +#endif + NULL, /* Not yet implemented */ + NULL, /* No seeking on UART */ + NULL, /* No fstat on UART */ +}; + + + +/* This table maps the standard streams to device operations table entries. */ +const devoptab_t *devoptab_list[MAX_OPEN_DEVICES] = { 0 }; + +static const devoptab_name_t devoptab_names[] = { +#if UART_0_EN + {"UART0", &dotab_uart0}, +#endif +#if UART_1_EN + {"UART1", &dotab_uart1}, +#endif +#if UART_2_EN + {"UART2", &dotab_uart2}, +#endif +#if UART_3_EN + {"UART3", &dotab_uart3}, +#endif +#if UART_4_EN + {"UART4", &dotab_uart4}, +#endif +}; + +const devoptab_name_list_t devoptab_name_list = { + sizeof(devoptab_names) / sizeof(devoptab_names[0]), /* len */ + &devoptab_names[0], /* data */ +}; + +void devicemap_init(void) +{ + /* Set up stdin, stdout and stderr */ + devoptab_list[STDIN_FILENO] = &dotab_stdin; + devoptab_list[STDOUT_FILENO] = &dotab_stdout; + devoptab_list[STDERR_FILENO] = &dotab_stdout; +} diff --git a/boards/mulle/dist/gdb.conf b/boards/mulle/dist/gdb.conf new file mode 100644 index 0000000000..101da5ec6d --- /dev/null +++ b/boards/mulle/dist/gdb.conf @@ -0,0 +1,4 @@ +set architecture arm +set arm force-mode thumb +set remote hardware-breakpoint-limit 6 +set remote hardware-watchpoint-limit 4 diff --git a/boards/mulle/dist/openocd/README.md b/boards/mulle/dist/openocd/README.md new file mode 100644 index 0000000000..b0c5ef277f --- /dev/null +++ b/boards/mulle/dist/openocd/README.md @@ -0,0 +1,9 @@ +Mulle OpenOCD configuration files +================================= + +The configuration file in this directory has been tested with OpenOCD v0.7.0. +The interface used is ftdi, OpenOCD must be built with --enable-ftdi + +To start the OpenOCD GDB server: + + openocd -f mulle.cfg diff --git a/boards/mulle/dist/openocd/mulle-programmer-0.60.conf b/boards/mulle/dist/openocd/mulle-programmer-0.60.conf new file mode 100644 index 0000000000..dc3324f9f4 --- /dev/null +++ b/boards/mulle/dist/openocd/mulle-programmer-0.60.conf @@ -0,0 +1,53 @@ +# +# Mulle programming board. +# +# The Mulle programming board uses a FTDI FT2232H chip for USB UART and JTAG +# combined functionality. +# + +# Reduce this if you are having problems with losing connection to the Mulle +adapter_khz 1000 + +# JTAG interface configuration + +interface ftdi +ftdi_device_desc "Mulle Programmer v0.60" +ftdi_vid_pid 0x0403 0x6010 + +ftdi_channel 1 +ftdi_layout_init 0x0008 0x005b + +# These are the pins that are used for SRST and TRST. Note that the Mulle +# programming board inverts the reset signal between the FTDI chip and the MCU, +# so we need to use -ndata here to tell OpenOCD that the signals are active HIGH. +ftdi_layout_signal nTRST -ndata 0x0010 +ftdi_layout_signal nSRST -ndata 0x0040 + +# In the eyes of OpenOCD, the reset signal is push-pull, because of the hardware +# design however, it is actually open drain. +# The trst pin can only be used if the MCU has been configured by setting the +# correct pin multiplexing function on the TRST pin (PTA5). +# If you have configured the TRST pin correctly you can change srst_only to +# trst_and_srst +reset_config srst_only srst_push_pull srst_gates_jtag + +# MCU +gdb_memory_map enable +gdb_flash_program enable + +source [find target/k60.cfg] + +# +# Bank definition for the 'program flash' (instructions and/or data) +# +flash bank $_CHIPNAME.pflash.0 kinetis 0x00000000 0x20000 0 4 $_TARGETNAME +flash bank $_CHIPNAME.pflash.1 kinetis 0x00020000 0x20000 0 4 $_TARGETNAME + +# The following section makes new gdb connections cause the MCU to do a system +# reset, in order to be in a known state. +# Comment this out in order to be able to debug an already started program. +$_TARGETNAME configure -event gdb-attach { + echo "Resetting because of gdb-attach event..." + # To make flash probe and gdb load to flash work we need a reset init. + reset init +} diff --git a/boards/mulle/dist/openocd/mulle-programmer-0.70.conf b/boards/mulle/dist/openocd/mulle-programmer-0.70.conf new file mode 100644 index 0000000000..531a8b0d60 --- /dev/null +++ b/boards/mulle/dist/openocd/mulle-programmer-0.70.conf @@ -0,0 +1,52 @@ +# +# Mulle programming board. +# +# The Mulle programming board uses a FTDI FT2232H chip for USB UART and JTAG +# combined functionality. +# + +# Reduce this if you are having problems with losing connection to the Mulle +adapter_khz 1000 + +# JTAG interface configuration + +interface ftdi +ftdi_device_desc "Mulle Programmer v0.70" +ftdi_vid_pid 0x0403 0x6010 + +ftdi_channel 1 +ftdi_layout_init 0x0008 0x005b + +# These are the pins that are used for SRST and TRST. Active LOW on programmer +# boards v0.70 and up (used to be active HIGH) +ftdi_layout_signal nTRST -data 0x0010 +ftdi_layout_signal nSRST -data 0x0040 + +# In the eyes of OpenOCD, the reset signal is push-pull, because of the hardware +# design however, it is actually open drain. +# The trst pin can only be used if the MCU has been configured by setting the +# correct pin multiplexing function on the TRST pin (PTA5). +# If you have configured the TRST pin correctly you can change srst_only to +# trst_and_srst +reset_config srst_only srst_push_pull srst_gates_jtag + +# MCU +gdb_memory_map enable +gdb_flash_program enable + +source [find target/k60.cfg] + +# +# Bank definition for the 'program flash' (instructions and/or data) +# +flash bank $_CHIPNAME.pflash.0 kinetis 0x00000000 0x40000 0 4 $_TARGETNAME +flash bank $_CHIPNAME.pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME + +# The following section makes new gdb connections cause the MCU to do a system +# reset, in order to be in a known state. +# Comment this out in order to be able to debug an already started program. +$_TARGETNAME configure -event gdb-attach { + echo "Resetting because of gdb-attach event..." + # To make flash probe and gdb load to flash work we need a reset init. + reset init +} diff --git a/boards/mulle/include/board.h b/boards/mulle/include/board.h new file mode 100644 index 0000000000..ad410a4ffe --- /dev/null +++ b/boards/mulle/include/board.h @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2014 Eistec AB + * + * 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_mulle Eistec Mulle + * @ingroup boards + * @brief Board specific files for Eistec Mulle IoT boards + * @{ + * + * @file + * @brief Board specific definitions for the Eistec Mulle IoT board + * + * @author Joakim Gebart + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "cpu.h" +#include "periph_conf.h" + +/* Use the on board RTC 32kHz clock for LPTMR clocking. */ +#undef LPTIMER_CLKSRC +/** @brief Clock source for the LPTMR module */ +#define LPTIMER_CLKSRC LPTIMER_CLKSRC_ERCLK32K + +/** Disable hardware watchdog, for debugging purposes, don't use this on production builds. */ +#define DISABLE_WDOG 1 + +/** + * @name Assign the first hardware timer. + * This timer will be used to implement an absolute reference for hwtimer_now() et al. + */ +#define HW_TIMER TIMER_0 + +/** + * @name Number of subsequent channels of the PIT to assign to the RIOT hardware + * timer library, starting after the HW_TIMER above. + */ +#define HW_TIMERS_COUNT 1 + +/** + * @name Define UART device and baudrate for stdio + * @{ + */ +#define STDIO UART_0 +#define STDIO_BAUDRATE (115200U) +#define STDIO_RX_BUFSIZE (64U) +/** @} */ + +/** + * @name LEDs configuration + * @{ + */ + +#define LED_RED_GPIO GPIO_0 +#define LED_RED_PORT GPIO_0_DEV +#define LED_RED_PIN GPIO_0_PIN +#define LED_YELLOW_GPIO GPIO_1 +#define LED_YELLOW_PORT GPIO_1_DEV +#define LED_YELLOW_PIN GPIO_1_PIN +#define LED_GREEN_GPIO GPIO_2 +#define LED_GREEN_PORT GPIO_2_DEV +#define LED_GREEN_PIN GPIO_2_PIN + +/** @} */ + +/** + * @name Macros for controlling the on-board LEDs. + * @{ + */ +#define LED_RED_ON (BITBAND_REG(LED_RED_PORT->PSOR, LED_RED_PIN) = 1) +#define LED_RED_OFF (BITBAND_REG(LED_RED_PORT->PCOR, LED_RED_PIN) = 1) +#define LED_RED_TOGGLE (BITBAND_REG(LED_RED_PORT->PTOR, LED_RED_PIN) = 1) +#define LED_YELLOW_ON (BITBAND_REG(LED_YELLOW_PORT->PSOR, LED_YELLOW_PIN) = 1) +#define LED_YELLOW_OFF (BITBAND_REG(LED_YELLOW_PORT->PCOR, LED_YELLOW_PIN) = 1) +#define LED_YELLOW_TOGGLE (BITBAND_REG(LED_YELLOW_PORT->PTOR, LED_YELLOW_PIN) = 1) +#define LED_GREEN_ON (BITBAND_REG(LED_GREEN_PORT->PSOR, LED_GREEN_PIN) = 1) +#define LED_GREEN_OFF (BITBAND_REG(LED_GREEN_PORT->PCOR, LED_GREEN_PIN) = 1) +#define LED_GREEN_TOGGLE (BITBAND_REG(LED_GREEN_PORT->PTOR, LED_GREEN_PIN) = 1) +/** @} */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize board specific hardware, including clock, LEDs and std-IO + */ +void board_init(void); + +/** + * Define the type for the radio packet length for the transceiver + */ +typedef uint8_t radio_packet_length_t; + +#ifdef __cplusplus +} +#endif + +/** + * @name Define the interface to the AT86RF231 radio + * @{ + */ +#define AT86RF231_SPI SPI_0 +#define AT86RF231_CS GPIO_14 +#define AT86RF231_INT GPIO_12 +/** @todo work around missing RESET pin on Mulle v0.6x */ +#define AT86RF231_RESET GPIO_5 +#define AT86RF231_SLEEP GPIO_13 +/** @} */ + +/** + * @name LIS3DH configuration + * @{ + */ + +#define LIS3DH_INT1 GPIO_3 +#define LIS3DH_INT2 GPIO_4 +#define LIS3DH_CS GPIO_15 +#define LIS3DH_SPI SPI_2 + +/** @} */ + +/** + * @name Mulle power control configuration + */ +/** @{ */ +#define MULLE_POWER_AVDD GPIO_6 /**< AVDD enable pin */ +#define MULLE_POWER_VPERIPH GPIO_7 /**< VPERIPH enable pin */ +#define MULLE_POWER_VSEC GPIO_5 /**< VSEC enable pin */ +/** @} */ + +/** + * @name K60 clock dividers + */ +/** @{ */ +/** + * System clock divider setting, the actual hardware register value, see reference manual for details. + */ +#define CONFIG_CLOCK_K60_SYS_DIV 0x00 + +/** + * Bus clock divider setting, the actual hardware register value, see reference manual for details + */ +#define CONFIG_CLOCK_K60_BUS_DIV 0x01 + +/** + * Flexbus clock divider setting, the actual hardware register value, see reference manual for details + */ +#define CONFIG_CLOCK_K60_FB_DIV 0x01 + +/** + * Flash clock divider setting, the actual hardware register value, see reference manual for details + */ +#define CONFIG_CLOCK_K60_FLASH_DIV 0x03 + +/** @} */ + +#endif /* BOARD_H_ */ +/** @} */ diff --git a/boards/mulle/include/devicemap.h b/boards/mulle/include/devicemap.h new file mode 100644 index 0000000000..9a6b3d8880 --- /dev/null +++ b/boards/mulle/include/devicemap.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014-2015 Eistec AB + * + * 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. + */ + +#ifndef DEVICEMAP_H_ +#define DEVICEMAP_H_ + +/** + * @ingroup board_mulle + * @{ + * + * @file + * @brief Device I/O mappings for the Mulle platform. + * + * @author Joakim Gebart + * + */ + +#include "devopttab.h" + +/** Maximum number of file descriptors allocated to hardware devices. All fd's + * above this number will be remapped to CFS accesses. */ +#define MAX_OPEN_DEVICES 16 /* Arbitrarily chosen */ + +/** Number of IO devices in this platform implementation */ +#define NUM_IO_DEVICES 16 /* Arbitrarily chosen */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This table maps the standard streams to device operations table entries. */ +extern const devoptab_t *devoptab_list[MAX_OPEN_DEVICES]; + +/* This table maps filenames to devices */ +/** @brief Mappings between file name and device handle */ +typedef struct { + const char *name; /**< Device file name */ + const devoptab_t *devoptab; /**< Pointer to device operations table entry */ +} devoptab_name_t; + +/** @brief Table of device files */ +typedef struct { + unsigned int len; /**< number of entries */ + const devoptab_name_t *data; /**< Pointer to first table entry */ +} devoptab_name_list_t; + +extern const devoptab_name_list_t devoptab_name_list; + +/** @brief Initialize the device map */ +void devicemap_init(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* !defined(DEVICEMAP_H_) */ diff --git a/boards/mulle/include/periph_conf.h b/boards/mulle/include/periph_conf.h new file mode 100644 index 0000000000..5aac250e1b --- /dev/null +++ b/boards/mulle/include/periph_conf.h @@ -0,0 +1,765 @@ +/* + * Copyright (C) 2015 Eistec AB + * + * 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_mulle + * @{ + * + * @file + * @name Peripheral MCU configuration for the Eistec Mulle + * + * @author Joakim Gebart + */ + +#ifndef MULLE_PERIPH_CONF_H +#define MULLE_PERIPH_CONF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @name Clock system configuration + * @{ + */ +#define KINETIS_CPU_USE_MCG 1 + +#define KINETIS_MCG_USE_ERC 1 +#define KINETIS_MCG_USE_PLL 0 +#define KINETIS_MCG_DCO_RANGE (96000000U) +#define KINETIS_MCG_ERC_OSCILLATOR 0 +#define KINETIS_MCG_ERC_FRDIV 0 +#define KINETIS_MCG_ERC_RANGE 0 +#define KINETIS_MCG_ERC_FREQ (32768U) + +/* Base clocks, used by SystemCoreClockUpdate */ +/** Value of the external crystal or oscillator clock frequency in Hz */ +#define CPU_XTAL_CLK_HZ 8000000u +/** Value of the external 32k crystal or oscillator clock frequency in Hz */ +#define CPU_XTAL32k_CLK_HZ 32768u +/** Value of the slow internal oscillator clock frequency in Hz */ +#define CPU_INT_SLOW_CLK_HZ 32768u +/** Value of the fast internal oscillator clock frequency in Hz */ +#define CPU_INT_FAST_CLK_HZ 4000000u +/** Default System clock value */ +#define DEFAULT_SYSTEM_CLOCK (CPU_XTAL32k_CLK_HZ * 2929u) + +/** @todo Investigate the side effects of making F_CPU run-time variable */ +#define F_CPU DEFAULT_SYSTEM_CLOCK + +/** @} */ + +/** + * @name Timer configuration + * @{ + */ +#define TIMER_NUMOF (1U) +#define TIMER_0_EN 1 +#define TIMER_1_EN 0 +#define TIMER_IRQ_PRIO 1 +#define TIMER_DEV PIT +#define TIMER_MAX_VALUE (0xffffffff) +#define TIMER_CLOCK SystemBusClock +#define TIMER_CLKEN() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_PIT_SHIFT) = 1) + +/* Timer 0 configuration */ +#define TIMER_0_PRESCALER_CH 0 +#define TIMER_0_COUNTER_CH 1 +#define TIMER_0_ISR isr_pit1 +#define TIMER_0_IRQ_CHAN PIT1_IRQn + +/* Timer 1 configuration */ +#define TIMER_1_PRESCALER_CH 2 +#define TIMER_1_COUNTER_CH 3 +#define TIMER_1_ISR isr_pit3 +#define TIMER_1_IRQ_CHAN PIT3_IRQn + +/** @} */ + + +/** + * @name UART configuration + * @{ + */ +#define UART_NUMOF (2U) +#define UART_0_EN 1 +#define UART_1_EN 1 +#define UART_2_EN 0 +#define UART_3_EN 0 +#define UART_4_EN 0 +#define UART_IRQ_PRIO 1 + +/* UART 0 device configuration */ +#define UART_0_DEV UART1 +#define UART_0_CLKEN() (BITBAND_REG(SIM->SCGC4, SIM_SCGC4_UART1_SHIFT) = 1) +#define UART_0_CLKDIS() (BITBAND_REG(SIM->SCGC4, SIM_SCGC4_UART1_SHIFT) = 0) +#define UART_0_CLK (SystemSysClock) +#define UART_0_IRQ_CHAN UART1_RX_TX_IRQn +#define UART_0_ISR isr_uart1_status +/* UART 0 pin configuration */ +#define UART_0_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define UART_0_PORT PORTC +#define UART_0_TX_PIN 4 +#define UART_0_RX_PIN 3 +/* Function number in pin multiplex, see K60 Sub-Family Reference Manual, + * section 10.3.1 K60 Signal Multiplexing and Pin Assignments */ +#define UART_0_AF 3 +#define UART_0_TX_PCR_MUX 3 +#define UART_0_RX_PCR_MUX 3 + +/* UART 1 device configuration */ +#define UART_1_DEV UART0 +#define UART_1_CLKEN() (BITBAND_REG(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT) = 1) +#define UART_1_CLKDIS() (BITBAND_REG(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT) = 0) +#define UART_1_CLK (SystemSysClock) +#define UART_1_IRQ_CHAN UART0_RX_TX_IRQn +#define UART_1_ISR isr_uart0_status +/* UART 1 pin configuration */ +#define UART_1_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTA_SHIFT) = 1) +#define UART_1_PORT PORTA +#define UART_1_TX_PIN 14 +#define UART_1_RX_PIN 15 +/* Function number in pin multiplex, see K60 Sub-Family Reference Manual, + * section 10.3.1 K60 Signal Multiplexing and Pin Assignments */ +#define UART_1_AF 3 +#define UART_1_TX_PCR_MUX 3 +#define UART_1_RX_PCR_MUX 3 + +/** @} */ + + +/** + * @name ADC configuration + * @{ + */ +#define ADC_NUMOF (2U) +#define ADC_0_EN 1 +#define ADC_1_EN 1 +#define ADC_MAX_CHANNELS 6 + +/* ADC 0 configuration */ +#define ADC_0_DEV ADC0 +#define ADC_0_CHANNELS 4 +#define ADC_0_CLKEN() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_ADC0_SHIFT) = 1) +#define ADC_0_CLKDIS() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_ADC0_SHIFT) = 0) +#define ADC_0_PORT_CLKEN() /* no PORT pins configured */ +#define ADC_0_MODULE_CLOCK SystemBusClock +/* ADC 0 channel 0 pin config */ +#define ADC_0_CH0 26 /* Temp sensor channel */ +#define ADC_0_CH0_PORT 0 /* this channel is not part of the pin mux on this CPU */ +#define ADC_0_CH0_PIN 0 +#define ADC_0_CH0_PIN_AF 0 +/* ADC 0 channel 1 pin config */ +#define ADC_0_CH1 27 /* Band gap channel */ +#define ADC_0_CH1_PORT 0 /* this channel is not part of the pin mux on this CPU */ +#define ADC_0_CH1_PIN 0 +#define ADC_0_CH1_PIN_AF 0 +/* ADC 0 channel 2 pin config */ +#define ADC_0_CH2 29 /* V_REFSH */ +#define ADC_0_CH2_PORT 0 /* this channel is not part of the pin mux on this CPU */ +#define ADC_0_CH2_PIN 0 +#define ADC_0_CH2_PIN_AF 0 +/* ADC 0 channel 3 pin config */ +#define ADC_0_CH3 30 /* V_REFSL */ +#define ADC_0_CH3_PORT 0 /* this channel is not part of the pin mux on this CPU */ +#define ADC_0_CH3_PIN 0 +#define ADC_0_CH3_PIN_AF 0 +/* ADC 0 channel 4 pin config */ +#define ADC_0_CH4 4 +#define ADC_0_CH4_PORT 0 +#define ADC_0_CH4_PIN 0 +#define ADC_0_CH4_PIN_AF 0 +/* ADC 0 channel 5 pin config */ +#define ADC_0_CH5 5 +#define ADC_0_CH5_PORT 0 +#define ADC_0_CH5_PIN 0 +#define ADC_0_CH5_PIN_AF 0 + +/* ADC 1 configuration */ +#define ADC_1_DEV ADC1 +#define ADC_1_CHANNELS 2 +#define ADC_1_CLKEN() (BITBAND_REG(SIM->SCGC3, SIM_SCGC3_ADC1_SHIFT) = 1) +#define ADC_1_CLKDIS() (BITBAND_REG(SIM->SCGC3, SIM_SCGC3_ADC1_SHIFT) = 0) +#define ADC_1_PORT_CLKEN() /* no PORT pins configured */ +#define ADC_1_MODULE_CLOCK SystemBusClock +/* ADC 1 channel 0 pin config */ +#define ADC_1_CH0 0 /* DADP0, connected externally to Mulle Vbat/2 on PGA1_DP */ +#define ADC_1_CH0_PORT 0 /* this channel is not part of the pin mux on this CPU */ +#define ADC_1_CH0_PIN 0 +#define ADC_1_CH0_PIN_AF 0 +/* ADC 1 channel 1 pin config */ +#define ADC_1_CH1 19 /* AD19, connected externally to Mulle Vchr/2 on PGA1_DM */ +#define ADC_1_CH1_PORT 0 /* this channel is not part of the pin mux on this CPU */ +#define ADC_1_CH1_PIN 0 +#define ADC_1_CH1_PIN_AF 0 +/* ADC 1 channel 2 pin config */ +#define ADC_1_CH2 12 +#define ADC_1_CH2_PIN 0 +#define ADC_1_CH2_PIN_AF 0 +#define ADC_1_CH2_PORT 0 +/* ADC 1 channel 3 pin config */ +#define ADC_1_CH3 13 +#define ADC_1_CH3_PIN 0 +#define ADC_1_CH3_PIN_AF 0 +#define ADC_1_CH3_PORT 0 +/* ADC 1 channel 4 pin config */ +#define ADC_1_CH4 14 +#define ADC_1_CH4_PIN 0 +#define ADC_1_CH4_PIN_AF 0 +#define ADC_1_CH4_PORT 0 +/* ADC 1 channel 5 pin config */ +#define ADC_1_CH5 15 +#define ADC_1_CH5_PIN 0 +#define ADC_1_CH5_PIN_AF 0 +#define ADC_1_CH5_PORT 0 +/** @} */ + + +/** + * @name PWM configuration + * @{ + */ +#define PWM_NUMOF (0U) +#define PWM_0_EN 1 +#define PWM_1_EN 1 +#define PWM_MAX_CHANNELS 4 + +/** @} */ + + +/** + * @name SPI configuration + * @{ + */ +#define SPI_NUMOF 3 +#define SPI_0_EN 1 +#define SPI_1_EN 1 +#define SPI_2_EN 1 +#define SPI_3_EN 0 +#define SPI_4_EN 0 +#define SPI_5_EN 0 +#define SPI_6_EN 0 +#define SPI_7_EN 0 + +#define MULLE_PASTE_PARTS(left, index, right) MULLE_PASTE_PARTS2(left, index, right) +#define MULLE_PASTE_PARTS2(left, index, right) left##index##right + +/* SPI 0 device config */ +/* SPI_0 (in RIOT) is mapped to SPI0, CTAS=0 in hardware */ +#define SPI_0_INDEX 0 +#define SPI_0_CTAS 0 +#define SPI_0_DEV MULLE_PASTE_PARTS(SPI, SPI_0_INDEX, ) +#define SPI_0_CLKEN() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_SPI0_SHIFT) = 1) +#define SPI_0_CLKDIS() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_SPI0_SHIFT) = 0) +#define SPI_0_IRQ MULLE_PASTE_PARTS(SPI, SPI_0_INDEX, _IRQn) +#define SPI_0_IRQ_HANDLER MULLE_PASTE_PARTS(isr_spi, SPI_0_INDEX, ) +#define SPI_0_IRQ_PRIO 1 +#define SPI_0_FREQ SystemBusClock +/* SPI 0 pin configuration */ +#define SPI_0_SCK_PORT PORTD +#define SPI_0_SCK_PIN 1 +#define SPI_0_SCK_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define SPI_0_SCK_AF 2 +#define SPI_0_SIN_PORT PORTD +#define SPI_0_SIN_PIN 3 +#define SPI_0_SIN_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define SPI_0_SIN_AF 2 +#define SPI_0_SOUT_PORT PORTD +#define SPI_0_SOUT_PIN 2 +#define SPI_0_SOUT_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define SPI_0_SOUT_AF 2 +#define SPI_0_PCS0_PORT PORTD +#define SPI_0_PCS0_PIN 0 +#define SPI_0_PCS0_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define SPI_0_PCS0_AF 2 +/* SPI chip select polarity */ +#define SPI_0_PCS0_ACTIVE_LOW 1 +#define SPI_0_PCS1_ACTIVE_LOW 1 +#define SPI_0_PCS2_ACTIVE_LOW 1 +#define SPI_0_PCS3_ACTIVE_LOW 1 + +/* SPI 1 device config */ +/* SPI_1 (in RIOT) is mapped to SPI1, CTAS=0 in hardware */ +#define SPI_1_INDEX 1 +#define SPI_1_CTAS 0 +#define SPI_1_DEV MULLE_PASTE_PARTS(SPI, SPI_1_INDEX, ) +#define SPI_1_CLKEN() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_SPI1_SHIFT) = 1) +#define SPI_1_CLKDIS() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_SPI1_SHIFT) = 0) +#define SPI_1_IRQ MULLE_PASTE_PARTS(SPI, SPI_1_INDEX, _IRQn) +#define SPI_1_IRQ_HANDLER MULLE_PASTE_PARTS(isr_spi, SPI_1_INDEX, ) +#define SPI_1_IRQ_PRIO 1 +#define SPI_1_FREQ SystemBusClock +/* SPI 0 pin configuration */ +#define SPI_1_SCK_PORT PORTE +#define SPI_1_SCK_PIN 2 +#define SPI_1_SCK_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT) = 1) +#define SPI_1_SCK_AF 2 +#define SPI_1_SIN_PORT PORTE +#define SPI_1_SIN_PIN 3 +#define SPI_1_SIN_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT) = 1) +#define SPI_1_SIN_AF 2 +#define SPI_1_SOUT_PORT PORTE +#define SPI_1_SOUT_PIN 1 +#define SPI_1_SOUT_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT) = 1) +#define SPI_1_SOUT_AF 2 +#define SPI_1_PCS0_PORT PORTE +#define SPI_1_PCS0_PIN 4 +#define SPI_1_PCS0_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT) = 1) +#define SPI_1_PCS0_AF 2 +/* SPI chip select polarity */ +#define SPI_1_PCS0_ACTIVE_LOW 1 +#define SPI_1_PCS1_ACTIVE_LOW 1 +#define SPI_1_PCS2_ACTIVE_LOW 1 +#define SPI_1_PCS3_ACTIVE_LOW 1 + +/* SPI 2 device config */ +/* SPI_2 (in RIOT) is mapped to SPI0, CTAS=1 in hardware */ +#define SPI_2_INDEX 0 +#define SPI_2_CTAS 1 +#define SPI_2_DEV MULLE_PASTE_PARTS(SPI, SPI_2_INDEX, ) +#define SPI_2_CLKEN() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_SPI0_SHIFT) = 1) +#define SPI_2_CLKDIS() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_SPI0_SHIFT) = 0) +#define SPI_2_IRQ MULLE_PASTE_PARTS(SPI, SPI_2_INDEX, _IRQn) +/* #define SPI_2_IRQ_HANDLER MULLE_PASTE_PARTS(isr_spi, SPI_2_INDEX, ) */ +#define SPI_2_IRQ_PRIO 1 +#define SPI_2_FREQ SystemBusClock +/* SPI 2 pin configuration, must be the same as the other RIOT device using this + * hardware module */ +#define SPI_2_SCK_PORT PORTD +#define SPI_2_SCK_PIN 1 +#define SPI_2_SCK_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define SPI_2_SCK_AF 2 +#define SPI_2_SIN_PORT PORTD +#define SPI_2_SIN_PIN 3 +#define SPI_2_SIN_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define SPI_2_SIN_AF 2 +#define SPI_2_SOUT_PORT PORTD +#define SPI_2_SOUT_PIN 2 +#define SPI_2_SOUT_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define SPI_2_SOUT_AF 2 +#define SPI_2_PCS0_PORT PORTD +#define SPI_2_PCS0_PIN 0 +#define SPI_2_PCS0_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define SPI_2_PCS0_AF 2 +/* SPI chip select polarity */ +#define SPI_2_PCS0_ACTIVE_LOW 1 +#define SPI_2_PCS1_ACTIVE_LOW 1 +#define SPI_2_PCS2_ACTIVE_LOW 1 +#define SPI_2_PCS3_ACTIVE_LOW 1 + +/** + * @name SPI delay timing configuration + * @{ */ +/* These values are necessary for communicating with the AT86RF212B when running + * the MCU core at high clock frequencies. */ +/* NB: The given values are the reciprocals of the time, in order to compute the + * scalers using only integer math. */ +#define SPI_0_TCSC_FREQ (5555555) /* It looks silly, but this is correct. 1/180e-9 */ +#define SPI_0_TASC_FREQ (5454545) /* It looks silly, but this is correct. 1/183e-9 */ +#define SPI_0_TDT_FREQ (4000000) /* 1/250e-9 */ + +/* SPI_1 timings */ +#define SPI_1_TCSC_FREQ (0) +#define SPI_1_TASC_FREQ (0) +#define SPI_1_TDT_FREQ (0) + +/* SPI_2 timings */ +#define SPI_2_TCSC_FREQ (0) +#define SPI_2_TASC_FREQ (0) +#define SPI_2_TDT_FREQ (0) + +/** @} */ + +/** @} */ + + +/** + * @name I2C configuration + * @{ + */ +#define I2C_NUMOF (1U) +#define I2C_CLK SystemBusClock +#define I2C_0_EN 1 +#define I2C_1_EN 0 +#define I2C_IRQ_PRIO 1 +/** + * @name I2C baud rate configuration + * @{ + */ +/* Low (10 kHz): MUL = 4, SCL divider = 2560, total: 10240 */ +#define KINETIS_I2C_F_ICR_LOW (0x3D) +#define KINETIS_I2C_F_MULT_LOW (2) +/* Normal (100 kHz): MUL = 2, SCL divider = 240, total: 480 */ +#define KINETIS_I2C_F_ICR_NORMAL (0x1F) +#define KINETIS_I2C_F_MULT_NORMAL (1) +/* Fast (400 kHz): MUL = 1, SCL divider = 128, total: 128 */ +#define KINETIS_I2C_F_ICR_FAST (0x17) +#define KINETIS_I2C_F_MULT_FAST (0) +/* Fast plus (1000 kHz): MUL = 1, SCL divider = 48, total: 48 */ +#define KINETIS_I2C_F_ICR_FAST_PLUS (0x10) +#define KINETIS_I2C_F_MULT_FAST_PLUS (0) +/** @} */ + +/* I2C 0 device configuration */ +#define I2C_0_DEV I2C0 +#define I2C_0_CLKEN() (BITBAND_REG(SIM->SCGC4, SIM_SCGC4_I2C0_SHIFT) = 1) +#define I2C_0_CLKDIS() (BITBAND_REG(SIM->SCGC4, SIM_SCGC4_I2C0_SHIFT) = 0) +#define I2C_0_IRQ I2C0_IRQn +#define I2C_0_IRQ_HANDLER isr_i2c0 +/* I2C 0 pin configuration */ +#define I2C_0_PORT PORTB +#define I2C_0_PORT_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define I2C_0_PIN_AF 2 +#define I2C_0_SDA_PIN 1 +#define I2C_0_SCL_PIN 2 +#define I2C_0_PORT_CFG (PORT_PCR_MUX(I2C_0_PIN_AF) | PORT_PCR_ODE_MASK) +/** @} */ + + +/** + * @name GPIO configuration + * @{ + */ +#define GPIO_NUMOF 26 +#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_12_EN 1 +#define GPIO_13_EN 1 +#define GPIO_14_EN 1 +#define GPIO_15_EN 1 +#define GPIO_16_EN 1 +#define GPIO_17_EN 1 +#define GPIO_18_EN 1 +#define GPIO_19_EN 1 +#define GPIO_20_EN 1 +#define GPIO_21_EN 1 +#define GPIO_22_EN 1 +#define GPIO_23_EN 1 +#define GPIO_24_EN 1 +#define GPIO_25_EN 1 +#define GPIO_IRQ_PRIO 1 + +/* GPIO channel 0 config */ +/* Red LED */ +#define GPIO_0_PORT PORTC +#define GPIO_0_PORT_BASE PORTC_BASE +#define GPIO_0_DEV PTC +#define GPIO_0_PIN 15 +#define GPIO_0_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_0_IRQ PORTC_IRQn +#define GPIO_0_ISR isr_portc_pin_detect + +/* GPIO channel 1 config */ +/* Yellow LED */ +#define GPIO_1_PORT PORTC +#define GPIO_1_PORT_BASE PORTC_BASE +#define GPIO_1_DEV PTC +#define GPIO_1_PIN 14 +#define GPIO_1_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_1_IRQ PORTC_IRQn +#define GPIO_1_ISR isr_portc_pin_detect + +/* GPIO channel 2 config */ +/* Green LED */ +#define GPIO_2_PORT PORTC +#define GPIO_2_PORT_BASE PORTC_BASE +#define GPIO_2_DEV PTC +#define GPIO_2_PIN 13 +#define GPIO_2_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_2_IRQ PORTC_IRQn +#define GPIO_2_ISR isr_portc_pin_detect + +/* GPIO channel 3 config */ +/* LIS3DH INT1 */ +#define GPIO_3_PORT PORTC +#define GPIO_3_PORT_BASE PORTC_BASE +#define GPIO_3_DEV PTC +#define GPIO_3_PIN 18 +#define GPIO_3_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_3_IRQ PORTC_IRQn +#define GPIO_3_ISR isr_portc_pin_detect + +/* GPIO channel 4 config */ +/* LIS3DH INT2 */ +#define GPIO_4_PORT PORTC +#define GPIO_4_PORT_BASE PORTC_BASE +#define GPIO_4_DEV PTC +#define GPIO_4_PIN 17 +#define GPIO_4_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_4_IRQ PORTC_IRQn +#define GPIO_4_ISR isr_portc_pin_detect + +/* GPIO channel 5 config */ +/* VSEC enable */ +#define GPIO_5_PORT PORTB +#define GPIO_5_PORT_BASE PORTB_BASE +#define GPIO_5_DEV PTB +#define GPIO_5_PIN 16 +#define GPIO_5_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_5_IRQ PORTB_IRQn +#define GPIO_5_ISR isr_portb_pin_detect + +/* GPIO channel 6 config */ +/* AVDD enable */ +#define GPIO_6_PORT PORTB +#define GPIO_6_PORT_BASE PORTB_BASE +#define GPIO_6_DEV PTB +#define GPIO_6_PIN 17 +#define GPIO_6_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_6_IRQ PORTB_IRQn +#define GPIO_6_ISR isr_portb_pin_detect + +/* GPIO channel 7 config */ +/* VPERIPH enable */ +#define GPIO_7_PORT PORTD +#define GPIO_7_PORT_BASE PORTD_BASE +#define GPIO_7_DEV PTD +#define GPIO_7_PIN 7 +#define GPIO_7_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define GPIO_7_IRQ PORTD_IRQn +#define GPIO_7_ISR isr_portd_pin_detect + +/* GPIO channel 8 config */ +/* MC34673 enable */ +#define GPIO_8_PORT PORTB +#define GPIO_8_PORT_BASE PORTB_BASE +#define GPIO_8_DEV PTB +#define GPIO_8_PIN 23 +#define GPIO_8_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_8_IRQ PORTB_IRQn +#define GPIO_8_ISR isr_portb_pin_detect + +/* GPIO channel 9 config */ +/* MC34673 CHG */ +#define GPIO_9_PORT PORTB +#define GPIO_9_PORT_BASE PORTB_BASE +#define GPIO_9_DEV PTB +#define GPIO_9_PIN 22 +#define GPIO_9_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_9_IRQ PORTB_IRQn +#define GPIO_9_ISR isr_portb_pin_detect + +/* GPIO channel 10 config */ +/* MC34673 PPR */ +#define GPIO_10_PORT PORTB +#define GPIO_10_PORT_BASE PORTB_BASE +#define GPIO_10_DEV PTB +#define GPIO_10_PIN 21 +#define GPIO_10_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_10_IRQ PORTB_IRQn +#define GPIO_10_ISR isr_portb_pin_detect + +/* GPIO channel 11 config */ +/* MC34673 FAST */ +#define GPIO_11_PORT PORTB +#define GPIO_11_PORT_BASE PORTB_BASE +#define GPIO_11_DEV PTB +#define GPIO_11_PIN 20 +#define GPIO_11_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_11_IRQ PORTB_IRQn +#define GPIO_11_ISR isr_portb_pin_detect + +/* GPIO channel 12 config */ +/* AT86RF212 IRQ */ +#define GPIO_12_PORT PORTB +#define GPIO_12_PORT_BASE PORTB_BASE +#define GPIO_12_DEV PTB +#define GPIO_12_PIN 9 +#define GPIO_12_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_12_IRQ PORTB_IRQn +#define GPIO_12_ISR isr_portb_pin_detect + +/* GPIO channel 13 config */ +/* AT86RF212 SLP_TR */ +#define GPIO_13_PORT PORTE +#define GPIO_13_PORT_BASE PORTE_BASE +#define GPIO_13_DEV PTE +#define GPIO_13_PIN 6 +#define GPIO_13_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT) = 1) +#define GPIO_13_IRQ PORTE_IRQn +#define GPIO_13_ISR isr_porte_pin_detect + +/* GPIO channel 14 config */ +/* AT86RF212 SS */ +#define GPIO_14_PORT PORTD +#define GPIO_14_PORT_BASE PORTD_BASE +#define GPIO_14_DEV PTD +#define GPIO_14_PIN 4 +#define GPIO_14_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define GPIO_14_IRQ PORTD_IRQn +#define GPIO_14_ISR isr_portd_pin_detect + +/* GPIO channel 15 config */ +/* LIS3DH CS */ +#define GPIO_15_PORT PORTD +#define GPIO_15_PORT_BASE PORTD_BASE +#define GPIO_15_DEV PTD +#define GPIO_15_PIN 0 +#define GPIO_15_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define GPIO_15_IRQ PORTD_IRQn +#define GPIO_15_ISR isr_portd_pin_detect + +/* GPIO channel 16 config */ +/* FM25L04B CS */ +#define GPIO_16_PORT PORTD +#define GPIO_16_PORT_BASE PORTD_BASE +#define GPIO_16_DEV PTD +#define GPIO_16_PIN 6 +#define GPIO_16_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define GPIO_16_IRQ PORTD_IRQn +#define GPIO_16_ISR isr_portd_pin_detect + +/* GPIO channel 17 config */ +/* M25P16 CS */ +#define GPIO_17_PORT PORTD +#define GPIO_17_PORT_BASE PORTD_BASE +#define GPIO_17_DEV PTD +#define GPIO_17_PIN 5 +#define GPIO_17_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT) = 1) +#define GPIO_17_IRQ PORTD_IRQn +#define GPIO_17_ISR isr_portd_pin_detect + +/* GPIO channel 18 config */ +/* General purpose expansion PTB18 */ +#define GPIO_18_PORT PORTB +#define GPIO_18_PORT_BASE PORTB_BASE +#define GPIO_18_DEV PTB +#define GPIO_18_PIN 18 +#define GPIO_18_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_18_IRQ PORTB_IRQn +#define GPIO_18_ISR isr_portb_pin_detect + +/* GPIO channel 19 config */ +/* General purpose expansion PTB19 */ +#define GPIO_19_PORT PORTB +#define GPIO_19_PORT_BASE PORTB_BASE +#define GPIO_19_DEV PTB +#define GPIO_19_PIN 19 +#define GPIO_19_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT) = 1) +#define GPIO_19_IRQ PORTB_IRQn +#define GPIO_19_ISR isr_portb_pin_detect + +/* GPIO channel 20 config */ +/* General purpose expansion PTC0 */ +#define GPIO_20_PORT PORTC +#define GPIO_20_PORT_BASE PORTC_BASE +#define GPIO_20_DEV PTC +#define GPIO_20_PIN 0 +#define GPIO_20_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_20_IRQ PORTC_IRQn +#define GPIO_20_ISR isr_portc_pin_detect + +/* GPIO channel 21 config */ +/* General purpose expansion PTC1 */ +#define GPIO_21_PORT PORTC +#define GPIO_21_PORT_BASE PORTC_BASE +#define GPIO_21_DEV PTC +#define GPIO_21_PIN 1 +#define GPIO_21_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_21_IRQ PORTC_IRQn +#define GPIO_21_ISR isr_portc_pin_detect + +/* GPIO channel 22 config */ +/* General purpose expansion PTC2 */ +#define GPIO_22_PORT PORTC +#define GPIO_22_PORT_BASE PORTC_BASE +#define GPIO_22_DEV PTC +#define GPIO_22_PIN 2 +#define GPIO_22_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_22_IRQ PORTC_IRQn +#define GPIO_22_ISR isr_portc_pin_detect + +/* GPIO channel 23 config */ +/* General purpose expansion PTC5 */ +#define GPIO_23_PORT PORTC +#define GPIO_23_PORT_BASE PORTC_BASE +#define GPIO_23_DEV PTC +#define GPIO_23_PIN 5 +#define GPIO_23_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_23_IRQ PORTC_IRQn +#define GPIO_23_ISR isr_portc_pin_detect + +/* GPIO channel 24 config */ +/* General purpose expansion PTC6 */ +#define GPIO_24_PORT PORTC +#define GPIO_24_PORT_BASE PORTC_BASE +#define GPIO_24_DEV PTC +#define GPIO_24_PIN 6 +#define GPIO_24_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_24_IRQ PORTC_IRQn +#define GPIO_24_ISR isr_portc_pin_detect + +/* GPIO channel 25 config */ +/* General purpose expansion PTC7 */ +#define GPIO_25_PORT PORTC +#define GPIO_25_PORT_BASE PORTC_BASE +#define GPIO_25_DEV PTC +#define GPIO_25_PIN 7 +#define GPIO_25_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1) +#define GPIO_25_IRQ PORTC_IRQn +#define GPIO_25_ISR isr_portc_pin_detect + +/** @} */ + + +/** + * @name RTC configuration + * @{ + */ +/* RIOT RTC implementation uses RTT for underlying timekeeper */ +#define RTC_NUMOF (1U) +/** @} */ + +/** + * @name RTT configuration + * @{ + */ +#define RTT_NUMOF (1U) +#define RTT_IRQ_PRIO 1 +#define RTT_IRQ RTC_IRQn +#define RTT_ISR isr_rtc_alarm +#define RTT_DEV RTC +#define RTT_UNLOCK() (BITBAND_REG(SIM->SCGC6, SIM_SCGC6_RTC_SHIFT) = 1) +#define RTT_MAX_VALUE (0xffffffff) +#define RTT_FREQUENCY (1) /* in Hz */ + +/** + * RTC module crystal load capacitance configuration bits. + */ +/* enable 12pF load capacitance, might need adjusting.. */ +#define RTT_LOAD_CAP_BITS (RTC_CR_SC8P_MASK | RTC_CR_SC4P_MASK) +/** @} */ + + +/** + * @name Random Number Generator configuration + * @{ + */ +#define RANDOM_NUMOF (1U) +#define RANDOM_CLKEN() (BITBAND_REG(SIM->SCGC3, SIM_SCGC3_RNGA_SHIFT) = 1) +#define RANDOM_CLKDIS() (BITBAND_REG(SIM->SCGC3, SIM_SCGC3_RNGA_SHIFT) = 0) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MULLE_PERIPH_CONF_H */ +/** @} */