Add assembly bare metal blink examble for rp2350.
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
parent
3a571e61b4
commit
1e0a36f7b3
5 changed files with 231 additions and 0 deletions
29
bare_metal/rp2350/blink/Makefile
Normal file
29
bare_metal/rp2350/blink/Makefile
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
CC=arm-none-eabi-gcc
|
||||||
|
MACH=cortex-m33
|
||||||
|
CFLAGS= -c -mcpu=$(MACH) -mthumb -std=gnu11 -Wall -O0
|
||||||
|
LFLAGS= -nostdlib -T pico_plus_2.ld -Wl,-Map=final.map
|
||||||
|
|
||||||
|
assemble: vectors.o hello_world.o min_arm_image_def.o
|
||||||
|
|
||||||
|
vectors.o: vectors.s
|
||||||
|
$(CC) $(CFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
hello_world.o: hello_world.s
|
||||||
|
$(CC) $(CFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
min_arm_image_def.o: min_arm_image_def.s
|
||||||
|
$(CC) $(CFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
hello_world.elf: vectors.o hello_world.o min_arm_image_def.o
|
||||||
|
$(CC) $(LFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
clean:
|
||||||
|
- rm -rf $(wildcard *.o)
|
||||||
|
- rm -rf $(wildcard *.elf)
|
||||||
|
- rm -rf $(wildcard *.map)
|
||||||
|
|
||||||
|
link: hello_world.elf
|
||||||
|
|
||||||
|
PHONY: flash
|
||||||
|
flash:
|
||||||
|
sudo openocd -s tcl -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" -c "program hello_world.elf verify reset exit"
|
||||||
79
bare_metal/rp2350/blink/hello_world.s
Normal file
79
bare_metal/rp2350/blink/hello_world.s
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
.equ rst_base, 0x40020000 // Subsystems reset reg base 7.5.3
|
||||||
|
.equ rst_clr, 0x40023000 // Adding 0x3000 according 2.1.3
|
||||||
|
.equ io_bank, 0x40028000
|
||||||
|
.equ io_bank_gp25, 0x400280cc
|
||||||
|
.equ sio_base, 0xd0000000
|
||||||
|
.equ big_num, 0x00f00000 // For the delay.
|
||||||
|
.equ pads_base, 0x40038000 // Pad control registers base.
|
||||||
|
.equ pads_set, 0x4003a000
|
||||||
|
.equ pads_clr, 0x4003b000
|
||||||
|
.equ resets_wrd, 0b100001001000000 // Bits 14 (PLL_SYS), 9 (PADS_BANK0) and 6 (IO_BANK0)
|
||||||
|
|
||||||
|
.thumb_func // This makes sure that the address of start has its LSB set to signal thumb mode.
|
||||||
|
.global hello_start
|
||||||
|
hello_start:
|
||||||
|
// Bring PLL, PADS and IO out of reset
|
||||||
|
ldr r0, =rst_clr
|
||||||
|
ldr r2, =resets_wrd
|
||||||
|
str r2, [r0, #0]
|
||||||
|
check_rst:
|
||||||
|
ldr r0, =rst_base
|
||||||
|
ldr r1, [r0, #0x8] // Offset to RESET_DONE from rst_base
|
||||||
|
and r1, r1, r2 // Check bit 14, 9 and 6 to ensure the subsystems we care about are out of reset.
|
||||||
|
cmp r1, r2
|
||||||
|
bne check_rst
|
||||||
|
clocks_setup:
|
||||||
|
// TODO: Configure the crystal oscilator and set it as the reference clock.
|
||||||
|
// TODO: Configure the PLL and wait for it to lock.
|
||||||
|
// TODO: Change the sys clock source to the PLL.
|
||||||
|
configure_peripheral:
|
||||||
|
// See: https://github.com/raspberrypi/pico-sdk/blob/ee68c78d0afae2b69c03ae1a72bf5cc267a2d94c/src/rp2_common/hardware_gpio/gpio.c#L38
|
||||||
|
// Set pad input and output enabled.
|
||||||
|
ldr r0, =pads_set
|
||||||
|
mov r2, #0b1000000 // Set bit 6 to enable input.
|
||||||
|
str r2, [r0, #0x68]
|
||||||
|
ldr r0, =pads_clr
|
||||||
|
mov r2, #0b10000000 // Clear bit 7 to enable output.
|
||||||
|
str r2, [r0, #0x68]
|
||||||
|
// Set function 5 (SIO) to GPIO25
|
||||||
|
ldr r0, =io_bank_gp25
|
||||||
|
mov r1, #5 // FSEL 5 (SIO)
|
||||||
|
str r1, [r0]
|
||||||
|
// Remove isolation control on the pad control now that it's connected to its peripheral (SIO).
|
||||||
|
ldr r0, =pads_clr
|
||||||
|
mov r2, #1 // Clear bit 8 to remove isolation control.
|
||||||
|
lsl r2, r2, #8
|
||||||
|
str r2, [r0, #0x68]
|
||||||
|
// Enable the output
|
||||||
|
ldr r0, =sio_base
|
||||||
|
mov r1, #1
|
||||||
|
lsl r1, r1, #25 // Only enable gpio25
|
||||||
|
str r1, [r0, #0x38] // GPIO_OE_SET offset
|
||||||
|
blink:
|
||||||
|
ldr r0, =sio_base
|
||||||
|
mov r1, #1
|
||||||
|
lsl r1, r1, #25
|
||||||
|
led_loop:
|
||||||
|
str r1, [r0, #0x18] // GPIO_OUT_SET
|
||||||
|
ldr r3, =big_num
|
||||||
|
bl delay
|
||||||
|
|
||||||
|
str r1, [r0, #0x20] // GPIO_OUT_CLR
|
||||||
|
ldr r3, =big_num
|
||||||
|
bl delay
|
||||||
|
|
||||||
|
b led_loop
|
||||||
|
|
||||||
|
delay:
|
||||||
|
sub r3, #1
|
||||||
|
bne delay
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
// An interrupt handler that just spins.
|
||||||
|
.thumb_func
|
||||||
|
.global isr_default
|
||||||
|
isr_default:
|
||||||
|
b isr_default
|
||||||
|
|
||||||
37
bare_metal/rp2350/blink/min_arm_image_def.s
Normal file
37
bare_metal/rp2350/blink/min_arm_image_def.s
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Mete Balci
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
// ref: RP2350 datasheet 5.9.5.1. Minimum Arm IMAGE_DEF
|
||||||
|
|
||||||
|
// this is a single block with two items (IMAGE_TYPE and LAST) in it
|
||||||
|
|
||||||
|
// include this section in linker description in the first 4K of a flash image
|
||||||
|
.section .picobin_block, "a"
|
||||||
|
|
||||||
|
.word 0xffffded3 // PICOBIN_BLOCK_MARKER_START
|
||||||
|
|
||||||
|
// item 0 IMAGE_TYPE
|
||||||
|
|
||||||
|
.byte 0x42 // PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE
|
||||||
|
.byte 0x1 // item is 1 word
|
||||||
|
// Try Before You Buy - 0 (not set)
|
||||||
|
// Chip - b001 (RP2350)
|
||||||
|
// reserved - 0b0
|
||||||
|
// CPU - b000 (ARM)
|
||||||
|
// reserved - 0b00
|
||||||
|
// EXE Security - 0b10 (Secure mode)
|
||||||
|
// Image Type - 0b0001 (EXE)
|
||||||
|
.hword 0b0001000000100001
|
||||||
|
|
||||||
|
// item 1 LAST
|
||||||
|
|
||||||
|
.byte 0xff // PICOBIN_BLOCK_ITEM_2BS_LAST
|
||||||
|
.hword 0x0001 // item is 1 word
|
||||||
|
.byte 0 // pad
|
||||||
|
|
||||||
|
// relative pointer to next block in loop
|
||||||
|
// 0 means a link to itself, meaning there is no other block
|
||||||
|
.word 0
|
||||||
|
|
||||||
|
.word 0xab123579 // PICOBIN_BLOCK_MARKER_END
|
||||||
63
bare_metal/rp2350/blink/pico_plus_2.ld
Normal file
63
bare_metal/rp2350/blink/pico_plus_2.ld
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Minimal version of:
|
||||||
|
* - https://github.com/raspberrypi/pico-sdk/blob/ee68c78d0afae2b69c03ae1a72bf5cc267a2d94c/src/rp2_common/pico_crt0/rp2350/memmap_default.ld
|
||||||
|
* - https://github.com/raspberrypi/pico-sdk/blob/ee68c78d0afae2b69c03ae1a72bf5cc267a2d94c/src/rp2_common/pico_standard_link/pico_flash_region.template.ld
|
||||||
|
* - https://github.com/raspberrypi/pico-sdk/blob/ee68c78d0afae2b69c03ae1a72bf5cc267a2d94c/src/boards/include/boards/pimoroni_pico_plus2_rp2350.h#L88C1-L88C49
|
||||||
|
*
|
||||||
|
* Provides the following symbols to be used in assembly:
|
||||||
|
* - __StackTop
|
||||||
|
*/
|
||||||
|
__XIP_BASE = 0x10000000;
|
||||||
|
__XIP_SIZE = 16M; /* 16M is allocated to QSPI flash for the pico 2 plus */
|
||||||
|
|
||||||
|
__SRAM_BASE = 0x20000000;
|
||||||
|
__SRAM_SIZE = 512K;
|
||||||
|
|
||||||
|
__SCRATCH_X_BASE = 0x20080000;
|
||||||
|
__SCRATCH_Y_BASE = 0x20081000;
|
||||||
|
__SCRATCH_SIZE = 4K; /* Both scratch regions have the same size */
|
||||||
|
|
||||||
|
/* Memories */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = __XIP_BASE, LENGTH = __XIP_SIZE
|
||||||
|
RAM (rwx) : ORIGIN = __SRAM_BASE, LENGTH = __SRAM_SIZE
|
||||||
|
SCRATCH_X(rwx) : ORIGIN = __SCRATCH_X_BASE, LENGTH = __SCRATCH_SIZE
|
||||||
|
SCRATCH_Y(rwx) : ORIGIN = __SCRATCH_Y_BASE, LENGTH = __SCRATCH_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is to eliminate RWX permission error for text segment */
|
||||||
|
/* I don't think it's necessary */
|
||||||
|
/* PHDRS
|
||||||
|
{
|
||||||
|
text PT_LOAD FLAGS(5);
|
||||||
|
data PT_LOAD FLAGS(6);
|
||||||
|
bss PT_LOAD FLAGS(6);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Sections */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text : {
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
. = ALIGN(512); /* See https://forums.raspberrypi.com/viewtopic.php?t=387420 Quote: "So, in the RP2350 Cortex M33 with 16 internal exception vectors and 52 interrupts, the alignment must be 512 bytes. (16+52)x4 = 272, next power of two = 512" */
|
||||||
|
KEEP(*(.picobin_block))
|
||||||
|
*(.text)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
__data_start__ = .;
|
||||||
|
*(.data*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__data_end__ = .;
|
||||||
|
} > RAM /* AT > FLASH :data */ /* See: https://stackoverflow.com/questions/28809372/what-does-region1-at-region2-mean-in-an-ld-linker-script */
|
||||||
|
|
||||||
|
|
||||||
|
/* stack limit is poorly named, but historically is maximum heap ptr */
|
||||||
|
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); /* Used for core 0 */
|
||||||
|
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); /* Used for core 1 */
|
||||||
|
|
||||||
|
}
|
||||||
23
bare_metal/rp2350/blink/vectors.s
Normal file
23
bare_metal/rp2350/blink/vectors.s
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Based on https://github.com/raspberrypi/pico-sdk/blob/ee68c78d0afae2b69c03ae1a72bf5cc267a2d94c/src/rp2_common/pico_crt0/crt0.S
|
||||||
|
.section .vectors, "ax"
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
.global __vectors, __VECTOR_TABLE
|
||||||
|
__VECTOR_TABLE:
|
||||||
|
__vectors:
|
||||||
|
.word __StackTop
|
||||||
|
.word hello_start
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
|
.word isr_default
|
||||||
Loading…
Add table
Add a link
Reference in a new issue