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

📄 keyboard_example.c

📁 This software package contains the USB framework core developped by ATMEL, as well as two HID driv
💻 C
📖 第 1 页 / 共 2 页
字号:
    DEV_Resume();
#endif

    LED_INIT();
    LED_ON(LED_POWER);
    LED_OFF(LED_USB);
    LED_OFF(LED_MEM);
}

//------------------------------------------------------------------------------
//! \brief  Callback invoked when a new SETUP request is received
//!
//!         The new request if forwarded to the standard request handler,
//!         which performs the enumeration of the device.
//! \param  pUsb   Pointer to a S_usb instance
//------------------------------------------------------------------------------
static void CBK_NewRequest(const S_usb *pUsb)
{
    KBD_RequestHandler(&sKbd);
}

//------------------------------------------------------------------------------
//! \brief  Resets a timer when a new report has been sent.
//!
//!         This is necessary to comply with the configured Idle rate set by
//!         the host. When the timer expires, this means the report has been
//!         unchanged and that the device should resent it once.
//------------------------------------------------------------------------------
static void ResetTimer()
{
    // Check that Idle rate is not null (infinite)
    if (sKbd.bIdleRate > 0) {

        dTimerTicks = 0;
        AT91C_BASE_TC0->TC_RC = (AT91C_MASTER_CLOCK / 2) / 1000;
        AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
        AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
    }
}

//------------------------------------------------------------------------------
//! \brief  Called when the timer expires after a new input report has been sent
//!
//!         The same report is sent one more time to indicate that it is
//!         unchanged.
//------------------------------------------------------------------------------
static void TimerExpired()
{
    unsigned char bStatus;

    TRACE_DEBUG_H("Expired\n\r");
    AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;

    // Send current report once
    do {

        bStatus = KBD_SendReport(&sKbd, 0, 0);
    }
    while (bStatus != USB_STATUS_SUCCESS);
}

//------------------------------------------------------------------------------
//! \brief  Called when a timer tick occurs, every 1ms.
//!
//!         When the current Idle rate has been reached, the TimerExpired method
//!         is triggered.
//------------------------------------------------------------------------------
static void TimerTick()
{
    volatile unsigned int dDummy;

    // Increase tick count
    dTimerTicks++;

    // Check if Idle rate has been reached
    if (dTimerTicks >= (sKbd.bIdleRate*4)) {

        TimerExpired();
    }

    // Clear interrupt
    dDummy = AT91C_BASE_TC0->TC_SR;
}

//------------------------------------------------------------------------------
//! \brief  Called when the host has sent an output report to the device.
//------------------------------------------------------------------------------
static void ReportReceived()
{
    // Check the bmLEDs field
    if (ISSET(sKbd.sOutputReport.bmLeds, 1)) {

        LED_ON(LED_MEM);
    }
    else {

        LED_OFF(LED_MEM);
    }
}

//------------------------------------------------------------------------------
//! \brief  Receive loop for output report sent by the host.
//!
//!         When a new report is received, the KBD_ReceiveReport function is
//!         called again to start a new transfer immediately.
//------------------------------------------------------------------------------
static void ReceiveReports()
{
    unsigned char bStatus;

    do {

        bStatus = KBD_ReceiveReport(&sKbd, (Callback_f) ReportReceived, 0);
    }
    while (bStatus != USB_STATUS_SUCCESS);
}

//------------------------------------------------------------------------------
//          Main
//------------------------------------------------------------------------------
int main()
{
    unsigned int       dPioStatus;
    bool               isChanged;
    unsigned int       dNumPressedKeys;
    unsigned int       dKey;
    S_kbd_input_report *pInputReport = &(sKbd.sInputReport);
    unsigned char      bStatus;

    TRACE_INIT();
    TRACE_INFO("\n\rMain HID keyboard\n\r");

    // Configure timer 0
    // 1 ms precision
    AT91F_TC0_CfgPMC();
    AT91C_BASE_TC0->TC_CMR = AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO;
    AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
    AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
                          AT91C_ID_TC0,
                          AT91C_AIC_PRIOR_LOWEST,
                          0,
                          TimerTick);
    AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_TC0);

    // Initialize switches
    AT91F_BUTTON_Init();

    // Initialize the HID driver
    KBD_Init(&sKbd, &sUsb, (Callback_f) ReportReceived);

    TRACE_INFO("Connecting ... ");

    // Wait for the device to be powered before connecting it
    while (!ISSET(USB_GetState(&sUsb), USB_STATE_POWERED));

    USB_Connect(&sUsb);

    TRACE_INFO("OK\n\r");

    // Wait for the device to be configured
    while (!ISSET(USB_GetState(&sUsb), USB_STATE_CONFIGURED));

    // Start receiving reports on the Interrupt OUT pipe
    ReceiveReports();

    // Main loop
    while (1) {

        isChanged = false;
        dNumPressedKeys = 0;

        // Retrieve PIO status change
        dPioStatus = SWITCH_PIO->PIO_PDSR;

        // Check standard keys
        for (dKey = 0; dKey < NUM_NORMAL_KEYS; dKey++) {

            // Check for status mismatch
            if (ISCLEARED(dPioStatus, pKeyPios[dKey]) != pKeyPressed[dKey]) {

                // Update status
                pKeyPressed[dKey] = ISCLEARED(dPioStatus, pKeyPios[dKey]);

                // Check if key has been pressed or released
                if (pKeyPressed[dKey]) {

                    // Update input report
                    pInputReport->pPressedKeys[dNumPressedKeys] = pKeyCodes[dKey];
                    dNumPressedKeys++;
                }

                isChanged = true;
            }
        }

        // Check modifier keys
        for (dKey = NUM_NORMAL_KEYS; dKey < NUM_KEYS; dKey++) {

            // Check for status mismatch
            if (ISCLEARED(dPioStatus, pKeyPios[dKey]) != pKeyPressed[dKey]) {

                // Update status
                pKeyPressed[dKey] = ISCLEARED(dPioStatus, pKeyPios[dKey]);

                // Check if key has been pressed or released
                if (pKeyPressed[dKey]) {

                    // Update input report
                    SET(pInputReport->bmModifierKeys, pKeyCodes[dKey]);
                }
                else {

                    // Update input report
                    CLEAR(pInputReport->bmModifierKeys, pKeyCodes[dKey]);
                }

                isChanged = true;
            }
        }

        // Report status change
        if (isChanged) {

            // Clear remaining keys
            for (dKey = dNumPressedKeys; dKey < NUM_KEYS; dKey++) {

                pInputReport->pPressedKeys[dKey] = 0;
            }

            // Send new report
            do {

                bStatus = KBD_SendReport(&sKbd, (Callback_f) ResetTimer, 0);
            }
            while (bStatus != USB_STATUS_SUCCESS);
        }
    }
}


⌨️ 快捷键说明

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