1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
/*
* 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 "model.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,
dr_vidpid_stdio_usb_cant_connect,
};
#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, chip_t *chip, 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
#ifdef PAGE_SIZE
#undef PAGE_SIZE
#endif
#define PAGE_SIZE (1u << LOG2_PAGE_SIZE)
#define FLASH_SECTOR_ERASE_SIZE 4096u
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
|