⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hiddkeyboarddriver.c

📁 useful when developer using ARM7 to interface HID devices like USB Keyboard
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support 
 * ----------------------------------------------------------------------------
 * Copyright (c) 2008, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ----------------------------------------------------------------------------
 */

//------------------------------------------------------------------------------
//         Headers
//------------------------------------------------------------------------------

#include "HIDDKeyboardDriver.h"
#include "HIDDKeyboardDriverDescriptors.h"
#include "HIDDKeyboardCallbacks.h"
#include "HIDDKeyboardInputReport.h"
#include "HIDDKeyboardOutputReport.h"
#include <utility/trace.h>
#include <usb/common/core/USBGetDescriptorRequest.h>
#include <usb/common/hid/HIDGenericDescriptor.h>
#include <usb/common/hid/HIDDescriptor.h>
#include <usb/common/hid/HIDGenericRequest.h>
#include <usb/common/hid/HIDReportRequest.h>
#include <usb/common/hid/HIDIdleRequest.h>
#include <usb/common/hid/HIDKeypad.h>
#include <usb/device/core/USBD.h>
#include <usb/device/core/USBDDriver.h>

//------------------------------------------------------------------------------
//         Internal types
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// Driver structure for an HID device implementing keyboard functionalities.
//------------------------------------------------------------------------------
typedef struct {

    /// Standard USB device driver instance.
    USBDDriver usbdDriver;
    /// Idle rate (in milliseconds) of the input report.
    unsigned char inputReportIdleRate;
    /// Input report instance.
    HIDDKeyboardInputReport inputReport;
    /// Output report instance.
    HIDDKeyboardOutputReport outputReport;

} HIDDKeyboardDriver;

//------------------------------------------------------------------------------
//         Internal variables
//------------------------------------------------------------------------------

/// Static instance of the HID keyboard device driver.
static HIDDKeyboardDriver hiddKeyboardDriver;

//------------------------------------------------------------------------------
//         Internal functions
//------------------------------------------------------------------------------

/**
 Returns the descriptor requested by the host.

\param type Descriptor type.
\param length Maximum number of bytes to send.
\return 1 if the request has been handled by this function, otherwise 0.
*/
static unsigned char HIDDKeyboardDriver_GetDescriptor(unsigned char type,
                                                      unsigned char length)
{
    const USBConfigurationDescriptor *pConfiguration;
    HIDDescriptor *hidDescriptor;

    switch (type) {

        case HIDGenericDescriptor_REPORT:
            TRACE_INFO_WP("Report ");

            // Adjust length and send report descriptor
            if (length > HIDDKeyboardDriverDescriptors_REPORTSIZE) {

                length = HIDDKeyboardDriverDescriptors_REPORTSIZE;
            }
            USBD_Write(0, &hiddReportDescriptor, length, 0, 0);
            break;

        case HIDGenericDescriptor_HID:
            TRACE_INFO_WP("HID ");

            // Configuration descriptor is different depending on configuration
            if (USBD_IsHighSpeed()) {

                pConfiguration = hiddKeyboardDriver.usbdDriver.pDescriptors->pHsConfiguration;
            }
            else {

                pConfiguration = hiddKeyboardDriver.usbdDriver.pDescriptors->pFsConfiguration;
            }

            // Parse the device configuration to get the HID descriptor
            USBConfigurationDescriptor_Parse(
                                    pConfiguration,
                                    0,
                                    0,
                                    (USBGenericDescriptor **) &hidDescriptor);

            // Adjust length and send HID descriptor
            if (length > sizeof(HIDDescriptor)) {

                length = sizeof(HIDDescriptor);
            }
            USBD_Write(0, hidDescriptor, length, 0, 0);
            break;

        default:
            return 0;
    }

    return 1;
}

/**
 Sends the current Idle rate of the input report to the host.
*/
static void HIDDKeyboardDriver_GetIdle()
{
    TRACE_INFO_WP("gIdle ");

    USBD_Write(0, &(hiddKeyboardDriver.inputReportIdleRate), 1, 0, 0);
}

/**
 Retrieves the new idle rate of the input report from the USB host.

 \param idleRate New input report idle rate.
*/
static void HIDDKeyboardDriver_SetIdle(unsigned char idleRate)
{
    TRACE_INFO_WP("sIdle(%d) ", idleRate);

    hiddKeyboardDriver.inputReportIdleRate = idleRate;
    USBD_Write(0, 0, 0, 0, 0);
}

/**
 Sends the requested report to the host.

\param type Report type.
\param length Maximum number of bytes to send.
*/
static void HIDDKeyboardDriver_GetReport(unsigned char type,
                                         unsigned short length)
{
    TRACE_INFO_WP("gReport ");

    // Check report type
    switch (type) {

        case HIDReportRequest_INPUT:
            TRACE_INFO_WP("In ");

            // Adjust size and send report
            if (length > sizeof(HIDDKeyboardInputReport)) {

                length = sizeof(HIDDKeyboardInputReport);
            }
            USBD_Write(0, // Endpoint #0
                       &(hiddKeyboardDriver.inputReport),
                       length,
                       0, // No callback
                       0);
            break;

        case HIDReportRequest_OUTPUT:
            TRACE_INFO_WP("Out ");

            // Adjust size and send report
            if (length > sizeof(HIDDKeyboardOutputReport)) {

                length = sizeof(HIDDKeyboardOutputReport);
            }
            USBD_Write(0, // Endpoint #0
                       &(hiddKeyboardDriver.outputReport),
                       length,
                       0, // No callback
                       0);
            break;

        default:
            USBD_Stall(0);
    }
}

/**
 Callback invoked when an output report has been received from the host.
 Forward the new status of the LEDs to the user program via the
 HIDDKeyboardCallbacks_LedsChanged callback.
*/
static void HIDDKeyboardDriver_ReportReceived()
{
    TRACE_INFO_WP("oReport ");

    // Trigger callback
    HIDDKeyboardCallbacks_LedsChanged(
        HIDDKeyboardOutputReport_GetNumLockStatus(&(hiddKeyboardDriver.outputReport)),
        HIDDKeyboardOutputReport_GetCapsLockStatus(&(hiddKeyboardDriver.outputReport)),
        HIDDKeyboardOutputReport_GetScrollLockStatus(&(hiddKeyboardDriver.outputReport)));

    // Restart transfer
    USBD_Read(HIDDKeyboardDriverDescriptors_INTERRUPTOUT,
              &(hiddKeyboardDriver.outputReport),
              sizeof(HIDDKeyboardOutputReport),
              (TransferCallback) HIDDKeyboardDriver_ReportReceived,
              0); // No argument for callback function
}

/**
 Retrieves the new value of a report from the host and saves it.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -