make keyboard device work with lpc1347

This commit is contained in:
hathach 2012-11-28 11:53:23 +07:00
parent a5eecb4055
commit 851f5bfd06
12 changed files with 909 additions and 22 deletions

View File

@ -35,6 +35,7 @@
<option id="gnu.c.compiler.option.misc.other.204394496" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections" valueType="string"/>
<option id="gnu.c.compiler.option.include.paths.1207481236" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/CMSISv2p10_LPC13Uxx/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/LPC13Uxx_DriverLib/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tinyusb/tinyusb}&quot;"/>
</option>
<option id="gnu.c.compiler.option.include.files.318820756" name="Include files (-include)" superClass="gnu.c.compiler.option.include.files"/>
@ -59,10 +60,12 @@
</option>
<option id="gnu.c.link.option.paths.1465143173" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/CMSISv2p10_LPC13Uxx/Debug}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/LPC13Uxx_DriverLib/Debug}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tinyusb/Debug}&quot;"/>
</option>
<option id="gnu.c.link.option.libs.447978281" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="CMSISv2p10_LPC13Uxx"/>
<listOptionValue builtIn="false" value="LPC13Uxx_DriverLib"/>
<listOptionValue builtIn="false" value="tinyusb"/>
</option>
<option id="com.crt.advproject.link.gcc.hdrlib.1111642583" name="Use C library" superClass="com.crt.advproject.link.gcc.hdrlib" value="com.crt.advproject.gcc.link.hdrlib.codered.nohost" valueType="enumerated"/>

View File

@ -4,6 +4,7 @@
<comment></comment>
<projects>
<project>CMSISv2p10_LPC13Uxx</project>
<project>LPC13Uxx_DriverLib</project>
<project>tinyusb</project>
</projects>
<buildSpec>

View File

@ -37,8 +37,8 @@
#include "descriptors.h"
#ifdef CFG_USB_HID_KEYBOARD
ALIGNED(4) const uint8_t HID_KeyboardReportDescriptor[] = {
#ifdef CFG_CLASS_HID_KEYBOARD
ATTR_ALIGNED(4) const uint8_t HID_KeyboardReportDescriptor[] = {
HID_UsagePage ( HID_USAGE_PAGE_GENERIC ),
HID_Usage ( HID_USAGE_GENERIC_KEYBOARD ),
HID_Collection ( HID_Application ),
@ -81,7 +81,7 @@ ALIGNED(4) const uint8_t HID_KeyboardReportDescriptor[] = {
#endif
#ifdef CFG_USB_HID_MOUSE
ALIGNED(4) const uint8_t HID_MouseReportDescriptor[] = {
ATTR_ALIGNED(4) const uint8_t HID_MouseReportDescriptor[] = {
HID_UsagePage ( HID_USAGE_PAGE_GENERIC ),
HID_Usage ( HID_USAGE_GENERIC_MOUSE ),
HID_Collection ( HID_Application ),
@ -119,7 +119,7 @@ ALIGNED(4) const uint8_t HID_MouseReportDescriptor[] = {
#endif
/* USB Standard Device Descriptor */
ALIGNED(4) const USB_DEVICE_DESCRIPTOR USB_DeviceDescriptor =
ATTR_ALIGNED(4) const USB_DEVICE_DESCRIPTOR USB_DeviceDescriptor =
{
.bLength = sizeof(USB_DEVICE_DESCRIPTOR),
.bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE,
@ -153,7 +153,7 @@ ALIGNED(4) const USB_DEVICE_DESCRIPTOR USB_DeviceDescriptor =
.bNumConfigurations = 0x01
};
ALIGNED(4) const USB_FS_CONFIGURATION_DESCRIPTOR USB_FsConfigDescriptor =
ATTR_ALIGNED(4) const USB_FS_CONFIGURATION_DESCRIPTOR USB_FsConfigDescriptor =
{
.Config =
{
@ -276,7 +276,7 @@ ALIGNED(4) const USB_FS_CONFIGURATION_DESCRIPTOR USB_FsConfigDescriptor =
},
#endif
#ifdef CFG_USB_HID_KEYBOARD
#ifdef CFG_CLASS_HID_KEYBOARD
///// USB HID Keyboard interface
.HID_KeyboardInterface =
{
@ -358,7 +358,7 @@ ALIGNED(4) const USB_FS_CONFIGURATION_DESCRIPTOR USB_FsConfigDescriptor =
.ConfigDescTermination = 0,
};
ALIGNED(4) const USB_STR_DESCRIPTOR USB_StringDescriptor =
ATTR_ALIGNED(4) const USB_STR_DESCRIPTOR USB_StringDescriptor =
{
.LangID = { .bLength = 0x04, .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
.strLangID= {0x0409}, // US English

View File

@ -88,7 +88,7 @@ typedef PRE_PACK struct POST_PACK _USB_INTERFACE_ASSOCIATION_DESCRIPTOR
///////////////////////////////////////////////////////////////////////
// Interface Assosication Descriptor if device is CDC + other class
#define IAD_DESC_REQUIRED ( defined(CFG_USB_CDC) && (defined(CFG_USB_HID_KEYBOARD) || defined(CFG_USB_HID_MOUSE)) )
#define IAD_DESC_REQUIRED ( defined(CFG_USB_CDC) && (CLASS_HID) )
#ifdef CFG_USB_CDC
#define INTERFACES_OF_CDC 2
@ -96,7 +96,7 @@ typedef PRE_PACK struct POST_PACK _USB_INTERFACE_ASSOCIATION_DESCRIPTOR
#define INTERFACES_OF_CDC 0
#endif
#ifdef CFG_USB_HID_KEYBOARD
#ifdef CFG_CLASS_HID_KEYBOARD
#define INTERFACES_OF_HID_KEYBOARD 1
#else
#define INTERFACES_OF_HID_KEYBOARD 0
@ -157,7 +157,7 @@ typedef struct
USB_ENDPOINT_DESCRIPTOR CDC_DataInEndpoint;
#endif
#ifdef CFG_USB_HID_KEYBOARD
#ifdef CFG_CLASS_HID_KEYBOARD
//Keyboard HID Interface
USB_INTERFACE_DESCRIPTOR HID_KeyboardInterface;
HID_DESCRIPTOR HID_KeyboardHID;

View File

@ -13,12 +13,47 @@ __CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
int main(void)
{
uint32_t currentSecond, lastSecond;
currentSecond = lastSecond = 0;
SystemInit();
systickInit(1);
GPIOInit();
#define CFG_LED_PORT (0)
#define CFG_LED_PIN (7)
#define CFG_LED_ON (1)
#define CFG_LED_OFF (0)
GPIOSetDir(CFG_LED_PORT, CFG_LED_PIN, 1);
LPC_GPIO->CLR[CFG_LED_PORT] = (1 << CFG_LED_PIN);
tusb_init();
while (1)
{
currentSecond = systickGetSecondsActive();
if (currentSecond != lastSecond)
{
/* Toggle LED once per second */
lastSecond = currentSecond;
GPIOSetBitValue(CFG_LED_PORT, CFG_LED_PIN, lastSecond % 2);
#if !defined(CFG_USB_CDC)
if (usb_isConfigured())
{
#ifdef CFG_CLASS_HID_KEYBOARD
uint8_t keys[6] = {HID_USAGE_KEYBOARD_aA};
usb_hid_keyboard_sendKeys(0x00, keys, 1);
#endif
#ifdef CFG_USB_HID_MOUSE
usb_hid_mouse_send(0, 10, 10);
#endif
}
#endif
}
}
return 0;

337
tinyusb/class/hid.c Normal file
View File

@ -0,0 +1,337 @@
/*
* hid.c
*
* Created on: Nov 27, 2012
* Author: hathach (thachha@live.com)
*/
/*
* Software License Agreement (BSD License)
* Copyright (c) 2012, hathach (thachha@live.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the tiny usb stack.
*/
#include "hid.h"
//#include "../systick/systick.h"
#ifdef CLASS_HID
#ifdef CFG_CLASS_HID_KEYBOARD
USB_HID_KeyboardReport_t hid_keyboard_report;
volatile static bool bKeyChanged = false;
#endif
#ifdef CFG_USB_HID_MOUSE
USB_HID_MouseReport_t hid_mouse_report;
volatile static bool bMouseChanged = false;
#endif
/**************************************************************************/
/*!
@brief Handler for HID_GetReport in the USB ROM driver
*/
/**************************************************************************/
ErrorCode_t HID_GetReport( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* plength)
{
USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*) hHid;
/* ReportID = SetupPacket.wValue.WB.L; */
if (pSetup->wValue.WB.H == HID_REPORT_INPUT)
return (ERR_USBD_STALL); /* Not Supported */
switch (pHidCtrl->protocol)
{
#ifdef CFG_CLASS_HID_KEYBOARD
case HID_PROTOCOL_KEYBOARD:
*pBuffer = (uint8_t*) &hid_keyboard_report;
*plength = sizeof(USB_HID_KeyboardReport_t);
if (!bKeyChanged)
{
memset(pBuffer, 0, *plength);
}
bKeyChanged = false;
break;
#endif
#ifdef CFG_USB_HID_MOUSE
case HID_PROTOCOL_MOUSE:
*pBuffer = (uint8_t*) &hid_mouse_report;
*plength = sizeof(USB_HID_MouseReport_t);
if (!bMouseChanged)
{
memset(pBuffer, 0, *plength);
}
bMouseChanged = false;
break;
#endif
default:
break;
}
return (LPC_OK);
}
/**************************************************************************/
/*!
@brief Handler for HIS_SetReport in the USB ROM driver
*/
/**************************************************************************/
ErrorCode_t HID_SetReport( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length)
{
/* we will reuse standard EP0Buf */
if (length == 0)
return LPC_OK;
/* ReportID = SetupPacket.wValue.WB.L; */
if (pSetup->wValue.WB.H != HID_REPORT_OUTPUT)
return (ERR_USBD_STALL); /* Not Supported */
return (LPC_OK);
}
/**************************************************************************/
/*!
@brief HID endpoint in handler for the USB ROM driver
*/
/**************************************************************************/
ErrorCode_t HID_EpIn_Hdlr (USBD_HANDLE_T hUsb, void* data, uint32_t event)
{
if (USB_EVT_IN == event)
{
USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*)data;
switch(pHidCtrl->protocol)
{
#ifdef CFG_CLASS_HID_KEYBOARD
case HID_PROTOCOL_KEYBOARD:
if (!bKeyChanged)
{
memset(&hid_keyboard_report, 0, sizeof(USB_HID_KeyboardReport_t));
}
USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, (uint8_t*) &hid_keyboard_report, sizeof(USB_HID_KeyboardReport_t));
bKeyChanged = false;
break;
#endif
#ifdef CFG_USB_HID_MOUSE
case HID_PROTOCOL_MOUSE:
if (!bMouseChanged)
{
memset(&hid_mouse_report, 0, sizeof(USB_HID_MouseReport_t));
}
USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, (uint8_t*) &hid_mouse_report, sizeof(USB_HID_MouseReport_t));
bMouseChanged = false;
break;
#endif
default:
break;
}
}
return LPC_OK;
}
/**************************************************************************/
/*!
@brief HID endpoint out handler for the USB ROM driver
*/
/**************************************************************************/
ErrorCode_t HID_EpOut_Hdlr (USBD_HANDLE_T hUsb, void* data, uint32_t event)
{
if (USB_EVT_OUT == event)
{
// not used yet
// uint8_t outreport[8];
// USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*)data;
// USBD_API->hw->ReadEP(hUsb, pHidCtrl->epout_adr, outreport);
}
return LPC_OK;
}
/**************************************************************************/
/*!
@brief Initialises USB HID using the ROM based drivers
*/
/**************************************************************************/
ErrorCode_t usb_hid_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const *const pIntfDesc, uint8_t const * const pHIDReportDesc, uint32_t ReportDescLength, uint32_t* mem_base, uint32_t* mem_size)
{
USB_HID_REPORT_T reports_data =
{
.desc = (uint8_t*) pHIDReportDesc,
.len = ReportDescLength,
.idle_time = 0,
};
USBD_HID_INIT_PARAM_T hid_param =
{
.mem_base = *mem_base,
.mem_size = *mem_size,
.intf_desc = (uint8_t*)pIntfDesc,
.report_data = &reports_data,
.max_reports = 1,
/* user defined functions */
.HID_GetReport = HID_GetReport,
.HID_SetReport = HID_SetReport,
.HID_EpIn_Hdlr = HID_EpIn_Hdlr,
.HID_EpOut_Hdlr = HID_EpOut_Hdlr
};
ASSERT( (pIntfDesc != NULL) && (pIntfDesc->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE), ERR_FAILED);
ASSERT_STATUS( USBD_API->hid->init(hUsb, &hid_param) );
/* update memory variables */
*mem_base = hid_param.mem_base;
*mem_size = hid_param.mem_size;
return LPC_OK;
}
/**************************************************************************/
/*!
*/
/**************************************************************************/
ErrorCode_t usb_hid_configured(USBD_HANDLE_T hUsb)
{
#ifdef CFG_CLASS_HID_KEYBOARD
USBD_API->hw->WriteEP(hUsb , HID_KEYBOARD_EP_IN , (uint8_t* ) &hid_keyboard_report , sizeof(USB_HID_KeyboardReport_t) ); // initial packet for IN endpoint , will not work if omitted
#endif
#ifdef CFG_USB_HID_MOUSE
USBD_API->hw->WriteEP(hUsb , HID_MOUSE_EP_IN , (uint8_t* ) &hid_mouse_report , sizeof(USB_HID_MouseReport_t) ); // initial packet for IN endpoint, will not work if omitted
#endif
return LPC_OK;
}
#ifdef CFG_CLASS_HID_KEYBOARD
/**************************************************************************/
/*!
@brief Send the supplied key codes out via HID USB keyboard emulation
@param[in] modifier
KB modifier code bits (see USB_HID_KB_KEYMODIFIER_CODE)
@param[in] keycodes
A buffer containing up to six keycodes
@param[in] numkey
The number of keys to send (max 6)
@note Note that for HID KBs, letter codes are not case sensitive. To
create an upper-case letter, you need to include the correct
KB modifier code(s), for ex: (1 << HID_KEYMODIFIER_LEFTSHIFT)
@section EXAMPLE
@code
// Send an unmodified 'a' character
if (usb_isConfigured())
{
uint8_t keys[6] = {HID_USAGE_KEYBOARD_aA};
usb_hid_keyboard_sendKeys(0x00, keys, 1);
}
// Send Windows + 'e' (shortcut for 'explorer.exe')
if (usb_isConfigured())
{
uint8_t keys[6] = {HID_USAGE_KEYBOARD_aA + 'e' - 'a'};
usb_hid_keyboard_sendKeys((1<<HID_KEYMODIFIER_LEFTGUI), keys, 1);
}
@endcode
*/
/**************************************************************************/
ErrorCode_t usb_hid_keyboard_sendKeys(uint8_t modifier, uint8_t keycodes[], uint8_t numkey)
{
uint32_t start_time = systickGetSecondsActive();
while (bKeyChanged) // TODO blocking while previous key has yet sent - can use fifo to improve this
{
ASSERT_MESSAGE(systickGetSecondsActive() - start_time < 5, ERR_FAILED, "HID Keyboard Timeout");
}
ASSERT(keycodes && numkey && numkey <=6, ERR_FAILED);
hid_keyboard_report.Modifier = modifier;
memset(hid_keyboard_report.KeyCode, 0, 6);
memcpy(hid_keyboard_report.KeyCode, keycodes, numkey);
bKeyChanged = true;
return LPC_OK;
}
#endif
#ifdef CFG_USB_HID_MOUSE
/**************************************************************************/
/*!
@brief Send the supplied mouse event out via HID USB mouse emulation
@param[in] buttons
Indicate which button(s) are being pressed (see
USB_HID_MOUSE_BUTTON_CODE)
@param[in] x
Position adjustment on the X scale
@param[in] y
Position adjustment on the Y scale
@section EXAMPLE
@code
if (usb_isConfigured())
{
// Move the mouse +10 in the X direction and + 10 in the Y direction
usb_hid_mouse_send(0x00, 10, 10);
}
@endcode
*/
/**************************************************************************/
ErrorCode_t usb_hid_mouse_send(uint8_t buttons, int8_t x, int8_t y)
{
uint32_t start_time = systickGetSecondsActive();
while (bMouseChanged) // TODO Block while previous key hasn't been sent - can use fifo to improve this
{
ASSERT_MESSAGE(systickGetSecondsActive() - start_time < 5, ERR_FAILED, "HID Mouse Timeout");
}
hid_mouse_report.Button = buttons;
hid_mouse_report.X = x;
hid_mouse_report.Y = y;
bMouseChanged = true;
return LPC_OK;
}
#endif
#endif

142
tinyusb/class/hid.h Normal file
View File

@ -0,0 +1,142 @@
/*
* hid.h
*
* Created on: Nov 27, 2012
* Author: hathach (thachha@live.com)
*/
/*
* Software License Agreement (BSD License)
* Copyright (c) 2012, hathach (thachha@live.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the tiny usb stack.
*/
#ifndef _TUSB_HID_H_
#define _TUSB_HID_H_
#ifdef __cplusplus
extern "C" {
#endif
// TODO refractor
#include "common/common.h"
#include "device/dcd.h"
ErrorCode_t usb_hid_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const *const pIntfDesc, uint8_t const * const pHIDReportDesc, uint32_t ReportDescLength, uint32_t* mem_base, uint32_t* mem_size);
ErrorCode_t usb_hid_configured(USBD_HANDLE_T hUsb);
ErrorCode_t usb_hid_keyboard_sendKeys(uint8_t modifier, uint8_t keycodes[], uint8_t numkey);
ErrorCode_t usb_hid_mouse_send(uint8_t buttons, int8_t x, int8_t y);
/** \brief Standard HID Boot Protocol Mouse Report.
*
* Type define for a standard Boot Protocol Mouse report
*/
typedef PRE_PACK struct
{
uint8_t Button; /**< Button mask for currently pressed buttons in the mouse. */
int8_t X; /**< Current delta X movement of the mouse. */
int8_t Y; /**< Current delta Y movement on the mouse. */
} POST_PACK USB_HID_MouseReport_t;
/** \brief Standard HID Boot Protocol Keyboard Report.
*
* Type define for a standard Boot Protocol Keyboard report
*/
typedef PRE_PACK struct
{
uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of HID_KEYBOARD_MODIFER_* masks). */
uint8_t Reserved; /**< Reserved for OEM use, always set to 0. */
uint8_t KeyCode[6]; /**< Key codes of the currently pressed keys. */
} POST_PACK USB_HID_KeyboardReport_t;
/* Button codes for HID mouse */
enum USB_HID_MOUSE_BUTTON_CODE
{
HID_MOUSEBUTTON_RIGHT = 0,
HID_MOUSEBUTTON_LEFT = 1,
HID_MOUSEBUTTON_MIDDLE = 2
};
/* KB modifier codes for HID KB */
enum USB_HID_KB_KEYMODIFIER_CODE
{
HID_KEYMODIFIER_LEFTCTRL = 0,
HID_KEYMODIFIER_LEFTSHIFT,
HID_KEYMODIFIER_LEFTALT,
HID_KEYMODIFIER_LEFTGUI,
HID_KEYMODIFIER_RIGHTCTRL,
HID_KEYMODIFIER_RIGHTSHIFT,
HID_KEYMODIFIER_RIGHTALT,
HID_KEYMODIFIER_RIGHTGUI
};
enum USB_HID_LOCAL_CODE
{
HID_Local_NotSupported = 0,
HID_Local_Arabic,
HID_Local_Belgian,
HID_Local_Canadian_Bilingual,
HID_Local_Canadian_French,
HID_Local_Czech_Republic,
HID_Local_Danish,
HID_Local_Finnish,
HID_Local_French,
HID_Local_German,
HID_Local_Greek,
HID_Local_Hebrew,
HID_Local_Hungary,
HID_Local_International,
HID_Local_Italian,
HID_Local_Japan_Katakana,
HID_Local_Korean,
HID_Local_Latin_American,
HID_Local_Netherlands_Dutch,
HID_Local_Norwegian,
HID_Local_Persian_Farsi,
HID_Local_Poland,
HID_Local_Portuguese,
HID_Local_Russia,
HID_Local_Slovakia,
HID_Local_Spanish,
HID_Local_Swedish,
HID_Local_Swiss_French,
HID_Local_Swiss_German,
HID_Local_Switzerland,
HID_Local_Taiwan,
HID_Local_Turkish_Q,
HID_Local_UK,
HID_Local_US,
HID_Local_Yugoslavia,
HID_Local_Turkish_F
};
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_HID_H__ */

View File

@ -51,7 +51,7 @@
#include "errors.h"
//#if ( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG )
#if 1
#if 1 // TODO refractor ASSERT
#define PRINTF_LOCATION(mess) printf("Assert: %s at line %d: %s\n", __func__, __LINE__, mess)
#else
#define PRINTF_LOCATION(mess)

212
tinyusb/common/fifo.c Normal file
View File

@ -0,0 +1,212 @@
/*
* fifo.c
*
* Created on: Nov 27, 2012
* Author: hathach (thachha@live.com)
*/
/*
* Software License Agreement (BSD License)
* Copyright (c) 2012, hathach (thachha@live.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the tiny usb stack.
*/
#include "fifo.h"
/**************************************************************************/
/*!
@brief Disables the IRQ specified in the FIFO's 'irq' field
to prevent reads/write issues with interrupts
@param[in] f
Pointer to the FIFO that should be protected
*/
/**************************************************************************/
static inline void mutex_lock (fifo_t* f)
{
if (f->irq > 0)
NVIC_DisableIRQ(f->irq);
}
/**************************************************************************/
/*!
@brief Re-enables the IRQ specified in the FIFO's 'irq' field
@param[in] f
Pointer to the FIFO that should be protected
*/
/**************************************************************************/
static inline void mutex_unlock (fifo_t* f)
{
if (f->irq > 0)
NVIC_EnableIRQ(f->irq);
}
/**************************************************************************/
/*!
@brief Initialises the FIFO buffer
@param[in] f
Pointer to the fifo_t object to intiialize
@param[in] buffer
Pointer to the buffer's location in memory
@param[in] size
The buffer size in bytes
@param[in] overwritable
Set to TRUE is the FIFO is overwritable when the FIFO
is full (the first element will be overwritten)
@param[in] irq
The IRQ number to disable for MUTEX protection.
Set the -1 if not required.
*/
/**************************************************************************/
void fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable, IRQn_Type irq)
{
f->buf = buffer;
f->size = size;
f->rd_ptr = f->wr_ptr = f->len = 0;
f->overwritable = overwritable;
f->irq = irq;
}
/**************************************************************************/
/*!
@brief Read one byte out of the RX buffer.
This function will return the byte located at the array index of the
read pointer, and then increment the read pointer index. If the read
pointer exceeds the maximum buffer size, it will roll over to zero.
@param[in] f
Pointer to the FIFO buffer to manipulate
@param[in] data
Pointer to the place holder for data read from the buffer
@returns TRUE if the queue is not empty
*/
/**************************************************************************/
bool fifo_read(fifo_t* f, uint8_t *data)
{
if (fifo_isEmpty(f))
return false;
mutex_lock(f);
*data = f->buf[f->rd_ptr];
f->rd_ptr = (f->rd_ptr + 1) % f->size;
f->len--;
mutex_unlock(f);
return true;
}
/**************************************************************************/
/*!
@brief Read a byte array from FIFO
@param[in] f
Pointer to the FIFO buffer to manipulate
@param[in] rx
Pointer to the place holder for data read from the buffer
@param[in] maxlen
The maximum number of bytes to read from the FIFO
@returns The actual number of bytes read from the FIFO
*/
/**************************************************************************/
uint16_t fifo_readArray(fifo_t* f, uint8_t* rx, uint16_t maxlen)
{
uint16_t len = 0;
while ( len < maxlen && fifo_read(f, rx) )
{
len++;
rx++;
}
return len;
}
/**************************************************************************/
/*!
@brief Write one byte into the RX buffer.
This function will write one byte into the array index specified by
the write pointer and increment the write index. If the write index
exceeds the max buffer size, then it will roll over to zero.
@param[in] f
Pointer to the FIFO buffer to manipulate
@param[in] data
The byte to add to the FIFO
@returns TRUE if the data was written to the FIFO (overwrittable
FIFO will always return TRUE)
*/
/**************************************************************************/
bool fifo_write(fifo_t* f, uint8_t data)
{
if ( fifo_isFull(f) && f->overwritable == false)
return false;
mutex_lock(f);
f->buf[f->wr_ptr] = data;
f->wr_ptr = (f->wr_ptr + 1) % f->size;
if (fifo_isFull(f))
{
f->rd_ptr = f->wr_ptr; // keep the full state (rd == wr && len = size)
}else
{
f->len++;
}
mutex_unlock(f);
return true;
}
/**************************************************************************/
/*!
@brief Clear the fifo read and write pointers and set length to zero
@param[in] f
Pointer to the FIFO buffer to manipulate
*/
/**************************************************************************/
void fifo_clear(fifo_t *f)
{
mutex_lock(f);
f->rd_ptr = 0;
f->wr_ptr = 0;
f->len = 0;
mutex_unlock(f);
}

76
tinyusb/common/fifo.h Normal file
View File

@ -0,0 +1,76 @@
/*
* fifo.h
*
* Created on: Nov 27, 2012
* Author: hathach (thachha@live.com)
*/
/*
* Software License Agreement (BSD License)
* Copyright (c) 2012, hathach (thachha@live.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the tiny usb stack.
*/
#ifndef _TUSB_FIFO_H_
#define _TUSB_FIFO_H_
#include "common/common.h"
/* ToDo: Describe each field in fifo_t */
typedef struct _fifo_t
{
uint8_t* buf;
uint16_t size;
volatile uint16_t len;
volatile uint16_t wr_ptr;
volatile uint16_t rd_ptr;
bool overwritable;
IRQn_Type irq;
} fifo_t;
void fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable, IRQn_Type irq);
bool fifo_write(fifo_t* f, uint8_t data);
bool fifo_read(fifo_t* f, uint8_t *data);
uint16_t fifo_readArray(fifo_t* f, uint8_t * rx, uint16_t maxlen);
void fifo_clear(fifo_t*);
static inline bool fifo_isEmpty(fifo_t* f)
{
return (f->len == 0);
}
static inline bool fifo_isFull(fifo_t* f)
{
return (f->len == f->size);
}
static inline uint16_t fifo_getLength(fifo_t* f)
{
return f->len;
}
#endif /* _TUSB_FIFO_H_ */

View File

@ -40,20 +40,58 @@
// TODO refractor later
#include "descriptors.h"
#define USB_ROM_SIZE (1024*2)
uint8_t usb_RomDriver_buffer[USB_ROM_SIZE]ALIGNED(2048) /*__BSS(RAM2)*/;
USBD_HANDLE_T g_hUsb;
volatile static bool isConfigured = false;
/**************************************************************************/
/*!
@brief Handler for the USB Configure Event
*/
/**************************************************************************/
ErrorCode_t USB_Configure_Event (USBD_HANDLE_T hUsb)
{
USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb;
if (pCtrl->config_value)
{
#if defined(CLASS_HID)
ASSERT_STATUS( usb_hid_configured(hUsb) );
#endif
#ifdef CFG_USB_CDC
ASSERT_STATUS( usb_cdc_configured(hUsb) );
#endif
}
isConfigured = true;
return LPC_OK;
}
/**************************************************************************/
/*!
@brief Handler for the USB Reset Event
*/
/**************************************************************************/
ErrorCode_t USB_Reset_Event (USBD_HANDLE_T hUsb)
{
isConfigured = false;
return LPC_OK;
}
void dcd_init()
{
/* ROM DRIVER INIT */
/* ROM DRIVER INIT */
USBD_API_INIT_PARAM_T usb_param =
{
// .usb_reg_base = LPC_USB_BASE,
// .max_num_ep = USB_MAX_EP_NUM,
// .mem_base = (uint32_t) usb_RomDriver_buffer,
// .mem_size = USB_ROM_SIZE, //USBD_API->hw->GetMemSize()
//
// .USB_Configure_Event = USB_Configure_Event,
// .USB_Reset_Event = USB_Reset_Event
.usb_reg_base = LPC_USB_BASE,
.max_num_ep = USB_MAX_EP_NUM,
.mem_base = (uint32_t) usb_RomDriver_buffer,
.mem_size = USB_ROM_SIZE, //USBD_API->hw->GetMemSize()
.USB_Configure_Event = USB_Configure_Event,
.USB_Reset_Event = USB_Reset_Event
};
USB_CORE_DESCS_T DeviceDes =
@ -65,7 +103,50 @@ void dcd_init()
.device_qualifier = NULL
};
USBD_HANDLE_T g_hUsb;
/* Start USB hardware initialisation */
ASSERT_STATUS(USBD_API->hw->Init(&g_hUsb, &DeviceDes, &usb_param));
/* Initialise the class driver(s) */
#ifdef CFG_USB_CDC
ASSERT_STATUS( usb_cdc_init(g_hUsb, &USB_FsConfigDescriptor.CDC_CCI_Interface,
&USB_FsConfigDescriptor.CDC_DCI_Interface, &usb_param.mem_base, &usb_param.mem_size) );
#endif
#ifdef CFG_CLASS_HID_KEYBOARD
ASSERT_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_KeyboardInterface ,
HID_KeyboardReportDescriptor, USB_FsConfigDescriptor.HID_KeyboardHID.DescriptorList[0].wDescriptorLength,
&usb_param.mem_base , &usb_param.mem_size) );
#endif
#ifdef CFG_USB_HID_MOUSE
ASSERT_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_MouseInterface ,
HID_MouseReportDescriptor, USB_FsConfigDescriptor.HID_MouseHID.DescriptorList[0].wDescriptorLength,
&usb_param.mem_base , &usb_param.mem_size) );
#endif
/* Enable the USB interrupt */
NVIC_EnableIRQ(USB_IRQ_IRQn);
/* Perform USB soft connect */
USBD_API->hw->Connect(g_hUsb, 1);
}
/**************************************************************************/
/*!
@brief Indicates whether USB is configured or not
*/
/**************************************************************************/
bool usb_isConfigured(void)
{
return isConfigured;
}
/**************************************************************************/
/*!
@brief Redirect the USB IRQ handler to the ROM handler
*/
/**************************************************************************/
void USB_IRQHandler(void)
{
USBD_API->hw->ISR(g_hUsb);
}

View File

@ -47,9 +47,9 @@
#define CFG_TUSB_HOST
#define CFG_TUSB_DEVICE
#define CFG_USB_HID_KEYBOARD
#define CFG_CLASS_HID_KEYBOARD
#define CLASS_HID (defined CFG_USB_HID_KEYBOARD)
#define CLASS_HID (defined CFG_CLASS_HID_KEYBOARD)
// TODO APP