Merge branch 'master' of github.com:HiFiPhile/tinyusb into vendor_fifo
This commit is contained in:
@@ -924,6 +924,31 @@ typedef struct TU_ATTR_PACKED {
|
||||
} subrange[numSubRanges]; \
|
||||
}
|
||||
|
||||
// 6.1 Interrupt Data Message Format
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t bInfo;
|
||||
uint8_t bAttribute;
|
||||
union
|
||||
{
|
||||
uint16_t wValue;
|
||||
struct
|
||||
{
|
||||
uint8_t wValue_cn_or_mcn;
|
||||
uint8_t wValue_cs;
|
||||
};
|
||||
};
|
||||
union
|
||||
{
|
||||
uint16_t wIndex;
|
||||
struct
|
||||
{
|
||||
uint8_t wIndex_ep_or_int;
|
||||
uint8_t wIndex_entity_id;
|
||||
};
|
||||
};
|
||||
} audio_interrupt_data_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -96,13 +96,6 @@
|
||||
#define USE_LINEAR_BUFFER 1
|
||||
#endif
|
||||
|
||||
// Temporarily put the check here
|
||||
#if defined(TUP_USBIP_FSDEV) || defined(TUP_USBIP_DWC2)
|
||||
#define USE_ISO_EP_ALLOCATION 1
|
||||
#else
|
||||
#define USE_ISO_EP_ALLOCATION 0
|
||||
#endif
|
||||
|
||||
// Declaration of buffers
|
||||
|
||||
// Check for maximum supported numbers
|
||||
@@ -301,10 +294,12 @@ typedef struct
|
||||
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
uint8_t ep_int_ctr; // Audio control interrupt EP.
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
uint8_t ep_int; // Audio control interrupt EP.
|
||||
#endif
|
||||
|
||||
bool mounted; // Device opened
|
||||
|
||||
/*------------- From this point, data is not cleared by bus reset -------------*/
|
||||
|
||||
uint16_t desc_length; // Length of audio function descriptor
|
||||
@@ -358,8 +353,8 @@ typedef struct
|
||||
#endif
|
||||
|
||||
// Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74)
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE];
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6];
|
||||
#endif
|
||||
|
||||
// Decoding parameters - parameters are set when alternate AS interface is set by host
|
||||
@@ -486,23 +481,7 @@ bool tud_audio_n_mounted(uint8_t func_id)
|
||||
TU_VERIFY(func_id < CFG_TUD_AUDIO);
|
||||
audiod_function_t* audio = &_audiod_fct[func_id];
|
||||
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
|
||||
if (audio->ep_out == 0) return false;
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_IN
|
||||
if (audio->ep_in == 0) return false;
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
if (audio->ep_int_ctr == 0) return false;
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
|
||||
if (audio->ep_fb == 0) return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
return audio->mounted;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -825,24 +804,30 @@ tu_fifo_t* tud_audio_n_get_tx_support_ff(uint8_t func_id, uint8_t ff_idx)
|
||||
#endif
|
||||
|
||||
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
|
||||
// If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_ctr_done_cb() is called in inform user
|
||||
uint16_t tud_audio_int_ctr_n_write(uint8_t func_id, uint8_t const* buffer, uint16_t len)
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
// If no interrupt transmit is pending bytes get written into buffer and a transmit is scheduled - once transmit completed tud_audio_int_done_cb() is called in inform user
|
||||
bool tud_audio_int_n_write(uint8_t func_id, const audio_interrupt_data_t * data)
|
||||
{
|
||||
TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL);
|
||||
|
||||
TU_VERIFY(_audiod_fct[func_id].ep_int != 0);
|
||||
|
||||
// We write directly into the EP's buffer - abort if previous transfer not complete
|
||||
TU_VERIFY(!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int_ctr));
|
||||
TU_VERIFY(usbd_edpt_claim(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int));
|
||||
|
||||
TU_VERIFY(tu_memcpy_s(_audiod_fct[func_id].ep_int_ctr_buf, CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE, buffer, len)==0);
|
||||
|
||||
// Schedule transmit
|
||||
TU_VERIFY(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int_ctr, _audiod_fct[func_id].ep_int_ctr_buf, len));
|
||||
// Check length
|
||||
if (tu_memcpy_s(_audiod_fct[func_id].ep_int_buf, sizeof(_audiod_fct[func_id].ep_int_buf), data, sizeof(audio_interrupt_data_t)) == 0)
|
||||
{
|
||||
// Schedule transmit
|
||||
TU_ASSERT(usbd_edpt_xfer(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int, _audiod_fct[func_id].ep_int_buf, sizeof(_audiod_fct[func_id].ep_int_buf)), 0);
|
||||
} else
|
||||
{
|
||||
// Release endpoint since we don't make any transfer
|
||||
usbd_edpt_release(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_int);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// This function is called once a transmit of an audio packet was successfully completed. Here, we encode samples and place it in IN EP's buffer for next transmission.
|
||||
@@ -1404,6 +1389,10 @@ void audiod_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
bool audiod_deinit(void) {
|
||||
return false; // TODO not implemented yet
|
||||
}
|
||||
|
||||
void audiod_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
@@ -1447,10 +1436,11 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
|
||||
// Verify version is correct - this check can be omitted
|
||||
TU_VERIFY(itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2);
|
||||
|
||||
// Verify interrupt control EP is enabled if demanded by descriptor - this should be best some static check however - this check can be omitted
|
||||
if (itf_desc->bNumEndpoints == 1) // 0 or 1 EPs are allowed
|
||||
// Verify interrupt control EP is enabled if demanded by descriptor
|
||||
TU_ASSERT(itf_desc->bNumEndpoints <= 1); // 0 or 1 EPs are allowed
|
||||
if (itf_desc->bNumEndpoints == 1)
|
||||
{
|
||||
TU_VERIFY(CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0);
|
||||
TU_ASSERT(CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP);
|
||||
}
|
||||
|
||||
// Alternate setting MUST be zero - this check can be omitted
|
||||
@@ -1483,7 +1473,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_ISO_EP_ALLOCATION
|
||||
#ifdef TUP_DCD_EDPT_ISO_ALLOC
|
||||
{
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_IN
|
||||
uint8_t ep_in = 0;
|
||||
@@ -1559,7 +1549,7 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // USE_ISO_EP_ALLOCATION
|
||||
#endif // TUP_DCD_EDPT_ISO_ALLOC
|
||||
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL
|
||||
{
|
||||
@@ -1594,6 +1584,32 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
|
||||
}
|
||||
#endif // CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL
|
||||
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
{
|
||||
uint8_t const *p_desc = _audiod_fct[i].p_desc;
|
||||
uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN;
|
||||
// Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning
|
||||
while (p_desc_end - p_desc > 0)
|
||||
{
|
||||
// For each endpoint
|
||||
if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT)
|
||||
{
|
||||
tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc;
|
||||
uint8_t const ep_addr = desc_ep->bEndpointAddress;
|
||||
// If endpoint is input-direction and interrupt-type
|
||||
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.xfer == TUSB_XFER_INTERRUPT)
|
||||
{
|
||||
// Store endpoint number and open endpoint
|
||||
_audiod_fct[i].ep_int = ep_addr;
|
||||
TU_ASSERT(usbd_edpt_open(_audiod_fct[i].rhport, desc_ep));
|
||||
}
|
||||
}
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
_audiod_fct[i].mounted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1655,7 +1671,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
|
||||
if (audio->ep_in_as_intf_num == itf)
|
||||
{
|
||||
audio->ep_in_as_intf_num = 0;
|
||||
#if !USE_ISO_EP_ALLOCATION
|
||||
#ifndef TUP_DCD_EDPT_ISO_ALLOC
|
||||
usbd_edpt_close(rhport, audio->ep_in);
|
||||
#endif
|
||||
|
||||
@@ -1686,7 +1702,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
|
||||
if (audio->ep_out_as_intf_num == itf)
|
||||
{
|
||||
audio->ep_out_as_intf_num = 0;
|
||||
#if !USE_ISO_EP_ALLOCATION
|
||||
#ifndef TUP_DCD_EDPT_ISO_ALLOC
|
||||
usbd_edpt_close(rhport, audio->ep_out);
|
||||
#endif
|
||||
|
||||
@@ -1707,7 +1723,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
|
||||
|
||||
// Close corresponding feedback EP
|
||||
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
|
||||
#if !USE_ISO_EP_ALLOCATION
|
||||
#ifndef TUP_DCD_EDPT_ISO_ALLOC
|
||||
usbd_edpt_close(rhport, audio->ep_fb);
|
||||
#endif
|
||||
audio->ep_fb = 0;
|
||||
@@ -1739,7 +1755,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
|
||||
if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT)
|
||||
{
|
||||
tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const *) p_desc;
|
||||
#if USE_ISO_EP_ALLOCATION
|
||||
#ifdef TUP_DCD_EDPT_ISO_ALLOC
|
||||
TU_ASSERT(usbd_edpt_iso_activate(rhport, desc_ep));
|
||||
#else
|
||||
TU_ASSERT(usbd_edpt_open(rhport, desc_ep));
|
||||
@@ -2120,10 +2136,10 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
|
||||
{
|
||||
audiod_function_t* audio = &_audiod_fct[func_id];
|
||||
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
|
||||
// Data transmission of control interrupt finished
|
||||
if (audio->ep_int_ctr == ep_addr)
|
||||
if (audio->ep_int == ep_addr)
|
||||
{
|
||||
// According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49)
|
||||
// In case there is nothing to send we have to return a NAK - this is taken care of by PHY ???
|
||||
@@ -2132,7 +2148,8 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
|
||||
// I assume here, that things above are handled by PHY
|
||||
// All transmission is done - what remains to do is to inform job was completed
|
||||
|
||||
if (tud_audio_int_ctr_done_cb) TU_VERIFY(tud_audio_int_ctr_done_cb(rhport, (uint16_t) xferred_bytes));
|
||||
if (tud_audio_int_done_cb) tud_audio_int_done_cb(rhport);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -196,13 +196,9 @@
|
||||
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION 0 // 0 or 1
|
||||
#endif
|
||||
|
||||
// Audio interrupt control EP size - disabled if 0
|
||||
#ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control - if required - 6 Bytes according to UAC 2 specification (p. 74)
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE
|
||||
#define CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE 6 // Buffer size of audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74)
|
||||
// Enable/disable interrupt EP (required for notifying host of control changes)
|
||||
#ifndef CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
#define CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP 0 // Feedback - 0 or 1
|
||||
#endif
|
||||
|
||||
// Use software encoding/decoding
|
||||
@@ -393,8 +389,8 @@ uint16_t tud_audio_n_write_support_ff (uint8_t func_id, uint8_t ff_i
|
||||
tu_fifo_t* tud_audio_n_get_tx_support_ff (uint8_t func_id, uint8_t ff_idx);
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
uint16_t tud_audio_int_ctr_n_write (uint8_t func_id, uint8_t const* buffer, uint16_t len);
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
bool tud_audio_int_n_write (uint8_t func_id, const audio_interrupt_data_t * data);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -437,8 +433,8 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff (uint8_t ff_idx);
|
||||
|
||||
// INT CTR API
|
||||
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
static inline uint16_t tud_audio_int_ctr_write (uint8_t const* buffer, uint16_t len);
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
static inline bool tud_audio_int_write (const audio_interrupt_data_t * data);
|
||||
#endif
|
||||
|
||||
// Buffer control EP data and schedule a transmit
|
||||
@@ -537,8 +533,8 @@ TU_ATTR_WEAK TU_ATTR_FAST_FUNC void tud_audio_feedback_interval_isr(uint8_t func
|
||||
|
||||
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
|
||||
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied);
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
TU_ATTR_WEAK void tud_audio_int_done_cb(uint8_t rhport);
|
||||
#endif
|
||||
|
||||
// Invoked when audio set interface request received
|
||||
@@ -669,10 +665,10 @@ static inline tu_fifo_t* tud_audio_get_tx_support_ff(uint8_t ff_idx)
|
||||
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
|
||||
static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t len)
|
||||
#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP
|
||||
static inline bool tud_audio_int_write(const audio_interrupt_data_t * data)
|
||||
{
|
||||
return tud_audio_int_ctr_n_write(0, buffer, len);
|
||||
return tud_audio_int_n_write(0, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -689,6 +685,7 @@ static inline bool tud_audio_fb_set(uint32_t feedback)
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void audiod_init (void);
|
||||
bool audiod_deinit (void);
|
||||
void audiod_reset (uint8_t rhport);
|
||||
uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -91,11 +91,14 @@ bool tud_bt_acl_data_send(void *event, uint16_t event_len)
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void btd_init(void)
|
||||
{
|
||||
void btd_init(void) {
|
||||
tu_memclr(&_btd_itf, sizeof(_btd_itf));
|
||||
}
|
||||
|
||||
bool btd_deinit(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void btd_reset(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
|
||||
@@ -104,6 +104,7 @@ bool tud_bt_acl_data_send(void *acl_data, uint16_t data_len);
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void btd_init (void);
|
||||
bool btd_deinit (void);
|
||||
void btd_reset (uint8_t rhport);
|
||||
uint16_t btd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool btd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *request);
|
||||
|
||||
@@ -253,11 +253,39 @@ void cdcd_init(void)
|
||||
// In this way, the most current data is prioritized.
|
||||
tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true);
|
||||
|
||||
tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex));
|
||||
tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL);
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex);
|
||||
osal_mutex_t mutex_wr = osal_mutex_create(&p_cdc->tx_ff_mutex);
|
||||
TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, );
|
||||
|
||||
tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, mutex_rd);
|
||||
tu_fifo_config_mutex(&p_cdc->tx_ff, mutex_wr, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool cdcd_deinit(void) {
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
for(uint8_t i=0; i<CFG_TUD_CDC; i++) {
|
||||
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
|
||||
osal_mutex_t mutex_rd = p_cdc->rx_ff.mutex_rd;
|
||||
osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr;
|
||||
|
||||
if (mutex_rd) {
|
||||
osal_mutex_delete(mutex_rd);
|
||||
tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL);
|
||||
}
|
||||
|
||||
if (mutex_wr) {
|
||||
osal_mutex_delete(mutex_wr);
|
||||
tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cdcd_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -247,6 +247,7 @@ static inline bool tud_cdc_write_clear(void)
|
||||
// INTERNAL USBD-CLASS DRIVER API
|
||||
//--------------------------------------------------------------------+
|
||||
void cdcd_init (void);
|
||||
bool cdcd_deinit (void);
|
||||
void cdcd_reset (uint8_t rhport);
|
||||
uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool cdcd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -160,11 +160,14 @@ void dfu_moded_reset(uint8_t rhport)
|
||||
reset_state();
|
||||
}
|
||||
|
||||
void dfu_moded_init(void)
|
||||
{
|
||||
void dfu_moded_init(void) {
|
||||
dfu_moded_reset(0);
|
||||
}
|
||||
|
||||
bool dfu_moded_deinit(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -86,6 +86,7 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt);
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void dfu_moded_init(void);
|
||||
bool dfu_moded_deinit(void);
|
||||
void dfu_moded_reset(uint8_t rhport);
|
||||
uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -51,8 +51,11 @@
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void dfu_rtd_init(void)
|
||||
{
|
||||
void dfu_rtd_init(void) {
|
||||
}
|
||||
|
||||
bool dfu_rtd_deinit(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void dfu_rtd_reset(uint8_t rhport)
|
||||
|
||||
@@ -43,6 +43,7 @@ void tud_dfu_runtime_reboot_to_dfu_cb(void);
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void dfu_rtd_init(void);
|
||||
bool dfu_rtd_deinit(void);
|
||||
void dfu_rtd_reset(uint8_t rhport);
|
||||
uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -300,6 +300,19 @@ typedef struct TU_ATTR_PACKED
|
||||
int8_t pan; // using AC Pan
|
||||
} hid_mouse_report_t;
|
||||
|
||||
|
||||
// Absolute Mouse: same as the Standard (relative) Mouse Report but
|
||||
// with int16_t instead of int8_t for X and Y coordinates.
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */
|
||||
int16_t x; /**< Current x position of the mouse. */
|
||||
int16_t y; /**< Current y position of the mouse. */
|
||||
int8_t wheel; /**< Current delta wheel movement on the mouse. */
|
||||
int8_t pan; // using AC Pan
|
||||
} hid_abs_mouse_report_t;
|
||||
|
||||
|
||||
/// Standard Mouse Buttons Bitmap
|
||||
typedef enum
|
||||
{
|
||||
|
||||
@@ -146,6 +146,19 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id,
|
||||
return tud_hid_n_report(instance, report_id, &report, sizeof(report));
|
||||
}
|
||||
|
||||
bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal)
|
||||
{
|
||||
hid_abs_mouse_report_t report =
|
||||
{
|
||||
.buttons = buttons,
|
||||
.x = x,
|
||||
.y = y,
|
||||
.wheel = vertical,
|
||||
.pan = horizontal
|
||||
};
|
||||
return tud_hid_n_report(instance, report_id, &report, sizeof(report));
|
||||
}
|
||||
|
||||
bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id,
|
||||
int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) {
|
||||
hid_gamepad_report_t report =
|
||||
@@ -166,11 +179,14 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id,
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD-CLASS API
|
||||
//--------------------------------------------------------------------+
|
||||
void hidd_init(void)
|
||||
{
|
||||
void hidd_init(void) {
|
||||
hidd_reset(0);
|
||||
}
|
||||
|
||||
bool hidd_deinit(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void hidd_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -72,6 +72,16 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi
|
||||
// use template layout report as defined by hid_mouse_report_t
|
||||
bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
|
||||
|
||||
// ABSOLUTE MOUSE: convenient helper to send absolute mouse report if application
|
||||
// use template layout report as defined by hid_abs_mouse_report_t
|
||||
bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal);
|
||||
|
||||
|
||||
static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal)
|
||||
{
|
||||
return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal);
|
||||
}
|
||||
|
||||
// Gamepad: convenient helper to send gamepad report if application
|
||||
// use template layout report TUD_HID_REPORT_DESC_GAMEPAD
|
||||
bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons);
|
||||
@@ -266,6 +276,55 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y
|
||||
HID_COLLECTION_END , \
|
||||
HID_COLLECTION_END \
|
||||
|
||||
// Absolute Mouse Report Descriptor Template
|
||||
#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
||||
HID_USAGE_MIN ( 1 ) ,\
|
||||
HID_USAGE_MAX ( 5 ) ,\
|
||||
HID_LOGICAL_MIN ( 0 ) ,\
|
||||
HID_LOGICAL_MAX ( 1 ) ,\
|
||||
/* Left, Right, Middle, Backward, Forward buttons */ \
|
||||
HID_REPORT_COUNT( 5 ) ,\
|
||||
HID_REPORT_SIZE ( 1 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
/* 3 bit padding */ \
|
||||
HID_REPORT_COUNT( 1 ) ,\
|
||||
HID_REPORT_SIZE ( 3 ) ,\
|
||||
HID_INPUT ( HID_CONSTANT ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
/* X, Y absolute position [0, 32767] */ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
||||
HID_LOGICAL_MIN ( 0x00 ) ,\
|
||||
HID_LOGICAL_MAX_N( 0x7FFF, 2 ) ,\
|
||||
HID_REPORT_SIZE ( 16 ) ,\
|
||||
HID_REPORT_COUNT ( 2 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
/* Vertical wheel scroll [-127, 127] */ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
|
||||
HID_LOGICAL_MIN ( 0x81 ) ,\
|
||||
HID_LOGICAL_MAX ( 0x7f ) ,\
|
||||
HID_REPORT_COUNT( 1 ) ,\
|
||||
HID_REPORT_SIZE ( 8 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \
|
||||
/* Horizontal wheel scroll [-127, 127] */ \
|
||||
HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \
|
||||
HID_LOGICAL_MIN ( 0x81 ), \
|
||||
HID_LOGICAL_MAX ( 0x7f ), \
|
||||
HID_REPORT_COUNT( 1 ), \
|
||||
HID_REPORT_SIZE ( 8 ), \
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
|
||||
HID_COLLECTION_END , \
|
||||
HID_COLLECTION_END \
|
||||
|
||||
// Consumer Control Report Descriptor Template
|
||||
#define TUD_HID_REPORT_DESC_CONSUMER(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\
|
||||
@@ -406,6 +465,7 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void hidd_init (void);
|
||||
bool hidd_deinit (void);
|
||||
void hidd_reset (uint8_t rhport);
|
||||
uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -373,12 +373,10 @@ bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4])
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void midid_init(void)
|
||||
{
|
||||
void midid_init(void) {
|
||||
tu_memclr(_midid_itf, sizeof(_midid_itf));
|
||||
|
||||
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
|
||||
{
|
||||
for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) {
|
||||
midid_interface_t* midi = &_midid_itf[i];
|
||||
|
||||
// config fifo
|
||||
@@ -386,12 +384,38 @@ void midid_init(void)
|
||||
tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS.
|
||||
|
||||
#if CFG_FIFO_MUTEX
|
||||
tu_fifo_config_mutex(&midi->rx_ff, NULL, osal_mutex_create(&midi->rx_ff_mutex));
|
||||
tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex), NULL);
|
||||
osal_mutex_t mutex_rd = osal_mutex_create(&midi->rx_ff_mutex);
|
||||
osal_mutex_t mutex_wr = osal_mutex_create(&midi->tx_ff_mutex);
|
||||
TU_ASSERT(mutex_wr != NULL && mutex_wr != NULL, );
|
||||
|
||||
tu_fifo_config_mutex(&midi->rx_ff, NULL, mutex_rd);
|
||||
tu_fifo_config_mutex(&midi->tx_ff, mutex_wr, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool midid_deinit(void) {
|
||||
#if CFG_FIFO_MUTEX
|
||||
for(uint8_t i=0; i<CFG_TUD_MIDI; i++) {
|
||||
midid_interface_t* midi = &_midid_itf[i];
|
||||
osal_mutex_t mutex_rd = midi->rx_ff.mutex_rd;
|
||||
osal_mutex_t mutex_wr = midi->tx_ff.mutex_wr;
|
||||
|
||||
if (mutex_rd) {
|
||||
osal_mutex_delete(mutex_rd);
|
||||
tu_fifo_config_mutex(&midi->rx_ff, NULL, NULL);
|
||||
}
|
||||
|
||||
if (mutex_wr) {
|
||||
osal_mutex_delete(mutex_wr);
|
||||
tu_fifo_config_mutex(&midi->tx_ff, NULL, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void midid_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -158,6 +158,7 @@ static inline bool tud_midi_packet_write (uint8_t const packet[4])
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void midid_init (void);
|
||||
bool midid_deinit (void);
|
||||
void midid_reset (uint8_t rhport);
|
||||
uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -251,11 +251,15 @@ static inline void set_sense_medium_not_present(uint8_t lun)
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void mscd_init(void)
|
||||
{
|
||||
void mscd_init(void) {
|
||||
tu_memclr(&_mscd_itf, sizeof(mscd_interface_t));
|
||||
}
|
||||
|
||||
bool mscd_deinit(void) {
|
||||
// nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
void mscd_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -150,6 +150,7 @@ TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun);
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void mscd_init (void);
|
||||
bool mscd_deinit (void);
|
||||
void mscd_reset (uint8_t rhport);
|
||||
uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request);
|
||||
|
||||
@@ -132,11 +132,14 @@ void netd_report(uint8_t *buf, uint16_t len)
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void netd_init(void)
|
||||
{
|
||||
void netd_init(void) {
|
||||
tu_memclr(&_netd_itf, sizeof(_netd_itf));
|
||||
}
|
||||
|
||||
bool netd_deinit(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void netd_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -260,6 +260,10 @@ void netd_init(void)
|
||||
ncm_prepare_for_tx();
|
||||
}
|
||||
|
||||
bool netd_deinit(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void netd_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -105,6 +105,7 @@ void tud_network_link_state_cb(bool state);
|
||||
// INTERNAL USBD-CLASS DRIVER API
|
||||
//--------------------------------------------------------------------+
|
||||
void netd_init (void);
|
||||
bool netd_deinit (void);
|
||||
void netd_reset (uint8_t rhport);
|
||||
uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -260,6 +260,13 @@ void usbtmcd_init_cb(void)
|
||||
usbtmcLock = osal_mutex_create(&usbtmcLockBuffer);
|
||||
}
|
||||
|
||||
bool usbtmcd_deinit(void) {
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
osal_mutex_delete(usbtmcLock);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len)
|
||||
{
|
||||
(void)rhport;
|
||||
|
||||
@@ -98,11 +98,12 @@ bool tud_usbtmc_start_bus_read(void);
|
||||
|
||||
/* "callbacks" from USB device core */
|
||||
|
||||
void usbtmcd_init_cb(void);
|
||||
bool usbtmcd_deinit(void);
|
||||
uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
void usbtmcd_reset_cb(uint8_t rhport);
|
||||
bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
|
||||
bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
void usbtmcd_init_cb(void);
|
||||
|
||||
/************************************************************
|
||||
* USBTMC Descriptor Templates
|
||||
|
||||
48
src/class/vendor/vendor_device.c
vendored
48
src/class/vendor/vendor_device.c
vendored
@@ -202,27 +202,63 @@ uint32_t tud_vendor_n_write_available (uint8_t itf)
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void vendord_init(void)
|
||||
{
|
||||
void vendord_init(void) {
|
||||
tu_memclr(_vendord_itf, sizeof(_vendord_itf));
|
||||
|
||||
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++)
|
||||
{
|
||||
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) {
|
||||
#if CFG_TUD_VENDOR_RX_BUFSIZE > 0 || CFG_TUD_VENDOR_TX_BUFSIZE > 0
|
||||
vendord_interface_t* p_itf = &_vendord_itf[i];
|
||||
#endif
|
||||
// config fifo
|
||||
#if CFG_TUD_VENDOR_RX_BUFSIZE > 0
|
||||
tu_fifo_config(&p_itf->rx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false);
|
||||
tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex));
|
||||
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
osal_mutex_t mutex_rd = osal_mutex_create(&p_itf->rx_ff_mutex);
|
||||
TU_ASSERT(mutex_rd,);
|
||||
tu_fifo_config_mutex(&p_itf->rx_ff, NULL, mutex_rd);
|
||||
#endif
|
||||
#endif
|
||||
#if CFG_TUD_VENDOR_TX_BUFSIZE > 0
|
||||
tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false);
|
||||
tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL);
|
||||
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
osal_mutex_t mutex_wr = osal_mutex_create(&p_itf->tx_ff_mutex);
|
||||
TU_ASSERT(mutex_wr,);
|
||||
tu_fifo_config_mutex(&p_itf->tx_ff, mutex_wr, NULL);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool vendord_deinit(void) {
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
#if CFG_TUD_VENDOR_RX_BUFSIZE > 0
|
||||
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) {
|
||||
vendord_interface_t* p_itf = &_vendord_itf[i];
|
||||
osal_mutex_t mutex_rd = p_itf->rx_ff.mutex_rd;
|
||||
|
||||
if (mutex_rd) {
|
||||
osal_mutex_delete(mutex_rd);
|
||||
tu_fifo_config_mutex(&p_itf->rx_ff, NULL, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if CFG_TUD_VENDOR_TX_BUFSIZE > 0
|
||||
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) {
|
||||
vendord_interface_t* p_itf = &_vendord_itf[i];
|
||||
osal_mutex_t mutex_wr = p_itf->tx_ff.mutex_wr;
|
||||
|
||||
if (mutex_wr) {
|
||||
osal_mutex_delete(mutex_wr);
|
||||
tu_fifo_config_mutex(&p_itf->tx_ff, NULL, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void vendord_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
1
src/class/vendor/vendor_device.h
vendored
1
src/class/vendor/vendor_device.h
vendored
@@ -161,6 +161,7 @@ static inline uint32_t tud_vendor_write_available (void)
|
||||
// Internal Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
void vendord_init(void);
|
||||
bool vendord_deinit(void);
|
||||
void vendord_reset(uint8_t rhport);
|
||||
uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||
|
||||
@@ -755,15 +755,20 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint
|
||||
TU_LOG_DRV(" reopen VS %d\r\n", altnum);
|
||||
uint8_t const *desc = _videod_itf[stm->index_vc].beg;
|
||||
|
||||
#ifndef TUP_DCD_EDPT_ISO_ALLOC
|
||||
/* Close endpoints of previous settings. */
|
||||
for (i = 0; i < TU_ARRAY_SIZE(stm->desc.ep); ++i) {
|
||||
uint_fast16_t ofs_ep = stm->desc.ep[i];
|
||||
if (!ofs_ep) break;
|
||||
uint8_t ep_adr = _desc_ep_addr(desc + ofs_ep);
|
||||
usbd_edpt_close(rhport, ep_adr);
|
||||
stm->desc.ep[i] = 0;
|
||||
TU_LOG_DRV(" close EP%02x\r\n", ep_adr);
|
||||
tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)(desc + ofs_ep);
|
||||
/* Only ISO endpoints needs to be closed */
|
||||
if(ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) {
|
||||
usbd_edpt_close(rhport, ep->bEndpointAddress);
|
||||
stm->desc.ep[i] = 0;
|
||||
TU_LOG_DRV(" close EP%02x\r\n", ep->bEndpointAddress);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* clear transfer management information */
|
||||
stm->buffer = NULL;
|
||||
@@ -788,16 +793,18 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint
|
||||
TU_ASSERT(cur < end);
|
||||
tusb_desc_endpoint_t const *ep = (tusb_desc_endpoint_t const*)cur;
|
||||
uint_fast32_t max_size = stm->max_payload_transfer_size;
|
||||
if (altnum) {
|
||||
if ((TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer) &&
|
||||
(tu_edpt_packet_size(ep) < max_size)) {
|
||||
/* FS must be less than or equal to max packet size */
|
||||
return false;
|
||||
}
|
||||
if (altnum && (TUSB_XFER_ISOCHRONOUS == ep->bmAttributes.xfer)) {
|
||||
/* FS must be less than or equal to max packet size */
|
||||
TU_VERIFY (tu_edpt_packet_size(ep) >= max_size);
|
||||
#ifdef TUP_DCD_EDPT_ISO_ALLOC
|
||||
usbd_edpt_iso_activate(rhport, ep);
|
||||
#else
|
||||
TU_ASSERT(usbd_edpt_open(rhport, ep));
|
||||
#endif
|
||||
} else {
|
||||
TU_VERIFY(TUSB_XFER_BULK == ep->bmAttributes.xfer);
|
||||
TU_ASSERT(usbd_edpt_open(rhport, ep));
|
||||
}
|
||||
TU_ASSERT(usbd_edpt_open(rhport, ep));
|
||||
stm->desc.ep[i] = (uint16_t) (cur - desc);
|
||||
TU_LOG_DRV(" open EP%02x\r\n", _desc_ep_addr(cur));
|
||||
}
|
||||
@@ -1229,6 +1236,10 @@ void videod_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
bool videod_deinit(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void videod_reset(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) {
|
||||
@@ -1283,6 +1294,24 @@ uint16_t videod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
|
||||
cur = _next_desc_itf(cur, end);
|
||||
stm->desc.end = (uint16_t) ((uintptr_t)cur - (uintptr_t)itf_desc);
|
||||
stm->state = VS_STATE_PROBING;
|
||||
#ifdef TUP_DCD_EDPT_ISO_ALLOC
|
||||
/* Allocate ISO endpoints */
|
||||
uint16_t ep_size = 0;
|
||||
uint16_t ep_addr = 0;
|
||||
uint8_t const *p_desc = (uint8_t const*)itf_desc + stm->desc.beg;
|
||||
uint8_t const *p_desc_end = (uint8_t const*)itf_desc + stm->desc.end;
|
||||
while (p_desc < p_desc_end) {
|
||||
if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) {
|
||||
tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc;
|
||||
if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) {
|
||||
ep_addr = desc_ep->bEndpointAddress;
|
||||
ep_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_size);
|
||||
}
|
||||
}
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
}
|
||||
if(ep_addr > 0 && ep_size > 0) usbd_edpt_iso_alloc(rhport, ep_addr, ep_size);
|
||||
#endif
|
||||
if (0 == stm_idx && 1 == bInCollection) {
|
||||
/* If there is only one streaming interface and no alternate settings,
|
||||
* host may not issue set_interface so open the streaming interface here. */
|
||||
|
||||
@@ -85,6 +85,7 @@ TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
|
||||
// INTERNAL USBD-CLASS DRIVER API
|
||||
//--------------------------------------------------------------------+
|
||||
void videod_init (void);
|
||||
bool videod_deinit (void);
|
||||
void videod_reset (uint8_t rhport);
|
||||
uint16_t videod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
|
||||
bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -100,6 +100,13 @@
|
||||
#define TUP_DCD_ENDPOINT_MAX 8
|
||||
#define TUP_RHPORT_HIGHSPEED 1
|
||||
|
||||
#elif TU_CHECK_MCU(OPT_MCU_MCXA15)
|
||||
// USB0 is chipidea FS
|
||||
#define TUP_USBIP_CHIPIDEA_FS
|
||||
#define TUP_USBIP_CHIPIDEA_FS_MCX
|
||||
|
||||
#define TUP_DCD_ENDPOINT_MAX 16
|
||||
|
||||
#elif TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX)
|
||||
#define TUP_USBIP_CHIPIDEA_HS
|
||||
#define TUP_USBIP_EHCI
|
||||
@@ -434,4 +441,8 @@
|
||||
#define TU_ATTR_FAST_FUNC
|
||||
#endif
|
||||
|
||||
#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV)
|
||||
#define TUP_DCD_EDPT_ISO_ALLOC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -122,6 +122,9 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W
|
||||
// Initialize controller to device mode
|
||||
void dcd_init(uint8_t rhport);
|
||||
|
||||
// Deinitialize controller, unset device mode.
|
||||
bool dcd_deinit(uint8_t rhport);
|
||||
|
||||
// Interrupt Handler
|
||||
void dcd_int_handler(uint8_t rhport);
|
||||
|
||||
|
||||
@@ -43,8 +43,13 @@
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Callback weak stubs (called if application does not provide)
|
||||
// Weak stubs: invoked if no strong implementation is available
|
||||
//--------------------------------------------------------------------+
|
||||
TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
return false;
|
||||
}
|
||||
|
||||
TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
|
||||
(void)rhport;
|
||||
(void)eventid;
|
||||
@@ -96,6 +101,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
|
||||
{
|
||||
DRIVER_NAME("CDC")
|
||||
.init = cdcd_init,
|
||||
.deinit = cdcd_deinit,
|
||||
.reset = cdcd_reset,
|
||||
.open = cdcd_open,
|
||||
.control_xfer_cb = cdcd_control_xfer_cb,
|
||||
@@ -108,6 +114,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
|
||||
{
|
||||
DRIVER_NAME("MSC")
|
||||
.init = mscd_init,
|
||||
.deinit = NULL,
|
||||
.reset = mscd_reset,
|
||||
.open = mscd_open,
|
||||
.control_xfer_cb = mscd_control_xfer_cb,
|
||||
@@ -118,121 +125,131 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
|
||||
|
||||
#if CFG_TUD_HID
|
||||
{
|
||||
DRIVER_NAME("HID")
|
||||
.init = hidd_init,
|
||||
.reset = hidd_reset,
|
||||
.open = hidd_open,
|
||||
.control_xfer_cb = hidd_control_xfer_cb,
|
||||
.xfer_cb = hidd_xfer_cb,
|
||||
.sof = NULL
|
||||
DRIVER_NAME("HID")
|
||||
.init = hidd_init,
|
||||
.deinit = hidd_deinit,
|
||||
.reset = hidd_reset,
|
||||
.open = hidd_open,
|
||||
.control_xfer_cb = hidd_control_xfer_cb,
|
||||
.xfer_cb = hidd_xfer_cb,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO
|
||||
{
|
||||
DRIVER_NAME("AUDIO")
|
||||
.init = audiod_init,
|
||||
.reset = audiod_reset,
|
||||
.open = audiod_open,
|
||||
.control_xfer_cb = audiod_control_xfer_cb,
|
||||
.xfer_cb = audiod_xfer_cb,
|
||||
.sof = audiod_sof_isr
|
||||
DRIVER_NAME("AUDIO")
|
||||
.init = audiod_init,
|
||||
.deinit = audiod_deinit,
|
||||
.reset = audiod_reset,
|
||||
.open = audiod_open,
|
||||
.control_xfer_cb = audiod_control_xfer_cb,
|
||||
.xfer_cb = audiod_xfer_cb,
|
||||
.sof = audiod_sof_isr
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_VIDEO
|
||||
{
|
||||
DRIVER_NAME("VIDEO")
|
||||
.init = videod_init,
|
||||
.reset = videod_reset,
|
||||
.open = videod_open,
|
||||
.control_xfer_cb = videod_control_xfer_cb,
|
||||
.xfer_cb = videod_xfer_cb,
|
||||
.sof = NULL
|
||||
DRIVER_NAME("VIDEO")
|
||||
.init = videod_init,
|
||||
.deinit = videod_deinit,
|
||||
.reset = videod_reset,
|
||||
.open = videod_open,
|
||||
.control_xfer_cb = videod_control_xfer_cb,
|
||||
.xfer_cb = videod_xfer_cb,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_MIDI
|
||||
{
|
||||
DRIVER_NAME("MIDI")
|
||||
.init = midid_init,
|
||||
.open = midid_open,
|
||||
.reset = midid_reset,
|
||||
.control_xfer_cb = midid_control_xfer_cb,
|
||||
.xfer_cb = midid_xfer_cb,
|
||||
.sof = NULL
|
||||
DRIVER_NAME("MIDI")
|
||||
.init = midid_init,
|
||||
.deinit = midid_deinit,
|
||||
.open = midid_open,
|
||||
.reset = midid_reset,
|
||||
.control_xfer_cb = midid_control_xfer_cb,
|
||||
.xfer_cb = midid_xfer_cb,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_VENDOR
|
||||
{
|
||||
DRIVER_NAME("VENDOR")
|
||||
.init = vendord_init,
|
||||
.reset = vendord_reset,
|
||||
.open = vendord_open,
|
||||
.control_xfer_cb = tud_vendor_control_xfer_cb,
|
||||
.xfer_cb = vendord_xfer_cb,
|
||||
.sof = NULL
|
||||
DRIVER_NAME("VENDOR")
|
||||
.init = vendord_init,
|
||||
.deinit = vendord_deinit,
|
||||
.reset = vendord_reset,
|
||||
.open = vendord_open,
|
||||
.control_xfer_cb = tud_vendor_control_xfer_cb,
|
||||
.xfer_cb = vendord_xfer_cb,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_USBTMC
|
||||
{
|
||||
DRIVER_NAME("TMC")
|
||||
.init = usbtmcd_init_cb,
|
||||
.reset = usbtmcd_reset_cb,
|
||||
.open = usbtmcd_open_cb,
|
||||
.control_xfer_cb = usbtmcd_control_xfer_cb,
|
||||
.xfer_cb = usbtmcd_xfer_cb,
|
||||
.sof = NULL
|
||||
DRIVER_NAME("TMC")
|
||||
.init = usbtmcd_init_cb,
|
||||
.deinit = usbtmcd_deinit,
|
||||
.reset = usbtmcd_reset_cb,
|
||||
.open = usbtmcd_open_cb,
|
||||
.control_xfer_cb = usbtmcd_control_xfer_cb,
|
||||
.xfer_cb = usbtmcd_xfer_cb,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_DFU_RUNTIME
|
||||
{
|
||||
DRIVER_NAME("DFU-RUNTIME")
|
||||
.init = dfu_rtd_init,
|
||||
.reset = dfu_rtd_reset,
|
||||
.open = dfu_rtd_open,
|
||||
.control_xfer_cb = dfu_rtd_control_xfer_cb,
|
||||
.xfer_cb = NULL,
|
||||
.sof = NULL
|
||||
DRIVER_NAME("DFU-RUNTIME")
|
||||
.init = dfu_rtd_init,
|
||||
.deinit = dfu_rtd_deinit,
|
||||
.reset = dfu_rtd_reset,
|
||||
.open = dfu_rtd_open,
|
||||
.control_xfer_cb = dfu_rtd_control_xfer_cb,
|
||||
.xfer_cb = NULL,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_DFU
|
||||
{
|
||||
DRIVER_NAME("DFU")
|
||||
.init = dfu_moded_init,
|
||||
.reset = dfu_moded_reset,
|
||||
.open = dfu_moded_open,
|
||||
.control_xfer_cb = dfu_moded_control_xfer_cb,
|
||||
.xfer_cb = NULL,
|
||||
.sof = NULL
|
||||
DRIVER_NAME("DFU")
|
||||
.init = dfu_moded_init,
|
||||
.deinit = dfu_moded_deinit,
|
||||
.reset = dfu_moded_reset,
|
||||
.open = dfu_moded_open,
|
||||
.control_xfer_cb = dfu_moded_control_xfer_cb,
|
||||
.xfer_cb = NULL,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM
|
||||
{
|
||||
DRIVER_NAME("NET")
|
||||
.init = netd_init,
|
||||
.reset = netd_reset,
|
||||
.open = netd_open,
|
||||
.control_xfer_cb = netd_control_xfer_cb,
|
||||
.xfer_cb = netd_xfer_cb,
|
||||
.sof = NULL,
|
||||
DRIVER_NAME("NET")
|
||||
.init = netd_init,
|
||||
.deinit = netd_deinit,
|
||||
.reset = netd_reset,
|
||||
.open = netd_open,
|
||||
.control_xfer_cb = netd_control_xfer_cb,
|
||||
.xfer_cb = netd_xfer_cb,
|
||||
.sof = NULL,
|
||||
},
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_BTH
|
||||
{
|
||||
DRIVER_NAME("BTH")
|
||||
.init = btd_init,
|
||||
.reset = btd_reset,
|
||||
.open = btd_open,
|
||||
.control_xfer_cb = btd_control_xfer_cb,
|
||||
.xfer_cb = btd_xfer_cb,
|
||||
.sof = NULL
|
||||
DRIVER_NAME("BTH")
|
||||
.init = btd_init,
|
||||
.deinit = btd_deinit,
|
||||
.reset = btd_reset,
|
||||
.open = btd_open,
|
||||
.control_xfer_cb = btd_control_xfer_cb,
|
||||
.xfer_cb = btd_xfer_cb,
|
||||
.sof = NULL
|
||||
},
|
||||
#endif
|
||||
};
|
||||
@@ -402,7 +419,7 @@ bool tud_init(uint8_t rhport) {
|
||||
// Init class drivers
|
||||
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
|
||||
usbd_class_driver_t const* driver = get_driver(i);
|
||||
TU_ASSERT(driver);
|
||||
TU_ASSERT(driver && driver->init);
|
||||
TU_LOG_USBD("%s init\r\n", driver->name);
|
||||
driver->init();
|
||||
}
|
||||
@@ -416,6 +433,41 @@ bool tud_init(uint8_t rhport) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tud_deinit(uint8_t rhport) {
|
||||
// skip if not initialized
|
||||
if (!tud_inited()) return true;
|
||||
|
||||
TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport);
|
||||
|
||||
// Deinit device controller driver
|
||||
dcd_int_disable(rhport);
|
||||
dcd_disconnect(rhport);
|
||||
dcd_deinit(rhport);
|
||||
|
||||
// Deinit class drivers
|
||||
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
|
||||
usbd_class_driver_t const* driver = get_driver(i);
|
||||
if(driver && driver->deinit) {
|
||||
TU_LOG_USBD("%s deinit\r\n", driver->name);
|
||||
driver->deinit();
|
||||
}
|
||||
}
|
||||
|
||||
// Deinit device queue & task
|
||||
osal_queue_delete(_usbd_q);
|
||||
_usbd_q = NULL;
|
||||
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
// TODO make sure there is no task waiting on this mutex
|
||||
osal_mutex_delete(_usbd_mutex);
|
||||
_usbd_mutex = NULL;
|
||||
#endif
|
||||
|
||||
_usbd_rhport = RHPORT_INVALID;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void configuration_reset(uint8_t rhport) {
|
||||
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
|
||||
usbd_class_driver_t const* driver = get_driver(i);
|
||||
@@ -1181,6 +1233,11 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t
|
||||
// TU_VERIFY(tud_ready());
|
||||
|
||||
TU_LOG_USBD(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
|
||||
#if CFG_TUD_LOG_LEVEL >= 3
|
||||
if(dir == TUSB_DIR_IN) {
|
||||
TU_LOG_MEM(CFG_TUD_LOG_LEVEL, buffer, total_bytes, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Attempt to transfer on a busy endpoint, sound like an race condition !
|
||||
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
|
||||
|
||||
@@ -37,9 +37,12 @@ extern "C" {
|
||||
// Application API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Init device stack
|
||||
// Init device stack on roothub port
|
||||
bool tud_init (uint8_t rhport);
|
||||
|
||||
// Deinit device stack on roothub port
|
||||
bool tud_deinit(uint8_t rhport);
|
||||
|
||||
// Check if device stack is already initialized
|
||||
bool tud_inited(void);
|
||||
|
||||
@@ -393,6 +396,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
|
||||
|
||||
// For more channels, add definitions here
|
||||
|
||||
/* Standard AC Interrupt Endpoint Descriptor(4.8.2.1) */
|
||||
#define TUD_AUDIO_DESC_STD_AC_INT_EP_LEN 7
|
||||
#define TUD_AUDIO_DESC_STD_AC_INT_EP(_ep, _interval) \
|
||||
TUD_AUDIO_DESC_STD_AC_INT_EP_LEN, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(6), _interval
|
||||
|
||||
/* Standard AS Interface Descriptor(4.9.1) */
|
||||
#define TUD_AUDIO_DESC_STD_AS_INT_LEN 9
|
||||
#define TUD_AUDIO_DESC_STD_AS_INT(_itfnum, _altset, _nEPs, _stridx) \
|
||||
@@ -468,7 +476,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
|
||||
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
|
||||
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
|
||||
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
|
||||
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
|
||||
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
|
||||
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
|
||||
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
|
||||
|
||||
@@ -517,7 +525,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
|
||||
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
|
||||
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
|
||||
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
|
||||
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
|
||||
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
|
||||
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
|
||||
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
|
||||
|
||||
@@ -565,7 +573,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
|
||||
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
|
||||
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
|
||||
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
|
||||
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
|
||||
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) ((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
|
||||
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
|
||||
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\
|
||||
/* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\
|
||||
|
||||
@@ -45,6 +45,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
void (* init ) (void);
|
||||
bool (* deinit ) (void);
|
||||
void (* reset ) (uint8_t rhport);
|
||||
uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len);
|
||||
bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
|
||||
|
||||
@@ -125,7 +125,7 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// optional hcd configuration, called by tuh_configure()
|
||||
bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_ATTR_WEAK;
|
||||
bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param);
|
||||
|
||||
// Initialize controller to host mode
|
||||
bool hcd_init(uint8_t rhport);
|
||||
|
||||
@@ -52,6 +52,13 @@ TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TU_ATTR_WEAK bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
|
||||
(void) rhport;
|
||||
(void) cfg_id;
|
||||
(void) cfg_param;
|
||||
return false;
|
||||
}
|
||||
|
||||
TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
|
||||
(void) rhport;
|
||||
(void) eventid;
|
||||
@@ -332,11 +339,7 @@ bool tuh_rhport_reset_bus(uint8_t rhport, bool active) {
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) {
|
||||
if ( hcd_configure ) {
|
||||
return hcd_configure(rhport, cfg_id, cfg_param);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return hcd_configure(rhport, cfg_id, cfg_param);
|
||||
}
|
||||
|
||||
static void clear_device(usbh_device_t* dev) {
|
||||
@@ -422,7 +425,7 @@ bool tuh_deinit(uint8_t rhport) {
|
||||
// Class drivers
|
||||
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
|
||||
usbh_class_driver_t const* driver = get_driver(drv_id);
|
||||
if (driver) {
|
||||
if (driver && driver->deinit) {
|
||||
TU_LOG_USBH("%s deinit\r\n", driver->name);
|
||||
driver->deinit();
|
||||
}
|
||||
|
||||
@@ -73,11 +73,25 @@ typedef struct {
|
||||
tusb_desc_interface_t desc;
|
||||
} tuh_itf_info_t;
|
||||
|
||||
// ConfigID for tuh_config()
|
||||
// ConfigID for tuh_configure()
|
||||
enum {
|
||||
TUH_CFGID_RPI_PIO_USB_CONFIGURATION = OPT_MCU_RP2040 << 8 // cfg_param: pio_usb_configuration_t
|
||||
TUH_CFGID_INVALID = 0,
|
||||
TUH_CFGID_RPI_PIO_USB_CONFIGURATION = 100, // cfg_param: pio_usb_configuration_t
|
||||
TUH_CFGID_MAX3421 = 200,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t max_nak; // max NAK per endpoint per frame
|
||||
uint8_t cpuctl; // R16: CPU Control Register
|
||||
uint8_t pinctl; // R17: Pin Control Register. FDUPSPI bit is ignored
|
||||
} tuh_configure_max3421_t;
|
||||
|
||||
typedef union {
|
||||
// For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t
|
||||
|
||||
tuh_configure_max3421_t max3421;
|
||||
} tuh_configure_param_t;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// APPLICATION CALLBACK
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include "host/hcd.h"
|
||||
#include "host/usbh.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
@@ -166,6 +167,17 @@ enum {
|
||||
DEFAULT_HIEN = HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ | HIRQ_HXFRDN_IRQ | HIRQ_RCVDAV_IRQ
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame
|
||||
};
|
||||
|
||||
enum {
|
||||
EP_STATE_IDLE = 0,
|
||||
EP_STATE_COMPLETE = 1,
|
||||
EP_STATE_ATTEMPT_1 = 2, // pending 1st attempt
|
||||
EP_STATE_ATTEMPT_MAX = 15
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -173,18 +185,21 @@ enum {
|
||||
typedef struct {
|
||||
uint8_t daddr;
|
||||
|
||||
struct TU_ATTR_PACKED {
|
||||
uint8_t ep_dir : 1;
|
||||
uint8_t is_iso : 1;
|
||||
uint8_t is_setup : 1;
|
||||
uint8_t data_toggle : 1;
|
||||
uint8_t xfer_pending : 1;
|
||||
uint8_t xfer_complete : 1;
|
||||
union { ;
|
||||
struct TU_ATTR_PACKED {
|
||||
uint8_t ep_num : 4;
|
||||
uint8_t is_setup : 1;
|
||||
uint8_t is_out : 1;
|
||||
uint8_t is_iso : 1;
|
||||
}hxfr_bm;
|
||||
|
||||
uint8_t hxfr;
|
||||
};
|
||||
|
||||
struct TU_ATTR_PACKED {
|
||||
uint8_t ep_num : 4;
|
||||
uint16_t packet_size : 12;
|
||||
uint8_t state : 4;
|
||||
uint8_t data_toggle : 1;
|
||||
uint16_t packet_size : 11;
|
||||
};
|
||||
|
||||
uint16_t total_len;
|
||||
@@ -195,6 +210,8 @@ typedef struct {
|
||||
TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 12, "size is not correct");
|
||||
|
||||
typedef struct {
|
||||
volatile uint16_t frame_count;
|
||||
|
||||
// cached register
|
||||
uint8_t sndbc;
|
||||
uint8_t hirq;
|
||||
@@ -204,18 +221,24 @@ typedef struct {
|
||||
uint8_t hxfr;
|
||||
|
||||
atomic_flag busy; // busy transferring
|
||||
volatile uint16_t frame_count;
|
||||
|
||||
max3421_ep_t ep[CFG_TUH_MAX3421_ENDPOINT_TOTAL]; // [0] is reserved for addr0
|
||||
|
||||
OSAL_MUTEX_DEF(spi_mutexdef);
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
OSAL_MUTEX_DEF(spi_mutexdef);
|
||||
osal_mutex_t spi_mutex;
|
||||
#endif
|
||||
|
||||
max3421_ep_t ep[CFG_TUH_MAX3421_ENDPOINT_TOTAL]; // [0] is reserved for addr0
|
||||
} max3421_data_t;
|
||||
|
||||
static max3421_data_t _hcd_data;
|
||||
|
||||
// max NAK before giving up in a frame. 0 means infinite NAKs
|
||||
static tuh_configure_max3421_t _tuh_cfg = {
|
||||
.max_nak = MAX_NAK_DEFAULT,
|
||||
.cpuctl = 0, // default: INT pulse width = 10.6 us
|
||||
.pinctl = 0, // default: negative edge interrupt
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// API: SPI transfer with MAX3421E
|
||||
// - spi_cs_api(), spi_xfer_api(), int_api(): must be implemented by application
|
||||
@@ -304,7 +327,6 @@ static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint
|
||||
tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
|
||||
}
|
||||
|
||||
static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) {
|
||||
@@ -359,10 +381,11 @@ TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t dat
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static max3421_ep_t* find_ep_not_addr0(uint8_t daddr, uint8_t ep_num, uint8_t ep_dir) {
|
||||
uint8_t const is_out = 1-ep_dir;
|
||||
for(size_t i=1; i<CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) {
|
||||
max3421_ep_t* ep = &_hcd_data.ep[i];
|
||||
// for control endpoint, skip direction check
|
||||
if (daddr == ep->daddr && ep_num == ep->ep_num && (ep_dir == ep->ep_dir || ep_num == 0)) {
|
||||
// control endpoint is bi-direction (skip check)
|
||||
if (daddr == ep->daddr && ep_num == ep->hxfr_bm.ep_num && (ep_num == 0 || is_out == ep->hxfr_bm.is_out)) {
|
||||
return ep;
|
||||
}
|
||||
}
|
||||
@@ -393,14 +416,23 @@ static void free_ep(uint8_t daddr) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if endpoint has an queued transfer and not reach max NAK
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool is_ep_pending(max3421_ep_t const * ep) {
|
||||
uint8_t const state = ep->state;
|
||||
return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) &&
|
||||
(_tuh_cfg.max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _tuh_cfg.max_nak);
|
||||
}
|
||||
|
||||
// Find the next pending endpoint using round-robin scheduling, starting from next endpoint.
|
||||
// return NULL if not found
|
||||
// TODO respect interrupt endpoint's interval
|
||||
static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) {
|
||||
size_t const idx = (size_t) (cur_ep - _hcd_data.ep);
|
||||
|
||||
// starting from next endpoint
|
||||
for (size_t i = idx + 1; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) {
|
||||
max3421_ep_t* ep = &_hcd_data.ep[i];
|
||||
if (ep->xfer_pending && ep->packet_size) {
|
||||
// TU_LOG3("next pending i = %u\r\n", i);
|
||||
if (is_ep_pending(ep)) {
|
||||
return ep;
|
||||
}
|
||||
}
|
||||
@@ -408,8 +440,7 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) {
|
||||
// wrap around including current endpoint
|
||||
for (size_t i = 0; i <= idx; i++) {
|
||||
max3421_ep_t* ep = &_hcd_data.ep[i];
|
||||
if (ep->xfer_pending && ep->packet_size) {
|
||||
// TU_LOG3("next pending i = %u\r\n", i);
|
||||
if (is_ep_pending(ep)) {
|
||||
return ep;
|
||||
}
|
||||
}
|
||||
@@ -424,10 +455,11 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) {
|
||||
// optional hcd configuration, called by tuh_configure()
|
||||
bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
|
||||
(void) rhport;
|
||||
(void) cfg_id;
|
||||
(void) cfg_param;
|
||||
TU_VERIFY(cfg_id == TUH_CFGID_MAX3421 && cfg_param != NULL);
|
||||
|
||||
return false;
|
||||
tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param;
|
||||
_tuh_cfg = cfg->max3421;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialize controller to host mode
|
||||
@@ -438,6 +470,7 @@ bool hcd_init(uint8_t rhport) {
|
||||
|
||||
TU_LOG2_INT(sizeof(max3421_ep_t));
|
||||
TU_LOG2_INT(sizeof(max3421_data_t));
|
||||
TU_LOG2_INT(offsetof(max3421_data_t, ep));
|
||||
|
||||
tu_memclr(&_hcd_data, sizeof(_hcd_data));
|
||||
_hcd_data.peraddr = 0xff; // invalid
|
||||
@@ -447,7 +480,7 @@ bool hcd_init(uint8_t rhport) {
|
||||
#endif
|
||||
|
||||
// full duplex, interrupt negative edge
|
||||
reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false);
|
||||
reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false);
|
||||
|
||||
// v1 is 0x01, v2 is 0x12, v3 is 0x13
|
||||
uint8_t const revision = reg_read(rhport, REVISION_ADDR, false);
|
||||
@@ -476,7 +509,7 @@ bool hcd_init(uint8_t rhport) {
|
||||
tuh_max3421_int_api(rhport, true);
|
||||
|
||||
// Enable Interrupt pin
|
||||
reg_write(rhport, CPUCTL_ADDR, CPUCTL_IE, false);
|
||||
reg_write(rhport, CPUCTL_ADDR, _tuh_cfg.cpuctl | CPUCTL_IE, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -487,9 +520,9 @@ bool hcd_deinit(uint8_t rhport) {
|
||||
// disable interrupt
|
||||
tuh_max3421_int_api(rhport, false);
|
||||
|
||||
// reset max3421
|
||||
// reset max3421 and power down
|
||||
reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false);
|
||||
reg_write(rhport, USBCTL_ADDR, 0, false);
|
||||
reg_write(rhport, USBCTL_ADDR, USBCTL_PWRDOWN, false);
|
||||
|
||||
#if OSAL_MUTEX_REQUIRED
|
||||
osal_mutex_delete(_hcd_data.spi_mutex);
|
||||
@@ -557,7 +590,6 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) {
|
||||
// Open an endpoint
|
||||
bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * ep_desc) {
|
||||
(void) rhport;
|
||||
(void) daddr;
|
||||
|
||||
uint8_t const ep_num = tu_edpt_number(ep_desc->bEndpointAddress);
|
||||
tusb_dir_t const ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress);
|
||||
@@ -569,12 +601,9 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * e
|
||||
ep = allocate_ep();
|
||||
TU_ASSERT(ep);
|
||||
ep->daddr = daddr;
|
||||
ep->ep_num = (uint8_t) (ep_num & 0x0f);
|
||||
ep->ep_dir = (ep_dir == TUSB_DIR_IN) ? 1 : 0;
|
||||
}
|
||||
|
||||
if ( TUSB_XFER_ISOCHRONOUS == ep_desc->bmAttributes.xfer ) {
|
||||
ep->is_iso = 1;
|
||||
ep->hxfr_bm.ep_num = (uint8_t) (ep_num & 0x0f);
|
||||
ep->hxfr_bm.is_out = (ep_dir == TUSB_DIR_OUT) ? 1 : 0;
|
||||
ep->hxfr_bm.is_iso = (TUSB_XFER_ISOCHRONOUS == ep_desc->bmAttributes.xfer) ? 1 : 0;
|
||||
}
|
||||
|
||||
ep->packet_size = (uint16_t) (tu_edpt_packet_size(ep_desc) & 0x7ff);
|
||||
@@ -582,7 +611,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * e
|
||||
return true;
|
||||
}
|
||||
|
||||
void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
// Page 12: Programming BULK-OUT Transfers
|
||||
// TODO double buffered
|
||||
if (switch_ep) {
|
||||
@@ -598,12 +627,10 @@ void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr);
|
||||
}
|
||||
sndbc_write(rhport, xact_len, in_isr);
|
||||
|
||||
uint8_t const hxfr = (uint8_t ) (ep->ep_num | HXFR_OUT_NIN | (ep->is_iso ? HXFR_ISO : 0));
|
||||
hxfr_write(rhport, hxfr, in_isr);
|
||||
hxfr_write(rhport, ep->hxfr, in_isr);
|
||||
}
|
||||
|
||||
void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
static void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
// Page 13: Programming BULK-IN Transfers
|
||||
if (switch_ep) {
|
||||
peraddr_write(rhport, ep->daddr, in_isr);
|
||||
@@ -612,34 +639,36 @@ void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
reg_write(rhport, HCTL_ADDR, hctl, in_isr);
|
||||
}
|
||||
|
||||
uint8_t const hxfr = (uint8_t) (ep->ep_num | (ep->is_iso ? HXFR_ISO : 0));
|
||||
hxfr_write(rhport, hxfr, in_isr);
|
||||
hxfr_write(rhport, ep->hxfr, in_isr);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline
|
||||
void xact_inout(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
if (ep->ep_num == 0 ) {
|
||||
static void xact_setup(uint8_t rhport, max3421_ep_t *ep, bool in_isr) {
|
||||
peraddr_write(rhport, ep->daddr, in_isr);
|
||||
fifo_write(rhport, SUDFIFO_ADDR, ep->buf, 8, in_isr);
|
||||
hxfr_write(rhport, HXFR_SETUP, in_isr);
|
||||
}
|
||||
|
||||
static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
if (ep->hxfr_bm.ep_num == 0 ) {
|
||||
// setup
|
||||
if (ep->is_setup) {
|
||||
peraddr_write(rhport, ep->daddr, in_isr);
|
||||
fifo_write(rhport, SUDFIFO_ADDR, ep->buf, 8, in_isr);
|
||||
hxfr_write(rhport, HXFR_SETUP, in_isr);
|
||||
if (ep->hxfr_bm.is_setup) {
|
||||
xact_setup(rhport, ep, in_isr);
|
||||
return;
|
||||
}
|
||||
|
||||
// status
|
||||
if (ep->buf == NULL || ep->total_len == 0) {
|
||||
uint8_t const hxfr = HXFR_HS | (ep->ep_dir ? 0 : HXFR_OUT_NIN);
|
||||
uint8_t const hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN));
|
||||
peraddr_write(rhport, ep->daddr, in_isr);
|
||||
hxfr_write(rhport, hxfr, in_isr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ep->ep_dir) {
|
||||
xact_in(rhport, ep, switch_ep, in_isr);
|
||||
}else {
|
||||
if (ep->hxfr_bm.is_out) {
|
||||
xact_out(rhport, ep, switch_ep, in_isr);
|
||||
}else {
|
||||
xact_in(rhport, ep, switch_ep, in_isr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,25 +680,21 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf
|
||||
max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir);
|
||||
TU_VERIFY(ep);
|
||||
|
||||
// control transfer can switch direction
|
||||
ep->ep_dir = ep_dir ? 1u : 0u;
|
||||
if (ep_num == 0) {
|
||||
// control transfer can switch direction
|
||||
ep->hxfr_bm.is_out = ep_dir ? 0 : 1;
|
||||
ep->hxfr_bm.is_setup = 0;
|
||||
ep->data_toggle = 1;
|
||||
}
|
||||
|
||||
ep->buf = buffer;
|
||||
ep->total_len = buflen;
|
||||
ep->xferred_len = 0;
|
||||
ep->xfer_complete = 0;
|
||||
ep->xfer_pending = 1;
|
||||
|
||||
if ( ep_num == 0 ) {
|
||||
ep->is_setup = 0;
|
||||
ep->data_toggle = 1;
|
||||
}
|
||||
ep->state = EP_STATE_ATTEMPT_1;
|
||||
|
||||
// carry out transfer if not busy
|
||||
if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) {
|
||||
xact_inout(rhport, ep, true, false);
|
||||
} else {
|
||||
return true;
|
||||
if (!atomic_flag_test_and_set(&_hcd_data.busy)) {
|
||||
xact_generic(rhport, ep, true, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -692,17 +717,16 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]
|
||||
max3421_ep_t* ep = find_opened_ep(daddr, 0, 0);
|
||||
TU_ASSERT(ep);
|
||||
|
||||
ep->ep_dir = 0;
|
||||
ep->is_setup = 1;
|
||||
ep->hxfr_bm.is_out = 1;
|
||||
ep->hxfr_bm.is_setup = 1;
|
||||
ep->buf = (uint8_t*)(uintptr_t) setup_packet;
|
||||
ep->total_len = 8;
|
||||
ep->xferred_len = 0;
|
||||
ep->xfer_complete = 0;
|
||||
ep->xfer_pending = 1;
|
||||
ep->state = EP_STATE_ATTEMPT_1;
|
||||
|
||||
// carry out transfer if not busy
|
||||
if ( !atomic_flag_test_and_set(&_hcd_data.busy) ) {
|
||||
xact_inout(rhport, ep, true, false);
|
||||
if (!atomic_flag_test_and_set(&_hcd_data.busy)) {
|
||||
xact_setup(rhport, ep, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -767,22 +791,23 @@ static void handle_connect_irq(uint8_t rhport, bool in_isr) {
|
||||
}
|
||||
|
||||
static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl, bool in_isr) {
|
||||
uint8_t const ep_addr = tu_edpt_addr(ep->ep_num, ep->ep_dir);
|
||||
uint8_t const ep_dir = 1-ep->hxfr_bm.is_out;
|
||||
uint8_t const ep_addr = tu_edpt_addr(ep->hxfr_bm.ep_num, ep_dir);
|
||||
|
||||
// save data toggle
|
||||
if (ep->ep_dir) {
|
||||
if (ep_dir) {
|
||||
ep->data_toggle = (hrsl & HRSL_RCVTOGRD) ? 1u : 0u;
|
||||
}else {
|
||||
ep->data_toggle = (hrsl & HRSL_SNDTOGRD) ? 1u : 0u;
|
||||
}
|
||||
|
||||
ep->xfer_pending = 0;
|
||||
ep->state = EP_STATE_IDLE;
|
||||
hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, in_isr);
|
||||
|
||||
// Find next pending endpoint
|
||||
max3421_ep_t *next_ep = find_next_pending_ep(ep);
|
||||
max3421_ep_t * next_ep = find_next_pending_ep(ep);
|
||||
if (next_ep) {
|
||||
xact_inout(rhport, next_ep, true, in_isr);
|
||||
xact_generic(rhport, next_ep, true, in_isr);
|
||||
}else {
|
||||
// no more pending
|
||||
atomic_flag_clear(&_hcd_data.busy);
|
||||
@@ -812,20 +837,23 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
|
||||
case HRSL_NAK:
|
||||
if (ep_num == 0) {
|
||||
// NAK on control, retry immediately
|
||||
// control endpoint -> retry immediately
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||
}else {
|
||||
// NAK on non-control, find next pending to switch
|
||||
max3421_ep_t *next_ep = find_next_pending_ep(ep);
|
||||
} else {
|
||||
if (ep->state < EP_STATE_ATTEMPT_MAX) {
|
||||
ep->state++;
|
||||
}
|
||||
|
||||
max3421_ep_t * next_ep = find_next_pending_ep(ep);
|
||||
if (ep == next_ep) {
|
||||
// this endpoint is only one pending, retry immediately
|
||||
// this endpoint is only one pending -> retry immediately
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||
}else if (next_ep) {
|
||||
// switch to next pending TODO could have issue with double buffered if not clear previously out data
|
||||
xact_inout(rhport, next_ep, true, in_isr);
|
||||
}else {
|
||||
TU_ASSERT(false,);
|
||||
} else if (next_ep) {
|
||||
// switch to next pending endpoint TODO could have issue with double buffered if not clear previously out data
|
||||
xact_generic(rhport, next_ep, true, in_isr);
|
||||
} else {
|
||||
// no more pending in this frame -> clear busy
|
||||
atomic_flag_clear(&_hcd_data.busy);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -847,12 +875,14 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
|
||||
if (ep_dir) {
|
||||
// IN transfer: fifo data is already received in RCVDAV IRQ
|
||||
if ( hxfr_type & HXFR_HS ) {
|
||||
ep->xfer_complete = 1;
|
||||
|
||||
// mark control handshake as complete
|
||||
if (hxfr_type & HXFR_HS) {
|
||||
ep->state = EP_STATE_COMPLETE;
|
||||
}
|
||||
|
||||
// short packet or all bytes transferred
|
||||
if ( ep->xfer_complete ) {
|
||||
if (ep->state == EP_STATE_COMPLETE) {
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr);
|
||||
}else {
|
||||
// more to transfer
|
||||
@@ -886,13 +916,13 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
void print_hirq(uint8_t hirq) {
|
||||
TU_LOG3_HEX(hirq);
|
||||
|
||||
if (hirq & HIRQ_HXFRDN_IRQ) TU_LOG3(" HXFRDN");
|
||||
if (hirq & HIRQ_FRAME_IRQ) TU_LOG3(" FRAME");
|
||||
if (hirq & HIRQ_CONDET_IRQ) TU_LOG3(" CONDET");
|
||||
if (hirq & HIRQ_SUSDN_IRQ) TU_LOG3(" SUSDN");
|
||||
if (hirq & HIRQ_SNDBAV_IRQ) TU_LOG3(" SNDBAV");
|
||||
if (hirq & HIRQ_RCVDAV_IRQ) TU_LOG3(" RCVDAV");
|
||||
if (hirq & HIRQ_RWU_IRQ) TU_LOG3(" RWU");
|
||||
if (hirq & HIRQ_HXFRDN_IRQ) TU_LOG3(" HXFRDN");
|
||||
if (hirq & HIRQ_FRAME_IRQ) TU_LOG3(" FRAME");
|
||||
if (hirq & HIRQ_CONDET_IRQ) TU_LOG3(" CONDET");
|
||||
if (hirq & HIRQ_SUSDN_IRQ) TU_LOG3(" SUSDN");
|
||||
if (hirq & HIRQ_SNDBAV_IRQ) TU_LOG3(" SNDBAV");
|
||||
if (hirq & HIRQ_RCVDAV_IRQ) TU_LOG3(" RCVDAV");
|
||||
if (hirq & HIRQ_RWU_IRQ) TU_LOG3(" RWU");
|
||||
if (hirq & HIRQ_BUSEVENT_IRQ) TU_LOG3(" BUSEVENT");
|
||||
|
||||
TU_LOG3("\r\n");
|
||||
@@ -909,6 +939,25 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||
|
||||
if (hirq & HIRQ_FRAME_IRQ) {
|
||||
_hcd_data.frame_count++;
|
||||
|
||||
max3421_ep_t* ep_retry = NULL;
|
||||
|
||||
// reset all endpoints attempt counter
|
||||
for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) {
|
||||
max3421_ep_t* ep = &_hcd_data.ep[i];
|
||||
if (ep->packet_size && ep->state > EP_STATE_ATTEMPT_1) {
|
||||
ep->state = EP_STATE_ATTEMPT_1;
|
||||
|
||||
if (ep_retry == NULL) {
|
||||
ep_retry = ep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start usb transfer if not busy
|
||||
if (ep_retry != NULL && !atomic_flag_test_and_set(&_hcd_data.busy)) {
|
||||
xact_generic(rhport, ep_retry, true, in_isr);
|
||||
}
|
||||
}
|
||||
|
||||
if (hirq & HIRQ_CONDET_IRQ) {
|
||||
@@ -917,17 +966,17 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||
|
||||
// queue more transfer in handle_xfer_done() can cause hirq to be set again while external IRQ may not catch and/or
|
||||
// not call this handler again. So we need to loop until all IRQ are cleared
|
||||
while ( hirq & (HIRQ_RCVDAV_IRQ | HIRQ_HXFRDN_IRQ) ) {
|
||||
if ( hirq & HIRQ_RCVDAV_IRQ ) {
|
||||
while (hirq & (HIRQ_RCVDAV_IRQ | HIRQ_HXFRDN_IRQ)) {
|
||||
if (hirq & HIRQ_RCVDAV_IRQ) {
|
||||
uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
||||
max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1);
|
||||
max3421_ep_t* ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1);
|
||||
uint8_t xact_len = 0;
|
||||
|
||||
// RCVDAV_IRQ can trigger 2 times (dual buffered)
|
||||
while ( hirq & HIRQ_RCVDAV_IRQ ) {
|
||||
while (hirq & HIRQ_RCVDAV_IRQ) {
|
||||
uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr);
|
||||
xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len);
|
||||
if ( xact_len ) {
|
||||
if (xact_len) {
|
||||
fifo_read(rhport, ep->buf, xact_len, in_isr);
|
||||
ep->buf += xact_len;
|
||||
ep->xferred_len += xact_len;
|
||||
@@ -938,12 +987,12 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||
hirq = reg_read(rhport, HIRQ_ADDR, in_isr);
|
||||
}
|
||||
|
||||
if ( xact_len < ep->packet_size || ep->xferred_len >= ep->total_len ) {
|
||||
ep->xfer_complete = 1;
|
||||
if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) {
|
||||
ep->state = EP_STATE_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hirq & HIRQ_HXFRDN_IRQ ) {
|
||||
if (hirq & HIRQ_HXFRDN_IRQ) {
|
||||
hirq_write(rhport, HIRQ_HXFRDN_IRQ, in_isr);
|
||||
handle_xfer_done(rhport, in_isr);
|
||||
}
|
||||
|
||||
@@ -29,19 +29,28 @@
|
||||
|
||||
#include "fsl_device_registers.h"
|
||||
|
||||
#define CI_FS_REG(_port) ((ci_fs_regs_t*) USBFS0_BASE)
|
||||
#define CI_REG CI_FS_REG(0)
|
||||
#if CFG_TUSB_MCU == OPT_MCU_MCXN9
|
||||
#define CI_FS_REG(_port) ((ci_fs_regs_t*) USBFS0_BASE)
|
||||
#define CIFS_IRQN USB0_FS_IRQn
|
||||
|
||||
void dcd_int_enable(uint8_t rhport)
|
||||
{
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_MCXA15
|
||||
#define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE)
|
||||
#define CIFS_IRQN USB0_IRQn
|
||||
|
||||
#else
|
||||
#error "MCU is not supported"
|
||||
#endif
|
||||
|
||||
#define CI_REG CI_FS_REG(0)
|
||||
|
||||
void dcd_int_enable(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
NVIC_EnableIRQ(USB0_FS_IRQn);
|
||||
NVIC_EnableIRQ(CIFS_IRQN);
|
||||
}
|
||||
|
||||
void dcd_int_disable(uint8_t rhport)
|
||||
{
|
||||
void dcd_int_disable(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
NVIC_DisableIRQ(USB0_FS_IRQn);
|
||||
NVIC_DisableIRQ(CIFS_IRQN);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -295,7 +295,7 @@ void dcd_init(uint8_t rhport)
|
||||
CI_REG->INT_EN = USB_INTEN_USBRSTEN_MASK;
|
||||
|
||||
dcd_connect(rhport);
|
||||
// NVIC_ClearPendingIRQ(USB0_IRQn);
|
||||
// NVIC_ClearPendingIRQ(CIFS_IRQN);
|
||||
}
|
||||
|
||||
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
|
||||
|
||||
@@ -407,6 +407,19 @@ void dcd_init(uint8_t rhport) {
|
||||
dcd_connect(rhport);
|
||||
}
|
||||
|
||||
bool dcd_deinit(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
|
||||
reset_non_control_endpoints();
|
||||
irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq);
|
||||
|
||||
// reset usb hardware into initial state
|
||||
reset_block(RESETS_RESET_USBCTRL_BITS);
|
||||
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcd_int_enable(__unused uint8_t rhport) {
|
||||
assert(rhport == 0);
|
||||
irq_set_enabled(USBCTRL_IRQ, true);
|
||||
|
||||
@@ -409,6 +409,16 @@ bool hcd_init(uint8_t rhport)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hcd_deinit(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
|
||||
irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq);
|
||||
reset_block(RESETS_RESET_USBCTRL_BITS);
|
||||
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void hcd_port_reset(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -102,17 +102,25 @@ static int _dcd_bind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_
|
||||
usbdev = dev;
|
||||
usbdcd_driver.ep[0] = dev->ep0;
|
||||
|
||||
#ifdef EP_ALLOCREQ
|
||||
// SDK v2
|
||||
usbdcd_driver.req[0] = EP_ALLOCREQ(usbdcd_driver.ep[0]);
|
||||
if (usbdcd_driver.req[0] != NULL)
|
||||
{
|
||||
if (usbdcd_driver.req[0] != NULL) {
|
||||
usbdcd_driver.req[0]->len = 64;
|
||||
usbdcd_driver.req[0]->buf = EP_ALLOCBUFFER(usbdcd_driver.ep[0], 64);
|
||||
if (!usbdcd_driver.req[0]->buf)
|
||||
{
|
||||
if (!usbdcd_driver.req[0]->buf) {
|
||||
EP_FREEREQ(usbdcd_driver.ep[0], usbdcd_driver.req[0]);
|
||||
usbdcd_driver.req[0] = NULL;
|
||||
return ENOMEM;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// SDK v3
|
||||
usbdcd_driver.req[0] = usbdev_allocreq(usbdcd_driver.ep[0], 64);
|
||||
if (usbdcd_driver.req[0] == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
usbdcd_driver.req[0]->callback = usbdcd_ep0incomplete;
|
||||
|
||||
@@ -295,13 +303,19 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc)
|
||||
}
|
||||
|
||||
usbdcd_driver.req[epnum] = NULL;
|
||||
|
||||
#ifdef EP_ALLOCREQ
|
||||
// sdk v2
|
||||
usbdcd_driver.req[epnum] = EP_ALLOCREQ(usbdcd_driver.ep[epnum]);
|
||||
if (usbdcd_driver.req[epnum] != NULL)
|
||||
{
|
||||
if (usbdcd_driver.req[epnum] != NULL) {
|
||||
usbdcd_driver.req[epnum]->len = ep_mps;
|
||||
}
|
||||
else
|
||||
{
|
||||
#else
|
||||
// sdk v3
|
||||
usbdcd_driver.req[epnum] = usbdev_allocreq(usbdcd_driver.ep[epnum], ep_mps);
|
||||
#endif
|
||||
|
||||
if(usbdcd_driver.req[epnum] == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,11 @@
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
|
||||
#include "stm32h5xx.h"
|
||||
#define FSDEV_BUS_32BIT
|
||||
|
||||
#if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE)
|
||||
#define USB_DRD_BASE USB_DRD_FS_BASE
|
||||
#endif
|
||||
|
||||
#define FSDEV_PMA_SIZE (2048u)
|
||||
#undef USB_PMAADDR
|
||||
#define USB_PMAADDR USB_DRD_PMAADDR
|
||||
|
||||
@@ -97,7 +97,6 @@ static uint16_t ep0_pending[2]; // Index determines direction as t
|
||||
|
||||
// TX FIFO RAM allocation so far in words - RX FIFO size is readily available from dwc2->grxfsiz
|
||||
static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs)
|
||||
static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size)
|
||||
|
||||
// SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by
|
||||
static bool _sof_en;
|
||||
@@ -113,20 +112,6 @@ static inline uint16_t calc_grxfsiz(uint16_t max_ep_size, uint8_t ep_count) {
|
||||
return 15 + 2 * (max_ep_size / 4) + 2 * ep_count;
|
||||
}
|
||||
|
||||
static void update_grxfsiz(uint8_t rhport) {
|
||||
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
|
||||
uint8_t const ep_count = _dwc2_controller[rhport].ep_count;
|
||||
|
||||
// Determine largest EP size for RX FIFO
|
||||
uint16_t max_epsize = 0;
|
||||
for (uint8_t epnum = 0; epnum < ep_count; epnum++) {
|
||||
max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size);
|
||||
}
|
||||
|
||||
// Update size of RX FIFO
|
||||
dwc2->grxfsiz = calc_grxfsiz(max_epsize, ep_count);
|
||||
}
|
||||
|
||||
static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
|
||||
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
|
||||
uint8_t const ep_count = _dwc2_controller[rhport].ep_count;
|
||||
@@ -268,7 +253,6 @@ static void bus_reset(uint8_t rhport) {
|
||||
uint8_t const ep_count = _dwc2_controller[rhport].ep_count;
|
||||
|
||||
tu_memclr(xfer_status, sizeof(xfer_status));
|
||||
_out_ep_closed = false;
|
||||
|
||||
_sof_en = false;
|
||||
|
||||
@@ -791,26 +775,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t
|
||||
}
|
||||
|
||||
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
|
||||
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
|
||||
|
||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
|
||||
edpt_disable(rhport, ep_addr, false);
|
||||
|
||||
// Update max_size
|
||||
xfer_status[epnum][dir].max_size = 0; // max_size = 0 marks a disabled EP - required for changing FIFO allocation
|
||||
|
||||
if (dir == TUSB_DIR_IN) {
|
||||
uint16_t const fifo_size = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXFD_Msk) >> DIEPTXF_INEPTXFD_Pos;
|
||||
uint16_t const fifo_start = (dwc2->dieptxf[epnum - 1] & DIEPTXF_INEPTXSA_Msk) >> DIEPTXF_INEPTXSA_Pos;
|
||||
|
||||
// For now only the last opened endpoint can be closed without fuss.
|
||||
TU_ASSERT(fifo_start == _dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx,);
|
||||
_allocated_fifo_words_tx -= fifo_size;
|
||||
} else {
|
||||
_out_ep_closed = true; // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty
|
||||
}
|
||||
}
|
||||
|
||||
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
|
||||
@@ -1181,14 +1146,6 @@ void dcd_int_handler(uint8_t rhport) {
|
||||
handle_rxflvl_irq(rhport);
|
||||
} while (dwc2->gotgint & GINTSTS_RXFLVL);
|
||||
|
||||
// Manage RX FIFO size
|
||||
if (_out_ep_closed) {
|
||||
update_grxfsiz(rhport);
|
||||
|
||||
// Disable flag
|
||||
_out_ep_closed = false;
|
||||
}
|
||||
|
||||
dwc2->gintmsk |= GINTMSK_RXFLVLM;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#define TUSB_VERSION_MAJOR 0
|
||||
#define TUSB_VERSION_MINOR 16
|
||||
#define TUSB_VERSION_REVISION 0
|
||||
#define TUSB_VERSION_BUILD 1
|
||||
#define TUSB_VERSION_BUILD 3
|
||||
|
||||
#define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR << 24 | TUSB_VERSION_MINOR << 16 | TUSB_VERSION_REVISION << 8 | TUSB_VERSION_BUILD)
|
||||
#define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION)
|
||||
@@ -144,7 +144,6 @@
|
||||
#define OPT_MCU_RX72N 1402 ///< Renesas RX72N
|
||||
#define OPT_MCU_RAXXX 1403 ///< Renesas RAxxx families
|
||||
|
||||
|
||||
// Mind Motion
|
||||
#define OPT_MCU_MM32F327X 1500 ///< Mind Motion MM32F327
|
||||
|
||||
@@ -181,6 +180,7 @@
|
||||
|
||||
// NXP LPC MCX
|
||||
#define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series
|
||||
#define OPT_MCU_MCXA15 2301 ///< NXP MCX A15 Series
|
||||
|
||||
// Check if configured MCU is one of listed
|
||||
// Apply _TU_CHECK_MCU with || as separator to list of input
|
||||
|
||||
Reference in New Issue
Block a user