From 73d7ab201e46e1eca9a190e65f96db7158805a65 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 10 Jun 2019 22:29:18 +0700 Subject: [PATCH 01/15] remove dcd_edpt_busy() --- src/device/dcd.h | 3 --- src/portable/microchip/samd21/dcd_samd21.c | 16 ------------ src/portable/microchip/samd51/dcd_samd51.c | 16 ------------ src/portable/nordic/nrf5x/dcd_nrf5x.c | 15 ----------- .../nxp/lpc11_13_15/dcd_lpc11_13_15.c | 8 ------ src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 8 ------ src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 12 --------- src/portable/st/stm32f3/dcd_stm32f3.c | 14 ++++++---- src/portable/st/stm32f4/dcd_stm32f4.c | 26 ------------------- 9 files changed, 9 insertions(+), 109 deletions(-) diff --git a/src/device/dcd.h b/src/device/dcd.h index 0ed4a77d..168eb181 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -110,9 +110,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoi // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); -// Check if endpoint transferring is complete (TODO remove) -bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr); - // Stall endpoint void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); diff --git a/src/portable/microchip/samd21/dcd_samd21.c b/src/portable/microchip/samd21/dcd_samd21.c index fedfa2ec..7f3c3495 100644 --- a/src/portable/microchip/samd21/dcd_samd21.c +++ b/src/portable/microchip/samd21/dcd_samd21.c @@ -229,22 +229,6 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) } } -bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - // USBD shouldn't check control endpoint state - if ( 0 == ep_addr ) return false; - - uint8_t const epnum = tu_edpt_number(ep_addr); - UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; - - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - return ep->EPINTFLAG.bit.TRCPT1 == 0 && ep->EPSTATUS.bit.BK1RDY == 1; - } - return ep->EPINTFLAG.bit.TRCPT0 == 0 && ep->EPSTATUS.bit.BK0RDY == 1; -} - /*------------------------------------------------------------------*/ static bool maybe_handle_setup_packet(void) { diff --git a/src/portable/microchip/samd51/dcd_samd51.c b/src/portable/microchip/samd51/dcd_samd51.c index a43609b9..f2aff857 100644 --- a/src/portable/microchip/samd51/dcd_samd51.c +++ b/src/portable/microchip/samd51/dcd_samd51.c @@ -233,22 +233,6 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) } } -bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - // USBD shouldn't check control endpoint state - if ( 0 == ep_addr ) return false; - - uint8_t const epnum = tu_edpt_number(ep_addr); - UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum]; - - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - return ep->EPINTFLAG.bit.TRCPT1 == 0 && ep->EPSTATUS.bit.BK1RDY == 1; - } - return ep->EPINTFLAG.bit.TRCPT0 == 0 && ep->EPSTATUS.bit.BK0RDY == 1; -} - /*------------------------------------------------------------------*/ static bool maybe_handle_setup_packet(void) { diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 37b5459f..093dcfd7 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -332,21 +332,6 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) } } -bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - // USBD shouldn't check control endpoint state - if ( 0 == tu_edpt_number(ep_addr) ) return false; - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - xfer_td_t* xfer = get_td(epnum, dir); - - return xfer->actual_len < xfer->total_len; -} - /*------------------------------------------------------------------*/ /* Interrupt Handler *------------------------------------------------------------------*/ diff --git a/src/portable/nxp/lpc11_13_15/dcd_lpc11_13_15.c b/src/portable/nxp/lpc11_13_15/dcd_lpc11_13_15.c index 0dab2caf..39c365d8 100644 --- a/src/portable/nxp/lpc11_13_15/dcd_lpc11_13_15.c +++ b/src/portable/nxp/lpc11_13_15/dcd_lpc11_13_15.c @@ -218,14 +218,6 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } -bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - uint8_t const ep_id = ep_addr2id(ep_addr); - return _dcd.ep[ep_id][0].active; -} - static void prepare_ep_xfer(uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) { uint16_t const nbytes = tu_min16(total_bytes, DMA_NBYTES_MAX); diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index cdc4d58d..2b49f52e 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -316,14 +316,6 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } -bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - - uint8_t ep_id = ep_addr2idx( ep_addr ); - return (_dcd.udca[ep_id] != NULL && !_dcd.udca[ep_id]->retired); -} - void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 049624d9..519e0dcc 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -240,18 +240,6 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } -bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - uint8_t const ep_idx = 2*epnum + dir; - - dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx]; - - return p_qtd->active; -// return !p_qhd->qtd_overlay.halted && p_qhd->qtd_overlay.active; -} - bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { uint8_t const epnum = tu_edpt_number(ep_addr); diff --git a/src/portable/st/stm32f3/dcd_stm32f3.c b/src/portable/st/stm32f3/dcd_stm32f3.c index 648ff0e1..7339863b 100644 --- a/src/portable/st/stm32f3/dcd_stm32f3.c +++ b/src/portable/st/stm32f3/dcd_stm32f3.c @@ -67,15 +67,19 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc { return false; } + bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ return false;} -bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr) -{ return false;} +{ + return false; +} void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) -{} +{ +} + void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) -{} +{ +} #endif diff --git a/src/portable/st/stm32f4/dcd_stm32f4.c b/src/portable/st/stm32f4/dcd_stm32f4.c index 996950ab..3cb502be 100644 --- a/src/portable/st/stm32f4/dcd_stm32f4.c +++ b/src/portable/st/stm32f4/dcd_stm32f4.c @@ -397,32 +397,6 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) } } -bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE; - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE; - - // USBD shouldn't check control endpoint state - if ( 0 == ep_addr ) return false; - - uint8_t const epnum = tu_edpt_number(ep_addr); - - bool enabled = false; - bool xferring = true; - - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - enabled = (in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPENA_Msk); - xferring = (in_ep[epnum].DIEPTSIZ & USB_OTG_DIEPTSIZ_PKTCNT_Msk); - } else { - enabled = (out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPENA_Msk); - xferring = (out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_PKTCNT_Msk); - } - - // TODO: Also check that endpoint is active (not just enabled)? - return (enabled && xferring); -} - /*------------------------------------------------------------------*/ // TODO: Split into "receive on endpoint 0" and "receive generic"; endpoint 0's From 6991b28532605ceae685cb8be1fee904e09f12fe Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 1 Jul 2019 22:38:06 +0700 Subject: [PATCH 02/15] improving midi support, adding midi exmaple rename TUSB_DESC_CLASS_SPECIFIC to TUSB_DESC_CS_INTERFACE --- .../device/cdc_msc_hid/src/usb_descriptors.c | 4 +- .../src/usb_descriptors.c | 6 +- .../hid_generic_inout/src/usb_descriptors.c | 6 +- examples/device/midi/Makefile | 12 ++ examples/device/midi/src/main.c | 115 ++++++++++++++ examples/device/midi/src/tusb_config.h | 85 ++++++++++ examples/device/midi/src/usb_descriptors.c | 149 ++++++++++++++++++ .../device/msc_dual_lun/src/usb_descriptors.c | 6 +- src/class/audio/audio.h | 44 +++++- src/class/cdc/cdc.h | 20 ++- src/class/cdc/cdc_device.c | 2 +- src/class/cdc/cdc_host.c | 2 +- src/class/midi/midi.h | 117 ++++++++++++-- src/common/tusb_types.h | 34 ++-- src/device/usbd.h | 45 +++++- 15 files changed, 596 insertions(+), 51 deletions(-) create mode 100644 examples/device/midi/Makefile create mode 100644 examples/device/midi/src/main.c create mode 100644 examples/device/midi/src/tusb_config.h create mode 100644 examples/device/midi/src/usb_descriptors.c diff --git a/examples/device/cdc_msc_hid/src/usb_descriptors.c b/examples/device/cdc_msc_hid/src/usb_descriptors.c index 8cd6062b..1692151a 100644 --- a/examples/device/cdc_msc_hid/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid/src/usb_descriptors.c @@ -32,7 +32,7 @@ * [MSB] HID | MSC | CDC [LSB] */ #define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) ) //------------- Device Descriptors -------------// tusb_desc_device_t const desc_device = @@ -188,6 +188,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) chr_count = 1; }else { + // Convert ASCII string into UTF-16 + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; const char* str = string_desc_arr[index]; diff --git a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c index b60615ca..579e1ebc 100644 --- a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c @@ -32,7 +32,7 @@ * [MSB] HID | MSC | CDC [LSB] */ #define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) ) //------------- Device Descriptors -------------// tusb_desc_device_t const desc_device = @@ -126,7 +126,7 @@ enum uint8_t const desc_configuration[] = { - // Inteface count, string index, total length, attribute, power in mA + // interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), #if CFG_TUD_CDC @@ -189,6 +189,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) chr_count = 1; }else { + // Convert ASCII string into UTF-16 + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; const char* str = string_desc_arr[index]; diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c index 3cf0f711..ced91593 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -32,7 +32,7 @@ * [MSB] HID | MSC | CDC [LSB] */ #define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) ) //------------- Device Descriptors -------------// tusb_desc_device_t const desc_device = @@ -81,7 +81,7 @@ enum uint8_t const desc_configuration[] = { - // Inteface count, string index, total length, attribute, power in mA + // interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval @@ -138,6 +138,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) chr_count = 1; }else { + // Convert ASCII string into UTF-16 + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; const char* str = string_desc_arr[index]; diff --git a/examples/device/midi/Makefile b/examples/device/midi/Makefile new file mode 100644 index 00000000..5a455078 --- /dev/null +++ b/examples/device/midi/Makefile @@ -0,0 +1,12 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +include ../../rules.mk diff --git a/examples/device/midi/src/main.c b/examples/device/midi/src/main.c new file mode 100644 index 00000000..60500df9 --- /dev/null +++ b/examples/device/midi/src/main.c @@ -0,0 +1,115 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * 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 + * THE SOFTWARE. + * + */ + +#include +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +void led_blinking_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + tusb_init(); + + while (1) + { + // tinyusb device task + tud_task(); + + led_blinking_task(); + } + + return 0; +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + blink_interval_ms = BLINK_NOT_MOUNTED; +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + static uint32_t start_ms = 0; + static bool led_state = false; + + // Blink every 1000 ms + if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/device/midi/src/tusb_config.h b/examples/device/midi/src/tusb_config.h new file mode 100644 index 00000000..cb6eca33 --- /dev/null +++ b/examples/device/midi/src/tusb_config.h @@ -0,0 +1,85 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * 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 + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#else +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +#endif + +#define CFG_TUSB_OS OPT_OS_NONE + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* 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 + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUD_ENDOINT0_SIZE 64 + +//------------- CLASS -------------// +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 0 +#define CFG_TUD_MIDI 1 +#define CFG_TUD_CUSTOM_CLASS 0 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/midi/src/usb_descriptors.c b/examples/device/midi/src/usb_descriptors.c new file mode 100644 index 00000000..192dacfb --- /dev/null +++ b/examples/device/midi/src/usb_descriptors.c @@ -0,0 +1,149 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * 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 + * THE SOFTWARE. + * + */ + +#include "tusb.h" + +/* 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. + * + * Auto ProductID layout's Bitmap: + * [MSB] MIDI | HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) ) + +//------------- Device Descriptors -------------// +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + // Use Interface Association Descriptor (IAD) for Audio + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +//------------- Configuration Descriptor -------------// +enum +{ + ITF_NUM_MIDI = 0, + ITF_NUM_MIDI_STREAMING, + ITF_NUM_TOTAL +}; + +enum +{ + CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN + TUD_MIDI_DESC_LEN +}; + +// Use Endpoint 2 instead of 1 due to NXP MCU +// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number +// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... +#define EPNUM_MIDI 0x02 + +uint8_t const desc_configuration[] = +{ + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // Interface number, string index, EP Out & EP In address, EP size + TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI, 0x80 | EPNUM_MIDI, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64) +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//------------- String Descriptors -------------// + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + "123456", // 3: Serials, should use chip ID +}; + +static uint16_t _desc_str[32]; + +// Invoked when received GET STRING DESCRIPTOR request +// 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) +{ + uint8_t chr_count; + + if ( index == 0) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + }else + { + // Convert ASCII string into UTF-16 + + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + if ( chr_count > 31 ) chr_count = 31; + + for(uint8_t i=0; i Date: Mon, 1 Jul 2019 22:57:23 +0700 Subject: [PATCH 03/15] added adafruit feather m4 express board --- hw/bsp/feather_m4_express/board.mk | 47 +++++ .../board_feather_m4_express.c | 120 +++++++++++++ hw/bsp/feather_m4_express/samd51g19a_flash.ld | 164 ++++++++++++++++++ .../metro_m4_express/board_metro_m4_express.c | 2 +- 4 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 hw/bsp/feather_m4_express/board.mk create mode 100644 hw/bsp/feather_m4_express/board_feather_m4_express.c create mode 100644 hw/bsp/feather_m4_express/samd51g19a_flash.ld diff --git a/hw/bsp/feather_m4_express/board.mk b/hw/bsp/feather_m4_express/board.mk new file mode 100644 index 00000000..c62d9bc3 --- /dev/null +++ b/hw/bsp/feather_m4_express/board.mk @@ -0,0 +1,47 @@ +CFLAGS += \ + -D__SAMD51J19A__ \ + -mthumb \ + -mabi=aapcs-linux \ + -mcpu=cortex-m4 \ + -mfloat-abi=hard \ + -mfpu=fpv4-sp-d16 \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_SAMD51 + +CFLAGS += -Wno-error=undef + +# All source paths should be relative to the top level. +LD_FILE = hw/bsp/metro_m4_express/samd51g19a_flash.ld + +SRC_C += \ + hw/mcu/microchip/samd/asf4/samd51/gcc/gcc/startup_samd51.c \ + hw/mcu/microchip/samd/asf4/samd51/gcc/system_samd51.c \ + hw/mcu/microchip/samd/asf4/samd51/hpl/gclk/hpl_gclk.c \ + hw/mcu/microchip/samd/asf4/samd51/hpl/mclk/hpl_mclk.c \ + hw/mcu/microchip/samd/asf4/samd51/hpl/osc32kctrl/hpl_osc32kctrl.c \ + hw/mcu/microchip/samd/asf4/samd51/hpl/oscctrl/hpl_oscctrl.c \ + hw/mcu/microchip/samd/asf4/samd51/hal/src/hal_atomic.c + +INC += \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/ \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/config \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/include \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/hal/include \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/hal/utils/include \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/port \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/hri \ + $(TOP)/hw/mcu/microchip/samd/asf4/samd51/CMSIS/Include + +# For TinyUSB port source +VENDOR = microchip +CHIP_FAMILY = samd51 + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM4F + +# For flash-jlink target +JLINK_DEVICE = ATSAMD51J19 +JLINK_IF = swd + +# flash using jlink +flash: flash-jlink diff --git a/hw/bsp/feather_m4_express/board_feather_m4_express.c b/hw/bsp/feather_m4_express/board_feather_m4_express.c new file mode 100644 index 00000000..2261e57b --- /dev/null +++ b/hw/bsp/feather_m4_express/board_feather_m4_express.c @@ -0,0 +1,120 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * 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 + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "bsp/board.h" + +#include "sam.h" +#include "hal/include/hal_gpio.h" +#include "hal/include/hal_init.h" +#include "hpl/gclk/hpl_gclk_base.h" +#include "hpl_mclk_config.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ +#define LED_PIN 23 +#define BUTTON_PIN 22 // pin D12 + +/* Referenced GCLKs, should be initialized firstly */ +#define _GCLK_INIT_1ST 0xFFFFFFFF + +/* Not referenced GCLKs, initialized last */ +#define _GCLK_INIT_LAST (~_GCLK_INIT_1ST) + +void board_init(void) +{ + // Clock init ( follow hpl_init.c ) + hri_nvmctrl_set_CTRLA_RWS_bf(NVMCTRL, 0); + + _osc32kctrl_init_sources(); + _oscctrl_init_sources(); + _mclk_init(); +#if _GCLK_INIT_1ST + _gclk_init_generators_by_fref(_GCLK_INIT_1ST); +#endif + _oscctrl_init_referenced_generators(); + _gclk_init_generators_by_fref(_GCLK_INIT_LAST); + + // Led init + gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); + gpio_set_pin_level(LED_PIN, 0); + + // Button init + gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer (samd SystemCoreClock may not correct) + SysTick_Config(CONF_CPU_FREQUENCY / 1000); +#endif + + /* USB Clock init + * The USB module requires a GCLK_USB of 48 MHz ~ 0.25% clock + * for low speed and full speed operation. */ + hri_gclk_write_PCHCTRL_reg(GCLK, USB_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK1_Val | GCLK_PCHCTRL_CHEN); + hri_mclk_set_AHBMASK_USB_bit(MCLK); + hri_mclk_set_APBBMASK_USB_bit(MCLK); + + // USB Pin Init + gpio_set_pin_direction(PIN_PA24, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA24, false); + gpio_set_pin_pull_mode(PIN_PA24, GPIO_PULL_OFF); + gpio_set_pin_direction(PIN_PA25, GPIO_DIRECTION_OUT); + gpio_set_pin_level(PIN_PA25, false); + gpio_set_pin_pull_mode(PIN_PA25, GPIO_PULL_OFF); + + gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM); + gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + gpio_set_pin_level(LED_PIN, state); +} + +uint32_t board_button_read(void) +{ + // button is active low + return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler (void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/feather_m4_express/samd51g19a_flash.ld b/hw/bsp/feather_m4_express/samd51g19a_flash.ld new file mode 100644 index 00000000..cf5db380 --- /dev/null +++ b/hw/bsp/feather_m4_express/samd51g19a_flash.ld @@ -0,0 +1,164 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD51G19A + * + * Copyright (c) 2017 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000 + 16K, LENGTH = 0x00080000 - 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 + bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000 + qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0xC000; + +/* Section Definitions */ +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + .bkupram (NOLOAD): + { + . = ALIGN(8); + _sbkupram = .; + *(.bkupram .bkupram.*); + . = ALIGN(8); + _ebkupram = .; + } > bkupram + + .qspi (NOLOAD): + { + . = ALIGN(8); + _sqspi = .; + *(.qspi .qspi.*); + . = ALIGN(8); + _eqspi = .; + } > qspi + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + end = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + STACK_SIZE; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/hw/bsp/metro_m4_express/board_metro_m4_express.c b/hw/bsp/metro_m4_express/board_metro_m4_express.c index 7c1b9ace..2abb44b4 100644 --- a/hw/bsp/metro_m4_express/board_metro_m4_express.c +++ b/hw/bsp/metro_m4_express/board_metro_m4_express.c @@ -36,7 +36,7 @@ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ #define LED_PIN 16 -#define BUTTON_PIN (32 + 17) // pin D2 +#define BUTTON_PIN 17 // pin D12 /* Referenced GCLKs, should be initialized firstly */ #define _GCLK_INIT_1ST 0xFFFFFFFF From e70232809389dec570d0f1e81a13885c2a48bb1b Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 1 Jul 2019 23:11:16 +0700 Subject: [PATCH 04/15] fix compiling --- examples/device/midi/src/tusb_config.h | 4 ++++ src/class/audio/audio.h | 2 +- src/class/midi/midi_device.c | 2 +- src/class/midi/midi_device.h | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/device/midi/src/tusb_config.h b/examples/device/midi/src/tusb_config.h index cb6eca33..222c1741 100644 --- a/examples/device/midi/src/tusb_config.h +++ b/examples/device/midi/src/tusb_config.h @@ -78,6 +78,10 @@ #define CFG_TUD_MIDI 1 #define CFG_TUD_CUSTOM_CLASS 0 +//------------- MIDI -------------// +#define CFG_TUD_MIDI_RX_BUFSIZE 64 +#define CFG_TUD_MIDI_TX_BUFSIZE 64 + #ifdef __cplusplus } #endif diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index a6f19858..83b8906d 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -43,7 +43,7 @@ typedef enum { AUDIO_SUBCLASS_CONTROL = 0x01 , ///< Audio Control AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming - AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming + AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming } audio_subclass_type_t; /// Audio Protocol Codes diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 2454db47..65a8df65 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -252,7 +252,7 @@ void midid_reset(uint8_t rhport) bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length) { // For now handle the audio control interface as well. - if ( AUDIO_SUBCLASS_AUDIO_CONTROL == p_interface_desc->bInterfaceSubClass) { + if ( AUDIO_SUBCLASS_CONTROL == p_interface_desc->bInterfaceSubClass) { uint8_t const * p_desc = tu_desc_next ( (uint8_t const *) p_interface_desc ); (*p_length) = sizeof(tusb_desc_interface_t); diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 45e00901..db995265 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -29,7 +29,9 @@ #include "common/tusb_common.h" #include "device/usbd.h" + #include "class/audio/audio.h" +#include "midi.h" //--------------------------------------------------------------------+ // Class Driver Configuration From 57433135ce0fd08b13bd4065ab3dcc9ec2fb3856 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 1 Jul 2019 23:19:14 +0700 Subject: [PATCH 05/15] fix midi template --- src/device/usbd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/usbd.h b/src/device/usbd.h index a0a84304..d3a5dce6 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -195,9 +195,9 @@ TU_ATTR_WEAK void tud_resume_cb(void); /* MS In Jack (External) */\ 6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EXTERNAL, 2, 0,\ /* MS Out Jack (Embedded), connected to In Jack External */\ - 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EMBEDDED, 3, 1, 2, 1,\ + 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EMBEDDED, 3, 1, 2, 1, 0,\ /* MS Out Jack (External), connected to In Jack Embedded */\ - 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, 4, 1, 1, 1,\ + 9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, 4, 1, 1, 1, 0,\ /* Endpoint Out */\ 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\ /* MS Endpoint (connected to embedded jack in) */\ From 3f3ef6f4e659ba53794667893bf7ee6be77f5d91 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Jul 2019 16:42:12 +0700 Subject: [PATCH 06/15] clean up --- src/class/cdc/cdc_device.h | 100 +++++++++++++++++++++++++++++------ src/class/midi/midi_device.c | 7 --- src/class/midi/midi_device.h | 61 ++++++++++++++------- 3 files changed, 126 insertions(+), 42 deletions(-) diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 3c1af9db..bd8aecfe 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -48,7 +48,7 @@ * @{ */ //--------------------------------------------------------------------+ -// APPLICATION API (Multiple Interfaces) +// Application API (Multiple Interfaces) // CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ bool tud_cdc_n_connected (uint8_t itf); @@ -68,26 +68,26 @@ uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str); bool tud_cdc_n_write_flush (uint8_t itf); //--------------------------------------------------------------------+ -// APPLICATION API (Interface0) +// Application API (Interface0) //--------------------------------------------------------------------+ -static inline bool tud_cdc_connected (void) { return tud_cdc_n_connected(0); } -static inline uint8_t tud_cdc_get_line_state (void) { return tud_cdc_n_get_line_state(0); } -static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding) { return tud_cdc_n_get_line_coding(0, coding);} -static inline void tud_cdc_set_wanted_char (char wanted) { tud_cdc_n_set_wanted_char(0, wanted); } +static inline bool tud_cdc_connected (void); +static inline uint8_t tud_cdc_get_line_state (void); +static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding); +static inline void tud_cdc_set_wanted_char (char wanted); -static inline uint32_t tud_cdc_available (void) { return tud_cdc_n_available(0); } -static inline signed char tud_cdc_read_char (void) { return tud_cdc_n_read_char(0); } -static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize) { return tud_cdc_n_read(0, buffer, bufsize); } -static inline void tud_cdc_read_flush (void) { tud_cdc_n_read_flush(0); } -static inline signed char tud_cdc_peek (int pos) { return tud_cdc_n_peek(0, pos); } +static inline uint32_t tud_cdc_available (void); +static inline signed char tud_cdc_read_char (void); +static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize); +static inline void tud_cdc_read_flush (void); +static inline signed char tud_cdc_peek (int pos); -static inline uint32_t tud_cdc_write_char (char ch) { return tud_cdc_n_write_char(0, ch); } -static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize) { return tud_cdc_n_write(0, buffer, bufsize); } -static inline uint32_t tud_cdc_write_str (char const* str) { return tud_cdc_n_write_str(0, str); } -static inline bool tud_cdc_write_flush (void) { return tud_cdc_n_write_flush(0); } +static inline uint32_t tud_cdc_write_char (char ch); +static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize); +static inline uint32_t tud_cdc_write_str (char const* str); +static inline bool tud_cdc_write_flush (void); //--------------------------------------------------------------------+ -// APPLICATION CALLBACK API (WEAK is optional) +// Application Callback API (weak is optional) //--------------------------------------------------------------------+ // Invoked when received new data @@ -102,6 +102,74 @@ TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); // Invoked when line coding is change via SET_LINE_CODING TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); +//--------------------------------------------------------------------+ +// Application API (Interface0) Implementation +//--------------------------------------------------------------------+ +static inline bool tud_cdc_connected (void) +{ + return tud_cdc_n_connected(0); +} + +static inline uint8_t tud_cdc_get_line_state (void) +{ + return tud_cdc_n_get_line_state(0); +} + +static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding) +{ + return tud_cdc_n_get_line_coding(0, coding); +} + +static inline void tud_cdc_set_wanted_char (char wanted) +{ + tud_cdc_n_set_wanted_char(0, wanted); +} + +static inline uint32_t tud_cdc_available (void) +{ + return tud_cdc_n_available(0); +} + +static inline signed char tud_cdc_read_char (void) +{ + return tud_cdc_n_read_char(0); +} + +static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize) +{ + return tud_cdc_n_read(0, buffer, bufsize); +} + +static inline void tud_cdc_read_flush (void) +{ + tud_cdc_n_read_flush(0); +} + +static inline signed char tud_cdc_peek (int pos) +{ + return tud_cdc_n_peek(0, pos); +} + +static inline uint32_t tud_cdc_write_char (char ch) +{ + return tud_cdc_n_write_char(0, ch); +} + +static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize) +{ + return tud_cdc_n_write(0, buffer, bufsize); +} + +static inline uint32_t tud_cdc_write_str (char const* str) +{ + return tud_cdc_n_write_str(0, str); +} + +static inline bool tud_cdc_write_flush (void) +{ + return tud_cdc_n_write_flush(0); +} + /** @} */ /** @} */ diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 65a8df65..fbfbcae0 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -87,12 +87,6 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t jack_id) return tu_fifo_count(&_midid_itf[itf].rx_ff); } -char tud_midi_n_read_char(uint8_t itf, uint8_t jack_id) -{ - char ch; - return tu_fifo_read(&_midid_itf[itf].rx_ff, &ch) ? ch : (-1); -} - uint32_t tud_midi_n_read(uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize) { return tu_fifo_read_n(&_midid_itf[itf].rx_ff, buffer, bufsize); @@ -103,7 +97,6 @@ void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id) tu_fifo_clear(&_midid_itf[itf].rx_ff); } - void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bufsize) { if (bufsize % 4 != 0) { return; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index db995265..c08b119a 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -51,41 +51,64 @@ * @{ */ //--------------------------------------------------------------------+ -// APPLICATION API (Multiple Interfaces) +// Application API (Multiple Interfaces) // CFG_TUD_MIDI > 1 //--------------------------------------------------------------------+ bool tud_midi_n_connected (uint8_t itf); - uint32_t tud_midi_n_available (uint8_t itf, uint8_t jack_id); -char tud_midi_n_read_char (uint8_t itf, uint8_t jack_id); uint32_t tud_midi_n_read (uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize); void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id); -char tud_midi_n_peek (uint8_t itf, uint8_t jack_id, int pos); - -uint32_t tud_midi_n_write_char (uint8_t itf, char ch); uint32_t tud_midi_n_write (uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); bool tud_midi_n_write_flush (uint8_t itf); //--------------------------------------------------------------------+ -// APPLICATION API (Interface0) +// Application API (Interface0) //--------------------------------------------------------------------+ -static inline bool tud_midi_connected (void) { return tud_midi_n_connected(0); } - -static inline uint32_t tud_midi_available (void) { return tud_midi_n_available(0, 0); } -static inline char tud_midi_read_char (void) { return tud_midi_n_read_char(0, 0); } -static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize) { return tud_midi_n_read(0, 0, buffer, bufsize); } -static inline void tud_midi_read_flush (void) { tud_midi_n_read_flush(0, 0); } -static inline char tud_midi_peek (int pos) { return tud_midi_n_peek(0, 0, pos); } - -static inline uint32_t tud_midi_write_char (char ch) { return tud_midi_n_write_char(0, ch); } -static inline uint32_t tud_midi_write (uint8_t jack_id, void const* buffer, uint32_t bufsize) { return tud_midi_n_write(0, jack_id, buffer, bufsize); } -static inline bool tud_midi_write_flush (void) { return tud_midi_n_write_flush(0); } +static inline bool tud_midi_connected (void); +static inline uint32_t tud_midi_available (void); +static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize); +static inline void tud_midi_read_flush (void); +static inline uint32_t tud_midi_write (uint8_t jack_id, void const* buffer, uint32_t bufsize); +static inline bool tud_midi_write_flush (void); //--------------------------------------------------------------------+ -// APPLICATION CALLBACK API (WEAK is optional) +// Application Callback API (weak is optional) //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf); +//--------------------------------------------------------------------+ +// Application API (Interface0) Implementation +//--------------------------------------------------------------------+ +static inline bool tud_midi_connected (void) +{ + return tud_midi_n_connected(0); +} + +static inline uint32_t tud_midi_available (void) +{ + return tud_midi_n_available(0, 0); +} + +static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize) +{ + return tud_midi_n_read(0, 0, buffer, bufsize); +} + +static inline void tud_midi_read_flush (void) +{ + tud_midi_n_read_flush(0, 0); +} + +static inline uint32_t tud_midi_write (uint8_t jack_id, void const* buffer, uint32_t bufsize) +{ + return tud_midi_n_write(0, jack_id, buffer, bufsize); +} + +static inline bool tud_midi_write_flush (void) +{ + return tud_midi_n_write_flush(0); +} + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ From 62d3b916919c33fba001ff046b97e38200feb2df Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Jul 2019 18:23:42 +0700 Subject: [PATCH 07/15] clean up --- src/class/cdc/cdc_device.c | 13 +++++++------ src/class/midi/midi_device.h | 1 - 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index d9e12830..46493679 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -73,21 +73,18 @@ typedef struct //--------------------------------------------------------------------+ CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; -//bool pending_read_from_host; TODO remove static void _prep_out_transaction (uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; // skip if previous transfer not complete if ( usbd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_out) ) return; - //if (pending_read_from_host) return; // Prepare for incoming data but only allow what we can store in the ring buffer. uint16_t max_read = tu_fifo_remaining(&p_cdc->rx_ff); if ( max_read >= CFG_TUD_CDC_EPSIZE ) { usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE); -// pending_read_from_host = true; } } @@ -296,7 +293,6 @@ bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t } // Prepare for incoming data -// pending_read_from_host = false; _prep_out_transaction(cdc_id); return true; @@ -392,11 +388,16 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (tud_cdc_rx_cb && tu_fifo_count(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf); // prepare for OUT transaction -// pending_read_from_host = false; _prep_out_transaction(itf); } - // nothing to do with in and notif endpoint for now + // sent data +// if ( ep_addr == p_cdc->ep_in ) +// { +// +// } + + // nothing to do with notif endpoint for now return true; } diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index c08b119a..656fa4fb 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -40,7 +40,6 @@ #define CFG_TUD_MIDI_EPSIZE 64 #endif - #ifdef __cplusplus extern "C" { #endif From 1a0e02fa1b004e68a00e5fbfbc4ea854c9036875 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Jul 2019 00:52:25 +0700 Subject: [PATCH 08/15] tested midi example --- examples/device/cdc_msc_hid/src/main.c | 2 +- examples/device/hid_generic_inout/src/main.c | 2 +- examples/device/midi/src/main.c | 54 +++++++++++++++++++- examples/device/msc_dual_lun/src/main.c | 2 +- examples/host/cdc_msc_hid/src/main.c | 2 +- src/class/cdc/cdc_device.h | 2 +- src/class/midi/midi_device.h | 18 ++++++- 7 files changed, 75 insertions(+), 7 deletions(-) diff --git a/examples/device/cdc_msc_hid/src/main.c b/examples/device/cdc_msc_hid/src/main.c index 8ebdddd8..771638ac 100644 --- a/examples/device/cdc_msc_hid/src/main.c +++ b/examples/device/cdc_msc_hid/src/main.c @@ -263,7 +263,7 @@ void led_blinking_task(void) static uint32_t start_ms = 0; static bool led_state = false; - // Blink every 1000 ms + // Blink every interval ms if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; diff --git a/examples/device/hid_generic_inout/src/main.c b/examples/device/hid_generic_inout/src/main.c index bbc61a79..77d6cf7b 100644 --- a/examples/device/hid_generic_inout/src/main.c +++ b/examples/device/hid_generic_inout/src/main.c @@ -154,7 +154,7 @@ void led_blinking_task(void) static uint32_t start_ms = 0; static bool led_state = false; - // Blink every 1000 ms + // Blink every interval ms if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; diff --git a/examples/device/midi/src/main.c b/examples/device/midi/src/main.c index 60500df9..0cb9b522 100644 --- a/examples/device/midi/src/main.c +++ b/examples/device/midi/src/main.c @@ -30,6 +30,12 @@ #include "bsp/board.h" #include "tusb.h" +/* This MIDI example send sequence of note (on/off) repeatedly. To test on PC, you need to install + * synth software and midi connection management software. On + * - Linux (Ubuntu) : install qsynth, qjackctl. Then connect TinyUSB output port to FLUID Synth input port + * + */ + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ @@ -48,6 +54,7 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); +void midi_task(void); /*------------- MAIN -------------*/ int main(void) @@ -62,6 +69,8 @@ int main(void) tud_task(); led_blinking_task(); + + midi_task(); } return 0; @@ -98,6 +107,49 @@ void tud_resume_cb(void) blink_interval_ms = BLINK_MOUNTED; } +//--------------------------------------------------------------------+ +// MIDI Task +//--------------------------------------------------------------------+ + +// Variable that holds the current position in the sequence. +uint32_t note_pos = 0; + +// Store example melody as an array of note values +uint8_t note_sequence[] = +{ + 74,78,81,86,90,93,98,102,57,61,66,69,73,78,81,85,88,92,97,100,97,92,88,85,81,78, + 74,69,66,62,57,62,66,69,74,78,81,86,90,93,97,102,97,93,90,85,81,78,73,68,64,61, + 56,61,64,68,74,78,81,86,90,93,98,102 +}; + +void midi_task(void) +{ + static uint32_t start_ms = 0; + + // send note every 1000 ms + if (board_millis() - start_ms < 286) return; // not enough time + start_ms += 286; + + // Previous positions in the note sequence. + int previous = note_pos - 1; + + // If we currently are at position 0, set the + // previous position to the last note in the sequence. + if (previous < 0) previous = sizeof(note_sequence) - 1; + + // Send Note On for current position at full velocity (127) on channel 1. + tudi_midi_write24(0, 0x90, note_sequence[note_pos], 127); + + // Send Note Off for previous note. + tudi_midi_write24(0, 0x80, note_sequence[previous], 0); + + // Increment position + note_pos++; + + // If we are at the end of the sequence, start over. + if (note_pos >= sizeof(note_sequence)) note_pos = 0; +} + //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ @@ -106,7 +158,7 @@ void led_blinking_task(void) static uint32_t start_ms = 0; static bool led_state = false; - // Blink every 1000 ms + // Blink every interval ms if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; diff --git a/examples/device/msc_dual_lun/src/main.c b/examples/device/msc_dual_lun/src/main.c index 60500df9..060f2064 100644 --- a/examples/device/msc_dual_lun/src/main.c +++ b/examples/device/msc_dual_lun/src/main.c @@ -106,7 +106,7 @@ void led_blinking_task(void) static uint32_t start_ms = 0; static bool led_state = false; - // Blink every 1000 ms + // Blink every interval ms if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 61f10112..8625bbcd 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -169,7 +169,7 @@ void led_blinking_task(void) static bool led_state = false; - // Blink every 1000 ms + // Blink every interval ms if ( board_millis() - start_ms < interval_ms) return; // not enough time start_ms += interval_ms; diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index bd8aecfe..8d09094a 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -103,7 +103,7 @@ TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); //--------------------------------------------------------------------+ -// Application API (Interface0) Implementation +// Inline Functions //--------------------------------------------------------------------+ static inline bool tud_cdc_connected (void) { diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 656fa4fb..6458a683 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -60,6 +60,8 @@ void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id); uint32_t tud_midi_n_write (uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); bool tud_midi_n_write_flush (uint8_t itf); +static inline uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); + //--------------------------------------------------------------------+ // Application API (Interface0) //--------------------------------------------------------------------+ @@ -68,6 +70,7 @@ static inline uint32_t tud_midi_available (void); static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize); static inline void tud_midi_read_flush (void); static inline uint32_t tud_midi_write (uint8_t jack_id, void const* buffer, uint32_t bufsize); +static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); static inline bool tud_midi_write_flush (void); //--------------------------------------------------------------------+ @@ -76,8 +79,15 @@ static inline bool tud_midi_write_flush (void); TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf); //--------------------------------------------------------------------+ -// Application API (Interface0) Implementation +// Inline Functions //--------------------------------------------------------------------+ + +static inline uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3) +{ + uint8_t msg[3] = { b1, b2, b3 }; + return tud_midi_n_write(itf, jack_id, msg, 3); +} + static inline bool tud_midi_connected (void) { return tud_midi_n_connected(0); @@ -103,6 +113,12 @@ static inline uint32_t tud_midi_write (uint8_t jack_id, void const* buffer, uint return tud_midi_n_write(0, jack_id, buffer, bufsize); } +static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3) +{ + uint8_t msg[3] = { b1, b2, b3 }; + return tud_midi_write(jack_id, msg, 3); +} + static inline bool tud_midi_write_flush (void) { return tud_midi_n_write_flush(0); From 5273907d97affade7cb8e9ac293ecdb9b6eba7b8 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Jul 2019 00:53:58 +0700 Subject: [PATCH 09/15] rename midi example to midi_test --- examples/device/{midi => midi_test}/Makefile | 0 examples/device/{midi => midi_test}/src/main.c | 0 examples/device/{midi => midi_test}/src/tusb_config.h | 0 examples/device/{midi => midi_test}/src/usb_descriptors.c | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename examples/device/{midi => midi_test}/Makefile (100%) rename examples/device/{midi => midi_test}/src/main.c (100%) rename examples/device/{midi => midi_test}/src/tusb_config.h (100%) rename examples/device/{midi => midi_test}/src/usb_descriptors.c (100%) diff --git a/examples/device/midi/Makefile b/examples/device/midi_test/Makefile similarity index 100% rename from examples/device/midi/Makefile rename to examples/device/midi_test/Makefile diff --git a/examples/device/midi/src/main.c b/examples/device/midi_test/src/main.c similarity index 100% rename from examples/device/midi/src/main.c rename to examples/device/midi_test/src/main.c diff --git a/examples/device/midi/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h similarity index 100% rename from examples/device/midi/src/tusb_config.h rename to examples/device/midi_test/src/tusb_config.h diff --git a/examples/device/midi/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c similarity index 100% rename from examples/device/midi/src/usb_descriptors.c rename to examples/device/midi_test/src/usb_descriptors.c From 6a8465384b428e25e8387f7921478a533ac57591 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Jul 2019 00:55:33 +0700 Subject: [PATCH 10/15] include midi_test in travis build --- tools/build_all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_all.py b/tools/build_all.py index 4b0cf982..93bdef4c 100644 --- a/tools/build_all.py +++ b/tools/build_all.py @@ -12,7 +12,7 @@ success_count = 0 fail_count = 0 exit_status = 0 -all_device_example = ["cdc_msc_hid", "msc_dual_lun", "hid_generic_inout"] +all_device_example = ["cdc_msc_hid", "hid_generic_inout", "midi_test", "msc_dual_lun"] all_boards = [] for entry in os.scandir("hw/bsp"): From ea29eb49af790d043d127272238f1a670a927a6e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Jul 2019 01:17:26 +0700 Subject: [PATCH 11/15] example clean up --- examples/device/cdc_msc_hid/src/tusb_config.h | 15 +++------------ .../device/cdc_msc_hid_freertos/src/tusb_config.h | 12 +++--------- .../device/hid_generic_inout/src/tusb_config.h | 4 +--- examples/device/midi_test/src/tusb_config.h | 2 +- examples/device/msc_dual_lun/src/tusb_config.h | 4 +--- 5 files changed, 9 insertions(+), 28 deletions(-) diff --git a/examples/device/cdc_msc_hid/src/tusb_config.h b/examples/device/cdc_msc_hid/src/tusb_config.h index 2c89a63b..e55dc9d0 100644 --- a/examples/device/cdc_msc_hid/src/tusb_config.h +++ b/examples/device/cdc_msc_hid/src/tusb_config.h @@ -79,25 +79,16 @@ #define CFG_TUD_MIDI 0 #define CFG_TUD_CUSTOM_CLASS 0 -//------------- CDC -------------// - -// FIFO size of CDC TX and RX +// CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE 64 #define CFG_TUD_CDC_TX_BUFSIZE 64 -//------------- MSC -------------// - -// Buffer size of Device Mass storage +// MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_BUFSIZE 512 -//------------- HID -------------// - -// Should be sufficient to hold ID (if any) + Data +// HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_BUFSIZE 16 -#define CFG_TUD_MIDI_RX_BUFSIZE 512 -#define CFG_TUD_MIDI_TX_BUFSIZE 512 - #ifdef __cplusplus } #endif diff --git a/examples/device/cdc_msc_hid_freertos/src/tusb_config.h b/examples/device/cdc_msc_hid_freertos/src/tusb_config.h index b4e18de9..76ec948e 100644 --- a/examples/device/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_hid_freertos/src/tusb_config.h @@ -79,20 +79,14 @@ #define CFG_TUD_MIDI 0 #define CFG_TUD_CUSTOM_CLASS 0 -//------------- CDC -------------// - -// FIFO size of CDC TX and RX +// CDC FIFO size of TX and RX #define CFG_TUD_CDC_RX_BUFSIZE 64 #define CFG_TUD_CDC_TX_BUFSIZE 64 -//------------- MSC -------------// - -// Buffer size of Device Mass storage +// MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_BUFSIZE 512 -//------------- HID -------------// - -// Should be sufficient to hold ID (if any) + Data +// HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_BUFSIZE 16 #ifdef __cplusplus diff --git a/examples/device/hid_generic_inout/src/tusb_config.h b/examples/device/hid_generic_inout/src/tusb_config.h index dc7d9881..fb19d516 100644 --- a/examples/device/hid_generic_inout/src/tusb_config.h +++ b/examples/device/hid_generic_inout/src/tusb_config.h @@ -78,9 +78,7 @@ #define CFG_TUD_MIDI 0 #define CFG_TUD_CUSTOM_CLASS 0 -//------------- HID -------------// - -// Should be sufficient to hold ID (if any) + Data +// HID buffer size Should be sufficient to hold ID (if any) + Data #define CFG_TUD_HID_BUFSIZE 64 #ifdef __cplusplus diff --git a/examples/device/midi_test/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h index 222c1741..6ea2f43d 100644 --- a/examples/device/midi_test/src/tusb_config.h +++ b/examples/device/midi_test/src/tusb_config.h @@ -78,7 +78,7 @@ #define CFG_TUD_MIDI 1 #define CFG_TUD_CUSTOM_CLASS 0 -//------------- MIDI -------------// +// MIDI FIFO size of TX and RX #define CFG_TUD_MIDI_RX_BUFSIZE 64 #define CFG_TUD_MIDI_TX_BUFSIZE 64 diff --git a/examples/device/msc_dual_lun/src/tusb_config.h b/examples/device/msc_dual_lun/src/tusb_config.h index ae57b4d6..db9974ea 100644 --- a/examples/device/msc_dual_lun/src/tusb_config.h +++ b/examples/device/msc_dual_lun/src/tusb_config.h @@ -78,9 +78,7 @@ #define CFG_TUD_MIDI 0 #define CFG_TUD_CUSTOM_CLASS 0 -//------------- MSC -------------// - -// Buffer size of Device Mass storage +// MSC Buffer size of Device Mass storage #define CFG_TUD_MSC_BUFSIZE 512 #ifdef __cplusplus From 50f4c61d7cbacea6de43f2905de89e269048b21e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Jul 2019 01:22:41 +0700 Subject: [PATCH 12/15] fix midi_write prototype --- src/class/midi/midi_device.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 6458a683..10af2127 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -69,7 +69,7 @@ static inline bool tud_midi_connected (void); static inline uint32_t tud_midi_available (void); static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize); static inline void tud_midi_read_flush (void); -static inline uint32_t tud_midi_write (uint8_t jack_id, void const* buffer, uint32_t bufsize); +static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); static inline bool tud_midi_write_flush (void); @@ -108,7 +108,7 @@ static inline void tud_midi_read_flush (void) tud_midi_n_read_flush(0, 0); } -static inline uint32_t tud_midi_write (uint8_t jack_id, void const* buffer, uint32_t bufsize) +static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize) { return tud_midi_n_write(0, jack_id, buffer, bufsize); } From b0e5a1a9ec52d85fdab44d5aa2cc72e15e5315cc Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Jul 2019 01:27:51 +0700 Subject: [PATCH 13/15] remove tud_midi_write_flush() send asap. rename tud_midi_connected() to tud_midi_mounted() --- src/class/cdc/cdc_device.c | 6 ++++-- src/class/midi/midi_device.c | 18 +++++++++--------- src/class/midi/midi_device.h | 15 ++++----------- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 46493679..6d13dafc 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -370,7 +370,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ uint8_t const itf = 0; cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; - // receive new data + // Received new data if ( ep_addr == p_cdc->ep_out ) { for(uint32_t i=0; iep_in ) // { // diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index fbfbcae0..76776d71 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -74,7 +74,8 @@ typedef struct //--------------------------------------------------------------------+ CFG_TUSB_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI]; -bool tud_midi_n_connected(uint8_t itf) { +bool tud_midi_n_mounted (uint8_t itf) +{ midid_interface_t* midi = &_midid_itf[itf]; return midi->itf_num != 0; } @@ -126,15 +127,14 @@ void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bu static bool maybe_transmit(midid_interface_t* midi, uint8_t itf_index) { - TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, midi->ep_in) ); // skip if previous transfer not complete + TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, midi->ep_in) ); // skip if previous transfer not complete - uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EPSIZE); - if (count > 0) - { - TU_VERIFY( tud_midi_n_connected(itf_index) ); // fifo is empty if not connected - TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, midi->ep_in, midi->epin_buf, count) ); - } - return true; + uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EPSIZE); + if (count > 0) + { + TU_ASSERT( usbd_edpt_xfer(TUD_OPT_RHPORT, midi->ep_in, midi->epin_buf, count) ); + } + return true; } uint32_t tud_midi_n_write(uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize) diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 10af2127..939c8c6e 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -53,25 +53,23 @@ // Application API (Multiple Interfaces) // CFG_TUD_MIDI > 1 //--------------------------------------------------------------------+ -bool tud_midi_n_connected (uint8_t itf); +bool tud_midi_n_mounted (uint8_t itf); uint32_t tud_midi_n_available (uint8_t itf, uint8_t jack_id); uint32_t tud_midi_n_read (uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize); void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id); uint32_t tud_midi_n_write (uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); -bool tud_midi_n_write_flush (uint8_t itf); static inline uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); //--------------------------------------------------------------------+ // Application API (Interface0) //--------------------------------------------------------------------+ -static inline bool tud_midi_connected (void); +static inline bool tud_midi_mounted (void); static inline uint32_t tud_midi_available (void); static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize); static inline void tud_midi_read_flush (void); static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); -static inline bool tud_midi_write_flush (void); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) @@ -88,9 +86,9 @@ static inline uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t return tud_midi_n_write(itf, jack_id, msg, 3); } -static inline bool tud_midi_connected (void) +static inline bool tud_midi_mounted (void) { - return tud_midi_n_connected(0); + return tud_midi_n_mounted(0); } static inline uint32_t tud_midi_available (void) @@ -119,11 +117,6 @@ static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b return tud_midi_write(jack_id, msg, 3); } -static inline bool tud_midi_write_flush (void) -{ - return tud_midi_n_write_flush(0); -} - //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ From 1b242cb3c6135b380bc97cf02711605d64703233 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Jul 2019 01:31:56 +0700 Subject: [PATCH 14/15] clean up --- src/class/midi/midi_device.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 939c8c6e..490abaf8 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -53,23 +53,24 @@ // Application API (Multiple Interfaces) // CFG_TUD_MIDI > 1 //--------------------------------------------------------------------+ -bool tud_midi_n_mounted (uint8_t itf); -uint32_t tud_midi_n_available (uint8_t itf, uint8_t jack_id); -uint32_t tud_midi_n_read (uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize); -void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id); -uint32_t tud_midi_n_write (uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); +bool tud_midi_n_mounted (uint8_t itf); +uint32_t tud_midi_n_available (uint8_t itf, uint8_t jack_id); +uint32_t tud_midi_n_read (uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize); +void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id); +uint32_t tud_midi_n_write (uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); -static inline uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); +static inline +uint32_t tud_midi_n_write24 (uint8_t itf, uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); //--------------------------------------------------------------------+ // Application API (Interface0) //--------------------------------------------------------------------+ -static inline bool tud_midi_mounted (void); -static inline uint32_t tud_midi_available (void); -static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize); -static inline void tud_midi_read_flush (void); -static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); -static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); +static inline bool tud_midi_mounted (void); +static inline uint32_t tud_midi_available (void); +static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize); +static inline void tud_midi_read_flush (void); +static inline uint32_t tud_midi_write (uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize); +static inline uint32_t tudi_midi_write24 (uint8_t jack_id, uint8_t b1, uint8_t b2, uint8_t b3); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) From 3ec279b424ea463577420e75db54deebf409be2b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 4 Jul 2019 01:57:49 +0700 Subject: [PATCH 15/15] update docs --- README.md | 4 ++-- docs/boards.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fca60849..8cd2c1ea 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,8 @@ The stack supports the following MCUs - **Nordic:** nRF52840 - **NXP:** LPC11Uxx, LPC13xx, LPC175x_6x, LPC177x_8x, LPC18xx, LPC40xx, LPC43xx -- **MicroChip:** SAMD21, SAMD51 -- **ST:** STM32F4 +- **MicroChip:** SAMD21, SAMD51 (device only) +- **ST:** STM32F4 (device only) [Here is the list of supported Boards](docs/boards.md) diff --git a/docs/boards.md b/docs/boards.md index da49d4a1..dee2ceeb 100644 --- a/docs/boards.md +++ b/docs/boards.md @@ -25,6 +25,7 @@ This code base already had supported for a handful of following boards ### MicroChip SAMD +- [Adafruit Feather M4 Express](https://www.adafruit.com/product/3857) - [Adafruit Metro M0 Express](https://www.adafruit.com/product/3505) - [Adafruit Metro M4 Express](https://www.adafruit.com/product/3382)