SAMV71 Xplained Ultra Software Package 1.4

host_hid.c

Go to the documentation of this file.
00001 /* This source file is part of the AVR Software Framework 2.0.0 release */
00002 
00003 /*This file is prepared for Doxygen automatic documentation generation.*/
00004 /*! \file *********************************************************************
00005  *
00006  * \brief Management of the generic host HID features.
00007  *
00008  * This file manages the generic host HID features.
00009  *
00010  * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32
00011  * - Supported devices:  All AVR32 devices with a USB module can be used.
00012  * - AppNote:
00013  *
00014  * \author               Atmel Corporation: http://www.atmel.com \n
00015  *                       Support and FAQ: http://support.atmel.no/
00016  *
00017  ******************************************************************************/
00018 
00019 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
00020  *
00021  * Redistribution and use in source and binary forms, with or without
00022  * modification, are permitted provided that the following conditions are met:
00023  *
00024  * 1. Redistributions of source code must retain the above copyright notice, this
00025  * list of conditions and the following disclaimer.
00026  *
00027  * 2. Redistributions in binary form must reproduce the above copyright notice,
00028  * this list of conditions and the following disclaimer in the documentation
00029  * and/or other materials provided with the distribution.
00030  *
00031  * 3. The name of Atmel may not be used to endorse or promote products derived
00032  * from this software without specific prior written permission.
00033  *
00034  * 4. This software may only be redistributed and used in connection with an Atmel
00035  * AVR product.
00036  *
00037  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00038  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00039  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00040  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
00041  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00042  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00043  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00044  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00045  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00046  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00047  *
00048  */
00049 
00050 //_____  I N C L U D E S _______________________________________________________
00051 
00052 #include <stddef.h>
00053 #include "compiler.h"
00054 #include "conf_usb.h"
00055 #include "usb_task.h"
00056 #include "usb_host_task.h"
00057 #include "usb_host_enum.h"
00058 #include "hid.h"
00059 #include "host_hid.h"
00060 
00061 
00062 //_____ M A C R O S ____________________________________________________________
00063 
00064 
00065 //_____ D E F I N I T I O N S __________________________________________________
00066 
00067 //! HID report descriptor parser control structure.
00068 static struct
00069 {
00070   size_t length;
00071   const hid_item_t *item;
00072 } host_hid_report_descriptor_parser =
00073 {
00074   0,
00075   NULL
00076 };
00077 
00078 
00079 //_____ D E C L A R A T I O N S ________________________________________________
00080 
00081 /*! \name Standard Requests Applied to HID
00082  */
00083 //! @{
00084 
00085 
00086 Status_t host_hid_get_descriptor(U8 descriptor_type, U8 descriptor_index, U8 s_interface)
00087 {
00088   Status_t status;
00089   const hid_descriptor_t *hid_descriptor = (hid_descriptor_t *)&data_stage;
00090   U8 i;
00091 
00092   usb_request.bmRequestType   = 0x81;
00093   usb_request.bRequest        = GET_DESCRIPTOR;
00094   usb_request.wValue          = descriptor_type << 8 | descriptor_index;
00095   usb_request.wIndex          = Get_interface_number(s_interface);
00096   usb_request.wLength         = SIZEOF_DATA_STAGE;
00097   usb_request.incomplete_read = FALSE;
00098 
00099   status = host_transfer_control(data_stage);
00100 
00101   switch (descriptor_type)
00102   {
00103   case HID_DESCRIPTOR:
00104     for (i = 0; i < hid_descriptor->bNumDescriptors; i++)
00105     {
00106       if (hid_descriptor->Descriptor[i].bType == HID_REPORT_DESCRIPTOR)
00107       {
00108         host_hid_report_descriptor_parser.length =
00109           usb_format_usb_to_mcu_data(16, hid_descriptor->Descriptor[i].wLength);
00110         break;
00111       }
00112     }
00113     break;
00114 
00115   case HID_REPORT_DESCRIPTOR:
00116     host_hid_report_descriptor_parser.item = (hid_item_t *)&data_stage;
00117     break;
00118   }
00119 
00120   return status;
00121 }
00122 
00123 
00124 Status_t host_hid_set_descriptor(U8 descriptor_type, U8 descriptor_index, U8 s_interface, U16 length)
00125 {
00126   usb_request.bmRequestType   = 0x01;
00127   usb_request.bRequest        = SET_DESCRIPTOR;
00128   usb_request.wValue          = descriptor_type << 8 | descriptor_index;
00129   usb_request.wIndex          = Get_interface_number(s_interface);
00130   usb_request.wLength         = length;
00131   usb_request.incomplete_read = FALSE;
00132 
00133   return host_transfer_control(data_stage);
00134 }
00135 
00136 
00137 //! @}
00138 
00139 
00140 /*! \name HID-Specific Requests
00141  */
00142 //! @{
00143 
00144 
00145 Status_t host_hid_get_report(U8 report_type, U8 report_id, U8 s_interface)
00146 {
00147   usb_request.bmRequestType   = 0xA1;
00148   usb_request.bRequest        = HID_GET_REPORT;
00149   usb_request.wValue          = report_type << 8 | report_id;
00150   usb_request.wIndex          = Get_interface_number(s_interface);
00151   usb_request.wLength         = SIZEOF_DATA_STAGE;
00152   usb_request.incomplete_read = FALSE;
00153 
00154   return host_transfer_control(data_stage);
00155 }
00156 
00157 
00158 Status_t host_hid_set_report(U8 report_type, U8 report_id, U8 s_interface, U16 length)
00159 {
00160   usb_request.bmRequestType   = 0x21;
00161   usb_request.bRequest        = HID_SET_REPORT;
00162   usb_request.wValue          = report_type << 8 | report_id;
00163   usb_request.wIndex          = Get_interface_number(s_interface);
00164   usb_request.wLength         = length;
00165   usb_request.incomplete_read = FALSE;
00166 
00167   return host_transfer_control(data_stage);
00168 }
00169 
00170 
00171 U8 host_hid_get_idle(U8 report_id, U8 s_interface)
00172 {
00173   usb_request.bmRequestType   = 0xA1;
00174   usb_request.bRequest        = HID_GET_IDLE;
00175   usb_request.wValue          = 0x00 << 8 | report_id;
00176   usb_request.wIndex          = Get_interface_number(s_interface);
00177   usb_request.wLength         = 0x0001;
00178   usb_request.incomplete_read = FALSE;
00179 
00180   host_transfer_control(data_stage);
00181 
00182   return data_stage[0x00];
00183 }
00184 
00185 
00186 Status_t host_hid_set_idle(U8 duration_4_ms, U8 report_id, U8 s_interface)
00187 {
00188   usb_request.bmRequestType   = 0x21;
00189   usb_request.bRequest        = HID_SET_IDLE;
00190   usb_request.wValue          = duration_4_ms << 8 | report_id;
00191   usb_request.wIndex          = Get_interface_number(s_interface);
00192   usb_request.wLength         = 0x0000;
00193   usb_request.incomplete_read = FALSE;
00194 
00195   return host_transfer_control(data_stage);
00196 }
00197 
00198 
00199 U8 host_hid_get_protocol(U8 s_interface)
00200 {
00201   usb_request.bmRequestType   = 0xA1;
00202   usb_request.bRequest        = HID_GET_PROTOCOL;
00203   usb_request.wValue          = 0x0000;
00204   usb_request.wIndex          = Get_interface_number(s_interface);
00205   usb_request.wLength         = 0x0001;
00206   usb_request.incomplete_read = FALSE;
00207 
00208   host_transfer_control(data_stage);
00209 
00210   return data_stage[0x00];
00211 }
00212 
00213 
00214 Status_t host_hid_set_protocol(U8 protocol, U8 s_interface)
00215 {
00216   usb_request.bmRequestType   = 0x21;
00217   usb_request.bRequest        = HID_SET_PROTOCOL;
00218   usb_request.wValue          = protocol;
00219   usb_request.wIndex          = Get_interface_number(s_interface);
00220   usb_request.wLength         = 0x0000;
00221   usb_request.incomplete_read = FALSE;
00222 
00223   return host_transfer_control(data_stage);
00224 }
00225 
00226 
00227 //! @}
00228 
00229 
00230 /*! \name HID Report Descriptor Parsing Functions
00231  */
00232 //! @{
00233 
00234 
00235 Status_bool_t host_hid_get_item(host_hid_item_t *item)
00236 {
00237   const hid_item_t *hid_item = host_hid_report_descriptor_parser.item;
00238   U8 size;
00239 
00240   if (host_hid_report_descriptor_parser.length <
00241       (U8 *)&hid_item->header - (U8 *)hid_item +
00242       sizeof(hid_item->header))
00243     return FALSE;
00244 
00245   item->type = hid_item->header.bType;
00246 
00247   if (hid_item->header.bTag == HID_ITEM_TAG_LONG_ITEM)
00248   {
00249     if (host_hid_report_descriptor_parser.length <
00250         (U8 *)&hid_item->long_format.bDataSize - (U8 *)hid_item +
00251         sizeof(hid_item->long_format.bDataSize))
00252       return FALSE;
00253 
00254     size = hid_item->long_format.bDataSize;
00255 
00256     if (host_hid_report_descriptor_parser.length <
00257         (U8 *)&hid_item->long_format.data - (U8 *)hid_item +
00258         size)
00259       return FALSE;
00260 
00261     item->tag = hid_item->long_format.bLongItemTag;
00262 
00263     item->long_format = TRUE;
00264 
00265     item->long_data.size = size;
00266     item->long_data.data = &hid_item->long_format.data;
00267 
00268     host_hid_report_descriptor_parser.length -=
00269       (U8 *)&hid_item->long_format.data - (U8 *)hid_item +
00270       size;
00271 
00272     host_hid_report_descriptor_parser.item =
00273       (hid_item_t *)&hid_item->long_format.data[size];
00274   }
00275   else
00276   {
00277     U8 i;
00278 
00279     size = (hid_item->short_format.bSize) ?
00280              1 << (hid_item->short_format.bSize - 1) :
00281              0;
00282 
00283     if (host_hid_report_descriptor_parser.length <
00284         (U8 *)&hid_item->short_format.data - (U8 *)hid_item +
00285         size)
00286       return FALSE;
00287 
00288     item->tag = hid_item->short_format.bTag;
00289 
00290     item->long_format = FALSE;
00291 
00292     item->short_data.value = 0x00000000;
00293     for (i = 0; i < size; i++)
00294     {
00295       item->short_data.value = item->short_data.value << 8 |
00296                                hid_item->short_format.data[i];
00297     }
00298     item->short_data.value =
00299       usb_format_usb_to_mcu_data(32, item->short_data.value <<
00300                                      ((sizeof(U32) - size) << 3));
00301 
00302     host_hid_report_descriptor_parser.length -=
00303       (U8 *)&hid_item->short_format.data - (U8 *)hid_item +
00304       size;
00305 
00306     host_hid_report_descriptor_parser.item =
00307       (hid_item_t *)&hid_item->short_format.data[size];
00308   }
00309 
00310   return TRUE;
00311 }
00312 
00313 
00314 //! @}
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines