usbFunctionWrite support loading incoming write/OUT data to buffer objects.

Still untested, need to write some host code to test things out.
This commit is contained in:
paul eeepc 2016-11-29 15:27:31 -06:00
parent fe1b0e0ba5
commit cb0941e86c
6 changed files with 145 additions and 22 deletions

View File

@ -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 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 uint8_t *rptr = rv; //used for return pointer set to small rv buffer by default
switch (spacket->opcode) { switch (spacket->opcode) {
//opcodes which don't address a specific buffer object //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 ); //spacket->operandMSB, spacket->operandLSB, spacket->miscdata );
//return pointer to buffer's data //return pointer to buffer's data
rptr = called_buff->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;
} }
break; break;
@ -237,6 +259,7 @@ void raw_buffer_reset( )
* status of raw buffer updated to prevent future collisions * status of raw buffer updated to prevent future collisions
* bank status byte contains buffer's id * bank status byte contains buffer's id
* buffer status updated from UNALLOC to EMPTY * buffer status updated from UNALLOC to EMPTY
* buffer size set according to allocation
* all other buffer values cleared to zero * all other buffer values cleared to zero
* Rtn: SUCCESS or ERROR code if unable to allocate * 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 //seems that buffer and raw are free allocate them as requested
buff->id = new_id; buff->id = new_id;
buff->status = EMPTY; 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 //set buffer data pointer to base ram address
buff->data = &raw_buffer[base_bank*RAW_BANK_SIZE]; buff->data = &raw_buffer[base_bank*RAW_BANK_SIZE];

View File

@ -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 ); 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 #endif

View File

@ -179,6 +179,8 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
//will detect when return length differs from requested //will detect when return length differs from requested
return rlen; 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 //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 //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 //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().. * to 1 in usbconfig.h and return 0xff in usbFunctionSetup()..
*/ */
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) { 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;
}
} }

View File

@ -25,4 +25,5 @@
#define RV_DATA0_IDX RV_ERR_IDX + 1 //first index of return data #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 #define RV_DATA_MAX_IDX RETURN_BUFF_SIZE - 1 //last index available for return data
#endif #endif

View File

@ -4,7 +4,6 @@ int erase_nes( USBtransfer *transfer )
{ {
debug("erasing"); debug("erasing");
//dict opcode addr data //dict opcode addr data
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); 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, 1, 0);
@ -13,16 +12,16 @@ int erase_nes( USBtransfer *transfer )
debug("read status"); debug("read status");
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); 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, 1, 0);
debug("allocate 0"); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 4, 0);
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER0, 0x1A00, 1); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0);
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2A01, 1); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 8, 0);
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER2, 0x3A02, 1); dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 14, 0);
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER3, 0x4A03, 1);
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER4, 0x5A04, 1); debug("allocate");
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER5, 0x6A05, 1); dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER0, 0x1000, 4);
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER6, 0x7A06, 1); dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2104, 4);
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x8A07, 1); dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER2, 0x3508, 4);
debug("read status"); dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER3, 0x4A0C, 4);
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0); 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, 1, 0);
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 2, 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, 5, 0);
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 6, 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, 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); //dict opcode addr data
debug("reset"); //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0);
dictionary_call( transfer, BUFFER, RAW_BUFFER_RESET, 0, 0); //dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 1, 0);
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); //debug("reset");
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x8A07, 1); //dictionary_call( transfer, BUFFER, RAW_BUFFER_RESET, 0, 0);
dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 7, 0); //debug("read status");
dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x5A05, 1); //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); //dictionary_call( transfer, IO, IO_RESET, 0, 0);

View File

@ -26,8 +26,9 @@
//which limits to 256 bytes per buffer currently //which limits to 256 bytes per buffer currently
//having 16bit value support would expand this, or somehow shifting current byte //having 16bit value support would expand this, or somehow shifting current byte
//to account for multiple bytes could expand further //to account for multiple bytes could expand further
#define NUM_RAW_BANKS 8 // 8*32 = 256 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 NUM_RAW_BANKS 16 //16*32 = 512 bytes of buffer
#define RAW_BANK_SIZE 32 //bank size in bytes #define RAW_BANK_SIZE 32 //bank size in bytes
//number of buffer objects //number of buffer objects
@ -48,8 +49,10 @@
#define PROBLEM 0x10 #define PROBLEM 0x10
#define USB_UNLOADING 0x80 #define USB_UNLOADING 0x80
#define USB_LOADING 0x90 #define USB_LOADING 0x90
#define USB_FULL 0x98
#define CHECKING 0xC0 #define CHECKING 0xC0
#define DUMPING 0xD0 #define DUMPING 0xD0
#define DUMP_FULL 0xD8
#define ERASING 0xE0 #define ERASING 0xE0
#define FLASHING 0xF0 #define FLASHING 0xF0
#define FLASH_WAIT 0xF8 #define FLASH_WAIT 0xF8
@ -92,7 +95,10 @@
#define BUFF_OPCODE_BUFN_NRV_MAX 0xBF #define BUFF_OPCODE_BUFN_NRV_MAX 0xBF
// //
#define BUFF_OPCODE_BUFN_RV_MIN 0xC0 #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 //allocate firmware sram to a buffer
@ -111,6 +117,18 @@
#define ALLOCATE_BUFFER7 0x87 #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... //~16 bytes per buffer...
//as initially defined in firmware //as initially defined in firmware