Transfering more than 255 bytes.
Posted: Wed Jan 21, 2009 10:27 pm
Hi i need to transfer a big buffer from an ATmega32 to the computer.
For that i have redefined "bytesRemaining" variable from uchar to usbWord_t and made some simple changes to usbFunctionWrite and Read.
I test this writing 1800 bytes from the computer to the uC memory and reading it again.
The writing works perfectly because i turn on a led when the last value in the buffer is equal to what i send.
The reading doesnt work at more than 255 bytes.
When i try to transfer 1800 bytes (1800=0x708) it only transfers 8 bytes.
i think that it is being masked or stored in uchar somewhere in the driver, but the usbFunctionWrite is not.
Here is my code:
Is it possible for someone knowing better the driver to check wether only the usbFunctionRead() part is being masked?
Or i am missing something in my function?
For that i have redefined "bytesRemaining" variable from uchar to usbWord_t and made some simple changes to usbFunctionWrite and Read.
I test this writing 1800 bytes from the computer to the uC memory and reading it again.
The writing works perfectly because i turn on a led when the last value in the buffer is equal to what i send.
The reading doesnt work at more than 255 bytes.
When i try to transfer 1800 bytes (1800=0x708) it only transfers 8 bytes.
i think that it is being masked or stored in uchar somewhere in the driver, but the usbFunctionWrite is not.
Here is my code:
Code: Select all
uchar usbFunctionWrite(uchar *data, uchar len)
{
if(bytesRemaining.word == 0)
return 1;
if(len > bytesRemaining.word)
len = bytesRemaining.byte[0];
switch(transferType){
case USB_HID_CUSTOM_RQ_ADC_BUFFER:
memcpy(nextTransferByte, data, len);
nextTransferByte += len;
break;
case USB_HID_CUSTOM_RQ_EEPROM:
eeprom_write_block(data, (uchar *)0 + currentAddress, len);
currentAddress += len;
break;
}
bytesRemaining.word -= len;
return (bytesRemaining.word == 0); // return 1 if this was the last chunk
}
Code: Select all
uchar usbFunctionRead(uchar *data, uchar len)
{
//uchar i;
if(len > bytesRemaining.word)
len = bytesRemaining.byte[0];
switch(transferType){
case USB_HID_CUSTOM_RQ_ADC_BUFFER:
memcpy( data , nextTransferByte , len );
//for (i=0 ; i < len ; i++){
// data[i] = nextTransferByte[i];
//}
nextTransferByte += len;
break;
case USB_HID_CUSTOM_RQ_EEPROM:
eeprom_read_block(data, (uchar *)0 + currentAddress, len);
currentAddress += len;
break;
}
bytesRemaining.word -= len;
return len;
}
Code: Select all
typedef union word{
unsigned word;
uchar byte[2];
}word_t;
static word_t bytesRemaining;
static uchar transferType;
static uchar *nextTransferByte;
static uchar adcBuffer[ADC_BUFFER_SIZE];
Code: Select all
usbMsgLen_t usbFunctionSetup(uchar setupData[8])
{
usbRequest_t *rq = (void *)setupData;
switch(rq->bmRequestType & USBRQ_TYPE_MASK){
case USBRQ_TYPE_CLASS:
// "Class" specific requests
switch(rq->bRequest){
case USBRQ_HID_GET_REPORT:
// wValue: ReportType (highbyte), ReportID (lowbyte)
// we only have one report type, so don't look at wValue
switch(rq->wIndex.bytes[0]){
case USB_HID_CUSTOM_RQ_ADC_BUFFER:
transferType = USB_HID_CUSTOM_RQ_ADC_BUFFER;
nextTransferByte = adcBuffer;
bytesRemaining.word = rq->wLength.word;
return USB_NO_MSG; // use usbFunctionRead() to send data to the host
}
// fallback and use usbFunctionRead() to obtain data
case USBRQ_HID_SET_REPORT:
switch(rq->wIndex.bytes[0]){
case USB_HID_CUSTOM_RQ_ADC_BUFFER:
transferType = USB_HID_CUSTOM_RQ_ADC_BUFFER;
nextTransferByte = adcBuffer;
bytesRemaining.word = rq->wLength.word;
return USB_NO_MSG; // use usbFunctionWrite() to receive data from host
case USB_HID_CUSTOM_RQ_START_CONVERTION:
switch ( rq->wLength.bytes[0] )
{
case 0:
ADCSRA = ( ADCSRA_CONFIG | ADC_PRESCALER_0 );
break;
default:
case 1:
ADCSRA = ( ADCSRA_CONFIG | ADC_PRESCALER_1 );
break;
case 2:
ADCSRA = ( ADCSRA_CONFIG | ADC_PRESCALER_2 );
break;
}
ADMUX = ADMUX_CONFIG; // Reset ADMUX
SFIOR &= 0x1F;
adcBuffer_intr_pointer = adcBuffer;
adcBuffer_index = 0;
SBI( ADCSRA , ADEN );
SBI( LEDPORT , LED1 );
return 0;
case USB_HID_CUSTOM_RQ_EEPROM:
transferType = USB_HID_CUSTOM_RQ_EEPROM;
bytesRemaining.byte[0] = rq->wLength.bytes[0];
bytesRemaining.byte[1] = 0;
currentAddress = 0;
//currentAddress2 = 0;
return USB_NO_MSG; // use usbFunctionWrite() to receive data from host
case USB_HID_CUSTOM_RQ_LED:
LEDPORT = ((rq->wValue.bytes[0]<<2)& LEDMASK);
return 0;
}
}
break;
}
return 0; // default for not implemented requests: return no data back to host
}
Is it possible for someone knowing better the driver to check wether only the usbFunctionRead() part is being masked?
Or i am missing something in my function?