2019-04-25 15:30:25 +02:00
# include < QMessageBox >
2017-11-29 00:16:29 +01:00
# include <QTreeWidget>
2019-05-15 00:55:22 +02:00
# include <QTreeWidgetItem>
# include <QTreeWidgetItemIterator>
2017-11-29 00:16:29 +01:00
# include <QTimer>
2019-03-29 23:51:22 +01:00
# include <QStandardPaths>
# include <QFileDialog>
2019-04-24 23:23:20 +02:00
# include <QCloseEvent>
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
//#include "string.h"
2017-11-26 21:22:11 +01:00
# include "hidapi.h"
# include "usbselector.h"
# include "ui_usbselector.h"
2019-05-15 00:55:22 +02:00
// ONLY REQUIRED UNDER MINGW
# ifdef DrawText
# undef DrawText
# endif
# define WORD _WORD
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-05-15 00:55:22 +02:00
extern char __usb_devicepath [ 8192 ] ;
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 ) ;
}
2019-04-24 23:23:20 +02:00
2017-11-26 21:22:11 +01:00
USBSelector : : USBSelector ( QWidget * parent ) :
QDialog ( parent ) ,
2019-05-18 00:00:33 +02:00
update_thread ( this ) ,
ui ( new Ui : : USBSelector )
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-05-13 18:29:32 +02:00
SelectedDeviceName . clear ( ) ;
2019-03-07 19:14:55 +01:00
ui - > updateFirmware - > hide ( ) ;
2019-04-23 23:29:33 +02:00
ui - > updateProgress - > hide ( ) ;
2019-05-13 18:29:32 +02:00
ui - > USBtreeWidget - > clear ( ) ;
ui - > USBtreeWidget - > hideColumn ( 1 ) ;
ui - > USBtreeWidget - > hideColumn ( 3 ) ;
ui - > USBtreeWidget - > hideColumn ( 4 ) ;
2019-05-18 00:00:33 +02:00
norefresh = false ;
2019-05-10 23:50:19 +02:00
2019-05-15 00:55:22 +02:00
QTimer : : singleShot ( 200 , this , SLOT ( refresh ( ) ) ) ;
2017-11-29 00:16:29 +01:00
}
USBSelector : : ~ USBSelector ( )
{
2017-11-30 00:48:44 +01:00
2017-11-29 00:16:29 +01:00
delete ui ;
}
2019-04-24 23:23:20 +02:00
void USBSelector : : closeEvent ( QCloseEvent * event )
{
if ( ! update_thread . isRunning ( ) ) event - > accept ( ) ;
else event - > ignore ( ) ;
}
void USBSelector : : reject ( )
{
if ( ! update_thread . isRunning ( ) ) QDialog : : reject ( ) ;
}
2017-11-29 00:16:29 +01:00
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 ) ;
2019-05-13 18:29:32 +02:00
SelectedDevicePath = newitem - > text ( 3 ) ;
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
2019-05-15 00:55:22 +02:00
// MAKE SURE WE CLOSE EVERYTHING AND RESET THE ENTIRE LIBRARY BEFORE ENUMERATION
usb_shutdown ( ) ;
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 ;
}
2019-05-15 00:55:22 +02:00
2017-11-26 21:22:11 +01:00
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 ) ;
2019-05-15 00:55:22 +02:00
2017-11-29 00:16:29 +01:00
while ( * it ) {
( * it ) - > setDisabled ( true ) ;
+ + it ;
}
}
2019-05-15 00:55:22 +02:00
QString manuf ;
QString tmp ;
QString pid ;
QString newpath ;
2017-11-26 21:22:11 +01:00
while ( cur_dev ) {
if ( cur_dev - > manufacturer_string ) manuf = QString : : fromStdWString ( cur_dev - > manufacturer_string ) ;
2019-05-15 00:55:22 +02:00
else manuf . clear ( ) ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
manuf . detach ( ) ;
2017-11-29 00:16:29 +01:00
2019-05-15 00:55:22 +02:00
if ( manuf . startsWith ( " newRPL " ) ) {
2019-05-13 18:29:32 +02:00
2019-05-15 00:55:22 +02:00
pid = QString : : number ( cur_dev - > vendor_id , 16 ) + " : " + QString : : number ( cur_dev - > product_id , 16 ) ;
newpath = QString ( cur_dev - > path ) ;
newpath . detach ( ) ;
2019-05-13 18:29:32 +02:00
2019-05-15 00:55:22 +02:00
int nitems = ui - > USBtreeWidget - > topLevelItemCount ( ) ;
int k ;
QTreeWidgetItem * item ;
2019-05-13 18:29:32 +02:00
2019-05-15 00:55:22 +02:00
newitem = 0 ;
for ( k = 0 ; k < nitems ; + + k ) {
item = ui - > USBtreeWidget - > topLevelItem ( k ) ;
if ( item ) {
if ( ( item - > text ( 4 ) = = pid ) & & ( item - > text ( 3 ) = = newpath ) )
{
// FOUND THE SAME ITEM AGAIN
newitem = item ;
item - > setDisabled ( false ) ;
break ;
}
}
2017-11-29 00:16:29 +01:00
}
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
if ( ! newitem ) {
newitem = new QTreeWidgetItem ( ) ;
if ( ! newitem ) return ;
2017-11-29 00:16:29 +01:00
2019-05-15 00:55:22 +02:00
newitem - > setText ( 0 , " Empty " ) ;
newitem - > setText ( 1 , " Empty " ) ;
newitem - > setText ( 2 , " Empty " ) ;
newitem - > setText ( 3 , " Empty " ) ;
newitem - > setText ( 4 , " Empty " ) ;
2017-11-29 00:16:29 +01:00
2019-05-15 00:55:22 +02:00
ui - > USBtreeWidget - > addTopLevelItem ( newitem ) ;
}
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
if ( cur_dev - > product_string ) tmp = QString : : fromStdWString ( cur_dev - > product_string ) ;
else tmp = " [Unknown] " ;
if ( cur_dev - > serial_number ) tmp + = QString ( " |SN= " ) + QString : : fromStdWString ( cur_dev - > serial_number ) ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
tmp . detach ( ) ;
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] " ;
2019-05-15 00:55:22 +02:00
tmp . detach ( ) ;
newitem - > setText ( 1 , tmp ) ;
tmp = QString : : number ( cur_dev - > vendor_id , 16 ) + " : " + QString : : number ( cur_dev - > product_id , 16 ) ;
tmp . detach ( ) ;
newitem - > setText ( 4 , tmp ) ;
newitem - > setText ( 3 , newpath ) ;
}
cur_dev = cur_dev - > next ;
}
hid_free_enumeration ( devs ) ;
// NOW ELIMINATE ANY ITEMS THAT ARE NOT ENABLED
{
int restart = 1 ;
while ( restart ) {
int nitems = ui - > USBtreeWidget - > topLevelItemCount ( ) ;
if ( nitems = = 0 ) break ;
int k ;
QTreeWidgetItem * item ;
for ( k = 0 ; k < nitems ; + + k ) {
item = ui - > USBtreeWidget - > topLevelItem ( k ) ;
if ( item ) {
if ( item - > isDisabled ( ) ) {
if ( SelectedDevicePath = = item - > text ( 3 ) ) {
ui - > buttonBox - > setStandardButtons ( QDialogButtonBox : : Cancel ) ;
SelectedDevicePath . clear ( ) ;
ui - > selectedCalc - > setText ( QString ( " No device selected. " ) ) ;
ui - > USBtreeWidget - > clearSelection ( ) ;
ui - > updateFirmware - > hide ( ) ;
}
QTreeWidgetItem * pparent = item - > parent ( ) ;
if ( pparent ) pparent - > removeChild ( item ) ;
delete item ;
restart = 1 ;
break ;
}
// THE DEVICE IS ACTIVE
2019-05-13 18:29:32 +02:00
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
tmp = item - > text ( 3 ) ;
tmp . detach ( ) ;
2017-11-26 21:22:11 +01:00
2019-05-07 23:35:11 +02:00
// STOP THE DRIVER AND REINITIALIZE COMPLETELY
__usb_paused = 1 ;
while ( __usb_paused > = 0 ) ;
2019-05-18 00:00:33 +02:00
usb_shutdown ( ) ;
2019-05-15 00:55:22 +02:00
// SET THE DRIVER TO USE THIS DEVICE AND START THE DRIVER
2019-05-15 16:29:15 +02:00
if ( safe_stringcpy ( __usb_devicepath , 8192 , tmp . toUtf8 ( ) . constData ( ) ) ) __usb_devicepath [ 0 ] = 0 ;
2019-05-15 00:55:22 +02:00
__usb_timeout = 200 ; // SET TIMEOUT TO 200 ms FOR QUICK DETECTION
2019-05-18 00:00:33 +02:00
usb_init ( 0 ) ; // FORCE REINITIALIZATION, CLOSE ANY PREVIOUS HANDLES IF THEY EXIST
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
if ( usb_isconnected ( ) )
2017-11-28 00:54:11 +01:00
{
2019-04-06 00:38:00 +02:00
unsigned char buffer [ 1024 ] ;
2019-05-07 23:35:11 +02:00
int res ;
2019-04-06 00:38:00 +02:00
int available = 0 ;
2019-05-07 23:35:11 +02:00
__usb_paused = 0 ;
2019-05-15 00:55:22 +02:00
2019-04-06 00:38:00 +02:00
do {
2019-05-09 00:57:48 +02:00
2019-05-15 00:55:22 +02:00
usb_sendcontrolpacket ( P_TYPE_GETSTATUS ) ;
2019-05-07 23:35:11 +02:00
2019-05-15 00:55:22 +02:00
tmr_t start , end ;
// WAIT FOR THE CONTROL PACKET TO BE SENT
start = tmr_ticks ( ) ;
res = 0 ;
while ( __usb_drvstatus & USB_STATUS_TXCTL ) {
2019-05-07 23:35:11 +02:00
2019-05-15 00:55:22 +02:00
if ( ( __usb_drvstatus & ( USB_STATUS_CONFIGURED | USB_STATUS_INIT | USB_STATUS_CONNECTED ) ) ! = ( USB_STATUS_CONFIGURED | USB_STATUS_INIT | USB_STATUS_CONNECTED ) ) break ;
2019-05-07 23:35:11 +02:00
2019-05-15 00:55:22 +02:00
QThread : : yieldCurrentThread ( ) ;
2019-05-10 16:42:17 +02:00
2019-05-15 00:55:22 +02:00
end = tmr_ticks ( ) ;
if ( tmr_ticks2ms ( start , end ) > __usb_timeout ) {
res = - 1 ;
break ;
}
}
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
if ( res < 0 ) break ;
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
if ( ! usb_waitforreport ( ) ) { res = - 1 ; break ; }
// WAIT FOR A RESPONSE
USB_PACKET * pkt = usb_getreport ( ) ;
2019-05-07 23:35:11 +02:00
2019-05-15 00:55:22 +02:00
if ( P_FILEID ( pkt ) ! = 0 ) {
2019-05-09 19:08:33 +02:00
2019-05-15 00:55:22 +02:00
// REQUEST UNCONDITIONAL ABORT
__usb_fileid = 0xffff ;
usb_sendcontrolpacket ( P_TYPE_ABORT ) ;
__usb_fileid = 0 ;
2019-05-09 00:57:48 +02:00
2019-05-15 00:55:22 +02:00
tmr_t start , end ;
2019-05-07 23:35:11 +02:00
2019-05-09 00:57:48 +02:00
2019-05-15 00:55:22 +02:00
// WAIT FOR THE CONTROL PACKET TO BE SENT
start = tmr_ticks ( ) ;
res = 0 ;
while ( __usb_drvstatus & USB_STATUS_TXCTL ) {
2019-05-09 00:57:48 +02:00
2019-05-15 00:55:22 +02:00
if ( ( __usb_drvstatus & ( USB_STATUS_CONFIGURED | USB_STATUS_INIT | USB_STATUS_CONNECTED ) ) ! = ( USB_STATUS_CONFIGURED | USB_STATUS_INIT | USB_STATUS_CONNECTED ) ) break ;
2019-05-09 00:57:48 +02:00
2019-05-15 00:55:22 +02:00
QThread : : yieldCurrentThread ( ) ;
end = tmr_ticks ( ) ;
if ( tmr_ticks2ms ( start , end ) > __usb_timeout ) {
res = - 1 ;
break ;
}
}
continue ;
2019-05-09 00:57:48 +02:00
}
2019-05-15 00:55:22 +02:00
usb_releasereport ( ) ;
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
if ( res < 0 ) break ;
// GOT AN ANSWER, MAKE SURE REMOTE IS READY TO RECEIVE
if ( __usb_drvstatus & ( USB_STATUS_HALT | USB_STATUS_ERROR ) ) { res = - 1 ; break ; }
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
// ATTEMPT TO SEND SOMETHING TO SEE IF IT'S ACTIVELY RESPONDING
uint32_t getversion [ 6 ] = {
MKPROLOG ( SECO , 5 ) , // ACTUAL DATA
CMD_VERSION ,
CMD_DROP ,
CMD_USBSEND ,
CMD_DROP ,
CMD_QSEMI
} ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
int fileid ;
res = fileid = usb_txfileopen ( ' O ' ) ;
if ( ! res ) break ;
2017-11-28 00:54:11 +01:00
2019-05-15 00:55:22 +02:00
res = usb_filewrite ( fileid , ( BYTEPTR ) getversion , 6 * sizeof ( uint32_t ) ) ;
2017-11-28 00:54:11 +01:00
2019-05-15 00:55:22 +02:00
if ( ! res ) break ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
res = usb_txfileclose ( fileid ) ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
if ( res < 0 ) break ;
2017-11-26 21:22:11 +01:00
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
// WAIT FOR THE FILE TO ARRIVE
start = tmr_ticks ( ) ;
res = 0 ;
while ( ! usb_hasdata ( ) ) {
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
if ( ( __usb_drvstatus & ( USB_STATUS_CONFIGURED | USB_STATUS_INIT | USB_STATUS_CONNECTED ) ) ! = ( USB_STATUS_CONFIGURED | USB_STATUS_INIT | USB_STATUS_CONNECTED ) ) break ;
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
QThread : : yieldCurrentThread ( ) ;
end = tmr_ticks ( ) ;
if ( tmr_ticks2ms ( start , end ) > __usb_timeout ) {
res = - 1 ;
break ;
}
}
if ( res < 0 ) break ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
res = fileid = usb_rxfileopen ( ) ;
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
if ( res < 0 ) break ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
res = usb_fileread ( fileid , buffer , 1024 ) ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
if ( res < = 0 ) break ;
2019-04-06 00:38:00 +02:00
2019-05-15 00:55:22 +02:00
usb_rxfileclose ( fileid ) ;
2017-11-26 21:22:11 +01:00
2019-05-15 00:55:22 +02:00
{
unsigned int strprolog ;
strprolog = buffer [ 0 ] + ( buffer [ 1 ] < < 8 ) + ( buffer [ 2 ] < < 16 ) + ( buffer [ 3 ] < < 24 ) ;
int length = rplStrSize ( & strprolog ) ;
2019-05-18 00:00:33 +02:00
tmp = QString : : fromUtf8 ( ( char * ) ( buffer + 4 ) , length ) ;
2019-05-15 00:55:22 +02:00
tmp . detach ( ) ;
available = 1 ;
}
2019-04-06 00:38:00 +02:00
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
2019-05-07 23:35:11 +02:00
__usb_paused = 1 ;
while ( __usb_paused > = 0 ) ;
usb_shutdown ( ) ;
2019-05-10 23:50:19 +02:00
__usb_curdevice = 0 ;
2019-05-07 23:35:11 +02:00
__usb_timeout = 5000 ; // SET TIMEOUT TO THE DEFAULT 5000ms
2017-12-04 19:02:06 +01:00
2019-05-15 00:55:22 +02:00
if ( ! available ) {
tmp = " [Device not responding] " ;
}
item - > setText ( 2 , tmp ) ;
2019-05-10 23:50:19 +02:00
2017-12-04 19:02:06 +01:00
}
2017-11-28 19:15:50 +01:00
2019-05-15 00:55:22 +02:00
restart = 0 ;
}
2017-11-28 19:15:50 +01:00
2017-11-30 19:23:09 +01:00
}
}
2017-11-28 19:15:50 +01:00
2019-05-15 00:55:22 +02:00
__usb_timeout = 5000 ; // MAKE SURE WE LEAVE THE TIMEOUT TO THE DEFAULT VALUE
2017-11-28 19:15:50 +01:00
2019-05-13 18:29:32 +02:00
}
2019-05-15 00:55:22 +02:00
2019-05-18 00:00:33 +02:00
ui - > USBtreeWidget - > resizeColumnToContents ( 0 ) ;
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 ( )
{
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 ( )
{
2019-05-18 00:00:33 +02: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 : : refresh ( )
{
2019-05-18 00:00:33 +02:00
if ( norefresh ) return ;
2017-11-29 00:16:29 +01:00
RefreshList ( ) ;
2019-05-15 00:55:22 +02:00
QTimer : : singleShot ( 500 , this , SLOT ( refresh ( ) ) ) ;
2019-05-10 23:50:19 +02:00
2017-11-28 19:15:50 +01:00
}
2019-03-09 00:05:36 +01:00
extern " C " int usbremotefwupdatestart ( ) ;
extern " C " int usbsendtoremote ( uint32_t * data , int nwords ) ;
2019-05-18 00:00:33 +02:00
2019-03-09 00:05:36 +01:00
void USBSelector : : on_updateFirmware_clicked ( )
{
2019-04-22 18:11:07 +02:00
// STOP REFRESHING THE LIST
2019-05-18 00:51:39 +02:00
norefresh = true ;
2019-04-22 18:11:07 +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
2019-05-23 00:45:03 +02:00
norefresh = false ;
QTimer : : singleShot ( 500 , this , SLOT ( refresh ( ) ) ) ;
2019-04-22 18:11:07 +02:00
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
2019-05-23 00:45:03 +02:00
norefresh = false ;
QTimer : : singleShot ( 500 , this , SLOT ( refresh ( ) ) ) ;
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
2019-05-23 00:45:03 +02:00
norefresh = false ;
QTimer : : singleShot ( 500 , this , SLOT ( refresh ( ) ) ) ;
2019-04-22 18:11:07 +02:00
return ;
}
} else {
// START REFRESHING THE LIST AGAIN
2019-05-23 00:45:03 +02:00
norefresh = false ;
QTimer : : singleShot ( 500 , this , SLOT ( refresh ( ) ) ) ;
2019-05-18 00:00:33 +02:00
2019-04-22 18:11:07 +02:00
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
2019-05-18 00:00:33 +02:00
__usb_paused = 1 ;
while ( __usb_paused > = 0 ) ;
usb_shutdown ( ) ;
if ( safe_stringcpy ( __usb_devicepath , 8192 , SelectedDevicePath . toUtf8 ( ) . constData ( ) ) ) __usb_devicepath [ 0 ] = 0 ;
usb_init ( 0 ) ;
2019-03-09 00:05:36 +01:00
2019-05-23 00:45:03 +02:00
__fwupdate_progress = 0 ;
2019-05-18 00:00:33 +02:00
if ( ! usb_isconnected ( ) ) {
2019-04-23 23:29:33 +02:00
// TODO: ERROR PROCESS
2019-05-18 00:00:33 +02:00
// START REFRESHING THE LIST AGAIN
2019-05-23 00:45:03 +02:00
finishedupdate ( ) ;
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 ( )
{
2019-05-18 00:00:33 +02:00
2019-04-23 23:29:33 +02:00
// PUT THE USB DRIVER TO REST
__usb_paused = 1 ;
2019-04-25 19:16:42 +02:00
while ( __usb_paused > = 0 ) ;
2019-04-23 23:29:33 +02:00
2019-05-18 00:00:33 +02:00
usb_shutdown ( ) ;
2019-04-23 23:29:33 +02:00
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-05-23 00:45:03 +02:00
//ui->USBtreeWidget->clear();
2019-04-23 23:29:33 +02:00
ui - > USBtreeWidget - > setEnabled ( true ) ;
ui - > updateFirmware - > setEnabled ( true ) ;
ui - > updateProgress - > hide ( ) ;
ui - > updateProgress - > setValue ( 0 ) ;
ui - > buttonBox - > setEnabled ( true ) ;
numberoftries = 0 ;
2019-05-23 00:45:03 +02:00
norefresh = false ;
2019-04-23 23:29:33 +02:00
// AND JUST HOPE IT WILL RECONENCT SOME TIME
2019-05-18 00:00:33 +02:00
// START REFRESHING THE LIST AGAIN
2019-05-23 00:45:03 +02:00
QTimer : : singleShot ( 0 , this , SLOT ( refresh ( ) ) ) ;
2019-04-23 23:29:33 +02:00
}
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 ( )
{
2019-04-25 19:16:42 +02:00
2019-04-23 23:29:33 +02:00
int nwords = __fwupdate_nwords ;
__fwupdate_progress = 0 ;
2019-04-19 23:05:47 +02:00
// START USB DRIVER
__usb_paused = 0 ;
2019-04-25 15:30:25 +02:00
{
2019-05-18 00:00:33 +02:00
// WAIT 200ms BEFORE STARTING ANOTHER CONVERSATION WITH THE DEVICE
2019-04-25 15:30:25 +02:00
tmr_t start , end ;
start = tmr_ticks ( ) ;
2019-04-25 19:16:42 +02:00
do end = tmr_ticks ( ) ; while ( tmr_ticks2ms ( start , end ) < 200 ) ;
2019-04-25 15:30:25 +02:00
}
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-25 19:16:42 +02:00
{
2019-05-07 23:35:11 +02:00
// WAIT 500ms BEFORE STARTING ANOTHER CONVERSATION WITH THE DEVICE
2019-04-25 19:16:42 +02:00
tmr_t start , end ;
start = tmr_ticks ( ) ;
2019-05-21 19:12:26 +02:00
do end = tmr_ticks ( ) ; while ( tmr_ticks2ms ( start , end ) < 500 ) ;
2019-04-25 19:16:42 +02:00
}
2019-03-09 00:05:36 +01:00
2019-05-07 23:35:11 +02:00
WORD header [ 3 ] ;
2019-04-22 18:11:07 +02:00
int result = 1 , offset = 0 ;
2019-05-09 00:57:48 +02:00
int fileid ;
2019-04-22 18:11:07 +02:00
2019-04-25 19:16:42 +02:00
while ( result & & ( nwords > 1024 ) ) {
2019-03-09 00:05:36 +01:00
2019-05-09 00:57:48 +02:00
if ( result ) result = fileid = usb_txfileopen ( ' W ' ) ;
if ( ! result ) {
2019-04-19 23:05:47 +02:00
// TODO: SOME KIND OF ERROR
2019-04-22 18:11:07 +02:00
break ;
2019-04-19 23:05:47 +02:00
}
2019-04-22 18:11:07 +02:00
// SEND FIRMWARE BLOCK MARKER
2019-04-19 23:05:47 +02:00
2019-05-07 23:35:11 +02:00
header [ 0 ] = TEXT2WORD ( ' F ' , ' W ' , ' U ' , ' P ' ) ;
header [ 1 ] = __fwupdate_address + ( offset < < 2 ) ;
header [ 2 ] = 1024 ;
2019-04-19 23:05:47 +02:00
2019-05-09 00:57:48 +02:00
if ( result & & ( ! usb_filewrite ( fileid , ( BYTEPTR ) header , 3 * sizeof ( WORD ) ) ) ) {
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-05-07 23:35:11 +02:00
BYTEPTR buffer = __fwupdate_buffer + offset * sizeof ( WORD ) ;
2019-05-09 00:57:48 +02:00
if ( ! usb_filewrite ( fileid , buffer , 1024 * sizeof ( WORD ) ) ) {
2019-05-07 23:35:11 +02:00
result = 0 ;
break ;
2019-04-22 14:12:52 +02:00
}
2019-05-07 23:35:11 +02:00
offset + = 1024 ;
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-05-09 00:57:48 +02:00
if ( result & & ( ! usb_txfileclose ( fileid ) ) ) {
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-25 19:16:42 +02:00
if ( result & & nwords ) {
2019-05-09 00:57:48 +02:00
result = fileid = usb_txfileopen ( ' W ' ) ;
2019-04-19 23:05:47 +02:00
2019-04-22 18:11:07 +02:00
// SEND FIRMWARE BLOCK MARKER
2019-05-07 23:35:11 +02:00
header [ 0 ] = TEXT2WORD ( ' F ' , ' W ' , ' U ' , ' P ' ) ;
header [ 1 ] = __fwupdate_address + ( offset < < 2 ) ;
header [ 2 ] = nwords ;
2019-04-22 18:11:07 +02:00
2019-05-09 00:57:48 +02:00
if ( result & & ( ! usb_filewrite ( fileid , ( BYTEPTR ) header , 3 * sizeof ( WORD ) ) ) ) {
2019-04-22 18:11:07 +02:00
// TODO: SOME KIND OF ERROR
result = 0 ;
}
2019-04-23 23:29:33 +02:00
if ( result ) {
2019-05-07 23:35:11 +02:00
BYTEPTR buffer = __fwupdate_buffer + offset * sizeof ( WORD ) ;
2019-05-09 00:57:48 +02:00
if ( ! usb_filewrite ( fileid , buffer , nwords * sizeof ( WORD ) ) ) {
2019-05-07 23:35:11 +02:00
result = 0 ;
2019-04-22 18:11:07 +02:00
}
2019-05-07 23:35:11 +02:00
offset + = nwords ;
2019-04-23 23:29:33 +02:00
}
2019-04-22 18:11:07 +02:00
2019-05-09 00:57:48 +02:00
if ( result & & ( ! usb_txfileclose ( fileid ) ) ) {
2019-04-22 18:11:07 +02:00
// TODO: SOME KIND OF ERROR
result = 0 ;
}
2019-05-07 23:35:11 +02:00
__fwupdate_progress = offset ;
2019-04-22 18:11:07 +02:00
2019-05-07 23:35:11 +02:00
}
2019-04-22 18:11:07 +02:00
2019-05-07 23:35:11 +02:00
// DONE SENDING THE LAST BLOCK
2019-04-22 14:12:52 +02:00
{
2019-04-25 19:16:42 +02:00
// WAIT TWO FULL SECONDS BEFORE STARTING ANOTHER CONVERSATION WITH THE DEVICE
2019-04-22 14:12:52 +02:00
tmr_t start , end ;
start = tmr_ticks ( ) ;
2019-04-25 19:16:42 +02:00
do end = tmr_ticks ( ) ; while ( tmr_ticks2ms ( start , end ) < 2000 ) ;
2019-04-22 14:12:52 +02:00
}
2019-04-19 23:05:47 +02:00
// NOW FINISH THE TEST BY RESETTING
2019-05-09 00:57:48 +02:00
result = fileid = usb_txfileopen ( ' W ' ) ;
2019-03-09 00:05:36 +01:00
2019-05-07 23:35:11 +02:00
header [ 0 ] = TEXT2WORD ( ' F ' , ' W ' , ' U ' , ' P ' ) ;
header [ 1 ] = 0xffffffff ;
header [ 2 ] = 0 ;
2019-04-19 23:05:47 +02:00
2019-05-09 00:57:48 +02:00
if ( result & & ( ! usb_filewrite ( fileid , ( BYTEPTR ) header , 3 * sizeof ( WORD ) ) ) ) {
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-05-09 00:57:48 +02:00
if ( result & & ( ! usb_txfileclose ( fileid ) ) ) {
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
2019-04-24 23:23:20 +02:00