Skip to content

Commit e19e380

Browse files
committed
Implement device enumeration for GlasgowSWDInterface.
1 parent 34f7f09 commit e19e380

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

GlasgowSWDInterface.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
@brief Implementation of GlasgowSWDInterface
3434
*/
3535

36+
#include <functional>
3637
#include "jtaghal.h"
3738

3839
#if HAVE_LIBUSB
@@ -42,6 +43,124 @@
4243

4344
using namespace std;
4445

46+
static void ForEachGlasgowDevice(std::function<bool(libusb_device_descriptor *, libusb_device_handle *)> fn)
47+
{
48+
int ret;
49+
50+
libusb_context *context;
51+
if((ret = libusb_init(&context)) != 0) {
52+
throw JtagExceptionWrapper(
53+
"libusb_init failed",
54+
libusb_error_name(ret));
55+
}
56+
57+
ssize_t device_count;
58+
libusb_device **device_list;
59+
if((device_count = libusb_get_device_list(context, &device_list)) < 0) {
60+
libusb_exit(context);
61+
62+
throw JtagExceptionWrapper(
63+
"libusb_get_device_list failed",
64+
libusb_error_name(device_count));
65+
}
66+
67+
for(int i = 0; i < device_count; i++) {
68+
libusb_device *device = device_list[i];
69+
libusb_device_descriptor device_desc;
70+
if((ret = libusb_get_device_descriptor(device, &device_desc)) != 0) {
71+
LogError("Cannot get USB device descriptor for device %03d:%03d\n",
72+
libusb_get_bus_number(device),
73+
libusb_get_port_number(device));
74+
continue;
75+
}
76+
77+
if(device_desc.idVendor != VID_QIHW || device_desc.idProduct != PID_GLASGOW)
78+
continue;
79+
80+
libusb_device_handle *device_handle;
81+
if((ret = libusb_open(device, &device_handle)) != 0) {
82+
LogError("Cannot open Glasgow device %03d:%03d\n",
83+
libusb_get_bus_number(device),
84+
libusb_get_port_number(device));
85+
continue;
86+
}
87+
88+
bool done = fn(&device_desc, device_handle);
89+
90+
libusb_close(device_handle);
91+
92+
if(done) break;
93+
}
94+
95+
libusb_free_device_list(device_list, /*unref_devices=*/true);
96+
97+
libusb_exit(context);
98+
}
99+
100+
int GlasgowSWDInterface::GetInterfaceCount()
101+
{
102+
int count = 0;
103+
104+
ForEachGlasgowDevice([&](libusb_device_descriptor *, libusb_device_handle *) {
105+
count++;
106+
return false;
107+
});
108+
109+
return count;
110+
}
111+
112+
string GlasgowSWDInterface::GetAPIVersion()
113+
{
114+
return "";
115+
}
116+
117+
string GlasgowSWDInterface::GetSerialNumber(int index)
118+
{
119+
int ret;
120+
int curr_index = 0;
121+
char device_serial[64] = {};
122+
123+
ForEachGlasgowDevice([&](libusb_device_descriptor *desc, libusb_device_handle *handle) {
124+
if(curr_index == index) {
125+
if((ret = libusb_get_string_descriptor_ascii(handle, desc->iSerialNumber,
126+
(uint8_t *)device_serial, sizeof(device_serial))) != 0) {
127+
strncpy(device_serial, "(error)", sizeof(device_serial));
128+
}
129+
130+
return true;
131+
} else {
132+
index++;
133+
return false;
134+
}
135+
});
136+
137+
return device_serial;
138+
}
139+
140+
string GlasgowSWDInterface::GetDescription(int index)
141+
{
142+
int curr_index = 0;
143+
uint16_t revision = 0;
144+
145+
ForEachGlasgowDevice([&](libusb_device_descriptor *desc, libusb_device_handle *) {
146+
if(curr_index == index) {
147+
revision = desc->bcdDevice;
148+
149+
return true;
150+
} else {
151+
index++;
152+
return false;
153+
}
154+
});
155+
156+
string description = "Glasgow rev";
157+
description += 'A' + (revision & 0xff) - 1;
158+
if((revision >> 8) == 0xa0 || (revision >> 8) == 0x00) {
159+
description += " (no firmware)";
160+
}
161+
return description;
162+
}
163+
45164
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46165
// Construction / destruction
47166

GlasgowSWDInterface.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
class GlasgowSWDInterface : public SWDInterface
5050
{
5151
public:
52+
static int GetInterfaceCount();
53+
static std::string GetAPIVersion();
54+
static std::string GetSerialNumber(int index);
55+
static std::string GetDescription(int index);
56+
5257
GlasgowSWDInterface(const std::string& serial);
5358
virtual ~GlasgowSWDInterface();
5459

0 commit comments

Comments
 (0)