Flash NROM PRG-ROM operations are pretty well up to snuff now.
Had to add check to get cur_buff status and wait to send payload until it's empty. Still need to add timeout check as it'll spin forever if there is a problem and it's never empty... device should be able to handle buffer sizes smaller than usb transfer but this probably isn't true if the first two bytes are stuffed into setup packet. Currently relies on end of (upto) 8 byte transfer to fill buffer. MAKECHECKS would verify we don't overflow buffer.. Still kind of a half thought out idea unfortunately.
This commit is contained in:
parent
fe04496cfb
commit
52a1b306c9
|
|
@ -229,10 +229,10 @@ uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff,
|
||||||
*rvalue = raw_bank_status[operLSB];
|
*rvalue = raw_bank_status[operLSB];
|
||||||
*rlength += 1;
|
*rlength += 1;
|
||||||
break;
|
break;
|
||||||
//case GET_BUFF_OPERATION:
|
case GET_CUR_BUFF_STATUS:
|
||||||
// *rvalue = operation;
|
*rvalue = cur_buff->status;
|
||||||
// *rlength += 1;
|
*rlength += 1;
|
||||||
// break;
|
break;
|
||||||
case GET_PRI_ELEMENTS:
|
case GET_PRI_ELEMENTS:
|
||||||
rvalue[0] = buff->last_idx;
|
rvalue[0] = buff->last_idx;
|
||||||
rvalue[1] = buff->status;
|
rvalue[1] = buff->status;
|
||||||
|
|
@ -337,6 +337,8 @@ uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbu
|
||||||
cur_usb_load_buff = cur_buff;
|
cur_usb_load_buff = cur_buff;
|
||||||
cur_buff->status = USB_LOADING;
|
cur_buff->status = USB_LOADING;
|
||||||
} else {
|
} else {
|
||||||
|
//both buffers are in use
|
||||||
|
//last buffer is flashing, and cur is full, need to wait on last to finish
|
||||||
set_operation( PROBLEM );
|
set_operation( PROBLEM );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -710,15 +712,19 @@ void update_buffers()
|
||||||
//cur_buff will get sent to usbFunctionWrite on next payload OUT transfer
|
//cur_buff will get sent to usbFunctionWrite on next payload OUT transfer
|
||||||
//All we need to do here is monitor usbFWr's status via incoming_bytes_remain
|
//All we need to do here is monitor usbFWr's status via incoming_bytes_remain
|
||||||
//which gets set to 254 on wr transfers once gets to zero buffer is filled
|
//which gets set to 254 on wr transfers once gets to zero buffer is filled
|
||||||
if ( (incoming_bytes_remain == 0) && (cur_buff->status != EMPTY) ) {
|
//if ( (incoming_bytes_remain == 0) && (cur_buff->status != EMPTY) ) {
|
||||||
incoming_bytes_remain--; //don't want to re-enter
|
// incoming_bytes_remain--; //don't want to re-enter
|
||||||
//if ( cur_buff->status == USB_FULL) {
|
if ( cur_buff->status == USB_FULL) {
|
||||||
|
|
||||||
//buffer full, send to flash routine
|
//buffer full, send to flash routine
|
||||||
last_buff = cur_buff;
|
last_buff = cur_buff;
|
||||||
//but first want to update cur_buff to next buffer so it can
|
//but first want to update cur_buff to next buffer so it can
|
||||||
//start loading on next OUT transfer
|
//start loading on next OUT transfer
|
||||||
cur_buff = get_next_buff( cur_buff, num_buff );
|
cur_buff = get_next_buff( cur_buff, num_buff );
|
||||||
|
|
||||||
|
//the other buffer must be complete if we've gotten to this point
|
||||||
|
//because this function only gets called from main
|
||||||
|
//so we can now change it from FLASHED to EMPTY
|
||||||
cur_buff->status = EMPTY;
|
cur_buff->status = EMPTY;
|
||||||
|
|
||||||
last_buff->status = FLASHING;
|
last_buff->status = FLASHING;
|
||||||
|
|
|
||||||
|
|
@ -303,6 +303,13 @@ USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||||
data_cur++;
|
data_cur++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//need to account for the fact that cur_byte will roll over being 8bit value
|
||||||
|
if ( cur_usb_load_buff->last_idx == (cur_usb_load_buff->cur_byte + len - 1) ) {
|
||||||
|
//this signals to buffer.c so it can update cur_usb_load_buf
|
||||||
|
//and start tasking this buffer to programming
|
||||||
|
cur_usb_load_buff->status = USB_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
//update counters and status
|
//update counters and status
|
||||||
cur_usb_load_buff->cur_byte += len;
|
cur_usb_load_buff->cur_byte += len;
|
||||||
incoming_bytes_remain -= len;
|
incoming_bytes_remain -= len;
|
||||||
|
|
@ -311,15 +318,9 @@ USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||||
//want this function to be as fast as possible, so buffer.c checks if
|
//want this function to be as fast as possible, so buffer.c checks if
|
||||||
//the buffer is full 'behind the scenes' outside of this function.
|
//the buffer is full 'behind the scenes' outside of this function.
|
||||||
|
|
||||||
//if ( (cur_usb_load_buff->last_idx) == buf_cur) {
|
|
||||||
if ( cur_usb_load_buff->last_idx == cur_usb_load_buff->cur_byte ) {
|
|
||||||
//this signals to buffer.c so it can update cur_usb_load_buf
|
|
||||||
//and start tasking this buffer to programming
|
|
||||||
cur_usb_load_buff->status = USB_FULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( incoming_bytes_remain == 0 ) { //done with OUT transfer
|
if ( incoming_bytes_remain == 0 ) { //done with OUT transfer
|
||||||
cur_usb_load_buff->status = USB_FULL;
|
// cur_usb_load_buff->status = USB_FULL;
|
||||||
return PAYLD_DONE;
|
return PAYLD_DONE;
|
||||||
} else { //more data packets remain to complete OUT transfer
|
} else { //more data packets remain to complete OUT transfer
|
||||||
return NOT_DONE;
|
return NOT_DONE;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,26 @@ int reset_buffers( USBtransfer *transfer )
|
||||||
USB_IN, NULL, 1);
|
USB_IN, NULL, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Desc:Get cur_buff status. Used to ensure device is ready for next payload
|
||||||
|
* Pre:
|
||||||
|
* Post:
|
||||||
|
* Rtn: cur buff status byte
|
||||||
|
*/
|
||||||
|
int get_cur_buff_status( USBtransfer *transfer, int *status )
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
uint8_t data[2];
|
||||||
|
|
||||||
|
rv = dictionary_call( transfer, DICT_BUFFER, GET_CUR_BUFF_STATUS, NILL, NILL,
|
||||||
|
USB_IN, data, 2);
|
||||||
|
|
||||||
|
if ( rv == SUCCESS )
|
||||||
|
//was able to retrieve status
|
||||||
|
*status = data[RV_DATA0_IDX];
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/* Desc:allocate buffers on device
|
/* Desc:allocate buffers on device
|
||||||
* Pre: buffers must be reset
|
* Pre: buffers must be reset
|
||||||
* Post:All buffers and raw sram unallocated
|
* Post:All buffers and raw sram unallocated
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "pindef.h"
|
#include "pindef.h"
|
||||||
|
|
||||||
int reset_buffers( USBtransfer *transfer );
|
int reset_buffers( USBtransfer *transfer );
|
||||||
|
int get_cur_buff_status( USBtransfer *transfer, int *status );
|
||||||
int allocate_buffers( USBtransfer *transfer, int num_buffers, int buff_size );
|
int allocate_buffers( USBtransfer *transfer, int num_buffers, int buff_size );
|
||||||
int set_mem_n_part( USBtransfer *transfer, int buff_num, int mem_type, int part_num );
|
int set_mem_n_part( USBtransfer *transfer, int buff_num, int mem_type, int part_num );
|
||||||
int set_map_n_mapvar( USBtransfer *transfer, int buff_num, int mapper, int map_var );
|
int set_map_n_mapvar( USBtransfer *transfer, int buff_num, int mapper, int map_var );
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
|
||||||
int buff_size = 256;
|
int buff_size = 256;
|
||||||
int buff0 = 0;
|
int buff0 = 0;
|
||||||
int buff1 = 1;
|
int buff1 = 1;
|
||||||
|
int cur_buff_status = 0;
|
||||||
int i;
|
int i;
|
||||||
uint8_t data[buff_size];
|
uint8_t data[buff_size];
|
||||||
|
|
||||||
|
|
@ -128,15 +129,36 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
|
||||||
|
|
||||||
for( i=0; i<(32*KByte/buff_size); i++) {
|
for( i=0; i<(32*KByte/buff_size); i++) {
|
||||||
//for( i=0; i<8; i++) {
|
//for( i=0; i<8; i++) {
|
||||||
//debug("\n\npayload out #%d", i);
|
debug("\n\npayload out #%d", i);
|
||||||
//get_operation( transfer );
|
//get_operation( transfer );
|
||||||
get_buff_elements( transfer, buff0 );
|
//get_buff_elements( transfer, buff0 );
|
||||||
get_buff_elements( transfer, buff1 );
|
//get_buff_elements( transfer, buff1 );
|
||||||
|
//get_buff_elements( transfer, buff0 );
|
||||||
|
//get_buff_elements( transfer, buff1 );
|
||||||
|
|
||||||
|
//The device doesn't have a good way to respond if the last buffer is flashing
|
||||||
|
//and the current one is full. We can only send a payload if the current buffer
|
||||||
|
//is empty.
|
||||||
|
|
||||||
|
//Read next chunk from file
|
||||||
check(! read_from_file( rom, data, buff_size ), "Error with file read");
|
check(! read_from_file( rom, data, buff_size ), "Error with file read");
|
||||||
|
|
||||||
|
//ensure cur_buff is EMPTY prior to sending data
|
||||||
|
check(! get_cur_buff_status( transfer, &cur_buff_status ), "Error retrieving cur_buff->status");
|
||||||
|
while (cur_buff_status != EMPTY ) {
|
||||||
|
debug("cur_buff->status: %x ", cur_buff_status);
|
||||||
|
check(! get_cur_buff_status( transfer, &cur_buff_status ), "Error retrieving cur_buff->status");
|
||||||
|
}
|
||||||
|
debug("cur_buff->status: %x\n", cur_buff_status);
|
||||||
|
|
||||||
|
//send data
|
||||||
check(! payload_out( transfer, data, buff_size ), "Error with payload OUT");
|
check(! payload_out( transfer, data, buff_size ), "Error with payload OUT");
|
||||||
//if ( i % 256 == 0 ) debug("payload in #%d", i);
|
//if ( i % 256 == 0 ) debug("payload in #%d", i);
|
||||||
if ( i % 32 == 0 ) debug("payload out #%d", i);
|
if ( i % 32 == 0 ) debug("payload out #%d", i);
|
||||||
}
|
}
|
||||||
|
check(! get_cur_buff_status( transfer, &cur_buff_status ), "Error retrieving cur_buff->status");
|
||||||
|
debug("\n\n\ncur_buff->status: %x\n", cur_buff_status);
|
||||||
|
|
||||||
get_operation( transfer );
|
get_operation( transfer );
|
||||||
get_buff_elements( transfer, buff0 );
|
get_buff_elements( transfer, buff0 );
|
||||||
get_buff_elements( transfer, buff1 );
|
get_buff_elements( transfer, buff1 );
|
||||||
|
|
@ -144,10 +166,11 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart )
|
||||||
get_buff_elements( transfer, buff1 );
|
get_buff_elements( transfer, buff1 );
|
||||||
get_buff_elements( transfer, buff0 );
|
get_buff_elements( transfer, buff0 );
|
||||||
get_buff_elements( transfer, buff1 );
|
get_buff_elements( transfer, buff1 );
|
||||||
|
get_operation( transfer );
|
||||||
debug("payload done");
|
debug("payload done");
|
||||||
|
|
||||||
//end operation at reset
|
//end operation at reset
|
||||||
check(! set_operation( transfer, RESET ), "Unable to set buffer operation");
|
//check(! set_operation( transfer, RESET ), "Unable to set buffer operation");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ int set_operation( USBtransfer *transfer, int operation )
|
||||||
int get_operation( USBtransfer *transfer )
|
int get_operation( USBtransfer *transfer )
|
||||||
{
|
{
|
||||||
printf("operation:");
|
printf("operation:");
|
||||||
dictionary_call( transfer, DICT_OPER, GET_OPERATION, NILL, NILL,
|
dictionary_call_debug( transfer, DICT_OPER, GET_OPERATION, NILL, NILL,
|
||||||
USB_IN, NULL, RV_DATA0_IDX+1);
|
USB_IN, NULL, RV_DATA0_IDX+1);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,9 +192,8 @@
|
||||||
//return value status of that raw bank (set to bank id if allocated)
|
//return value status of that raw bank (set to bank id if allocated)
|
||||||
#define RAW_BANK_STATUS 0x60
|
#define RAW_BANK_STATUS 0x60
|
||||||
|
|
||||||
//retrieve buffer manager current operation variable
|
//retrieve cur_buff status
|
||||||
//#define GET_BUFF_OPERATION 0x61
|
#define GET_CUR_BUFF_STATUS 0x61
|
||||||
//moved to shared_dict_operation.h
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue