cancel
Showing results for 
Search instead for 
Did you mean: 

USB Bulk IN pipe data errors?

robin23
Associate
Posted on January 14, 2009 at 08:07

USB Bulk IN pipe data errors?

2 REPLIES 2
robin23
Associate
Posted on May 17, 2011 at 12:57

As part of our design we are trying to implement a double buffered IN endpoint. All of the examples found for the STM32 are for OUT endpoints. We seem to have achieved double buffering as we are filling 16 out of the 19 available slots per frame. Occasionally the first few bytes of the block (64) sent from the endpoint ISR is corrupted but not every time. The suspicion is that we are testing the wrong flags in the ISR and may be modifying the data as it is sent? Below is the USB code snippets

The endpoint is setup in the usb_prop file in the standard device reset routine:

Code:

void Device_Reset()

{

// Set device as not configured state

pInformation->Current_Configuration = 0;

// Current Feature initialization

pInformation->Current_Feature = Device_ConfigDescriptor[7];

SetBTABLE(BTABLE_ADDRESS);

// Initialize Endpoint 0

SetEPType(ENDP0, EP_CONTROL);

SetEPTxStatus(ENDP0, EP_TX_NAK);

SetEPRxAddr(ENDP0, ENDP0_RXADDR);

SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);

SetEPTxAddr(ENDP0, ENDP0_TXADDR);

Clear_Status_Out(ENDP0);

SetEPRxValid(ENDP0);

// Initialize Endpoint 1

SetEPType(ENDP1, EP_BULK);

SetEP_KIND(ENDP1);

SetEPDblBuffAddr(ENDP1, ENDP1_BUF0Addr, ENDP1_BUF1Addr);

SetEPDblBuffCount(ENDP1, EP_DBUF_IN, 0x40);

ClearDTOG_RX(ENDP1);

ClearDTOG_TX(ENDP1);

SetEPRxStatus(ENDP1, EP_RX_DIS);

SetEPTxStatus(ENDP1, EP_TX_NAK); // we'll NAK until frame data available

SetEPRxValid(ENDP0);

// Set this device to response on default address

SetDeviceAddress(0);

bDeviceState = ATTACHED;

}

When we want to commence the transfer we fill the buffers with data then signal the data available. Once the first buffer is emptied the EP1 in callback fires to fill the emptied buffer with the next 64 bytes of data?

Code:

void BeginUpload()

{

u8 i;

u8 blockBuffer[64]; // block buffer size

uploadAddress = EXT_SRAM_START; // reset USB read upload address

frameMode = FRAME_MODE_UPLOAD_PENDING; // start upload

// add an additional 2 blocks to the data size as padding (this may be removed later)

for (i = 0; i < 128; i++)

*((u8 *)(dmaAddress++)) = 0x5A;

// fill the info frame with, image size, frame id and ''out of image'' marker (0xFFFF)

*((u32 *)&blockBuffer[56]) = dmaAddress & (EXT_SRAM_SIZE-1); // size of image (4 bytes, LSB first)

*((u16 *)&blockBuffer[60]) = frameId.w; // frame count (2 bytes, LSB first)

blockBuffer[62] = 0xFF; // illegal within JPEG image ...

blockBuffer[63] = 0xFF; // ... therefore must be out of frame

for (i = 0; i < 56/*sizeof(blockBuffer)*/; i++)

blockBuffer[i] = 0x0A; // first block to send test

UserToPMABufferCopy(blockBuffer, ENDP1_BUF0Addr, sizeof(blockBuffer));

for (i = 0; i < 56/*sizeof(blockBuffer)*/; i++)

blockBuffer[i] = 0x0B; // first block to send test

UserToPMABufferCopy(blockBuffer, ENDP1_BUF1Addr, sizeof(blockBuffer));

ClearDTOG_RX(ENDP1);

ClearDTOG_TX(ENDP1);

ToggleDTOG_RX(ENDP1);

ToggleDTOG_RX(ENDP1); // added now both A and B are sent

SetEPTxStatus(ENDP1, EP_TX_VALID); // now we have data to send

}

In the interrupt routine 64 byte chunks are copied from the buffer until it is exhasted. On the last interrupt the alternate buffer still has 64 bytes to send from the previous ISR so the flag is just toggled. After that the end point reverts to NAKing the host until the routine is initiated again from the routine above.

Code:

/*******************************************************************************

* Function Name : EP1_IN_Callback

* Description : Endpoint 1 in callback routine.

* Input : None.

* Output : None.

* Return : None.

*******************************************************************************/

void EP1_IN_Callback(void)

{

if ((uploadAddress >= EXT_SRAM_START) & (uploadAddress < EXT_SRAM_LIMIT))

{

// in upload mode

if (uploadAddress < dmaAddress)

{

_ToggleDTOG_RX(ENDP1); //signal to the USB engine that there is data to transmit

// refill the buffer that has just been emptied

// determine which buffer to copy into

if ((GetENDPOINT(ENDP1) & EP_DTOG_RX))

{

Debug1On();

// write to ENDP1_BUF0Addr buffer

UserToPMABufferCopy((u8 *)uploadAddress, ENDP1_BUF0Addr, EP1_BUFFER_SIZE);

Debug1Off();

}

else

{

Debug2On();

// write to ENDP1_BUF1Addr buffer

UserToPMABufferCopy((u8 *)uploadAddress, ENDP1_BUF1Addr, EP1_BUFFER_SIZE);

Debug2Off();

}

uploadAddress += EP1_BUFFER_SIZE;

}

else if (uploadAddress > 0)

{

// should be one more block to transmit

_ToggleDTOG_RX(ENDP1); //signal to the USB engine that there is data to transmit

// finished uploading

// reset upload address to signal upload complete

uploadAddress = 0;

}

}

}

eng22
Associate II
Posted on May 17, 2011 at 12:57

Hey robin.stone, could you figure out what was happening?

Kind of having similar doubts here. Exact the same trouble with the lack of examples.

Thanks.