radio_tool 0.2.1
Loading...
Searching...
No Matches
h8sx.hpp
1
18#pragma once
19
20#include <stdint.h>
21#include <vector>
22#include <string>
23#include <sstream>
24#include <iomanip>
25#include <iostream>
26
27#include <libusb-1.0/libusb.h>
28#include <radio_tool/h8sx/h8sx_exception.hpp>
29
30#define CHECK_ERR(errstr) \
31 do \
32 { \
33 if (err < LIBUSB_SUCCESS) \
34 { \
35 std::string e = std::string(errstr) + \
36 std::string(libusb_error_name(err)); \
37 throw radio_tool::h8sx::H8SXException(e); \
38 } \
39 } while (0)
40
41#if defined(__GNUC__)
42#define PACK(__Declaration__) __Declaration__ __attribute__((__packed__))
43#elif defined(_MSC_VER)
44#define PACK(__Declaration__) __pragma(pack(push, 1)) __Declaration__ __pragma(pack(pop))
45#endif
46
47#define BULK_EP_IN 0x82
48#define BULK_EP_OUT 0x01
49#define BUF_SIZE 64 * 1024 // Max transfer size 64KB
50
52{
53 enum class H8SXCmd : uint8_t
54 {
55 /*
56 * Begin the inquiry phase
57 */
58 BEGIN_INQUIRY = 0x55,
59
60 /*
61 * Inquiry regarding device codes
62 */
63 DEVICE_INQUIRY = 0x20,
64
65 /*
66 * Selection of device code
67 */
68 DEVICE_SELECT = 0x10,
69
70 /*
71 * Inquiry regarding numbers of clock modes
72 * and values of each mode
73 */
74 CLOCK_MODE_INQUIRY = 0x21,
75
76 /*
77 * Indication of the selected clock mode
78 */
79 CLOCK_MODE_SELECT = 0x11,
80
81 /*
82 * Inquiry regarding the unit of program data
83 */
84 PROG_UNIT_INQUIRY = 0x27,
85
86 /*
87 * Selection of new bit rate
88 */
89 BITRATE_SELECT = 0x3F,
90
91 /*
92 * Erasing of user MAT and user boot MAT, and
93 * entry to programming/erasing state
94 */
95 BEGIN_PROGRAMMING = 0x40,
96
97 /*
98 * Transfers the user MAT programming
99 * program
100 */
101 USER_MAT_SELECT = 0x43,
102
103 /*
104 * Programs 128 bytes of data
105 */
106 PROGRAM_128B = 0x50,
107
108 /*
109 * Checks the checksum of the user MAT
110 */
111 USER_MAT_CHECKSUM = 0x4B,
112 };
113
114 // Supported device inquiry response
115 PACK(struct dev_inq_hdr_t {
116 uint8_t cmd = 0;
117 uint8_t size = 0;
118 uint8_t ndev = 0;
119 uint8_t nchar = 0;
120 char code[4] = {0};
121 });
122
123 PACK(struct dev_sel_t {
124 uint8_t cmd = 0;
125 uint8_t size = 0;
126 char code[4] = {0};
127 uint8_t sum = 0;
128 });
129
130 PACK(struct prog_chunk_t {
131 uint8_t cmd = static_cast<uint8_t>(H8SXCmd::PROGRAM_128B);
132 uint32_t addr = 0;
133 uint8_t data[1024] = {0};
134 uint8_t sum = 0;
135 });
136
137 PACK(struct prog_end_t {
138 uint8_t cmd = static_cast<uint8_t>(H8SXCmd::PROGRAM_128B);
139 uint32_t addr = 0xffffffff;
140 uint8_t sum = 0xb4;
141 });
142
143 PACK(struct sum_chk_t {
144 uint8_t cmd;
145 uint8_t size;
146 uint32_t chk;
147 uint8_t sum;
148 });
149
150 class H8SX
151 {
152 public:
153 H8SX(libusb_device_handle *device)
154 : timeout(5000), device(device) {}
155
156 auto Init() const -> void;
157 auto IdentifyDevice() const -> std::string;
158 auto Download(const std::vector<uint8_t> &) const -> void;
159
160 private:
161 libusb_context *usb_ctx;
162
163 auto GetDeviceString(const libusb_device_descriptor &, libusb_device_handle *) const -> std::wstring;
164 auto Checksum(const uint8_t *data, const size_t len) const -> uint8_t;
165
166 protected:
167 const uint16_t timeout;
168 libusb_device_handle *device;
169 struct dev_inq_hdr_t *dir;
170
171 auto CheckDevice() const -> void;
172
176 auto InitDownload() const -> void;
177
181 auto InitUpload() const -> void;
182 };
183} // namespace radio_tool::h8sx
auto InitUpload() const -> void
auto InitDownload() const -> void
Definition: h8sx.cpp:188