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

📄 keyboard_driver.c

📁 This software package contains the USB framework core developped by ATMEL, as well as two HID driv
💻 C
📖 第 1 页 / 共 2 页
字号:
static const S_usb_endpoint_descriptor *pEndpoints[] = {

    &(sConfiguration.sInterruptIn),
    &(sConfiguration.sInterruptOut)
};

//! \brief  Standard descriptors list
static const S_std_descriptors sDescriptors = {

    &sDevice,
    (S_usb_configuration_descriptor *) &sConfiguration,
    pStrings,
    pEndpoints
};

//------------------------------------------------------------------------------
//      Internal functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//! \brief  Invokes the "report received" callback if it is set.
//! \param  pKbd Pointer to a S_kbd instance
//------------------------------------------------------------------------------
static void KBD_ReportReceived(const S_kbd *pKbd)
{
    if (pKbd->fReportReceivedCallback != 0) {

        pKbd->fReportReceivedCallback(0, 0, 0, 0);
    }

    // Send a ZLP to the host
    USB_SendZLP0(pKbd->sClass.pUsb, 0, 0);
}

//------------------------------------------------------------------------------
//      Exported functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//! \brief  Handles standard and class-specific SETUP requests.
//!
//! \param  pKbd Pointer to a S_kbd instance
//! \see    S_kbd
//------------------------------------------------------------------------------
void KBD_RequestHandler(S_kbd *pKbd)
{
    const S_usb   *pUsb = pKbd->sClass.pUsb;
    S_usb_request *pSetup = USB_GetSetup(pUsb);

    TRACE_DEBUG_M("NewReq ");

    // Check request type
    if (USB_REQUEST_TYPE(pSetup) == USB_STANDARD_REQUEST) {

        // Handle standard requests
        switch (pSetup->bRequest) {
        //----------------------
        case USB_GET_DESCRIPTOR:
        //----------------------
            // Identify requested descriptor
            switch (HBYTE(pSetup->wValue)) {
            //-------------------------
            case HID_REPORT_DESCRIPTOR:
            //-------------------------
                // Send report descriptor
                TRACE_DEBUG_M("Report ");
                USB_Write(pUsb,
                          0,
                          pReport,
                          min(sizeof(pReport), pSetup->wLength),
                          0,
                          0);
                break;

            //------------------
            case HID_DESCRIPTOR:
            //------------------
                // Send HID descriptor
                TRACE_DEBUG_M("HID ");

                USB_Write(pUsb,
                          0,
                          (void *) &sConfiguration.sHID,
                          min(sizeof(S_hid_descriptor), pSetup->wLength),
                          0,
                          0);
                break;

            //------
            default:
            //------
                // Forward request to standard handler
                STD_RequestHandler(&(pKbd->sClass));
                break;
            }
            break;

        //------
        default:
        //------
            // Forward request to standard handler
            STD_RequestHandler(&(pKbd->sClass));
            break;
        }
    }
    else {

        // Handle class-specific requests
        switch (pSetup->bRequest) {
        //----------------
        case HID_GET_IDLE:
        //----------------
            // Return current Idle rate
            TRACE_DEBUG_M("gIdle ");

            USB_Write(pUsb, 0, &(pKbd->bIdleRate), 1, 0, 0);
            break;

        //----------------
        case HID_SET_IDLE:
        //----------------
            // Get new Idle rate
            pKbd->bIdleRate = HBYTE(pSetup->wValue);
            TRACE_DEBUG_M("sIdle(%d) ", pKbd->bIdleRate);

            USB_SendZLP0(pUsb, 0, 0);
            break;

        //------------------
        case HID_GET_REPORT:
        //------------------
            // Send the current report to the host
            TRACE_DEBUG_M("gReport ");

            // Check report type
            if (HBYTE(pSetup->wValue) == HID_INPUT_REPORT) {

                // Send report
                TRACE_DEBUG_M("In ");
                USB_Write(pUsb, 0, &(pKbd->sInputReport),
                          KBD_INPUT_REPORT_SIZE, 0, 0);
            }
            else if (HBYTE(pSetup->wValue) == HID_OUTPUT_REPORT) {

                // Send report
                TRACE_DEBUG_M("Out ");
                USB_Write(pUsb, 0, &(pKbd->sOutputReport),
                          KBD_OUTPUT_REPORT_SIZE, 0, 0);
            }
            else {

                // STALL endpoint 0
                USB_Stall(pUsb, 0);
            }
            break;

        //------------------
        case HID_SET_REPORT:
        //------------------
            // Retrieve new report
            TRACE_DEBUG_M("sReport ");

            // Check report type
            if (HBYTE(pSetup->wValue) == HID_OUTPUT_REPORT) {

                // Retrieve report
                USB_Read(pUsb, 0, &(pKbd->sOutputReport), KBD_OUTPUT_REPORT_SIZE,
                         (Callback_f) KBD_ReportReceived, pKbd);
            }
            else {

                // STALL endpoint 0
                USB_Stall(pUsb, 0);
            }
            break;

        //------
        default:
        //------
            // STALL endpoint 0
            TRACE_WARNING("W: KBD_RequestHandler: Unknown request 0x%02X\n\r",
                          pSetup->bRequest);
            USB_Stall(pUsb, 0);
        }
    }
}

//------------------------------------------------------------------------------
//! \brief  Initializes a HID keyboard driver
//!
//!         This method sets the standard descriptors of the device and the
//!         default HID keyboard configuration.
//! \param  pKbd      Pointer to a S_kbd instance
//! \param  pUsb      Pointer to the S_usb driver instance to use
//! \param  fCallback Callback function to invoke when a new report is received
//! \see    S_kbd
//! \see    S_usb
//------------------------------------------------------------------------------
void KBD_Init(S_kbd *pKbd, const S_usb *pUsb, Callback_f fCallback)
{
    // Initialize mouse driver
    pKbd->bIdleRate = 0;
    pKbd->sInputReport.bmModifierKeys = 0;
    pKbd->sInputReport.pPressedKeys[0] = 0;
    pKbd->sInputReport.pPressedKeys[1] = 0;
    pKbd->sInputReport.pPressedKeys[2] = 0;
    pKbd->sOutputReport.bmLeds = 0;
    pKbd->fReportReceivedCallback = fCallback;

    // Initialize standard class attributes
    pKbd->sClass.pUsb = pUsb;
    pKbd->sClass.pDescriptors = &sDescriptors;

    // Initialize the USB driver
    USB_Init(pUsb);
}

//------------------------------------------------------------------------------
//! \brief  Sends the current mouse report to the host, through the interrupt IN
//!         endpoint
//! \param  pKbd      Pointer to a S_kbd instance
//! \param  fCallback Optional callback function to invoke when the report is
//!                   sent
//! \param  pArgument Optional argument to pass to the callback function
//------------------------------------------------------------------------------
unsigned char KBD_SendReport(const S_kbd *pKbd,
                             Callback_f  fCallback,
                             void        *pArgument)
{
    return USB_Write(pKbd->sClass.pUsb, KBD_INTERRUPT_IN, &(pKbd->sInputReport),
                     KBD_INPUT_REPORT_SIZE, fCallback, pArgument);
}

//------------------------------------------------------------------------------
//! \brief  Waits for a new report from the host to be received.
//! \param  pKbd      Pointer to a S_kbd instance
//! \param  fCallback Optional callback function to invoke when the report is
//!                   received
//! \param  pArgument Optional argument to pass to the callback function
//------------------------------------------------------------------------------
unsigned char KBD_ReceiveReport(S_kbd *pKbd,
                                Callback_f  fCallback,
                                void        *pArgument)
{
    return USB_Read(pKbd->sClass.pUsb, KBD_INTERRUPT_OUT, &(pKbd->sOutputReport),
                    KBD_OUTPUT_REPORT_SIZE, fCallback, pArgument);
}

⌨️ 快捷键说明

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