rp2040

RP2040 Programming without SDK
Log | Files | Refs

commit 4bd1aedd867266f7f05e28b8edbba3ceac9b6d62
parent e4552941012ea76bbfebbcd9d88f18c40287650b
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Fri, 14 Apr 2023 11:50:54 +0900

make something which doesn't work

Diffstat:
Aboot2_sram.s | 152+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmach.s | 61++++++++++++++++++++++++++++++-------------------------------
2 files changed, 182 insertions(+), 31 deletions(-)

diff --git a/boot2_sram.s b/boot2_sram.s @@ -0,0 +1,152 @@ +// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd. +// SPDX-License-Identifier: BSD-3-Clause + +.cpu cortex-m0plus +.thumb + + .section .boot2 + .global setup_ssi + .thumb_func +setup_ssi: + push {r4, r5, r6, r7, lr} + + // setup QSPI pad + ldr r4, pads_qspi_base + ldr r1, =(0 << 4 | 0 << 1 | 1) // 2mA, schmitt off, slew fast + str r1, [r4, #0x4] // PADS_QSPI: GPIO_QSPI_SCLK + + // r4 should not be changed from this point on + ldr r4, xip_ssi_base + + // set SSI standard SPI + // disable SSI + mov r1, #0 + str r1, [r4, #0x8] // SSI: SSIENR + //set divider + mov r1, #0x2 + str r1, [r4, #0x14] // SSI: BAUDR + // set 1-cycle sample delay. + mov r1, #1 + mov r2, #0xf0 + str r1, [r4, r2] // SSI: RX_SAMPLE_DLY + // setup SSI + ldr r1, =(7 << 16 | 3 << 8) // 8bit data frame size, eeprom + str r1, [r4, #0] // SSI: CTRLR0 + mov r1, #0 // NDF = 0 + str r1, [r4, #0x4] // SSI: CTRLR1 + // enable SSI + mov r1, #1 + str r1, [r4, #0x8] // SSI: SSIENR + + // set flash QSPI + // write enable + mov r1, #0x06 // write enable + str r1, [r4, #0x60] // SSI: DR0 + bl wait_ssi + ldr r1, [r4, #0x60] // SSI: DR0 + // enable QSPI + mov r1, #0x31 // write status register-2 + str r1, [r4, #0x60] // SSI: DR0 + mov r1, #0x2 // quad enable + str r1, [r4, #0x60] // SSI: DR0 + bl wait_ssi + ldr r1, [r4, #0x60] // SSI: DR0 + ldr r1, [r4, #0x60] // SSI: DR0 +wait_sreg: + mov r1, #0x5 // read status register-1 + // This str is required twice if TMOD = 0. + // In this case, /CS signal is set to high just + // after the first str instruction and the flash + // doesn't shift out the status register. + // On the other hand, If TMOD = 3 (eeprom), + // then the /CS is kept to low until NDF + 1 + // data frames are captured. + // Shiran Kedo. + str r1, [r4, #0x60] // SSI: DR0 + bl wait_ssi + ldr r1, [r4, #0x60] // SSI: DR0 + mov r2, #1 // BUSY flag + tst r1, r2 + bne wait_sreg + + // set SSI QSPI + // disable SSI + mov r1, #0 + str r1, [r4, #0x8] // SSI: SSIENR + // set up QSPI + // DFS is said to be the number of clocks of a data frame - 1. + // But in QSPI mode, a frame is 32 bits and is transfered in 8 clocks. + // However, if DFS is set to 7, It doesn't work. + // Maybe this is a bug of the documentation. + ldr r1, =(2 << 21 | 31 << 16 | 3 << 8) // quad, 32bit data frame, eeprom + str r1, [r4, #0] // SSI: CTRLR0 + ldr r1, =(4 << 11 | 2 << 8 | 6 << 2 | 1 << 0) + mov r2, #0xf4 + str r1, [r4, r2] // SSI: SPI_CTRLR0 + // re-enable SSI + mov r1, #1 + str r1, [r4, #0x8] // SSI: SSIENR + + // this code should be rewritten using dma. + mov r5, #0xeb + lsl r5, r5, #24 + ldr r6, boot2_end + lsl r6, r6, #8 + lsr r6, r6, #8 + add r5, r5, r6 // flash read command + ldr r6, sram_base // sram dst address + ldr r7, etext + sub r7, r0, r3 + lsr r7, #2 // counter +sram_cpy: + str r5, [r4, #0x60] // SSI: DR0 + bl wait_ssi + ldr r0, [r4, #0x60] // SSI: DR0 + str r0, [r6, #0] + add r5, r5, #0x4 + add r6, r6, #0x4 + sub r7, r7, #0x1 + bne sram_cpy + + // exit from boot2 + pop {r4, r5, r6, r7} + pop {r0} + cmp r0, #0 + beq initial_boot + bx r0 +initial_boot: + ldr r0, sram_base + ldr r1, m0plus_vtor + str r0, [r1, #0] // M0PLUS: VTOR + ldr r1, [r0, #4] // entry point + ldr r0, [r0, #0] // stack pointer + mov sp, r0 + bx r1 + +wait_ssi: + // asumes that r4 is xip_ssi_base + ldr r1, [r4, #0x28] // SSI: SR + mov r2, #4 // TFE + tst r1, r2 + beq wait_ssi + mov r2, #1 // BUSY + tst r1, r2 + bne wait_ssi + bx lr + + .align 2 +boot2_end: + .word 0x10000000 + 0x100 +xip_ssi_base: + .word 0x18000000 +sram_base: + .word 0x20000000 +pads_qspi_base: + .word 0x40020000 +m0plus_vtor: + .word 0xe0000000 + 0xed08 +etext: + .word _etext +literals: + .ltorg + diff --git a/mach.s b/mach.s @@ -16,7 +16,7 @@ hang: .global init .thumb_func init: - push {lr} + push {r4, lr} // unreset gpio and pll_sys and uart0 mov r1, #1 lsl r0, r1, #5 // io_bank0 @@ -134,54 +134,53 @@ pll_lock: lsl r1, r1, #5 str r1, [r0, #0x2c] // UART0_UARTLCR_H + ldr r0, =(0 << 21 | 32 << 16 | 3 << 8) // SSI: CTRLR0 + ldr r1, =(0x0 << 24 | 0 << 11 | 0 << 8 | 0 << 2 | 0) // SSI: SPI_CTRLR0 + bl setup_ssi bl exit_xip - ldr r3, xip_ssi_base + ldr r4, xip_ssi_base - mov r1, #0x06 // write enable - str r1, [r3, #0x60] // SSI: DR0 - bl wait_ssi - bl ssi_drain + ldr r0, =(0 << 21 | 32 << 16 | 3 << 8) // SSI: CTRLR0 + ldr r1, =(0x0 << 24 | 0 << 11 | 0 << 8 | 0 << 2 | 0) // SSI: SPI_CTRLR0 + bl setup_ssi + + mov r0, #0x03 + lsl r0, r0, #24 + str r0, [r4, #0x60] // SSI: DR0 - mov r1, #0x05 // read status register-1 - str r1, [r3, #0x60] // SSI: DR0 bl wait_ssi bl ssi_print - mov r1, #0x35 // read status register-2 + + pop {r4, pc} + +exit_xip: + push {lr} + mov r1, #0 + str r1, [r3, #0x60] // SSI: DR0 + str r1, [r3, #0x60] // SSI: DR0 str r1, [r3, #0x60] // SSI: DR0 - bl wait_ssi - bl ssi_print - mov r1, #0x15 // read status register-3 str r1, [r3, #0x60] // SSI: DR0 bl wait_ssi - bl ssi_print - + bl ssi_drain pop {pc} -exit_xip: +setup_ssi: push {lr} - ldr r3, xip_ssi_base // disable ssi - mov r1, #0 - str r1, [r3, #0x8] // SSI: SSIENR - ldr r1, =(0 << 21 | 7 << 16 | 3 << 8) - str r1, [r3, #0] // SSI: CTRLR0 - mov r1, #0 // NDF - str r1, [r3, #4] // SSI: CTRLR1 + mov r2, #0 + str r2, [r3, #0x8] // SSI: SSIENR + // setup SSI + str r0, [r3, #0] // SSI: CTRLR0 + mov r2, #0 // NDF + str r2, [r3, #4] // SSI: CTRLR1 // setup SPI - ldr r1, =(0x0 << 24 | 0 << 11 | 2 << 8 | 0 << 2 | 0) mov r2, #0xf4 str r1, [r3, r2] // SSI: SPI_CTRLR0 // reenable SSI - mov r1, #1 - str r1, [r3, #0x8] // SSI: SSIENR - // exit xip mode - mov r1, #0x00 - str r1, [r3, #0x60] // SSI: DR0 - bl wait_ssi - bl ssi_drain - + mov r2, #1 + str r2, [r3, #0x8] // SSI: SSIENR pop {pc} wait_ssi: