blob: f2ad2f8515c8e2bca8420e484886d2fe3950fa55 [file] [log] [blame]
Austin Schuh9b360e92013-03-27 04:47:04 +00001#include "get.h"
2
Austin Schuh9b360e92013-03-27 04:47:04 +00003#include <stdio.h>
Austin Schuh9b360e92013-03-27 04:47:04 +00004#include <unistd.h>
Brian Silverman798c7782013-03-28 16:48:02 -07005#include <inttypes.h>
6#include <string.h>
7
8#include <queue>
9#include <iostream>
Austin Schuh9b360e92013-03-27 04:47:04 +000010#include <map>
11
Brian Silverman798c7782013-03-28 16:48:02 -070012#include <google/gflags.h>
13#include "aos/common/mutex.h"
14#include "aos/common/logging/logging_impl.h"
Austin Schuh9b360e92013-03-27 04:47:04 +000015
16DEFINE_int32(vid, 0x1424, "Vendor ID of the device.");
17DEFINE_int32(pid, 0xd243, "Product ID of the device.");
18DEFINE_bool(send, true,
19 "True if the code should send packets. (default: true)");
20
21// USB descriptors in use:
22// 0x81 Interrupt IN endpoint with the received CAN packets.
23// These packets are 64 bytes maximum, and have the same format as
24// SocketCAN.
25// 0x04 Interrupt OUT endpoint with the CAN packets to send.
26// These packets are 64 bytes maximum, and have the same format as
27// SocketCAN.
28// 0x82 Bulk IN endpoint with printf output.
29// 0x05 Bulk OUT endpoint for stdin.
30
31bool can_frame_priority_comparator::operator() (
32 const struct can_frame& x,
33 const struct can_frame& y) const {
34 // Error frames win first.
35 if (x.can_id & CAN_EFF_FLAG) {
36 return false;
37 }
38 if (y.can_id & CAN_EFF_FLAG) {
39 return true;
40 }
41 // Extended frames send the first 11 bits out just like a standard frame.
42 int x_standard_bits = (x.can_id & CAN_SFF_MASK);
43 int y_standard_bits = (y.can_id & CAN_SFF_MASK);
44 if (x_standard_bits == y_standard_bits) {
45 // RTR wins next.
46 bool x_rtr = (x.can_id & CAN_RTR_FLAG);
47 bool y_rtr = (y.can_id & CAN_RTR_FLAG);
48 if (x_rtr == y_rtr) {
49 // Now check if it is an EFF packet.
50 bool x_eff = (x.can_id & CAN_EFF_FLAG);
51 bool y_eff = (y.can_id & CAN_EFF_FLAG);
52 if (x_eff == y_eff) {
53 // Now compare the bits in the extended frame.
54 return (x.can_id & CAN_EFF_MASK) < (y.can_id & CAN_EFF_MASK);
55 } else if (x_eff < y_eff) {
56 return false;
57 } else {
58 return true;
59 }
60 } else if (x_rtr < y_rtr) {
61 return true;
62 } else {
63 return false;
64 }
65 } else {
66 return x_standard_bits < y_standard_bits;
67 }
68}
69
Brian Silverman798c7782013-03-28 16:48:02 -070070class GyroDriver::PacketReceiver : public ::aos::util::Thread {
Austin Schuh9b360e92013-03-27 04:47:04 +000071 public:
72 // refusing to send any more frames.
73 static const int kMaxRXFrames = 128;
74
75 explicit PacketReceiver(LibUSBDeviceHandle *dev_handle)
76 : Thread(), dev_handle_(dev_handle), rx_queue_(new can_priority_queue) {}
77
78 // Serve.
Brian Silverman798c7782013-03-28 16:48:02 -070079 virtual void Run();
Austin Schuh9b360e92013-03-27 04:47:04 +000080
81 bool GetCanFrame(struct can_frame *msg);
82
83 private:
84 typedef std::priority_queue<struct can_frame,
85 std::vector<struct can_frame>,
86 can_frame_priority_comparator> can_priority_queue;
87
88 LibUSBDeviceHandle *dev_handle_;
Brian Silverman798c7782013-03-28 16:48:02 -070089 ::aos::Mutex rx_mutex_;
Austin Schuh9b360e92013-03-27 04:47:04 +000090 std::unique_ptr<can_priority_queue> rx_queue_;
Austin Schuh9b360e92013-03-27 04:47:04 +000091};
92
93GyroDriver::GyroDriver(LibUSBDeviceHandle *dev_handle)
94 : dev_handle_(dev_handle), dbg_(new DbgReader(this)),
Brian Silverman798c7782013-03-28 16:48:02 -070095 rx_(new GyroDriver::PacketReceiver(dev_handle)) {}
Austin Schuh9b360e92013-03-27 04:47:04 +000096
97
98std::string GyroDriver::GetDebugData() {
99 char data[64];
100 int r;
101 int transferred;
102 r = dev_handle_->bulk_transfer(0x82,
103 (unsigned char *)data, sizeof(data),
104 &transferred, 0);
105 return std::string(data, transferred);
106}
107
Austin Schuh9b360e92013-03-27 04:47:04 +0000108GyroDriver::~GyroDriver() {
Brian Silverman798c7782013-03-28 16:48:02 -0700109 rx_->Join();
110 dbg_->Join();
Austin Schuh9b360e92013-03-27 04:47:04 +0000111}
112
113//bool GyroDriver::GetCanFrame(struct can_frame *msg) {
114// return rx_->GetCanFrame(msg);
115//}
116
117struct DataStruct{
118 int64_t gyro_angle;
119
120 int32_t right_drive;
121 int32_t left_drive;
122 int32_t shooter_angle;
123 int32_t shooter;
124 int32_t indexer;
125 int32_t wrist;
126
127 int32_t capture_top_rise;
128 int32_t capture_top_fall;
129 int32_t capture_bottom_fall_delay;
130 int32_t capture_wrist_rise;
131 int32_t capture_shooter_angle_rise;
132
133 int8_t top_rise_count;
134
135 int8_t top_fall_count;
136
137 int8_t bottom_rise_count;
138
139 int8_t bottom_fall_delay_count;
140 int8_t bottom_fall_count;
141
142 int8_t wrist_rise_count;
143
144 int8_t shooter_angle_rise_count;
145} __attribute__((__packed__));
146
Brian Silverman798c7782013-03-28 16:48:02 -0700147void GyroDriver::PacketReceiver::Run() {
148 int r;
149 int actual;
150 uint8_t data[64];
Austin Schuh9b360e92013-03-27 04:47:04 +0000151 DataStruct *real_data;
Brian Silverman798c7782013-03-28 16:48:02 -0700152 static_assert(sizeof(*real_data) <= sizeof(data), "it doesn't fit");
153
154 uint8_t *data_pointer = data;
155 memcpy(&real_data, &data_pointer, sizeof(data_pointer));
Austin Schuh9b360e92013-03-27 04:47:04 +0000156
Brian Silverman798c7782013-03-28 16:48:02 -0700157 while (should_continue()) {
Austin Schuh9b360e92013-03-27 04:47:04 +0000158 r = dev_handle_->interrupt_transfer(
159 0x81, data, sizeof(data), &actual, 1000);
160 printf("size: %d\n",sizeof(DataStruct));
Brian Silverman798c7782013-03-28 16:48:02 -0700161 if (actual <= 0) {
162 LOG(FATAL, "didn't get any data\n");
Austin Schuh9b360e92013-03-27 04:47:04 +0000163 }
164
Brian Silverman798c7782013-03-28 16:48:02 -0700165 if (r != 0) {
166 LOG(ERROR, "Read Error. Read %d\n", actual);
167 }
168
169 printf("angle: %"PRId64"\n", real_data->gyro_angle);
Austin Schuh9b360e92013-03-27 04:47:04 +0000170 printf("drivel: %d\n", real_data->left_drive);
171 printf("driver: %d\n", real_data->right_drive);
172 printf("shooter: %d\n", real_data->shooter);
173 printf("shooter_angle: %d\n", real_data->shooter_angle);
174 printf("indexer: %d\n", real_data->indexer);
175 printf("wrist: %d\n", real_data->wrist);
176 printf("capture:\n");
177 printf(" wrist_rise{%d}: %d\n", real_data->wrist_rise_count,
178 real_data->capture_wrist_rise);
179 printf(" shooter_angle_rise{%d}: %d\n", real_data->shooter_angle_rise_count,
180 real_data->capture_shooter_angle_rise);
181 printf(" bottom_rise_delay{%d}; \n", real_data->bottom_rise_count);
182 printf(" bottom_fall_delay{%d,%d}: %d\n", real_data->bottom_fall_count,
183 real_data->bottom_fall_delay_count,
184 real_data->capture_bottom_fall_delay);
185 printf(" top_rise{%d}: %d\n", real_data->top_rise_count,
186 real_data->capture_top_rise);
187 printf(" top_fall{%d}: %d\n", real_data->top_fall_count,
188 real_data->capture_top_fall);
189
190
191
192
193 //if (actual > 1) {
194 // rx_cond_.notify_all();
195 //}
196 }
197 //rx_cond_.notify_all();
Brian Silverman798c7782013-03-28 16:48:02 -0700198 LOG(INFO, "Receive thread down.");
Austin Schuh9b360e92013-03-27 04:47:04 +0000199}
200
201DbgReader::DbgReader(GyroDriver *gyro)
202 : Thread(), gyro_(gyro) {}
203
Brian Silverman798c7782013-03-28 16:48:02 -0700204void DbgReader::Run() {
205 LOG(INFO, "Running debug dump thread.");
206 while (should_continue()) {
Austin Schuh9b360e92013-03-27 04:47:04 +0000207 printf("%s", gyro_->GetDebugData().c_str());
208 }
Brian Silverman798c7782013-03-28 16:48:02 -0700209 LOG(INFO, "Exiting debug dump thread.");
Austin Schuh9b360e92013-03-27 04:47:04 +0000210}
211
212
213int main(int argc, char ** argv) {
Austin Schuh9b360e92013-03-27 04:47:04 +0000214 google::ParseCommandLineFlags(&argc, &argv, true);
Brian Silverman798c7782013-03-28 16:48:02 -0700215 ::aos::logging::Init();
Austin Schuh9b360e92013-03-27 04:47:04 +0000216
217 LibUSB libusb;
218
219 {
220 std::unique_ptr<LibUSBDeviceHandle> dev_handle(
Brian Silverman798c7782013-03-28 16:48:02 -0700221 libusb.FindDeviceWithVIDPID(FLAGS_vid, FLAGS_pid));
222 if (!dev_handle) {
223 LOG(FATAL, "couldn't find device\n");
224 }
Austin Schuh9b360e92013-03-27 04:47:04 +0000225
226 GyroDriver gyro(dev_handle.release());
227
228 while(true){
229 sleep(50);
230 }
231 }
232 return 0;
233}