summaryrefslogtreecommitdiff
path: root/utils/regtools/qeditor
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-02-04 00:18:51 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2014-02-10 23:14:25 +0100
commit0e0c610df0d3d4044d0b21ddc1752a5dacd7f86e (patch)
treeaca4cf3c5dd86384ee8018d9049e2c3469d597ea /utils/regtools/qeditor
parent81dfed27cf7ca1008b9cf21c084310eaeae082ac (diff)
downloadrockbox-0e0c610df0d3d4044d0b21ddc1752a5dacd7f86e.tar.gz
rockbox-0e0c610df0d3d4044d0b21ddc1752a5dacd7f86e.zip
utils/regtools: make qeditor able to poke directly at a hwstub device
This commit add the very handy feature of being able to read registers directly from a device using hwstub. This is mostly trivial using the hwstub library and the biggest change here is actually: - being able to read registers by name and/or addresses - being able to enumerate devives The UI code currently doesn't handle hotplug but the backend does so it should be trivial to add in the future. It also opens up the possibility the write registers from hwstub or save the register values to a file. Since it relies on both hwstub and libusb, a switch has been introduced in qmake to disable it (use -config nohwstub). Change-Id: I5d7d7a2a7c97ecd7407227357c8553c2773ea6cc
Diffstat (limited to 'utils/regtools/qeditor')
-rw-r--r--utils/regtools/qeditor/backend.cpp317
-rw-r--r--utils/regtools/qeditor/backend.h113
-rw-r--r--utils/regtools/qeditor/main.cpp7
-rw-r--r--utils/regtools/qeditor/qeditor.pro14
-rw-r--r--utils/regtools/qeditor/regtab.cpp65
-rw-r--r--utils/regtools/qeditor/regtab.h11
6 files changed, 486 insertions, 41 deletions
diff --git a/utils/regtools/qeditor/backend.cpp b/utils/regtools/qeditor/backend.cpp
index e011965bd2..d2b75be701 100644
--- a/utils/regtools/qeditor/backend.cpp
+++ b/utils/regtools/qeditor/backend.cpp
@@ -3,6 +3,10 @@
3#include <QDebug> 3#include <QDebug>
4#include "backend.h" 4#include "backend.h"
5 5
6/**
7 * Backend
8 */
9
6Backend::Backend() 10Backend::Backend()
7{ 11{
8} 12}
@@ -43,9 +47,16 @@ IoBackend *Backend::CreateDummyIoBackend()
43 return new DummyIoBackend(); 47 return new DummyIoBackend();
44} 48}
45 49
46IoBackend::IoBackend() 50#ifdef HAVE_HWSTUB
51IoBackend *Backend::CreateHWStubIoBackend(HWStubDevice *dev)
47{ 52{
53 return new HWStubIoBackend(dev);
48} 54}
55#endif
56
57/**
58 * FileIoBackend
59 */
49 60
50FileIoBackend::FileIoBackend(const QString& filename) 61FileIoBackend::FileIoBackend(const QString& filename)
51{ 62{
@@ -91,27 +102,230 @@ bool FileIoBackend::Reload()
91 return true; 102 return true;
92} 103}
93 104
94DummyIoBackend::DummyIoBackend() 105#ifdef HAVE_HWSTUB
106/**
107 * HWStubDevice
108 */
109HWStubDevice::HWStubDevice(struct libusb_device *dev)
95{ 110{
111 libusb_ref_device(dev);
112 m_dev = dev;
113 m_handle = 0;
114 m_hwdev = 0;
115 m_valid = Probe();
96} 116}
97 117
98QString DummyIoBackend::GetSocName() 118HWStubDevice::~HWStubDevice()
99{ 119{
100 return ""; 120 Close();
121 libusb_unref_device(m_dev);
101} 122}
102 123
103bool DummyIoBackend::ReadRegister(const QString& name, soc_word_t& value) 124int HWStubDevice::GetBusNumber()
104{ 125{
105 (void) name; 126 return libusb_get_bus_number(m_dev);
106 (void) value; 127}
128
129int HWStubDevice::GetDevAddress()
130{
131 return libusb_get_device_address(m_dev);
132}
133
134bool HWStubDevice::Probe()
135{
136 struct libusb_device_descriptor desc;
137 if(libusb_get_device_descriptor(m_dev, &desc))
138 return false;
139 if(desc.idVendor != HWSTUB_USB_VID || desc.idProduct != HWSTUB_USB_PID)
140 return false;
141 if(!Open())
142 return false;
143 int ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_VERSION, &m_hwdev_ver, sizeof(m_hwdev_ver));
144 if(ret != sizeof(m_hwdev_ver))
145 goto Lerr;
146 if(m_hwdev_ver.bMajor != HWSTUB_VERSION_MAJOR || m_hwdev_ver.bMinor < HWSTUB_VERSION_MINOR)
147 goto Lerr;
148 // get target
149 ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_TARGET, &m_hwdev_target, sizeof(m_hwdev_target));
150 if(ret != sizeof(m_hwdev_target))
151 goto Lerr;
152 // get STMP information
153 if(m_hwdev_target.dID == HWSTUB_TARGET_STMP)
154 {
155 ret = hwstub_get_desc(m_hwdev, HWSTUB_DT_STMP, &m_hwdev_stmp, sizeof(m_hwdev_stmp));
156 if(ret != sizeof(m_hwdev_stmp))
157 goto Lerr;
158 }
159 Close();
160 return true;
161
162 Lerr:
163 Close();
107 return false; 164 return false;
108} 165}
109 166
110bool DummyIoBackend::Reload() 167bool HWStubDevice::Open()
168{
169 if(libusb_open(m_dev, &m_handle))
170 return false;
171 m_hwdev = hwstub_open(m_handle);
172 if(m_hwdev == 0)
173 {
174 libusb_close(m_handle);
175 return false;
176 }
177 return true;
178}
179
180void HWStubDevice::Close()
181{
182 if(m_hwdev)
183 hwstub_release(m_hwdev);
184 m_hwdev = 0;
185 if(m_handle)
186 libusb_close(m_handle);
187 m_handle = 0;
188}
189
190bool HWStubDevice::ReadMem(soc_addr_t addr, size_t length, void *buffer)
191{
192 if(!m_hwdev)
193 return false;
194 int ret = hwstub_rw_mem(m_hwdev, 1, addr, buffer, length);
195 return ret >= 0 && (size_t)ret == length;
196}
197
198bool HWStubDevice::IsValid()
199{
200 return m_valid;
201}
202
203
204/**
205 * HWStubIoBackend
206 */
207
208HWStubIoBackend::HWStubIoBackend(HWStubDevice *dev)
209{
210 m_dev = dev;
211 m_dev->Open();
212 struct hwstub_target_desc_t target = m_dev->GetTargetInfo();
213 if(target.dID == HWSTUB_TARGET_STMP)
214 {
215 struct hwstub_stmp_desc_t stmp = m_dev->GetSTMPInfo();
216 if(stmp.wChipID == 0x3780)
217 m_soc = "imx233";
218 else if(stmp.wChipID >= 0x3700 && stmp.wChipID < 0x3780)
219 m_soc = "stmp3700";
220 else if(stmp.wChipID >= 0x3600 && stmp.wChipID < 0x3700)
221 m_soc = "stmp3600";
222 else
223 m_soc = QString("stmp%1").arg(stmp.wChipID, 4, 16, QChar('0'));
224 }
225 else if(target.dID == HWSTUB_TARGET_RK27)
226 m_soc = "rk27x";
227 else
228 m_soc = target.bName;
229}
230
231QString HWStubIoBackend::GetSocName()
232{
233 return m_soc;
234}
235
236HWStubIoBackend::~HWStubIoBackend()
237{
238 m_dev->Close();
239}
240
241bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value)
242{
243 return m_dev->ReadMem(addr, sizeof(value), &value);
244}
245
246bool HWStubIoBackend::Reload()
111{ 247{
112 return true; 248 return true;
113} 249}
114 250
251/**
252 * HWStubBackendHelper
253 */
254HWStubBackendHelper::HWStubBackendHelper()
255{
256 libusb_init(NULL);
257#ifdef LIBUSB_NO_HOTPLUG
258 m_hotplug = false;
259#else
260 m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG);
261 if(m_hotplug)
262 {
263 m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback(
264 NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
265 LIBUSB_HOTPLUG_ENUMERATE, HWSTUB_USB_VID, HWSTUB_USB_PID, HWSTUB_CLASS,
266 &HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this), &m_hotplug_handle);
267 }
268#endif
269}
270
271HWStubBackendHelper::~HWStubBackendHelper()
272{
273#ifndef LIBUSB_NO_HOTPLUG
274 if(m_hotplug)
275 libusb_hotplug_deregister_callback(NULL, m_hotplug_handle);
276#endif
277}
278
279QList< HWStubDevice* > HWStubBackendHelper::GetDevList()
280{
281 QList< HWStubDevice* > list;
282 libusb_device **dev_list;
283 ssize_t cnt = libusb_get_device_list(NULL, &dev_list);
284 for(int i = 0; i < cnt; i++)
285 {
286 HWStubDevice *dev = new HWStubDevice(dev_list[i]);
287 /* filter out non-hwstub devices */
288 if(dev->IsValid())
289 list.push_back(dev);
290 else
291 delete dev;
292 }
293 libusb_free_device_list(dev_list, 1);
294 return list;
295}
296
297#ifndef LIBUSB_NO_HOTPLUG
298void HWStubBackendHelper::OnHotPlug(bool arrived, struct libusb_device *dev)
299{
300 /* signal it */
301 emit OnDevListChanged(arrived, dev);
302}
303
304int HWStubBackendHelper::HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev,
305 libusb_hotplug_event event, void *user_data)
306{
307 HWStubBackendHelper *helper = reinterpret_cast< HWStubBackendHelper* >(user_data);
308 switch(event)
309 {
310 case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: helper->OnHotPlug(true, dev); break;
311 case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: helper->OnHotPlug(false, dev); break;
312 default: break;
313 }
314 return 0;
315}
316#endif
317
318bool HWStubBackendHelper::HasHotPlugSupport()
319{
320 return m_hotplug;
321}
322
323#endif
324
325/**
326 * BackendHelper
327 */
328
115BackendHelper::BackendHelper(IoBackend *io_backend, const soc_t& soc) 329BackendHelper::BackendHelper(IoBackend *io_backend, const soc_t& soc)
116 :m_io_backend(io_backend), m_soc(soc) 330 :m_io_backend(io_backend), m_soc(soc)
117{ 331{
@@ -119,38 +333,87 @@ BackendHelper::BackendHelper(IoBackend *io_backend, const soc_t& soc)
119 333
120bool BackendHelper::ReadRegister(const QString& dev, const QString& reg, soc_word_t& v) 334bool BackendHelper::ReadRegister(const QString& dev, const QString& reg, soc_word_t& v)
121{ 335{
122 return m_io_backend->ReadRegister("HW." + dev + "." + reg, v); 336 if(m_io_backend->SupportAccess(IoBackend::ByName))
337 return m_io_backend->ReadRegister("HW." + dev + "." + reg, v);
338 if(m_io_backend->SupportAccess(IoBackend::ByAddress))
339 {
340 soc_addr_t addr;
341 if(GetRegisterAddress(dev, reg, addr))
342 return m_io_backend->ReadRegister(addr, v);
343 }
344 return false;
123} 345}
124 346
125bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg, 347
126 const QString& field, soc_word_t& v) 348bool BackendHelper::GetDeviceDesc(const QString& dev, soc_dev_t& dev_desc, size_t& index)
127{ 349{
128 soc_dev_t *sdev = 0;
129 for(size_t i = 0; i < m_soc.dev.size(); i++) 350 for(size_t i = 0; i < m_soc.dev.size(); i++)
130 { 351 {
131 for(size_t j = 0; j < m_soc.dev[i].addr.size(); j++) 352 for(size_t j = 0; j < m_soc.dev[i].addr.size(); j++)
132 if(m_soc.dev[i].addr[j].name.c_str() == dev) 353 if(m_soc.dev[i].addr[j].name.c_str() == dev)
133 sdev = &m_soc.dev[i]; 354 {
355 dev_desc = m_soc.dev[i];
356 index = j;
357 return true;
358 }
134 } 359 }
135 if(sdev == 0) 360 return false;
136 return false; 361}
137 soc_reg_t *sreg = 0; 362
138 for(size_t i = 0; i < sdev->reg.size(); i++) 363bool BackendHelper::GetRegisterDesc(const soc_dev_t& dev, const QString& reg,
364 soc_reg_t& reg_desc, size_t& index)
365{
366 for(size_t i = 0; i < dev.reg.size(); i++)
139 { 367 {
140 for(size_t j = 0; j < sdev->reg[i].addr.size(); j++) 368 for(size_t j = 0; j < dev.reg[i].addr.size(); j++)
141 if(sdev->reg[i].addr[j].name.c_str() == reg) 369 if(dev.reg[i].addr[j].name.c_str() == reg)
142 sreg = &sdev->reg[i]; 370 {
371 index = j;
372 reg_desc = dev.reg[i];
373 return true;
374 }
143 } 375 }
144 if(sreg == 0) 376 return false;
377}
378
379bool BackendHelper::GetFieldDesc(const soc_reg_t& reg_desc, const QString& field,
380 soc_reg_field_t& field_desc)
381{
382 for(size_t i = 0; i < reg_desc.field.size(); i++)
383 if(reg_desc.field[i].name.c_str() == field)
384 field_desc = reg_desc.field[i];
385 return false;
386}
387
388bool BackendHelper::GetRegisterAddress(const QString& dev, const QString& reg,
389 soc_addr_t& addr)
390{
391 size_t dev_index, reg_index;
392 soc_dev_t dev_desc;
393 soc_reg_t reg_desc;
394 if(!GetDeviceDesc(dev, dev_desc, dev_index))
395 return false;
396 if(!GetRegisterDesc(dev_desc, reg, reg_desc, reg_index))
397 return false;
398 addr = dev_desc.addr[dev_index].addr + reg_desc.addr[reg_index].addr;
399 return true;
400}
401
402bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg,
403 const QString& field, soc_word_t& v)
404{
405 size_t dev_index, reg_index;
406 soc_dev_t dev_desc;
407 soc_reg_t reg_desc;
408 soc_reg_field_t field_desc;
409 if(!GetDeviceDesc(dev, dev_desc, dev_index))
410 return false;
411 if(!GetRegisterDesc(dev_desc, reg, reg_desc, reg_index))
145 return false; 412 return false;
146 soc_reg_field_t *sfield = 0; 413 if(!GetFieldDesc(reg_desc, field, field_desc))
147 for(size_t i = 0; i < sreg->field.size(); i++)
148 if(sreg->field[i].name.c_str() == field)
149 sfield = &sreg->field[i];
150 if(sfield == 0)
151 return false; 414 return false;
152 if(!ReadRegister(dev, reg, v)) 415 if(!ReadRegister(dev, reg, v))
153 return false; 416 return false;
154 v = (v & sfield->bitmask()) >> sfield->first_bit; 417 v = (v & field_desc.bitmask()) >> field_desc.first_bit;
155 return true; 418 return true;
156} \ No newline at end of file 419} \ No newline at end of file
diff --git a/utils/regtools/qeditor/backend.h b/utils/regtools/qeditor/backend.h
index 536eb8cec5..55f31cce52 100644
--- a/utils/regtools/qeditor/backend.h
+++ b/utils/regtools/qeditor/backend.h
@@ -4,16 +4,29 @@
4#include <QObject> 4#include <QObject>
5#include <QStringList> 5#include <QStringList>
6#include <QMap> 6#include <QMap>
7#include <QVector>
7#include "soc_desc.hpp" 8#include "soc_desc.hpp"
9#ifdef HAVE_HWSTUB
10#include "hwstub.h"
11#endif
8 12
9class IoBackend : public QObject 13class IoBackend : public QObject
10{ 14{
11 Q_OBJECT 15 Q_OBJECT
12public: 16public:
13 IoBackend(); 17 IoBackend() {}
18 virtual ~IoBackend() {}
14 19
20 enum AccessType
21 {
22 ByName,
23 ByAddress,
24 };
25
26 virtual bool SupportAccess(AccessType type) = 0;
15 virtual QString GetSocName() = 0; 27 virtual QString GetSocName() = 0;
16 virtual bool ReadRegister(const QString& name, soc_word_t& value) = 0; 28 virtual bool ReadRegister(const QString& name, soc_word_t& value) = 0;
29 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value) = 0;
17 virtual bool Reload() = 0; 30 virtual bool Reload() = 0;
18}; 31};
19 32
@@ -21,11 +34,15 @@ class DummyIoBackend : public IoBackend
21{ 34{
22 Q_OBJECT 35 Q_OBJECT
23public: 36public:
24 DummyIoBackend(); 37 DummyIoBackend() {}
25 38
26 virtual QString GetSocName(); 39 virtual bool SupportAccess(AccessType type) { (void) type; return false; }
27 virtual bool ReadRegister(const QString& name, soc_word_t& value); 40 virtual QString GetSocName() { return ""; }
28 virtual bool Reload(); 41 virtual bool ReadRegister(const QString& name, soc_word_t& value)
42 { (void) name; (void) value; return false; }
43 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value)
44 { (void) addr; (void) value; return false; }
45 virtual bool Reload() { return false; }
29}; 46};
30 47
31class FileIoBackend : public IoBackend 48class FileIoBackend : public IoBackend
@@ -34,8 +51,11 @@ class FileIoBackend : public IoBackend
34public: 51public:
35 FileIoBackend(const QString& filename); 52 FileIoBackend(const QString& filename);
36 53
54 virtual bool SupportAccess(AccessType type) { return type == ByName; }
37 virtual QString GetSocName(); 55 virtual QString GetSocName();
38 virtual bool ReadRegister(const QString& name, soc_word_t& value); 56 virtual bool ReadRegister(const QString& name, soc_word_t& value);
57 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value)
58 { (void) addr; (void) value; return false; }
39 virtual bool Reload(); 59 virtual bool Reload();
40 60
41protected: 61protected:
@@ -44,6 +64,82 @@ protected:
44 QMap< QString, soc_word_t > m_map; 64 QMap< QString, soc_word_t > m_map;
45}; 65};
46 66
67#ifdef HAVE_HWSTUB
68class HWStubDevice
69{
70public:
71 HWStubDevice(struct libusb_device *dev);
72 ~HWStubDevice();
73 bool IsValid();
74 bool Open();
75 void Close();
76 int GetBusNumber();
77 int GetDevAddress();
78 /* Calls below are cached and do not require the device to be opened */
79 inline struct hwstub_version_desc_t GetVersionInfo() { return m_hwdev_ver; }
80 inline struct hwstub_target_desc_t GetTargetInfo() { return m_hwdev_target; }
81 inline struct hwstub_stmp_desc_t GetSTMPInfo() { return m_hwdev_stmp; }
82 /* Calls below require the device to be opened */
83 bool ReadMem(soc_addr_t addr, size_t length, void *buffer);
84
85protected:
86 bool Probe();
87
88 bool m_valid;
89 struct libusb_device *m_dev;
90 libusb_device_handle *m_handle;
91 struct hwstub_device_t *m_hwdev;
92 struct hwstub_version_desc_t m_hwdev_ver;
93 struct hwstub_target_desc_t m_hwdev_target;
94 struct hwstub_stmp_desc_t m_hwdev_stmp;
95};
96
97class HWStubIoBackend : public IoBackend
98{
99 Q_OBJECT
100public:
101 HWStubIoBackend(HWStubDevice *dev);
102 virtual ~HWStubIoBackend();
103
104 virtual bool SupportAccess(AccessType type) { return type == ByAddress; }
105 virtual QString GetSocName();
106 virtual bool ReadRegister(const QString& name, soc_word_t& value)
107 { (void) name; (void) value; return false; }
108 virtual bool ReadRegister(soc_addr_t addr, soc_word_t& value);
109 virtual bool Reload();
110
111protected:
112 QString m_soc;
113 HWStubDevice *m_dev;
114};
115
116#if LIBUSB_API_VERSION < 0x01000102
117#define LIBUSB_NO_HOTPLUG
118#endif
119
120class HWStubBackendHelper : public QObject
121{
122 Q_OBJECT
123public:
124 HWStubBackendHelper();
125 ~HWStubBackendHelper();
126 bool HasHotPlugSupport();
127 QList< HWStubDevice* > GetDevList();
128
129signals:
130 void OnDevListChanged(bool arrived, struct libusb_device *dev);
131
132protected:
133#ifndef LIBUSB_NO_HOTPLUG
134 void OnHotPlug(bool arrived, struct libusb_device *dev);
135 static int HotPlugCallback(struct libusb_context *ctx, struct libusb_device *dev,
136 libusb_hotplug_event event, void *user_data);
137 libusb_hotplug_callback_handle m_hotplug_handle;
138#endif
139 bool m_hotplug;
140};
141#endif
142
47class Backend : public QObject 143class Backend : public QObject
48{ 144{
49 Q_OBJECT 145 Q_OBJECT
@@ -55,6 +151,9 @@ public:
55 bool GetSocByName(const QString& name, soc_t& s); 151 bool GetSocByName(const QString& name, soc_t& s);
56 IoBackend *CreateDummyIoBackend(); 152 IoBackend *CreateDummyIoBackend();
57 IoBackend *CreateFileIoBackend(const QString& filename); 153 IoBackend *CreateFileIoBackend(const QString& filename);
154#ifdef HAVE_HWSTUB
155 IoBackend *CreateHWStubIoBackend(HWStubDevice *dev);
156#endif
58 157
59signals: 158signals:
60 void OnSocListChanged(); 159 void OnSocListChanged();
@@ -69,6 +168,10 @@ public:
69 bool ReadRegister(const QString& dev, const QString& reg, soc_word_t& v); 168 bool ReadRegister(const QString& dev, const QString& reg, soc_word_t& v);
70 bool ReadRegisterField(const QString& dev, const QString& reg, 169 bool ReadRegisterField(const QString& dev, const QString& reg,
71 const QString& field, soc_word_t& v); 170 const QString& field, soc_word_t& v);
171 bool GetDeviceDesc(const QString& dev, soc_dev_t& dev_desc, size_t& index);
172 bool GetRegisterDesc(const soc_dev_t& dev, const QString& reg, soc_reg_t& reg_desc, size_t& index);
173 bool GetFieldDesc(const soc_reg_t& reg_desc, const QString& field, soc_reg_field_t& field_desc);
174 bool GetRegisterAddress(const QString& dev, const QString& reg, soc_addr_t& addr);
72private: 175private:
73 IoBackend *m_io_backend; 176 IoBackend *m_io_backend;
74 soc_t m_soc; 177 soc_t m_soc;
diff --git a/utils/regtools/qeditor/main.cpp b/utils/regtools/qeditor/main.cpp
index 0e4e67bfb7..576d3a16fc 100644
--- a/utils/regtools/qeditor/main.cpp
+++ b/utils/regtools/qeditor/main.cpp
@@ -6,25 +6,24 @@ int main(int argc, char *argv[])
6{ 6{
7 QApplication app(argc, argv); 7 QApplication app(argc, argv);
8 8
9 Backend *backend = new Backend; 9 Backend backend;;
10 QDir dir(QCoreApplication::applicationDirPath()); 10 QDir dir(QCoreApplication::applicationDirPath());
11 dir.cdUp(); 11 dir.cdUp();
12 dir.cd("desc"); 12 dir.cd("desc");
13 dir.setFilter(QDir::Files); 13 dir.setFilter(QDir::Files);
14 printf("%s\n", dir.absolutePath().toStdString().c_str());
15 QFileInfoList list = dir.entryInfoList(); 14 QFileInfoList list = dir.entryInfoList();
16 for(int i = 0; i < list.size(); i++) 15 for(int i = 0; i < list.size(); i++)
17 { 16 {
18 QFileInfo fileInfo = list.at(i); 17 QFileInfo fileInfo = list.at(i);
19 if(fileInfo.fileName().right(4) != ".xml" || fileInfo.fileName().left(5) != "regs-") 18 if(fileInfo.fileName().right(4) != ".xml" || fileInfo.fileName().left(5) != "regs-")
20 continue; 19 continue;
21 backend->LoadSocDesc(fileInfo.absoluteFilePath()); 20 backend.LoadSocDesc(fileInfo.absoluteFilePath());
22 } 21 }
23 22
24 QCoreApplication::setOrganizationName("Rockbox"); 23 QCoreApplication::setOrganizationName("Rockbox");
25 QCoreApplication::setApplicationName("Register Editor"); 24 QCoreApplication::setApplicationName("Register Editor");
26 QCoreApplication::setOrganizationDomain("rockbox.org"); 25 QCoreApplication::setOrganizationDomain("rockbox.org");
27 MainWindow win(backend); 26 MainWindow win(&backend);
28 win.show(); 27 win.show();
29 return app.exec(); 28 return app.exec();
30} 29}
diff --git a/utils/regtools/qeditor/qeditor.pro b/utils/regtools/qeditor/qeditor.pro
index 4e25a48d89..5604fe9d41 100644
--- a/utils/regtools/qeditor/qeditor.pro
+++ b/utils/regtools/qeditor/qeditor.pro
@@ -3,6 +3,16 @@ QT += widgets
3HEADERS += mainwindow.h backend.h regtab.h analyser.h settings.h std_analysers.h 3HEADERS += mainwindow.h backend.h regtab.h analyser.h settings.h std_analysers.h
4SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp std_analysers.cpp settings.cpp 4SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp std_analysers.cpp settings.cpp
5LIBS += -L../lib/ -lsocdesc -lxml2 5LIBS += -L../lib/ -lsocdesc -lxml2
6INCLUDEPATH += ../lib/ 6INCLUDEPATH += ../lib/ ../../hwstub/lib
7 7
8CONFIG += debug \ No newline at end of file 8unix {
9 !nohwstub {
10 message("Use 'qmake -config nohwstub' if you want to disable hwstub support")
11 LIBS += -L../../hwstub/lib -lhwstub
12 DEFINES += HAVE_HWSTUB
13 CONFIG += link_pkgconfig
14 PKGCONFIG += libusb-1.0
15 }
16}
17
18CONFIG += debug
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp
index 4f7a73cffc..8f64bbf48a 100644
--- a/utils/regtools/qeditor/regtab.cpp
+++ b/utils/regtools/qeditor/regtab.cpp
@@ -13,6 +13,7 @@
13#include <QTableWidget> 13#include <QTableWidget>
14#include <QHeaderView> 14#include <QHeaderView>
15#include <QFileDialog> 15#include <QFileDialog>
16#include <QDebug>
16#include "backend.h" 17#include "backend.h"
17#include "analyser.h" 18#include "analyser.h"
18 19
@@ -65,6 +66,9 @@ RegTab::RegTab(Backend *backend, QTabWidget *parent)
65 m_data_selector = new QComboBox; 66 m_data_selector = new QComboBox;
66 m_data_selector->addItem(QIcon::fromTheme("face-sad"), "None", QVariant(DataSelNothing)); 67 m_data_selector->addItem(QIcon::fromTheme("face-sad"), "None", QVariant(DataSelNothing));
67 m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile)); 68 m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile));
69#ifdef HAVE_HWSTUB
70 m_data_selector->addItem(QIcon::fromTheme("multimedia-player"), "Device...", QVariant(DataSelDevice));
71#endif
68 m_data_sel_edit = new QLineEdit; 72 m_data_sel_edit = new QLineEdit;
69 m_data_sel_edit->setReadOnly(true); 73 m_data_sel_edit->setReadOnly(true);
70 m_data_soc_label = new QLabel; 74 m_data_soc_label = new QLabel;
@@ -72,6 +76,10 @@ RegTab::RegTab(Backend *backend, QTabWidget *parent)
72 data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); 76 data_sel_reload->setIcon(QIcon::fromTheme("view-refresh"));
73 data_sel_layout->addWidget(m_data_selector); 77 data_sel_layout->addWidget(m_data_selector);
74 data_sel_layout->addWidget(m_data_sel_edit); 78 data_sel_layout->addWidget(m_data_sel_edit);
79#ifdef HAVE_HWSTUB
80 m_dev_selector = new QComboBox;
81 data_sel_layout->addWidget(m_dev_selector, 1);
82#endif
75 data_sel_layout->addWidget(m_data_soc_label); 83 data_sel_layout->addWidget(m_data_soc_label);
76 data_sel_layout->addWidget(data_sel_reload); 84 data_sel_layout->addWidget(data_sel_reload);
77 data_sel_group->setLayout(data_sel_layout); 85 data_sel_group->setLayout(data_sel_layout);
@@ -107,6 +115,10 @@ RegTab::RegTab(Backend *backend, QTabWidget *parent)
107 this, SLOT(OnAnalyserChanged(QListWidgetItem *, QListWidgetItem *))); 115 this, SLOT(OnAnalyserChanged(QListWidgetItem *, QListWidgetItem *)));
108 connect(m_analysers_list, SIGNAL(itemClicked(QListWidgetItem *)), this, 116 connect(m_analysers_list, SIGNAL(itemClicked(QListWidgetItem *)), this,
109 SLOT(OnAnalyserClicked(QListWidgetItem *))); 117 SLOT(OnAnalyserClicked(QListWidgetItem *)));
118#ifdef HAVE_HWSTUB
119 connect(m_dev_selector, SIGNAL(currentIndexChanged(int)),
120 this, SLOT(OnDevChanged(int)));
121#endif
110 122
111 OnSocListChanged(); 123 OnSocListChanged();
112 OnDataSelChanged(DataSelNothing); 124 OnDataSelChanged(DataSelNothing);
@@ -141,6 +153,10 @@ void RegTab::OnDataSelChanged(int index)
141 QVariant var = m_data_selector->itemData(index); 153 QVariant var = m_data_selector->itemData(index);
142 if(var == DataSelFile) 154 if(var == DataSelFile)
143 { 155 {
156 m_data_sel_edit->show();
157#ifdef HAVE_HWSTUB
158 m_dev_selector->hide();
159#endif
144 QFileDialog *fd = new QFileDialog(m_data_selector); 160 QFileDialog *fd = new QFileDialog(m_data_selector);
145 fd->setFilter("Textual files (*.txt);;All files (*)"); 161 fd->setFilter("Textual files (*.txt);;All files (*)");
146 fd->setDirectory(Settings::Get()->value("regtab/loaddatadir", QDir::currentPath()).toString()); 162 fd->setDirectory(Settings::Get()->value("regtab/loaddatadir", QDir::currentPath()).toString());
@@ -155,8 +171,20 @@ void RegTab::OnDataSelChanged(int index)
155 } 171 }
156 Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath()); 172 Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath());
157 } 173 }
174#ifdef HAVE_HWSTUB
175 else if(var == DataSelDevice)
176 {
177 m_data_sel_edit->hide();
178 m_dev_selector->show();
179 OnDevListChanged();
180 }
181#endif
158 else 182 else
159 { 183 {
184 m_data_sel_edit->show();
185#ifdef HAVE_HWSTUB
186 m_dev_selector->hide();
187#endif
160 delete m_io_backend; 188 delete m_io_backend;
161 m_io_backend = m_backend->CreateDummyIoBackend(); 189 m_io_backend = m_backend->CreateDummyIoBackend();
162 SetDataSocName(""); 190 SetDataSocName("");
@@ -204,7 +232,7 @@ void RegTab::OnAnalyserClicked(QListWidgetItem *current)
204 delete m_right_content; 232 delete m_right_content;
205 AnalyserFactory *ana = AnalyserFactory::GetAnalyserByName(current->text()); 233 AnalyserFactory *ana = AnalyserFactory::GetAnalyserByName(current->text());
206 m_right_content = ana->Create(m_cur_soc, m_io_backend)->GetWidget(); 234 m_right_content = ana->Create(m_cur_soc, m_io_backend)->GetWidget();
207 m_right_panel->addWidget(m_right_content); 235 m_right_panel->addWidget(m_right_content, 1);
208} 236}
209 237
210void RegTab::DisplayRegister(soc_dev_t& dev, soc_dev_addr_t& dev_addr, 238void RegTab::DisplayRegister(soc_dev_t& dev, soc_dev_addr_t& dev_addr,
@@ -256,8 +284,8 @@ void RegTab::DisplayRegister(soc_dev_t& dev, soc_dev_addr_t& dev_addr,
256 top_layout->addStretch(); 284 top_layout->addStretch();
257 285
258 soc_word_t value; 286 soc_word_t value;
259 bool has_value = m_io_backend->ReadRegister(QString().sprintf("HW.%s.%s", 287 BackendHelper helper(m_io_backend, m_cur_soc);
260 dev_addr.name.c_str(), reg_addr.name.c_str()), value); 288 bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value);
261 289
262 QHBoxLayout *raw_val_layout = 0; 290 QHBoxLayout *raw_val_layout = 0;
263 if(has_value) 291 if(has_value)
@@ -348,6 +376,37 @@ void RegTab::OnSocListChanged()
348 m_soc_selector->addItem(socs[i]); 376 m_soc_selector->addItem(socs[i]);
349} 377}
350 378
379#ifdef HAVE_HWSTUB
380void RegTab::OnDevListChanged()
381{
382 m_dev_selector->clear();
383 QList< HWStubDevice* > list = m_hwstub_helper.GetDevList();
384 foreach(HWStubDevice *dev, list)
385 {
386 QString name = QString("Bus %1 Device %2: %3").arg(dev->GetBusNumber())
387 .arg(dev->GetDevAddress()).arg(dev->GetTargetInfo().bName);
388 m_dev_selector->addItem(QIcon::fromTheme("multimedia-player"), name,
389 QVariant::fromValue((void *)dev));
390 }
391 if(list.size() > 0)
392 m_dev_selector->setCurrentIndex(0);
393 else
394 SetDataSocName("");
395}
396
397void RegTab::OnDevChanged(int index)
398{
399 if(index == -1)
400 return;
401 HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(index).value< void* >());
402 delete m_io_backend;
403 m_io_backend = m_backend->CreateHWStubIoBackend(dev);
404 SetDataSocName(m_io_backend->GetSocName());
405 OnDataSocActivated(m_io_backend->GetSocName());
406 OnDataChanged();
407}
408#endif
409
351void RegTab::FillDevSubTree(RegTreeItem *item) 410void RegTab::FillDevSubTree(RegTreeItem *item)
352{ 411{
353 soc_dev_t& sd = m_cur_soc.dev[item->GetDevIndex()]; 412 soc_dev_t& sd = m_cur_soc.dev[item->GetDevIndex()];
diff --git a/utils/regtools/qeditor/regtab.h b/utils/regtools/qeditor/regtab.h
index 7ec8c9009f..d570eb6f90 100644
--- a/utils/regtools/qeditor/regtab.h
+++ b/utils/regtools/qeditor/regtab.h
@@ -25,6 +25,9 @@ enum
25{ 25{
26 DataSelNothing, 26 DataSelNothing,
27 DataSelFile, 27 DataSelFile,
28#ifdef HAVE_HWSTUB
29 DataSelDevice,
30#endif
28}; 31};
29 32
30class RegTreeItem : public QTreeWidgetItem 33class RegTreeItem : public QTreeWidgetItem
@@ -56,6 +59,10 @@ protected:
56 soc_reg_t& reg, soc_reg_addr_t& reg_addr); 59 soc_reg_t& reg, soc_reg_addr_t& reg_addr);
57 void SetDataSocName(const QString& socname); 60 void SetDataSocName(const QString& socname);
58 QComboBox *m_soc_selector; 61 QComboBox *m_soc_selector;
62#ifdef HAVE_HWSTUB
63 QComboBox *m_dev_selector;
64 HWStubBackendHelper m_hwstub_helper;
65#endif
59 Backend *m_backend; 66 Backend *m_backend;
60 QTreeWidget *m_reg_tree; 67 QTreeWidget *m_reg_tree;
61 soc_t m_cur_soc; 68 soc_t m_cur_soc;
@@ -71,6 +78,10 @@ protected:
71 QListWidget *m_analysers_list; 78 QListWidget *m_analysers_list;
72 79
73private slots: 80private slots:
81#ifdef HAVE_HWSTUB
82 void OnDevListChanged();
83 void OnDevChanged(int index);
84#endif
74 void OnSocChanged(const QString& text); 85 void OnSocChanged(const QString& text);
75 void OnSocListChanged(); 86 void OnSocListChanged();
76 void OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); 87 void OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);