convert line endings to unix

This commit is contained in:
Triss 2021-06-28 22:10:51 +02:00
parent 9f306e9407
commit 4bbf372ec5
3 changed files with 560 additions and 560 deletions

View File

@ -1,182 +1,182 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2019 Ha Thach (tinyusb.org)
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "tusb_config.h" #include "tusb_config.h"
#include "bsp/board.h" /* a tinyusb header */ #include "bsp/board.h" /* a tinyusb header */
#include "tusb.h" #include "tusb.h"
#include "DAP_config.h" /* ARM code *assumes* this is included prior to DAP.h */ #include "DAP_config.h" /* ARM code *assumes* this is included prior to DAP.h */
#include "DAP.h" #include "DAP.h"
#include "util.h" #include "util.h"
#include "protocfg.h" #include "protocfg.h"
#include "protos.h" #include "protos.h"
#include "libco.h" #include "libco.h"
#ifdef PICO_BOARD #ifdef PICO_BOARD
#include <pico/binary_info.h> #include <pico/binary_info.h>
/*#include <hardware/i2c.h> /*#include <hardware/i2c.h>
#include "pinout.h"*/ #include "pinout.h"*/
#endif #endif
static cothread_t mainthread; static cothread_t mainthread;
void thread_yield(void) { void thread_yield(void) {
co_switch(mainthread); co_switch(mainthread);
} }
#define DEFAULT_STACK_SIZE 1024 #define DEFAULT_STACK_SIZE 1024
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
static cothread_t uartthread; static cothread_t uartthread;
static uint8_t uartstack[DEFAULT_STACK_SIZE]; static uint8_t uartstack[DEFAULT_STACK_SIZE];
static void uart_thread_fn(void) { static void uart_thread_fn(void) {
cdc_uart_init(); cdc_uart_init();
thread_yield(); thread_yield();
while (1) { while (1) {
cdc_uart_task(); cdc_uart_task();
thread_yield(); thread_yield();
} }
} }
#endif #endif
#ifdef DBOARD_HAS_SERPROG #ifdef DBOARD_HAS_SERPROG
static cothread_t serprogthread; static cothread_t serprogthread;
static uint8_t serprogstack[DEFAULT_STACK_SIZE]; static uint8_t serprogstack[DEFAULT_STACK_SIZE];
static void serprog_thread_fn(void) { static void serprog_thread_fn(void) {
cdc_serprog_init(); cdc_serprog_init();
thread_yield(); thread_yield();
while (1) { while (1) {
cdc_serprog_task(); cdc_serprog_task();
thread_yield(); thread_yield();
} }
} }
#endif #endif
// FIXME // FIXME
extern uint32_t co_active_buffer[64]; extern uint32_t co_active_buffer[64];
uint32_t co_active_buffer[64]; uint32_t co_active_buffer[64];
extern cothread_t co_active_handle; extern cothread_t co_active_handle;
cothread_t co_active_handle; cothread_t co_active_handle;
int main(void) { int main(void) {
mainthread = co_active(); mainthread = co_active();
// TODO: split this out in a bsp-specific file // TODO: split this out in a bsp-specific file
#if defined(PICO_BOARD) && !defined(USE_USBCDC_FOR_STDIO) #if defined(PICO_BOARD) && !defined(USE_USBCDC_FOR_STDIO)
// use hardcoded values from TinyUSB board.h // use hardcoded values from TinyUSB board.h
bi_decl(bi_2pins_with_func(0, 1, GPIO_FUNC_UART)); bi_decl(bi_2pins_with_func(0, 1, GPIO_FUNC_UART));
/*i2c_init(PINOUT_I2C_DEV, 100*1000); /*i2c_init(PINOUT_I2C_DEV, 100*1000);
gpio_set_function(PINOUT_I2C_SCL, GPIO_FUNC_I2C); gpio_set_function(PINOUT_I2C_SCL, GPIO_FUNC_I2C);
gpio_set_function(PINOUT_I2C_SDA, GPIO_FUNC_I2C); gpio_set_function(PINOUT_I2C_SDA, GPIO_FUNC_I2C);
gpio_pull_up(PINOUT_I2C_SCL); gpio_pull_up(PINOUT_I2C_SCL);
gpio_pull_up(PINOUT_I2C_SDA); gpio_pull_up(PINOUT_I2C_SDA);
bi_decl(bi_2pins_with_func(PINOUT_I2C_SCL, PINOUT_I2C_SDA, GPIO_FUNC_I2C));*/ bi_decl(bi_2pins_with_func(PINOUT_I2C_SCL, PINOUT_I2C_SDA, GPIO_FUNC_I2C));*/
#endif #endif
board_init(); board_init();
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
uartthread = co_derive(uartstack, sizeof uartstack, uart_thread_fn); uartthread = co_derive(uartstack, sizeof uartstack, uart_thread_fn);
co_switch(uartthread); // will call cdc_uart_init() on correct thread co_switch(uartthread); // will call cdc_uart_init() on correct thread
#endif #endif
#ifdef DBOARD_HAS_SERPROG #ifdef DBOARD_HAS_SERPROG
serprogthread = co_derive(serprogstack, sizeof serprogstack, serprog_thread_fn); serprogthread = co_derive(serprogstack, sizeof serprogstack, serprog_thread_fn);
co_switch(serprogthread); // will call cdc_serprog_init() on correct thread co_switch(serprogthread); // will call cdc_serprog_init() on correct thread
#endif #endif
#ifdef DBOARD_HAS_CMSISDAP #ifdef DBOARD_HAS_CMSISDAP
DAP_Setup(); DAP_Setup();
#endif #endif
tusb_init(); tusb_init();
#ifdef USE_USBCDC_FOR_STDIO #ifdef USE_USBCDC_FOR_STDIO
stdio_usb_init(); stdio_usb_init();
#endif #endif
while (1) { while (1) {
/*uint8_t val = 0x12; /*uint8_t val = 0x12;
i2c_write_timeout_us(PINOUT_I2C_DEV, 0x13, &val, 1, false, 1000*1000);*/ i2c_write_timeout_us(PINOUT_I2C_DEV, 0x13, &val, 1, false, 1000*1000);*/
tud_task(); // tinyusb device task tud_task(); // tinyusb device task
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
co_switch(uartthread); co_switch(uartthread);
#endif #endif
//i2c_write_timeout_us(PINOUT_I2C_DEV, 0x13, &val, 1, false, 1000*1000); //i2c_write_timeout_us(PINOUT_I2C_DEV, 0x13, &val, 1, false, 1000*1000);
tud_task(); // tinyusb device task tud_task(); // tinyusb device task
#ifdef DBOARD_HAS_SERPROG #ifdef DBOARD_HAS_SERPROG
co_switch(serprogthread); co_switch(serprogthread);
#endif #endif
} }
return 0; return 0;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// USB HID // USB HID
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Invoked when received GET_REPORT control request // Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length. // Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request // Return zero will cause the stack to STALL request
uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id,
hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
// TODO not Implemented // TODO not Implemented
(void) instance; (void) instance;
(void) report_id; (void) report_id;
(void) report_type; (void) report_type;
(void) buffer; (void) buffer;
(void) reqlen; (void) reqlen;
return 0; return 0;
} }
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id,
hid_report_type_t report_type, uint8_t const* RxDataBuffer, uint16_t bufsize) { hid_report_type_t report_type, uint8_t const* RxDataBuffer, uint16_t bufsize) {
static uint8_t TxDataBuffer[CFG_TUD_HID_EP_BUFSIZE]; static uint8_t TxDataBuffer[CFG_TUD_HID_EP_BUFSIZE];
uint32_t response_size = TU_MIN(CFG_TUD_HID_EP_BUFSIZE, bufsize); uint32_t response_size = TU_MIN(CFG_TUD_HID_EP_BUFSIZE, bufsize);
// This doesn't use multiple report and report ID // This doesn't use multiple report and report ID
(void) instance; (void) instance;
(void) report_id; (void) report_id;
(void) report_type; (void) report_type;
#ifdef DBOARD_HAS_CMSISDAP #ifdef DBOARD_HAS_CMSISDAP
DAP_ProcessCommand(RxDataBuffer, TxDataBuffer); DAP_ProcessCommand(RxDataBuffer, TxDataBuffer);
#endif #endif
tud_hid_report(0, TxDataBuffer, response_size); tud_hid_report(0, TxDataBuffer, response_size);
} }

View File

@ -1,118 +1,118 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2019 Ha Thach (tinyusb.org)
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
*/ */
#ifndef _TUSB_CONFIG_H__ #ifndef _TUSB_CONFIG_H__
#define _TUSB_CONFIG_H__ #define _TUSB_CONFIG_H__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "protocfg.h" #include "protocfg.h"
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// COMMON CONFIGURATION // COMMON CONFIGURATION
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// defined by board.mk // defined by board.mk
#ifndef CFG_TUSB_MCU #ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
// RHPort number used for device can be defined by board.mk, default to port 0 // RHPort number used for device can be defined by board.mk, default to port 0
#ifndef BOARD_DEVICE_RHPORT_NUM #ifndef BOARD_DEVICE_RHPORT_NUM
#define BOARD_DEVICE_RHPORT_NUM 0 #define BOARD_DEVICE_RHPORT_NUM 0
#endif #endif
// RHPort max operational speed can defined by board.mk // RHPort max operational speed can defined by board.mk
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed
#ifndef BOARD_DEVICE_RHPORT_SPEED #ifndef BOARD_DEVICE_RHPORT_SPEED
#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \
CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56)
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED
#else #else
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
#endif #endif
#endif #endif
// Device mode with rhport and speed defined by board.mk // Device mode with rhport and speed defined by board.mk
#if BOARD_DEVICE_RHPORT_NUM == 0 #if BOARD_DEVICE_RHPORT_NUM == 0
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#elif BOARD_DEVICE_RHPORT_NUM == 1 #elif BOARD_DEVICE_RHPORT_NUM == 1
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED)
#else #else
#error "Incorrect RHPort configuration" #error "Incorrect RHPort configuration"
#endif #endif
// This example doesn't use an RTOS // This example doesn't use an RTOS
#ifdef PICO_BOARD #ifdef PICO_BOARD
#define CFG_TUSB_OS OPT_OS_PICO #define CFG_TUSB_OS OPT_OS_PICO
#else #else
#define CFG_TUSB_OS OPT_OS_NONE #define CFG_TUSB_OS OPT_OS_NONE
#endif #endif
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build // CFG_TUSB_DEBUG is defined by compiler in DEBUG build
// #define CFG_TUSB_DEBUG 0 // #define CFG_TUSB_DEBUG 0
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* Tinyusb use follows macros to declare transferring memory so that they can be put * Tinyusb use follows macros to declare transferring memory so that they can be put
* into those specific section. * into those specific section.
* e.g * e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/ */
#ifndef CFG_TUSB_MEM_SECTION #ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION #define CFG_TUSB_MEM_SECTION
#endif #endif
#ifndef CFG_TUSB_MEM_ALIGN #ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#endif #endif
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// DEVICE CONFIGURATION // DEVICE CONFIGURATION
//-------------------------------------------------------------------- //--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE #ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64 #define CFG_TUD_ENDPOINT0_SIZE 64
#endif #endif
//------------- CLASS -------------// //------------- CLASS -------------//
#define CFG_TUD_MSC 0 #define CFG_TUD_MSC 0
#define CFG_TUD_MIDI 0 #define CFG_TUD_MIDI 0
#define CFG_TUD_NET 0 #define CFG_TUD_NET 0
// see also: bsp/<family>/protocfg.h // see also: bsp/<family>/protocfg.h
#define CFG_TUD_HID_EP_BUFSIZE 64 #define CFG_TUD_HID_EP_BUFSIZE 64
// CDC FIFO size of TX and RX // CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* _TUSB_CONFIG_H_ */ #endif /* _TUSB_CONFIG_H_ */

View File

@ -1,260 +1,260 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2019 Ha Thach (tinyusb.org)
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
*/ */
#include "tusb.h" #include "tusb.h"
#include "util.h" #include "util.h"
#include "protos.h" #include "protos.h"
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
* *
* Auto ProductID layout's Bitmap: * Auto ProductID layout's Bitmap:
* [MSB] HID | MSC | CDC [LSB] * [MSB] HID | MSC | CDC [LSB]
*/ */
#ifdef DBOARD_HAS_I2C #ifdef DBOARD_HAS_I2C
#define USB_BCD_BASE 0x6000 #define USB_BCD_BASE 0x6000
#else #else
#define USB_BCD_BASE 0x4000 #define USB_BCD_BASE 0x4000
#endif #endif
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) #define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
#define USB_BCD (USB_BCD_BASE | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 3) | _PID_MAP(HID, 6) | \ #define USB_BCD (USB_BCD_BASE | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 3) | _PID_MAP(HID, 6) | \
_PID_MAP(MIDI, 9) | _PID_MAP(VENDOR, 12) ) \ _PID_MAP(MIDI, 9) | _PID_MAP(VENDOR, 12) ) \
// String Descriptor Index // String Descriptor Index
enum { enum {
STRID_LANGID = 0, STRID_LANGID = 0,
STRID_MANUFACTURER, STRID_MANUFACTURER,
STRID_PRODUCT, STRID_PRODUCT,
STRID_SERIAL, STRID_SERIAL,
STRID_CONFIG, STRID_CONFIG,
STRID_IF_HID_CMSISDAP, STRID_IF_HID_CMSISDAP,
STRID_IF_VND_I2CTINYUSB, STRID_IF_VND_I2CTINYUSB,
STRID_IF_CDC_UART, STRID_IF_CDC_UART,
STRID_IF_CDC_SERPROG, STRID_IF_CDC_SERPROG,
STRID_IF_CDC_STDIO, STRID_IF_CDC_STDIO,
}; };
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Device Descriptors // Device Descriptors
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
tusb_desc_device_t const desc_device = { tusb_desc_device_t const desc_device = {
.bLength = sizeof(tusb_desc_device_t), .bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE, .bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0110, // TODO: 0x0200 ? .bcdUSB = 0x0110, // TODO: 0x0200 ?
.bDeviceClass = 0x00, .bDeviceClass = 0x00,
.bDeviceSubClass = 0x00, .bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00, .bDeviceProtocol = 0x00,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USB_VID, .idVendor = USB_VID,
.idProduct = USB_PID, .idProduct = USB_PID,
.bcdDevice = USB_BCD, .bcdDevice = USB_BCD,
.iManufacturer = STRID_MANUFACTURER, .iManufacturer = STRID_MANUFACTURER,
.iProduct = STRID_PRODUCT, .iProduct = STRID_PRODUCT,
.iSerialNumber = STRID_SERIAL, .iSerialNumber = STRID_SERIAL,
.bNumConfigurations = 0x01 .bNumConfigurations = 0x01
}; };
// Invoked when received GET DEVICE DESCRIPTOR // Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
uint8_t const * tud_descriptor_device_cb(void) { uint8_t const * tud_descriptor_device_cb(void) {
return (uint8_t const *) &desc_device; return (uint8_t const *) &desc_device;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// HID Report Descriptor // HID Report Descriptor
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static uint8_t const desc_hid_report[] = { static uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE) TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE)
}; };
// Invoked when received GET HID REPORT DESCRIPTOR // Invoked when received GET HID REPORT DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete // Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) { uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) {
(void) instance; (void) instance;
return desc_hid_report; return desc_hid_report;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Configuration Descriptor // Configuration Descriptor
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
enum { enum {
#ifdef DBOARD_HAS_I2C #ifdef DBOARD_HAS_I2C
ITF_NUM_VND_I2CTINYUSB, ITF_NUM_VND_I2CTINYUSB,
#endif #endif
#ifdef DBOARD_HAS_CMSISDAP #ifdef DBOARD_HAS_CMSISDAP
ITF_NUM_HID_CMSISDAP, ITF_NUM_HID_CMSISDAP,
#endif #endif
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
ITF_NUM_CDC_UART_COM, ITF_NUM_CDC_UART_COM,
ITF_NUM_CDC_UART_DATA, ITF_NUM_CDC_UART_DATA,
#endif #endif
#ifdef DBOARD_HAS_SERPROG #ifdef DBOARD_HAS_SERPROG
ITF_NUM_CDC_SERPROG_COM, ITF_NUM_CDC_SERPROG_COM,
ITF_NUM_CDC_SERPROG_DATA, ITF_NUM_CDC_SERPROG_DATA,
#endif #endif
#ifdef USE_USBCDC_FOR_STDIO #ifdef USE_USBCDC_FOR_STDIO
ITF_NUM_CDC_STDIO_COM, ITF_NUM_CDC_STDIO_COM,
ITF_NUM_CDC_STDIO_DATA, ITF_NUM_CDC_STDIO_DATA,
#endif #endif
ITF_NUM_TOTAL ITF_NUM_TOTAL
}; };
#define TUD_I2CTINYUSB_LEN (9) #define TUD_I2CTINYUSB_LEN (9)
#define TUD_I2CTINYUSB_DESCRIPTOR(_itfnum, _stridx) \ #define TUD_I2CTINYUSB_DESCRIPTOR(_itfnum, _stridx) \
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, 0, 0, 0, _stridx \ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, 0, 0, 0, _stridx \
enum { enum {
CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN
#ifdef DBOARD_HAS_I2C #ifdef DBOARD_HAS_I2C
+ TUD_I2CTINYUSB_LEN + TUD_I2CTINYUSB_LEN
#endif #endif
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
+ TUD_CDC_DESC_LEN + TUD_CDC_DESC_LEN
#endif #endif
#ifdef DBOARD_HAS_CMSISDAP #ifdef DBOARD_HAS_CMSISDAP
+ TUD_HID_INOUT_DESC_LEN + TUD_HID_INOUT_DESC_LEN
#endif #endif
#ifdef DBOARD_HAS_SERPROG #ifdef DBOARD_HAS_SERPROG
+ TUD_CDC_DESC_LEN + TUD_CDC_DESC_LEN
#endif #endif
#ifdef USE_USBCDC_FOR_STDIO #ifdef USE_USBCDC_FOR_STDIO
+ TUD_CDC_DESC_LEN + TUD_CDC_DESC_LEN
#endif #endif
}; };
#define EPNUM_CDC_UART_OUT 0x02 #define EPNUM_CDC_UART_OUT 0x02
#define EPNUM_CDC_UART_IN 0x82 #define EPNUM_CDC_UART_IN 0x82
#define EPNUM_CDC_UART_NOTIF 0x83 #define EPNUM_CDC_UART_NOTIF 0x83
#define EPNUM_HID_CMSISDAP 0x04 #define EPNUM_HID_CMSISDAP 0x04
#define EPNUM_CDC_SERPROG_OUT 0x05 #define EPNUM_CDC_SERPROG_OUT 0x05
#define EPNUM_CDC_SERPROG_IN 0x85 #define EPNUM_CDC_SERPROG_IN 0x85
#define EPNUM_CDC_SERPROG_NOTIF 0x86 #define EPNUM_CDC_SERPROG_NOTIF 0x86
#define EPNUM_CDC_STDIO_OUT 0x07 #define EPNUM_CDC_STDIO_OUT 0x07
#define EPNUM_CDC_STDIO_IN 0x87 #define EPNUM_CDC_STDIO_IN 0x87
#define EPNUM_CDC_STDIO_NOTIF 0x88 #define EPNUM_CDC_STDIO_NOTIF 0x88
// NOTE: if you modify this table, don't forget to keep tusb_config.h up to date as well! // NOTE: if you modify this table, don't forget to keep tusb_config.h up to date as well!
// TODO: maybe add some strings to all these interfaces // TODO: maybe add some strings to all these interfaces
uint8_t const desc_configuration[] = { uint8_t const desc_configuration[] = {
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, STRID_CONFIG, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, STRID_CONFIG, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
#ifdef DBOARD_HAS_CMSISDAP #ifdef DBOARD_HAS_CMSISDAP
TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID_CMSISDAP, STRID_IF_HID_CMSISDAP, 0/*HID_PROTOCOL_NONE*/, sizeof(desc_hid_report), EPNUM_HID_CMSISDAP, 0x80 | (EPNUM_HID_CMSISDAP+0), CFG_TUD_HID_EP_BUFSIZE, 1), TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID_CMSISDAP, STRID_IF_HID_CMSISDAP, 0/*HID_PROTOCOL_NONE*/, sizeof(desc_hid_report), EPNUM_HID_CMSISDAP, 0x80 | (EPNUM_HID_CMSISDAP+0), CFG_TUD_HID_EP_BUFSIZE, 1),
#endif #endif
#ifdef DBOARD_HAS_I2C #ifdef DBOARD_HAS_I2C
TUD_I2CTINYUSB_DESCRIPTOR(ITF_NUM_VND_I2CTINYUSB, STRID_IF_VND_I2CTINYUSB), TUD_I2CTINYUSB_DESCRIPTOR(ITF_NUM_VND_I2CTINYUSB, STRID_IF_VND_I2CTINYUSB),
#endif #endif
#ifdef DBOARD_HAS_UART #ifdef DBOARD_HAS_UART
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_UART_COM, STRID_IF_CDC_UART, EPNUM_CDC_UART_NOTIF, 64, EPNUM_CDC_UART_OUT, EPNUM_CDC_UART_IN, 64), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_UART_COM, STRID_IF_CDC_UART, EPNUM_CDC_UART_NOTIF, 64, EPNUM_CDC_UART_OUT, EPNUM_CDC_UART_IN, 64),
#endif #endif
#ifdef DBOARD_HAS_SERPROG #ifdef DBOARD_HAS_SERPROG
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_SERPROG_COM, STRID_IF_CDC_SERPROG, EPNUM_CDC_SERPROG_NOTIF, 64, EPNUM_CDC_SERPROG_OUT, EPNUM_CDC_SERPROG_IN, 64), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_SERPROG_COM, STRID_IF_CDC_SERPROG, EPNUM_CDC_SERPROG_NOTIF, 64, EPNUM_CDC_SERPROG_OUT, EPNUM_CDC_SERPROG_IN, 64),
#endif #endif
#ifdef USE_USBCDC_FOR_STDIO #ifdef USE_USBCDC_FOR_STDIO
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_STDIO_COM, STRID_IF_CDC_STDIO, EPNUM_CDC_STDIO_NOTIF, 64, EPNUM_CDC_STDIO_OUT, EPNUM_CDC_STDIO_IN, 64), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_STDIO_COM, STRID_IF_CDC_STDIO, EPNUM_CDC_STDIO_NOTIF, 64, EPNUM_CDC_STDIO_OUT, EPNUM_CDC_STDIO_IN, 64),
#endif #endif
}; };
// Invoked when received GET CONFIGURATION DESCRIPTOR // Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete // Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { uint8_t const * tud_descriptor_configuration_cb(uint8_t index) {
(void) index; // for multiple configurations (void) index; // for multiple configurations
return desc_configuration; return desc_configuration;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// String Descriptors // String Descriptors
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// array of pointer to string descriptors // array of pointer to string descriptors
char const* string_desc_arr [] = { char const* string_desc_arr [] = {
[STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409) [STRID_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409)
[STRID_MANUFACTURER] = INFO_MANUFACTURER, // Manufacturer [STRID_MANUFACTURER] = INFO_MANUFACTURER, // Manufacturer
[STRID_PRODUCT] = INFO_PRODUCT(INFO_BOARDNAME), // Product [STRID_PRODUCT] = INFO_PRODUCT(INFO_BOARDNAME), // Product
[STRID_CONFIG] = "Configuration descriptor", [STRID_CONFIG] = "Configuration descriptor",
// max string length check: ||||||||||||||||||||||||||||||| // max string length check: |||||||||||||||||||||||||||||||
[STRID_IF_HID_CMSISDAP] = "CMSIS-DAP HID interface", [STRID_IF_HID_CMSISDAP] = "CMSIS-DAP HID interface",
[STRID_IF_VND_I2CTINYUSB] = "I2C-Tiny-USB interface", [STRID_IF_VND_I2CTINYUSB] = "I2C-Tiny-USB interface",
[STRID_IF_CDC_UART] = "UART CDC interface", [STRID_IF_CDC_UART] = "UART CDC interface",
[STRID_IF_CDC_SERPROG] = "Serprog CDC interface", [STRID_IF_CDC_SERPROG] = "Serprog CDC interface",
[STRID_IF_CDC_STDIO] = "stdio CDC interface (debug)", [STRID_IF_CDC_STDIO] = "stdio CDC interface (debug)",
}; };
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
static uint16_t _desc_str[32]; static uint16_t _desc_str[32];
(void) langid; (void) langid;
uint8_t chr_count = 0; uint8_t chr_count = 0;
if (STRID_LANGID == index) { if (STRID_LANGID == index) {
memcpy(&_desc_str[1], string_desc_arr[STRID_LANGID], 2); memcpy(&_desc_str[1], string_desc_arr[STRID_LANGID], 2);
chr_count = 1; chr_count = 1;
} else if (STRID_SERIAL == index) { } else if (STRID_SERIAL == index) {
chr_count = get_unique_id_u16(_desc_str + 1); chr_count = get_unique_id_u16(_desc_str + 1);
} else { } else {
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
if (!(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0]))) if (!(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])))
return NULL; return NULL;
const char* str = string_desc_arr[index]; const char* str = string_desc_arr[index];
// Cap at max char // Cap at max char
chr_count = TU_MIN(strlen(str), 31); chr_count = TU_MIN(strlen(str), 31);
// Convert ASCII string into UTF-16 // Convert ASCII string into UTF-16
for (int i = 0; i < chr_count; i++) { for (int i = 0; i < chr_count; i++) {
_desc_str[1+i] = str[i]; _desc_str[1+i] = str[i];
} }
} }
// first byte is length (including header), second byte is string type // first byte is length (including header), second byte is string type
_desc_str[0] = (TUSB_DESC_STRING << 8) | (2*chr_count + 2); _desc_str[0] = (TUSB_DESC_STRING << 8) | (2*chr_count + 2);
return _desc_str; return _desc_str;
} }