add tud_speed_get()

- define both fs and hs configuration descriptor
- rename CFG_TUD_CDC_EPSIZE to CFG_TUD_CDC_EP_BUFSIZE with default size of 64 for FS, and 512 for HS
This commit is contained in:
hathach 2020-07-16 00:44:09 +07:00
parent e1b3fe81c4
commit 706413f751
9 changed files with 90 additions and 28 deletions

View File

@ -74,10 +74,10 @@ uint8_t const * tud_descriptor_device_cb(void)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
enum enum
{ {
ITF_NUM_CDC1 = 0, ITF_NUM_CDC_0 = 0,
ITF_NUM_CDC_DATA1, ITF_NUM_CDC_0_DATA,
ITF_NUM_CDC2, ITF_NUM_CDC_1,
ITF_NUM_CDC_DATA2, ITF_NUM_CDC_1_DATA,
ITF_NUM_TOTAL ITF_NUM_TOTAL
}; };
@ -86,30 +86,58 @@ enum
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 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 ... // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
#define EPNUM_CDC 2 #define EPNUM_CDC_0_NOTIF 0x81
#define EPNUM_CDC_0_DATA 0x02
#define EPNUM_CDC_1_NOTIF 0x84
#define EPNUM_CDC_1_DATA 0x05
#else #else
#define EPNUM_CDC 2 #define EPNUM_CDC_0_NOTIF 0x81
#define EPNUM_CDC_0_DATA 0x02
#define EPNUM_CDC_1_NOTIF 0x83
#define EPNUM_CDC_1_DATA 0x04
#endif #endif
uint8_t const desc_configuration[] = uint8_t const desc_fs_configuration[] =
{ {
// Config number, interface count, string index, total length, attribute, power in mA // Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size. // 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC1, 4, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, TUD_OPT_HIGH_SPEED ? 512 : 64), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_DATA, 0x80 | EPNUM_CDC_0_DATA, 64),
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size. // 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC2, 4, 0x83, 8, EPNUM_CDC + 2, 0x80 | (EPNUM_CDC + 2), TUD_OPT_HIGH_SPEED ? 512 : 64), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_DATA, 0x80 | EPNUM_CDC_1_DATA, 64),
}; };
#if TUD_OPT_HIGH_SPEED
uint8_t const desc_hs_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_DATA, 0x80 | EPNUM_CDC_0_DATA, 512),
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_DATA, 0x80 | EPNUM_CDC_1_DATA, 512),
};
#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;
#if TUD_OPT_HIGH_SPEED
// Although we are highspeed, host may be fullspeed.
return (tud_speed_get() == TUSB_SPEED_HIGH ) ? desc_hs_configuration : desc_fs_configuration;
#else
return desc_fs_configuration;
#endif
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -114,18 +114,32 @@ enum
#endif #endif
uint8_t const desc_configuration[] = uint8_t const desc_fs_configuration[] =
{ {
// Config number, interface count, string index, total length, attribute, power in mA // Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size. // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
// Interface number, string index, EP Out & EP In address, EP size // Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
}; };
#if TUD_OPT_HIGH_SPEED
uint8_t const desc_hs_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
};
#endif
// Invoked when received GET CONFIGURATION DESCRIPTOR // Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
@ -133,7 +147,13 @@ uint8_t const desc_configuration[] =
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;
#if TUD_OPT_HIGH_SPEED
// Although we are highspeed, host may be fullspeed.
return (tud_speed_get() == TUSB_SPEED_HIGH ) ? desc_hs_configuration : desc_fs_configuration;
#else
return desc_fs_configuration;
#endif
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -86,10 +86,10 @@ enum
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 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 ... // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
#define EPNUM_CDC 2 #define EPNUM_CDC_0 2
#define EPNUM_VENDOR 5 #define EPNUM_VENDOR 5
#else #else
#define EPNUM_CDC 2 #define EPNUM_CDC_0 2
#define EPNUM_VENDOR 3 #define EPNUM_VENDOR 3
#endif #endif
@ -99,7 +99,7 @@ uint8_t const desc_configuration[] =
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size. // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, TUD_OPT_HIGH_SPEED ? 512 : 64), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, EPNUM_CDC_0, 0x80 | EPNUM_CDC_0, TUD_OPT_HIGH_SPEED ? 512 : 64),
// Interface number, string index, EP Out & IN address, EP size // Interface number, string index, EP Out & IN address, EP size
TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 5, EPNUM_VENDOR, 0x80 | EPNUM_VENDOR, TUD_OPT_HIGH_SPEED ? 512 : 64) TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 5, EPNUM_VENDOR, 0x80 | EPNUM_VENDOR, TUD_OPT_HIGH_SPEED ? 512 : 64)

View File

@ -131,8 +131,14 @@ size: $(BUILD)/$(BOARD)-firmware.elf
@$(SIZE) $< @$(SIZE) $<
-@echo '' -@echo ''
.PHONY: clean
clean: clean:
rm -rf $(BUILD) $(RM) -rf $(BUILD)
# Print out the value of a make variable.
# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile
print-%:
@echo $* = $($*)
# Flash binary using Jlink # Flash binary using Jlink
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)

View File

@ -61,8 +61,8 @@ typedef struct
#endif #endif
// Endpoint Transfer buffer // Endpoint Transfer buffer
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EPSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EPSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE];
}cdcd_interface_t; }cdcd_interface_t;
@ -82,9 +82,9 @@ static void _prep_out_transaction (uint8_t itf)
// Prepare for incoming data but only allow what we can store in the ring buffer. // 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); uint16_t max_read = tu_fifo_remaining(&p_cdc->rx_ff);
if ( max_read >= TU_ARRAY_SIZE(p_cdc->epout_buf) ) if ( max_read >= sizeof(p_cdc->epout_buf) )
{ {
usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_out, p_cdc->epout_buf, TU_ARRAY_SIZE(p_cdc->epout_buf)); usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf));
} }
} }
@ -148,7 +148,7 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize)
#if 0 // TODO issue with circuitpython's REPL #if 0 // TODO issue with circuitpython's REPL
// flush if queue more than endpoint size // flush if queue more than endpoint size
if ( tu_fifo_count(&_cdcd_itf[itf].tx_ff) >= CFG_TUD_CDC_EPSIZE ) if ( tu_fifo_count(&_cdcd_itf[itf].tx_ff) >= CFG_TUD_CDC_EP_BUFSIZE )
{ {
tud_cdc_n_write_flush(itf); tud_cdc_n_write_flush(itf);
} }
@ -164,7 +164,7 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf)
// skip if previous transfer not complete yet // skip if previous transfer not complete yet
TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_in), 0 ); TU_VERIFY( !usbd_edpt_busy(TUD_OPT_RHPORT, p_cdc->ep_in), 0 );
uint16_t count = tu_fifo_read_n(&_cdcd_itf[itf].tx_ff, p_cdc->epin_buf, TU_ARRAY_SIZE(p_cdc->epin_buf)); uint16_t count = tu_fifo_read_n(&_cdcd_itf[itf].tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf));
if ( count ) if ( count )
{ {
TU_VERIFY( tud_cdc_n_connected(itf), 0 ); // fifo is empty if not connected TU_VERIFY( tud_cdc_n_connected(itf), 0 ); // fifo is empty if not connected
@ -420,7 +420,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
{ {
// There is no data left, a ZLP should be sent if // There is no data left, a ZLP should be sent if
// xferred_bytes is multiple of EP size and not zero // xferred_bytes is multiple of EP size and not zero
if ( xferred_bytes && (0 == (xferred_bytes % CFG_TUD_CDC_EPSIZE)) ) if ( xferred_bytes && (0 == (xferred_bytes % CFG_TUD_CDC_EP_BUFSIZE)) )
{ {
usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_in, NULL, 0); usbd_edpt_xfer(TUD_OPT_RHPORT, p_cdc->ep_in, NULL, 0);
} }

View File

@ -34,8 +34,8 @@
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Class Driver Configuration // Class Driver Configuration
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#ifndef CFG_TUD_CDC_EPSIZE #ifndef CFG_TUD_CDC_EP_BUFSIZE
#define CFG_TUD_CDC_EPSIZE 64 #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -294,6 +294,11 @@ void usbd_driver_print_control_complete_name(bool (*control_complete) (uint8_t,
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Application API // Application API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
tusb_speed_t tud_speed_get(void)
{
return (tusb_speed_t) _usbd_dev.speed;
}
bool tud_mounted(void) bool tud_mounted(void)
{ {
return _usbd_dev.configured; return _usbd_dev.configured;

View File

@ -53,6 +53,9 @@ bool tud_task_event_ready(void);
// Interrupt handler, name alias to DCD // Interrupt handler, name alias to DCD
#define tud_int_handler dcd_int_handler #define tud_int_handler dcd_int_handler
// Get current bus speed
tusb_speed_t tud_speed_get(void);
// Check if device is connected and configured // Check if device is connected and configured
bool tud_mounted(void); bool tud_mounted(void);

View File

@ -38,7 +38,7 @@ all_boards.sort()
def build_example(example, board): def build_example(example, board):
subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True, subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return subprocess.run("make -j 4 -C examples/device/{} BOARD={} all".format(example, board), shell=True, return subprocess.run("make -j -C examples/device/{} BOARD={} all".format(example, board), shell=True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def build_size(example, board): def build_size(example, board):