今天跑一下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调出笔记本然后在笔记本上打出一行字:
|