/**************************************************************************** Function : issueBlock Description : Send data over USB bus to UBW32. Parameters : unsigned int Destination address on PIC device. char Byte count (max 56). char Verify vs. write. Returns : ErrorCode ERR_NONE on success, or error code as returned from usbWrite(); ****************************************************************************/ static ErrorCode issueBlock( const unsigned int addr, const char len, const char verify) { ErrorCode status; #ifdef DEBUG (void)printf("Address: %08x Len %d\n",addr,len); #else (void)putchar('.'); fflush(stdout); #endif bufWrite32(usbBuf,1,addr); usbBuf[5] = len; if(verify) { DEBUGMSG("Verifying"); usbBuf[0] = GET_DATA; if(ERR_NONE == (status = usbWrite(6,1))) { #ifdef DEBUG int i; if(memcmp(&usbBuf[64 - len],hexBuf,len)) { (void)puts("Verify FAIL\nExpected:"); (void)printf("NA NA NA NA NA NA NA NA - "); for(i=0;i<(56-len);i++) (void)printf("NA "); for(i=0;i<len;i++) (void)printf("%02x ",hexBuf[i]); (void)putchar('\n'); fflush(stdout); return ERR_VERIFY; } else { (void)puts("Verify OK"); return ERR_NONE; } #else return (memcmp(&usbBuf[64 - len],hexBuf,len) ? ERR_VERIFY : ERR_NONE); #endif } } else { DEBUGMSG("Writing"); usbBuf[0] = PROGRAM_DEVICE; /* Regardless of actual byte count, data packet is always 64 bytes. Following the header, the bootloader wants the data portion 'right justified' within packet. Odd. */ memcpy(&usbBuf[64 - len],hexBuf,len); if((ERR_NONE == (status = usbWrite(64,0))) && (len < 56)) { /* Short data packets need flushing */ DEBUGMSG("Completing"); usbBuf[0] = PROGRAM_COMPLETE; status = usbWrite(1,0); } } #ifdef DEBUG if(status != ERR_NONE) (void)puts("ERROR"); #endif return status; }
/**************************************************************************** Function : issueBlock Description : Send data over USB bus to device. Parameters : unsigned int Destination address on PIC device. char Byte count (max 56). char Verify vs. write. Returns : ErrorCode ERR_NONE on success, or error code as returned from usbWrite(); ****************************************************************************/ static ErrorCode issueBlock( unsigned int addr, char len, char verify) { ErrorCode status; #ifdef DEBUG (void)printf("Address: %08x Len %d\n",addr,len); #else (void)putchar('.'); fflush(stdout); #endif // check device memory blocks are programmable if ( verifyBlockProgrammable( &addr, &len ) ) { #ifdef DEBUG printf( "Skip data on address %04x with length %d\n", addr, len ); #endif return ERR_NONE; } // length must be even if ( len & 1 ) { #ifdef DEBUG printf( "Add one byte to data on address %04x with length %d\n", addr, len ); #endif hexBuf[ len++ ] = 0xff; } /* Short data packets need flushing */ if (!verify && len == 0 && !Flushed) { DEBUGMSG("Completing"); usbBuf[0] = PROGRAM_COMPLETE; status = usbWrite(1,0); Flushed= 1; return status; } bufWrite32(usbBuf,1,addr / bytesPerAddress); usbBuf[5] = len; if(verify) { DEBUGMSG("Verifying"); usbBuf[0] = GET_DATA; if(ERR_NONE == (status = usbWrite(6,1))) { #ifdef DEBUG int i; if(memcmp(&usbBuf[64 - len],hexBuf,len)) { (void)puts("Verify FAIL\nExpected:"); (void)printf("NA NA NA NA NA NA NA NA - "); for(i=0;i<(56-len);i++) (void)printf("NA "); for(i=0;i<len;i++) (void)printf("%02x ",hexBuf[i]); (void)putchar('\n'); fflush(stdout); return ERR_VERIFY; } else { (void)puts("Verify OK"); return ERR_NONE; } #else return (memcmp(&usbBuf[64 - len],hexBuf,len) ? ERR_VERIFY : ERR_NONE); #endif } } else { DEBUGMSG("Writing"); usbBuf[0] = PROGRAM_DEVICE; /* Regardless of actual byte count, data packet is always 64 bytes. Following the header, the bootloader wants the data portion 'right justified' within packet. Odd. */ memcpy(&usbBuf[64 - len],hexBuf,len); if((ERR_NONE == (status = usbWrite(64,0))) && (len < 56)) { /* Short data packets need flushing */ DEBUGMSG("Completing"); usbBuf[0] = PROGRAM_COMPLETE; status = usbWrite(1,0); } // flag if external code may need to flush before next write Flushed= (len < 56); } #ifdef DEBUG if(status != ERR_NONE) (void)puts("ERROR"); #endif return status; }