CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

USB HID set feature report [RESOLVED]

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
acs4design



Joined: 26 May 2016
Posts: 4

View user's profile Send private message

USB HID set feature report [RESOLVED]
PostPosted: Tue Nov 01, 2016 2:34 pm     Reply with quote

Has anyone had any luck filling in the code for the USB_HID_REQUEST_SET_REPORT? I'm writing code for an HID temperature sensor and windows is trying to set the state of the sensor through the SET FEATURE REPORT request. I can't however seem to figure out how to get the feature report that it is trying to send to me.

Any Thoughts?

Code:


void usb_isr_tkn_setup_ClassInterface(void)
{
   switch(usb_ep0_rx_buffer[1])
   {
   
    //JSG
        case USB_HID_REQUEST_GET_REPORT: //01
            debug_usb_token(debug_putc,"GR");
            switch(usb_ep0_rx_buffer[3])
            {
                case 0x01: //Input Report
                    usb_getInput_len = usb_ep0_rx_buffer[7];
                    usb_getInput_len <<= 8;
                    usb_getInput_len |= usb_ep0_rx_buffer[6];
                   
                    //JSG // may need to parse a byte to figure out which interface this is for
                    usb_getInput_intf = usb_ep0_rx_buffer[4];
                    usb_getInput_repid = usb_ep0_rx_buffer[2];
                    //usb_getfeature_ptr = //USB_HID_FEATURE_REPORTS_INDEXES[usb_getfeature_intf][usb_getfeature_repid];
                    usb_getInput_ptr = USB_HID_INPUT_REPORTS_INDEXES[usb_getInput_intf][usb_getInput_repid];

                    fprintf(PIC16, "GIR - PTR 0x%04.4lX", usb_getInput_ptr);
                    fprintf(PIC16, " REPID %ld, INTF %ld, LEN %ld\r\n", usb_getInput_repid, usb_getInput_intf, usb_getInput_len); 
                    if(usb_getfeature_ptr != 0xFFFFL)
                    {
                        USB_stack_status.dev_req=GET_INPUT_REPORT;
                        usb_copy_input_report_to_ep();
                    }
                    else
                    {
                        usb_request_stall();
                    }
                    break;
                case 0x03: //Feature Report
                    usb_getfeature_len = usb_ep0_rx_buffer[7];
                    usb_getfeature_len <<= 8;
                    usb_getfeature_len |= usb_ep0_rx_buffer[6];
                   
                    //JSG // may need to parse a byte to figure out which interface this is for
                    usb_getfeature_intf = usb_ep0_rx_buffer[4];
                    usb_getfeature_repid = usb_ep0_rx_buffer[2];
                    usb_getfeature_ptr = USB_HID_FEATURE_REPORTS_INDEXES[usb_getfeature_intf][usb_getfeature_repid];

                    fprintf(PIC16, "GFR - PTR 0x%04.4lX", usb_getfeature_ptr);
                    fprintf(PIC16, " REPID %ld, INTF %ld, LEN %ld\r\n", usb_getfeature_repid, usb_getfeature_intf, usb_getfeature_len); 
                    if(usb_getfeature_ptr != 0xFFFFL)
                    {
                        USB_stack_status.dev_req=GET_FEATURE_REPORT;
                        usb_copy_report_to_ep();
                    }
                    else
                    {
                        usb_request_stall();
                    }
                    break;
                default:
                    usb_request_stall();
                    break;
            }
            break;
   
        case USB_HID_REQUEST_SET_REPORT:

            /*****  WHAT GOES HERE???  *****/
            /*****  WHAT GOES HERE???  *****/
            /*****  WHAT GOES HERE???  *****/

            break;   
    //JSG   
    #IF USB_HID_BOOT_PROTOCOL
        case USB_HID_REQUEST_GET_PROTOCOL:  //03
            debug_usb_token(debug_putc,"GP");
            usb_ep0_tx_buffer[0]=hid_protocol[usb_ep0_rx_buffer[4]];
            usb_request_send_response(1);
            break;
    #ENDIF


Last edited by acs4design on Wed Nov 02, 2016 4:44 pm; edited 1 time in total
acs4design



Joined: 26 May 2016
Posts: 4

View user's profile Send private message

PostPosted: Wed Nov 02, 2016 12:34 pm     Reply with quote

It looks as though the *data* for the HID REQUEST SET REPORT is actually sent *before* the actual SET Request. I do actually receive the SET request, but I can't find the actual data that is supposed to go with it.

If it is in the next packet, how do I flag it as part of the set feature report request? If it comes before, how could I possibly know what that data is to be used for and be able to discern that data from anything else?



As you can see in lines marked in pink as 1 and 2, this is the data I need. It comes before the Set Report request in lines marked as 3 and 4
acs4design



Joined: 26 May 2016
Posts: 4

View user's profile Send private message

UPDATE
PostPosted: Wed Nov 02, 2016 3:21 pm     Reply with quote

So the Set request data *does* come after the the actual set request. I get the Set Feature Request and print 16 bytes of ep0_rx_buffer and the data past the 8th byte has not changed and is all zeros. However, on the next EP0 setup packet, I print the same 16 bytes and you can see that the buffer had ,at one time, the data that I was looking for.

the "00 D0 07 00 00 01 01 00" is part of the data that I was looking for.

EP0 SETUP: A1 01 03 03 03 00 16 00 00 00 00 00 00 00 00 00
GFR - PTR 0x0102 REPID 3, INTF 3, LEN 22
EP0 SETUP: A1 01 03 03 03 00 16 00 00 00 00 00 00 00 00 00
GFR - PTR 0x0102 REPID 3, INTF 3, LEN 22
EP0 SETUP: 21 09 03 03 03 00 16 00 00 00 00 00 00 00 00 00
SFR - PTR 0x0102 REPID 3, INTF 3, LEN 22
SFR PKT: 21 09 03 03 03 00 16 00 00 00 00 00 00 00 00 00
EP0 SETUP: A1 01 03 03 03 00 16 00 00 D0 07 00 00 01 01 00
GFR - PTR 0x0102 REPID 3, INTF 3, LEN 22
EP0 SETUP: A1 01 03 03 03 00 16 00 00 D0 07 00 00 01 01 00
GFR - PTR 0x0102 REPID 3, INTF 3, LEN 22
EP0 SETUP: 21 09 03 03 03 00 16 00 00 D0 07 00 00 01 01 00
SFR - PTR 0x0102 REPID 3, INTF 3, LEN 22

Somewhere along the way the data is not getting to usb_isr_tok_dne(); Since the buffer for ep0_rx_buffer is dual port RAM, the USB engine is writing to that ram and it has written the data I'm looking for. The question is, why isn't it getting passed up? or am I just missing it?
acs4design



Joined: 26 May 2016
Posts: 4

View user's profile Send private message

RESOLVED!!!
PostPosted: Wed Nov 02, 2016 3:59 pm     Reply with quote

In the SET REPORT inside of usb_isr_tkn_setup_ClassInterface() I set a flag in USB_stack_status.dev_req=SET_FEATURE_REPORT. This is a new flag that I have added. I also have to call usb_request_get_data(); in order to make sure I setup EP0_OUT ready to take another packet. Although, I'm not 100% sure it's necessary.

Code:

        case USB_HID_REQUEST_SET_REPORT:
            switch(usb_ep0_rx_buffer[3])
            {
                case 0x03: //Feature Report
                    //Take down all of the information because our data is in the next packet and we need to remember
                    //all of the pertinents
                    usb_setfeature_len = usb_ep0_rx_buffer[7];
                    usb_setfeature_len <<= 8;
                    usb_setfeature_len |= usb_ep0_rx_buffer[6];
                    usb_setfeature_intf = usb_ep0_rx_buffer[4];
                    usb_setfeature_repid = usb_ep0_rx_buffer[2];
                    usb_setfeature_ptr = USB_HID_FEATURE_REPORTS_INDEXES[usb_setfeature_intf][usb_setfeature_repid];

                    if(usb_setfeature_ptr != 0xFFFFL)
                    {
                        usb_request_get_data();
                        //I'll set this variable and wait for it to come through in usb_isr_tok_out_dne()
                        //that's where it should come out
                        USB_stack_status.dev_req=SET_FEATURE_REPORT;
                    }
                    else
                    {
                        fprintf(PIC16, "*** STALLED ***\r\n");
                        usb_request_stall();
                    }
                    break;
                default:
                    usb_request_stall();
                    break;
            }
            break;   
    //JSG   



Then in usb_isr_tok_out_dne() the next packet to come in (through the OUT) should be the one I'm looking for and there is no header, it's just raw data.

Below is the corrected usb_isr_tok_setup_dne() function that I ended up using. For now, I'm just printing the bytes I received in the feature report. Notice that I use "__usb_cdc_state" to check the state to make sure the raw data packet doesn't need to go there first. There is probably a better way to do this, but for now it is working.

Code:


extern usb_cdc_state_e __usb_cdc_state;
void usb_isr_tok_out_dne(unsigned int8 endpoint)
{
    if (endpoint==0)
    {
        #if USB_CDC_DEVICE
        if(__usb_cdc_state != USB_CDC_OUT_NOTHING)
        {
            usb_isr_tok_out_cdc_control_dne();
        }
        #endif
       
        if(USB_stack_status.dev_req == SET_FEATURE_REPORT)
        {
            fprintf(PIC16, "EP0 TOUT: ");
            for(int i = 0; i < 16; i++)
            {
                fprintf(PIC16, "%X ", usb_ep0_rx_buffer[i]);
            }
            fprintf(PIC16, "\r\n");
            usb_copy_ep_to_report();
        }
    }
    #if USB_CDC_DEVICE
    else if (endpoint==USB_CDC_DATA_OUT_ENDPOINT)//see ex_usb_serial.c example and usb_cdc.h driver
    {
        usb_isr_tok_out_cdc_data_dne();
    }
    #endif
}



Here is the function that actually copies the report data into the actual feature report location.

Code:

void usb_copy_ep_to_report(void)
{
    unsigned int i=0;
    while ((usb_setfeature_len)&&(i<USB_MAX_EP0_PACKET_LENGTH))
    {
        usb_setfeature_len--;
        USB_HID_FEATURE_REPORTS[usb_setfeature_ptr++] = usb_ep0_rx_buffer[i++];
    }

   if ((!usb_getdesc_len)&&(i!=USB_MAX_EP0_PACKET_LENGTH))
   {
         USB_stack_status.dev_req = NONE;
   }
}




PLEASE NOTE: The code snippets shown here are not the only changes that were necessary to get this working. There is lots going on behind the scenes necessary to get feature reports working in general. The device I have created has a CDC interface and two HID interfaces. So the code has been heavily modified to deal with all of these interfaces and configurations.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group