mirror of
https://github.com/andreili/katapult.git
synced 2025-08-23 19:34:06 +02:00
Synchronize with the latest Klipper code. This pulls in the latest lib/ files (needed to use the pico-sdk v2.0.0 version). It updates to latest can2040 code (needed for pico-sdk v2.0.0 support). It implements USB double buffering (as is now done in Klipper). It adds in support for additional UART pins (as is now done in Klipper). It adds support for rp2350 chips. This replaces the execute in ram code previously implemented in Katapult with the execute in ram code that is now standard in Klipper. The CONFIG_RP2040_ADD_BOOT_SIGNATURE kconfig symbol was removed and the build now always produces a katapult.withclear.uf2 file. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
148 lines
4.8 KiB
C
148 lines
4.8 KiB
C
/*
|
|
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#ifndef _PICOBOOT_CONNECTION_H
|
|
#define _PICOBOOT_CONNECTION_H
|
|
|
|
// todo we should use fully encapsulate libusb
|
|
|
|
#include <assert.h>
|
|
#if HAS_LIBUSB
|
|
#include <libusb.h>
|
|
#endif
|
|
#include "boot/picoboot.h"
|
|
|
|
#include "addresses.h"
|
|
|
|
#define VENDOR_ID_RASPBERRY_PI 0x2e8au
|
|
#define PRODUCT_ID_RP2040_USBBOOT 0x0003u
|
|
#define PRODUCT_ID_PICOPROBE 0x0004u
|
|
#define PRODUCT_ID_MICROPYTHON 0x0005u
|
|
#define PRODUCT_ID_STDIO_USB 0x0009u
|
|
#define PRODUCT_ID_RP2040_STDIO_USB 0x000au
|
|
#define PRODUCT_ID_RP2350_USBBOOT 0x000fu
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
enum picoboot_device_result {
|
|
dr_vidpid_bootrom_ok,
|
|
dr_vidpid_bootrom_no_interface,
|
|
dr_vidpid_bootrom_cant_connect,
|
|
dr_vidpid_micropython,
|
|
dr_vidpid_picoprobe,
|
|
dr_vidpid_unknown,
|
|
dr_error,
|
|
dr_vidpid_stdio_usb,
|
|
};
|
|
|
|
typedef enum {
|
|
rp2040,
|
|
rp2350,
|
|
unknown
|
|
} model_t;
|
|
|
|
typedef enum {
|
|
rp2350_a2,
|
|
rp2350_unknown
|
|
} rp2350_version_t;
|
|
|
|
#if HAS_LIBUSB
|
|
// note that vid and pid are filters, unless both are specified in which case a device with that VID and PID is allowed for RP2350
|
|
enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_device_handle **dev_handle, model_t *model, int vid, int pid, const char* ser);
|
|
|
|
int picoboot_reset(libusb_device_handle *usb_device);
|
|
int picoboot_cmd_status_verbose(libusb_device_handle *usb_device, struct picoboot_cmd_status *status,
|
|
bool local_verbose);
|
|
int picoboot_cmd_status(libusb_device_handle *usb_device, struct picoboot_cmd_status *status);
|
|
int picoboot_exclusive_access(libusb_device_handle *usb_device, uint8_t exclusive);
|
|
int picoboot_enter_cmd_xip(libusb_device_handle *usb_device);
|
|
int picoboot_exit_xip(libusb_device_handle *usb_device);
|
|
int picoboot_reboot(libusb_device_handle *usb_device, uint32_t pc, uint32_t sp, uint32_t delay_ms);
|
|
int picoboot_reboot2(libusb_device_handle *usb_device, struct picoboot_reboot2_cmd *reboot_cmd);
|
|
int picoboot_get_info(libusb_device_handle *usb_device, struct picoboot_get_info_cmd *cmd, uint8_t *buffer, uint32_t len);
|
|
int picoboot_exec(libusb_device_handle *usb_device, uint32_t addr);
|
|
// int picoboot_exec2(libusb_device_handle *usb_device, struct picoboot_exec2_cmd *exec2_cmd); // currently unused
|
|
int picoboot_flash_erase(libusb_device_handle *usb_device, uint32_t addr, uint32_t len);
|
|
int picoboot_vector(libusb_device_handle *usb_device, uint32_t addr);
|
|
int picoboot_write(libusb_device_handle *usb_device, uint32_t addr, uint8_t *buffer, uint32_t len);
|
|
int picoboot_read(libusb_device_handle *usb_device, uint32_t addr, uint8_t *buffer, uint32_t len);
|
|
int picoboot_otp_write(libusb_device_handle *usb_device, struct picoboot_otp_cmd *otp_cmd, uint8_t *buffer, uint32_t len);
|
|
int picoboot_otp_read(libusb_device_handle *usb_device, struct picoboot_otp_cmd *otp_cmd, uint8_t *buffer, uint32_t len);
|
|
int picoboot_poke(libusb_device_handle *usb_device, uint32_t addr, uint32_t data);
|
|
int picoboot_peek(libusb_device_handle *usb_device, uint32_t addr, uint32_t *data);
|
|
int picoboot_flash_id(libusb_device_handle *usb_device, uint64_t *data);
|
|
#endif
|
|
|
|
// we require 256 (as this is the page size supported by the device)
|
|
#define LOG2_PAGE_SIZE 8u
|
|
#define PAGE_SIZE (1u << LOG2_PAGE_SIZE)
|
|
#define FLASH_SECTOR_ERASE_SIZE 4096u
|
|
|
|
enum memory_type {
|
|
rom,
|
|
flash,
|
|
sram,
|
|
sram_unstriped,
|
|
xip_sram,
|
|
invalid,
|
|
};
|
|
|
|
// inclusive of ends
|
|
static inline enum memory_type get_memory_type(uint32_t addr, model_t model) {
|
|
if (addr >= FLASH_START && addr <= FLASH_END_RP2040) {
|
|
return flash;
|
|
}
|
|
if (addr >= ROM_START && addr <= ROM_END_RP2040) {
|
|
return rom;
|
|
}
|
|
if (addr >= SRAM_START && addr <= SRAM_END_RP2040) {
|
|
return sram;
|
|
}
|
|
if (model == rp2350) {
|
|
if (addr >= FLASH_START && addr <= FLASH_END_RP2350) {
|
|
return flash;
|
|
}
|
|
if (addr >= ROM_START && addr <= ROM_END_RP2350) {
|
|
return rom;
|
|
}
|
|
if (addr >= SRAM_START && addr <= SRAM_END_RP2350) {
|
|
return sram;
|
|
}
|
|
}
|
|
if (addr >= MAIN_RAM_BANKED_START && addr <= MAIN_RAM_BANKED_END) {
|
|
return sram_unstriped;
|
|
}
|
|
if (model == rp2040) {
|
|
if (addr >= XIP_SRAM_START_RP2040 && addr <= XIP_SRAM_END_RP2040) {
|
|
return xip_sram;
|
|
}
|
|
} else if (model == rp2350) {
|
|
if (addr >= XIP_SRAM_START_RP2350 && addr <= XIP_SRAM_END_RP2350) {
|
|
return xip_sram;
|
|
}
|
|
}
|
|
return invalid;
|
|
}
|
|
|
|
static inline bool is_transfer_aligned(uint32_t addr, model_t model) {
|
|
enum memory_type t = get_memory_type(addr, model);
|
|
return t != invalid && !(t == flash && addr & (PAGE_SIZE-1));
|
|
}
|
|
|
|
static inline bool is_size_aligned(uint32_t addr, int size) {
|
|
#ifndef _MSC_VER
|
|
assert(__builtin_popcount(size)==1);
|
|
#endif
|
|
return !(addr & (size-1));
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|