Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/device/dcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size);
// Controller API
//--------------------------------------------------------------------+

// optional dcd configuration, called by tud_configure()
bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param);

// Initialize controller to device mode
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init);

Expand Down
15 changes: 12 additions & 3 deletions src/device/usbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@ TU_ATTR_WEAK bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t
return false;
}

TU_ATTR_WEAK bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
(void) rhport; (void) cfg_id; (void) cfg_param;
return false;
}

//--------------------------------------------------------------------+
// Debug
//--------------------------------------------------------------------+
Expand Down Expand Up @@ -493,13 +498,14 @@ void tud_sof_cb_enable(bool en) {
usbd_sof_enable(_usbd_rhport, SOF_CONSUMER_USER, en);
}

//--------------------------------------------------------------------+
// USBD Task
//--------------------------------------------------------------------+
bool tud_inited(void) {
return _usbd_rhport != RHPORT_INVALID;
}

bool tud_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
return dcd_configure(rhport, cfg_id, cfg_param);
}

bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
if (tud_inited()) {
return true; // skip if already initialized
Expand Down Expand Up @@ -623,6 +629,9 @@ bool tud_task_event_ready(void) {
return !osal_queue_empty(_usbd_q);
}

//--------------------------------------------------------------------+
// USBD Task
//--------------------------------------------------------------------+
/* USB Device Driver task
* This top level thread manages all device controller event and delegates events to class-specific drivers.
* This should be called periodically within the mainloop or rtos thread.
Expand Down
20 changes: 20 additions & 0 deletions src/device/usbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,30 @@
extern "C" {
#endif

// ConfigID for tuh_configure()
enum {
TUD_CFGID_INVALID = 0,
TUD_CFGID_DWC2 = 100,
};

typedef struct {
uint16_t bm_double_buffered; // bitmap of IN endpoints to be double buffered, only effective for bulk endpoints
} tud_configure_dwc2_t;

typedef union {
tud_configure_dwc2_t dwc2;
} tud_configure_param_t;

//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+

// Configure device stack behavior with dynamic or port-specific parameters.
// Should be called before tud_init()
// - cfg_id : configure ID (TBD)
// - cfg_param: configure data, structure depends on the ID
bool tud_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param);

// New API to replace tud_init() to init device stack on specific roothub port
bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init);

Expand Down
21 changes: 17 additions & 4 deletions src/portable/synopsys/dwc2/dcd_dwc2.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#define DWC2_DEBUG 2

#include "device/dcd.h"
#include "device/usbd.h"
#include "device/usbd_pvt.h"
#include "dwc2_common.h"

Expand Down Expand Up @@ -76,6 +77,10 @@ CFG_TUD_MEM_SECTION static struct {
TUD_EPBUF_DEF(setup_packet, 8);
} _dcd_usbbuf;

static tud_configure_dwc2_t _tud_cfg = {
.bm_double_buffered = 0
};

TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_ep_count(const dwc2_regs_t* dwc2) {
#if TU_CHECK_MCU(OPT_MCU_GD32VF103)
(void) dwc2;
Expand Down Expand Up @@ -212,8 +217,8 @@ static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
_dcd_data.allocated_epin_count++;
}

// If The TXFELVL is configured as half empty, the fifo must be twice the max_size.
if ((dwc2->gahbcfg & GAHBCFG_TX_FIFO_EPMTY_LVL) == 0) {
// Enable double buffering if configured
if (((_tud_cfg.bm_double_buffered & (1 << epnum)) != 0) && (epnum > 0)) {
fifo_size *= 2;
}

Expand Down Expand Up @@ -446,6 +451,16 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
//--------------------------------------------------------------------
// Controller API
//--------------------------------------------------------------------
// optional dcd configuration, called by tud_configure()
bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
(void) rhport;
TU_VERIFY(cfg_id == TUD_CFGID_DWC2 && cfg_param != NULL);

const tud_configure_param_t* const cfg = (const tud_configure_param_t*) cfg_param;
_tud_cfg = cfg->dwc2;
return true;
}

bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
(void) rh_init;
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
Expand Down Expand Up @@ -492,9 +507,7 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
// Enable required interrupts
dwc2->gintmsk |= GINTMSK_OTGINT | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM;

// TX FIFO empty level for interrupt is complete empty
uint32_t gahbcfg = dwc2->gahbcfg;
gahbcfg |= GAHBCFG_TX_FIFO_EPMTY_LVL;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is no need to set FIFO level to complete empty in any case ?

gahbcfg |= GAHBCFG_GINT; // Enable global interrupt
dwc2->gahbcfg = gahbcfg;

Expand Down
Loading