From fbb5234497a9973f5ff7b884f838db16f6f4fab1 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Sun, 17 Nov 2024 02:30:38 +0100 Subject: [PATCH] Change set to produce a working blinky example This is a minimum viable set of changes to tinygo, to get a blinky example running. These should be broken into separate steps. The changes are roughly: * Remove the second stage bootloader because it has been replaced by the boot rom on the rp2040 * Add a minimum viable image desciptor to the binary, to allow the boot rom to recongize the binary as an application * Disable the peripheral resets because the hardware works differently than the RP2040 (need to re-evaluate this) * Skip PLL init because the boot rom should have enabled it. This should definitely be fixed and then re-enabled. * When enabling a GPIO pin, disable the isolation latch Only the GPIO hardware seems functional, the init routines should be improved before continuing with other peripherals. --- src/machine/machine_rp2.go | 2 +- src/machine/machine_rp2350_resets.go | 10 +++++----- src/machine/machine_rp2_2350.go | 2 ++ src/machine/machine_rp2_gpio.go | 4 +++- targets/arm.ld | 1 + targets/embedded_block.S | 11 +++++++++++ targets/pico2.json | 3 +-- targets/rp2350.json | 5 +++-- targets/rp2350.ld | 20 +++----------------- 9 files changed, 30 insertions(+), 28 deletions(-) create mode 100644 targets/embedded_block.S diff --git a/src/machine/machine_rp2.go b/src/machine/machine_rp2.go index 1d01866bd0..6b3b97e8c0 100644 --- a/src/machine/machine_rp2.go +++ b/src/machine/machine_rp2.go @@ -58,7 +58,7 @@ func machineInit() { bits = ^uint32(initUnreset) unresetBlockWait(bits) - clocks.init() +// clocks.init() // Peripheral clocks should now all be running unresetBlockWait(RESETS_RESET_Msk) diff --git a/src/machine/machine_rp2350_resets.go b/src/machine/machine_rp2350_resets.go index 830fc13468..c224cb754d 100644 --- a/src/machine/machine_rp2350_resets.go +++ b/src/machine/machine_rp2350_resets.go @@ -25,20 +25,20 @@ var resets = (*resetsType)(unsafe.Pointer(rp.RESETS)) // resetBlock resets hardware blocks specified // by the bit pattern in bits. func resetBlock(bits uint32) { - resets.frceOff.Set(bits) +// resets.frceOff.Set(bits) } // unresetBlock brings hardware blocks specified by the // bit pattern in bits out of reset. func unresetBlock(bits uint32) { - resets.frceOn.Set(bits) +// resets.frceOn.Set(bits) } // unresetBlockWait brings specified hardware blocks // specified by the bit pattern in bits // out of reset and wait for completion. func unresetBlockWait(bits uint32) { - unresetBlock(bits) - for !resets.resetDone.HasBits(bits) { - } +// unresetBlock(bits) +// for !resets.resetDone.HasBits(bits) { +// } } diff --git a/src/machine/machine_rp2_2350.go b/src/machine/machine_rp2_2350.go index adb75f0090..a9d61f817c 100644 --- a/src/machine/machine_rp2_2350.go +++ b/src/machine/machine_rp2_2350.go @@ -7,6 +7,8 @@ import ( "unsafe" ) +var DefaultUART = UART0 + const ( LED = GPIO25 _NUMBANK0_GPIOS = 48 diff --git a/src/machine/machine_rp2_gpio.go b/src/machine/machine_rp2_gpio.go index 4f3765845c..2dd3526da1 100644 --- a/src/machine/machine_rp2_gpio.go +++ b/src/machine/machine_rp2_gpio.go @@ -126,7 +126,7 @@ func (p Pin) setSchmitt(trigger bool) { func (p Pin) setFunc(fn pinFunc) { // Set input enable, Clear output disable p.padCtrl().ReplaceBits(rp.PADS_BANK0_GPIO0_IE, - rp.PADS_BANK0_GPIO0_IE_Msk|rp.PADS_BANK0_GPIO0_OD_Msk, 0) + rp.PADS_BANK0_GPIO0_IE_Msk|rp.PADS_BANK0_GPIO0_OD_Msk|rp.PADS_BANK0_GPIO0_ISO_Msk, 0) // Zero all fields apart from fsel; we want this IO to do what the peripheral tells it. // This doesn't affect e.g. pullup/pulldown, as these are in pad controls. @@ -136,7 +136,9 @@ func (p Pin) setFunc(fn pinFunc) { // init initializes the gpio pin func (p Pin) init() { mask := uint32(1) << p + rp.SIO.GPIO_OE_CLR.Set(mask) + p.clr() } diff --git a/targets/arm.ld b/targets/arm.ld index 39b5c75ddb..07548cb87f 100644 --- a/targets/arm.ld +++ b/targets/arm.ld @@ -9,6 +9,7 @@ SECTIONS .text : { KEEP(*(.isr_vector)) + KEEP(*(.embedded_block)) *(.text) *(.text.*) *(.rodata) diff --git a/targets/embedded_block.S b/targets/embedded_block.S new file mode 100644 index 0000000000..e32918b3f5 --- /dev/null +++ b/targets/embedded_block.S @@ -0,0 +1,11 @@ +// Inspired by embedded_start_block.inc.S and embedded_end_block.inc.S +// Minimum viable block image from datasheet section 5.9.5.1, "Minimum Arm IMAGE_DEF" +.section .embedded_block, "a" +.p2align 2 +embedded_block: +.word 0xffffded3 +.word 0x10210142 +.word 0x000001ff +.word 0x00000000 +.word 0xab123579 +embedded_block_end: diff --git a/targets/pico2.json b/targets/pico2.json index 13f07e18cb..dbee33ccbd 100644 --- a/targets/pico2.json +++ b/targets/pico2.json @@ -3,8 +3,7 @@ "rp2350" ], "build-tags": ["pico2"], - "linkerscript": "targets/pico2.ld", + "linkerscript": "targets/rp2350.ld", "extra-files": [ - "targets/pico_boot_stage2.S" ] } diff --git a/targets/rp2350.json b/targets/rp2350.json index 0f6e5fb4e9..0d31702152 100644 --- a/targets/rp2350.json +++ b/targets/rp2350.json @@ -8,9 +8,10 @@ "msd-firmware-name": "firmware.uf2", "binary-format": "uf2", "uf2-family-id": "0xe48bff59","comment":"See page 393 of RP2350 datasheet: RP2350 Arm Secure image (i.e. one intended to be booted directly by the bootrom)", - "rp2040-boot-patch": true, "extra-files": [ - "targets/rp2350_boot2_generic03h.S" + "src/device/rp/rp2350.s", + "targets/rp2350_boot2_generic03h.S", + "targets/embedded_block.S" ], "linkerscript": "targets/rp2350.ld", "openocd-interface": "picoprobe", diff --git a/targets/rp2350.ld b/targets/rp2350.ld index 95fe3bbeee..b73711aa05 100644 --- a/targets/rp2350.ld +++ b/targets/rp2350.ld @@ -10,9 +10,9 @@ MEMORY i.e: Separate stacks for core0 and core1. */ SRAM4 : ORIGIN = 0x20080000, LENGTH = 4k SRAM5 : ORIGIN = 0x20081000, LENGTH = 4k - /* Reserve exactly 256 bytes at start of flash for second stage bootloader */ - BOOT2_TEXT (rx) : ORIGIN = 0x10000000, LENGTH = 256 - FLASH_TEXT (rx) : ORIGIN = 0x10000000 + 256, LENGTH = 2048k - 256 + FLASH_TEXT (rx) : ORIGIN = 0x10000000, LENGTH = 2048k + + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 512k } @@ -20,20 +20,6 @@ _stack_size = 2K; SECTIONS { - /* Second stage bootloader is prepended to the image. It must be 256 bytes - and checksummed. The gap to the checksum is zero-padded. - */ - .boot2 : { - __boot2_start__ = .; - KEEP (*(.boot2)); - - /* Explicitly allocate space for CRC32 checksum at end of second stage - bootloader - */ - . = __boot2_start__ + 256 - 4; - LONG(0) - } > BOOT2_TEXT = 0x0 - /* The second stage will always enter the image at the start of .text. The debugger will use the ELF entry point, which is the _entry_point symbol if present, otherwise defaults to start of .text.