hathach 13 лет назад
Родитель
Сommit
a5eecb4055

+ 354 - 0
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) {
+	}
+}

+ 374 - 0
demos/device/keyboard/descriptors.c

@@ -0,0 +1,374 @@
+/*
+ * descriptors.c
+ *
+ *  Created on: Nov 26, 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 "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'}
+};

+ 184 - 0
demos/device/keyboard/descriptors.h

@@ -0,0 +1,184 @@
+/*
+ * descriptors.h
+ *
+ *  Created on: Nov 26, 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 _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

+ 25 - 0
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;
+}