2017-11-26 21:22:11 +01:00
# include <QMessageBox>
2017-11-29 00:16:29 +01:00
# include <QTreeWidget>
# include <QTimer>
2019-03-29 23:51:22 +01:00
# include <QStandardPaths>
# include <QFileDialog>
2017-11-26 21:22:11 +01:00
2019-03-29 23:51:22 +01:00
# include "string.h"
2017-11-26 21:22:11 +01:00
# include "hidapi.h"
# include "usbselector.h"
# include "ui_usbselector.h"
2017-11-28 00:54:11 +01:00
extern " C " {
2017-11-26 21:22:11 +01:00
# include "newrpl.h"
# include "libraries.h"
2017-11-30 19:23:09 +01:00
extern hid_device * __usb_curdevice ;
2019-04-19 23:05:47 +02:00
extern volatile int __usb_paused ;
2019-04-23 23:29:33 +02:00
int __fwupdate_progress ;
int __fwupdate_address ;
int __fwupdate_nwords ;
BYTEPTR __fwupdate_buffer ;
2017-11-30 19:23:09 +01:00
2019-04-11 00:40:42 +02:00
2017-11-28 00:54:11 +01:00
BINT64 rplObjChecksum ( WORDPTR object ) ;
}
2017-11-26 21:22:11 +01:00
USBSelector : : USBSelector ( QWidget * parent ) :
QDialog ( parent ) ,
2019-04-23 23:29:33 +02:00
ui ( new Ui : : USBSelector ) ,
update_thread ( this )
2017-11-26 21:22:11 +01:00
{
ui - > setupUi ( this ) ;
2017-11-30 19:23:09 +01:00
2017-11-29 19:17:45 +01:00
SelectedDevicePath . clear ( ) ;
2019-03-07 19:14:55 +01:00
ui - > updateFirmware - > hide ( ) ;
2019-04-23 23:29:33 +02:00
ui - > updateProgress - > hide ( ) ;
2017-11-29 19:17:45 +01:00
2017-11-29 00:16:29 +01:00
RefreshList ( ) ;
tmr = new QTimer ( this ) ;
if ( tmr ) {
connect ( tmr , SIGNAL ( timeout ( ) ) , this , SLOT ( refresh ( ) ) ) ;
2017-12-15 16:08:46 +01:00
tmr - > start ( 500 ) ;
2017-11-29 00:16:29 +01:00
}
2019-04-11 00:40:42 +02:00
2017-11-29 00:16:29 +01:00
}
USBSelector : : ~ USBSelector ( )
{
2017-11-30 00:48:44 +01:00
if ( tmr ) {
tmr - > stop ( ) ;
delete tmr ;
tmr = 0 ;
}
2017-11-29 00:16:29 +01:00
delete ui ;
}
void USBSelector : : on_USBtreeWidget_itemSelectionChanged ( )
{
QString result ;
result . clear ( ) ;
QTreeWidgetItem * newitem ;
if ( ui - > USBtreeWidget - > selectedItems ( ) . count ( ) > = 1 ) newitem = ui - > USBtreeWidget - > selectedItems ( ) . first ( ) ;
else {
return ;
}
2017-11-29 19:17:45 +01:00
if ( newitem - > text ( 2 ) = = QString ( " [Device not responding] " ) ) {
ui - > buttonBox - > setStandardButtons ( QDialogButtonBox : : Cancel ) ;
SelectedDevicePath . clear ( ) ;
2017-12-14 19:12:35 +01:00
SelectedDeviceName . clear ( ) ;
2017-11-29 19:17:45 +01:00
ui - > selectedCalc - > setText ( QString ( " No device selected. " ) ) ;
2019-03-07 19:14:55 +01:00
ui - > updateFirmware - > hide ( ) ;
2017-11-29 19:17:45 +01:00
}
else {
ui - > buttonBox - > setStandardButtons ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel ) ;
SelectedDevicePath = newitem - > data ( 0 , Qt : : UserRole + 3 ) . toString ( ) ;
2017-12-14 19:12:35 +01:00
SelectedDeviceName = newitem - > text ( 0 ) + QString ( " [build " ) + newitem - > text ( 2 ) . right ( 4 ) + QString ( " ] " ) ;
ui - > selectedCalc - > setText ( SelectedDeviceName ) ;
2019-03-07 19:14:55 +01:00
ui - > updateFirmware - > show ( ) ;
2017-11-29 19:17:45 +01:00
}
2017-11-29 00:16:29 +01:00
}
2017-11-29 19:17:45 +01:00
QString & USBSelector : : getSelectedDevicePath ( )
{
return SelectedDevicePath ;
}
2017-11-29 00:16:29 +01:00
2017-12-14 19:12:35 +01:00
QString & USBSelector : : getSelectedDeviceName ( )
{
return SelectedDeviceName ;
}
2017-11-29 00:16:29 +01:00
void USBSelector : : RefreshList ( )
{
2017-11-26 21:22:11 +01:00
struct hid_device_info * devs , * cur_dev ;
2017-11-29 00:16:29 +01:00
QTreeWidgetItem * newitem ;
2017-11-26 21:22:11 +01:00
2017-11-29 19:17:45 +01:00
2017-11-26 21:22:11 +01:00
if ( hid_init ( ) )
{
2017-11-29 00:16:29 +01:00
ui - > USBtreeWidget - > clear ( ) ;
2017-11-26 21:22:11 +01:00
return ;
}
devs = hid_enumerate ( 0x0 , 0x0 ) ;
if ( ! devs ) {
2017-11-29 00:16:29 +01:00
ui - > USBtreeWidget - > clear ( ) ;
2017-11-26 21:22:11 +01:00
return ;
}
cur_dev = devs ;
QString result ;
result . clear ( ) ;
2017-11-29 00:16:29 +01:00
{
// FIRST DISABLE ALL ITEMS IN THE LIST
QTreeWidgetItemIterator it ( ui - > USBtreeWidget ) ;
while ( * it ) {
( * it ) - > setDisabled ( true ) ;
+ + it ;
}
}
2017-11-26 21:22:11 +01:00
while ( cur_dev ) {
QString manuf ;
if ( cur_dev - > manufacturer_string ) manuf = QString : : fromStdWString ( cur_dev - > manufacturer_string ) ;
if ( manuf . startsWith ( " newRPL " ) ) {
2017-11-29 00:16:29 +01:00
QTreeWidgetItemIterator it ( ui - > USBtreeWidget ) ;
newitem = 0 ;
while ( * it ) {
2017-11-29 19:17:45 +01:00
if ( ( ( * it ) - > data ( 0 , Qt : : UserRole + 1 ) . toInt ( ) = = cur_dev - > vendor_id )
& & ( ( * it ) - > data ( 0 , Qt : : UserRole + 2 ) . toInt ( ) = = cur_dev - > product_id )
& & ( ( * it ) - > data ( 0 , Qt : : UserRole + 3 ) . toString ( ) = = QString ( cur_dev - > path ) )
2017-11-29 00:16:29 +01:00
)
{
// FOUND THE SAME ITEM AGAIN
newitem = * it ;
( * it ) - > setDisabled ( false ) ;
}
+ + it ;
2017-11-26 21:22:11 +01:00
2017-11-29 00:16:29 +01:00
}
if ( ! newitem ) {
newitem = new QTreeWidgetItem ( ui - > USBtreeWidget ) ;
if ( ! newitem ) return ;
}
2017-11-26 21:22:11 +01:00
QString tmp ;
if ( cur_dev - > product_string ) tmp = QString : : fromStdWString ( cur_dev - > product_string ) ;
else tmp = " [Unknown] " ;
2017-11-30 19:23:09 +01:00
if ( cur_dev - > serial_number ) tmp + = QString ( " |SN= " ) + QString : : fromStdWString ( cur_dev - > serial_number ) ;
2017-11-26 21:22:11 +01:00
newitem - > setText ( 0 , tmp ) ;
if ( cur_dev - > manufacturer_string ) tmp = QString : : fromStdWString ( cur_dev - > manufacturer_string ) ;
else tmp = " [Unknown] " ;
newitem - > setText ( 1 , tmp ) ;
2017-11-29 19:17:45 +01:00
newitem - > setData ( 0 , Qt : : UserRole + 1 , QVariant ( cur_dev - > vendor_id ) ) ;
newitem - > setData ( 0 , Qt : : UserRole + 2 , QVariant ( cur_dev - > product_id ) ) ;
newitem - > setData ( 0 , Qt : : UserRole + 3 , QVariant ( QString ( cur_dev - > path ) ) ) ;
2017-11-30 19:23:09 +01:00
newitem - > setData ( 0 , Qt : : UserRole + 4 , QVariant ( QString : : fromStdWString ( cur_dev - > serial_number ) ) ) ;
2017-11-26 21:22:11 +01:00
hid_device * thisdev ;
thisdev = hid_open_path ( cur_dev - > path ) ;
2017-11-28 00:54:11 +01:00
if ( thisdev )
{
2019-04-06 00:38:00 +02:00
unsigned char buffer [ 1024 ] ;
int res , datalen ;
int available = 0 ;
do {
// ASK IF REMOTE IS READY TO RECEIVE DATA
memset ( buffer , 0 , RAWHID_TX_SIZE + 1 ) ;
buffer [ 0 ] = 0 ; // REPORT ID
buffer [ 1 ] = USB_BLOCKMARK_GETSTATUS ; // CHECK IF REMOTE IS AVAILABLE TO ANSWER
res = hid_write ( thisdev , buffer , RAWHID_TX_SIZE + 1 ) ;
if ( res < 0 ) break ;
res = hid_read_timeout ( thisdev , buffer , RAWHID_RX_SIZE , 100 ) ;
if ( res < 0 ) break ;
// WE GOT A RESPONSE, IGNORE IT AND SEND THE REQUEST
2017-11-26 21:22:11 +01:00
// ATTEMPT TO SEND SOMETHING TO SEE IF IT'S ACTIVELY RESPONDING
2017-12-04 19:02:06 +01:00
uint32_t getversion [ 16 ] = {
2017-11-30 00:48:44 +01:00
0 , // 0 = DON'T USE REPORT ID'S - THIS IS REQUIRED ONLY FOR HIDAPI
2017-12-11 16:29:40 +01:00
USB_BLOCKMARK_SINGLE , // BLOCK SIZE AND MARKER
2017-11-28 00:54:11 +01:00
0 , // CRC32
2017-11-30 00:48:44 +01:00
MKPROLOG ( SECO , 5 ) , // ACTUAL DATA
2017-11-26 21:22:11 +01:00
CMD_VERSION ,
CMD_DROP ,
CMD_USBSEND ,
2017-11-30 00:48:44 +01:00
CMD_DROP ,
2017-12-04 19:02:06 +01:00
CMD_QSEMI ,
0 , 0 , 0 , 0 , 0 , 0 , 0
2017-11-26 21:22:11 +01:00
} ;
2017-11-30 00:48:44 +01:00
getversion [ 1 ] | = ( 1 + OBJSIZE ( getversion [ 3 ] ) ) < < 10 ;
2019-04-10 00:15:31 +02:00
getversion [ 2 ] = usb_crc32roll ( 0 , ( BYTEPTR ) & ( getversion [ 3 ] ) , ( 1 + OBJSIZE ( getversion [ 3 ] ) ) * 4 ) ;
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
res = hid_write ( thisdev , ( ( const unsigned char * ) getversion ) + 3 , RAWHID_TX_SIZE + 1 ) ;
2017-11-28 00:54:11 +01:00
2019-04-06 00:38:00 +02:00
if ( res < 0 ) break ;
2017-11-28 00:54:11 +01:00
2019-04-06 00:38:00 +02:00
res = hid_read_timeout ( thisdev , buffer , RAWHID_RX_SIZE , 100 ) ;
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
if ( res < 0 ) break ;
// WE GOT A RESPONSE OR IT TIMED OUT, IGNORE IT
while ( ( res > 0 ) & & ( buffer [ 0 ] ! = USB_BLOCKMARK_GETSTATUS ) ) res = hid_read_timeout ( thisdev , buffer , RAWHID_RX_SIZE , 100 ) ;
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
if ( res < 0 ) break ;
// WE GOT A RESPONSE, THE DEVICE IS ALIVE!
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
if ( buffer [ 0 ] = = USB_BLOCKMARK_GETSTATUS ) {
2017-12-04 19:02:06 +01:00
// REMOTE IS ASKING IF WE ARE READY TO RECEIVE DATA
2019-04-06 00:38:00 +02:00
// SAVE THE SIZE OF WHATEVER IS TRYING TO SEND FOR LATER USE
datalen = buffer [ 1 ] ;
datalen | = ( buffer [ 2 ] ) < < 8 ;
datalen | = ( buffer [ 3 ] ) < < 16 ;
datalen | = ( buffer [ 4 ] ) < < 24 ;
2017-12-04 19:02:06 +01:00
memset ( buffer , 0 , RAWHID_TX_SIZE + 1 ) ;
buffer [ 0 ] = 0 ; // REPORT ID
2017-12-11 16:29:40 +01:00
buffer [ 1 ] = USB_BLOCKMARK_RESPONSE ; // RE ARE RESPONDING TO THE REQUEST
2017-12-04 19:02:06 +01:00
buffer [ 2 ] = 0 ; // WE ARE NOT BUSY
2017-11-26 21:22:11 +01:00
2017-12-04 19:02:06 +01:00
res = hid_write ( thisdev , buffer , RAWHID_TX_SIZE + 1 ) ;
2019-04-06 00:38:00 +02:00
} else break ;
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
while ( ( res > 0 ) & & ( buffer [ 0 ] ! = USB_BLOCKMARK_SINGLE ) ) res = hid_read_timeout ( thisdev , buffer , RAWHID_RX_SIZE , 100 ) ;
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
if ( res < 0 ) break ;
// WE GOT A RESPONSE, THE DEVICE IS ALIVE!
// RECEIVE THE DATA
if ( buffer [ 0 ] = = USB_BLOCKMARK_SINGLE ) {
2017-12-04 19:02:06 +01:00
unsigned int strprolog ;
strprolog = buffer [ 8 ] + ( buffer [ 9 ] < < 8 ) + ( buffer [ 10 ] < < 16 ) + ( buffer [ 11 ] < < 24 ) ;
2017-11-26 21:22:11 +01:00
2017-12-04 19:02:06 +01:00
tmp = QString : : fromUtf8 ( ( const char * ) ( buffer + 12 ) , rplStrSize ( & strprolog ) ) ;
newitem - > setText ( 2 , tmp ) ;
available = 1 ;
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
// REMOTE NEEDS CONFIRMATION THAT WE GOT ALL THE DATA
memset ( buffer , 0 , RAWHID_TX_SIZE + 1 ) ;
buffer [ 0 ] = 0 ; // REPORT ID
buffer [ 1 ] = USB_BLOCKMARK_RESPONSE ; // RE ARE RESPONDING TO THE REQUEST
buffer [ 2 ] = 0 ; // WE ARE NOT BUSY
buffer [ 7 ] = buffer [ 3 ] = datalen & 0xff ; // DATALEN HAS TO BE < PACKET SIZE FOR THIS TO WORK
res = hid_write ( thisdev , buffer , RAWHID_TX_SIZE + 1 ) ;
}
else break ;
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
} while ( ! available ) ;
2017-11-26 21:22:11 +01:00
2017-12-04 19:02:06 +01:00
hid_close ( thisdev ) ;
if ( ! available ) {
tmp = " [Device not responding] " ;
newitem - > setText ( 2 , tmp ) ;
}
}
}
cur_dev = cur_dev - > next ;
2017-11-26 21:22:11 +01:00
}
hid_free_enumeration ( devs ) ;
2017-11-28 19:15:50 +01:00
2017-11-29 00:16:29 +01:00
// NOW ELIMINATE ANY ITEMS THAT ARE NOT ENABLED
{
2017-11-28 19:15:50 +01:00
2017-11-29 00:16:29 +01:00
QTreeWidgetItemIterator it ( ui - > USBtreeWidget ) ;
while ( * it ) {
2017-11-30 19:23:09 +01:00
if ( ( * it ) - > isDisabled ( ) ) {
if ( SelectedDevicePath = = ( * it ) - > data ( 0 , Qt : : UserRole + 3 ) . toString ( ) ) {
ui - > buttonBox - > setStandardButtons ( QDialogButtonBox : : Cancel ) ;
SelectedDevicePath . clear ( ) ;
ui - > selectedCalc - > setText ( QString ( " No device selected. " ) ) ;
ui - > USBtreeWidget - > clearSelection ( ) ;
2019-03-07 19:14:55 +01:00
ui - > updateFirmware - > hide ( ) ;
2017-11-30 19:23:09 +01:00
}
delete ( * it ) ;
}
2017-11-29 00:16:29 +01:00
+ + it ;
}
2017-11-28 19:15:50 +01:00
2017-11-29 00:16:29 +01:00
}
2017-11-28 19:15:50 +01:00
2017-11-29 00:16:29 +01:00
// DONE, THE LIST WAS REFRESHED
2017-11-28 19:15:50 +01:00
2017-11-29 00:16:29 +01:00
}
2017-11-28 19:15:50 +01:00
2017-11-29 00:16:29 +01:00
void USBSelector : : on_USBSelector_accepted ( )
{
if ( tmr ) {
tmr - > stop ( ) ;
delete tmr ;
2017-11-30 00:48:44 +01:00
tmr = 0 ;
2017-11-29 00:16:29 +01:00
}
2017-11-30 19:23:09 +01:00
2017-11-29 00:16:29 +01:00
}
2017-11-28 19:15:50 +01:00
2017-11-29 00:16:29 +01:00
void USBSelector : : on_USBSelector_rejected ( )
{
if ( tmr ) {
tmr - > stop ( ) ;
delete tmr ;
2017-11-30 00:48:44 +01:00
tmr = 0 ;
2017-11-29 00:16:29 +01:00
}
}
2017-11-28 19:15:50 +01:00
2017-11-29 00:16:29 +01:00
void USBSelector : : refresh ( )
{
RefreshList ( ) ;
2017-11-28 19:15:50 +01:00
}
2019-03-09 00:05:36 +01:00
void USBSelector : : reconnect ( )
{
if ( ! __usb_curdevice ) {
RefreshList ( ) ;
if ( ! SelectedDevicePath . isEmpty ( ) ) {
// CONNECT TO THE USB DEVICE
__usb_curdevice = hid_open_path ( SelectedDevicePath . toUtf8 ( ) . constData ( ) ) ;
}
}
if ( ! __usb_curdevice ) {
+ + numberoftries ;
if ( numberoftries > 10 ) {
if ( tmr ) {
tmr - > stop ( ) ;
delete tmr ;
tmr = 0 ;
}
// FAILED TO RECONNECT AFTER 5 SECONDS
// TODO: SHOW SOME ERROR DIALOG
}
return ; // WAIT FOR ANOTHER TRY
}
// THE DEVICE IS BACK!
if ( tmr ) {
tmr - > stop ( ) ;
delete tmr ;
tmr = 0 ;
}
// TODO: ASK THE USER IF HE WANTS TO RESTORE FIRMWARE AFTER SUCCE
return ;
}
extern " C " int usbremotefwupdatestart ( ) ;
extern " C " int usbsendtoremote ( uint32_t * data , int nwords ) ;
extern " C " void usbflush ( ) ;
void USBSelector : : on_updateFirmware_clicked ( )
{
2019-04-22 18:11:07 +02:00
// STOP REFRESHING THE LIST
if ( tmr ) {
tmr - > stop ( ) ;
delete tmr ;
tmr = 0 ;
}
2019-04-23 23:29:33 +02:00
2019-03-29 23:51:22 +01:00
QString path ;
2019-04-22 18:11:07 +02:00
// THIS IS ONLY FOR 50g/40g/39g HARDWARE
// TODO: IMPROVE ON THIS FOR OTHER HARDWARE PLATFORMS
unsigned int address ;
unsigned int nwords ;
2019-03-29 23:51:22 +01:00
path = QStandardPaths : : locate ( QStandardPaths : : DocumentsLocation , " newRPL " , QStandardPaths : : LocateDirectory ) ;
if ( path . isEmpty ( ) ) path = QStandardPaths : : writableLocation ( QStandardPaths : : DocumentsLocation ) ;
QString fname = QFileDialog : : getOpenFileName ( this , " Select firmware file to send to calculator " , path , " firmware binary files (*.bin *.* *) " ) ;
if ( ! fname . isEmpty ( ) ) {
QFile file ( fname ) ;
if ( ! file . open ( QIODevice : : ReadOnly ) ) {
QMessageBox a ( QMessageBox : : Warning , " Error while opening " , " Cannot open file " + fname , QMessageBox : : Ok , this ) ;
a . exec ( ) ;
2019-04-22 18:11:07 +02:00
// START REFRESHING THE LIST AGAIN
tmr = new QTimer ( this ) ;
if ( tmr ) {
connect ( tmr , SIGNAL ( timeout ( ) ) , this , SLOT ( reconnect ( ) ) ) ;
tmr - > start ( 500 ) ;
}
2019-03-29 23:51:22 +01:00
return ;
}
// FILE IS OPEN AND READY FOR READING
filedata = file . readAll ( ) ;
file . close ( ) ;
// THIS IS ONLY VALID FOR 50G AND COUSINS, FIX LATER
2019-04-22 18:11:07 +02:00
if ( ( strncmp ( filedata . constData ( ) , " KINPOHP39G+IMAGE " , 16 ) = = 0 ) | |
( strncmp ( filedata . constData ( ) , " KINPOHP40G+IMAGE " , 16 ) = = 0 ) | |
( strncmp ( filedata . constData ( ) , " KINPOUPDATEIMAGE " , 16 ) = = 0 ) ) {
address = 0x4000 ;
nwords = filedata . size ( ) > > 2 ;
2019-03-29 23:51:22 +01:00
filedata . replace ( 0 , 16 , " Kinposhcopyright " ) ;
}
else {
QMessageBox a ( QMessageBox : : Warning , " Invalid firmware image " , " Invalid firmware image " , QMessageBox : : Ok , this ) ;
a . exec ( ) ;
2019-04-22 18:11:07 +02:00
// START REFRESHING THE LIST AGAIN
tmr = new QTimer ( this ) ;
if ( tmr ) {
connect ( tmr , SIGNAL ( timeout ( ) ) , this , SLOT ( reconnect ( ) ) ) ;
tmr - > start ( 500 ) ;
}
2019-03-29 23:51:22 +01:00
return ;
}
QMessageBox warn ( QMessageBox : : Warning , " Firmware update " , " Firmware on the remote device is about to be updated. Do NOT disconnect the device. OK to proceed? " , QMessageBox : : Yes | QMessageBox : : No , this ) ;
2019-04-22 18:11:07 +02:00
if ( warn . exec ( ) = = QMessageBox : : No ) {
// START REFRESHING THE LIST AGAIN
tmr = new QTimer ( this ) ;
if ( tmr ) {
connect ( tmr , SIGNAL ( timeout ( ) ) , this , SLOT ( reconnect ( ) ) ) ;
tmr - > start ( 500 ) ;
}
2019-03-29 23:51:22 +01:00
2019-04-22 18:11:07 +02:00
return ;
}
} else {
// START REFRESHING THE LIST AGAIN
tmr = new QTimer ( this ) ;
if ( tmr ) {
connect ( tmr , SIGNAL ( timeout ( ) ) , this , SLOT ( reconnect ( ) ) ) ;
tmr - > start ( 500 ) ;
}
return ;
}
2019-03-29 23:51:22 +01:00
2019-04-23 23:29:33 +02:00
ui - > USBtreeWidget - > setEnabled ( false ) ;
2019-03-29 23:51:22 +01:00
2019-04-23 23:29:33 +02:00
ui - > updateFirmware - > setEnabled ( false ) ;
ui - > updateProgress - > setRange ( 0 , nwords ) ;
ui - > updateProgress - > show ( ) ;
ui - > updateProgress - > setValue ( 0 ) ;
ui - > buttonBox - > setEnabled ( false ) ;
2019-03-29 23:51:22 +01:00
2019-03-09 00:05:36 +01:00
2019-04-23 23:29:33 +02:00
// CONNECT TO THE USB DEVICE
__usb_curdevice = hid_open_path ( SelectedDevicePath . toUtf8 ( ) . constData ( ) ) ;
2019-03-09 00:05:36 +01:00
2019-04-23 23:29:33 +02:00
if ( ! __usb_curdevice ) {
// TODO: ERROR PROCESS
// START REFRESHING THE LIST AGAIN
tmr = new QTimer ( this ) ;
if ( tmr ) {
connect ( tmr , SIGNAL ( timeout ( ) ) , this , SLOT ( reconnect ( ) ) ) ;
tmr - > start ( 500 ) ;
}
2019-03-09 00:05:36 +01:00
2019-04-23 23:29:33 +02:00
return ;
2019-04-22 18:11:07 +02:00
}
2019-04-23 23:29:33 +02:00
__fwupdate_progress = 0 ;
__fwupdate_address = address ;
__fwupdate_nwords = nwords ;
__fwupdate_buffer = ( BYTEPTR ) filedata . constData ( ) ;
connect ( & update_thread , SIGNAL ( finished ( ) ) , this , SLOT ( finishedupdate ( ) ) ) ;
update_thread . start ( ) ;
while ( ! update_thread . isRunning ( ) ) ; // WAIT FOR THE THREAD TO START
// START REPORTING PROGRESS
QTimer : : singleShot ( 0 , this , SLOT ( updateprogress ( ) ) ) ;
}
void USBSelector : : finishedupdate ( )
{
// PUT THE USB DRIVER TO REST
__usb_paused = 1 ;
// AT THIS POINT, THE CALC MUST'VE RESET TO LOAD THE NEW FIRMWARE
hid_close ( __usb_curdevice ) ;
__usb_curdevice = 0 ;
int result = __fwupdate_address ;
if ( ! result ) {
QMessageBox a ( QMessageBox : : Warning , " Communication error while sending firmware " , " USB communication error " , QMessageBox : : Ok , this ) ;
a . exec ( ) ;
2019-03-09 00:05:36 +01:00
}
2019-04-23 23:29:33 +02:00
ui - > USBtreeWidget - > clear ( ) ;
ui - > USBtreeWidget - > setEnabled ( true ) ;
ui - > updateFirmware - > setEnabled ( true ) ;
ui - > updateProgress - > hide ( ) ;
ui - > updateProgress - > setValue ( 0 ) ;
ui - > buttonBox - > setEnabled ( true ) ;
numberoftries = 0 ;
// START REFRESHING THE LIST AGAIN
tmr = new QTimer ( this ) ;
if ( tmr ) {
connect ( tmr , SIGNAL ( timeout ( ) ) , this , SLOT ( reconnect ( ) ) ) ;
tmr - > start ( 500 ) ;
}
// AND JUST HOPE IT WILL RECONENCT SOME TIME
}
void USBSelector : : updateprogress ( )
{
if ( ! update_thread . isRunning ( ) ) return ;
ui - > updateProgress - > setValue ( __fwupdate_progress ) ;
QTimer : : singleShot ( 0 , this , SLOT ( updateprogress ( ) ) ) ;
}
// ****************************************** USB DRIVER ON A SEPARATE THREAD
FWThread : : FWThread ( QObject * parent )
: QThread ( parent )
{
}
FWThread : : ~ FWThread ( )
{
}
void FWThread : : run ( )
{
int nwords = __fwupdate_nwords ;
__fwupdate_progress = 0 ;
2019-04-19 23:05:47 +02:00
// START USB DRIVER
__usb_paused = 0 ;
// TODO: SHOW NICE WINDOW WITH UPDATE STEPS
2019-03-09 00:05:36 +01:00
// SEND CMD_USBFWUPDATE TO THE CALC
if ( ! usbremotefwupdatestart ( ) ) {
2019-04-23 23:29:33 +02:00
__fwupdate_address = 0 ;
2019-03-09 00:05:36 +01:00
return ;
}
2019-04-22 18:11:07 +02:00
int result = 1 , offset = 0 ;
while ( nwords > 1024 ) {
2019-03-09 00:05:36 +01:00
2019-04-19 23:05:47 +02:00
if ( ! usb_transmitlong_start ( ) ) {
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
break ;
2019-04-19 23:05:47 +02:00
}
2019-04-22 18:11:07 +02:00
// SEND FIRMWARE BLOCK MARKER
if ( result & & ( ! usb_transmitlong_word ( TEXT2WORD ( ' F ' , ' W ' , ' U ' , ' P ' ) ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
break ;
2019-04-19 23:05:47 +02:00
}
2019-04-22 18:11:07 +02:00
// SEND ADDRESS TO BURN THIS BLOCK
2019-04-23 23:29:33 +02:00
if ( result & & ( ! usb_transmitlong_word ( __fwupdate_address + ( offset < < 2 ) ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
break ;
2019-04-19 23:05:47 +02:00
}
2019-04-22 18:11:07 +02:00
// SEND SIZE OF THE BLOCK
if ( result & & ( ! usb_transmitlong_word ( 1024 ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
break ;
2019-04-19 23:05:47 +02:00
}
2019-04-23 23:29:33 +02:00
if ( result ) {
2019-04-22 18:11:07 +02:00
int k ;
2019-04-23 23:29:33 +02:00
WORDPTR buffer = ( WORDPTR ) __fwupdate_buffer ;
2019-04-22 18:11:07 +02:00
for ( k = 0 ; k < 1024 ; + + k )
2019-04-22 14:12:52 +02:00
{
2019-04-22 18:11:07 +02:00
if ( result & & ( ! usb_transmitlong_word ( buffer [ offset ] ) ) ) {
// TODO: SOME KIND OF ERROR
result = 0 ;
break ;
}
+ + offset ;
2019-04-22 14:12:52 +02:00
}
2019-04-23 23:29:33 +02:00
}
2019-04-22 14:12:52 +02:00
2019-04-19 23:05:47 +02:00
2019-04-22 18:11:07 +02:00
if ( result & & ( ! usb_transmitlong_finish ( ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
break ;
2019-04-19 23:05:47 +02:00
}
2019-04-22 18:11:07 +02:00
nwords - = 1024 ;
2019-04-23 23:29:33 +02:00
__fwupdate_progress = offset ;
2019-04-22 18:11:07 +02:00
2019-04-19 23:05:47 +02:00
}
2019-04-22 18:11:07 +02:00
if ( nwords ) {
if ( ! usb_transmitlong_start ( ) ) {
// TODO: SOME KIND OF ERROR
result = 0 ;
}
2019-04-19 23:05:47 +02:00
2019-04-22 18:11:07 +02:00
// SEND FIRMWARE BLOCK MARKER
if ( result & & ( ! usb_transmitlong_word ( TEXT2WORD ( ' F ' , ' W ' , ' U ' , ' P ' ) ) ) ) {
// TODO: SOME KIND OF ERROR
result = 0 ;
}
// SEND ADDRESS TO BURN THIS BLOCK
2019-04-23 23:29:33 +02:00
if ( result & & ( ! usb_transmitlong_word ( __fwupdate_address + ( offset < < 2 ) ) ) ) {
2019-04-22 18:11:07 +02:00
// TODO: SOME KIND OF ERROR
result = 0 ;
}
// SEND SIZE OF THE BLOCK
if ( result & & ( ! usb_transmitlong_word ( nwords ) ) ) {
// TODO: SOME KIND OF ERROR
result = 0 ;
}
2019-04-23 23:29:33 +02:00
if ( result ) {
2019-04-22 18:11:07 +02:00
int k ;
2019-04-23 23:29:33 +02:00
WORDPTR buffer = ( WORDPTR ) __fwupdate_buffer ;
2019-04-22 18:11:07 +02:00
for ( k = 0 ; k < nwords ; + + k )
{
if ( result & & ( ! usb_transmitlong_word ( buffer [ offset ] ) ) ) {
// TODO: SOME KIND OF ERROR
result = 0 ;
2019-04-23 23:29:33 +02:00
break ;
2019-04-22 18:11:07 +02:00
}
+ + offset ;
}
2019-04-23 23:29:33 +02:00
__fwupdate_progress = offset ;
}
2019-04-22 18:11:07 +02:00
if ( result & & ( ! usb_transmitlong_finish ( ) ) ) {
// TODO: SOME KIND OF ERROR
result = 0 ;
}
// DONE SENDING THE LAST BLOCK
2019-04-19 23:05:47 +02:00
}
2019-04-22 14:12:52 +02:00
{
// WAIT ONE FULL SECOND BEFORE STARTING ANOTHER CONVERSATION WITH THE DEVICE
tmr_t start , end ;
start = tmr_ticks ( ) ;
do end = tmr_ticks ( ) ; while ( tmr_ticks2ms ( start , end ) < 1000 ) ;
}
2019-04-19 23:05:47 +02:00
// NOW FINISH THE TEST BY RESETTING
2019-04-22 18:11:07 +02:00
if ( result & & ( ! usb_transmitlong_start ( ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
2019-04-19 23:05:47 +02:00
}
2019-03-09 00:05:36 +01:00
2019-04-22 18:11:07 +02:00
if ( result & & ( ! usb_transmitlong_word ( TEXT2WORD ( ' F ' , ' W ' , ' U ' , ' P ' ) ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
2019-04-19 23:05:47 +02:00
}
// FOR DEBUG, JUST WRITE ONE WORD TO THIS ADDRESS
2019-04-22 18:11:07 +02:00
if ( result & & ( ! usb_transmitlong_word ( 0xFFFFFFFF ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
2019-04-19 23:05:47 +02:00
}
2019-04-22 18:11:07 +02:00
if ( result & & ( ! usb_transmitlong_word ( 0x0 ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
2019-04-19 23:05:47 +02:00
}
2019-04-22 18:11:07 +02:00
if ( result & & ( ! usb_transmitlong_finish ( ) ) ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
result = 0 ;
2019-04-19 23:05:47 +02:00
}
2019-03-29 23:51:22 +01:00
2019-04-23 23:29:33 +02:00
__fwupdate_address = result ;
2019-04-22 18:11:07 +02:00
2019-04-23 23:29:33 +02:00
}
2019-03-29 23:51:22 +01:00
2019-03-09 00:05:36 +01:00