Wait to recive data on LUFA

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

First of all congrats for your awesome forum and support. I'm a newbie and most of my questions are already reported so most of the times i don't even need to ask for a solution, just needed to search a little bit.

So for all the community that have been helping me indirectly, my sincere thank you.

But this time i don't find the solution to my problem. I feel like it's a very primitive question but i can't figure out (shame on me!).

 

I doing a USB-HDI project and i studied the USB specifications until i found the LUFA project and man... that saved my ass!

The LUFA project saved me a lot of time implementing the boring USB work on device side, specially because i'm not a master of programming. 

 

I adopted the "CLASS_GENERIC_HID" demo to my project and now i can send and receive data packets.

The problem is that when i send a data packet from the device (ATMEGA16U2) i can't block the program flow until the response data from the host (PC) is received.

I want to do this only in one part of my work (in one function) and not in the entire solution.

 

I Tried to do something like this:

On "CALLBACK_HID_Device_ProcessHIDReport" function i put a global variable "flag_data_recived" that change it's state to 1 every time that this function is processed.

On my function that i want to wait for data from the host i block the program flow using a while condition associated with the global variable that i created previously.

Something like that:

 

my_function()   

{

      flag_data_recived=1;

      Send_Data_To_Host();

      

     while(flag_data_recived==0)

     {

      }

 

     // continue data flow

 

}

 

The problem is, with that the program never process the "CALLBACK_HID_Device_ProcessHIDReport" and obviously never jump the while condition. Which is very strange to me because the "CALLBACK_HID_Device_ProcessHIDReport" function is activated by interrupts.

 

Can you give a simple explanation for what are happening there? There is a better solution to this?

 

Thanks in advance!
Cheers ;)

 

 

 

This topic has a solution.

Last Edited: Thu. Jul 23, 2015 - 07:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Come on, anyone?

 

Any help will be appreciated!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've read that LUFA doesn't work right for Xmega. 

 

I don't know LUFA nor HID so that exhausts my knowledge of the subject.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm pretty sure that is not the problem since an Atmega16u2 is part of AVRmega family and not Xmega family.

 

Since i can't overcome this and i don't get any help to solve it, i'm considering to change the project conditions and block the program flow until receive new data on the device every time that sends data over usb.

But, how can i do that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I haven't worked with the HID class, but I have used LUFA for the CDC class Virtual Serial Port demo.

That provides the function

CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface)

 

Does HID provide something similar?

If so, then you could loop waiting for bytes received to be greater than zero.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck99, you gave me an idea but unfortunately it seems doesn't work :/

The HID class provides this function:

 

void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
                                          const uint8_t ReportID,
                                          const uint8_t ReportType,
                                          const void* ReportData,
                                          const uint16_t ReportSize)

 

Which process HID reports from the host. I tried to call this function on my function that i desire to wait until the data is received. On "CALLBACK_HID_Device_ProcessHIDReport" function i inserted a while loop to only leave this function when the last to bytes transmitted are equal to 0xFF (255), and store the data received on a "DATA_FROM_HOST" table (which is global and initialized to zeros).

For example:

 

my_function()   

{

        uint16_t ReportSize = USB_ControlRequest.wLength;

    uint8_t  ReportID   = (USB_ControlRequest.wValue & 0xFF);
    uint8_t  ReportType = (USB_ControlRequest.wValue >> 8) - 1;
    uint8_t  ReportData[ReportSize];

    CALLBACK_HID_Device_ProcessHIDReport(&Generic_HID_Interface, ReportID, ReportType,
        &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0));

 

     // continue data flow

 

}

 

 

void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
                                          const uint8_t ReportID,
                                          const uint8_t ReportType,
                                          const void* ReportData,
                                          const uint16_t ReportSize)
{
    

    int i;

      while ((DATA_FROM_HOST[6]!=0xFF) && (DATA_FROM_HOST[7]!=0xFF))
      {
         uint8_t* Data       = (uint8_t*)ReportData;
        for (i=0;i<8;i++)
        {
            DATA_FROM_HOST[i]=Data[i];
        }
    }    
}

 

But it seems that i never receive the data that i want to transmit and i can never get away from the while loop. So i tried a new way....

I put the while loop on my_function that calls the "CALLBACK_HID_Device_ProcessHIDReport" at all times that the last to bytes received are different to 0xFF (255) and the "CALLBACK_HID_Device_ProcessHIDReport" function is only responsible for receiving data.

For example:

 

my_function()   

{

   

     while ((DATA_FROM_HOST[6]!=0xFF) && (DATA_FROM_HOST[7]!=0xFF))

    {

         uint16_t ReportSize = USB_ControlRequest.wLength;

         uint8_t  ReportID   = (USB_ControlRequest.wValue & 0xFF);
         uint8_t  ReportType = (USB_ControlRequest.wValue >> 8) - 1;
         uint8_t  ReportData[ReportSize];

         CALLBACK_HID_Device_ProcessHIDReport(&Generic_HID_Interface, ReportID, ReportType,
                                              &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0));

     }

     // continue data flow

 

}

 

 

void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
                                          const uint8_t ReportID,
                                          const uint8_t ReportType,
                                          const void* ReportData,
                                          const uint16_t ReportSize)
{
    

        int i;

        uint8_t* Data       = (uint8_t*)ReportData;
        for (i=0;i<8;i++)
        {
            DATA_FROM_HOST[i]=Data[i];
        } 
}

 

Once again, my code never leaves the while loop. It seems whether i insert a while loop to my code to wait to receive the data that i want, i stop receiving new data from the host.

I start to go crazy with this!

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

As mentioned in my previous post, I haven't worked with the HID class, but I took a look at it and think I see the problem.

 

In the file GenericHID.c

int main(void)
{
    SetupHardware();

    LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
    GlobalInterruptEnable();

    for (;;)
    {
        HID_Device_USBTask(&Generic_HID_Interface);
        USB_USBTask();
    }
}

Note the for(;;) loop. This runs continuously and should not be blocked or it will break your USB connection.

Add your functions to the end of this for loop.

 

 

When the Host sends data to your device, the following function is called:

/** HID class driver callback function for the processing of HID reports from the host.
 *
 *  \param[in] HIDInterfaceInfo  Pointer to the HID class interface configuration structure being referenced
 *  \param[in] ReportID    Report ID of the received report from the host
 *  \param[in] ReportType  The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature
 *  \param[in] ReportData  Pointer to a buffer where the received report has been stored
 *  \param[in] ReportSize  Size in bytes of the received HID report
 */
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
                                          const uint8_t ReportID,
                                          const uint8_t ReportType,
                                          const void* ReportData,
                                          const uint16_t ReportSize)
{

uint8_t*    Data = (uint8_t*)ReportData;

uint16_t    Size =  ReportSize;

 

/* Add your code here to process the data that the Host sent */

 

}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"The customer is always right"... in this case the code is always right!

 

Actually my functions are called at the end of the for loop, but what happens is that i only receive new data when i process this for loop again and introducing while loops in my functions to wait to recieve data actually blocks the next interaction of this for loop so i never receive the new data.
How could i miss that?! Thanks for your response Chuck99.

 

Now its time to re-think all code again. ;)