rp2040: Added needed options to Kconfig, cleaned up.

Modified linker script and loader to load whole bootloader to the RAM.
Removed whatchdog.
Fixed gpio.c compilation.

Signed-off-by: Alex Malishev <malishev@gmail.com>
This commit is contained in:
sh83 2022-10-21 22:52:30 +03:00 committed by Eric Callahan
parent a253e73116
commit 09140ead87
6 changed files with 180 additions and 81 deletions

View File

@ -1,4 +1,4 @@
# Kconfig settings for STM32 processors
# Kconfig settings for RP2040 processor
if MACH_RP2040
@ -6,14 +6,7 @@ config RP2040_SELECT
bool
default y
select HAVE_GPIO
select HAVE_GPIO_ADC
select HAVE_GPIO_SPI
select HAVE_GPIO_I2C
select HAVE_GPIO_BITBANGING
select HAVE_STRICT_TIMING
select HAVE_CHIPID
select HAVE_GPIO_HARD_PWM
select HAVE_STEPPER_BOTH_EDGE
config BOARD_DIRECTORY
string
@ -47,6 +40,21 @@ config FLASH_START
hex
default 0x10000000
config APPLICATION_START
default 0x10004000
hex
config DEPLOYER_START
hex
default 0x10004000
config RP2040_BOOTLOADER_START
hex
default 0x10000100
config BLOCK_SIZE
int
default 64
######################################################################
# Bootloader options
@ -86,9 +94,6 @@ choice
config RP2040_CANBUS
bool "CAN bus"
select CANSERIAL
config RP2040_USBCANBUS
bool "USB to CAN bus bridge"
select USBCANBUS
endchoice
config RP2040_CANBUS_GPIO_RX

View File

@ -8,27 +8,22 @@ dirs-y += src/rp2040 src/generic lib/rp2040/elf2uf2 lib/fast-hash lib/can2040
CFLAGS += -mcpu=cortex-m0plus -mthumb -Ilib/cmsis-core
CFLAGS += -Ilib/rp2040 -Ilib/rp2040/cmsis_include -Ilib/fast-hash -Ilib/can2040
CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs
CFLAGS_klipper.elf += -T $(OUT)src/rp2040/rp2040_link.ld
$(OUT)klipper.elf: $(OUT)stage2.o $(OUT)src/rp2040/rp2040_link.ld
CFLAGS_canboot.elf += --specs=nano.specs --specs=nosys.specs
CFLAGS_canboot.elf += -T $(OUT)src/rp2040/rp2040_link.ld
# Add source files
src-y += rp2040/main.c rp2040/gpio.c rp2040/adc.c generic/crc16_ccitt.c
src-y += generic/armcm_boot.c generic/armcm_irq.c generic/armcm_reset.c
src-y += generic/timer_irq.c rp2040/timer.c rp2040/bootrom.c
mcu-y = rp2040/main.c rp2040/gpio.c rp2040/timer.c rp2040/flash.c rp2040/hw_flash.c
mcu-y += generic/armcm_irq.c generic/crc16_ccitt.c
src-y += rp2040/armcm_canboot.c $(mcu-y)
src-$(CONFIG_USBSERIAL) += rp2040/usbserial.c generic/usb_cdc.c
src-$(CONFIG_USBSERIAL) += rp2040/chipid.c
src-$(CONFIG_SERIAL) += rp2040/serial.c generic/serial_irq.c
src-$(CONFIG_CANSERIAL) += rp2040/can.c rp2040/chipid.c ../lib/can2040/can2040.c
src-$(CONFIG_CANSERIAL) += generic/canserial.c generic/canbus.c
src-$(CONFIG_CANSERIAL) += ../lib/fast-hash/fasthash.c
src-$(CONFIG_USBCANBUS) += rp2040/can.c rp2040/chipid.c ../lib/can2040/can2040.c
src-$(CONFIG_USBCANBUS) += generic/canserial.c generic/usb_canbus.c
src-$(CONFIG_USBCANBUS) += ../lib/fast-hash/fasthash.c rp2040/usbserial.c
src-$(CONFIG_HAVE_GPIO_HARD_PWM) += rp2040/hard_pwm.c
src-$(CONFIG_HAVE_GPIO_SPI) += rp2040/spi.c
src-$(CONFIG_HAVE_GPIO_I2C) += rp2040/i2c.c
$(OUT)canboot.elf: $(OUT)stage2.o $(OUT)src/rp2040/rp2040_link.ld
# rp2040 stage2 building
STAGE2_FILE := $(shell echo $(CONFIG_RP2040_STAGE2_FILE))
$(OUT)stage2.o: lib/rp2040/boot_stage2/$(STAGE2_FILE) $(OUT)autoconf.h
@ -38,24 +33,30 @@ $(OUT)stage2.o: lib/rp2040/boot_stage2/$(STAGE2_FILE) $(OUT)autoconf.h
$(Q)$(OBJCOPY) -O binary $(OUT)stage2raw.o $(OUT)stage2raw.bin
$(Q)lib/rp2040/boot_stage2/pad_checksum -s 0xffffffff $(OUT)stage2raw.bin $(OUT)stage2.S
$(Q)$(CC) $(CFLAGS) -c $(OUT)stage2.S -o $(OUT)stage2.o
OBJS_klipper.elf += $(OUT)stage2.o
OBJS_canboot.elf += $(OUT)stage2.o
# Binary output file rules
target-y += $(OUT)klipper.uf2
target-y += $(OUT)canboot.uf2
$(OUT)lib/rp2040/elf2uf2/elf2uf2: lib/rp2040/elf2uf2/main.cpp
@echo " Building $@"
$(Q)g++ -g -O -Ilib/rp2040 $< -o $@
$(OUT)klipper.uf2: $(OUT)klipper.elf $(OUT)lib/rp2040/elf2uf2/elf2uf2
$(OUT)canboot.uf2: $(OUT)canboot.elf $(OUT)lib/rp2040/elf2uf2/elf2uf2
@echo " Creating uf2 file $@"
$(Q)$(OUT)lib/rp2040/elf2uf2/elf2uf2 $< $@
$(Q)$(OUT)lib/rp2040/elf2uf2/elf2uf2 $(OUT)canboot.elf $(OUT)canboot.uf2
lib/rp2040_flash/rp2040_flash:
@echo " Building rp2040_flash"
$(Q)make -C lib/rp2040_flash rp2040_flash
# Flash rules
flash: $(OUT)klipper.uf2 lib/rp2040_flash/rp2040_flash
@echo " Flashing $< to $(FLASH_DEVICE)"
$(Q)$(PYTHON) ./scripts/flash_usb.py -t $(CONFIG_MCU) -d "$(FLASH_DEVICE)" $(if $(NOSUDO),--no-sudo) $(OUT)klipper.uf2
flash: $(OUT)canboot.uf2 lib/rp2040_flash/rp2040_flash
@echo " Flashing $< "
$(Q)./lib/rp2040_flash/rp2040_flash $(OUT)canboot.uf2
# Deployer build
deployer-y += generic/armcm_boot.c generic/armcm_reset.c $(mcu-y)
CFLAGS_deployer.elf += --specs=nano.specs --specs=nosys.specs
CFLAGS_deployer.elf += -T $(OUT)src/generic/armcm_deployer.ld
$(OUT)deployer.elf: $(OUT)src/generic/armcm_deployer.ld

135
src/rp2040/armcm_canboot.c Normal file
View File

@ -0,0 +1,135 @@
// CanBoot specific entry code for ARM Cortex-M vector table and bootup
//
// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include <string.h> // memcpy
#include "generic/armcm_boot.h" // DECL_ARMCM_IRQ
#include "autoconf.h" // CONFIG_MCU
#include "board/internal.h" // SysTick
#include "board/irq.h" // irq_disable
#include "board/misc.h" // get_bootup_code
#include "command.h" // DECL_CONSTANT_STR
// Export MCU type
DECL_CONSTANT_STR("MCU", CONFIG_MCU);
// Symbols created by armcm_link.lds.S linker script
extern uint32_t _data_start, _data_end, _data_flash;
extern uint32_t _bss_start, _bss_end, _stack_start;
extern uint32_t _stack_end;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
uint64_t
get_bootup_code(void)
{
uint64_t *req_code = (void*)&_stack_end;
return *req_code;
}
void
set_bootup_code(uint64_t code)
{
uint64_t *req_code = (void*)&_stack_end;
*req_code = code;
barrier();
}
#pragma GCC diagnostic pop
// Helper function to read area of flash
void
application_read_flash(uint32_t address, uint32_t *dest)
{
memcpy(dest, (void*)address, CONFIG_BLOCK_SIZE);
}
// Check if the application flash area looks valid
int
application_check_valid(void)
{
uint32_t *app = (void*)CONFIG_APPLICATION_START;
return *app != 0 && *app != 0xffffffff;
}
// Jump to the main application (exiting the bootloader)
void
application_jump(void)
{
irq_disable();
set_bootup_code(REQUEST_START_APP);
NVIC_SystemReset();
}
static void
start_application(void)
{
set_bootup_code(0);
uint32_t *vtor = (void*)CONFIG_APPLICATION_START;
SCB->VTOR = (uint32_t)vtor;
asm volatile("MSR msp, %0\n bx %1" : : "r"(vtor[0]), "r"(vtor[1]));
}
void __noreturn __visible
__attribute__((used, section(".reset_handler_flash.reset_handler_stage_two")))
reset_handler_stage_two(void)
{
// Copy global variables from flash to ram
uint32_t count = (&_data_end - &_data_start);
for(int i = 0; i < count; i++) {
(&_data_start)[i] = (&_data_flash)[i];
barrier();
}
// Clear the bss segment
count = (&_bss_end - &_bss_start);
for(int i = 0 ; i < count; i++ ) {
(&_bss_start)[i] = 0;
barrier();
}
SCB->VTOR = (uint32_t)VectorTable;
barrier();
//All data have been transferred to the ram.
//Now it is safe to call any function, not just in .reset_handler_flash.
// Initializing the C library isn't needed...
//__libc_init_array();
uint64_t bootup_code = get_bootup_code();
if (bootup_code == REQUEST_START_APP)
start_application();
// Run the main board specific code
armcm_main();
// The armcm_main() call should not return
for (;;)
;
}
// Initial code entry point - invoked by the processor after a reset
asm(".section .reset_handler_flash.ResetHandler\n"
".balign 8\n"
".8byte " __stringify(CANBOOT_SIGNATURE) "\n"
".global ResetHandler\n"
".type ResetHandler, %function\n"
"ResetHandler:\n"
" b reset_handler_stage_two\n"
);
extern void ResetHandler();
DECL_ARMCM_IRQ(ResetHandler, -15);
// Code called for any undefined interrupts
void
DefaultHandler(void)
{
for (;;)
;
}
const void *VectorTableFlash[32] __attribute__((used, section(".vector_table_flash"))) = {
&_stack_end,
ResetHandler
};

View File

@ -48,13 +48,9 @@ mask_to_pin(uint32_t mask)
struct gpio_out
gpio_out_setup(uint8_t pin, uint8_t val)
{
if (pin > 30)
goto fail;
struct gpio_out g = { .bit=1<<pin };
gpio_out_reset(g, val);
return g;
fail:
shutdown("Not an output pin");
}
void
@ -93,13 +89,9 @@ gpio_out_write(struct gpio_out g, uint8_t val)
struct gpio_in
gpio_in_setup(uint8_t pin, int8_t pull_up)
{
if (pin > 30)
goto fail;
struct gpio_in g = { .bit=1<<pin };
gpio_in_reset(g, pull_up);
return g;
fail:
shutdown("Not an input pin");
}
void

View File

@ -14,42 +14,6 @@
#include "internal.h" // enable_pclock
#include "sched.h" // sched_main
/****************************************************************
* watchdog handler
****************************************************************/
void
watchdog_reset(void)
{
watchdog_hw->load = 0x800000; // ~350ms
}
DECL_TASK(watchdog_reset);
void
watchdog_init(void)
{
watchdog_reset();
watchdog_hw->ctrl = (WATCHDOG_CTRL_PAUSE_DBG0_BITS
| WATCHDOG_CTRL_PAUSE_DBG1_BITS
| WATCHDOG_CTRL_PAUSE_JTAG_BITS
| WATCHDOG_CTRL_ENABLE_BITS);
}
DECL_INIT(watchdog_init);
/****************************************************************
* Bootloader
****************************************************************/
void
bootloader_request(void)
{
// Use the bootrom-provided code to reset into BOOTSEL mode
reset_to_usb_boot(0, 0);
}
/****************************************************************
* Clock setup
****************************************************************/
@ -163,6 +127,7 @@ clock_setup(void)
// Main entry point - called from armcm_boot.c:ResetHandler()
void
noinline
armcm_main(void)
{
clock_setup();

View File

@ -20,11 +20,9 @@ SECTIONS
.text : {
. = ALIGN(4);
KEEP(*(.boot2))
_text_vectortable_start = .;
KEEP(*(.vector_table))
_text_vectortable_end = .;
*(.text .text.*)
*(.rodata .rodata*)
KEEP(*(.vector_table_flash))
KEEP(*(.reset_handler_flash))
KEEP(*(.reset_handler_flash.*))
} > rom
. = ALIGN(4);
@ -32,8 +30,11 @@ SECTIONS
.data : AT (_data_flash)
{
. = ALIGN(4);
. = ALIGN(128);
_data_start = .;
KEEP(*(.vector_table))
*(.text .text.*)
*(.rodata .rodata*)
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
@ -50,7 +51,7 @@ SECTIONS
_bss_end = .;
} > ram
_stack_start = CONFIG_RAM_START + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE ;
_stack_start = CONFIG_RAM_START + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE - 1024;
.stack _stack_start (NOLOAD) :
{
. = . + CONFIG_STACK_SIZE;