V USB HID data logger

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
sriharir_91
Posts: 2
Joined: Mon Jun 27, 2016 5:31 pm

V USB HID data logger

Post by sriharir_91 » Mon Jun 27, 2016 5:36 pm

Hi, I have been trying to build a HID keyboard device that types out sensor values. But before that I wanted my device to type out random values onto a notepad. I used to Easylogger code as reference to construct my device descriptor (After a lot of trials I got the following descriptor to work) but it doesnt print out anything on the notepad. Despite a lot of googling, I haven't been able to understand fully what the usbfunctionsetup() does exactly (I checked the usbconfig.h, Maybe I am not experienced in embedded systems yet to understand it). Kindly help. the code is below:

Code: Select all

PROGMEM const char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = 
{
    0x05, 0x01,                    //    USAGE_PAGE (Generic Desktop)
    0x09, 0x06,                    //   USAGE (Keyboard)
    0xa1, 0x01,                    //   COLLECTION (Application)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x01,                    //   REPORT_COUNT (1)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
    0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
    0xc0                           //    END_COLLECTION
};
//Buffer for logs
struct LOG_ENTRY
{
    unsigned char hour;
    unsigned char minute;
    unsigned char second;
    unsigned char day;
    unsigned char month;
    unsigned char year;
    unsigned char percentage;
}logs[50];
 
void buff_log()
{
            int j;
            for(j=0;j<50;j++)
            {
                logs[j].hour=0xff;
                logs[j].minute=0xff;
                logs[j].second=0xff;
                logs[j].day=0xff;
                logs[j].month=0xff;
                logs[j].year=0xff;
                logs[j].percentage=0xff;
        }
        /*   
        }//End of if() block
    }//end of while() polling loop
    */
}//End of buff_log()
 
static void buildReport(int i, int j)
{   
    memset(reportBuffer,'\0',sizeof(reportBuffer));
    if(j==0) {reportBuffer[0]=logs[i].hour;}            else if(j==1) { reportBuffer[1]=logs[i].minute; }
    else if(j==2) { reportBuffer[1]=logs[i].second; }    else if(j==3) { reportBuffer[1]=logs[i].day; }
    else if(j==4) { reportBuffer[1]=logs[i].month; }    else if(j==5) { reportBuffer[1]=logs[i].year; }
    else if(j==6) { reportBuffer[1]=logs[i].percentage; }        else if(j==7) { reportBuffer[1]=0; }
}
 
USB_PUBLIC uchar usbFunctionSetup(uchar data[8])
{
    usbRequest_t *rq = (void *)data;                    //Casting the data to correct type
       
        usbMsgPtr =  reportBuffer;
       
        if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS)
        {                                                // class request type
            if(rq->bRequest == USBRQ_HID_GET_REPORT)    // wValue: ReportType (highbyte), ReportID (lowbyte)
            { 
                buildReport(0,0);                            // we only have one report type, so don't look at wValue
                return sizeof(reportBuffer);            // The entire buffer has to be sent at one shot.
            }
               
            else if(rq->bRequest == USBRQ_HID_GET_IDLE)
            {
                usbMsgPtr = &idleRate;
                return 1;
            }
           
            else if(rq->bRequest == USBRQ_HID_SET_IDLE)
            {
                idleRate = rq->wValue.bytes[1];
            }
        }
       
        else
        {
            /* no vendor specific requests implemented */
        }
       
    return 0;                                            //Since data is in static RAM, we don't need usbFunctionWrite()
}
 
int main(void)
{
    int j=0;
/******************************************* Initialization***************************************/   
    io_init();
    buff_log();                //To retrieve logs from the main controller unit
    odDebugInit();
   
    usbDeviceDisconnect();    //Enforce enumeration by disconnecting and connecting for the first time
   
    for(j=0;j<20;j++)        // 300 ms disconnect - Comment during simulation
    {   
        _delay_ms(15);
    }
   
    usbDeviceConnect();
    wdt_enable(WDTO_1S);    //Enable the watchdog timer
    usbInit();
    sei();
/*******************************************Loop forever*******************************************/   
   
    while(1)
    {   
        wdt_reset();                    //Reset the watchdog timer
        usbPoll();
             
        if(usbInterruptIsReady()&&i<50)        // we can send another data
        {
               
            for(j=0;j<8;j++)   
            {
                buildReport(i,j);
                usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
            }
            i++;               
        }
       
    }//End of while(1) Infinite loop
/*************************************************************************************************/   
return 0;
}//End of main()

Post Reply