add epin, epout to dwc2 regs
This commit is contained in:
parent
8df078dc9e
commit
3755814f57
|
@ -31,6 +31,7 @@
|
||||||
#include "device/dcd_attr.h"
|
#include "device/dcd_attr.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if TUSB_OPT_DEVICE_ENABLED && \
|
#if TUSB_OPT_DEVICE_ENABLED && \
|
||||||
( defined(DCD_ATTR_DWC2_STM32) || TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) )
|
( defined(DCD_ATTR_DWC2_STM32) || TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) )
|
||||||
|
|
||||||
|
@ -52,8 +53,8 @@
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#define DWC2_REG(_port) ((dwc2_regs_t*) DWC2_REG_BASE)
|
#define DWC2_REG(_port) ((dwc2_regs_t*) DWC2_REG_BASE)
|
||||||
#define EPIN_REG(_port) ((dwc2_epin_t*) (DWC2_REG_BASE + DWC2_IN_ENDPOINT_BASE))
|
#define EPIN_REG(_port) (DWC2_REG(_port)->epin)
|
||||||
#define EPOUT_REG(_port) ((dwc2_epout_t*) (DWC2_REG_BASE + DWC2_OUT_ENDPOINT_BASE))
|
#define EPOUT_REG(_port) (DWC2_REG(_port)->epout)
|
||||||
#define FIFO_BASE(_port, _x) ((volatile uint32_t*) (DWC2_REG_BASE + DWC2_FIFO_BASE + (_x) * DWC2_FIFO_SIZE))
|
#define FIFO_BASE(_port, _x) ((volatile uint32_t*) (DWC2_REG_BASE + DWC2_FIFO_BASE + (_x) * DWC2_FIFO_SIZE))
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -127,7 +128,7 @@ static void bus_reset(uint8_t rhport)
|
||||||
|
|
||||||
// 1. NAK for all OUT endpoints
|
// 1. NAK for all OUT endpoints
|
||||||
for(uint8_t n = 0; n < DWC2_EP_MAX; n++) {
|
for(uint8_t n = 0; n < DWC2_EP_MAX; n++) {
|
||||||
out_ep[n].DOEPCTL |= DOEPCTL_SNAK;
|
out_ep[n].doepctl |= DOEPCTL_SNAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Un-mask interrupt bits
|
// 2. Un-mask interrupt bits
|
||||||
|
@ -193,10 +194,10 @@ static void bus_reset(uint8_t rhport)
|
||||||
dwc2->dieptxf0 = (16 << TX0FD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
|
dwc2->dieptxf0 = (16 << TX0FD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
|
||||||
|
|
||||||
// Fixed control EP0 size to 64 bytes
|
// Fixed control EP0 size to 64 bytes
|
||||||
in_ep[0].DIEPCTL &= ~(0x03 << DIEPCTL_MPSIZ_Pos);
|
in_ep[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos);
|
||||||
xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64;
|
xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64;
|
||||||
|
|
||||||
out_ep[0].DOEPTSIZ |= (3 << DOEPTSIZ_STUPCNT_Pos);
|
out_ep[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos);
|
||||||
|
|
||||||
dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT;
|
dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT;
|
||||||
}
|
}
|
||||||
|
@ -290,17 +291,17 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
|
||||||
// IN and OUT endpoint xfers are interrupt-driven, we just schedule them here.
|
// IN and OUT endpoint xfers are interrupt-driven, we just schedule them here.
|
||||||
if(dir == TUSB_DIR_IN) {
|
if(dir == TUSB_DIR_IN) {
|
||||||
// A full IN transfer (multiple packets, possibly) triggers XFRC.
|
// A full IN transfer (multiple packets, possibly) triggers XFRC.
|
||||||
in_ep[epnum].DIEPTSIZ = (num_packets << DIEPTSIZ_PKTCNT_Pos) |
|
in_ep[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) |
|
||||||
((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk);
|
((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk);
|
||||||
|
|
||||||
in_ep[epnum].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK;
|
in_ep[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
|
||||||
|
|
||||||
// For ISO endpoint set correct odd/even bit for next frame.
|
// For ISO endpoint set correct odd/even bit for next frame.
|
||||||
if ((in_ep[epnum].DIEPCTL & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1)
|
if ((in_ep[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1)
|
||||||
{
|
{
|
||||||
// Take odd/even bit from frame counter.
|
// Take odd/even bit from frame counter.
|
||||||
uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
|
uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
|
||||||
in_ep[epnum].DIEPCTL |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
|
in_ep[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
|
||||||
}
|
}
|
||||||
// Enable fifo empty interrupt only if there are something to put in the fifo.
|
// Enable fifo empty interrupt only if there are something to put in the fifo.
|
||||||
if(total_bytes != 0) {
|
if(total_bytes != 0) {
|
||||||
|
@ -308,16 +309,16 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// A full OUT transfer (multiple packets, possibly) triggers XFRC.
|
// A full OUT transfer (multiple packets, possibly) triggers XFRC.
|
||||||
out_ep[epnum].DOEPTSIZ &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ);
|
out_ep[epnum].doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ);
|
||||||
out_ep[epnum].DOEPTSIZ |= (num_packets << DOEPTSIZ_PKTCNT_Pos) |
|
out_ep[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) |
|
||||||
((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk);
|
((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk);
|
||||||
|
|
||||||
out_ep[epnum].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK;
|
out_ep[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK;
|
||||||
if ((out_ep[epnum].DOEPCTL & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1)
|
if ((out_ep[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1)
|
||||||
{
|
{
|
||||||
// Take odd/even bit from frame counter.
|
// Take odd/even bit from frame counter.
|
||||||
uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
|
uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
|
||||||
out_ep[epnum].DOEPCTL |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk);
|
out_ep[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,12 +404,12 @@ void dcd_init (uint8_t rhport)
|
||||||
|
|
||||||
void dcd_int_enable (uint8_t rhport)
|
void dcd_int_enable (uint8_t rhport)
|
||||||
{
|
{
|
||||||
dcd_dwc2_int_enable(rhport);
|
dwc2_dcd_int_enable(rhport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_int_disable (uint8_t rhport)
|
void dcd_int_disable (uint8_t rhport)
|
||||||
{
|
{
|
||||||
dcd_dwc2_int_disable(rhport);
|
dwc2_dcd_int_disable(rhport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
|
void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
|
||||||
|
@ -491,7 +492,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
||||||
dwc2->grxfsiz = sz;
|
dwc2->grxfsiz = sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_ep[epnum].DOEPCTL |= (1 << DOEPCTL_USBAEP_Pos) |
|
out_ep[epnum].doepctl |= (1 << DOEPCTL_USBAEP_Pos) |
|
||||||
(desc_edpt->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) |
|
(desc_edpt->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) |
|
||||||
(desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) |
|
(desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) |
|
||||||
(xfer->max_size << DOEPCTL_MPSIZ_Pos);
|
(xfer->max_size << DOEPCTL_MPSIZ_Pos);
|
||||||
|
@ -532,7 +533,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
||||||
// Both TXFD and TXSA are in unit of 32-bit words.
|
// Both TXFD and TXSA are in unit of 32-bit words.
|
||||||
dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
|
dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
|
||||||
|
|
||||||
in_ep[epnum].DIEPCTL |= (1 << DIEPCTL_USBAEP_Pos) |
|
in_ep[epnum].diepctl |= (1 << DIEPCTL_USBAEP_Pos) |
|
||||||
(epnum << DIEPCTL_TXFNUM_Pos) |
|
(epnum << DIEPCTL_TXFNUM_Pos) |
|
||||||
(desc_edpt->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) |
|
(desc_edpt->bmAttributes.xfer << DIEPCTL_EPTYP_Pos) |
|
||||||
(desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) |
|
(desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DIEPCTL_SD0PID_SEVNFRM : 0) |
|
||||||
|
@ -559,11 +560,11 @@ void dcd_edpt_close_all (uint8_t rhport)
|
||||||
for(uint8_t n = 1; n < DWC2_EP_MAX; n++)
|
for(uint8_t n = 1; n < DWC2_EP_MAX; n++)
|
||||||
{
|
{
|
||||||
// disable OUT endpoint
|
// disable OUT endpoint
|
||||||
out_ep[n].DOEPCTL = 0;
|
out_ep[n].doepctl = 0;
|
||||||
xfer_status[n][TUSB_DIR_OUT].max_size = 0;
|
xfer_status[n][TUSB_DIR_OUT].max_size = 0;
|
||||||
|
|
||||||
// disable IN endpoint
|
// disable IN endpoint
|
||||||
in_ep[n].DIEPCTL = 0;
|
in_ep[n].diepctl = 0;
|
||||||
xfer_status[n][TUSB_DIR_IN].max_size = 0;
|
xfer_status[n][TUSB_DIR_IN].max_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,21 +646,21 @@ static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall)
|
||||||
if ( dir == TUSB_DIR_IN )
|
if ( dir == TUSB_DIR_IN )
|
||||||
{
|
{
|
||||||
// Only disable currently enabled non-control endpoint
|
// Only disable currently enabled non-control endpoint
|
||||||
if ( (epnum == 0) || !(in_ep[epnum].DIEPCTL & DIEPCTL_EPENA) )
|
if ( (epnum == 0) || !(in_ep[epnum].diepctl & DIEPCTL_EPENA) )
|
||||||
{
|
{
|
||||||
in_ep[epnum].DIEPCTL |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0);
|
in_ep[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Stop transmitting packets and NAK IN xfers.
|
// Stop transmitting packets and NAK IN xfers.
|
||||||
in_ep[epnum].DIEPCTL |= DIEPCTL_SNAK;
|
in_ep[epnum].diepctl |= DIEPCTL_SNAK;
|
||||||
while ( (in_ep[epnum].DIEPINT & DIEPINT_INEPNE) == 0 ) {}
|
while ( (in_ep[epnum].diepint & DIEPINT_INEPNE) == 0 ) {}
|
||||||
|
|
||||||
// Disable the endpoint.
|
// Disable the endpoint.
|
||||||
in_ep[epnum].DIEPCTL |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0);
|
in_ep[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0);
|
||||||
while ( (in_ep[epnum].DIEPINT & DIEPINT_EPDISD_Msk) == 0 ) {}
|
while ( (in_ep[epnum].diepint & DIEPINT_EPDISD_Msk) == 0 ) {}
|
||||||
|
|
||||||
in_ep[epnum].DIEPINT = DIEPINT_EPDISD;
|
in_ep[epnum].diepint = DIEPINT_EPDISD;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the FIFO, and wait until we have confirmed it cleared.
|
// Flush the FIFO, and wait until we have confirmed it cleared.
|
||||||
|
@ -670,9 +671,9 @@ static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Only disable currently enabled non-control endpoint
|
// Only disable currently enabled non-control endpoint
|
||||||
if ( (epnum == 0) || !(out_ep[epnum].DOEPCTL & DOEPCTL_EPENA) )
|
if ( (epnum == 0) || !(out_ep[epnum].doepctl & DOEPCTL_EPENA) )
|
||||||
{
|
{
|
||||||
out_ep[epnum].DOEPCTL |= stall ? DOEPCTL_STALL : 0;
|
out_ep[epnum].doepctl |= stall ? DOEPCTL_STALL : 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -684,10 +685,10 @@ static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall)
|
||||||
while ( (dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0 ) {}
|
while ( (dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0 ) {}
|
||||||
|
|
||||||
// Ditto here- disable the endpoint.
|
// Ditto here- disable the endpoint.
|
||||||
out_ep[epnum].DOEPCTL |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0);
|
out_ep[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0);
|
||||||
while ( (out_ep[epnum].DOEPINT & DOEPINT_EPDISD_Msk) == 0 ) {}
|
while ( (out_ep[epnum].doepint & DOEPINT_EPDISD_Msk) == 0 ) {}
|
||||||
|
|
||||||
out_ep[epnum].DOEPINT = DOEPINT_EPDISD;
|
out_ep[epnum].doepint = DOEPINT_EPDISD;
|
||||||
|
|
||||||
// Allow other OUT endpoints to keep receiving.
|
// Allow other OUT endpoints to keep receiving.
|
||||||
dwc2->dctl |= DCTL_CGONAK;
|
dwc2->dctl |= DCTL_CGONAK;
|
||||||
|
@ -742,13 +743,13 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
// Clear stall and reset data toggle
|
// Clear stall and reset data toggle
|
||||||
if ( dir == TUSB_DIR_IN )
|
if ( dir == TUSB_DIR_IN )
|
||||||
{
|
{
|
||||||
in_ep[epnum].DIEPCTL &= ~DIEPCTL_STALL;
|
in_ep[epnum].diepctl &= ~DIEPCTL_STALL;
|
||||||
in_ep[epnum].DIEPCTL |= DIEPCTL_SD0PID_SEVNFRM;
|
in_ep[epnum].diepctl |= DIEPCTL_SD0PID_SEVNFRM;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out_ep[epnum].DOEPCTL &= ~DOEPCTL_STALL;
|
out_ep[epnum].doepctl &= ~DOEPCTL_STALL;
|
||||||
out_ep[epnum].DOEPCTL |= DOEPCTL_SD0PID_SEVNFRM;
|
out_ep[epnum].doepctl |= DOEPCTL_SD0PID_SEVNFRM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,7 +860,7 @@ static void handle_rxflvl_ints(uint8_t rhport, dwc2_epout_t * out_ep) {
|
||||||
|
|
||||||
// Truncate transfer length in case of short packet
|
// Truncate transfer length in case of short packet
|
||||||
if(bcnt < xfer->max_size) {
|
if(bcnt < xfer->max_size) {
|
||||||
xfer->total_len -= (out_ep[epnum].DOEPTSIZ & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos;
|
xfer->total_len -= (out_ep[epnum].doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos;
|
||||||
if(epnum == 0) {
|
if(epnum == 0) {
|
||||||
xfer->total_len -= ep0_pending[TUSB_DIR_OUT];
|
xfer->total_len -= ep0_pending[TUSB_DIR_OUT];
|
||||||
ep0_pending[TUSB_DIR_OUT] = 0;
|
ep0_pending[TUSB_DIR_OUT] = 0;
|
||||||
|
@ -872,7 +873,7 @@ static void handle_rxflvl_ints(uint8_t rhport, dwc2_epout_t * out_ep) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04: // Setup packet done (Interrupt)
|
case 0x04: // Setup packet done (Interrupt)
|
||||||
out_ep[epnum].DOEPTSIZ |= (3 << DOEPTSIZ_STUPCNT_Pos);
|
out_ep[epnum].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x06: // Setup packet recvd
|
case 0x06: // Setup packet recvd
|
||||||
|
@ -899,16 +900,16 @@ static void handle_epout_ints (uint8_t rhport, dwc2_regs_t *dwc2, dwc2_epout_t *
|
||||||
if ( dwc2->daint & (1 << (DAINT_OEPINT_Pos + n)) )
|
if ( dwc2->daint & (1 << (DAINT_OEPINT_Pos + n)) )
|
||||||
{
|
{
|
||||||
// SETUP packet Setup Phase done.
|
// SETUP packet Setup Phase done.
|
||||||
if ( out_ep[n].DOEPINT & DOEPINT_STUP )
|
if ( out_ep[n].doepint & DOEPINT_STUP )
|
||||||
{
|
{
|
||||||
out_ep[n].DOEPINT = DOEPINT_STUP;
|
out_ep[n].doepint = DOEPINT_STUP;
|
||||||
dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true);
|
dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// OUT XFER complete
|
// OUT XFER complete
|
||||||
if ( out_ep[n].DOEPINT & DOEPINT_XFRC )
|
if ( out_ep[n].doepint & DOEPINT_XFRC )
|
||||||
{
|
{
|
||||||
out_ep[n].DOEPINT = DOEPINT_XFRC;
|
out_ep[n].doepint = DOEPINT_XFRC;
|
||||||
|
|
||||||
// EP0 can only handle one packet
|
// EP0 can only handle one packet
|
||||||
if ( (n == 0) && ep0_pending[TUSB_DIR_OUT] )
|
if ( (n == 0) && ep0_pending[TUSB_DIR_OUT] )
|
||||||
|
@ -935,9 +936,9 @@ static void handle_epin_ints(uint8_t rhport, dwc2_regs_t * dwc2, dwc2_epin_t * i
|
||||||
if ( dwc2->daint & (1 << (DAINT_IEPINT_Pos + n)) )
|
if ( dwc2->daint & (1 << (DAINT_IEPINT_Pos + n)) )
|
||||||
{
|
{
|
||||||
// IN XFER complete (entire xfer).
|
// IN XFER complete (entire xfer).
|
||||||
if ( in_ep[n].DIEPINT & DIEPINT_XFRC )
|
if ( in_ep[n].diepint & DIEPINT_XFRC )
|
||||||
{
|
{
|
||||||
in_ep[n].DIEPINT = DIEPINT_XFRC;
|
in_ep[n].diepint = DIEPINT_XFRC;
|
||||||
|
|
||||||
// EP0 can only handle one packet
|
// EP0 can only handle one packet
|
||||||
if((n == 0) && ep0_pending[TUSB_DIR_IN]) {
|
if((n == 0) && ep0_pending[TUSB_DIR_IN]) {
|
||||||
|
@ -949,26 +950,26 @@ static void handle_epin_ints(uint8_t rhport, dwc2_regs_t * dwc2, dwc2_epin_t * i
|
||||||
}
|
}
|
||||||
|
|
||||||
// XFER FIFO empty
|
// XFER FIFO empty
|
||||||
if ( (in_ep[n].DIEPINT & DIEPINT_TXFE) && (dwc2->diepempmsk & (1 << n)) )
|
if ( (in_ep[n].diepint & DIEPINT_TXFE) && (dwc2->diepempmsk & (1 << n)) )
|
||||||
{
|
{
|
||||||
// DIEPINT's TXFE bit is read-only, software cannot clear it.
|
// diepint's TXFE bit is read-only, software cannot clear it.
|
||||||
// It will only be cleared by hardware when written bytes is more than
|
// It will only be cleared by hardware when written bytes is more than
|
||||||
// - 64 bytes or
|
// - 64 bytes or
|
||||||
// - Half of TX FIFO size (configured by DIEPTXF)
|
// - Half of TX FIFO size (configured by DIEPTXF)
|
||||||
|
|
||||||
uint16_t remaining_packets = (in_ep[n].DIEPTSIZ & DIEPTSIZ_PKTCNT_Msk) >> DIEPTSIZ_PKTCNT_Pos;
|
uint16_t remaining_packets = (in_ep[n].dieptsiz & DIEPTSIZ_PKTCNT_Msk) >> DIEPTSIZ_PKTCNT_Pos;
|
||||||
|
|
||||||
// Process every single packet (only whole packets can be written to fifo)
|
// Process every single packet (only whole packets can be written to fifo)
|
||||||
for(uint16_t i = 0; i < remaining_packets; i++)
|
for(uint16_t i = 0; i < remaining_packets; i++)
|
||||||
{
|
{
|
||||||
uint16_t const remaining_bytes = (in_ep[n].DIEPTSIZ & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos;
|
uint16_t const remaining_bytes = (in_ep[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos;
|
||||||
|
|
||||||
// Packet can not be larger than ep max size
|
// Packet can not be larger than ep max size
|
||||||
uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size);
|
uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size);
|
||||||
|
|
||||||
// It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current
|
// It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current
|
||||||
// EP has to be checked if the buffer can take another WHOLE packet
|
// EP has to be checked if the buffer can take another WHOLE packet
|
||||||
if(packet_size > ((in_ep[n].DTXFSTS & DTXFSTS_INEPTFSAV_Msk) << 2)) break;
|
if(packet_size > ((in_ep[n].dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) break;
|
||||||
|
|
||||||
// Push packet to Tx-FIFO
|
// Push packet to Tx-FIFO
|
||||||
if (xfer->ff)
|
if (xfer->ff)
|
||||||
|
@ -986,7 +987,7 @@ static void handle_epin_ints(uint8_t rhport, dwc2_regs_t * dwc2, dwc2_epin_t * i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn off TXFE if all bytes are written.
|
// Turn off TXFE if all bytes are written.
|
||||||
if (((in_ep[n].DIEPTSIZ & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos) == 0)
|
if (((in_ep[n].dieptsiz & DIEPTSIZ_XFRSIZ_Msk) >> DIEPTSIZ_XFRSIZ_Pos) == 0)
|
||||||
{
|
{
|
||||||
dwc2->diepempmsk &= ~(1 << n);
|
dwc2->diepempmsk &= ~(1 << n);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,13 +50,13 @@ static void dcd_int_handler_wrap(void* arg)
|
||||||
dcd_int_handler(0);
|
dcd_int_handler(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dcd_dwc2_int_enable (uint8_t rhport)
|
static inline void dwc2_dcd_int_enable (uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih);
|
esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void dcd_dwc2_int_disable (uint8_t rhport)
|
static inline void dwc2_dcd_int_disable (uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
esp_intr_free(usb_ih);
|
esp_intr_free(usb_ih);
|
||||||
|
|
|
@ -55,14 +55,14 @@ static inline void __eclic_disable_interrupt (uint32_t irq){
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE
|
TU_ATTR_ALWAYS_INLINE
|
||||||
static inline void dcd_dwc2_int_enable(uint8_t rhport)
|
static inline void dwc2_dcd_int_enable(uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
__eclic_enable_interrupt(RHPORT_IRQn);
|
__eclic_enable_interrupt(RHPORT_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE
|
TU_ATTR_ALWAYS_INLINE
|
||||||
static inline void dcd_dwc2_int_disable (uint8_t rhport)
|
static inline void dwc2_dcd_int_disable (uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
__eclic_disable_interrupt(RHPORT_IRQn);
|
__eclic_disable_interrupt(RHPORT_IRQn);
|
||||||
|
|
|
@ -91,14 +91,14 @@
|
||||||
extern uint32_t SystemCoreClock;
|
extern uint32_t SystemCoreClock;
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE
|
TU_ATTR_ALWAYS_INLINE
|
||||||
static inline void dcd_dwc2_int_enable(uint8_t rhport)
|
static inline void dwc2_dcd_int_enable(uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
NVIC_EnableIRQ(RHPORT_IRQn);
|
NVIC_EnableIRQ(RHPORT_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE
|
TU_ATTR_ALWAYS_INLINE
|
||||||
static inline void dcd_dwc2_int_disable (uint8_t rhport)
|
static inline void dwc2_dcd_int_disable (uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
NVIC_DisableIRQ(RHPORT_IRQn);
|
NVIC_DisableIRQ(RHPORT_IRQn);
|
||||||
|
|
|
@ -40,16 +40,41 @@ typedef struct
|
||||||
// Host Channel
|
// Host Channel
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
volatile uint32_t hcchar; // 500 + 20n Host Channel Characteristics Register
|
volatile uint32_t hcchar; // 500 + 20*ch Host Channel Characteristics Register
|
||||||
volatile uint32_t hcsplt; // 504 + 20n Host Channel Split Control Register
|
volatile uint32_t hcsplt; // 504 + 20*ch Host Channel Split Control Register
|
||||||
volatile uint32_t hcint; // 508 + 20n Host Channel Interrupt Register
|
volatile uint32_t hcint; // 508 + 20*ch Host Channel Interrupt Register
|
||||||
volatile uint32_t hcintmsk; // 50C + 20n Host Channel Interrupt Mask Register
|
volatile uint32_t hcintmsk; // 50C + 20*ch Host Channel Interrupt Mask Register
|
||||||
volatile uint32_t hctsiz; // 510 + 20n Host Channel Transfer Size Register
|
volatile uint32_t hctsiz; // 510 + 20*ch Host Channel Transfer Size Register
|
||||||
volatile uint32_t hcdma; // 514 + 20n Host Channel DMA Address Register
|
volatile uint32_t hcdma; // 514 + 20*ch Host Channel DMA Address Register
|
||||||
uint32_t reserved518; // 518 + 20n
|
uint32_t reserved518; // 518 + 20*ch
|
||||||
volatile uint32_t hcdmab; // 51C + 20n Host Channel DMA Address Register
|
volatile uint32_t hcdmab; // 51C + 20*ch Host Channel DMA Address Register
|
||||||
} dwc2_channel_t;
|
} dwc2_channel_t;
|
||||||
|
|
||||||
|
// Endpoint IN
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
volatile uint32_t diepctl; // 900 + 20*ep Device IN Endpoint Control
|
||||||
|
uint32_t reserved04; // 904
|
||||||
|
volatile uint32_t diepint; // 908 + 20*ep Device IN Endpoint Interrupt
|
||||||
|
uint32_t reserved0c; // 90C
|
||||||
|
volatile uint32_t dieptsiz; // 910 + 20*ep Device IN Endpoint Transfer Size
|
||||||
|
volatile uint32_t diepdma; // 914 + 20*ep Device IN Endpoint DMA Address
|
||||||
|
volatile uint32_t dtxfsts; // 918 + 20*ep Device IN Endpoint Tx FIFO Status
|
||||||
|
uint32_t reserved1c; // 91C
|
||||||
|
} dwc2_epin_t;
|
||||||
|
|
||||||
|
// Endpoint OUT
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
volatile uint32_t doepctl; // B00 + 20*ep Device OUT Endpoint Control
|
||||||
|
uint32_t reserved04; // B04
|
||||||
|
volatile uint32_t doepint; // B08 + 20*ep Device OUT Endpoint Interrupt
|
||||||
|
uint32_t reserved0c; // B0C
|
||||||
|
volatile uint32_t doeptsiz; // B10 + 20*ep Device OUT Endpoint Transfer Size
|
||||||
|
volatile uint32_t doepdma; // B14 + 20*ep Device OUT Endpoint DMA Address
|
||||||
|
uint32_t reserved18[2]; // B18..B1C
|
||||||
|
} dwc2_epout_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
//------------- Core Global -------------//
|
//------------- Core Global -------------//
|
||||||
|
@ -123,48 +148,22 @@ union {
|
||||||
volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time Register
|
volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time Register
|
||||||
volatile uint32_t dthrctl; // 830 Device threshold Control
|
volatile uint32_t dthrctl; // 830 Device threshold Control
|
||||||
volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask
|
volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask
|
||||||
|
|
||||||
volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt
|
volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt
|
||||||
volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk
|
volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk
|
||||||
volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask
|
volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask
|
||||||
volatile uint32_t doepeachmsk[16]; // 880..8BC Device Each OUT Endpoint mask
|
volatile uint32_t doepeachmsk[16]; // 880..8BC Device Each OUT Endpoint mask
|
||||||
uint32_t reserved8c0[16]; // 8C0..8FC
|
uint32_t reserved8c0[16]; // 8C0..8FC
|
||||||
|
|
||||||
//------------- Device IN Endpoint -------------//
|
//------------- Device Endpoint -------------//
|
||||||
|
dwc2_epin_t epin[16]; // 900..AFC IN Endpoints
|
||||||
|
dwc2_epout_t epout[16]; // B00..CFC OUT Endpoints
|
||||||
//------------- Device OUT Endpoint -------------//
|
|
||||||
} dwc2_regs_t;
|
} dwc2_regs_t;
|
||||||
|
|
||||||
TU_VERIFY_STATIC(offsetof(dwc2_regs_t, hcfg ) == 0x0400, "incorrect size");
|
TU_VERIFY_STATIC(offsetof(dwc2_regs_t, hcfg ) == 0x400, "incorrect size");
|
||||||
TU_VERIFY_STATIC(offsetof(dwc2_regs_t, channel) == 0x0500, "incorrect size");
|
TU_VERIFY_STATIC(offsetof(dwc2_regs_t, channel) == 0x500, "incorrect size");
|
||||||
TU_VERIFY_STATIC(offsetof(dwc2_regs_t, dcfg ) == 0x0800, "incorrect size");
|
TU_VERIFY_STATIC(offsetof(dwc2_regs_t, dcfg ) == 0x800, "incorrect size");
|
||||||
|
TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epin ) == 0x900, "incorrect size");
|
||||||
// Endpoint IN
|
TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epout ) == 0xB00, "incorrect size");
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
volatile uint32_t DIEPCTL; // dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h */
|
|
||||||
uint32_t Reserved04; // Reserved 900h + (ep_num * 20h) + 04h */
|
|
||||||
volatile uint32_t DIEPINT; // dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h */
|
|
||||||
uint32_t Reserved0C; // Reserved 900h + (ep_num * 20h) + 0Ch */
|
|
||||||
volatile uint32_t DIEPTSIZ; // IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h */
|
|
||||||
volatile uint32_t DIEPDMA; // IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h */
|
|
||||||
volatile uint32_t DTXFSTS; // IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h */
|
|
||||||
uint32_t Reserved18; // Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch */
|
|
||||||
} dwc2_epin_t;
|
|
||||||
|
|
||||||
// Endpoint OUT
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
volatile uint32_t DOEPCTL; // dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h */
|
|
||||||
uint32_t Reserved04; // Reserved B00h + (ep_num * 20h) + 04h */
|
|
||||||
volatile uint32_t DOEPINT; // dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h */
|
|
||||||
uint32_t Reserved0C; // Reserved B00h + (ep_num * 20h) + 0Ch */
|
|
||||||
volatile uint32_t DOEPTSIZ; // dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h */
|
|
||||||
volatile uint32_t DOEPDMA; // dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h */
|
|
||||||
uint32_t Reserved18[2]; // Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch */
|
|
||||||
} dwc2_epout_t;
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Register Base Address
|
// Register Base Address
|
||||||
|
|
Loading…
Reference in New Issue