rp2040

RP2040 Programming without SDK
Log | Files | Refs

commit 5b7a041b5df9da1add8515038342aa1a15d5d0b4
parent 78c59f4a1b6b2f3101551b20ee5f77ae30d97cf9
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 18 Apr 2023 11:05:44 +0900

use C to reprogram flash

Diffstat:
Mflash.s | 67++++++++++++++++++++++++++++++++++++++++++++++---------------------
Mmach.s | 10++++++++++
Mmain.c | 18++++++++++++++++++
3 files changed, 74 insertions(+), 21 deletions(-)

diff --git a/flash.s b/flash.s @@ -7,9 +7,11 @@ // erase the region of flash starting at ofs and size bytes long in size. // ofs must be aligned in 4K and size must be multiple of 4K frerase: - push {r4, lr} + push {r4, r5, r6, r7, lr} ldr r4, rom_base + mov r5, r0 + mov r6, r1 ldrh r0, [r4, #0x14] // rom_func_table ldr r1, =('I' | 'F' << 8) // _connect_internal_flash() @@ -27,13 +29,13 @@ frerase: ldr r1, =('R' | 'E' << 8) // _flash_range_erase() ldrh r2, [r4, #0x18] // rom_table_lookup blx r2 - mov r5, r0 - mov r0, #0 - mov r1, #1 - lsl r1, r1, #12 - lsl r2, r1, #4 - mov r3, #0xd8 - blx r5 + mov r7, r0 + mov r0, r5 + mov r1, r6 + mov r2, #1 + lsl r2, r2, #16 // 64K + mov r3, #0xd8 // block erase + blx r7 ldrh r0, [r4, #0x14] // rom_func_table ldr r1, =('F' | 'C' << 8) // _flash_flush_cache() @@ -42,19 +44,44 @@ frerase: blx r0 ldrh r0, [r4, #0x14] // rom_func_table - ldr r1, =('R' | 'P' << 8) // _flash_enter_cmd_xip() + ldr r1, =('C' | 'X' << 8) // _flash_enter_cmd_xip() + ldrh r2, [r4, #0x18] // rom_table_lookup + blx r2 + blx r0 + + pop {r4, r5, r6, r7, pc} + + .global frprog + // void frprog(uint32_t ofs, uint8_t *data, size_t count); + // ofs must be aligned in 256 and data must be multiple of 256 +frprog: + push {r4, r5, r6,r7, lr} + + ldr r4, rom_base + mov r5, r0 + mov r6, r1 + mov r7, r2 + + ldrh r0, [r4, #0x14] // rom_func_table + ldr r1, =('I' | 'F' << 8) // _connect_internal_flash() + ldrh r2, [r4, #0x18] // rom_table_lookup + blx r2 + blx r0 + + ldrh r0, [r4, #0x14] // rom_func_table + ldr r1, =('E' | 'X' << 8) // _flash_exit_xip() + ldrh r2, [r4, #0x18] // rom_table_lookup + blx r2 + blx r0 + + ldrh r0, [r4, #0x14] // rom_func_table + ldr r1, =('R' | 'P' << 8) // _flash_range_program() ldrh r2, [r4, #0x18] // rom_table_lookup blx r2 mov r3, r0 - mov r0, #0 - ldr r1, sram_base - mov r2, #1 - lsl r2, r2, #12 - add r1, r1, r2 - ldr r2, =0xdeadbeef - str r2, [r1, #0] - mov r2, #1 - lsl r2, r2, #8 + mov r0, r5 + mov r1, r6 + mov r2, r7 blx r3 ldrh r0, [r4, #0x14] // rom_func_table @@ -69,9 +96,7 @@ frerase: blx r2 blx r0 - ldr r3, xip_base - ldr r0, [r3, #0] - bl printh + pop {r4, r5, r6, r7, pc} .align 2 rom_base: diff --git a/mach.s b/mach.s @@ -228,6 +228,16 @@ printh_high: bge printh_loop pop {r4, r5, r6, pc} + + .global ldr + // uint32_t ldr(uint32_t addr) + // load content at addr +ldr: + ldr r0, [r0, #0] + bx lr + + + led_pr: // print register with 2 leds push {r0, r1, r2, r4, lr} diff --git a/main.c b/main.c @@ -1,10 +1,28 @@ +#include <stdint.h> +#include <stddef.h> + extern void init(void); extern void led_p2(void); +extern void frerase(uint32_t, size_t); +extern void frprog(uint32_t, uint8_t *, size_t); +extern uint32_t ldr(uint32_t); +extern void printh(uint32_t); +extern void putchar(char); int main(void) { + uint32_t ofs = 4 * 1024; + size_t size = 4 * 1024; + size_t count = 256; + uint8_t data[count]; + for (int i = 0; i < count; i++) + data[i] = 0xde; init(); + frerase(ofs, size); + frprog(ofs, data, count); + printh(ldr(0x10001000)); + putchar('\n'); while(1) { led_p2(); }