From 52a1b306c979b88ea6b21104e3d0f10c555bd26e Mon Sep 17 00:00:00 2001 From: Paul Molloy pinkASUS Date: Mon, 13 Feb 2017 23:51:51 -0600 Subject: [PATCH] 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. --- firmware/source/buffer.c | 20 +++++++++++++------- firmware/source/usb.c | 15 ++++++++------- host/source/buffer.c | 20 ++++++++++++++++++++ host/source/buffer.h | 1 + host/source/flash.c | 31 +++++++++++++++++++++++++++---- host/source/operation.c | 2 +- shared/shared_dict_buffer.h | 5 ++--- 7 files changed, 72 insertions(+), 22 deletions(-) diff --git a/firmware/source/buffer.c b/firmware/source/buffer.c index e353d63..c12e5fe 100644 --- a/firmware/source/buffer.c +++ b/firmware/source/buffer.c @@ -229,10 +229,10 @@ uint8_t buffer_opcode_return( uint8_t opcode, buffer *buff, *rvalue = raw_bank_status[operLSB]; *rlength += 1; break; - //case GET_BUFF_OPERATION: - // *rvalue = operation; - // *rlength += 1; - // break; + case GET_CUR_BUFF_STATUS: + *rvalue = cur_buff->status; + *rlength += 1; + break; case GET_PRI_ELEMENTS: rvalue[0] = buff->last_idx; 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_buff->status = USB_LOADING; } else { + //both buffers are in use + //last buffer is flashing, and cur is full, need to wait on last to finish set_operation( PROBLEM ); } } @@ -710,15 +712,19 @@ void update_buffers() //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 //which gets set to 254 on wr transfers once gets to zero buffer is filled - if ( (incoming_bytes_remain == 0) && (cur_buff->status != EMPTY) ) { - incoming_bytes_remain--; //don't want to re-enter - //if ( cur_buff->status == USB_FULL) { + //if ( (incoming_bytes_remain == 0) && (cur_buff->status != EMPTY) ) { + // incoming_bytes_remain--; //don't want to re-enter + if ( cur_buff->status == USB_FULL) { //buffer full, send to flash routine last_buff = cur_buff; //but first want to update cur_buff to next buffer so it can //start loading on next OUT transfer 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; last_buff->status = FLASHING; diff --git a/firmware/source/usb.c b/firmware/source/usb.c index e6b74dd..512cc91 100644 --- a/firmware/source/usb.c +++ b/firmware/source/usb.c @@ -303,6 +303,13 @@ USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) { 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 cur_usb_load_buff->cur_byte += 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 //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 - cur_usb_load_buff->status = USB_FULL; + // cur_usb_load_buff->status = USB_FULL; return PAYLD_DONE; } else { //more data packets remain to complete OUT transfer return NOT_DONE; diff --git a/host/source/buffer.c b/host/source/buffer.c index f1a9a60..849c98a 100644 --- a/host/source/buffer.c +++ b/host/source/buffer.c @@ -11,6 +11,26 @@ int reset_buffers( USBtransfer *transfer ) 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 * Pre: buffers must be reset * Post:All buffers and raw sram unallocated diff --git a/host/source/buffer.h b/host/source/buffer.h index c58b5bc..ed4272e 100644 --- a/host/source/buffer.h +++ b/host/source/buffer.h @@ -22,6 +22,7 @@ #include "pindef.h" 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 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 ); diff --git a/host/source/flash.c b/host/source/flash.c index fd434e8..8a99efd 100644 --- a/host/source/flash.c +++ b/host/source/flash.c @@ -29,6 +29,7 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart ) int buff_size = 256; int buff0 = 0; int buff1 = 1; + int cur_buff_status = 0; int i; 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<8; i++) { - //debug("\n\npayload out #%d", i); + debug("\n\npayload out #%d", i); //get_operation( transfer ); - get_buff_elements( transfer, buff0 ); - get_buff_elements( transfer, buff1 ); + //get_buff_elements( transfer, buff0 ); + //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"); + + //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"); //if ( i % 256 == 0 ) debug("payload in #%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_buff_elements( transfer, buff0 ); 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, buff0 ); get_buff_elements( transfer, buff1 ); + get_operation( transfer ); debug("payload done"); //end operation at reset - check(! set_operation( transfer, RESET ), "Unable to set buffer operation"); + //check(! set_operation( transfer, RESET ), "Unable to set buffer operation"); /* diff --git a/host/source/operation.c b/host/source/operation.c index 5aeb4b9..d9317bc 100644 --- a/host/source/operation.c +++ b/host/source/operation.c @@ -123,7 +123,7 @@ int set_operation( USBtransfer *transfer, int operation ) int get_operation( USBtransfer *transfer ) { 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); return SUCCESS; } diff --git a/shared/shared_dict_buffer.h b/shared/shared_dict_buffer.h index c025a7e..1d912a9 100644 --- a/shared/shared_dict_buffer.h +++ b/shared/shared_dict_buffer.h @@ -192,9 +192,8 @@ //return value status of that raw bank (set to bank id if allocated) #define RAW_BANK_STATUS 0x60 -//retrieve buffer manager current operation variable -//#define GET_BUFF_OPERATION 0x61 -//moved to shared_dict_operation.h +//retrieve cur_buff status +#define GET_CUR_BUFF_STATUS 0x61