From a8124e8983ab4bfe652076809828485472fcf6de Mon Sep 17 00:00:00 2001 From: Paul Molloy Date: Sun, 4 Jun 2017 20:13:58 -0500 Subject: [PATCH] Resolved issue where final buffer wasn't getting fully flashed. Added check to ensure buff1 is done before quitting and resetting buffers. Currently have a hacked load_oper_info_elements_chr function to test CHR-ROM flashing. NROM PRG & CHR flashing and dumping tested and working on black ASUS win10 machine. Firmware still doesn't implement previously added feature for oper_info rd/wr_func pointer. flash/dump.c simply overrides by providing the function pointer based on memory type. A bit frustrated with how complicated everything is currently... Feel like there's a lack of standard for function definition and calls. Would like majority of host program flow to be determined solely by script calls. Firmware is getting more generic and versatile at the cost of being SLOW!!! Perhaps that's okay though as it's not terribly slow in comparision to comparable AVR kazzo firmware builds. And with current target to migrate to STM32 device this generic setup is much cleaner and easier to work with. However complexity was added to the firmware code in order to help make it faster. Not sure the goal of faster should take priority over speed. Obsessing over speed will cause issues with race conditions, and complicate code to the point where I won't reach my goal. With the long break since I've been working on this project it's making me more willing to scrap some previous work for a cleaner solution more aligned with my end goal. I had to write some of this code to get a better idea of my what my end goal will look like anyway. Going to make a couple builds for UIROM, and action53 as they're urgently needed. But beyond that I need to start working on script features, and STM32 support! --- firmware/Makefile | 4 +- host/inlretro_commited.exe | Bin 112931 -> 117060 bytes host/source/buffer.c | 18 +++++++++ host/source/buffer.h | 1 + host/source/flash.c | 80 ++++++++++++++++++++----------------- host/source/operation.c | 75 ++++++++++++++++++++++++++++++++++ host/source/operation.h | 1 + 7 files changed, 140 insertions(+), 39 deletions(-) diff --git a/firmware/Makefile b/firmware/Makefile index 20e7acc..c61aa50 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -61,8 +61,8 @@ main.elf: shared $(OBJECTS) main.hex: main.elf rm -f main.hex main.eep.hex avr-objcopy -j .text -j .data -O ihex main.elf main.hex - avr-size -C --mcu=${DEVICE} main.elf -# avr-size main.hex +# avr-size -C --mcu=${DEVICE} main.elf + avr-size main.elf # debugging targets: diff --git a/host/inlretro_commited.exe b/host/inlretro_commited.exe index cddc5cd35c65c48902bb7e4b6ed3a6013d9ebce2..979b8f8c440534c2c8ebcf31fd588d1fd9827cf3 100644 GIT binary patch delta 40541 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 M;`sBsgKYBu0}A<6QUCw| delta 36510 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"); - debug("\n\n\ncur_buff->status: %x\n", cur_buff_status); - //TODO add check to ensure both buffers are done and operation is okay - //currently just make a few extra get elements calls to waste time + //debug("\n\n\ncur_buff->status: %x\n", cur_buff_status); + + //add check to ensure both buffers are done and operation is okay + //need to get status of buff1 and make sure it's flashed + while (cur_buff_status != FLASHED ) { + check(! get_buff_element_value( transfer, buff1, GET_PRI_ELEMENTS, BUFF_STATUS, &cur_buff_status ), + "Error retrieving buffer status post flashing"); + // debug("\n\n\ncur_buff->status: %x\n", cur_buff_status); + } - get_operation( transfer ); - get_buff_elements( transfer, buff0 ); - get_buff_elements( transfer, buff1 ); - get_operation( transfer ); debug("payload done"); //end operation at reset @@ -178,8 +153,11 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart ) //tell buffer manager when to stop // or not..? just reset buffers and start next memory or quit //reset buffers and setup to dump CHR-ROM + + //load operation elements into buff0 and then copy buff0 to oper_info + load_oper_info_elements_chr( transfer, cart ); + get_oper_info_elements( transfer ); -/* check(! reset_buffers( transfer ), "Unable to reset device buffers"); check(! allocate_buffers( transfer, num_buffers, buff_size ), "Unable to allocate buffers"); check(! set_mem_n_part( transfer, buff0, CHRROM, SST_MANF_ID ), "Unable to set mem_type and part"); @@ -191,16 +169,44 @@ int flash_cart( USBtransfer* transfer, rom_image *rom, cartridge *cart ) //inform buffer manager to start dumping operation now that buffers are initialized check(! set_operation( transfer, STARTFLASH ), "Unable to set buffer operation"); + + tstart = clock(); + + //now just need to call series of payload IN transfers to retrieve data + for( i=0; i<(8*KByte/buff_size); i++) { + + //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"); + } + + //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); } - debug("payload done"); -*/ + 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); + + //check to ensure both buffers are done and operation is okay before resetting + //need to get status of buff1 and make sure it's flashed + while (cur_buff_status != FLASHED ) { + check(! get_buff_element_value( transfer, buff1, GET_PRI_ELEMENTS, BUFF_STATUS, &cur_buff_status ), + "Error retrieving buffer status post flashing"); + // debug("\n\n\ncur_buff->status: %x\n", cur_buff_status); + } + debug("payload done"); //close file in main + + //end operation at reset + check(! set_operation( transfer, RESET ), "Unable to set buffer operation"); //reset io at end io_reset( transfer ); diff --git a/host/source/operation.c b/host/source/operation.c index d9317bc..97fd143 100644 --- a/host/source/operation.c +++ b/host/source/operation.c @@ -75,6 +75,81 @@ error: return ~SUCCESS; } +/* Desc:Set all oper_info elements based on cartridge + * Pre: buff0 must be initialized + * Post:oper_info elements loaded + * Rtn: SUCCESS if no errors + */ +int load_oper_info_elements_chr( USBtransfer *transfer, cartridge *cart ) +{ + uint8_t rv[RETURN_BUFF_SIZE]; + uint8_t buff_num = 0; //buffer used to load elements according to shared_dict_operation.h + uint8_t oper_info[OPER_DATA_NUM_BYTE_ELEMENTS]; +// int i; + + //first make sure buff0 is big enough + dictionary_call_debug( transfer, DICT_BUFFER, GET_PRI_ELEMENTS, NILL, buff_num, + USB_IN, rv, RETURN_BUFF_SIZE); + check( rv[BUFF_LASTIDX] >= OPER_DATA_NUM_BYTE_ELEMENTS, + "buff0 not large enough to load oper_info. Only %d available, need %d", + rv[BUFF_LASTIDX], OPER_DATA_NUM_BYTE_ELEMENTS ); + + //fill array with oper_info elements then payload to buff0 + //overall type of operation being performed + oper_info[OPERATION] = PREPARING, + //mask page_num lower byte to get directly addressable A15:A8 bits + oper_info[ADDRH_DMASK] = MSK_8KB, + //shift page_num to right this many bits to get cur bank value + oper_info[PG2BANK_SHRIGHT] = PG2B_8KB, + //most significant bit that must be valid for operation (ie A14 SST) + oper_info[VALID_ADDR_MSB] = 12, + //unlock sequence SST $5555 0xAA + //unlock sequence #1 bank number for mapper reg + oper_info[UNLOCK1_BANK] = 0, + //unlock sequence #1 A15:A8 + oper_info[UNLOCK1_AH] = 0x15, + //unlock sequence #1 A7:A0 + oper_info[UNLOCK1_AL] = 0x55, + //unlock sequence #1 D7:D0 + oper_info[UNLOCK1_DATA] = 0xAA, + ////unlock sequence SST $2AAA 0x55 + //unlock sequence #1 bank number for mapper reg + oper_info[UNLOCK2_BANK] = 0, + //unlock sequence #2 A15:A8 + oper_info[UNLOCK2_AH] = 0x0A, + //unlock sequence #2 A7:A0 + oper_info[UNLOCK2_AL] = 0xAA, + //unlock sequence #2 D7:D0 + oper_info[UNLOCK2_DATA] = 0x55, + //command SST byte write $5555 0xA0, SST sector/chip erase $5555 0x80 + //flash command bank (ie bank to write byte write, sector erase cmd) + oper_info[COMMAND_BANK] = 0, + //flash command A15:A8 + oper_info[COMMAND_AH] = 0x15, + //flash command A7:A0 + oper_info[COMMAND_AL] = 0x55, + ///flash command D7:D0 command 1 data (ie SST sect erase 0x80) + oper_info[COMMAND1_DATA]= 0xA0, + //flash command D7:D0 command 2 data (ie SST sect erase 0x30) + oper_info[COMMAND2_DATA]= 0, + //actual byte operation (ie Byte address bank and addr) + //current bank value for actual operation to be done (ie write byte) + oper_info[OPER_BANK] = 0, + //operation A15:A8 (ie actual byte write address) + oper_info[OPER_AH] = 0, + + //load byte element data into buff0 + dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOADN, + NILL, buff_num, USB_OUT, + oper_info, OPER_DATA_NUM_BYTE_ELEMENTS); + //now that elements are in buff0 instruct them to be copied over + dictionary_call_debug( transfer, DICT_OPER, COPY_BUFF0_TO_ELEMENTS, + NILL, NILL, USB_IN, NULL, RV_ERR_IDX+1); + +error: + return ~SUCCESS; +} + /* Desc:Get all oper_info elements * Pre: buff0 must be initialized * Post: diff --git a/host/source/operation.h b/host/source/operation.h index 635cbfd..75ce9c8 100644 --- a/host/source/operation.h +++ b/host/source/operation.h @@ -22,6 +22,7 @@ #include "pindef.h" int load_oper_info_elements( USBtransfer *transfer, cartridge *cart ); +int load_oper_info_elements_chr( USBtransfer *transfer, cartridge *cart ); int get_oper_info_elements( USBtransfer *transfer ); int set_operation( USBtransfer *transfer, int operation ); int get_operation( USBtransfer *transfer );