14 #include "ezusbthamway.h"
15 #include "charinterface.h"
18 #include <QApplication>
20 #define CUSB_BULK_WRITE_SIZE 40000
29 #define CMD_DIPSW 0x11u
32 #define ADDR_IDN 0x1fu
33 #define ADDR_CHARINTF 0xa0u
35 #define THAMWAY_USB_FIRMWARE_FILE "fx2fw.bix"
36 #define THAMWAY_USB_GPIFWAVE1_FILE "slow_dat.bin" //for USB1.1
37 #define THAMWAY_USB_GPIFWAVE2_FILE "fullspec_dat.bin" //for USB2.0 burst-transfer enabled
38 #define THAMWAY_USB_GPIFWAVE_SIZE 172
40 XMutex XWinCUSBInterface::s_mutex;
41 int XWinCUSBInterface::s_refcnt = 0;
42 std::deque<XWinCUSBInterface::USBDevice> XWinCUSBInterface::s_devices;
45 XWinCUSBInterface::openAllEZUSBdevices() {
46 QDir dir(QApplication::applicationDirPath());
47 auto load_firm = [&dir](
char *data,
int expected_size,
const char *filename){
48 QString path = filename;
52 filename + i18n_noncontext(
" not found."), __FILE__, __LINE__);
53 QFile file(dir.absoluteFilePath(path));
54 if( !file.open(QIODevice::ReadOnly))
56 filename + i18n_noncontext(
" not found."), __FILE__, __LINE__);
57 int size = file.read(data, expected_size);
58 if(size != expected_size)
60 filename + i18n_noncontext(
" is not proper."), __FILE__, __LINE__);
63 char firmware[CUSB_DWLSIZE];
64 load_firm(firmware, CUSB_DWLSIZE, THAMWAY_USB_FIRMWARE_FILE);
65 char gpifwave1[THAMWAY_USB_GPIFWAVE_SIZE];
66 load_firm(gpifwave1, THAMWAY_USB_GPIFWAVE_SIZE, THAMWAY_USB_GPIFWAVE1_FILE);
67 char gpifwave2[THAMWAY_USB_GPIFWAVE_SIZE];
68 bool always_slow_usb =
false;
70 load_firm(gpifwave2, THAMWAY_USB_GPIFWAVE_SIZE, THAMWAY_USB_GPIFWAVE2_FILE);
74 gMessagePrint(i18n_noncontext(
"Continues with slower USB speed."));
75 always_slow_usb =
true;
78 for(
int i = 0; i < 8; ++i) {
80 fprintf(stderr,
"cusb_init #%d\n", i);
81 if(cusb_init(i, &handle, (uint8_t *)firmware,
82 (
signed char*)
"F2FW", (
signed char*)
"20070627")) {
86 uint8_t sw = readDIPSW(handle);
91 s_devices.push_back(dev);
92 fprintf(stderr,
"Setting GPIF waves for handle 0x%x, DIPSW=%x\n", (
unsigned int)handle, (
unsigned int)sw);
93 char *gpifwave = gpifwave2;
94 if(always_slow_usb || (dev.addr == DEV_ADDR_PROT))
96 setWave(handle, (
const uint8_t*)gpifwave);
98 for(
int i = 0; i < 3; ++i) {
100 setLED(handle, 0x00u);
102 setLED(handle, 0xf0u);
106 if(s_devices.empty())
111 XWinCUSBInterface::setWave(
void *handle,
const uint8_t *wave) {
112 std::vector<uint8_t> buf;
113 buf.insert(buf.end(), {CMD_MODE, MODE_GPIF | MODE_8BIT | MODE_ADDR | MODE_NOFLOW | MODE_DEBG, CMD_GPIF});
114 buf.insert(buf.end(), wave, wave + 8);
115 buf.insert(buf.end(), {MODE_FLOW});
116 buf.insert(buf.end(), wave + 8 + 32*4, wave + 8 + 32*4 + 36);
117 if(usb_bulk_write( &handle, CPIPE, &buf[0], buf.size()) < 0)
119 const uint8_t cmdwaves[] = {CMD_WAVE0 , CMD_WAVE1, CMD_WAVE2, CMD_WAVE3};
120 for(
int i = 0; i <
sizeof(cmdwaves); ++i) {
122 buf.insert(buf.end(), cmdwaves + i, cmdwaves + i + 1);
123 buf.insert(buf.end(), wave + 8 + 32*i, wave + 8 + 32*(i + 1));
124 if(usb_bulk_write( &handle, CPIPE, &buf[0], buf.size()) < 0)
129 XWinCUSBInterface::closeAllEZUSBdevices() {
130 for(
auto it = s_devices.begin(); it != s_devices.end(); ++it) {
132 setLED(it->handle, 0);
138 fprintf(stderr,
"cusb_close\n");
139 usb_close( &it->handle);
144 XWinCUSBInterface::XWinCUSBInterface(
const char *name,
bool runtime,
const shared_ptr<XDriver> &driver, uint8_t addr_offset,
const char*
id)
145 :
XCustomCharInterface(name, runtime, driver), m_handle(0), m_idString(id), m_addrOffset(addr_offset) {
149 openAllEZUSBdevices();
153 for(
auto it = s_devices.begin(); it != s_devices.end(); ++it) {
157 idn = getIDN(it->handle, 7);
158 if( !idn.length())
continue;
162 if(it->addr != DEV_ADDR_PROT)
continue;
165 idn = formatString(
"%d:%s", it->addr, idn.c_str());
166 tr[ *device()].add(idn);
175 XWinCUSBInterface::~XWinCUSBInterface() {
176 if(isOpened())
close();
181 closeAllEZUSBdevices();
185 XWinCUSBInterface::open() throw (XInterfaceError &) {
188 for(
auto it = s_devices.begin(); it != s_devices.end(); ++it) {
190 if(sscanf(shot[ *
device()].to_str().c_str(),
"%d:", &addr) != 1)
192 if(addr == it->addr) {
193 m_handle = it->handle;
215 XWinCUSBInterface::resetBulkWrite() {
216 m_bBurstWrite =
false;
220 XWinCUSBInterface::deferWritings() {
221 assert(m_buffer.size() == 0);
222 m_bBurstWrite =
true;
225 XWinCUSBInterface::writeToRegister16(
unsigned int addr, uint16_t data) {
227 writeToRegister8(addr, data % 0x100u);
228 writeToRegister8(addr + 1, data / 0x100u);
232 writeToRegister8(addr, data % 0x100u);
233 writeToRegister8(addr + 1, data / 0x100u);
237 XWinCUSBInterface::writeToRegister8(
unsigned int addr, uint8_t data) {
238 addr += m_addrOffset;
239 assert(addr < 0x100u);
242 if(m_buffer.size() > CUSB_BULK_WRITE_SIZE) {
247 m_buffer.push_back(addr);
248 m_buffer.push_back(data);
252 uint8_t cmds[] = {CMD_BWRITE, 2, 0};
253 if(usb_bulk_write( &m_handle, CPIPE, cmds,
sizeof(cmds)) < 0)
255 uint8_t cmds2[] = {(uint8_t)(addr), data};
256 if(usb_bulk_write( &m_handle, TFIFO, cmds2,
sizeof(cmds2)) < 0)
261 XWinCUSBInterface::bulkWriteStored() {
264 uint16_t len = m_buffer.size();
265 uint8_t cmds[] = {CMD_BWRITE, (uint8_t)(len % 0x100u), (uint8_t)(len / 0x100u)};
266 if(usb_bulk_write( &m_handle, CPIPE, cmds,
sizeof(cmds)) < 0)
268 if(usb_bulk_write( &m_handle, TFIFO, (uint8_t*) &m_buffer[0], len) < 0)
275 XWinCUSBInterface::setLED(
void *handle, uint8_t data) {
276 uint8_t cmds[] = {CMD_LED, data};
277 if(usb_bulk_write( &handle, CPIPE, cmds,
sizeof(cmds)) < 0)
282 XWinCUSBInterface::readDIPSW(
void *handle) {
283 uint8_t cmds[] = {CMD_DIPSW};
284 if(usb_bulk_write( &handle, CPIPE, cmds,
sizeof(cmds)) < 0)
287 if(usb_bulk_read( &handle, RFIFO, buf, 1) != 1)
293 XWinCUSBInterface::getIDN(
void *handle,
int maxlen,
int addroffset) {
295 for(
int i = 0; ; ++i) {
296 char c = singleRead(handle, ADDR_IDN, addroffset);
304 for(
int i = 0; ; ++i) {
305 char c = singleRead(handle, ADDR_IDN, addroffset);
313 fprintf(stderr,
"getIDN:%s\n", idn.c_str());
317 XWinCUSBInterface::singleRead(
unsigned int addr) {
319 return singleRead(m_handle, addr, m_addrOffset);
323 XWinCUSBInterface::singleRead(
void *handle,
unsigned int addr,
unsigned int addroffset) {
325 assert(addr < 0x100u);
327 uint8_t cmds[] = {CMD_SWRITE, (uint8_t)(addr)};
328 if(usb_bulk_write( &handle, CPIPE, cmds,
sizeof(cmds)) < 0)
332 uint8_t cmds[] = {CMD_SREAD};
333 if(usb_bulk_write( &handle, CPIPE, cmds,
sizeof(cmds)) < 0)
336 if(usb_bulk_read( &handle, RFIFO, buf, 1) != 1)
342 XWinCUSBInterface::readRegister16(
unsigned int addr) {
344 return singleRead(addr) + singleRead(addr + 1) * (uint16_t)0x100u;
348 XWinCUSBInterface::burstRead(
unsigned int addr, uint8_t *buf,
unsigned int cnt) {
350 addr += m_addrOffset;
351 assert(addr < 0x100u);
353 uint8_t cmds[] = {CMD_SWRITE, (uint8_t)(addr)};
354 if(usb_bulk_write( &m_handle, CPIPE, cmds,
sizeof(cmds)) < 0)
357 const unsigned int blocksize = 512;
358 uint8_t cmds[] = {CMD_BREAD, blocksize % 0x100u, blocksize / 0x100u};
359 uint8_t bbuf[blocksize];
361 if(usb_bulk_write( &m_handle, CPIPE, cmds,
sizeof(cmds)) < 0)
363 int i = usb_bulk_read( &m_handle, RFIFO, bbuf, blocksize);
366 unsigned int n = std::min(cnt, (
unsigned int)i);
367 std::copy(bbuf, bbuf + n, buf);
374 XWinCUSBInterface::send(
const char *str)
throw (XCommError &) {
378 dbgPrint(driver()->getLabel() +
" Sending:\"" + dumpCString(str) +
"\"");
380 for(
int i = 0; i < buf.length(); ++i) {
381 writeToRegister8(ADDR_CHARINTF, (uint8_t)buf[i]);
384 catch (XCommError &e) {
385 e.print(driver()->getLabel() + i18n(
" SendError, because "));
390 XWinCUSBInterface::receive() throw (XCommError &) {
396 dbgPrint(driver()->
getLabel() +
" Receiving...");
397 for(
int i = 0; ; ++i) {
398 uint8_t c = singleRead(ADDR_CHARINTF);
399 if( !c || (c == 0xffu))
406 dbgPrint(driver()->
getLabel() +
" Received;\"" +
407 dumpCString((
const char*)&
buffer()[0]) +
"\"");
409 catch (XCommError &e) {
410 e.print(driver()->
getLabel() + i18n(
" ReceiveError, because "));