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