This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

USB bulk example modification to get a different number of characters



Hello every one, 

I have made some modifications to the Bulk example code from Tiva_Ware, i want to send a simple word : "odiame", and I want to get from the TM4C a complete sentence "por piedad yo te lo pido, odiame sin medida, ni clemencia!!!!!!".

The problem is that when I send the word "odiame" who has 6 characters, I only get from the MCU the first six characters "por pi", not the complete sentence. and If you can se in the figure the sentece is complete in "g_pui8USBTxBuffer".

I dont understand why I only can receive the same number of character that I send. Obviously it was the first intention of the USB BULK example, but I have made some modifications:

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "usblib/usblib.h"
#include "usblib/usb-ids.h"
#include "usblib/device/usbdevice.h"
#include "usblib/device/usbdbulk.h"
#include "utils/uartstdio.h"
#include "utils/ustdlib.h"
#include "drivers/pinout.h"
#include "usb_bulk_structs.h"

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

#define SYSTICKS_PER_SECOND 100											// The system tick rate expressed both as
#define SYSTICK_PERIOD_MS   (1000 / SYSTICKS_PER_SECOND)				// ticks per second and a millisecond period.
volatile uint32_t g_ui32SysTickCount = 0;								// The global system tick counter.

volatile uint32_t g_ui32TxCount = 0;									// Variables tracking transmit and receive counts.
volatile uint32_t g_ui32RxCount = 0;
uint_fast32_t ui32WriteIndex;
uint_fast32_t ui32ReadIndex;

tUSBRingBufObject sTxRing;
uint_fast32_t ui32Loopr, ui32Loops, ui32Space, ui32Count;

//*****************************************************************************
char val_2;
int aaa = 0;
int pos;
int ulLength;
char a_enviar[];
char prueba [100];
char cmp[BULK_BUFFER_SIZE];
//int ulLength = strlen(prueba);

char receptor[BULK_BUFFER_SIZE];
char cmp222 [BULK_BUFFER_SIZE];
//*****************************************************************************

#define COMMAND_PACKET_RECEIVED 0x00000001								// Flags used to pass commands from
#define COMMAND_STATUS_UPDATE   0x00000002								// interrupt context to the main loop.
volatile uint32_t g_ui32Flags = 0;
static volatile bool g_bUSBConfigured = false;							// Global flag indicating that a USB configuration has been set.
#ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line)		// The error routine that is called if the driver library encounters an error.
{}
#endif
void SysTickIntHandler(void) 											// Interrupt handler for the system tick counter.
{
    g_ui32SysTickCount++;												// Update our system tick counter.
}
//*****************************************************************************
//
// Receive new data and echo it back to the host.
//
// \param psDevice points to the instance data for the device whose data is to be processed.
// \param pi8Data points to the newly received data in the USB receive buffer.
// \param ui32NumBytes is the number of bytes of data available to be processed.
//
// This function is called whenever we receive a notification that data is
// available from the host. We read the data, byte-by-byte and swap the case
// of any alphabetical characters found then write it back out to be
// transmitted back to the host.
//
// \return Returns the number of bytes of data processed.
//
//*****************************************************************************
static uint32_t EchoNewDataToHost(tUSBDBulkDevice *psDevice, uint8_t *pi8Data, uint_fast32_t ui32NumBytes)
{
	int index = 0;
	volatile char val = 0x01;
    USBBufferInfoGet(&g_sTxBuffer, &sTxRing);								// Get the current buffer information to allow us to write directly to the transmit buffer
    ui32Space = USBBufferSpaceAvailable(&g_sTxBuffer); 						// How much space is there in the transmit buffer?
    ui32Loopr = (ui32Space < ui32NumBytes) ? ui32Space : ui32NumBytes;		// How many characters can we process this time round?
    ui32Loops = (ui32Space < ui32NumBytes) ? ui32Space : ui32NumBytes;		// How many characters can we process this time round?
    aaa = ui32NumBytes;
    ui32Count = ui32Loops;
    val_2 = ui32Count;
    g_ui32RxCount += ui32NumBytes;											// Update our receive counter.
    ui32ReadIndex = (uint32_t)(pi8Data - g_pui8USBRxBuffer);				// Set up to process the characters by directly accessing the USB buffers.
    ui32WriteIndex = sTxRing.ui32WriteIndex;
//    strcpy(prueba,"equi ku");
//    ulLength = strlen(prueba);

    while(ui32Loopr)
    {
        receptor[index] = g_pui8USBRxBuffer[ui32ReadIndex];
        ui32ReadIndex++;
        ui32ReadIndex = (ui32ReadIndex == BULK_BUFFER_SIZE) ? 0 : ui32ReadIndex;
        ui32Loopr--;
        index++;
    }

    index = 0;

    strcpy(cmp,"odiame");
    if (strcmp(receptor,cmp) == 0)
    {
    	strcpy(prueba,"por piedad yo te lo pido, odiame sin medida, ni clemencia!!!!!!");
    	ulLength = strlen(prueba);
    }
    else
    {
    	strcpy(prueba,"nada");
    	ulLength = strlen(prueba);
    }

	while(ulLength)
	{
		g_pui8USBTxBuffer[ui32WriteIndex] = prueba [index];
		ui32WriteIndex++;														// Move to the next character taking care to adjust the pointer for the buffer wrap if necessary.
		ui32WriteIndex = (ui32WriteIndex == BULK_BUFFER_SIZE) ? 0 : ui32WriteIndex;
		ulLength--;
		index++;
	}

    USBBufferDataWritten(&g_sTxBuffer, ui32Count);
	ulLength = strlen(prueba);
    memset(prueba,0,ulLength);
    return(ui32Count);
}

//*****************************************************************************
//
// Handles bulk driver notifications related to the transmit channel (data to
// the USB host).
//
// \param pvCBData is the client-supplied callback pointer for this channel.
// \param ulEvent identifies the event we are being notified about.
// \param ulMsgValue is an event-specific value.
// \param pvMsgData is an event-specific pointer.
//
// This function is called by the bulk driver to notify us of any events
// related to operation of the transmit data channel (the IN channel carrying
// data to the USB host).
//
// \return The return value is event-specific.
//
//*****************************************************************************
uint32_t TxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData)
{
    //
    // We are not required to do anything in response to any transmit event
    // in this example. All we do is update our transmit counter.
    //
    if(ui32Event == USB_EVENT_TX_COMPLETE)
    {
        g_ui32TxCount += ui32MsgValue;
    }
    return(0);
}

//*****************************************************************************
//
// Handles bulk driver notifications related to the receive channel (data from
// the USB host).
//
// \param pvCBData is the client-supplied callback pointer for this channel.
// \param ui32Event identifies the event we are being notified about.
// \param ui32MsgValue is an event-specific value.
// \param pvMsgData is an event-specific pointer.
//
// This function is called by the bulk driver to notify us of any events
// related to operation of the receive data channel (the OUT channel carrying
// data from the USB host).
//
// \return The return value is event-specific.
//
//*****************************************************************************
uint32_t RxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData)
{
    switch(ui32Event)															// Which event are we being sent?
    {
        case USB_EVENT_CONNECTED:												// We are connected to a host and communication is now possible
        {
            g_bUSBConfigured = true;
            g_ui32Flags |= COMMAND_STATUS_UPDATE;

            USBBufferFlush(&g_sTxBuffer); 										// Flush our buffers
            USBBufferFlush(&g_sRxBuffer);

            break;
        }

        case USB_EVENT_DISCONNECTED:											// The host has disconnected.
        {
            g_bUSBConfigured = false;
            g_ui32Flags |= COMMAND_STATUS_UPDATE;
            break;
        }

        case USB_EVENT_RX_AVAILABLE: 											// A new packet has been received.
        {
            tUSBDBulkDevice *psDevice;
            psDevice = (tUSBDBulkDevice *)pvCBData;								// Get a pointer to our instance data from the callback data parameter.
            return(EchoNewDataToHost(psDevice, pvMsgData, ui32MsgValue));		// Read the new packet and echo it back to the host.
        }

        case USB_EVENT_SUSPEND:													// Ignore SUSPEND and RESUME for now.
        case USB_EVENT_RESUME:
            break;
        default:																// Ignore all other events and return 0.
            break;
    }
    return(0);
}

int main(void)
{
    uint_fast32_t ui32TxCount;
    uint_fast32_t ui32RxCount;
    uint32_t ui32SysClock;

    ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |					 // Run from the PLL at 120 MHz.
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_PLL |
                                           SYSCTL_CFG_VCO_480), 120000000);
    PinoutSet(false, true);														 // Configure the device pins.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);							 // Enable UART0
    UARTStdioConfig(0, 115200, ui32SysClock);									 // Initialize the UART for console I/O.
    g_bUSBConfigured = false;													 // Not configured initially.

    ROM_SysTickPeriodSet(ui32SysClock / SYSTICKS_PER_SECOND);					 // Enable the system tick.
    ROM_SysTickIntEnable();
    ROM_SysTickEnable();

    UARTprintf("\033[2J\nTiva C Series USB bulk device example\n");					// Show the application name on the display and UART output.
    UARTprintf("---------------------------------\n\n");

    UARTprintf("Configuring USB... \n");											// Tell the user what we are up to.

    USBBufferInit(&g_sTxBuffer);													// Initialize the transmit and receive buffers.
    USBBufferInit(&g_sRxBuffer);
    USBStackModeSet(0, eUSBModeDevice, 0);											// Initialize the USB stack for device mode.
    USBDBulkInit(0, &g_sBulkDevice);												// Pass our device information to the USB
    																				// library and place the device on the bus.

    UARTprintf("Waiting for host...\r");											// Wait for initial configuration to complete.

    ui32RxCount = 0;																// Clear our local byte counters.
    ui32TxCount = 0;

    while(1)																		// Main application loop.
    {
        if(g_ui32Flags & COMMAND_STATUS_UPDATE)										// Have we been asked to update the status display?
        {
            g_ui32Flags &= ~COMMAND_STATUS_UPDATE;

            if(g_bUSBConfigured)
            {
                UARTprintf("Host Connected.            \n\n");
                UARTprintf("Data transferred:\n");
                UARTprintf("TX: %d  RX: %d                    \r",
                           g_ui32TxCount,
                           g_ui32RxCount);
            }
            else
            {
                UARTprintf("\n\nHost Disconnected.\n\n");
            }
        }

        if(ui32TxCount != g_ui32TxCount)											// Has there been any transmit traffic since we last checked?
        {
            ui32TxCount = g_ui32TxCount;											// Take a snapshot of the latest transmit count.
            UARTprintf("TX: %d  RX: %d                    \r",						// Update the displayed buffer count information.
                       g_ui32TxCount,
                       g_ui32RxCount);
        }

        if(ui32RxCount != g_ui32RxCount)											// Has there been any receive traffic since we last checked?
        {
            ui32RxCount = g_ui32RxCount;											// Take a snapshot of the latest receive count.
            UARTprintf("TX: %d  RX: %d                    \r",						// Update the displayed buffer count information.
                       g_ui32TxCount,
                       g_ui32RxCount);
        }
    }
}

Thanks in advance