summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/device/keyboard/cr_startup_lpc13u.c354
-rw-r--r--demos/device/keyboard/descriptors.c374
-rw-r--r--demos/device/keyboard/descriptors.h184
-rw-r--r--demos/device/keyboard/main.c25
4 files changed, 937 insertions, 0 deletions
diff --git a/demos/device/keyboard/cr_startup_lpc13u.c b/demos/device/keyboard/cr_startup_lpc13u.c
new file mode 100644
index 000000000..8b5d7eebb
--- /dev/null
+++ b/demos/device/keyboard/cr_startup_lpc13u.c
@@ -0,0 +1,354 @@
+//*****************************************************************************
+// +--+
+// | ++----+
+// +-++ |
+// | |
+// +-+--+ |
+// | +--+--+
+// +----+ Copyright (c) 2012 Code Red Technologies Ltd.
+//
+// NXP LPC13U Microcontroller Startup code for use with Red Suite
+//
+// Version : 120202
+//
+// Software License Agreement
+//
+// The software is owned by Code Red Technologies and/or its suppliers, and is
+// protected under applicable copyright laws. All rights are reserved. Any
+// use in violation of the foregoing restrictions may subject the user to criminal
+// sanctions under applicable laws, as well as to civil liability for the breach
+// of the terms and conditions of this license.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
+// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
+// CODE RED TECHNOLOGIES LTD.
+//
+//*****************************************************************************
+#if defined (__cplusplus)
+#ifdef __REDLIB__
+#error Redlib does not support C++
+#else
+//*****************************************************************************
+//
+// The entry point for the C++ library startup
+//
+//*****************************************************************************
+extern "C" {
+ extern void __libc_init_array(void);
+}
+#endif
+#endif
+
+#define WEAK __attribute__ ((weak))
+#define ALIAS(f) __attribute__ ((weak, alias (#f)))
+
+// Code Red - if CMSIS is being used, then SystemInit() routine
+// will be called by startup code rather than in application's main()
+#if defined (__USE_CMSIS)
+#include "LPC13Uxx.h"
+#endif
+
+//*****************************************************************************
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+//*****************************************************************************
+//
+// Forward declaration of the default handlers. These are aliased.
+// When the application defines a handler (with the same name), this will
+// automatically take precedence over these weak definitions
+//
+//*****************************************************************************
+void ResetISR(void);
+WEAK void NMI_Handler(void);
+WEAK void HardFault_Handler(void);
+WEAK void MemManage_Handler(void);
+WEAK void BusFault_Handler(void);
+WEAK void UsageFault_Handler(void);
+WEAK void SVC_Handler(void);
+WEAK void DebugMon_Handler(void);
+WEAK void PendSV_Handler(void);
+WEAK void SysTick_Handler(void);
+WEAK void IntDefaultHandler(void);
+//*****************************************************************************
+//
+// Forward declaration of the specific IRQ handlers. These are aliased
+// to the IntDefaultHandler, which is a 'forever' loop. When the application
+// defines a handler (with the same name), this will automatically take
+// precedence over these weak definitions
+//
+//*****************************************************************************
+void PIN_INT0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT2_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT3_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT4_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT5_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT6_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PIN_INT7_IRQHandler(void) ALIAS(IntDefaultHandler);
+void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void OSTIMER_IRQHandler(void) ALIAS(IntDefaultHandler);
+void SSP1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void I2C_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CT16B0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CT16B1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CT32B0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void CT32B1_IRQHandler(void) ALIAS(IntDefaultHandler);
+void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USART_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USB_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USB_FIQHandler(void) ALIAS(IntDefaultHandler);
+void ADC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void WDT_IRQHandler(void) ALIAS(IntDefaultHandler);
+void BOD_IRQHandler(void) ALIAS(IntDefaultHandler);
+void FMC_IRQHandler(void) ALIAS(IntDefaultHandler);
+void OSCFAIL_IRQHandler(void) ALIAS(IntDefaultHandler);
+void PVTCIRCUIT_IRQHandler(void) ALIAS(IntDefaultHandler);
+void USBWakeup_IRQHandler(void) ALIAS(IntDefaultHandler);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+// __main() is the entry point for Redlib based applications
+// main() is the entry point for Newlib based applications
+//
+//*****************************************************************************
+#if defined (__REDLIB__)
+extern void __main(void);
+#endif
+extern int main(void);
+//*****************************************************************************
+//
+// External declaration for the pointer to the stack top from the Linker Script
+//
+//*****************************************************************************
+extern void _vStackTop(void);
+
+//*****************************************************************************
+#if defined (__cplusplus)
+} // extern "C"
+#endif
+//*****************************************************************************
+//
+// The vector table. Note that the proper constructs must be placed on this to
+// ensure that it ends up at physical address 0x0000.0000.
+//
+//*****************************************************************************
+extern void (* const g_pfnVectors[])(void);
+__attribute__ ((section(".isr_vector")))
+void (* const g_pfnVectors[])(void) = {
+ // Core Level - CM3
+ &_vStackTop, // The initial stack pointer
+ ResetISR, // The reset handler
+ NMI_Handler, // The NMI handler
+ HardFault_Handler, // The hard fault handler
+ MemManage_Handler, // The MPU fault handler
+ BusFault_Handler, // The bus fault handler
+ UsageFault_Handler, // The usage fault handler
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ SVC_Handler, // SVCall handler
+ DebugMon_Handler, // Debug monitor handler
+ 0, // Reserved
+ PendSV_Handler, // The PendSV handler
+ SysTick_Handler, // The SysTick handler
+
+ // LPC13U External Interrupts
+ PIN_INT0_IRQHandler, // All GPIO pin can be routed to PIN_INTx
+ PIN_INT1_IRQHandler,
+ PIN_INT2_IRQHandler,
+ PIN_INT3_IRQHandler,
+ PIN_INT4_IRQHandler,
+ PIN_INT5_IRQHandler,
+ PIN_INT6_IRQHandler,
+ PIN_INT7_IRQHandler,
+ GINT0_IRQHandler,
+ GINT1_IRQHandler, // PIO0 (0:7)
+ 0,
+ 0,
+ OSTIMER_IRQHandler,
+ 0,
+ SSP1_IRQHandler, // SSP1
+ I2C_IRQHandler, // I2C
+ CT16B0_IRQHandler, // 16-bit Timer0
+ CT16B1_IRQHandler, // 16-bit Timer1
+ CT32B0_IRQHandler, // 32-bit Timer0
+ CT32B1_IRQHandler, // 32-bit Timer1
+ SSP0_IRQHandler, // SSP0
+ USART_IRQHandler, // USART
+ USB_IRQHandler, // USB IRQ
+ USB_FIQHandler, // USB FIQ
+ ADC_IRQHandler, // A/D Converter
+ WDT_IRQHandler, // Watchdog timer
+ BOD_IRQHandler, // Brown Out Detect
+ FMC_IRQHandler, // IP2111 Flash Memory Controller
+ OSCFAIL_IRQHandler, // OSC FAIL
+ PVTCIRCUIT_IRQHandler, // PVT CIRCUIT
+ USBWakeup_IRQHandler, // USB wake up
+ 0,
+ };
+
+//*****************************************************************************
+// Functions to carry out the initialization of RW and BSS data sections. These
+// are written as separate functions rather than being inlined within the
+// ResetISR() function in order to cope with MCUs with multiple banks of
+// memory.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
+ unsigned int *pulDest = (unsigned int*) start;
+ unsigned int *pulSrc = (unsigned int*) romstart;
+ unsigned int loop;
+ for (loop = 0; loop < len; loop = loop + 4)
+ *pulDest++ = *pulSrc++;
+}
+
+__attribute__ ((section(".after_vectors")))
+void bss_init(unsigned int start, unsigned int len) {
+ unsigned int *pulDest = (unsigned int*) start;
+ unsigned int loop;
+ for (loop = 0; loop < len; loop = loop + 4)
+ *pulDest++ = 0;
+}
+
+//*****************************************************************************
+// The following symbols are constructs generated by the linker, indicating
+// the location of various points in the "Global Section Table". This table is
+// created by the linker via the Code Red managed linker script mechanism. It
+// contains the load address, execution address and length of each RW data
+// section and the execution and length of each BSS (zero initialized) section.
+//*****************************************************************************
+extern unsigned int __data_section_table;
+extern unsigned int __data_section_table_end;
+extern unsigned int __bss_section_table;
+extern unsigned int __bss_section_table_end;
+
+//*****************************************************************************
+// Reset entry point for your code.
+// Sets up a simple runtime environment and initializes the C/C++
+// library.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void
+ResetISR(void) {
+
+ //
+ // Copy the data sections from flash to SRAM.
+ //
+ unsigned int LoadAddr, ExeAddr, SectionLen;
+ unsigned int *SectionTableAddr;
+
+ // Load base address of Global Section Table
+ SectionTableAddr = &__data_section_table;
+
+ // Copy the data sections from flash to SRAM.
+ while (SectionTableAddr < &__data_section_table_end) {
+ LoadAddr = *SectionTableAddr++;
+ ExeAddr = *SectionTableAddr++;
+ SectionLen = *SectionTableAddr++;
+ data_init(LoadAddr, ExeAddr, SectionLen);
+ }
+ // At this point, SectionTableAddr = &__bss_section_table;
+ // Zero fill the bss segment
+ while (SectionTableAddr < &__bss_section_table_end) {
+ ExeAddr = *SectionTableAddr++;
+ SectionLen = *SectionTableAddr++;
+ bss_init(ExeAddr, SectionLen);
+ }
+
+#ifdef __USE_CMSIS
+ SystemInit();
+#endif
+
+#if defined (__cplusplus)
+ //
+ // Call C++ library initialisation
+ //
+ __libc_init_array();
+#endif
+
+#if defined (__REDLIB__)
+ // Call the Redlib library, which in turn calls main()
+ __main() ;
+#else
+ main();
+#endif
+ //
+ // main() shouldn't return, but if it does, we'll just enter an infinite loop
+ //
+ while (1) {
+ ;
+ }
+}
+
+//*****************************************************************************
+// Default exception handlers. Override the ones here by defining your own
+// handler routines in your application code.
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void NMI_Handler(void) {
+ while (1) {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void HardFault_Handler(void) {
+ while (1) {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void MemManage_Handler(void) {
+ while (1) {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void BusFault_Handler(void) {
+ while (1) {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void UsageFault_Handler(void) {
+ while (1) {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void SVC_Handler(void) {
+ while (1) {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void DebugMon_Handler(void) {
+ while (1) {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void PendSV_Handler(void) {
+ while (1) {
+ }
+}
+__attribute__ ((section(".after_vectors")))
+void SysTick_Handler(void) {
+ while (1) {
+ }
+}
+
+//*****************************************************************************
+//
+// Processor ends up here if an unexpected interrupt occurs or a handler
+// is not present in the application code.
+//
+//*****************************************************************************
+__attribute__ ((section(".after_vectors")))
+void IntDefaultHandler(void) {
+ //
+ // Go into an infinite loop.
+ //
+ while (1) {
+ }
+}
diff --git a/demos/device/keyboard/descriptors.c b/demos/device/keyboard/descriptors.c
new file mode 100644
index 000000000..ceb463afe
--- /dev/null
+++ b/demos/device/keyboard/descriptors.c
@@ -0,0 +1,374 @@
+/*
+ * descriptors.c
+ *
+ * Created on: Nov 26, 2012
+ * Author: hathach ([email protected])
+ */
+
+/*
+ * Software License Agreement (BSD License)
+ * Copyright (c) 2012, hathach ([email protected])
+ * 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 "descriptors.h"
+
+#ifdef CFG_USB_HID_KEYBOARD
+ALIGNED(4) const uint8_t HID_KeyboardReportDescriptor[] = {
+ HID_UsagePage ( HID_USAGE_PAGE_GENERIC ),
+ HID_Usage ( HID_USAGE_GENERIC_KEYBOARD ),
+ HID_Collection ( HID_Application ),
+ HID_UsagePage (HID_USAGE_PAGE_KEYBOARD),
+ HID_UsageMin (224 ),
+ HID_UsageMax (231 ),
+ HID_LogicalMin ( 0 ),
+ HID_LogicalMax ( 1 ),
+
+ HID_ReportCount ( 8 ), /* 8 bits */
+ HID_ReportSize ( 1 ),
+ HID_Input ( HID_Data | HID_Variable | HID_Absolute ), /* maskable modifier key */
+
+ HID_ReportCount ( 1 ),
+ HID_ReportSize (8 ),
+ HID_Input (HID_Constant ), /* reserved */
+
+ HID_UsagePage ( HID_USAGE_PAGE_LED ),
+ HID_UsageMin (1 ),
+ HID_UsageMax (5 ),
+ HID_ReportCount (5 ),
+ HID_ReportSize (1 ),
+ HID_Output ( HID_Data | HID_Variable | HID_Absolute ), /* 5-bit Led report */
+
+ HID_ReportCount ( 1 ),
+ HID_ReportSize (3 ), /* led padding */
+ HID_Output (HID_Constant ),
+
+ HID_UsagePage (HID_USAGE_PAGE_KEYBOARD),
+ HID_UsageMin (0 ),
+ HID_UsageMax (101 ),
+ HID_LogicalMin (0 ),
+ HID_LogicalMax (101 ),
+
+ HID_ReportCount (6 ),
+ HID_ReportSize (8 ),
+ HID_Input (HID_Data | HID_Array | HID_Absolute ), /* keycodes array 6 items */
+ HID_EndCollection,
+};
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+ALIGNED(4) const uint8_t HID_MouseReportDescriptor[] = {
+ HID_UsagePage ( HID_USAGE_PAGE_GENERIC ),
+ HID_Usage ( HID_USAGE_GENERIC_MOUSE ),
+ HID_Collection ( HID_Application ),
+ HID_Usage (HID_USAGE_GENERIC_POINTER),
+
+ HID_Collection ( HID_Physical ),
+ HID_UsagePage ( HID_USAGE_PAGE_BUTTON ),
+ HID_UsageMin ( 1 ),
+ HID_UsageMax ( 3 ),
+ HID_LogicalMin ( 0 ),
+ HID_LogicalMax ( 1 ),
+
+ HID_ReportCount ( 3 ), /* Left, Right and Middle mouse*/
+ HID_ReportSize ( 1 ),
+ HID_Input ( HID_Data | HID_Variable | HID_Absolute ),
+
+ HID_ReportCount ( 1 ),
+ HID_ReportSize ( 5 ),
+ HID_Input (HID_Constant ), /* reserved */
+
+ HID_UsagePage ( HID_USAGE_PAGE_GENERIC ),
+ HID_Usage ( HID_USAGE_GENERIC_X ),
+ HID_Usage ( HID_USAGE_GENERIC_Y ),
+ HID_LogicalMin ( 0x81 ), /* -127 */
+ HID_LogicalMax ( 0x7f ), /* 127 */
+
+ HID_ReportCount ( 2 ), /* X, Y position */
+ HID_ReportSize ( 8 ),
+ HID_Input ( HID_Data | HID_Variable | HID_Relative ), /* relative values */
+
+ HID_EndCollection,
+
+ HID_EndCollection,
+};
+#endif
+
+/* USB Standard Device Descriptor */
+ALIGNED(4) const USB_DEVICE_DESCRIPTOR USB_DeviceDescriptor =
+{
+ .bLength = sizeof(USB_DEVICE_DESCRIPTOR),
+ .bDescriptorType = USB_DEVICE_DESCRIPTOR_TYPE,
+ .bcdUSB = 0x0200,
+
+ #if IAD_DESC_REQUIRED
+ /* Multiple Interfaces Using Interface Association Descriptor (IAD) */
+ .bDeviceClass = USB_DEVICE_CLASS_IAD,
+ .bDeviceSubClass = USB_DEVICE_SUBCLASS_IAD,
+ .bDeviceProtocol = USB_DEVICE_PROTOCOL_IAD,
+ #elif defined CFG_USB_CDC
+ .bDeviceClass = CDC_COMMUNICATION_INTERFACE_CLASS,
+ .bDeviceSubClass = 0x00,
+ .bDeviceProtocol = 0x00,
+ #else
+ .bDeviceClass = 0x00,
+ .bDeviceSubClass = 0x00,
+ .bDeviceProtocol = 0x00,
+ #endif
+
+ .bMaxPacketSize0 = USB_MAX_PACKET0,
+
+ .idVendor = CFG_USB_VENDORID,
+ .idProduct = USB_PRODUCT_ID,
+ .bcdDevice = 0x0100,
+
+ .iManufacturer = 0x01,
+ .iProduct = 0x02,
+ .iSerialNumber = 0x03,
+
+ .bNumConfigurations = 0x01
+};
+
+ALIGNED(4) const USB_FS_CONFIGURATION_DESCRIPTOR USB_FsConfigDescriptor =
+{
+ .Config =
+ {
+ .bLength = sizeof(USB_CONFIGURATION_DESCRIPTOR),
+ .bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE,
+
+ .wTotalLength = sizeof(USB_FS_CONFIGURATION_DESCRIPTOR) - 1, // exclude termination
+ .bNumInterfaces = TOTAL_INTEFACES,
+
+ .bConfigurationValue = 1,
+ .iConfiguration = 0x00,
+ .bmAttributes = USB_CONFIG_BUS_POWERED,
+ .bMaxPower = USB_CONFIG_POWER_MA(100)
+ },
+
+ #if IAD_DESC_REQUIRED
+ // IAD points to CDC Interfaces
+ .CDC_IAD =
+ {
+ .bLength = sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR),
+ .bDescriptorType = USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE,
+
+ .bFirstInterface = 0,
+ .bInterfaceCount = 2,
+
+ .bFunctionClass = CDC_COMMUNICATION_INTERFACE_CLASS,
+ .bFunctionSubClass = CDC_ABSTRACT_CONTROL_MODEL,
+ .bFunctionProtocol = CDC_PROTOCOL_COMMON_AT_COMMANDS,
+
+ .iFunction = 0
+ },
+ #endif
+
+ #ifdef CFG_USB_CDC
+ // USB CDC Serial Interface
+ // CDC Control Interface
+ .CDC_CCI_Interface =
+ {
+ .bLength = sizeof(USB_INTERFACE_DESCRIPTOR),
+ .bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE,
+ .bInterfaceNumber = INTERFACE_INDEX_CDC,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = CDC_COMMUNICATION_INTERFACE_CLASS,
+ .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL,
+ .bInterfaceProtocol = CDC_PROTOCOL_COMMON_AT_COMMANDS,
+ .iInterface = 0x00
+ },
+
+ .CDC_Header =
+ {
+ .bFunctionLength = sizeof(CDC_HEADER_DESCRIPTOR),
+ .bDescriptorType = CDC_CS_INTERFACE,
+ .bDescriptorSubtype = CDC_HEADER,
+ .bcdCDC = 0x0120
+ },
+
+ .CDC_ACM =
+ {
+ .bFunctionLength = sizeof(CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR),
+ .bDescriptorType = CDC_CS_INTERFACE,
+ .bDescriptorSubtype = CDC_ABSTRACT_CONTROL_MANAGEMENT,
+ .bmCapabilities = 0x06 // Support Send_Break and Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State
+ },
+
+ .CDC_Union =
+ {
+ .sUnion =
+ {
+ .bFunctionLength = sizeof(CDC_UNION_1SLAVE_DESCRIPTOR),
+ .bDescriptorType = CDC_CS_INTERFACE,
+ .bDescriptorSubtype = CDC_UNION,
+ .bMasterInterface = 0
+ },
+ .bSlaveInterfaces[0] = 1
+ },
+
+ .CDC_NotificationEndpoint =
+ {
+ .bLength = sizeof(USB_ENDPOINT_DESCRIPTOR),
+ .bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE,
+ .bEndpointAddress = CDC_NOTIFICATION_EP,
+ .bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT,
+ .wMaxPacketSize = CDC_NOTIFICATION_EP_MAXPACKETSIZE,
+ .bInterval = 0xff // lowest polling rate
+ },
+
+ // CDC Data Interface
+ .CDC_DCI_Interface =
+ {
+ .bLength = sizeof(USB_INTERFACE_DESCRIPTOR),
+ .bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE,
+ .bInterfaceNumber = INTERFACE_INDEX_CDC+1,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = CDC_DATA_INTERFACE_CLASS,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0x00
+ },
+
+ .CDC_DataOutEndpoint =
+ {
+ .bLength = sizeof(USB_ENDPOINT_DESCRIPTOR),
+ .bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE,
+ .bEndpointAddress = CDC_DATA_EP_OUT,
+ .bmAttributes = USB_ENDPOINT_TYPE_BULK,
+ .wMaxPacketSize = CDC_DATA_EP_MAXPACKET_SIZE,
+ .bInterval = 0
+ },
+
+ .CDC_DataInEndpoint =
+ {
+ .bLength = sizeof(USB_ENDPOINT_DESCRIPTOR),
+ .bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE,
+ .bEndpointAddress = CDC_DATA_EP_IN,
+ .bmAttributes = USB_ENDPOINT_TYPE_BULK,
+ .wMaxPacketSize = CDC_DATA_EP_MAXPACKET_SIZE,
+ .bInterval = 0
+ },
+ #endif
+
+ #ifdef CFG_USB_HID_KEYBOARD
+ ///// USB HID Keyboard interface
+ .HID_KeyboardInterface =
+ {
+ .bLength = sizeof(USB_INTERFACE_DESCRIPTOR),
+ .bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE,
+ .bInterfaceNumber = INTERFACE_INDEX_HID_KEYBOARD,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_DEVICE_CLASS_HUMAN_INTERFACE,
+ .bInterfaceSubClass = HID_SUBCLASS_BOOT,
+ .bInterfaceProtocol = HID_PROTOCOL_KEYBOARD,
+ .iInterface = 0x00
+ },
+
+ .HID_KeyboardHID =
+ {
+ .bLength = sizeof(HID_DESCRIPTOR),
+ .bDescriptorType = HID_HID_DESCRIPTOR_TYPE,
+ .bcdHID = 0x0111,
+ .bCountryCode = HID_Local_NotSupported,
+ .bNumDescriptors = 1,
+ .DescriptorList[0] =
+ {
+ .bDescriptorType = HID_REPORT_DESCRIPTOR_TYPE,
+ .wDescriptorLength = sizeof(HID_KeyboardReportDescriptor)
+ },
+ },
+
+ .HID_KeyboardEndpoint =
+ {
+ .bLength = sizeof(USB_ENDPOINT_DESCRIPTOR),
+ .bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE,
+ .bEndpointAddress = HID_KEYBOARD_EP_IN,
+ .bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT,
+ .wMaxPacketSize = 0x08,
+ .bInterval = 0x0A
+ },
+ #endif
+
+ #ifdef CFG_USB_HID_MOUSE
+ .HID_MouseInterface =
+ {
+ .bLength = sizeof(USB_INTERFACE_DESCRIPTOR),
+ .bDescriptorType = USB_INTERFACE_DESCRIPTOR_TYPE,
+ .bInterfaceNumber = INTERFACE_INDEX_HID_MOUSE,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_DEVICE_CLASS_HUMAN_INTERFACE,
+ .bInterfaceSubClass = HID_SUBCLASS_BOOT,
+ .bInterfaceProtocol = HID_PROTOCOL_MOUSE,
+ .iInterface = 0x00
+ },
+
+ .HID_MouseHID =
+ {
+ .bLength = sizeof(HID_DESCRIPTOR),
+ .bDescriptorType = HID_HID_DESCRIPTOR_TYPE,
+ .bcdHID = 0x0111,
+ .bCountryCode = HID_Local_NotSupported,
+ .bNumDescriptors = 1,
+ .DescriptorList[0] =
+ {
+ .bDescriptorType = HID_REPORT_DESCRIPTOR_TYPE,
+ .wDescriptorLength = sizeof(HID_MouseReportDescriptor)
+ },
+ },
+
+ .HID_MouseEndpoint =
+ {
+ .bLength = sizeof(USB_ENDPOINT_DESCRIPTOR),
+ .bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE,
+ .bEndpointAddress = HID_MOUSE_EP_IN,
+ .bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT,
+ .wMaxPacketSize = 0x08,
+ .bInterval = 0x0A
+ },
+ #endif
+
+ .ConfigDescTermination = 0,
+};
+
+ALIGNED(4) const USB_STR_DESCRIPTOR USB_StringDescriptor =
+{
+ .LangID = { .bLength = 0x04, .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
+ .strLangID= {0x0409}, // US English
+
+ .Manufacturer = { .bLength = USB_STRING_LEN(sizeof(CFG_USB_STRING_MANUFACTURER)-1), .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
+ .strManufacturer = {'t', 'i', 'n', 'y', 'U', 'S', 'B'},
+
+ .Product = { .bLength = USB_STRING_LEN(sizeof(CFG_USB_STRING_PRODUCT)-1), .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
+ .strProduct = {'D', 'e', 'v', 'i', 'c', ' ', 'e', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd'},
+
+ .Serial = { .bLength = USB_STRING_LEN(USB_STRING_SERIAL_LEN), .bDescriptorType = USB_STRING_DESCRIPTOR_TYPE },
+ .strSerial = {'1', '2', '3', '4'}
+};
diff --git a/demos/device/keyboard/descriptors.h b/demos/device/keyboard/descriptors.h
new file mode 100644
index 000000000..d73f34dcd
--- /dev/null
+++ b/demos/device/keyboard/descriptors.h
@@ -0,0 +1,184 @@
+/*
+ * descriptors.h
+ *
+ * Created on: Nov 26, 2012
+ * Author: hathach ([email protected])
+ */
+
+/*
+ * Software License Agreement (BSD License)
+ * Copyright (c) 2012, hathach ([email protected])
+ * 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 _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+#include "tusb.h"
+
+#define CFG_USB_STRING_MANUFACTURER "tinyUSB"
+#define CFG_USB_STRING_PRODUCT "Device Keyboard"
+#define CFG_USB_STRING_SERIAL "1234"
+#define CFG_USB_VENDORID 0x1FC9
+
+/* USB Serial uses the MCUs unique 128-bit chip ID via an IAP call = 32 hex chars */
+#define USB_STRING_SERIAL_LEN 32
+
+#define USB_STRING_LEN(n) (2 + ((n)<<1))
+
+typedef PRE_PACK struct POST_PACK _USB_STR_DESCRIPTOR
+{
+ USB_COMMON_DESCRIPTOR LangID;
+ uint16_t strLangID[1];
+
+ USB_COMMON_DESCRIPTOR Manufacturer;
+ uint16_t strManufacturer[sizeof(CFG_USB_STRING_MANUFACTURER)-1]; // exclude null-character
+
+ USB_COMMON_DESCRIPTOR Product;
+ uint16_t strProduct[sizeof(CFG_USB_STRING_PRODUCT)-1]; // exclude null-character
+
+ USB_COMMON_DESCRIPTOR Serial;
+ uint16_t strSerial[sizeof(CFG_USB_STRING_SERIAL)-1];
+} USB_STR_DESCRIPTOR;
+
+// USB Interface Assosication Descriptor
+#define USB_DEVICE_CLASS_IAD USB_DEVICE_CLASS_MISCELLANEOUS
+#define USB_DEVICE_SUBCLASS_IAD 0x02
+#define USB_DEVICE_PROTOCOL_IAD 0x01
+
+// USB Interface Association Descriptor
+typedef PRE_PACK struct POST_PACK _USB_INTERFACE_ASSOCIATION_DESCRIPTOR
+{
+ uint8_t bLength; /**< Size of descriptor*/
+ uint8_t bDescriptorType; /**< Other_speed_Configuration Type*/
+
+ uint8_t bFirstInterface; /**< Index of the first associated interface. */
+ uint8_t bInterfaceCount; /**< Total number of associated interfaces. */
+
+ uint8_t bFunctionClass; /**< Interface class ID. */
+ uint8_t bFunctionSubClass; /**< Interface subclass ID. */
+ uint8_t bFunctionProtocol; /**< Interface protocol ID. */
+
+ uint8_t iFunction; /**< Index of the string descriptor describing the interface association. */
+} 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)) )
+
+#ifdef CFG_USB_CDC
+ #define INTERFACES_OF_CDC 2
+#else
+ #define INTERFACES_OF_CDC 0
+#endif
+
+#ifdef CFG_USB_HID_KEYBOARD
+ #define INTERFACES_OF_HID_KEYBOARD 1
+#else
+ #define INTERFACES_OF_HID_KEYBOARD 0
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+ #define INTERFACES_OF_HID_MOUSE 1
+#else
+ #define INTERFACES_OF_HID_MOUSE 0
+#endif
+
+#ifdef CFG_USB_HID_GENERIC
+ #define INTERFACES_OF_HID_GENERIC 1
+#else
+ #define INTERFACES_OF_HID_GENERIC 0
+#endif
+
+#ifdef CFG_USB_MASS_STORAGE
+ #define INTERFACES_OF_MASS_STORAGE 2
+#else
+ #define INTERFACES_OF_MASS_STORAGE 0
+#endif
+
+#define INTERFACE_INDEX_CDC 0
+#define INTERFACE_INDEX_HID_KEYBOARD (INTERFACE_INDEX_CDC + INTERFACES_OF_CDC )
+#define INTERFACE_INDEX_HID_MOUSE (INTERFACE_INDEX_HID_KEYBOARD + INTERFACES_OF_HID_KEYBOARD )
+#define INTERFACE_INDEX_HID_GENERIC (INTERFACE_INDEX_HID_MOUSE + INTERFACES_OF_HID_MOUSE )
+#define INTERFACE_INDEX_MASS_STORAGE (INTERFACE_INDEX_HID_GENERIC + INTERFACES_OF_HID_GENERIC )
+
+#define TOTAL_INTEFACES (INTERFACES_OF_CDC + INTERFACES_OF_HID_KEYBOARD + INTERFACES_OF_HID_MOUSE + INTERFACES_OF_HID_GENERIC + INTERFACES_OF_MASS_STORAGE)
+
+// Bitmap: MassStorage | Generic | Mouse | Key | CDC
+#define PRODUCTID_BITMAP(interface, n) ( (INTERFACES_OF_##interface ? 1 : 0) << (n) )
+#define USB_PRODUCT_ID (0x2000 | ( PRODUCTID_BITMAP(CDC, 0) | PRODUCTID_BITMAP(HID_KEYBOARD, 1) | PRODUCTID_BITMAP(HID_MOUSE, 2) | \
+ PRODUCTID_BITMAP(HID_GENERIC, 3) | PRODUCTID_BITMAP(MASS_STORAGE, 4) ) )
+
+///////////////////////////////////////////////////////////////////////
+typedef struct
+{
+ USB_CONFIGURATION_DESCRIPTOR Config;
+
+#if IAD_DESC_REQUIRED
+ USB_INTERFACE_ASSOCIATION_DESCRIPTOR CDC_IAD;
+#endif
+
+#ifdef CFG_USB_CDC
+ //CDC - Serial
+ //CDC Control Interface
+ USB_INTERFACE_DESCRIPTOR CDC_CCI_Interface;
+ CDC_HEADER_DESCRIPTOR CDC_Header;
+ CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR CDC_ACM;
+ CDC_UNION_1SLAVE_DESCRIPTOR CDC_Union;
+ USB_ENDPOINT_DESCRIPTOR CDC_NotificationEndpoint;
+
+ //CDC Data Interface
+ USB_INTERFACE_DESCRIPTOR CDC_DCI_Interface;
+ USB_ENDPOINT_DESCRIPTOR CDC_DataOutEndpoint;
+ USB_ENDPOINT_DESCRIPTOR CDC_DataInEndpoint;
+#endif
+
+#ifdef CFG_USB_HID_KEYBOARD
+ //Keyboard HID Interface
+ USB_INTERFACE_DESCRIPTOR HID_KeyboardInterface;
+ HID_DESCRIPTOR HID_KeyboardHID;
+ USB_ENDPOINT_DESCRIPTOR HID_KeyboardEndpoint;
+#endif
+
+#ifdef CFG_USB_HID_MOUSE
+ //Mouse HID Interface
+ USB_INTERFACE_DESCRIPTOR HID_MouseInterface;
+ HID_DESCRIPTOR HID_MouseHID;
+ USB_ENDPOINT_DESCRIPTOR HID_MouseEndpoint;
+#endif
+
+ unsigned char ConfigDescTermination;
+} USB_FS_CONFIGURATION_DESCRIPTOR;
+
+extern const USB_DEVICE_DESCRIPTOR USB_DeviceDescriptor;
+extern const USB_FS_CONFIGURATION_DESCRIPTOR USB_FsConfigDescriptor;
+extern const USB_STR_DESCRIPTOR USB_StringDescriptor;
+
+extern const uint8_t HID_KeyboardReportDescriptor[];
+extern const uint8_t HID_MouseReportDescriptor[];
+
+#endif
diff --git a/demos/device/keyboard/main.c b/demos/device/keyboard/main.c
new file mode 100644
index 000000000..3011c82c8
--- /dev/null
+++ b/demos/device/keyboard/main.c
@@ -0,0 +1,25 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cr_section_macros.h>
+#include <NXP/crp.h>
+#include "tusb.h"
+
+// Variable to store CRP value in. Will be placed automatically
+// by the linker when "Enable Code Read Protect" selected.
+// See crp.h header for more information
+__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
+
+int main(void)
+{
+ SystemInit();
+ tusb_init();
+
+ while (1)
+ {
+
+ }
+
+ return 0;
+}