rp2040: support Adafruit Feather RP2040
Этот коммит содержится в:
родитель
1913cb76a5
коммит
8e33f1c9eb
9 изменённых файлов: 145 добавлений и 27 удалений
2
Makefile
2
Makefile
|
@ -358,6 +358,8 @@ smoketest:
|
|||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=pico examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=feather-rp2040 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
# test pwm
|
||||
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm
|
||||
@$(MD5SUM) test.hex
|
||||
|
|
|
@ -43,7 +43,7 @@ See the [getting started instructions](https://tinygo.org/getting-started/) for
|
|||
|
||||
You can compile TinyGo programs for microcontrollers, WebAssembly and Linux.
|
||||
|
||||
The following 62 microcontroller boards are currently supported:
|
||||
The following 63 microcontroller boards are currently supported:
|
||||
|
||||
* [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333)
|
||||
* [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333)
|
||||
|
@ -52,6 +52,7 @@ The following 62 microcontroller boards are currently supported:
|
|||
* [Adafruit Feather M4](https://www.adafruit.com/product/3857)
|
||||
* [Adafruit Feather M4 CAN](https://www.adafruit.com/product/4759)
|
||||
* [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
|
||||
* [Adafruit Feather RP2040](https://www.adafruit.com/product/4884)
|
||||
* [Adafruit Feather STM32F405 Express](https://www.adafruit.com/product/4382)
|
||||
* [Adafruit Grand Central M4](https://www.adafruit.com/product/4064)
|
||||
* [Adafruit ItsyBitsy M0](https://www.adafruit.com/product/3727)
|
||||
|
|
10
src/machine/board_feather_rp2040.go
Обычный файл
10
src/machine/board_feather_rp2040.go
Обычный файл
|
@ -0,0 +1,10 @@
|
|||
// +build feather_rp2040
|
||||
|
||||
package machine
|
||||
|
||||
const (
|
||||
LED = GPIO13
|
||||
|
||||
// Onboard crystal oscillator frequency, in MHz.
|
||||
xoscFreq = 12 // MHz
|
||||
)
|
17
targets/feather-rp2040-boot-stage2.S
Обычный файл
17
targets/feather-rp2040-boot-stage2.S
Обычный файл
|
@ -0,0 +1,17 @@
|
|||
// Adafruit Feather RP2040 Stage 2 Bootloader
|
||||
|
||||
//
|
||||
// This file defines the parameters specific to the flash-chip found
|
||||
// on the Adafruit Feather RP2040. The generic implementation is in
|
||||
// rp2040-boot-stage2.S
|
||||
//
|
||||
|
||||
#define BOARD_PICO_FLASH_SPI_CLKDIV 2
|
||||
#define BOARD_CMD_READ 0xe7
|
||||
#define BOARD_QUAD_OK 1
|
||||
#define BOARD_QUAD_ENABLE_STATUS_BYTE 2
|
||||
#define BOARD_QUAD_ENABLE_BIT_MASK 2
|
||||
#define BOARD_SPLIT_STATUS_WRITE 1
|
||||
#define BOARD_WAIT_CYCLES 2
|
||||
|
||||
#include "rp2040-boot-stage2.S"
|
10
targets/feather-rp2040.json
Обычный файл
10
targets/feather-rp2040.json
Обычный файл
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"inherits": [
|
||||
"rp2040"
|
||||
],
|
||||
"build-tags": ["feather_rp2040"],
|
||||
"linkerscript": "targets/feather-rp2040.ld",
|
||||
"extra-files": [
|
||||
"targets/feather-rp2040-boot-stage2.S"
|
||||
]
|
||||
}
|
10
targets/feather-rp2040.ld
Обычный файл
10
targets/feather-rp2040.ld
Обычный файл
|
@ -0,0 +1,10 @@
|
|||
|
||||
MEMORY
|
||||
{
|
||||
/* 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 = 8192K - 256
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256k
|
||||
}
|
||||
|
||||
INCLUDE "targets/rp2040.ld"
|
17
targets/pico-boot-stage2.S
Обычный файл
17
targets/pico-boot-stage2.S
Обычный файл
|
@ -0,0 +1,17 @@
|
|||
// Raspberry Pi Pico Stage 2 Bootloader
|
||||
|
||||
//
|
||||
// This file defines the parameters specific to the flash-chip found
|
||||
// on the official Pico boards. The generic implementation is in
|
||||
// rp2040-boot-stage2.S
|
||||
//
|
||||
|
||||
#define BOARD_PICO_FLASH_SPI_CLKDIV 2
|
||||
#define BOARD_CMD_READ 0xeb
|
||||
#define BOARD_QUAD_OK 1
|
||||
#define BOARD_QUAD_ENABLE_STATUS_BYTE 2
|
||||
#define BOARD_QUAD_ENABLE_BIT_MASK 2
|
||||
#define BOARD_SPLIT_STATUS_WRITE 0
|
||||
#define BOARD_WAIT_CYCLES 4
|
||||
|
||||
#include "rp2040-boot-stage2.S"
|
|
@ -5,6 +5,6 @@
|
|||
"build-tags": ["pico"],
|
||||
"linkerscript": "targets/pico.ld",
|
||||
"extra-files": [
|
||||
"targets/pico_boot_stage2.S"
|
||||
"targets/pico-boot-stage2.S"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
//
|
||||
// Implementation of Pico stage 2 boot loader. This code is for the Winbond W25Q080
|
||||
// (as found in the Pico) from the official Pico SDK.
|
||||
// Implementation of RP2040 stage 2 boot loader. This code is derived from the
|
||||
// Winbond W25Q080 implementation (as found in the Pico) in the official Pico SDK.
|
||||
//
|
||||
// This implementation has been made 'stand-alone' by including necessary code /
|
||||
// symbols from the included files in the reference implementation directly into
|
||||
// the source. Care has been taken to preserve ordering and it has been verified
|
||||
// the generated binary is byte-for-byte identical to the reference code binary.
|
||||
// the source. It has also been modified to include the conditional logic from
|
||||
// the CircuitPython implementation that supports additional flash chips. The
|
||||
// CiruitPython source is here:
|
||||
// https://github.com/adafruit/circuitpython/blob/main/ports/raspberrypi/stage2.c.jinja
|
||||
//
|
||||
// This file cannot be assembled directly, instead assemble the board-specific file
|
||||
// (such as pico-boot-stage2.S) which defines the parameters specific to the flash
|
||||
// chip included on that board.
|
||||
//
|
||||
// Care has been taken to preserve ordering and it has been verified the generated
|
||||
// binary is byte-for-byte identical to the reference code binary when assembled for
|
||||
// the Pico.
|
||||
//
|
||||
// Note: the stage 2 boot loader must be 256 bytes in length and have a checksum
|
||||
// present. In TinyGo, the linker script is responsible for allocating 256 bytes
|
||||
|
@ -19,10 +29,6 @@
|
|||
// https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/boot_stage2/boot2_w25q080.S
|
||||
//
|
||||
|
||||
// Board Parameters
|
||||
#define PICO_FLASH_SPI_CLKDIV 2
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Second stage boot code
|
||||
|
@ -59,7 +65,8 @@
|
|||
#define CMD_WRITE_ENABLE 0x06
|
||||
#define CMD_READ_STATUS 0x05
|
||||
#define CMD_READ_STATUS2 0x35
|
||||
#define CMD_WRITE_STATUS 0x01
|
||||
#define CMD_WRITE_STATUS1 0x01
|
||||
#define CMD_WRITE_STATUS2 0x31
|
||||
#define SREG_DATA 0x02 // Enable quad-SPI mode
|
||||
|
||||
#define XIP_BASE 0x10000000
|
||||
|
@ -123,18 +130,32 @@
|
|||
// The bootrom is very conservative with SPI frequency, but here we should be
|
||||
// as aggressive as possible.
|
||||
|
||||
#ifndef PICO_FLASH_SPI_CLKDIV
|
||||
#define PICO_FLASH_SPI_CLKDIV 4
|
||||
#endif
|
||||
#define PICO_FLASH_SPI_CLKDIV BOARD_PICO_FLASH_SPI_CLKDIV
|
||||
#if PICO_FLASH_SPI_CLKDIV & 1
|
||||
#error PICO_FLASH_SPI_CLKDIV must be even
|
||||
#endif
|
||||
|
||||
#if BOARD_QUAD_OK==1
|
||||
// Define interface width: single/dual/quad IO
|
||||
#define FRAME_FORMAT SSI_CTRLR0_SPI_FRF_VALUE_QUAD
|
||||
#define TRANSACTION_TYPE SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A
|
||||
// Note that the INST_L field is used to select what XIP data gets pushed into
|
||||
// the TX FIFO:
|
||||
// INST_L_0_BITS {ADDR[23:0],XIP_CMD[7:0]} Load "mode bits" into XIP_CMD
|
||||
// Anything else {XIP_CMD[7:0],ADDR[23:0]} Load SPI command into XIP_CMD
|
||||
#define INSTRUCTION_LENGTH SSI_SPI_CTRLR0_INST_L_VALUE_NONE
|
||||
#define READ_INSTRUCTION MODE_CONTINUOUS_READ
|
||||
#define ADDR_L 8 // 6 for address, 2 for mode
|
||||
#else
|
||||
#define FRAME_FORMAT SSI_CTRLR0_SPI_FRF_VALUE_STD
|
||||
#define TRANSACTION_TYPE SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C1A
|
||||
#define INSTRUCTION_LENGTH SSI_SPI_CTRLR0_INST_L_VALUE_8B
|
||||
#define READ_INSTRUCTION BOARD_CMD_READ
|
||||
#define ADDR_L 6 // * 4 = 24
|
||||
#endif
|
||||
|
||||
// For W25Q080 this is the "Read data fast quad IO" instruction:
|
||||
#define CMD_READ 0xeb
|
||||
// The flash-chip specific read isntruction
|
||||
#define CMD_READ BOARD_CMD_READ
|
||||
|
||||
// "Mode bits" are 8 special bits sent immediately after
|
||||
// the address bits in a "Read Data Fast Quad I/O" command sequence.
|
||||
|
@ -142,13 +163,10 @@
|
|||
// next read does not require the 0xeb instruction prefix.
|
||||
#define MODE_CONTINUOUS_READ 0xa0
|
||||
|
||||
// The number of address + mode bits, divided by 4 (always 4, not function of
|
||||
// interface width).
|
||||
#define ADDR_L 8
|
||||
|
||||
// How many clocks of Hi-Z following the mode bits. For W25Q080, 4 dummy cycles
|
||||
// are required.
|
||||
#define WAIT_CYCLES 4
|
||||
#define WAIT_CYCLES BOARD_WAIT_CYCLES
|
||||
|
||||
|
||||
// If defined, we will read status reg, compare to SREG_DATA, and overwrite
|
||||
// with our value if the SR doesn't match.
|
||||
|
@ -184,10 +202,14 @@ _stage2_boot:
|
|||
ldr r0, [r3, #PADS_QSPI_GPIO_QSPI_SD0_OFFSET]
|
||||
movs r1, #PADS_QSPI_GPIO_QSPI_SD0_SCHMITT_BITS
|
||||
bics r0, r1
|
||||
#if BOARD_QUAD_OK==1
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD0_OFFSET]
|
||||
#endif
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD1_OFFSET]
|
||||
#if BOARD_QUAD_OK==1
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD2_OFFSET]
|
||||
str r0, [r3, #PADS_QSPI_GPIO_QSPI_SD3_OFFSET]
|
||||
#endif
|
||||
|
||||
ldr r3, =XIP_SSI_BASE
|
||||
|
||||
|
@ -225,9 +247,15 @@ program_sregs:
|
|||
str r1, [r3, #SSI_SSIENR_OFFSET]
|
||||
|
||||
// Check whether SR needs updating
|
||||
#if BOARD_QUAD_OK==1
|
||||
# if BOARD_QUAD_ENABLE_STATUS_BYTE==1
|
||||
movs r0, #CMD_READ_STATUS1
|
||||
# elif BOARD_QUAD_ENABLE_STATUS_BYTE==2
|
||||
movs r0, #CMD_READ_STATUS2
|
||||
# endif
|
||||
|
||||
bl read_flash_sreg
|
||||
movs r2, #SREG_DATA
|
||||
movs r2, #BOARD_QUAD_ENABLE_BIT_MASK
|
||||
cmp r0, r2
|
||||
beq skip_sreg_programming
|
||||
|
||||
|
@ -240,17 +268,37 @@ program_sregs:
|
|||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
// Send status write command followed by data bytes
|
||||
movs r1, #CMD_WRITE_STATUS
|
||||
# if BOARD_SPLIT_STATUS_WRITE==1
|
||||
# if BOARD_QUAD_ENABLE_STATUS_BYTE==1
|
||||
movs r1, #CMD_WRITE_STATUS1
|
||||
# elif BOARD_QUAD_ENABLE_STATUS_BYTE==2
|
||||
movs r1, #CMD_WRITE_STATUS2
|
||||
# endif
|
||||
str r1, [r3, #SSI_DR0_OFFSET]
|
||||
str r2, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
bl wait_ssi_ready
|
||||
//ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
# else
|
||||
movs r1, #CMD_WRITE_STATUS1
|
||||
str r1, [r3, #SSI_DR0_OFFSET]
|
||||
# if BOARD_QUAD_ENABLE_STATUS_BYTE==2
|
||||
movs r0, #0
|
||||
str r0, [r3, #SSI_DR0_OFFSET]
|
||||
# endif
|
||||
str r2, [r3, #SSI_DR0_OFFSET]
|
||||
|
||||
bl wait_ssi_ready
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
# if BOARD_QUAD_ENABLE_STATUS_BYTE==2
|
||||
ldr r1, [r3, #SSI_DR0_OFFSET]
|
||||
# endif
|
||||
|
||||
# endif
|
||||
// Poll status register for write completion
|
||||
1:
|
||||
movs r0, #CMD_READ_STATUS
|
||||
|
@ -258,6 +306,7 @@ program_sregs:
|
|||
movs r1, #1
|
||||
tst r0, r1
|
||||
bne 1b
|
||||
#endif
|
||||
|
||||
skip_sreg_programming:
|
||||
|
||||
|
@ -286,6 +335,7 @@ dummy_read:
|
|||
movs r1, #0x0 // NDF=0 (single 32b read)
|
||||
str r1, [r3, #SSI_CTRLR1_OFFSET]
|
||||
|
||||
#if BOARD_QUAD_OK==1
|
||||
#define SPI_CTRLR0_ENTER_XIP \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Address + mode bits */ \
|
||||
(WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
|
||||
|
@ -315,6 +365,7 @@ dummy_read:
|
|||
|
||||
movs r1, #0
|
||||
str r1, [r3, #SSI_SSIENR_OFFSET] // Disable SSI (and clear FIFO) to allow further config
|
||||
#endif
|
||||
|
||||
// Note that the INST_L field is used to select what XIP data gets pushed into
|
||||
// the TX FIFO:
|
||||
|
@ -322,13 +373,13 @@ dummy_read:
|
|||
// Anything else {XIP_CMD[7:0],ADDR[23:0]} Load SPI command into XIP_CMD
|
||||
configure_ssi:
|
||||
#define SPI_CTRLR0_XIP \
|
||||
(MODE_CONTINUOUS_READ /* Mode bits to keep flash in continuous read mode */ \
|
||||
(READ_INSTRUCTION /* Mode bits to keep flash in continuous read mode */ \
|
||||
<< SSI_SPI_CTRLR0_XIP_CMD_LSB) | \
|
||||
(ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Total number of address + mode bits */ \
|
||||
(WAIT_CYCLES << SSI_SPI_CTRLR0_WAIT_CYCLES_LSB) | /* Hi-Z dummy clocks following address + mode */ \
|
||||
(SSI_SPI_CTRLR0_INST_L_VALUE_NONE /* Do not send a command, instead send XIP_CMD as mode bits after address */ \
|
||||
(INSTRUCTION_LENGTH /* Do not send a command, instead send XIP_CMD as mode bits after address */ \
|
||||
<< SSI_SPI_CTRLR0_INST_L_LSB) | \
|
||||
(SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A /* Send Address in Quad I/O mode (and Command but that is zero bits long) */ \
|
||||
(TRANSACTION_TYPE /* Send Address in Quad I/O mode (and Command but that is zero bits long) */ \
|
||||
<< SSI_SPI_CTRLR0_TRANS_TYPE_LSB)
|
||||
|
||||
ldr r1, =(SPI_CTRLR0_XIP)
|
Загрузка…
Создание таблицы
Сослаться в новой задаче