Added support for firmware update for HP Prime (untested)

Added validation of firmware images for each device
Improved handling of CRC errors in USB file transfer protocols
Fixed several compiler warnings
This commit is contained in:
claudiol 2021-06-17 21:14:23 -04:00
parent 327f35796c
commit c198edc6ca
12 changed files with 290 additions and 1888 deletions

View file

@ -803,7 +803,9 @@ extern char SERIAL_NUMBER_ADDRESS[11];
#undef STR_PRODLENGTH
#define STR_PRODLENGTH 22+2
// Override USB buffer size
#undef LONG_BUFFER_SIZE
#define LONG_BUFFER_SIZE 6*32*RAWHID_RX_SIZE

View file

@ -63,6 +63,7 @@
#define USB_STATUS_NOWAIT (1<<19)
#define USB_STATUS_WAIT_FOR_ACK (1<<20) // PACKET HAS BEEN SENT ON EP1, WAIT FOR ACK
#define USB_STATUS_SEND_ZERO_LENGTH_PACKET (1<<21) // SEND ZERO LENGTH PACKET NEXT
#define USB_STATUS_WAIT_FOR_REPORT (1<<22) // REPORT WAS REQUESTED, WAIT FOR IT
// MAXIMUM SIZE OF A BLOCK OF DATA, LARGER BLOCKS WILL BE SPLIT INTO MULTIPLE SMALLER BLOCKS
#define USB_DATASIZE (RAWHID_TX_SIZE-8)
@ -101,7 +102,7 @@ typedef struct
#define P_TYPE_REPORT 0x84
#define LONG_BUFFER_SIZE 3*32*RAWHID_RX_SIZE
#define RING_BUFFER_SIZE ((int)sizeof(__usb_rxtxbuffer))
#define RING_BUFFER_SIZE (LONG_BUFFER_SIZE)
// NEW SIMPLIFIED GLOBALS
@ -111,12 +112,14 @@ extern BINT __usb_fileid; // CURRENT FILEID
extern BINT __usb_fileid_seq; // SEQUENTIAL NUMBER TO MAKE FILEID UNIQUE
extern BINT __usb_offset; // CURRENT OFFSET WITHIN THE FILE
extern WORD __usb_crc32; // CURRENT CRC32 OF DATA RECEIVED
extern BINT __usb_lastgood_offset; // LAST KNOWN GOOD OFFSET WITHIN THE FILE
extern WORD __usb_lastgood_crc; // LAST KNOWN MATCHING CRC32 OF DATA RECEIVED
extern BYTE __usb_ctlbuffer[RAWHID_RX_SIZE + 1]; // BUFFER TO RECEIVE CONTROL PACKETS IN THE CONTROL CHANNEL
extern BYTE __usb_tmprxbuffer[RAWHID_RX_SIZE + 1]; // TEMPORARY BUFFER TO RECEIVE DATA
extern BYTE __usb_ctlrxbuffer[RAWHID_RX_SIZE + 1]; // TEMPORARY BUFFER TO RECEIVE CONTROL PACKETS
extern BYTE __usb_ctltxbuffer[RAWHID_TX_SIZE + 1]; // TEMPORARY BUFFER TO TRANSMIT DATA
extern BYTE __usb_rxtxbuffer[LONG_BUFFER_SIZE]; // LARGE BUFFER TO RECEIVE AT LEAST 3 FULL FRAGMENTS
extern BYTE __usb_rxtxbuffer[]; // LARGE BUFFER TO RECEIVE AT LEAST 3 FULL FRAGMENTS
extern BINT __usb_rxoffset; // STARTING OFFSET OF THE DATA IN THE RX BUFFER
extern volatile BINT __usb_rxtxtop; // NUMBER OF BYTES USED IN THE RX BUFFER
extern volatile BINT __usb_rxtxbottom; // NUMBER OF BYTES IN THE RX BUFFER ALREADY READ BY THE USER

View file

@ -322,7 +322,6 @@ int FSUpdateHints(FS_VOLUME * fs)
void FSMarkVolumeReadOnly()
{
FS_VOLUME *fs;
if(FSystem.Volumes[FSystem.CurrentVolume] != NULL)
FSystem.Volumes[FSystem.CurrentVolume]->InitFlags |= VOLFLAG_READONLY;
}

View file

@ -197,8 +197,9 @@ void __keyb_update()
for(k=0;k<64;++k)
ggl_rect(&scr, SCREEN_WIDTH-4*(k+2), 0, SCREEN_WIDTH-4*(k+1),4 ,
(a&(1LL<<k))? 0xffffffff:0x44444444);
//************ END DEBUG
*/
//************ END DEBUG
// ANALYZE CHANGES
if(b != 0) {
// POST MESSAGE

View file

@ -239,6 +239,8 @@ BINT __usb_fileid __SYSTEM_GLOBAL__; // CURRENT FILEID
BINT __usb_fileid_seq __SYSTEM_GLOBAL__; // SEQUENTIAL NUMBER TO MAKE FILEID UNIQUE
BINT __usb_offset __SYSTEM_GLOBAL__; // CURRENT OFFSET WITHIN THE FILE
WORD __usb_crc32 __SYSTEM_GLOBAL__; // CURRENT CRC32 OF DATA RECEIVED
BINT __usb_lastgood_offset __SYSTEM_GLOBAL__; // LAST KNOWN GOOD OFFSET WITHIN THE FILE
WORD __usb_lastgood_crc __SYSTEM_GLOBAL__; // LAST KNOWN MATCHING CRC32 OF DATA RECEIVED
BYTE __usb_ctlbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // BUFFER TO RECEIVE CONTROL PACKETS IN THE CONTROL CHANNEL
BYTE __usb_tmprxbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // TEMPORARY BUFFER TO RECEIVE DATA
BYTE __usb_ctlrxbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // TEMPORARY BUFFER TO RECEIVE CONTROL PACKETS
@ -1082,7 +1084,7 @@ void usb_ep1_transmit()
int oldestdata = __usb_rxtxbottom - __usb_rxtxtop;
if(oldestdata < 0)
oldestdata += RING_BUFFER_SIZE;
if((bufoff < 0) || (bufoff > oldestdata)) {
if((bufoff < 0) || (bufoff > oldestdata) || (__usb_rxoffset!=__usb_lastgood_offset)) {
// WE DON'T HAVE THAT DATA STORED ANYMORE, ABORT THE FILE
usb_sendcontrolpacket(P_TYPE_ABORT);
__usb_fileid = 0;
@ -1110,7 +1112,7 @@ void usb_ep1_transmit()
__usb_offset = __usb_rxoffset;
}
__usb_txseq = 0; // RESTART BACK THE SEQUENCE NUMBER
__usb_crc32 = 0; // RESET THE CRC FROM HERE ON
__usb_crc32 = __usb_lastgood_crc; // RESET THE CRC FROM HERE ON
__usb_drvstatus &= ~USB_STATUS_ERROR; // REMOVE THE ERROR AND RESEND
}
@ -1144,6 +1146,12 @@ void usb_ep1_transmit()
if(p_type == 32)
p_type = 0x40;
if(p_type==1) {
// SAVE AT THE BEGINNING OF EACH FRAGMENT
__usb_lastgood_offset = __usb_offset;
__usb_lastgood_crc = __usb_crc32;
}
// SEND A FULL PACKET
*EP1_FIFO = p_type;
@ -1310,7 +1318,8 @@ void usb_ep2_receive()
else {
// GOT THE RIGHT OFFSET, RESET ERROR CONDITION IF ANY
if(__usb_drvstatus & USB_STATUS_ERROR) {
__usb_crc32 = 0;
// CRC AND OFFSET SHOULD BE CORRECTLY SET BY NOW
// SO LIFT THE ERROR CONDITION
__usb_drvstatus &= ~USB_STATUS_ERROR;
}
}
@ -1339,6 +1348,13 @@ void usb_ep2_receive()
}
// NEW PACKET IS READY TO BE RECEIVED, IF WE ARE STARTING A NEW FRAGMENT
// SAVE RESTORE POINT TO REQUEST THE FRAGMENT TO BE RESENT IF IT FAILS
if(p_type==1) {
__usb_lastgood_offset = __usb_offset;
__usb_lastgood_crc = __usb_crc32;
}
// WE HAVE NEW DATA, RECEIVE IT DIRECTLY AT THE BUFFER
rcvbuf = __usb_rxtxbuffer + __usb_rxtxtop;

View file

@ -76,6 +76,8 @@ BINT __usb_fileid __SYSTEM_GLOBAL__; // CURRENT FILEID
BINT __usb_fileid_seq __SYSTEM_GLOBAL__; // SEQUENTIAL NUMBER TO MAKE FILEID UNIQUE
BINT __usb_offset __SYSTEM_GLOBAL__; // CURRENT OFFSET WITHIN THE FILE
WORD __usb_crc32 __SYSTEM_GLOBAL__; // CURRENT CRC32 OF DATA RECEIVED
BINT __usb_lastgood_offset __SYSTEM_GLOBAL__; // LAST KNOWN GOOD OFFSET WITHIN THE FILE
WORD __usb_lastgood_crc __SYSTEM_GLOBAL__; // LAST KNOWN GOOD CRC32 OF DATA RECEIVED
BYTE __usb_ctlbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // BUFFER TO RECEIVE CONTROL PACKETS IN THE CONTROL CHANNEL
BYTE __usb_tmprxbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // TEMPORARY BUFFER TO RECEIVE DATA
BYTE __usb_ctlrxbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // TEMPORARY BUFFER TO RECEIVE CONTROL PACKETS
@ -345,6 +347,11 @@ void usb_ep1_transmit()
// DON'T SEND ANY DATA IF THE REMOTE REQUESTED HALT
return;
}
if(__usb_drvstatus & USB_STATUS_WAIT_FOR_ACK) {
// DON'T SEND ANY DATA IF WE ARE WAITING FOR AN ANSWER
return;
}
// WE HAVE A DATA PACKET TO SEND
if(__usb_drvstatus & USB_STATUS_ERROR) {
@ -360,7 +367,7 @@ void usb_ep1_transmit()
int oldestdata = __usb_rxtxbottom - __usb_rxtxtop;
if(oldestdata < 0)
oldestdata += RING_BUFFER_SIZE;
if((bufoff < 0) || (bufoff > oldestdata)) {
if((bufoff < 0) || (bufoff > oldestdata) ) {
// WE DON'T HAVE THAT DATA STORED ANYMORE, ABORT THE FILE
usb_sendcontrolpacket(P_TYPE_ABORT);
@ -396,7 +403,7 @@ void usb_ep1_transmit()
}
usb_mutex_lock();
__usb_txseq = 0; // RESTART BACK THE SEQUENCE NUMBER
__usb_crc32 = 0; // RESET THE CRC FROM HERE ON
__usb_crc32 = __usb_lastgood_crc; // RESET THE CRC FROM HERE ON
__usb_drvstatus &= ~USB_STATUS_ERROR; // REMOVE THE ERROR AND RESEND
usb_mutex_unlock();
}
@ -429,6 +436,12 @@ void usb_ep1_transmit()
if(p_type == 32)
p_type = 0x40;
if(p_type==1) {
// SAVE AT THE BEGINNING OF EACH FRAGMENT
__usb_lastgood_offset = __usb_offset;
__usb_lastgood_crc = __usb_crc32;
}
// SEND A FULL PACKET
BYTE tmpbuf[RAWHID_TX_SIZE + 1];
tmpbuf[0] = 0;
@ -591,7 +604,8 @@ void usb_ep2_receive()
// GOT THE RIGHT OFFSET, RESET ERROR CONDITION IF ANY
if(__usb_drvstatus & USB_STATUS_ERROR) {
usb_mutex_lock();
__usb_crc32 = 0;
// CRC AND OFFSET SHOULD BE CORRECTLY SET BY NOW
// SO LIFT THE ERROR CONDITION
__usb_drvstatus &= ~USB_STATUS_ERROR;
usb_mutex_unlock();
}
@ -616,6 +630,13 @@ void usb_ep2_receive()
}
// NEW PACKET IS READY TO BE RECEIVED, IF WE ARE STARTING A NEW FRAGMENT
// SAVE RESTORE POINT TO REQUEST THE FRAGMENT TO BE RESENT IF IT FAILS
if(p_type==1) {
__usb_lastgood_offset = __usb_offset;
__usb_lastgood_crc = __usb_crc32;
}
// WE HAVE NEW DATA, RECEIVE IT DIRECTLY AT THE BUFFER
rcvbuf = __usb_rxtxbuffer + __usb_rxtxtop;

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,8 @@ int SDCardInit(SD_CARD * card)
{
card->SysFlags = 0x1f;
card->Rca = 0x00010000;
card->CurrentBLen = card->MaxBlockLen = 9;
card->WriteBlockLen = 9;
return TRUE;
}

View file

@ -229,6 +229,8 @@ BINT __usb_fileid __SYSTEM_GLOBAL__; // CURRENT FILEID
BINT __usb_fileid_seq __SYSTEM_GLOBAL__; // SEQUENTIAL NUMBER TO MAKE FILEID UNIQUE
BINT __usb_offset __SYSTEM_GLOBAL__; // CURRENT OFFSET WITHIN THE FILE
WORD __usb_crc32 __SYSTEM_GLOBAL__; // CURRENT CRC32 OF DATA RECEIVED
BINT __usb_lastgood_offset __SYSTEM_GLOBAL__; // LAST KNOWN GOOD OFFSET WITHIN THE FILE
WORD __usb_lastgood_crc __SYSTEM_GLOBAL__; // LAST KNOWN MATCHING CRC32 OF DATA RECEIVED
BYTE __usb_ctlbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // BUFFER TO RECEIVE CONTROL PACKETS IN THE CONTROL CHANNEL
BYTE __usb_tmprxbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // TEMPORARY BUFFER TO RECEIVE DATA
BYTE __usb_ctlrxbuffer[RAWHID_RX_SIZE + 1] __SYSTEM_GLOBAL__; // TEMPORARY BUFFER TO RECEIVE CONTROL PACKETS
@ -246,6 +248,8 @@ BINT __usb_txseq __SYSTEM_GLOBAL__; // SEQUENTIAL NUMBER WITHIN A FRAGMENT O
BYTEPTR __usb_ctlbufptr __SYSTEM_GLOBAL__; // POINTER TO BUFFER DURING CONTROL CHANNEL TRANSFERS
BINT __usb_ctlcount __SYSTEM_GLOBAL__; // COUNT OF DATA DURING CONTROL CHANNEL TRANSFERS
// END OF NEW GLOBALS
// ********************************
@ -1141,7 +1145,7 @@ void usb_ep1_transmit()
int bufoff = (int)__usb_offset - (int)__usb_rxoffset;
int oldestdata = ringbuffer_dec(__usb_rxtxbottom, __usb_rxtxtop);
if((bufoff < 0) || (bufoff > oldestdata)) {
if((bufoff < 0) || (bufoff > oldestdata) || (__usb_rxoffset!=__usb_lastgood_offset)) {
// WE DON'T HAVE THAT DATA STORED ANYMORE, ABORT THE FILE
usb_sendcontrolpacket(P_TYPE_ABORT);
__usb_fileid = 0;
@ -1161,7 +1165,7 @@ void usb_ep1_transmit()
__usb_offset = __usb_rxoffset;
}
__usb_txseq = 0; // RESTART BACK THE SEQUENCE NUMBER
__usb_crc32 = 0; // RESET THE CRC FROM HERE ON
__usb_crc32 = __usb_lastgood_crc; // RESET THE CRC FROM HERE ON
__usb_drvstatus &= ~USB_STATUS_ERROR; // REMOVE THE ERROR AND RESEND
}
@ -1188,11 +1192,19 @@ void usb_ep1_transmit()
}
p_type = __usb_txseq + 1;
if(eof)
p_type |= 0x40;
if(p_type == 32)
p_type = 0x40;
if(p_type==1) {
// SAVE AT THE BEGINNING OF EACH FRAGMENT
__usb_lastgood_offset = __usb_offset;
__usb_lastgood_crc = __usb_crc32;
}
// SEND A FULL PACKET
// RAWHID_TX_SIZE AND USB_DATASIZE ARE ALWAYS EVEN
@ -1280,7 +1292,7 @@ void usb_ep2_receive()
int fifocnt = *BRCR & 0x3ff; // BRCR HAS HALFWORDS;
int lwo = *ESR & ESR_LWO;
if(fifocnt < 4 || (fifocnt == 4 && lwo)) { // LESS THAN 8 BYTES
if(fifocnt < 4 || ( (fifocnt == 4) && lwo)) { // LESS THAN 8 BYTES
// IGNORE THE MALFORMED PACKET
usb_flush_fifo2(fifocnt);
return;
@ -1326,6 +1338,7 @@ void usb_ep2_receive()
// THIS IS A DATA PACKET
// READ HEADER DIRECTLY INTO THE BUFFER
rcvbuf = __usb_tmprxbuffer;
rcvbuf[0] = MSB(halfword);
rcvbuf[1] = LSB(halfword);
@ -1368,7 +1381,8 @@ void usb_ep2_receive()
else {
// GOT THE RIGHT OFFSET, RESET ERROR CONDITION IF ANY
if(__usb_drvstatus & USB_STATUS_ERROR) {
__usb_crc32 = 0;
// CRC AND OFFSET SHOULD BE CORRECTLY SET BY NOW
// SO LIFT THE ERROR CONDITION
__usb_drvstatus &= ~USB_STATUS_ERROR;
}
}
@ -1389,12 +1403,21 @@ void usb_ep2_receive()
}
// NEW PACKET IS READY TO BE RECEIVED, IF WE ARE STARTING A NEW FRAGMENT
// SAVE RESTORE POINT TO REQUEST THE FRAGMENT TO BE RESENT IF IT FAILS
if(p_type==1) {
__usb_lastgood_offset = __usb_offset;
__usb_lastgood_crc = __usb_crc32;
}
// WE HAVE NEW DATA, RECEIVE IT DIRECTLY AT THE BUFFER
while(fifocnt && (cnt < pptr->p_dataused + 8)) {
halfword = *EP2BR;
--fifocnt;
if (fifocnt != 0 || !lwo) {
if ( (fifocnt != 0) || !lwo) {
__usb_rxtxbuffer[__usb_rxtxtop] = MSB(halfword);
__usb_crc32 = usb_crc32roll(__usb_crc32, __usb_rxtxbuffer + __usb_rxtxtop, 1);
__usb_rxtxtop = ringbuffer_inc(__usb_rxtxtop, 1);

View file

@ -61,6 +61,7 @@
4 BYTES = HIGHEST RECEIVED OFFSET SO FAR
1 BYTES = 0 = OK TO RECEIVE MORE DATA, 1 = ONE BUFFER IS FULL, HALT DATA UNTIL IT PROGRAM READS IT (OTHER BUFFER IS STILL AVAILABLE TO RECEIVE PACKETS THAT WERE ALREADY SENT)
1 BYTES = 0 = CRC32 OK SO FAR, 1 = CRC OR OTHER ERROR: RESEND FRAGMENTS FROM THE GIVEN OFFSET
1 BYTES = 1 = ALL BYTES IN THE FILE RECEIVED OK
COMMUNICATION PROTOCOL:
@ -136,8 +137,20 @@ void usb_sendcontrolpacket(int packet_type)
p->p_data[1] = (__usb_crc32 >> 8) & 0xff;
p->p_data[2] = (__usb_crc32 >> 16) & 0xff;
p->p_data[3] = (__usb_crc32 >> 24) & 0xff;
/*
// *************************************
// ** DEBUG ONLY: INTRODUCE A BAD CRC ON PURPOSE
// *************************************
if(__usb_offset==0xe00) {
if(!(__usb_drvstatus&(1<<22))) p->p_data[0]^=0xff;
__usb_drvstatus|=1<<22;
}
*/
__usb_drvstatus &= ~USB_STATUS_RXRCVD;
//__usb_drvstatus|=USB_STATUS_HALT;
__usb_drvstatus|=USB_STATUS_WAIT_FOR_REPORT;
break;
case P_TYPE_ENDOFFILE:
@ -150,6 +163,7 @@ void usb_sendcontrolpacket(int packet_type)
p->p_data[2] = (__usb_crc32 >> 16) & 0xff;
p->p_data[3] = (__usb_crc32 >> 24) & 0xff;
__usb_drvstatus &= ~USB_STATUS_RXRCVD;
__usb_drvstatus|=USB_STATUS_WAIT_FOR_REPORT;
break;
case P_TYPE_ABORT:
@ -162,10 +176,16 @@ void usb_sendcontrolpacket(int packet_type)
p->p_type = P_TYPE_REPORT;
p->p_fileidLSB = (BYTE) (__usb_fileid & 0xff);
p->p_fileidMSB = (BYTE) (__usb_fileid >> 8);
p->p_offset = __usb_offset;
p->p_offset = (__usb_drvstatus & USB_STATUS_ERROR) ? __usb_lastgood_offset : __usb_offset;
p->p_data[0] = (__usb_drvstatus & USB_STATUS_HALT) ? 1 : 0;
p->p_data[1] = (__usb_drvstatus & USB_STATUS_ERROR) ? 1 : 0;
p->p_data[2] = (__usb_rxtotalbytes) ? 1 : 0;
WORD crc = (__usb_drvstatus & USB_STATUS_ERROR) ? __usb_lastgood_crc : __usb_crc32;
p->p_data[4] = crc & 0xff;
p->p_data[5] = (crc >> 8) & 0xff;
p->p_data[6] = (crc >> 16) & 0xff;
p->p_data[7] = (crc >> 24) & 0xff;
break;
default:
@ -213,11 +233,9 @@ void usb_receivecontrolpacket()
if(__usb_fileid == P_FILEID(ctl)) {
usb_mutex_lock();
if(__usb_drvstatus & USB_STATUS_ERROR) {
// IGNORE THE CHECKPOINT, THERE WAS A PRIOR ERROR
usb_mutex_unlock();
break;
}
int previouserror= (__usb_drvstatus & USB_STATUS_ERROR);
__usb_drvstatus &= ~USB_STATUS_ERROR; // REMOVE ERROR SIGNAL
int used = __usb_rxtxtop - __usb_rxtxbottom;
@ -232,7 +250,8 @@ void usb_receivecontrolpacket()
crc |= ((WORD) ctl->p_data[2]) << 16;
crc |= ((WORD) ctl->p_data[3]) << 24;
if(__usb_crc32 != crc) {
__usb_drvstatus |= USB_STATUS_ERROR; // SIGNAL TO RESEND FROM CURRENT OFFSET
if(!previouserror) __usb_drvstatus |= USB_STATUS_ERROR; // SIGNAL TO RESEND FROM CURRENT OFFSET
else __usb_crc32=crc; // SYNC WITH THE CRC PROPOSED BY THE SENDER IF THERE WAS A PRIOR ERROR
}
usb_mutex_unlock();
@ -268,8 +287,10 @@ void usb_receivecontrolpacket()
__usb_drvstatus |= USB_STATUS_ERROR; // SIGNAL TO RESEND FROM CURRENT OFFSET
// SET TOTAL BYTES TO INDICATE WE RECEIVED THE LAST OF IT
if(!(__usb_drvstatus & USB_STATUS_ERROR))
__usb_rxtotalbytes = ctl->p_offset;
if(!(__usb_drvstatus & USB_STATUS_ERROR)) {
__usb_lastgood_offset = __usb_rxtotalbytes = ctl->p_offset;
__usb_lastgood_crc = crc;
}
usb_mutex_unlock();
@ -290,7 +311,7 @@ void usb_receivecontrolpacket()
~(USB_STATUS_TXDATA | USB_STATUS_TXCTL |
USB_STATUS_RXDATA | USB_STATUS_HALT | USB_STATUS_ERROR |
USB_STATUS_RXCTL | USB_STATUS_EOF | USB_STATUS_WAIT_FOR_ACK |
USB_STATUS_SEND_ZERO_LENGTH_PACKET);
USB_STATUS_SEND_ZERO_LENGTH_PACKET | USB_STATUS_WAIT_FOR_REPORT);
// ABORT ALL TRANSACTIONS
__usb_fileid = 0;
@ -328,7 +349,13 @@ void usb_receivecontrolpacket()
if(ctl->p_data[1]) {
// SIGNAL THE ERROR AND LEAVE THE REQUESTED OFFSET AT rxoffset
__usb_drvstatus |= USB_STATUS_ERROR;
__usb_rxoffset = ctl->p_offset;
__usb_rxoffset = __usb_lastgood_offset = ctl->p_offset;
// ALSO RECOVER THE CRC TO RESTART TRANSMISSION
WORD crc = ctl->p_data[4];
crc |= ((WORD) ctl->p_data[5]) << 8;
crc |= ((WORD) ctl->p_data[6]) << 16;
crc |= ((WORD) ctl->p_data[7]) << 24;
__usb_lastgood_crc = crc;
}
else {
__usb_drvstatus &= ~USB_STATUS_ERROR;
@ -347,6 +374,7 @@ void usb_receivecontrolpacket()
}
__usb_drvstatus |= USB_STATUS_RXRCVD;
__usb_drvstatus &= ~USB_STATUS_WAIT_FOR_REPORT; // DON'T WAIT ANY LONGER, WE GOT OUR REPORT
usb_mutex_unlock();
@ -385,10 +413,18 @@ int usb_hasdata()
{
if((__usb_drvstatus & USB_STATUS_RXDATA)
&& (__usb_rxtxtop != __usb_rxtxbottom)) {
int bytesready = __usb_rxtxtop - __usb_rxtxbottom;
if(bytesready < 0)
bytesready += RING_BUFFER_SIZE;
return bytesready;
//int bytesready = __usb_rxtxtop - __usb_rxtxbottom;
//if(bytesready < 0)
// bytesready += RING_BUFFER_SIZE;
// ONLY RETURN DATA THAT HAS BEEN CRC32 VERIFIED
int bytesverified = __usb_lastgood_offset - __usb_rxoffset;
if(bytesverified<0) return 0;
return bytesverified;
}
return 0;
}
@ -516,8 +552,8 @@ int usb_txfileopen(int file_type)
__usb_rxtxtop = __usb_rxtxbottom = 0;
__usb_txseq = 0; // FIRST PACKET NUMBER
__usb_offset = 0;
__usb_crc32 = 0; // RESET CRC32
__usb_lastgood_offset = __usb_offset = 0;
__usb_lastgood_crc = __usb_crc32 = 0; // RESET CRC32
__usb_txtotalbytes = 0;
// CREATE A NEW FILEID
++__usb_fileid_seq;

View file

@ -619,7 +619,7 @@ void LIB_HANDLER()
case OVR_ISTRUE:
{
if(ISPROLOG(rplPeekData(1))) {
if(ISPROLOG(*rplPeekData(1))) {
WORDPTR dataptr=rplPeekData(1);
BINT size=OBJSIZE(*dataptr)-2;
dataptr+=2;

View file

@ -560,25 +560,90 @@ void USBSelector::on_updateFirmware_clicked()
file.close();
// THIS IS ONLY VALID FOR 50G AND COUSINS, FIX LATER
if((strncmp(filedata.constData(), "KINPOHP39G+IMAGE", 16) == 0) ||
(strncmp(filedata.constData(), "KINPOHP40G+IMAGE", 16) == 0) ||
(strncmp(filedata.constData(), "KINPOUPDATEIMAGE", 16) == 0)) {
const char *calc_types[]={
"newRPL Calc",
"newRPL 50g",
"newRPL 39gs",
"newRPL 40gs",
"newRPL 48g2",
"newRPL PrG1",
0
};
const char *preamble_strings[]={
"KINPOUPDATEIMAGE",
"KINPOUPDATEIMAGE",
"KINPOHP39G+IMAGE",
"KINPOHP40G+IMAGE",
"KINPOHP48GIIMAGE",
"2416",
0
};
const int preamble_offset[]={
0,
0,
0,
0,
0,
24,
0
};
// CHECK IF VALID FIRMWARE WAS SELECTED
int calcidx=0;
while(calc_types[calcidx]) {
if(SelectedDeviceName.startsWith(calc_types[calcidx])) break;
++calcidx;
}
if(calc_types[calcidx]==nullptr) {
QMessageBox a(QMessageBox::Warning, "Device NOT Supported",
SelectedDeviceName + ": Firmware update not supported on this device", QMessageBox::Ok, this);
a.exec();
// START REFRESHING THE LIST AGAIN
norefresh = false;
QTimer::singleShot(500, this, SLOT(refresh()));
return;
}
// HERE WE HAVE THE INDEX OF A SUPPORTED DEVICE
//
// THIS IS ONLY VALID FOR 50G AND COUSINS, FIX LATER
const char *preamblestring = filedata.constData();
preamblestring+=preamble_offset[calcidx];
int bytelen=strlen(preamble_strings[calcidx]);
// CHECK IF SELECTED FIRMWARE IS VALID FOR THE TARGET
if( ((calcidx>0) && (strncmp(preamblestring,preamble_strings[calcidx],bytelen)!=0)) // DEVICES USING NEW FIRMWARES, FROM NOW ON
|| ((calcidx==0) && (strncmp(preamblestring,preamble_strings[2],bytelen)!=0) &&
(strncmp(preamblestring,preamble_strings[3],bytelen)!=0) &&
(strncmp(preamblestring,preamble_strings[4],bytelen)!=0)) ) // HANDLE SPECIAL CASE OF OLD FIRMWARES USING "newRPL Calc" FOR ALL DEVICES
{
// THIS IS NOT A VALID FIRMWARE IMAGE
QMessageBox a(QMessageBox::Warning, "Invalid firmware image",
"Selected file does not contain a valid image for this target device", QMessageBox::Ok, this);
a.exec();
// START REFRESHING THE LIST AGAIN
norefresh = false;
QTimer::singleShot(500, this, SLOT(refresh()));
return;
}
address = 0x4000;
nwords = filedata.size() >> 2;
filedata.replace(0, 16, "Kinposhcopyright");
}
else {
QMessageBox a(QMessageBox::Warning, "Invalid firmware image",
"Invalid firmware image", QMessageBox::Ok, this);
a.exec();
// START REFRESHING THE LIST AGAIN
norefresh = false;
QTimer::singleShot(500, this, SLOT(refresh()));
return;
}
if(calcidx<5) filedata.replace(0, 16, "Kinposhcopyright");
QMessageBox warn(QMessageBox::Warning, "Firmware update",
"Firmware on the remote device is about to be updated. Do NOT disconnect the device. OK to proceed?",