如题。
本人纯新手,需要将EK-TM4C123GXL模拟成usb_keyboard,哪位大神有例程吗>_<
在ek-lm系列里有这个例程,移植起来麻烦吗?求解~
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
如题。
本人纯新手,需要将EK-TM4C123GXL模拟成usb_keyboard,哪位大神有例程吗>_<
在ek-lm系列里有这个例程,移植起来麻烦吗?求解~
两个板子用的库的版本是一样的,所以只要把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_SECOND 100
//*****************************************************************************
//
// 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_DELAY 50
//*****************************************************************************
//
// 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)
{
}
}
}
}
我也看不到了,但是论坛给我发的邮件里有,再贴一遍~
问一下,如果先不在板子上实现任何按键功能,只是想让它被识别为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_SECOND 100
//*****************************************************************************
//
// 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_DELAY 50
//*****************************************************************************
//
// 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)
{
}
}
}
}