18#include <radio_tool/h8sx/h8sx.hpp>
27#define bswap32(x) _byteswap_ulong((x))
29#define bswap32(x) __builtin_bswap32((x))
34auto H8SX::IdentifyDevice() const -> std::
string
37 int transferred = 0, received = 0;
38 uint8_t buf[BUF_SIZE];
41 uint8_t cmd =
static_cast<uint8_t
>(H8SXCmd::BEGIN_INQUIRY);
42 err = libusb_bulk_transfer(device,
48 CHECK_ERR(
"cannot begin inquiry phase!");
51 err = libusb_bulk_transfer(device,
57 CHECK_ERR(
"I/O error!");
60 CHECK_ERR(
"wrong response from radio!");
63 cmd =
static_cast<uint8_t
>(H8SXCmd::DEVICE_INQUIRY);
64 err = libusb_bulk_transfer(device,
70 CHECK_ERR(
"I/O error!");
73 err = libusb_bulk_transfer(device,
80 err = libusb_bulk_transfer(device,
86 CHECK_ERR(
"error in device selection!");
87 auto dir = (
struct dev_inq_hdr_t *)buf;
89 buf[
sizeof(
struct dev_inq_hdr_t) + dir->nchar] =
'\0';
92 std::ostringstream dev_str;
93 dev_str << dir->code[0]
98 << buf +
sizeof(
struct dev_inq_hdr_t);
102auto H8SX::Download(
const std::vector<uint8_t> &data)
const ->
void
105 int transferred = 0, received = 0;
106 uint8_t buf[BUF_SIZE];
111 struct prog_chunk_t c = {};
112 uint8_t cmd =
static_cast<uint8_t
>(H8SXCmd::PROGRAM_128B);
113 uint32_t bin_sum = 0;
114 for (std::vector<uint8_t>::size_type i = 0; i < data.size() / 1024; i++)
116 c.addr = bswap32(i * 1024);
117 std::copy(data.begin() + i * 1024, data.begin() + (i + 1) * 1024, c.data);
118 bin_sum += Checksum((uint8_t *)&(c.data), 1024);
119 c.sum = Checksum((uint8_t *)&c,
sizeof(c) - 1);
120 err = libusb_bulk_transfer(device,
126 CHECK_ERR(
"error during programming!");
128 err = libusb_bulk_transfer(device,
134 CHECK_ERR(
"error during programming!");
137 CHECK_ERR(
"error during programming!");
143 struct prog_end_t e = {};
144 err = libusb_bulk_transfer(device,
150 CHECK_ERR(
"error during programming stop!");
152 err = libusb_bulk_transfer(device,
158 CHECK_ERR(
"error during programming stop!");
161 CHECK_ERR(
"error during programming stop!");
164 cmd =
static_cast<uint8_t
>(H8SXCmd::USER_MAT_CHECKSUM);
165 err = libusb_bulk_transfer(device,
171 CHECK_ERR(
"error during user MAT sum check!");
172 err = libusb_bulk_transfer(device,
178 CHECK_ERR(
"error during user MAT sum check!");
179 struct sum_chk_t *chk = (
struct sum_chk_t *)buf;
180 if (chk->cmd != 0x5B &&
182 chk->sum != Checksum((uint8_t *)chk,
sizeof(
struct sum_chk_t) - 1) &&
183 bswap32(chk->chk) != bin_sum)
185 CHECK_ERR(
"error during user MAT sum check!");
191 int transferred = 0, received = 0;
192 uint8_t buf[BUF_SIZE];
196 struct dev_sel_t sel = {0};
197 sel.cmd =
static_cast<uint8_t
>(H8SXCmd::DEVICE_SELECT);
199 for (
int i = 0; i < 4; i++)
200 sel.code[i] = dir->code[i];
201 sel.sum = Checksum((uint8_t *)&sel,
sizeof(sel) - 1);
202 err = libusb_bulk_transfer(device,
208 CHECK_ERR(
"error in device selection!");
210 err = libusb_bulk_transfer(device,
216 CHECK_ERR(
"error in device selection!");
219 CHECK_ERR(
"error in device selection!");
222 uint8_t cmd =
static_cast<uint8_t
>(H8SXCmd::CLOCK_MODE_INQUIRY);
223 err = libusb_bulk_transfer(device,
229 CHECK_ERR(
"error during clock mode inquiry!");
230 err = libusb_bulk_transfer(device,
236 CHECK_ERR(
"error during clock mode inquiry!");
238 err = libusb_bulk_transfer(device,
246 uint8_t csel[] = {0x11, 0x01, 0x01, 0xed};
247 err = libusb_bulk_transfer(device,
253 CHECK_ERR(
"error during clock mode selection!");
255 err = libusb_bulk_transfer(device,
261 CHECK_ERR(
"error in clock mode selection!");
264 CHECK_ERR(
"error in clock mode selection!");
267 cmd =
static_cast<uint8_t
>(H8SXCmd::PROG_UNIT_INQUIRY);
268 err = libusb_bulk_transfer(device,
274 CHECK_ERR(
"error during programming mode inquiry!");
275 err = libusb_bulk_transfer(device,
281 CHECK_ERR(
"error during programming mode inquiry!");
283 err = libusb_bulk_transfer(device,
291 uint8_t bsel[] = {0x3f, 0x07, 0x04, 0x80, 0x06, 0x40,
292 0x02, 0x01, 0x01, 0xec};
293 err = libusb_bulk_transfer(device,
299 CHECK_ERR(
"error during bit rate selection!");
301 err = libusb_bulk_transfer(device,
307 CHECK_ERR(
"error during bit rate selection!");
310 CHECK_ERR(
"error during bit rate selection!");
313 err = libusb_bulk_transfer(device,
319 CHECK_ERR(
"error during bit rate confirmation!");
321 err = libusb_bulk_transfer(device,
327 CHECK_ERR(
"error during bit rate confirmation!");
330 CHECK_ERR(
"error during bit rate confirmation!");
333 cmd =
static_cast<uint8_t
>(H8SXCmd::BEGIN_PROGRAMMING);
334 err = libusb_bulk_transfer(device,
340 CHECK_ERR(
"error during transition to programming state!");
342 err = libusb_bulk_transfer(device,
348 CHECK_ERR(
"error during transition to programming state!");
351 CHECK_ERR(
"error during transition to programming state!");
354 cmd =
static_cast<uint8_t
>(H8SXCmd::USER_MAT_SELECT);
355 err = libusb_bulk_transfer(device,
361 CHECK_ERR(
"error during user MAT programming selection!");
363 err = libusb_bulk_transfer(device,
369 CHECK_ERR(
"error during user MAT programming selection!");
372 CHECK_ERR(
"error during user MAT programming selection!");
375auto H8SX::Init() const ->
void
380 err = libusb_reset_device(device);
381 CHECK_ERR(
"cannot reset device!");
384 err = libusb_set_auto_detach_kernel_driver(device, 0);
385 CHECK_ERR(
"cannot unset auto-detach!");
388 if (libusb_kernel_driver_active(device, 0))
390 err = libusb_detach_kernel_driver(device, 0);
391 CHECK_ERR(
"cannot detach kernel!");
395 err = libusb_set_configuration(device, 1);
396 CHECK_ERR(
"cannot set configuration!");
399 err = libusb_claim_interface(device, 0);
400 CHECK_ERR(
"cannot claim interface!");
403auto H8SX::CheckDevice() const ->
void
405 if (this->device ==
nullptr)
406 throw std::runtime_error(
"Device is not opened");
409auto H8SX::Checksum(
const uint8_t *data,
size_t len)
const -> uint8_t
412 for (
size_t i = 0; i < len; i++)