-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds `make flash` support for the rp2040 target. Flashing is performed using a custom `rp2040_flash` tool that uses the PICOBOOT protocol. Root is not required. The user specifies the serial device of the rp2040 they wish to flash as the device. This device is reset into bootsel mode and `rp2040_flash` is invoked on the original USB device path. If the device is already in bootloader mode, the user can specify 'first' as `FLASH_DEVICE` which will simply invoke `rp2040_flash` with no bus/address options. Signed-off-by: Lasse Dalegaard <[email protected]>
- Loading branch information
1 parent
8a3727e
commit 7c0559c
Showing
10 changed files
with
1,124 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ bossac/bin/ | |
bossac/obj/ | ||
hidflash/hid-flash | ||
hub-ctrl/hub-ctrl | ||
rp2040_flash/rp2040_flash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/* | ||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
#ifndef _BOOT_PICOBOOT_H | ||
#define _BOOT_PICOBOOT_H | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <assert.h> | ||
|
||
#ifndef NO_PICO_PLATFORM | ||
#include "pico/platform.h" | ||
#endif | ||
|
||
/** \file picoboot.h | ||
* \defgroup boot_picoboot boot_picoboot | ||
* | ||
* Header file for the PICOBOOT USB interface exposed by an RP2040 in BOOTSEL mode. | ||
*/ | ||
|
||
#define PICOBOOT_MAGIC 0x431fd10bu | ||
|
||
// -------------------------------------------- | ||
// CONTROL REQUESTS FOR THE PICOBOOT INTERFACE | ||
// -------------------------------------------- | ||
|
||
// size 0 OUT - unstall EPs and reset | ||
#define PICOBOOT_IF_RESET 0x41 | ||
|
||
// size 16 IN - return the status of the last command | ||
#define PICOBOOT_IF_CMD_STATUS 0x42 | ||
|
||
// -------------------------------------------------- | ||
// COMMAND REQUESTS SENT TO THE PICOBOOT OUT ENDPOINT | ||
// -------------------------------------------------- | ||
// | ||
// picoboot_cmd structure of size 32 is sent to OUT endpoint | ||
// transfer_length bytes are transferred via IN/OUT | ||
// device responds on success with 0 length ACK packet set via OUT/IN | ||
// device may stall the transferring endpoint in case of error | ||
|
||
enum picoboot_cmd_id { | ||
PC_EXCLUSIVE_ACCESS = 0x1, | ||
PC_REBOOT = 0x2, | ||
PC_FLASH_ERASE = 0x3, | ||
PC_READ = 0x84, // either RAM or FLASH | ||
PC_WRITE = 5, // either RAM or FLASH (does no erase) | ||
PC_EXIT_XIP = 0x6, | ||
PC_ENTER_CMD_XIP = 0x7, | ||
PC_EXEC = 0x8, | ||
PC_VECTORIZE_FLASH = 0x9 | ||
}; | ||
|
||
enum picoboot_status { | ||
PICOBOOT_OK = 0, | ||
PICOBOOT_UNKNOWN_CMD = 1, | ||
PICOBOOT_INVALID_CMD_LENGTH = 2, | ||
PICOBOOT_INVALID_TRANSFER_LENGTH = 3, | ||
PICOBOOT_INVALID_ADDRESS = 4, | ||
PICOBOOT_BAD_ALIGNMENT = 5, | ||
PICOBOOT_INTERLEAVED_WRITE = 6, | ||
PICOBOOT_REBOOTING = 7, | ||
PICOBOOT_UNKNOWN_ERROR = 8, | ||
}; | ||
|
||
struct __packed picoboot_reboot_cmd { | ||
uint32_t dPC; // 0 means reset into bootrom | ||
uint32_t dSP; | ||
uint32_t dDelayMS; | ||
}; | ||
|
||
// used for EXEC, VECTORIZE_FLASH | ||
struct __packed picoboot_address_only_cmd { | ||
uint32_t dAddr; | ||
}; | ||
|
||
// used for READ, WRITE, FLASH_ERASE | ||
struct __packed picoboot_range_cmd { | ||
uint32_t dAddr; | ||
uint32_t dSize; | ||
}; | ||
|
||
enum picoboot_exclusive_type { | ||
NOT_EXCLUSIVE = 0, | ||
EXCLUSIVE, | ||
EXCLUSIVE_AND_EJECT | ||
}; | ||
|
||
struct __packed picoboot_exclusive_cmd { | ||
uint8_t bExclusive; | ||
}; | ||
|
||
// little endian | ||
struct __packed __aligned(4) picoboot_cmd { | ||
uint32_t dMagic; | ||
uint32_t dToken; // an identifier for this token to correlate with a status response | ||
uint8_t bCmdId; // top bit set for IN | ||
uint8_t bCmdSize; // bytes of actual data in the arg part of this structure | ||
uint16_t _unused; | ||
uint32_t dTransferLength; // length of IN/OUT transfer (or 0) if none | ||
union { | ||
uint8_t args[16]; | ||
struct picoboot_reboot_cmd reboot_cmd; | ||
struct picoboot_range_cmd range_cmd; | ||
struct picoboot_address_only_cmd address_only_cmd; | ||
struct picoboot_exclusive_cmd exclusive_cmd; | ||
}; | ||
}; | ||
|
||
static_assert(32 == sizeof(struct picoboot_cmd), "picoboot_cmd must be 32 bytes big"); | ||
|
||
struct __packed __aligned(4) picoboot_cmd_status { | ||
uint32_t dToken; | ||
uint32_t dStatusCode; | ||
uint8_t bCmdId; | ||
uint8_t bInProgress; | ||
uint8_t _pad[6]; | ||
}; | ||
|
||
static_assert(16 == sizeof(struct picoboot_cmd_status), "picoboot_cmd_status must be 16 bytes big"); | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
#ifndef _PICO_PLATFORM_H_ | ||
#define _PICO_PLATFORM_H_ | ||
|
||
#include "hardware/platform_defs.h" | ||
#include <stddef.h> | ||
|
||
#ifdef __unix__ | ||
|
||
#include <sys/cdefs.h> | ||
|
||
#endif | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#define __not_in_flash(grup) | ||
#define __not_in_flash_func(func) func | ||
#define __no_inline_not_in_flash_func(func) | ||
#define __in_flash(group) | ||
#define __scratch_x(group) | ||
#define __scratch_y(group) | ||
|
||
#define __packed_aligned | ||
#define __packed | ||
|
||
#define __time_critical_func(x) x | ||
#define __after_data(group) | ||
|
||
//int running_on_fpga() { return false; } | ||
extern void tight_loop_contents(); | ||
|
||
#ifndef __STRING | ||
#define __STRING(x) #x | ||
#endif | ||
|
||
#ifndef _MSC_VER | ||
#ifndef __noreturn | ||
#define __noreturn __attribute((noreturn)) | ||
#endif | ||
|
||
#ifndef __unused | ||
#define __unused __attribute__((unused)) | ||
#endif | ||
|
||
#ifndef __noinline | ||
#define __noinline __attribute__((noinline)) | ||
#endif | ||
|
||
#ifndef __aligned | ||
#define __aligned(x) __attribute__((aligned(x))) | ||
#endif | ||
|
||
#define PICO_WEAK_FUNCTION_DEF(x) _Pragma(__STRING(weak x)) | ||
#define PICO_WEAK_FUNCTION_IMPL_NAME(x) x | ||
|
||
#else | ||
#ifndef __noreturn | ||
#define __noreturn __declspec(noreturn) | ||
#endif | ||
|
||
#ifndef __unused | ||
#define __unused | ||
#endif | ||
|
||
#ifndef __noinline | ||
#define __noinline __declspec(noinline) | ||
#endif | ||
|
||
#ifndef __aligned | ||
#define __aligned(x) __declspec(align(x)) | ||
#endif | ||
|
||
#ifndef __CONCAT | ||
#define __CONCAT(x,y) x ## y | ||
#endif | ||
|
||
#define __thread __declspec( thread ) | ||
|
||
#define PICO_WEAK_FUNCTION_DEF(x) __pragma(comment(linker, __STRING(/alternatename:_##x=_##x##__weak))); | ||
#define PICO_WEAK_FUNCTION_IMPL_NAME(x) x ## __weak | ||
|
||
static __noreturn void __builtin_unreachable() { | ||
} | ||
|
||
#include <intrin.h> | ||
#define __builtin_clz __lzcnt | ||
#endif | ||
|
||
#ifndef count_of | ||
#define count_of(a) (sizeof(a)/sizeof((a)[0])) | ||
#endif | ||
|
||
#ifndef MAX | ||
#define MAX(a, b) ((a)>(b)?(a):(b)) | ||
#endif | ||
|
||
#ifndef MIN | ||
#define MIN(a, b) ((b)>(a)?(a):(b)) | ||
#endif | ||
|
||
// abort in our case | ||
void __noreturn __breakpoint(); | ||
|
||
void __noreturn panic_unsupported(); | ||
|
||
void __noreturn panic(const char *fmt, ...); | ||
|
||
// arggggghhhh there is a weak function called sem_init used by SDL | ||
#define sem_init sem_init_alternative | ||
|
||
extern uint32_t host_safe_hw_ptr_impl(uintptr_t x); | ||
// return a 32 bit handle for a raw ptr; DMA chaining for example embeds pointers in 32 bit values | ||
// which of course does not work if we're running the code natively on a 64 bit platforms. Therefore | ||
// we provide this macro which allows that code to provide a 64->32 bit mapping in host mode | ||
#define host_safe_hw_ptr(x) host_safe_hw_ptr_impl((uintptr_t)(x)) | ||
void *decode_host_safe_hw_ptr(uint32_t ptr); | ||
|
||
#define __fast_mul(a,b) ((a)*(b)) | ||
|
||
typedef unsigned int uint; | ||
|
||
static inline int32_t __mul_instruction(int32_t a,int32_t b) | ||
{ | ||
return a*b; | ||
} | ||
|
||
static inline void __compiler_memory_barrier(void) { | ||
} | ||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
CC=gcc | ||
CFLAGS=-c -Wall -ggdb | ||
LDFALGS= | ||
SOURCES=main.c picoboot_connection.c | ||
OBJECTS=$(SOURCES:.c=.o) | ||
LIBS=`pkg-config libusb-1.0 --libs` | ||
INCLUDE_DIRS+=-I../rp2040/ `pkg-config libusb-1.0 --cflags` | ||
|
||
EXECUTABLE=rp2040_flash | ||
|
||
all: $(EXECUTABLE) | ||
|
||
$(EXECUTABLE): $(OBJECTS) | ||
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ | ||
|
||
.c.o: | ||
$(CC) $(CFLAGS) $(INCLUDE_DIRS) $< -o $@ | ||
|
||
clean: | ||
rm -f $(OBJECTS) $(EXECUTABLE) |
Oops, something went wrong.