27#include <libusb-1.0/libusb.h>
75 enum class DFUState : uint8_t
80 DFU_DOWNLOAD_SYNC = 0x03,
81 DFU_DOWNLOAD_BUSY = 0x04,
82 DFU_DOWNLOAD_IDLE = 0x05,
83 DFU_MANIFEST_SYNC = 0x06,
85 DFU_MANIFEST_WAIT_RESET = 0x08,
86 DFU_UPLOAD_IDLE = 0x09,
88 DFU_UPLOAD_SYNC = 0x91,
89 DFU_UPLOAD_BUSY = 0x92
92 enum class DFUStatus : uint8_t
99 errCHECK_ERASE = 0x05,
109 errSTALLEDPKT = 0x0f,
112 static auto ToString(DFUStatus s)
118 case DFUStatus::errTARGET:
120 case DFUStatus::errFILE:
122 case DFUStatus::errWRITE:
124 case DFUStatus::errERASE:
126 case DFUStatus::errCHECK_ERASE:
127 return "errCHECK_ERASE";
128 case DFUStatus::errPROG:
130 case DFUStatus::errVERIFY:
132 case DFUStatus::errADDRESS:
134 case DFUStatus::errNOTDONE:
136 case DFUStatus::errFIRMWARE:
137 return "errFIRMWARE";
138 case DFUStatus::errVENDOR:
140 case DFUStatus::errUSBR:
142 case DFUStatus::errPOR:
144 case DFUStatus::errUNKNOWN:
146 case DFUStatus::errSTALLEDPKT:
147 return "errSTALLEDPKT";
152 static auto ToString(DFUState s)
158 case DFUState::DETACH:
160 case DFUState::DFU_IDLE:
162 case DFUState::DFU_DOWNLOAD_SYNC:
163 return "DFU_DOWNLOAD_SYNC";
164 case DFUState::DFU_DOWNLOAD_BUSY:
165 return "DFU_DOWNLOAD_BUSY";
166 case DFUState::DFU_DOWNLOAD_IDLE:
167 return "DFU_DOWNLOAD_IDLE";
168 case DFUState::DFU_MANIFEST_SYNC:
169 return "DFU_MANIFEST_SYNC";
170 case DFUState::DFU_MANIFEST:
171 return "DFU_MANIFEST";
172 case DFUState::DFU_MANIFEST_WAIT_RESET:
173 return "DFU_MANIFEST_WAIT_RESET";
174 case DFUState::DFU_UPLOAD_IDLE:
175 return "DFU_UPLOAD_IDLE";
176 case DFUState::DFU_ERROR:
178 case DFUState::DFU_UPLOAD_SYNC:
179 return "DFU_UPLOAD_SYNC";
180 case DFUState::DFU_UPLOAD_BUSY:
181 return "DFU_UPLOAD_BUSY";
189 DFUStatusReport(
const DFUStatus &status,
const uint32_t &timeout,
const DFUState &state,
const uint8_t &discarded)
190 : status(status), timeout(timeout), state(state), discarded(discarded)
195 const DFUStatus status;
196 const uint32_t timeout;
197 const DFUState state;
198 const uint8_t discarded;
203 static_cast<DFUStatus
>((
int)data[0]),
204 (((data[1] << 8) | data[2]) << 8) | data[3],
205 static_cast<DFUState
>((
int)data[4]),
214 auto ToString()
const -> std::string
216 std::stringstream out;
217 out <<
"Status: " << radio_tool::dfu::ToString(status) <<
", "
218 <<
"Timeout: 0x" << std::setfill(
'0') << std::setw(2) << std::hex << timeout <<
", "
219 <<
"State: " << radio_tool::dfu::ToString(state) <<
", "
220 <<
"Discarded: 0x" << std::setfill(
'0') << std::setw(2) << std::hex << discarded;
226 : status(DFUStatus::errUNKNOWN), timeout(0), state(DFUState::DFU_ERROR), discarded(0)
234 DFU(libusb_device_handle *device)
235 : timeout(5000), device(device) {}
237 auto SetAddress(
const uint32_t &)
const -> void;
238 auto Erase(
const uint32_t &)
const -> void;
239 auto Download(
const std::vector<uint8_t> &,
const uint16_t &wValue = 0)
const -> void;
240 auto Upload(
const uint16_t &,
const uint8_t &wValue = 0)
const -> std::vector<uint8_t>;
242 auto Get()
const -> std::vector<uint8_t>;
243 auto ReadUnprotected()
const -> void;
245 auto GetState()
const -> DFUState;
247 auto Abort()
const -> void;
248 auto Detach()
const -> void;
251 libusb_context *usb_ctx;
252 auto GetDeviceString(
const libusb_device_descriptor &, libusb_device_handle *)
const -> std::wstring;
255 const uint16_t timeout;
256 libusb_device_handle *device;
258 auto CheckDevice()
const -> void;