打印
[Atmel]

用SAM-BA或JLINK跑ATSAM4E16的程序(20) USB HID 键盘

[复制链接]
932|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ddllxxrr|  楼主 | 2015-11-30 21:05 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
今天跑一下USB HID键盘例程Studio7自带。
这个程序展示了HID键盘,由于HID Windows自动识别,所以不需要驱动程序。使用十分方便。
这个程序用了以下的模块组:
* -基本模块:
*   Startup, board, clock, interrupt, power management
* - USB堆栈和HID模块:
*   <br>services/usb/
*   <br>services/usb/udc/
*   <br>services/usb/class/hid/
*   <br>services/usb/class/hid/keyboard/
*
*    - main.c完成:
*      初使化时钟
*      初始化中断
*      管理UI
*    - 每个目标板完成如下 "./examples/product_board/":
*       - conf_foo.h   配置每个模块
*       - ui.c        用户接口(buttons, leds)

以下是UI.c的内容:


#include <asf.h>
#include "ui.h"

/** Sequence process running each \c SEQUENCE_PERIOD ms */
#define SEQUENCE_PERIOD 150

/** Wakeup, ignore button change until button is back to default state */
static bool btn_wakeup = false;

static struct {
        bool b_modifier;
        bool b_down;
        uint8_t value;
} ui_sequence[] = {
        /* Display windows menu */
        {true,true,HID_MODIFIER_LEFT_UI},
        /* Launch Windows Command line */
        {false,true,HID_R},
        {false,false,HID_R},
        /* Clear modifier */
        {true,false,HID_MODIFIER_LEFT_UI},
        /* Tape sequence "notepad" + return */
        {false,true,HID_N},
        {false,false,HID_N},
        {false,true,HID_O},
        {false,false,HID_O},
        {false,true,HID_T},
        {false,false,HID_T},
        {false,true,HID_E},
        {false,false,HID_E},
        {false,true,HID_P},
        {false,false,HID_P},
        {false,true,HID_A},
        {false,false,HID_A},
        {false,true,HID_D},
        {false,false,HID_D},
        {false,true,HID_ENTER},
        {false,false,HID_ENTER},
        /* Delay to wait "notepad" focus */
        {false,false,0}, /* No key (= SEQUENCE_PERIOD delay) */
        {false,false,0}, /* No key (= SEQUENCE_PERIOD delay) */
        {false,false,0}, /* No key (= SEQUENCE_PERIOD delay) */
        {false,false,0}, /* No key (= SEQUENCE_PERIOD delay) */
        {false,false,0}, /* No key (= SEQUENCE_PERIOD delay) */
        {false,false,0}, /* No key (= SEQUENCE_PERIOD delay) */
        {false,false,0}, /* No key (= SEQUENCE_PERIOD delay) */
        /* Display "Atmel " */
        {true,true,HID_MODIFIER_RIGHT_SHIFT}, /* Enable Maj */
        {false,true,HID_A},
        {false,false,HID_A},
        {true,false,HID_MODIFIER_RIGHT_SHIFT}, /* Disable Maj */
        {false,true,HID_T},
        {false,false,HID_T},
        {false,true,HID_M},
        {false,false,HID_M},
        {false,true,HID_E},
        {false,false,HID_E},
        {false,true,HID_L},
        {false,false,HID_L},
        {false,true,HID_SPACEBAR},
        {false,false,HID_SPACEBAR},
        /* Display "ARM " */
        {false,true,HID_CAPS_LOCK}, /* Enable caps lock */
        {false,false,HID_CAPS_LOCK},
        {false,true,HID_A},
        {false,false,HID_A},
        {false,true,HID_R},
        {false,false,HID_R},
        {false,true,HID_M},
        {false,false,HID_M},
        {false,true,HID_CAPS_LOCK}, /* Disable caps lock */
        {false,false,HID_CAPS_LOCK},
};

/* Wakeup pin is push button (BP3, fast wakeup 10) */
#define  WAKEUP_PMC_FSTT (PUSHBUTTON_2_WKUP_FSTT)
#define  WAKEUP_PIN      (GPIO_PUSH_BUTTON_2)
#define  WAKEUP_PIO      (PIN_PUSHBUTTON_2_PIO)
#define  WAKEUP_PIO_ID   (PIN_PUSHBUTTON_2_ID)
#define  WAKEUP_PIO_MASK (PIN_PUSHBUTTON_2_MASK)
#define  WAKEUP_PIO_ATTR \
        (PIO_INPUT | PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_LOW_LEVEL)

/* Interrupt on "pin change" from push button to do wakeup on USB
* Note:
* This interrupt is enable when the USB host enable remotewakeup feature
* This interrupt wakeup the CPU if this one is in idle mode
*/
static void ui_wakeup_handler(uint32_t id, uint32_t mask)
{
        if (WAKEUP_PIO_ID == id && WAKEUP_PIO_MASK == mask) {
                /* It is a wakeup then send wakeup USB */
                udc_remotewakeup();
                /* Wakeup, ignore button change until button is back to default state */
                btn_wakeup = true;
                LED_On(LED0);
        }
}

void ui_init(void)
{
        /* Set handler for push button (BP3) */
        pio_handler_set(WAKEUP_PIO, WAKEUP_PIO_ID, WAKEUP_PIO_MASK,
                WAKEUP_PIO_ATTR, ui_wakeup_handler);
        /* Enable IRQ for button (PIOA) */
        NVIC_EnableIRQ((IRQn_Type) WAKEUP_PIO_ID);
        /* Initialize LEDs */
        LED_Off(LED0);
        LED_Off(LED1);
}

void ui_powerdown(void)
{
        LED_Off(LED0);
        LED_Off(LED1);
}


void ui_wakeup_enable(void)
{
        /* Configure BP3 as PIO input */
        pio_configure_pin(WAKEUP_PIN, WAKEUP_PIO_ATTR);
        /* Enable interrupt for BP3 */
        pio_enable_pin_interrupt(WAKEUP_PIN);
        /* Enable fast wakeup for button pin (WKUP10 for PA20) */
        pmc_set_fast_startup_input(WAKEUP_PMC_FSTT);
}

void ui_wakeup_disable(void)
{
        /* Disable interrupt for button pin */
        pio_disable_pin_interrupt(WAKEUP_PIN);
        /* Disable fast wakeup for button pin (WKUP10 for BP3) */
        pmc_clr_fast_startup_input(WAKEUP_PMC_FSTT);
}

void ui_wakeup(void)
{
        LED_On(LED0);
}

void ui_process(uint16_t framenumber)
{
        bool b_btn_state, success;
        static bool btn_last_state = false;
        static bool sequence_running = false;
        static uint8_t sequence_pos = 0;
        uint8_t value;
        static uint16_t cpt_sof = 0;

        if ((framenumber % 1000) == 0) {
                LED_On(LED1);
        }
        if ((framenumber % 1000) == 500) {
                LED_Off(LED1);
        }
        /* Scan process running each 2ms */
        cpt_sof++;
        if ((cpt_sof % 2) == 0) {
                return;
        }

        /* Scan buttons on push button 2 (BP3) to send keys sequence */
        b_btn_state = !ioport_get_pin_level(GPIO_PUSH_BUTTON_2);
        if (b_btn_state != btn_last_state) {
                btn_last_state = b_btn_state;
                if (btn_wakeup) {
                        if (!b_btn_state) {
                                btn_wakeup = false;
                        }
                } else {
                        sequence_running = true;
                }
        }

        /* Sequence process running each period */
        if (SEQUENCE_PERIOD > cpt_sof) {
                return;
        }
        cpt_sof = 0;

        if (sequence_running) {
                /* Send next key */
                value = ui_sequence[sequence_pos].value;
                if (value!=0) {
                        if (ui_sequence[sequence_pos].b_modifier) {
                                if (ui_sequence[sequence_pos].b_down) {
                                        success = udi_hid_kbd_modifier_down(value);
                                } else {
                                        success = udi_hid_kbd_modifier_up(value);
                                }
                        } else {
                                if (ui_sequence[sequence_pos].b_down) {
                                        success = udi_hid_kbd_down(value);
                                } else {
                                        success = udi_hid_kbd_up(value);
                                }
                        }
                        if (!success) {
                                return; /* Retry it on next schedule */
                        }
                }
                /* Valid sequence position */
                sequence_pos++;
                if (sequence_pos >=
                        sizeof(ui_sequence) / sizeof(ui_sequence[0])) {
                        sequence_pos = 0;
                        sequence_running = false;
                }
        }
}

void ui_kbd_led(uint8_t value)
{
        if (value & HID_LED_CAPS_LOCK) {
                LED_On(LED2);
        } else {
                LED_Off(LED2);
        }
}

/**
* \defgroup UI User Interface
*
* Human interface on SAM4E-EK:
* - Led 0 (D2) is on when USB is wakeup
* - Led 1 (D3) blinks when USB host has checked and enabled HID Mouse interface
* - Led 2 (D4) displays caps lock status.
* - The push button 2 (BP3) opens a notepad application on Windows O.S.
*   and sends key sequence "Atmel ARM"
* - Only a low level on push button 2 (BP3) will generate a wakeup to USB Host
*   in remote wakeup mode.
*
*/
程序运行结果如下:

当我下载程序后重启系统后,第一次则提示按装驱动,这是WINDOWS自动完成的。


驱动完成后,我按下K4键,则windows自动执行,notpad调出笔记本然后在笔记本上打出一行字:






相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2399

主题

6963

帖子

68

粉丝