Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

lwIPDemo_Rowley_ARM7 - USB CDC send problem

Posted by *anonymous on January 9, 2011

Hello there,

I'm working on a project based on the lwIPDemo_Rowley_ARM7 project. I needed to implement a CDC device which receives commands via USB and sends responses corresponding to the received commands. The basic functionality of the usbCDCTask() is still the same as in the original demo and basically data transfer works.

But I noticed some strange behaviour recently: After a few  incoming requests (the EP1 FDR is read 30 times, most requests are somewhere between 64 and 128 bytes in length) and sending responses (the EP2 FDR is written 34 times), the next IN transfer does not take place. The 35th time the EP2 FDR is written and TXPTREADY is set, the data seems not to arrive at the host, although later the TXPKTREADY bit is cleared (which indicates, that the device received an IN token and all data was sent to the host). But in the usbSniff-Logs the package was nowhere to be found and the communication software on the host did not receive any response at all. Since the application on the microcontroller should only really send anything if a request was made, the communication between host and device hangs there.

After a bit of experimenting I found out, that if I set TXPKTREADY in every iteration of the task loop after it was reset, the data will be sent eventually, but this seems like an ugly hack. Does anyone have an idea what the problem could be? The relevant part of the code from the USB task is the following:

if (eDriverState == eREADY_TO_SEND && ucControlLineState && eApplicationMode != eEMAC) {
			// All EPs have been set up and the ControlLineState is active.
			if (!(AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] & AT91C_UDP_TXPKTRDY)) {
				if (xSendQueueData.ulByteCount || xQueuePeek(xParserSendQueue, &xSendQueueData, 0)) {
					/* There is no unsent buffered data & Got some bytes to transmit. */
					vUsartPrintf("(send %p) ==============>>\n", xSendQueueData.sBuffer);
					for (ulByte = 0; ulByte < usbDATA_ENDPOINT_SIZE && xSendQueueData.ulByteCount; ulByte++) {
						AT91C_BASE_UDP->UDP_FDR[usbEND_POINT_2] = *(xSendQueueData.sBuffer);
//						if (xSendQueueData.xAddress != eAddrBinary) {
//							vUsartPutChar(*(xSendQueueData.sBuffer));
//						}
						xSendQueueData.sBuffer++;
						xSendQueueData.ulByteCount--;
					}
//					vUsartPutChar('\n');
					if (!xSendQueueData.ulByteCount) {
						/* Packet completely transferred, remove item from queue and clear QueueData */
						vUsartPuts("Packet completely transferred\n");
						xQueueReceive(xParserSendQueue, &xSendQueueData, 0);
						xSendQueueData.sBuffer = 0;
						xSendQueueData.ulByteCount = 0;
					}
				}
				// For some reason the endpoint has to be marked ready anyway, if not a packet may not be transferred
				// at some point...
				AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] |= AT91C_UDP_TXPKTRDY;
			}

lwIPDemo_Rowley_ARM7 - USB CDC send problem

Posted by *anonymous on January 9, 2011

Sorry for the malformed code, here it is again, this time hopefully a bit more readable…

if (eDriverState == eREADY_TO_SEND && ucControlLineState && eApplicationMode != eEMAC) {
    // All EPs have been set up and the ControlLineState is active.
    if (!(AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] & AT91C_UDP_TXPKTRDY)) {
        if (xSendQueueData.ulByteCount || xQueuePeek(xParserSendQueue, &xSendQueueData, 0)) {
            /* There is no unsent buffered data & Got some bytes to transmit. */
            vUsartPrintf("(send %p) ==============>>\n", xSendQueueData.sBuffer);
            for (ulByte = 0; ulByte < usbDATA_ENDPOINT_SIZE && xSendQueueData.ulByteCount; ulByte++) {
                AT91C_BASE_UDP->UDP_FDR[usbEND_POINT_2] = *(xSendQueueData.sBuffer);
//				if (xSendQueueData.xAddress != eAddrBinary) {
//					vUsartPutChar(*(xSendQueueData.sBuffer));
//				}
                xSendQueueData.sBuffer++;
                xSendQueueData.ulByteCount--;
            }
//			vUsartPutChar('\n');
            if (!xSendQueueData.ulByteCount) {
                /* Packet completely transferred, remove item from queue and clear QueueData */
                vUsartPuts("Packet completely transferred\n");
                xQueueReceive(xParserSendQueue, &xSendQueueData, 0);
                xSendQueueData.sBuffer = 0;
                xSendQueueData.ulByteCount = 0;
            }
        }
        // For some reason the endpoint has to be marked ready anyway, if not a packet may not be transferred
        // at some point...
        AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] |= AT91C_UDP_TXPKTRDY;
    }
    ...
}

lwIPDemo_Rowley_ARM7 - USB CDC send problem

Posted by *anonymous on January 9, 2011

Just to clarify: the problem I described occurs when the last instruction

AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] |= AT91C_UDP_TXPKTRDY; 

is inside the if clause right before the last curly bracket. Like this:

                xSendQueueData.ulByteCount = 0;
            }
        AT91C_BASE_UDP->UDP_CSR[usbEND_POINT_2] |= AT91C_UDP_TXPKTRDY;
        }
    }
    ...
}

The snipped I posted first actually works, but indicates available data even if there actually should be no data available because it should already have been transferred to the host…


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS