blob: 1d3355713ccf219c899b4c32e25cd115072de328 [file] [log] [blame]
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _PICOBOOT_CONNECTION_CXX_H
#define _PICOBOOT_CONNECTION_CXX_H
#include "picoboot_connection.h"
#include <vector>
namespace picoboot {
struct command_failure : public std::exception {
explicit command_failure(int code) : code(code) {}
const char *what() const noexcept override;
private:
int code;
};
struct connection_error : public std::exception {
connection_error(int libusb_code) : libusb_code(libusb_code) {}
const int libusb_code;
};
struct connection {
explicit connection(libusb_device_handle *device, bool exclusive = true) : device(device), exclusive(exclusive) {
// do a device reset in case it was left in a bad state
reset();
if (exclusive) exclusive_access(EXCLUSIVE);
}
~connection() {
if (exclusive) {
if (picoboot_exclusive_access(device, NOT_EXCLUSIVE)) {
// failed to restore exclusive access, so just reset
reset();
}
}
}
void reset();
void exclusive_access(uint8_t exclusive);
void enter_cmd_xip();
void exit_xip();
void reboot(uint32_t pc, uint32_t sp, uint32_t delay_ms);
void exec(uint32_t addr);
void flash_erase(uint32_t addr, uint32_t len);
void vector(uint32_t addr);
void write(uint32_t addr, uint8_t *buffer, uint32_t len);
void write_bytes(uint32_t addr, std::vector<uint8_t> bytes) {
write(addr, bytes.data(), bytes.size());
}
void read(uint32_t addr, uint8_t *buffer, uint32_t len);
std::vector<uint8_t> read_bytes(uint32_t addr, uint32_t len) {
std::vector<uint8_t> bytes(len);
read(addr, bytes.data(), len);
return bytes;
}
private:
template <typename F> void wrap_call(F&& func);
libusb_device_handle *device;
bool exclusive;
};
}
#endif