adding some error checks to usbFunctionWrite.
Trying to prevent transfer from exceeding buffer size. Also verifying buffer's status is properly set to enforce upholding of the status. Giving usbFunctionWrite a means to communicate it's error/success back to host with USB 'dictionary'.
This commit is contained in:
parent
b6164aa3a6
commit
8cdeecdd77
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
|
//used to store success/error code of last transfer for debugging
|
||||||
|
static uint8_t usbWrite_status;
|
||||||
|
|
||||||
//USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]);
|
//USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]);
|
||||||
/* This function is called when the driver receives a SETUP transaction from
|
/* This function is called when the driver receives a SETUP transaction from
|
||||||
|
|
@ -168,6 +170,14 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||||
//just give buffer.c the setup packet and let it figure things out for itself
|
//just give buffer.c the setup packet and let it figure things out for itself
|
||||||
usbMsgPtr = (usbMsgPtr_t)buffer_usb_call( spacket, rv, &rlen );
|
usbMsgPtr = (usbMsgPtr_t)buffer_usb_call( spacket, rv, &rlen );
|
||||||
break; //end of BUFFER
|
break; //end of BUFFER
|
||||||
|
|
||||||
|
case USB:
|
||||||
|
//currently just a simple way to read back usbFunctionWrite status SUCCESS/ERROR
|
||||||
|
//if there are future status' to read back may have to create some functions
|
||||||
|
rv[RV_ERR_IDX] = SUCCESS;
|
||||||
|
rv[RV_DATA0_IDX] = usbWrite_status;
|
||||||
|
rlen = 2;
|
||||||
|
break; //end of USB
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//request (aka dictionary) is unknown
|
//request (aka dictionary) is unknown
|
||||||
|
|
@ -200,11 +210,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||||
*/
|
*/
|
||||||
//USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len) {
|
//USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len) {
|
||||||
// //this function should only get called if usbFunctionSetup returns USB_NO_MSG
|
// //this function should only get called if usbFunctionSetup returns USB_NO_MSG
|
||||||
//// data[0] = 0xAA;
|
|
||||||
// return len;
|
// return len;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
// V-USB description of this function:
|
||||||
//USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len);
|
//USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len);
|
||||||
/* This function is called by the driver to provide a control transfer's
|
/* This function is called by the driver to provide a control transfer's
|
||||||
* payload data (control-out). It is called in chunks of up to 8 bytes. The
|
* payload data (control-out). It is called in chunks of up to 8 bytes. The
|
||||||
|
|
@ -221,33 +231,71 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) {
|
||||||
* In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE
|
* In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE
|
||||||
* 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) {
|
|
||||||
//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
|
|
||||||
|
|
||||||
|
/* Desc:USB Write routine for OUT transfers
|
||||||
|
* the V-USB drivers call this function on OUT tokens
|
||||||
|
* and provide upto 8 byte data packet's payload
|
||||||
|
* for payloads longer than 8Bytes this gets called multiple times
|
||||||
|
* until all bytes have been transferred. Real thing to understand
|
||||||
|
* is that this function gets called once per data packet (max 8bytes)
|
||||||
|
* based on USB 1.1 low speed standard.
|
||||||
|
* buffer.c is the govnerning module for what buffer gets filled
|
||||||
|
* Pre: buffer.c must have set current usb loading buffer with global var
|
||||||
|
* the current buffer must have enough room for incoming data
|
||||||
|
* possible to use mutliple buffers for a single transfer, but
|
||||||
|
* buffer.c must orchestrate the swap to new buffer object.
|
||||||
|
* buffer.c sets global incoming bytes remain so it can keep
|
||||||
|
* track of this function's progress
|
||||||
|
* buffer object must be initialized, allocated, and status USB_LOADING
|
||||||
|
* Post:usbWrite_status updated with SUCCESS/ERROR number
|
||||||
|
* incoming data packet copied to cur_usb_load_buff
|
||||||
|
* global incoming_bytes_remain updated
|
||||||
|
* cur_usb_load_buff cur_byte updated based on data length
|
||||||
|
* cur_usb_load_buff status updated when it's full
|
||||||
|
* Rtn: message to V-USB driver so it can respond to host
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) {
|
||||||
|
|
||||||
uint8_t data_cur = 0; //current incoming byte to copy
|
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_cur = cur_usb_load_buff->cur_byte; //current buffer byte
|
||||||
uint8_t *buf_data = cur_usb_load_buff->data; //current buffer data array
|
uint8_t *buf_data = cur_usb_load_buff->data; //current buffer data array
|
||||||
|
|
||||||
|
//check that current buffer's status is USB_LOADING
|
||||||
|
if (cur_usb_load_buff->status != USB_LOADING) {
|
||||||
|
usbWrite_status = ERR_OUT_CURLDBUF_STATUS;
|
||||||
|
return STALL;
|
||||||
|
}
|
||||||
|
//check that current buffer's has enough room
|
||||||
|
if ( ((cur_usb_load_buff->size) - buf_cur) < len ) {
|
||||||
|
usbWrite_status = ERR_OUT_CURLDBUF_TO_SMALL;
|
||||||
|
return STALL;
|
||||||
|
}
|
||||||
|
|
||||||
//copy 1-8bytes of payload into buffer
|
//copy 1-8bytes of payload into buffer
|
||||||
while ( data_cur < len ) {
|
while ( data_cur < len ) {
|
||||||
buf_data[ buf_cur ] = data[data_cur];
|
buf_data[buf_cur] = data[data_cur];
|
||||||
buf_cur++;
|
buf_cur++;
|
||||||
data_cur++;
|
data_cur++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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;
|
||||||
|
usbWrite_status = SUCCESS;
|
||||||
|
|
||||||
//return 0xFF (-1) "STALL" if error
|
//check if buffer is full and update status accordingly
|
||||||
//return 1 if entire payload received successfully
|
if ( (cur_usb_load_buff->size) == buf_cur) {
|
||||||
//return 0 if more data expected to complete transfer
|
//this signals to buffer.c so it can update cur_usb_load_buf
|
||||||
if ( incoming_bytes_remain == 0 ) { //done with OUT transfer
|
//and start tasking this buffer to programming
|
||||||
return 1;
|
|
||||||
cur_usb_load_buff->status = USB_FULL;
|
cur_usb_load_buff->status = USB_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( incoming_bytes_remain == 0 ) { //done with OUT transfer
|
||||||
|
return PAYLD_DONE;
|
||||||
} else { //more data packets remain to complete OUT transfer
|
} else { //more data packets remain to complete OUT transfer
|
||||||
return 0;
|
return NOT_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@
|
||||||
#define ENDPOINT_IN 0x80 //In: device-to-host.
|
#define ENDPOINT_IN 0x80 //In: device-to-host.
|
||||||
#define ENDPOINT_OUT 0x00 //Out: host-to-device.
|
#define ENDPOINT_OUT 0x00 //Out: host-to-device.
|
||||||
|
|
||||||
|
//usbFunctionWrite return values
|
||||||
|
//return 0xFF (-1) "STALL" if error
|
||||||
|
//return 1 if entire payload received successfully
|
||||||
|
//return 0 if more data expected to complete transfer
|
||||||
|
#define STALL 0xFF
|
||||||
|
#define PAYLD_DONE 1
|
||||||
|
#define NOT_DONE 0
|
||||||
|
|
||||||
//TODO these should probably be in shared so host code and utilize them on the other side
|
//TODO these should probably be in shared so host code and utilize them on the other side
|
||||||
#define RETURN_BUFF_SIZE 8 //number of bytes in generic return buffer
|
#define RETURN_BUFF_SIZE 8 //number of bytes in generic return buffer
|
||||||
|
|
|
||||||
|
|
@ -119,4 +119,12 @@
|
||||||
//=============================================================================================
|
//=============================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================================
|
||||||
|
//=============================================================================================
|
||||||
|
#define USB 6
|
||||||
|
//currently no actual dictionary as there are no opcodes.
|
||||||
|
//just used to return status of usbfunctions in event of a transfer error.
|
||||||
|
//=============================================================================================
|
||||||
|
//=============================================================================================
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,9 @@
|
||||||
#define ERR_BUFF_RAW_ALREADY_ALLOC 193
|
#define ERR_BUFF_RAW_ALREADY_ALLOC 193
|
||||||
#define ERR_BUFF_ALLOC_SIZE_ZERO 194
|
#define ERR_BUFF_ALLOC_SIZE_ZERO 194
|
||||||
|
|
||||||
|
#define ERR_OUT_CURLDBUF_STATUS 200
|
||||||
|
#define ERR_OUT_CURLDBUF_TO_SMALL 201
|
||||||
|
|
||||||
//max error number 255
|
//max error number 255
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue