LUFA GenericHID callbacks question

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

The device is an atemga16u2, which is ram limited at 512 bytes. I keep my report size at 32 bytes. In my avr application, there is a 200 byte lookup table stored in eeprom. I need to read that LUT and sometimes overwrite LUT with new values. So, I break the data into chunks, and perform several reads/writes. For example, in the CALLBACK_HID_Device_ProcessHIDReport when I get an request to read a chunk of the LUT, I set a global flag indicating a LUT read request, and copy the chunk size & start location to globals. Then in the CALLBACK_HID_Device_CreateHIDReport I see the read LUT flag, and fill requested data and return true to force the send. On the host side, he is waiting for the requested data until he asks for the next chunk. This works occassionaly, but often the host side hangs and the device disconnects. I use the same LUT data for consistancy when testing. On the device side, am I using the LUFA callbacks appropriatly? I'm going to post some code below and hopefully keep it short, but demonstrate how I am using the callbacks....

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* hidReceiveBuffer       = (uint8_t*)ReportData;

	if((hidReceiveBuffer[0]==0xAB) &&(hidReceiveBuffer[1]==0xCD))
	{
		// Process GenericHID command packet
		switch(hidReceiveBuffer[2])	
		{

			case 0x8B:	// Command 0x8B - Send MAP to HOST
				request_num = 0x8B;
				seq_num = hidReceiveBuffer[3];
			break;
}
}
}


bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
                                         uint8_t* const ReportID,
                                         const uint8_t ReportType,
                                         void* ReportData,
                                         uint16_t* const ReportSize)
{
	uint8_t* hidSendBuffer = (uint8_t*)ReportData;

	switch(request_num)
	{

		case 0x8B:	//MAP being requested by host
			hidSendBuffer[0]  = 0xAB;	// Header
			hidSendBuffer[1]  = 0xCD;
			hidSendBuffer[2]  = 0x8B;
			hidSendBuffer[3]  = (seq_num | 0x80);	// Echo back as an ACK
			
			if(seq_num)
			{
				BUFFERindex = 4;
				MAPindex_start = (uint8_t)((seq_num-1)*10);
				MAPindex_end = MAPindex_start + 10;
				// put data into MSG from EEPROM
				if(MAPindex_end<101)	// Generic bounds checking, should add error code in msg
				{
				
				
					for(MAPindex = MAPindex_start; MAPindex> 8; // MSB
						++BUFFERindex;
						hidSendBuffer[BUFFERindex] = (tempMAP & 0x00FF);		// LSB
						++BUFFERindex;
					}
				}
			}
			request_num = 0x00;
			seq_num = 0x00;
			*ReportSize = GENERIC_REPORT_SIZE;	
			return true;
		break;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm still troubleshooting this problem.

Normal operation is the HID device stuffs volatile sensor data into the send packet and waits to get polled. Thats works fine. Then from the host side I send a request to read the lookup table. The lookup table size exceeds my report size, so I do it in multiple transfers, with eachone initated by the host, the device responds with an ack and the requested data. I can do this once, i.e. request and recieve the entire LUT, through 10 requests. If I try a second time, no dice. One thing I've noticed, on the host side, after I send the first LUT request report, I still get several dozen of the "normal operation" data reports before they get shut down my my flag system in the above switch statment. Is there some buffer on the host side I need to flush? Or is this normal on the device side? Cant be, the device is very limited in buffering. I'm very confused on thsis one.

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

My problems went away when I made all endpoints and report sizes equal. I dont think thats a requirment, but on the host app side, the 'segmented' reports was causing problems. I dont know, not a real fix, maybe I just bandaided it.