112 lines
3.3 KiB
C
112 lines
3.3 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>
|
||
|
#include <libusb.h>
|
||
|
#include "boot/picoboot.h"
|
||
|
|
||
|
#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,
|
||
|
};
|
||
|
|
||
|
enum picoboot_device_result picoboot_open_device(libusb_device *device, libusb_device_handle **dev_handle);
|
||
|
|
||
|
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_exec(libusb_device_handle *usb_device, uint32_t addr);
|
||
|
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_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);
|
||
|
|
||
|
#define ROM_START 0x00000000
|
||
|
#define ROM_END 0x00004000
|
||
|
#define FLASH_START 0x10000000
|
||
|
#define FLASH_END 0x11000000 // this is maximum
|
||
|
#define XIP_SRAM_BASE 0x15000000
|
||
|
#define XIP_SRAM_END 0x15004000
|
||
|
|
||
|
#define SRAM_START 0x20000000
|
||
|
#define SRAM_END 0x20042000
|
||
|
|
||
|
#define SRAM_UNSTRIPED_START 0x21000000
|
||
|
#define SRAM_UNSTRIPED_END 0x21040000
|
||
|
|
||
|
// 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) {
|
||
|
if (addr >= ROM_START && addr <= ROM_END) {
|
||
|
return rom;
|
||
|
}
|
||
|
if (addr >= FLASH_START && addr <= FLASH_END) {
|
||
|
return flash;
|
||
|
}
|
||
|
if (addr >= SRAM_START && addr <= SRAM_END) {
|
||
|
return sram;
|
||
|
}
|
||
|
if (addr >= SRAM_UNSTRIPED_START && addr <= SRAM_UNSTRIPED_END) {
|
||
|
return sram_unstriped;
|
||
|
}
|
||
|
if (addr >= XIP_SRAM_BASE && addr <= XIP_SRAM_END) {
|
||
|
return xip_sram;
|
||
|
}
|
||
|
return invalid;
|
||
|
}
|
||
|
|
||
|
static inline bool is_transfer_aligned(uint32_t addr) {
|
||
|
enum memory_type t = get_memory_type(addr);
|
||
|
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
|