mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-14 04:18:56 +00:00
added keyboard device demo
This commit is contained in:
parent
545fe61828
commit
a5eecb4055
354
demos/device/keyboard/cr_startup_lpc13u.c
Normal file
354
demos/device/keyboard/cr_startup_lpc13u.c
Normal file
@ -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
demos/device/keyboard/descriptors.c
Normal file
374
demos/device/keyboard/descriptors.c
Normal file
@ -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
demos/device/keyboard/descriptors.h
Normal file
184
demos/device/keyboard/descriptors.h
Normal file
@ -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
demos/device/keyboard/main.c
Normal file
25
demos/device/keyboard/main.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user