AgIsoStack++
A control-function-focused implementation of the major ISOBUS and J1939 protocols
Loading...
Searching...
No Matches
InnoMakerUsb2CanLib.h
1#pragma once
2#ifdef INNOMAKERUSB2CANLIB_EXPORTS
3#define INNOMAKERUSB2CANLIB_EXP __declspec(dllexport)
4#else
5#define INNOMAKERUSB2CANLIB_EXP __declspec(dllimport)
6#endif
7#include <iostream>
8#include "libusb.h"
9#include <vector>
10#include <atomic>
11
12// clang-format off
14
15using namespace std;
16
17class INNOMAKERUSB2CANLIB_EXP InnoMakerUsb2CanLib {
18
19public:
20 class InnoMakerDevice {
21 public:
22 libusb_device_handle *devHandle;
23 libusb_device *device;
24 bool isOpen;
25 };
26
27 struct innomaker_host_frame
28 {
29 UINT32 echo_id;
30 UINT32 can_id;
31 BYTE can_dlc;
32 BYTE channel;
33 BYTE flags;
34 BYTE reserved;
35 BYTE data[8];
36 UINT32 timestamp_us;
37 };
38
39 struct Innomaker_device_bittming
40 {
41 UINT32 prop_seg;
42 UINT32 phase_seg1;
43 UINT32 phase_seg2;
44 UINT32 sjw;
45 UINT32 brp;
46 };
47
48 enum UsbCanMode
49 {
50 UsbCanModeNormal = 0,
51 UsbCanModeLoopback,
52 UsbCanModeListenOnly,
53 };
54
55 class innomaker_tx_context
56 {
57 public:
58 UINT32 echo_id;
59 };
60
61 class spin_mutex {
62 std::atomic<bool> flag = ATOMIC_VAR_INIT(false);
63 public:
64 spin_mutex() = default;
65 spin_mutex(const spin_mutex&) = delete;
66 spin_mutex& operator= (const spin_mutex&) = delete;
67 void lock() {
68 bool expected = false;
69 while (!flag.compare_exchange_strong(expected, true))
70 expected = false;
71 }
72 void unlock() {
73 flag.store(false);
74 }
75 };
76
77 class innomaker_can
78 {
79 /* This lock prevents a race condition between xmit and receive. */
80 public:
81 spin_mutex tx_ctx_lock;
82 innomaker_tx_context tx_context[10];
83 };
84private:
85
86
87 struct innomaker_identify_mode
88 {
89 UINT32 mode;
90 };
91
92
93 struct innomaker_device_mode
94 {
95 UINT32 mode;
96 UINT32 flags;
97 };
98
99
101 struct UsbSetupPacket
102 {
103 public:
104 BYTE RequestType;
105 BYTE Request;
106 short Value;
107 short Index;
108 short Length;
109 };
110
111 static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data);
112 static int LIBUSB_CALL hotplug_callback_detach(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data);
113
114public:
115
117 bool setup();
118
120 bool setdown();
121
123 bool scanInnoMakerDevice();
124
126 int getInnoMakerDeviceCount();
127
129 InnoMakerDevice* getInnoMakerDevice(int devIndex);
130
132 bool openInnoMakerDevice(InnoMakerDevice *device);
133
135 bool closeInnoMakerDevice(InnoMakerDevice *device);
136
138 bool sendInnoMakerDeviceBuf(InnoMakerDevice *device, BYTE *buf, int size, unsigned int timeout);
139
141 bool recvInnoMakerDeviceBuf(InnoMakerDevice *device, BYTE *buf, int size, unsigned int timeout);
142
144 bool urbResetDevice(InnoMakerDevice *device);
145
147 bool urbSetupDevice(InnoMakerDevice *device, UsbCanMode canMode, Innomaker_device_bittming bittming);
148
149 InnoMakerUsb2CanLib() {
150 innoMakerDevices = new vector<InnoMakerDevice>();
151 }
152
153 ~InnoMakerUsb2CanLib() {
154 delete(innoMakerDevices);
155 }
156
157 /* Alloc a tx content */
158 innomaker_tx_context *innomaker_alloc_tx_context(innomaker_can *dev);
159
160
161 /* releases a tx context
162 */
163 void innomaker_free_tx_context(innomaker_tx_context *txc);
164
165
166 /* Get a tx context by id.
167 */
168 innomaker_tx_context *innomaker_get_tx_context(innomaker_can *dev, UINT id);
169
170private:
172 bool urbSetHostFormat(InnoMakerDevice *device);
174 bool urbSetBitrate(InnoMakerDevice *device, Innomaker_device_bittming bittming);
176 bool urbStartDevice(InnoMakerDevice *device, UsbCanMode mode);
177
178private:
180 vector<InnoMakerDevice> *innoMakerDevices;
182 int endPointOut = 2;
184 int endPointIn = 129;
186 libusb_hotplug_callback_handle hp[2];
188 UINT32 pid = 0x606f;
190 UINT32 vid = 0x1d50;
191 libusb_device **devs;
192
194 void(*addCallback)(InnoMakerDevice *device);
196 void(*removeCallback)(InnoMakerDevice *device);
197public:
198 int innomaker_MAX_TX_URBS = 10;
199};
200
201// clang-format on