refactor xfer_ctl_ptr() to take epnum/dir to reduce computation

This commit is contained in:
hathach
2024-07-31 17:24:41 +07:00
parent ce0fdc5609
commit 26b0df2c26

View File

@@ -165,7 +165,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested
// into the stack. // into the stack.
static void handle_bus_reset(uint8_t rhport); static void handle_bus_reset(uint8_t rhport);
static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix);
static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir);
// PMA allocation/access // PMA allocation/access
static uint16_t ep_buf_ptr; ///< Points to first free memory location static uint16_t ep_buf_ptr; ///< Points to first free memory location
@@ -183,13 +183,7 @@ static void edpt0_open(uint8_t rhport);
// Inline helper // Inline helper
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr) TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint8_t dir) {
{
uint8_t epnum = tu_edpt_number(ep_addr);
uint8_t dir = tu_edpt_dir(ep_addr);
// Fix -Werror=null-dereference
TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX, &xfer_status[0][0]);
return &xfer_status[epnum][dir]; return &xfer_status[epnum][dir];
} }
@@ -290,8 +284,9 @@ static void handle_ctr_tx(uint32_t ep_id) {
// Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary?
TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); TU_VERIFY(ep_reg & USB_EP_CTR_TX, );
uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD;
uint8_t ep_addr = (ep_reg & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; uint8_t ep_addr = (ep_reg & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK;
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN);
if (ep_is_iso(ep_reg)) { if (ep_is_iso(ep_reg)) {
// Ignore spurious interrupts that we don't schedule // Ignore spurious interrupts that we don't schedule
@@ -344,11 +339,9 @@ static void handle_ctr_rx(uint32_t ep_id) {
// Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary?
TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); TU_VERIFY(ep_reg & USB_EP_CTR_RX, );
ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; // Clear CTR RX and reserved CTR TX
uint8_t const ep_addr = ep_reg & USB_EPADDR_FIELD; uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD;
// Clear CTR RX and reserved CTR TX
ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX;
if (ep_reg & USB_EP_SETUP) { if (ep_reg & USB_EP_SETUP) {
uint32_t count = btable_get_count(ep_id, BTABLE_BUF_RX); uint32_t count = btable_get_count(ep_id, BTABLE_BUF_RX);
@@ -372,7 +365,7 @@ static void handle_ctr_rx(uint32_t ep_id) {
ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status
bool const is_iso = ep_is_iso(ep_reg); bool const is_iso = ep_is_iso(ep_reg);
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT);
uint8_t buf_id; uint8_t buf_id;
if (is_iso) { if (is_iso) {
@@ -394,10 +387,11 @@ static void handle_ctr_rx(uint32_t ep_id) {
} }
if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) {
uint8_t const ep_addr = ep_num;
// all bytes received or short packet // all bytes received or short packet
dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true);
if (ep_addr == 0u) { if (ep_num == 0) {
// prepared for status packet // prepared for status packet
btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE);
} }
@@ -598,6 +592,7 @@ void edpt0_open(uint8_t rhport) {
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
(void)rhport; (void)rhport;
uint8_t const ep_addr = desc_ep->bEndpointAddress; uint8_t const ep_addr = desc_ep->bEndpointAddress;
uint8_t const ep_num = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
const uint16_t packet_size = tu_edpt_packet_size(desc_ep); const uint16_t packet_size = tu_edpt_packet_size(desc_ep);
uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer);
@@ -624,8 +619,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
uint16_t pma_addr = dcd_pma_alloc(packet_size, false); uint16_t pma_addr = dcd_pma_alloc(packet_size, false);
btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr);
xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; xfer->max_packet_size = packet_size;
xfer->ep_idx = ep_idx;
ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK);
ep_reg = ep_add_dtog(ep_reg, dir, 0); ep_reg = ep_add_dtog(ep_reg, dir, 0);
@@ -663,6 +659,8 @@ void dcd_edpt_close_all(uint8_t rhport)
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
(void)rhport; (void)rhport;
uint8_t const ep_num = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS);
/* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA,
@@ -676,7 +674,9 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 0, pma_addr);
btable_set_addr(ep_idx, 1, pma_addr2); btable_set_addr(ep_idx, 1, pma_addr2);
xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx;
xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
xfer->ep_idx = ep_idx;
return true; return true;
} }
@@ -684,10 +684,13 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
(void)rhport; (void)rhport;
uint8_t const ep_addr = desc_ep->bEndpointAddress; uint8_t const ep_addr = desc_ep->bEndpointAddress;
uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx; uint8_t const ep_num = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(desc_ep); uint8_t const ep_idx = xfer->ep_idx;
xfer->max_packet_size = tu_edpt_packet_size(desc_ep);
uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK;
ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX;
@@ -735,12 +738,11 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
dcd_int_enable(0); dcd_int_enable(0);
} }
static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) {
(void) rhport; (void) rhport;
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
uint8_t const ep_idx = xfer->ep_idx; uint8_t const ep_idx = xfer->ep_idx;
uint8_t const dir = tu_edpt_dir(ep_addr);
if (dir == TUSB_DIR_IN) { if (dir == TUSB_DIR_IN) {
dcd_transmit_packet(xfer, ep_idx); dcd_transmit_packet(xfer, ep_idx);
@@ -764,31 +766,37 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) {
} }
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) {
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_num = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
xfer->buffer = buffer; xfer->buffer = buffer;
xfer->ff = NULL; xfer->ff = NULL;
xfer->total_len = total_bytes; xfer->total_len = total_bytes;
xfer->queued_len = 0; xfer->queued_len = 0;
return edpt_xfer(rhport, ep_addr); return edpt_xfer(rhport, ep_num, dir);
} }
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) {
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_num = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
xfer->buffer = NULL; xfer->buffer = NULL;
xfer->ff = ff; xfer->ff = ff;
xfer->total_len = total_bytes; xfer->total_len = total_bytes;
xfer->queued_len = 0; xfer->queued_len = 0;
return edpt_xfer(rhport, ep_addr); return edpt_xfer(rhport, ep_num, dir);
} }
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
(void)rhport; (void)rhport;
uint8_t const ep_num = tu_edpt_number(ep_addr);
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr);
uint8_t const ep_idx = xfer->ep_idx;
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
uint8_t const ep_idx = xfer->ep_idx;
uint32_t ep_reg = ep_read(ep_idx); uint32_t ep_reg = ep_read(ep_idx);
ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits
@@ -801,11 +809,12 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
(void)rhport; (void)rhport;
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_num = tu_edpt_number(ep_addr);
uint8_t const ep_idx = xfer->ep_idx;
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
uint32_t ep_reg = ep_read(ep_idx); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits uint8_t const ep_idx = xfer->ep_idx;
uint32_t ep_reg = ep_read(ep_idx) | EP_CTR_TXRX;
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir);
if (!ep_is_iso(ep_reg)) { if (!ep_is_iso(ep_reg)) {