TI中文支持网
TI专业的中文技术问题搜集分享网站

新手求一个能在EK-TM4C123GXL上跑的usb_dev_keyboard例程

如题。

本人纯新手,需要将EK-TM4C123GXL模拟成usb_keyboard,哪位大神有例程吗>_<

在ek-lm系列里有这个例程,移植起来麻烦吗?求解~

Sky Lau:

回复 xyz549040622:

你好,谢谢回答~

从dk-tm4c123g移植到ek-tm4c123g大致需要做哪部分的改动那?这两个板子主要区别是什么?

我对usb的了解只有一点,以后也只需要在这个usb_keyboard上做文章,您能建议一下需要学习哪些东西吗?

xyz549040622:

回复 Sky Lau:

两个板子的主控都一样的,就是外设的不同。你可以详细看看例子中需要操作说明外设,具体看看dk-tm4c123g中的外设原理图,然后到ek-tm4c123g对比下。我估计不需要修改很大的东西的。你看看usb的基本描述就差不多了。

Sky Lau:

回复 xyz549040622:

两个板子用的库的版本是一样的,所以只要把button的对应关系改一改,再把ek-tm4c123g没有的外设相关处理函数去掉不就行了吗?

主机获取描述符的过程是usblib/device/usbdhidkeyb.c里面处理好了的吧?

然后我这样改过之后,编译,然后烧进去,接到主机上没反应啊,按键功能没反应还好说,但是根本没被识别为键盘啊,是还需要做什么吗?

贴下改过之后的usb_dev_keyboard.c

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "grlib/grlib.h"
#include "grlib/widget.h"
#include "usblib/usblib.h"
#include "usblib/usbhid.h"
#include "usblib/device/usbdevice.h"
#include "usblib/device/usbdhid.h"
#include "usblib/device/usbdhidkeyb.h"
#include "drivers/buttons.h"
#include "usb_keyb_structs.h"//*****************************************************************************
//
//! <h1>USB HID Keyboard Device (usb_dev_keyboard)</h1>
//!
//! This example application turns the evaluation board into a USB keyboard
//! supporting the Human Interface Device class.When the push button is
//! pressed, a sequence of key presses is simulated to type a string.Care
//! should be taken to ensure that the active window can safely receive the
//! text; enter is not pressed at any point so no actions are attempted by the
//! host if a terminal window is used (for example).The status LED is used to
//! indicate the current Caps Lock state and is updated in response to any
//! other keyboard attached to the same USB host system.
//!
//! The device implemented by this application also supports USB remote wakeup
//! allowing it to request the host to reactivate a suspended bus.If the bus
//! is suspended (as indicated on the application display), pressing the
//! push button will request a remote wakeup assuming the host has not
//! specifically disabled such requests.
//
//*****************************************************************************//*****************************************************************************
//
// The system tick timer period.
//
//*****************************************************************************
#define SYSTICKS_PER_SECOND100//*****************************************************************************
//
// A mapping from the ASCII value received from the UART to the corresponding
// USB HID usage code.
//
//*****************************************************************************
static const int8_t g_ppi8KeyUsageCodes[][2] =
{{ 0, HID_KEYB_USAGE_SPACE },//0x20{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_1 },// ! 0x21{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_FQUOTE },// " 0x22{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_3 },// # 0x23{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_4 },// $ 0x24{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_5 },// % 0x25{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_7 },// & 0x26{ 0, HID_KEYB_USAGE_FQUOTE },// ' 0x27{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_9 },// ( 0x28{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_0 },// ) 0x29{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_8 },// * 0x2a{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_EQUAL },// + 0x2b{ 0, HID_KEYB_USAGE_COMMA },// , 0x2c{ 0, HID_KEYB_USAGE_MINUS },// - 0x2d{ 0, HID_KEYB_USAGE_PERIOD },// . 0x2e{ 0, HID_KEYB_USAGE_FSLASH },// / 0x2f{ 0, HID_KEYB_USAGE_0 },// 0 0x30{ 0, HID_KEYB_USAGE_1 },// 1 0x31{ 0, HID_KEYB_USAGE_2 },// 2 0x32{ 0, HID_KEYB_USAGE_3 },// 3 0x33{ 0, HID_KEYB_USAGE_4 },// 4 0x34{ 0, HID_KEYB_USAGE_5 },// 5 0x35{ 0, HID_KEYB_USAGE_6 },// 6 0x36{ 0, HID_KEYB_USAGE_7 },// 7 0x37{ 0, HID_KEYB_USAGE_8 },// 8 0x38{ 0, HID_KEYB_USAGE_9 },// 9 0x39{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_SEMICOLON }, // : 0x3a{ 0, HID_KEYB_USAGE_SEMICOLON },// ; 0x3b{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_COMMA },// < 0x3c{ 0, HID_KEYB_USAGE_EQUAL },// = 0x3d{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_PERIOD },// > 0x3e{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_FSLASH },// ? 0x3f{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_2 },// @ 0x40{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_A },// A 0x41{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_B },// B 0x42{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_C },// C 0x43{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_D },// D 0x44{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_E },// E 0x45{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_F },// F 0x46{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_G },// G 0x47{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_H },// H 0x48{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_I },// I 0x49{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_J },// J 0x4a{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_K },// K 0x4b{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_L },// L 0x4c{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_M },// M 0x4d{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_N },// N 0x4e{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_O },// O 0x4f{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_P },// P 0x50{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_Q },// Q 0x51{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_R },// R 0x52{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_S },// S 0x53{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_T },// T 0x54{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_U },// U 0x55{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_V },// V 0x56{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_W },// W 0x57{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_X },// X 0x58{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_Y },// Y 0x59{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_Z },// Z 0x5a{ 0, HID_KEYB_USAGE_LBRACKET },// [ 0x5b{ 0, HID_KEYB_USAGE_BSLASH },// \ 0x5c{ 0, HID_KEYB_USAGE_RBRACKET },// ] 0x5d{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_6 },// ^ 0x5e{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_MINUS },// _ 0x5f{ 0, HID_KEYB_USAGE_BQUOTE },// ` 0x60{ 0, HID_KEYB_USAGE_A },// a 0x61{ 0, HID_KEYB_USAGE_B },// b 0x62{ 0, HID_KEYB_USAGE_C },// c 0x63{ 0, HID_KEYB_USAGE_D },// d 0x64{ 0, HID_KEYB_USAGE_E },// e 0x65{ 0, HID_KEYB_USAGE_F },// f 0x66{ 0, HID_KEYB_USAGE_G },// g 0x67{ 0, HID_KEYB_USAGE_H },// h 0x68{ 0, HID_KEYB_USAGE_I },// i 0x69{ 0, HID_KEYB_USAGE_J },// j 0x6a{ 0, HID_KEYB_USAGE_K },// k 0x6b{ 0, HID_KEYB_USAGE_L },// l 0x6c{ 0, HID_KEYB_USAGE_M },// m 0x6d{ 0, HID_KEYB_USAGE_N },// n 0x6e{ 0, HID_KEYB_USAGE_O },// o 0x6f{ 0, HID_KEYB_USAGE_P },// p 0x70{ 0, HID_KEYB_USAGE_Q },// q 0x71{ 0, HID_KEYB_USAGE_R },// r 0x72{ 0, HID_KEYB_USAGE_S },// s 0x73{ 0, HID_KEYB_USAGE_T },// t 0x74{ 0, HID_KEYB_USAGE_U },// u 0x75{ 0, HID_KEYB_USAGE_V },// v 0x76{ 0, HID_KEYB_USAGE_W },// w 0x77{ 0, HID_KEYB_USAGE_X },// x 0x78{ 0, HID_KEYB_USAGE_Y },// y 0x79{ 0, HID_KEYB_USAGE_Z },// z 0x7a{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_LBRACKET },// { 0x7b{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_BSLASH },// | 0x7c{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_RBRACKET },// } 0x7d{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_BQUOTE },// ~ 0x7e
};//*****************************************************************************
//
// This global indicates whether or not we are connected to a USB host.
//
//*****************************************************************************
volatile bool g_bConnected = false;//*****************************************************************************
//
// This global indicates whether or not the USB bus is currently in the suspend
// state.
//
//*****************************************************************************
volatile bool g_bSuspended = false;//*****************************************************************************
//
// Global system tick counter holds elapsed time since the application started
// expressed in 100ths of a second.
//
//*****************************************************************************
volatile uint32_t g_ui32SysTickCount;//*****************************************************************************
//
// The number of system ticks to wait for each USB packet to be sent before
// we assume the host has disconnected.The value 50 equates to half a second.
//
//*****************************************************************************
#define MAX_SEND_DELAY50//*****************************************************************************
//
// This global is set to true if the host sends a request to set or clear
// any keyboard LED.
//
//*****************************************************************************
volatile bool g_bDisplayUpdateRequired;//*****************************************************************************
//
// This enumeration holds the various states that the keyboard can be in during
// normal operation.
//
//*****************************************************************************
volatile enum
{//// Unconfigured.//STATE_UNCONFIGURED,//// No keys to send and not waiting on data.//STATE_IDLE,//// Waiting on data to be sent out.//STATE_SENDING
}
g_eKeyboardState = STATE_UNCONFIGURED;//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif//*****************************************************************************
//
// Handles asynchronous events from the HID keyboard driver.
//
// \param pvCBData is the event callback pointer provided during
// USBDHIDKeyboardInit().This is a pointer to our keyboard device structure
// (&g_sKeyboardDevice).
// \param ui32Event identifies the event we are being called back for.
// \param ui32MsgData is an event-specific value.
// \param pvMsgData is an event-specific pointer.
//
// This function is called by the HID keyboard driver to inform the application
// of particular asynchronous events related to operation of the keyboard HID
// device.
//
// \return Returns 0 in all cases.
//
//*****************************************************************************
uint32_t
KeyboardHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgData,void *pvMsgData)
{switch (ui32Event){//// The host has connected to us and configured the device.//case USB_EVENT_CONNECTED:{g_bConnected = true;g_bSuspended = false;break;}//// The host has disconnected from us.//case USB_EVENT_DISCONNECTED:{g_bConnected = false;break;}//// We receive this event every time the host acknowledges transmission// of a report. It is used here purely as a way of determining whether// the host is still talking to us or not.//case USB_EVENT_TX_COMPLETE:{//// Enter the idle state since we finished sending something.//g_eKeyboardState = STATE_IDLE;break;}//// This event indicates that the host has suspended the USB bus.//case USB_EVENT_SUSPEND:{g_bSuspended = true;break;}//// This event signals that the host has resumed signalling on the bus.//case USB_EVENT_RESUME:{g_bSuspended = false;break;}//// This event indicates that the host has sent us an Output or// Feature report and that the report is now in the buffer we provided// on the previous USBD_HID_EVENT_GET_REPORT_BUFFER callback.//case USBD_HID_KEYB_EVENT_SET_LEDS:{//// Set the LED to match the current state of the caps lock LED.//ROM_GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2,(ui32MsgData & HID_KEYB_CAPS_LOCK) ? GPIO_PIN_2 :0);break;}//// We ignore all other events.//default:{break;}}return(0);
}//***************************************************************************
//
// Wait for a period of time for the state to become idle.
//
// \param ui32TimeoutTick is the number of system ticks to wait before
// declaring a timeout and returning \b false.
//
// This function polls the current keyboard state for ui32TimeoutTicks system
// ticks waiting for it to become idle.If the state becomes idle, the
// function returns true.If it ui32TimeoutTicks occur prior to the state
// becoming idle, false is returned to indicate a timeout.
//
// \return Returns \b true on success or \b false on timeout.
//
//***************************************************************************
bool
WaitForSendIdle(uint_fast32_t ui32TimeoutTicks)
{uint32_t ui32Start;uint32_t ui32Now;uint32_t ui32Elapsed;ui32Start = g_ui32SysTickCount;ui32Elapsed = 0;while(ui32Elapsed < ui32TimeoutTicks){//// Is the keyboard is idle, return immediately.//if(g_eKeyboardState == STATE_IDLE){return(true);}//// Determine how much time has elapsed since we started waiting.This// should be safe across a wrap of g_ui32SysTickCount.//ui32Now = g_ui32SysTickCount;ui32Elapsed = ((ui32Start < ui32Now) ? (ui32Now - ui32Start) :(((uint32_t)0xFFFFFFFF - ui32Start) + ui32Now + 1));}//// If we get here, we timed out so return a bad return code to let the// caller know.//return(false);
}//*****************************************************************************
//
// Sends a string of characters via the USB HID keyboard interface.
//
//*****************************************************************************
void
SendString(char *pcStr)
{uint32_t ui32Char;//// Loop while there are more characters in the string.//while(*pcStr){//// Get the next character from the string.//ui32Char = *pcStr++;//// Skip this character if it is a non-printable character.//if((ui32Char < ' ') || (ui32Char > '~')){continue;}//// Convert the character into an index into the keyboard usage code// table.//ui32Char -= ' ';//// Send the key press message.//g_eKeyboardState = STATE_SENDING;if(USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice,g_ppi8KeyUsageCodes[ui32Char][0],g_ppi8KeyUsageCodes[ui32Char][1],true) != KEYB_SUCCESS){return;}//// Wait until the key press message has been sent.//if(!WaitForSendIdle(MAX_SEND_DELAY)){g_bConnected = 0;return;}//// Send the key release message.//g_eKeyboardState = STATE_SENDING;if(USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice,0, g_ppi8KeyUsageCodes[ui32Char][1],false) != KEYB_SUCCESS){return;}//// Wait until the key release message has been sent.//if(!WaitForSendIdle(MAX_SEND_DELAY)){g_bConnected = 0;return;}}
}//*****************************************************************************
//
// This is the interrupt handler for the SysTick interrupt.It is used to
// update our local tick count which, in turn, is used to check for transmit
// timeouts.
//
//*****************************************************************************
void
SysTickIntHandler(void)
{g_ui32SysTickCount++;
}//*****************************************************************************
//
// This is the main loop that runs the application.
//
//*****************************************************************************
int
main(void)
{uint_fast32_t ui32LastTickCount;//// Enable lazy stacking for interrupt handlers.This allows floating-point// instructions to be used within interrupt handlers, but at the expense of// extra stack usage.//ROM_FPULazyStackingEnable();//// Set the clocking to run from the PLL at 50MHz.//ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);//// Enable the GPIO that is used for the on-board LED.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);ROM_GPIOPinTypeGPIOOutput(GPIO_PORTG_BASE, GPIO_PIN_2);ROM_GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, GPIO_PIN_2);//// Enable the GPIO peripheral used for USB, and configure the USB// pins.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPIOD);ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_AHB_BASE, GPIO_PIN_4 | GPIO_PIN_5);//// Initialize the buttons driver//ButtonsInit();//// Not configured initially.//g_bConnected = false;g_bSuspended = false;//bLastSuspend = false;//// Initialize the USB stack for device mode.//USBStackModeSet(0, eUSBModeDevice, 0);//// Pass our device information to the USB HID device class driver,// initialize the USB// controller and connect the device to the bus.//USBDHIDKeyboardInit(0, &g_sKeyboardDevice);//// Set the system tick to fire 100 times per second.//ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / SYSTICKS_PER_SECOND);ROM_SysTickIntEnable();ROM_SysTickEnable();//// The main loop starts here.We begin by waiting for a host connection// then drop into the main keyboard handling section.If the host// disconnects, we return to the top and wait for a new connection.//while(1){uint8_t ui8Buttons;uint8_t ui8ButtonsChanged;//// Wait here until USB device is connected to a host.//while(!g_bConnected){}//// Enter the idle state.//g_eKeyboardState = STATE_IDLE;//// Keep transferring characters from the UART to the USB host for as// long as we are connected to the host.//while(g_bConnected){//// Remember the current time.//ui32LastTickCount = g_ui32SysTickCount;//// See if the button was just pressed.//ui8Buttons = ButtonsPoll(&ui8ButtonsChanged, 0);if(BUTTON_PRESSED(ALL_BUTTONS, ui8Buttons, ui8ButtonsChanged)){//// If the bus is suspended then resume it.Otherwise, type// some "random" characters.//if(g_bSuspended){USBDHIDKeyboardRemoteWakeupRequest((void *)&g_sKeyboardDevice);}else{SendString("Make the Switch to TI Microcontrollers!");}}//// Wait for at least 1 system tick to have gone by before we poll// the buttons again.//while(g_ui32SysTickCount == ui32LastTickCount){}}}
}

xyz549040622:

回复 Sky Lau:

修改后的代码在哪呢,没看到

Sky Lau:

回复 xyz549040622:

我也看不到了,但是论坛给我发的邮件里有,再贴一遍~

问一下,如果先不在板子上实现任何按键功能,只是想让它被识别为keyboard,需要做哪些功工作?

我是把dk-tm4c123g例程里的button.h/c替换成了ek的,改了一下makefile,然后删掉关于OLED屏的处理函数,因为ek-tm4c123g上没有OLED屏。

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "grlib/grlib.h"
#include "grlib/widget.h"
#include "usblib/usblib.h"
#include "usblib/usbhid.h"
#include "usblib/device/usbdevice.h"
#include "usblib/device/usbdhid.h"
#include "usblib/device/usbdhidkeyb.h"
#include "drivers/buttons.h"
#include "usb_keyb_structs.h"//*****************************************************************************
//
//! <h1>USB HID Keyboard Device (usb_dev_keyboard)</h1>
//!
//! This example application turns the evaluation board into a USB keyboard
//! supporting the Human Interface Device class.When the push button is
//! pressed, a sequence of key presses is simulated to type a string.Care
//! should be taken to ensure that the active window can safely receive the
//! text; enter is not pressed at any point so no actions are attempted by the
//! host if a terminal window is used (for example).The status LED is used to
//! indicate the current Caps Lock state and is updated in response to any
//! other keyboard attached to the same USB host system.
//!
//! The device implemented by this application also supports USB remote wakeup
//! allowing it to request the host to reactivate a suspended bus.If the bus
//! is suspended (as indicated on the application display), pressing the
//! push button will request a remote wakeup assuming the host has not
//! specifically disabled such requests.
//
//*****************************************************************************//*****************************************************************************
//
// The system tick timer period.
//
//*****************************************************************************
#define SYSTICKS_PER_SECOND100//*****************************************************************************
//
// A mapping from the ASCII value received from the UART to the corresponding
// USB HID usage code.
//
//*****************************************************************************
static const int8_t g_ppi8KeyUsageCodes[][2] =
{{ 0, HID_KEYB_USAGE_SPACE },//0x20{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_1 },// ! 0x21{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_FQUOTE },// " 0x22{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_3 },// # 0x23{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_4 },// $ 0x24{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_5 },// % 0x25{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_7 },// & 0x26{ 0, HID_KEYB_USAGE_FQUOTE },// ' 0x27{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_9 },// ( 0x28{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_0 },// ) 0x29{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_8 },// * 0x2a{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_EQUAL },// + 0x2b{ 0, HID_KEYB_USAGE_COMMA },// , 0x2c{ 0, HID_KEYB_USAGE_MINUS },// - 0x2d{ 0, HID_KEYB_USAGE_PERIOD },// . 0x2e{ 0, HID_KEYB_USAGE_FSLASH },// / 0x2f{ 0, HID_KEYB_USAGE_0 },// 0 0x30{ 0, HID_KEYB_USAGE_1 },// 1 0x31{ 0, HID_KEYB_USAGE_2 },// 2 0x32{ 0, HID_KEYB_USAGE_3 },// 3 0x33{ 0, HID_KEYB_USAGE_4 },// 4 0x34{ 0, HID_KEYB_USAGE_5 },// 5 0x35{ 0, HID_KEYB_USAGE_6 },// 6 0x36{ 0, HID_KEYB_USAGE_7 },// 7 0x37{ 0, HID_KEYB_USAGE_8 },// 8 0x38{ 0, HID_KEYB_USAGE_9 },// 9 0x39{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_SEMICOLON }, // : 0x3a{ 0, HID_KEYB_USAGE_SEMICOLON },// ; 0x3b{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_COMMA },// < 0x3c{ 0, HID_KEYB_USAGE_EQUAL },// = 0x3d{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_PERIOD },// > 0x3e{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_FSLASH },// ? 0x3f{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_2 },// @ 0x40{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_A },// A 0x41{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_B },// B 0x42{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_C },// C 0x43{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_D },// D 0x44{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_E },// E 0x45{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_F },// F 0x46{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_G },// G 0x47{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_H },// H 0x48{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_I },// I 0x49{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_J },// J 0x4a{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_K },// K 0x4b{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_L },// L 0x4c{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_M },// M 0x4d{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_N },// N 0x4e{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_O },// O 0x4f{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_P },// P 0x50{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_Q },// Q 0x51{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_R },// R 0x52{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_S },// S 0x53{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_T },// T 0x54{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_U },// U 0x55{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_V },// V 0x56{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_W },// W 0x57{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_X },// X 0x58{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_Y },// Y 0x59{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_Z },// Z 0x5a{ 0, HID_KEYB_USAGE_LBRACKET },// [ 0x5b{ 0, HID_KEYB_USAGE_BSLASH },// \ 0x5c{ 0, HID_KEYB_USAGE_RBRACKET },// ] 0x5d{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_6 },// ^ 0x5e{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_MINUS },// _ 0x5f{ 0, HID_KEYB_USAGE_BQUOTE },// ` 0x60{ 0, HID_KEYB_USAGE_A },// a 0x61{ 0, HID_KEYB_USAGE_B },// b 0x62{ 0, HID_KEYB_USAGE_C },// c 0x63{ 0, HID_KEYB_USAGE_D },// d 0x64{ 0, HID_KEYB_USAGE_E },// e 0x65{ 0, HID_KEYB_USAGE_F },// f 0x66{ 0, HID_KEYB_USAGE_G },// g 0x67{ 0, HID_KEYB_USAGE_H },// h 0x68{ 0, HID_KEYB_USAGE_I },// i 0x69{ 0, HID_KEYB_USAGE_J },// j 0x6a{ 0, HID_KEYB_USAGE_K },// k 0x6b{ 0, HID_KEYB_USAGE_L },// l 0x6c{ 0, HID_KEYB_USAGE_M },// m 0x6d{ 0, HID_KEYB_USAGE_N },// n 0x6e{ 0, HID_KEYB_USAGE_O },// o 0x6f{ 0, HID_KEYB_USAGE_P },// p 0x70{ 0, HID_KEYB_USAGE_Q },// q 0x71{ 0, HID_KEYB_USAGE_R },// r 0x72{ 0, HID_KEYB_USAGE_S },// s 0x73{ 0, HID_KEYB_USAGE_T },// t 0x74{ 0, HID_KEYB_USAGE_U },// u 0x75{ 0, HID_KEYB_USAGE_V },// v 0x76{ 0, HID_KEYB_USAGE_W },// w 0x77{ 0, HID_KEYB_USAGE_X },// x 0x78{ 0, HID_KEYB_USAGE_Y },// y 0x79{ 0, HID_KEYB_USAGE_Z },// z 0x7a{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_LBRACKET },// { 0x7b{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_BSLASH },// | 0x7c{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_RBRACKET },// } 0x7d{ HID_KEYB_LEFT_SHIFT, HID_KEYB_USAGE_BQUOTE },// ~ 0x7e
};//*****************************************************************************
//
// This global indicates whether or not we are connected to a USB host.
//
//*****************************************************************************
volatile bool g_bConnected = false;//*****************************************************************************
//
// This global indicates whether or not the USB bus is currently in the suspend
// state.
//
//*****************************************************************************
volatile bool g_bSuspended = false;//*****************************************************************************
//
// Global system tick counter holds elapsed time since the application started
// expressed in 100ths of a second.
//
//*****************************************************************************
volatile uint32_t g_ui32SysTickCount;//*****************************************************************************
//
// The number of system ticks to wait for each USB packet to be sent before
// we assume the host has disconnected.The value 50 equates to half a second.
//
//*****************************************************************************
#define MAX_SEND_DELAY50//*****************************************************************************
//
// This global is set to true if the host sends a request to set or clear
// any keyboard LED.
//
//*****************************************************************************
volatile bool g_bDisplayUpdateRequired;//*****************************************************************************
//
// This enumeration holds the various states that the keyboard can be in during
// normal operation.
//
//*****************************************************************************
volatile enum
{//// Unconfigured.//STATE_UNCONFIGURED,//// No keys to send and not waiting on data.//STATE_IDLE,//// Waiting on data to be sent out.//STATE_SENDING
}
g_eKeyboardState = STATE_UNCONFIGURED;//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif//*****************************************************************************
//
// Handles asynchronous events from the HID keyboard driver.
//
// \param pvCBData is the event callback pointer provided during
// USBDHIDKeyboardInit().This is a pointer to our keyboard device structure
// (&g_sKeyboardDevice).
// \param ui32Event identifies the event we are being called back for.
// \param ui32MsgData is an event-specific value.
// \param pvMsgData is an event-specific pointer.
//
// This function is called by the HID keyboard driver to inform the application
// of particular asynchronous events related to operation of the keyboard HID
// device.
//
// \return Returns 0 in all cases.
//
//*****************************************************************************
uint32_t
KeyboardHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgData,void *pvMsgData)
{switch (ui32Event){//// The host has connected to us and configured the device.//case USB_EVENT_CONNECTED:{g_bConnected = true;g_bSuspended = false;break;}//// The host has disconnected from us.//case USB_EVENT_DISCONNECTED:{g_bConnected = false;break;}//// We receive this event every time the host acknowledges transmission// of a report. It is used here purely as a way of determining whether// the host is still talking to us or not.//case USB_EVENT_TX_COMPLETE:{//// Enter the idle state since we finished sending something.//g_eKeyboardState = STATE_IDLE;break;}//// This event indicates that the host has suspended the USB bus.//case USB_EVENT_SUSPEND:{g_bSuspended = true;break;}//// This event signals that the host has resumed signalling on the bus.//case USB_EVENT_RESUME:{g_bSuspended = false;break;}//// This event indicates that the host has sent us an Output or// Feature report and that the report is now in the buffer we provided// on the previous USBD_HID_EVENT_GET_REPORT_BUFFER callback.//case USBD_HID_KEYB_EVENT_SET_LEDS:{//// Set the LED to match the current state of the caps lock LED.//ROM_GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2,(ui32MsgData & HID_KEYB_CAPS_LOCK) ? GPIO_PIN_2 :0);break;}//// We ignore all other events.//default:{break;}}return(0);
}//***************************************************************************
//
// Wait for a period of time for the state to become idle.
//
// \param ui32TimeoutTick is the number of system ticks to wait before
// declaring a timeout and returning \b false.
//
// This function polls the current keyboard state for ui32TimeoutTicks system
// ticks waiting for it to become idle.If the state becomes idle, the
// function returns true.If it ui32TimeoutTicks occur prior to the state
// becoming idle, false is returned to indicate a timeout.
//
// \return Returns \b true on success or \b false on timeout.
//
//***************************************************************************
bool
WaitForSendIdle(uint_fast32_t ui32TimeoutTicks)
{uint32_t ui32Start;uint32_t ui32Now;uint32_t ui32Elapsed;ui32Start = g_ui32SysTickCount;ui32Elapsed = 0;while(ui32Elapsed < ui32TimeoutTicks){//// Is the keyboard is idle, return immediately.//if(g_eKeyboardState == STATE_IDLE){return(true);}//// Determine how much time has elapsed since we started waiting.This// should be safe across a wrap of g_ui32SysTickCount.//ui32Now = g_ui32SysTickCount;ui32Elapsed = ((ui32Start < ui32Now) ? (ui32Now - ui32Start) :(((uint32_t)0xFFFFFFFF - ui32Start) + ui32Now + 1));}//// If we get here, we timed out so return a bad return code to let the// caller know.//return(false);
}//*****************************************************************************
//
// Sends a string of characters via the USB HID keyboard interface.
//
//*****************************************************************************
void
SendString(char *pcStr)
{uint32_t ui32Char;//// Loop while there are more characters in the string.//while(*pcStr){//// Get the next character from the string.//ui32Char = *pcStr++;//// Skip this character if it is a non-printable character.//if((ui32Char < ' ') || (ui32Char > '~')){continue;}//// Convert the character into an index into the keyboard usage code// table.//ui32Char -= ' ';//// Send the key press message.//g_eKeyboardState = STATE_SENDING;if(USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice,g_ppi8KeyUsageCodes[ui32Char][0],g_ppi8KeyUsageCodes[ui32Char][1],true) != KEYB_SUCCESS){return;}//// Wait until the key press message has been sent.//if(!WaitForSendIdle(MAX_SEND_DELAY)){g_bConnected = 0;return;}//// Send the key release message.//g_eKeyboardState = STATE_SENDING;if(USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice,0, g_ppi8KeyUsageCodes[ui32Char][1],false) != KEYB_SUCCESS){return;}//// Wait until the key release message has been sent.//if(!WaitForSendIdle(MAX_SEND_DELAY)){g_bConnected = 0;return;}}
}//*****************************************************************************
//
// This is the interrupt handler for the SysTick interrupt.It is used to
// update our local tick count which, in turn, is used to check for transmit
// timeouts.
//
//*****************************************************************************
void
SysTickIntHandler(void)
{g_ui32SysTickCount++;
}//*****************************************************************************
//
// This is the main loop that runs the application.
//
//*****************************************************************************
int
main(void)
{uint_fast32_t ui32LastTickCount;//// Enable lazy stacking for interrupt handlers.This allows floating-point// instructions to be used within interrupt handlers, but at the expense of// extra stack usage.//ROM_FPULazyStackingEnable();//// Set the clocking to run from the PLL at 50MHz.//ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);//// Enable the GPIO that is used for the on-board LED.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);ROM_GPIOPinTypeGPIOOutput(GPIO_PORTG_BASE, GPIO_PIN_2);ROM_GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, GPIO_PIN_2);//// Enable the GPIO peripheral used for USB, and configure the USB// pins.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPIOD);ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_AHB_BASE, GPIO_PIN_4 | GPIO_PIN_5);//// Initialize the buttons driver//ButtonsInit();//// Not configured initially.//g_bConnected = false;g_bSuspended = false;//bLastSuspend = false;//// Initialize the USB stack for device mode.//USBStackModeSet(0, eUSBModeDevice, 0);//// Pass our device information to the USB HID device class driver,// initialize the USB// controller and connect the device to the bus.//USBDHIDKeyboardInit(0, &g_sKeyboardDevice);//// Set the system tick to fire 100 times per second.//ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / SYSTICKS_PER_SECOND);ROM_SysTickIntEnable();ROM_SysTickEnable();//// The main loop starts here.We begin by waiting for a host connection// then drop into the main keyboard handling section.If the host// disconnects, we return to the top and wait for a new connection.//while(1){uint8_t ui8Buttons;uint8_t ui8ButtonsChanged;//// Wait here until USB device is connected to a host.//while(!g_bConnected){}//// Enter the idle state.//g_eKeyboardState = STATE_IDLE;//// Keep transferring characters from the UART to the USB host for as// long as we are connected to the host.//while(g_bConnected){//// Remember the current time.//ui32LastTickCount = g_ui32SysTickCount;//// See if the button was just pressed.//ui8Buttons = ButtonsPoll(&ui8ButtonsChanged, 0);if(BUTTON_PRESSED(ALL_BUTTONS, ui8Buttons, ui8ButtonsChanged)){//这里的第一个参数原来是“SELECT_BUTTON”,但是ek上没有这个按键,//所以我改成了“ALL_BUTTONS”,不知道什么影响。。//// If the bus is suspended then resume it.Otherwise, type// some "random" characters.//if(g_bSuspended){USBDHIDKeyboardRemoteWakeupRequest((void *)&g_sKeyboardDevice);}else{SendString("Make the Switch to TI Microcontrollers!");}}//// Wait for at least 1 system tick to have gone by before we poll// the buttons again.//while(g_ui32SysTickCount == ui32LastTickCount){}}}
}

赞(0)
未经允许不得转载:TI中文支持网 » 新手求一个能在EK-TM4C123GXL上跑的usb_dev_keyboard例程
分享到: 更多 (0)