From 53de290fdadd115b1595d3e2f20d412734522bf7 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 14 Apr 2016 00:44:26 +0000 Subject: [PATCH] atmel samd: Basic framework. Thoughts: should this be a "sam0" family rather than samd? (Much like Atmel's own software package lumps all the cortex-m0+ devices in one family) This was enough to get a basic blinky working at least. --- Makefile | 1 + include/libopencm3/dispatch/nvic.h | 2 + include/libopencm3/sam/d/irq.json | 26 +++++++ include/libopencm3/sam/d/memorymap.h | 51 +++++++++++++ include/libopencm3/sam/d/port.h | 68 +++++++++++++++++ include/libopencm3/sam/memorymap.h | 2 + ld/devices.data | 4 + lib/dispatch/vector_nvic.c | 2 + lib/sam/d/Makefile | 38 ++++++++++ lib/sam/d/libopencm3_samd.ld | 106 +++++++++++++++++++++++++++ 10 files changed, 300 insertions(+) create mode 100644 include/libopencm3/sam/d/irq.json create mode 100644 include/libopencm3/sam/d/memorymap.h create mode 100644 include/libopencm3/sam/d/port.h create mode 100644 lib/sam/d/Makefile create mode 100644 lib/sam/d/libopencm3_samd.ld diff --git a/Makefile b/Makefile index d93efeac..c5cb5da5 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,7 @@ TARGETS:= stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/f7 \ lpc13xx lpc17xx lpc43xx/m4 lpc43xx/m0 lm3s lm4f \ efm32/tg efm32/g efm32/lg efm32/gg \ sam/3a sam/3n sam/3s sam/3u sam/3x \ + sam/d \ vf6xx # Be silent per default, but 'make V=1' will show all compiler calls. diff --git a/include/libopencm3/dispatch/nvic.h b/include/libopencm3/dispatch/nvic.h index 724ee379..1c705f83 100644 --- a/include/libopencm3/dispatch/nvic.h +++ b/include/libopencm3/dispatch/nvic.h @@ -49,6 +49,8 @@ # include #elif defined(SAM3X) # include +#elif defined(SAMD) +# include #elif defined(LM3S) || defined(LM4F) /* Yes, we use the same interrupt table for both LM3S and LM4F */ diff --git a/include/libopencm3/sam/d/irq.json b/include/libopencm3/sam/d/irq.json new file mode 100644 index 00000000..e9404825 --- /dev/null +++ b/include/libopencm3/sam/d/irq.json @@ -0,0 +1,26 @@ +{ + "irqs": [ + "pm", + "sysctrl", + "wdt", + "rtc", + "eic", + "nvmctrl", + "dmac", + "reserved1", + "evsys", + "sercom0", + "sercom1", + "sercom2", + "tcc0", + "tc1", + "tc2", + "adc", + "ac", + "dac", + "ptc" + ], + "partname_humanreadable": "Atmel SAMD series", + "partname_doxygen": "SAMD", + "includeguard": "LIBOPENCM3_SAMD_NVIC_H" +} \ No newline at end of file diff --git a/include/libopencm3/sam/d/memorymap.h b/include/libopencm3/sam/d/memorymap.h new file mode 100644 index 00000000..5633a05d --- /dev/null +++ b/include/libopencm3/sam/d/memorymap.h @@ -0,0 +1,51 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SAMD_MEMORYMAP_H +#define SAMD_MEMORYMAP_H + +#include + +/* --- SAMD AHB-APB bridge A -------------------------------------------- */ +#define PM_BASE (0x40000400U) +#define SYSCTRL_BASE (0x40000800U) +#define GCLK_BASE (0x40000c00U) +#define WDT_BASE (0x40001000U) +#define RTC_BASE (0x40001400U) +#define EIC_BASE (0x40001800U) +/* --- SAMD AHB-APB bridge B -------------------------------------------- */ +#define DSU_BASE (0x41002000U) +#define NVMCTRL_BASE (0x41004000U) +#define PORT_BASE (0x41004400U) +#define DMAC_BASE (0x41004800U) +#define MTB_BASE (0x41006000U) +/* --- SAMD AHB-APB bridge C -------------------------------------------- */ +#define EVSYS_BASE (0x42000400U) +#define SERCOM0_BASE (0x42000800U) +#define SERCOM1_BASE (0x42000c00U) +#define SERCOM2_BASE (0x42001000U) +#define TCC0_BASE (0x42001400U) +#define TC1_BASE (0x42001800U) +#define TC2_BASE (0x42001c00U) +#define ADC_BASE (0x42002000U) +#define AC_BASE (0x42002400U) +#define DAC_BASE (0x42002800U) +#define PTC_BASE (0x42002c00U) + +#endif diff --git a/include/libopencm3/sam/d/port.h b/include/libopencm3/sam/d/port.h new file mode 100644 index 00000000..2e71ad72 --- /dev/null +++ b/include/libopencm3/sam/d/port.h @@ -0,0 +1,68 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2016 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#pragma once + +#include + +/* --- Convenience macros ------------------------------------------------ */ + +#define PORTA PORT_BASE + 0 +#define PORTB PORT_BASE + 0x80 + +/* --- PORT registers ----------------------------------------------------- */ + +/* Direction register */ +#define PORT_DIR(port) MMIO32((port) + 0x0000) + +/* Direction clear register */ +#define PORT_DIRCLR(port) MMIO32((port) + 0x0004) + +/* Direction set register */ +#define PORT_DIRSET(port) MMIO32((port) + 0x0008) + +/* Direction toggle register */ +#define PORT_DIRTGL(port) MMIO32((port) + 0x000c) + +/* output register */ +#define PORT_OUT(port) MMIO32((port) + 0x0010) + +/* output clear register */ +#define PORT_OUTCLR(port) MMIO32((port) + 0x0014) + +/* output set register */ +#define PORT_OUTSET(port) MMIO32((port) + 0x0018) + +/* output toggle register */ +#define PORT_OUTTGL(port) MMIO32((port) + 0x001c) + +/* input register */ +#define PORT_IN(port) MMIO32((port) + 0x0020) + +/* Control register */ +#define PORT_CTRL(port) MMIO32((port) + 0x0024) + +/* Write configuration register */ +#define PORT_WRCONFIG(port) MMIO32((port) + 0x0028) + +/* Peripheral multiplexing registers */ +#define PORT_PMUX(port, n) MMIO8((port) + 0x0030 + (n)) + +/* Pin configuration registers */ +#define PORT_PINCFG(port, n) MMIO8((port) + 0x0040 + (n)) diff --git a/include/libopencm3/sam/memorymap.h b/include/libopencm3/sam/memorymap.h index eb1b85b9..67f1def3 100644 --- a/include/libopencm3/sam/memorymap.h +++ b/include/libopencm3/sam/memorymap.h @@ -31,6 +31,8 @@ # include #elif defined(SAM3X) # include +#elif defined(SAMD) +# include #else # error "Processor family not defined." #endif diff --git a/ld/devices.data b/ld/devices.data index 33a32331..92637036 100644 --- a/ld/devices.data +++ b/ld/devices.data @@ -187,6 +187,9 @@ sam3x4e* sam3xnfc ROM=256K RAM=32K RAM1=32K sam3x8c* sam3x ROM=512K RAM=64K RAM1=32K sam3x8e* sam3xnfc ROM=512K RAM=64K RAM1=32K +samd10?13* samd ROM=8K RAM=4K +samd10?14* samd ROM=16K RAM=4K + ################################################################################ # the lpc chips @@ -411,6 +414,7 @@ sam3n END ROM_OFF=0x00400000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft sam3s END ROM_OFF=0x00400000 RAM_OFF=0x20000000 CPU=cortex-m3 FPU=soft sam3u END ROM_OFF=0x00080000 RAM_OFF=0x20000000 RAM1_OFF=0x20080000 NFCRAM=4K NFCRAM_OFF=0x20100000 CPU=cortex-m3 FPU=soft sam3x END ROM_OFF=0x00080000 RAM_OFF=0x20000000 RAM1_OFF=0x20080000 CPU=cortex-m3 FPU=soft +samd END ROM_OFF=0x00000000 RAM_OFF=0x20000000 CPU=cortex-m0plus FPU=soft ################################################################################ # the lpc families diff --git a/lib/dispatch/vector_nvic.c b/lib/dispatch/vector_nvic.c index 1f9dafac..167ad872 100644 --- a/lib/dispatch/vector_nvic.c +++ b/lib/dispatch/vector_nvic.c @@ -45,6 +45,8 @@ # include "../sam/3u/vector_nvic.c" #elif defined(SAM3X) # include "../sam/3x/vector_nvic.c" +#elif defined(SAMD) +# include "../sam/d/vector_nvic.c" #elif defined(VF6XX) # include "../vf6xx/vector_nvic.c" diff --git a/lib/sam/d/Makefile b/lib/sam/d/Makefile new file mode 100644 index 00000000..24ab6cd6 --- /dev/null +++ b/lib/sam/d/Makefile @@ -0,0 +1,38 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2016 Karl Palsson +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = libopencm3_samd +SRCLIBDIR ?= ../.. + +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +TGT_CFLAGS = -Os -Wall -Wextra -I../../../include -fno-common \ + -mcpu=cortex-m0plus -mthumb $(FP_FLAGS) -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSAMD +TGT_CFLAGS += $(DEBUG_FLAGS) +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = + +VPATH += ../../cm3:../common + +include ../../Makefile.include + diff --git a/lib/sam/d/libopencm3_samd.ld b/lib/sam/d/libopencm3_samd.ld new file mode 100644 index 00000000..ada86c36 --- /dev/null +++ b/lib/sam/d/libopencm3_samd.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); +