atsamd: Update code to use armcm_boot mechanism

Replace the custom linker scripts with the src/generic/armcm_boot.c
mechanism.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-08-21 18:56:10 -04:00
parent 4990fe814d
commit 6338f6a5f0
7 changed files with 28 additions and 129 deletions

View File

@ -68,6 +68,10 @@ config FLASH_SIZE
default 0x80000 if MACH_SAMD51G19 || MACH_SAMD51J19 || MACH_SAMD51N19
default 0x100000 if MACH_SAMD51P20
config RAM_START
hex
default 0x20000000
config RAM_SIZE
hex
default 0x1000 if MACH_SAMD21E15

View File

@ -4,8 +4,8 @@
CROSS_PREFIX=arm-none-eabi-
dirs-y += src/atsamd src/generic
dirs-$(CONFIG_MACH_SAMD21) += lib/samd21/samd21a/gcc/gcc/
dirs-$(CONFIG_MACH_SAMD51) += lib/samd51/samd51a/gcc/gcc/
dirs-$(CONFIG_MACH_SAMD21) += lib/samd21/samd21a/gcc
dirs-$(CONFIG_MACH_SAMD51) += lib/samd51/samd51a/gcc
MCU := $(shell echo $(CONFIG_MCU) | tr a-z A-Z)
@ -15,11 +15,12 @@ CFLAGS-$(CONFIG_MACH_SAMD51) += -mfpu=fpv4-sp-d16 -mfloat-abi=hard
CFLAGS += $(CFLAGS-y) -D__$(MCU)__ -mthumb -Ilib/cmsis-core
CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs
CFLAGS_klipper.elf += -T $(OUT)src/atsamd/samd.ld
$(OUT)klipper.elf: $(OUT)src/atsamd/samd.ld
CFLAGS_klipper.elf += -T $(OUT)src/generic/armcm_boot.ld
$(OUT)klipper.elf: $(OUT)src/generic/armcm_boot.ld
# Add source files
src-y += atsamd/main.c atsamd/gpio.c generic/crc16_ccitt.c generic/armcm_irq.c
src-y += atsamd/main.c atsamd/gpio.c
src-y += generic/armcm_boot.c generic/armcm_irq.c generic/crc16_ccitt.c
src-$(CONFIG_USBSERIAL) += atsamd/usbserial.c generic/usb_cdc.c
src-$(CONFIG_SERIAL) += atsamd/serial.c generic/serial_irq.c
src-$(CONFIG_HAVE_GPIO_ADC) += atsamd/adc.c
@ -29,10 +30,8 @@ src-$(CONFIG_HAVE_SERCOM) += atsamd/sercom.c
src-$(CONFIG_HAVE_GPIO_HARD_PWM) += atsamd/hard_pwm.c
src-$(CONFIG_MACH_SAMD21) += atsamd/watchdog.c
src-$(CONFIG_MACH_SAMD21) += atsamd/clock.c atsamd/timer.c generic/timer_irq.c
src-$(CONFIG_MACH_SAMD21) += ../lib/samd21/samd21a/gcc/gcc/startup_samd21.c
src-$(CONFIG_MACH_SAMD51) += atsamd/samd51_watchdog.c
src-$(CONFIG_MACH_SAMD51) += atsamd/samd51_clock.c generic/armcm_timer.c
src-$(CONFIG_MACH_SAMD51) += ../lib/samd51/samd51a/gcc/gcc/startup_samd51.c
# Build the additional hex and bin output files
target-y += $(OUT)klipper.bin $(OUT)klipper.elf.hex

View File

@ -4,28 +4,12 @@
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "command.h" // DECL_CONSTANT
#include "command.h" // DECL_CONSTANT_STR
#include "internal.h" // NVIC_SystemReset
#include "sched.h" // sched_main
DECL_CONSTANT_STR("MCU", CONFIG_MCU);
// Return the start of memory available for dynamic allocations
void *
dynmem_start(void)
{
extern uint32_t _ezero;
return &_ezero;
}
// Return the end of memory available for dynamic allocations
void *
dynmem_end(void)
{
extern uint32_t _sstack;
return &_sstack;
}
void
command_reset(uint32_t *args)
{
@ -37,7 +21,6 @@ DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset");
int
main(void)
{
SystemInit();
sched_main();
return 0;
}

View File

@ -1,63 +0,0 @@
/* Linker script for atsamd chips
*
* Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
*
* This file may be distributed under the terms of the GNU GPLv3 license.
*/
#include "autoconf.h"
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
MEMORY
{
rom (rx) : ORIGIN = CONFIG_FLASH_START , LENGTH = CONFIG_FLASH_SIZE
ram (rwx) : ORIGIN = 0x20000000, LENGTH = CONFIG_RAM_SIZE
}
SECTIONS
{
.text : {
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.*)
*(.rodata .rodata*)
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
KEEP(*(.fini))
} > rom
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
.bss (NOLOAD) :
{
. = ALIGN(4);
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ezero = .;
} > ram
_sstack = 0x20000000 + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE ;
.stack _sstack (NOLOAD) :
{
. = . + CONFIG_STACK_SIZE;
_estack = .;
} > ram
}

View File

@ -4,6 +4,7 @@
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "board/armcm_boot.h" // armcm_enable_irq
#include "board/serial_irq.h" // serial_rx_data
#include "command.h" // DECL_CONSTANT_STR
#include "internal.h" // enable_pclock
@ -15,7 +16,7 @@ serial_enable_tx_irq(void)
SERCOM0->USART.INTENSET.reg = SERCOM_USART_INTENSET_DRE;
}
void __visible
void
SERCOM0_Handler(void)
{
uint32_t status = SERCOM0->USART.INTFLAG.reg;
@ -31,16 +32,6 @@ SERCOM0_Handler(void)
}
}
// Aliases for irq handler on SAMD51
void SERCOM0_0_Handler(void)
__visible __attribute__((alias("SERCOM0_Handler")));
void SERCOM0_1_Handler(void)
__visible __attribute__((alias("SERCOM0_Handler")));
void SERCOM0_2_Handler(void)
__visible __attribute__((alias("SERCOM0_Handler")));
void SERCOM0_3_Handler(void)
__visible __attribute__((alias("SERCOM0_Handler")));
DECL_CONSTANT_STR("RESERVE_PINS_serial", "PA11,PA10");
void
@ -69,17 +60,12 @@ serial_init(void)
su->INTENSET.reg = SERCOM_USART_INTENSET_RXC;
su->CTRLA.reg = areg | SERCOM_USART_CTRLA_ENABLE;
#if CONFIG_MACH_SAMD21
NVIC_SetPriority(SERCOM0_IRQn, 0);
NVIC_EnableIRQ(SERCOM0_IRQn);
armcm_enable_irq(SERCOM0_Handler, SERCOM0_IRQn, 0);
#elif CONFIG_MACH_SAMD51
NVIC_SetPriority(SERCOM0_0_IRQn, 0);
NVIC_SetPriority(SERCOM0_1_IRQn, 0);
NVIC_SetPriority(SERCOM0_2_IRQn, 0);
NVIC_SetPriority(SERCOM0_3_IRQn, 0);
NVIC_EnableIRQ(SERCOM0_0_IRQn);
NVIC_EnableIRQ(SERCOM0_1_IRQn);
NVIC_EnableIRQ(SERCOM0_2_IRQn);
NVIC_EnableIRQ(SERCOM0_3_IRQn);
armcm_enable_irq(SERCOM0_Handler, SERCOM0_0_IRQn, 0);
armcm_enable_irq(SERCOM0_Handler, SERCOM0_1_IRQn, 0);
armcm_enable_irq(SERCOM0_Handler, SERCOM0_2_IRQn, 0);
armcm_enable_irq(SERCOM0_Handler, SERCOM0_3_IRQn, 0);
#endif
}
DECL_INIT(serial_init);

View File

@ -4,6 +4,7 @@
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "board/armcm_boot.h" // armcm_enable_irq
#include "board/irq.h" // irq_disable
#include "board/misc.h" // timer_read_time
#include "board/timer_irq.h" // timer_dispatch_many
@ -33,7 +34,7 @@ timer_kick(void)
}
// IRQ handler
void __visible __aligned(16) // aligning helps stabilize perf benchmarks
void __aligned(16) // aligning helps stabilize perf benchmarks
TC4_Handler(void)
{
irq_disable();
@ -54,8 +55,7 @@ timer_init(void)
irqstatus_t flag = irq_save();
tc->CTRLA.reg = 0;
tc->CTRLA.reg = TC_CTRLA_MODE_COUNT32;
NVIC_SetPriority(TC4_IRQn, 2);
NVIC_EnableIRQ(TC4_IRQn);
armcm_enable_irq(TC4_Handler, TC4_IRQn, 2);
tc->INTENSET.reg = TC_INTENSET_MC0;
tc->COUNT.reg = 0;
timer_kick();

View File

@ -6,6 +6,7 @@
#include <string.h> // memcpy
#include "autoconf.h" // CONFIG_FLASH_START
#include "board/armcm_boot.h" // armcm_enable_irq
#include "board/io.h" // readl
#include "board/irq.h" // irq_disable
#include "board/usb_cdc.h" // usb_notify_ep0
@ -190,7 +191,7 @@ usb_request_bootloader(void)
* Setup and interrupts
****************************************************************/
void __visible
void
USB_Handler(void)
{
uint8_t s = USB->DEVICE.INTFLAG.reg;
@ -225,12 +226,6 @@ USB_Handler(void)
}
}
// Aliases for irq handeler on SAMD51
void USB_0_Handler(void) __visible __attribute__((alias("USB_Handler")));
void USB_1_Handler(void) __visible __attribute__((alias("USB_Handler")));
void USB_2_Handler(void) __visible __attribute__((alias("USB_Handler")));
void USB_3_Handler(void) __visible __attribute__((alias("USB_Handler")));
DECL_CONSTANT_STR("RESERVE_PINS_USB", "PA24,PA25");
void
@ -256,17 +251,12 @@ usbserial_init(void)
// enable irqs
USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_EORST;
#if CONFIG_MACH_SAMD21
NVIC_SetPriority(USB_IRQn, 1);
NVIC_EnableIRQ(USB_IRQn);
armcm_enable_irq(USB_Handler, USB_IRQn, 1);
#elif CONFIG_MACH_SAMD51
NVIC_SetPriority(USB_0_IRQn, 1);
NVIC_SetPriority(USB_1_IRQn, 1);
NVIC_SetPriority(USB_2_IRQn, 1);
NVIC_SetPriority(USB_3_IRQn, 1);
NVIC_EnableIRQ(USB_0_IRQn);
NVIC_EnableIRQ(USB_1_IRQn);
NVIC_EnableIRQ(USB_2_IRQn);
NVIC_EnableIRQ(USB_3_IRQn);
armcm_enable_irq(USB_Handler, USB_0_IRQn, 1);
armcm_enable_irq(USB_Handler, USB_1_IRQn, 1);
armcm_enable_irq(USB_Handler, USB_2_IRQn, 1);
armcm_enable_irq(USB_Handler, USB_3_IRQn, 1);
#endif
}
DECL_INIT(usbserial_init);