如题。
本人纯新手,需要将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){}}} }