From cb0941e86c19e59b2c48b62951d5b4a6d9d43513 Mon Sep 17 00:00:00 2001 From: paul eeepc Date: Tue, 29 Nov 2016 15:27:31 -0600 Subject: [PATCH] usbFunctionWrite support loading incoming write/OUT data to buffer objects. Still untested, need to write some host code to test things out. --- firmware/source/buffer.c | 35 +++++++++++++++++++ firmware/source/buffer.h | 6 ++++ firmware/source/usb.c | 31 +++++++++++++++- firmware/source/usb.h | 1 + host/source/erase.c | 70 +++++++++++++++++++++++++++---------- shared/shared_dict_buffer.h | 24 +++++++++++-- 6 files changed, 145 insertions(+), 22 deletions(-) diff --git a/firmware/source/buffer.c b/firmware/source/buffer.c index b4e7da1..d1eb5d2 100644 --- a/firmware/source/buffer.c +++ b/firmware/source/buffer.c @@ -41,6 +41,7 @@ uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint16_t *rlen) buffer *called_buff = &buff0; //used to point to buffer that was called based on opcode uint8_t *rptr = rv; //used for return pointer set to small rv buffer by default + switch (spacket->opcode) { //opcodes which don't address a specific buffer object @@ -89,6 +90,27 @@ uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint16_t *rlen) //spacket->operandMSB, spacket->operandLSB, spacket->miscdata ); //return pointer to buffer's data rptr = called_buff->data; + *rlen = (spacket->wLength); + break; + case BUFF_PAYLOAD0 ... BUFF_PAYLOAD7: + //for now just read write from designated buffer + //TODO make some checks that buffer is allocated/not busy etc + //determine endpoint IN/OUT + if ((spacket->bmRequestType & ENDPOINT_BIT) & ENDPOINT_IN) { + //read/dump from device to host + rptr = called_buff->data; + *rlen = (spacket->wLength); + called_buff->cur_byte = 0; + called_buff->status = USB_UNLOADING; + } else { //write to device from host + cur_usb_load_buff = called_buff; + incoming_bytes_remain = (spacket->wLength); + called_buff->cur_byte = 0; + called_buff->status = USB_LOADING; + //return USB_NO_MSG to get usbFunctionWrite + //called on incoming packets + *rlen = USB_NO_MSG; + } break; } break; @@ -237,6 +259,7 @@ void raw_buffer_reset( ) * status of raw buffer updated to prevent future collisions * bank status byte contains buffer's id * buffer status updated from UNALLOC to EMPTY + * buffer size set according to allocation * all other buffer values cleared to zero * Rtn: SUCCESS or ERROR code if unable to allocate */ @@ -272,6 +295,18 @@ uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_ //seems that buffer and raw are free allocate them as requested buff->id = new_id; buff->status = EMPTY; + buff->size = num_banks * RAW_BANK_SIZE; + + //zero out other elements + buff->cur_byte = 0; + buff->reload = 0; + buff->page_num = 0; + buff->mem_type = 0; + buff->part_num = 0; + buff->multiple = 0; + buff->add_mult = 0; + buff->mapper = 0; + buff->function = 0; //set buffer data pointer to base ram address buff->data = &raw_buffer[base_bank*RAW_BANK_SIZE]; diff --git a/firmware/source/buffer.h b/firmware/source/buffer.h index d23a90e..430fd88 100644 --- a/firmware/source/buffer.h +++ b/firmware/source/buffer.h @@ -17,5 +17,11 @@ void raw_buffer_reset( ); uint8_t allocate_buffer( buffer *buff, uint8_t new_id, uint8_t base_bank, uint8_t num_banks ); +//used to communicate to usbFunctionWrite which buffer object +//it should be filling +static buffer *cur_usb_load_buff; +//used to determine number of bytes left to finish current +//OUT transfer utilized by usbFunctionWrite +static uint16_t incoming_bytes_remain; #endif diff --git a/firmware/source/usb.c b/firmware/source/usb.c index f466d5e..7a8405a 100644 --- a/firmware/source/usb.c +++ b/firmware/source/usb.c @@ -179,6 +179,8 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { //will detect when return length differs from requested return rlen; + //need to return USB_NO_MSG for OUT transfers to make usbFunctionWrite called + //return USB_NO_MSG; //if want usbFunctionRead called during IN token data packets //Don't have a use for usbFunctionRead yet.. Not expecting to anytime soon //probably easier and perhaps faster to send cart dump commands and store rom image @@ -220,6 +222,33 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { * to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. */ USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) { - return 1; //"don't know how much data coming + //extern *buffer cur_usb_load_buff; + //buffer.c controls what buffer gets filled with extern ptr cur_usb_load_buf + //buffer.c also sets incoming_bytes_remain during setup packet + + uint8_t data_cur = 0; //current incoming byte to copy + uint8_t buf_cur = cur_usb_load_buff->cur_byte; //current buffer byte + uint8_t *buf_data = cur_usb_load_buff->data; //current buffer data array + + //copy 1-8bytes of payload into buffer + while ( data_cur < len ) { + buf_data[ buf_cur ] = data[data_cur]; + buf_cur++; + data_cur++; + } + + cur_usb_load_buff->cur_byte += len; + incoming_bytes_remain -= len; + + //return 0xFF (-1) "STALL" if error + //return 1 if entire payload received successfully + //return 0 if more data expected to complete transfer + if ( incoming_bytes_remain == 0 ) { //done with OUT transfer + return 1; + cur_usb_load_buff->status = USB_FULL; + } else { //more data packets remain to complete OUT transfer + return 0; + } + } diff --git a/firmware/source/usb.h b/firmware/source/usb.h index b8fa0b1..da0716b 100644 --- a/firmware/source/usb.h +++ b/firmware/source/usb.h @@ -25,4 +25,5 @@ #define RV_DATA0_IDX RV_ERR_IDX + 1 //first index of return data #define RV_DATA_MAX_IDX RETURN_BUFF_SIZE - 1 //last index available for return data + #endif diff --git a/host/source/erase.c b/host/source/erase.c index 395a174..43d48b8 100644 --- a/host/source/erase.c +++ b/host/source/erase.c @@ -4,7 +4,6 @@ int erase_nes( USBtransfer *transfer ) { debug("erasing"); - //dict opcode addr data dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 1, 0); @@ -13,16 +12,16 @@ int erase_nes( USBtransfer *transfer ) debug("read status"); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 1, 0); - debug("allocate 0"); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER0, 0x1A00, 1); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2A01, 1); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER2, 0x3A02, 1); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER3, 0x4A03, 1); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER4, 0x5A04, 1); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER5, 0x6A05, 1); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER6, 0x7A06, 1); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x8A07, 1); - debug("read status"); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 4, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 8, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 14, 0); + + debug("allocate"); + dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER0, 0x1000, 4); + dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2104, 4); + dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER2, 0x3508, 4); + dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER3, 0x4A0C, 4); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 1, 0); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 2, 0); @@ -31,14 +30,49 @@ int erase_nes( USBtransfer *transfer ) dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 5, 0); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 6, 0); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 8, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 9, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 10, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 11, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 12, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 13, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 14, 0); + dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 15, 0); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x8A07, 1); - debug("reset"); - dictionary_call( transfer, BUFFER, RAW_BUFFER_RESET, 0, 0); - dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x8A07, 1); - dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x5A05, 1); + //dict opcode addr data + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 1, 0); + //debug("reset"); + //dictionary_call( transfer, BUFFER, RAW_BUFFER_RESET, 0, 0); + //debug("read status"); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 1, 0); + //debug("allocate 0"); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER0, 0x1A00, 1); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2A01, 1); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER2, 0x3A02, 1); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER3, 0x4A03, 1); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER4, 0x5A04, 1); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER5, 0x6A05, 1); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER6, 0x7A06, 1); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x8A07, 1); + //debug("read status"); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 1, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 2, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 3, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 4, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 5, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 6, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); + + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x8A07, 1); + //debug("reset"); + //dictionary_call( transfer, BUFFER, RAW_BUFFER_RESET, 0, 0); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x8A07, 1); + //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); + //dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x5A05, 1); //dictionary_call( transfer, IO, IO_RESET, 0, 0); diff --git a/shared/shared_dict_buffer.h b/shared/shared_dict_buffer.h index b9b19d1..e8de5b4 100644 --- a/shared/shared_dict_buffer.h +++ b/shared/shared_dict_buffer.h @@ -26,8 +26,9 @@ //which limits to 256 bytes per buffer currently //having 16bit value support would expand this, or somehow shifting current byte //to account for multiple bytes could expand further -#define NUM_RAW_BANKS 8 // 8*32 = 256 bytes of buffer -//#define NUM_RAW_BANKS 16 //16*32 = 512 bytes of buffer +//#define NUM_RAW_BANKS 8 // 8*32 = 256 bytes of buffer +#define NUM_RAW_BANKS 16 //16*32 = 512 bytes of buffer + #define RAW_BANK_SIZE 32 //bank size in bytes //number of buffer objects @@ -48,8 +49,10 @@ #define PROBLEM 0x10 #define USB_UNLOADING 0x80 #define USB_LOADING 0x90 +#define USB_FULL 0x98 #define CHECKING 0xC0 #define DUMPING 0xD0 +#define DUMP_FULL 0xD8 #define ERASING 0xE0 #define FLASHING 0xF0 #define FLASH_WAIT 0xF8 @@ -92,7 +95,10 @@ #define BUFF_OPCODE_BUFN_NRV_MAX 0xBF // #define BUFF_OPCODE_BUFN_RV_MIN 0xC0 -#define BUFF_OPCODE_BUFN_RV_MAX 0xFF +#define BUFF_OPCODE_BUFN_RV_MAX 0xEF +// +#define BUFF_OPCODE_PAYLOAD_MIN 0xF0 +#define BUFF_OPCODE_PAYLOAD_MAX 0xFF //============================================================================================= //============================================================================================= //allocate firmware sram to a buffer @@ -111,6 +117,18 @@ #define ALLOCATE_BUFFER7 0x87 +//designate what buffer to fill with opcode +//endpoint direction determines if read/write +#define BUFF_PAYLOAD0 0xF0 +#define BUFF_PAYLOAD1 0xF1 +#define BUFF_PAYLOAD2 0xF2 +#define BUFF_PAYLOAD3 0xF3 +#define BUFF_PAYLOAD4 0xF4 +#define BUFF_PAYLOAD5 0xF5 +#define BUFF_PAYLOAD6 0xF6 +#define BUFF_PAYLOAD7 0xF7 + + //~16 bytes per buffer... //as initially defined in firmware