improve using ep_add_status/ep_add_dtog

This commit is contained in:
hathach 2024-07-31 12:09:50 +07:00
parent 126778298e
commit e60efec6b7
No known key found for this signature in database
GPG Key ID: 26FAB84F615C3C52
2 changed files with 37 additions and 57 deletions

View File

@ -364,10 +364,11 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) {
dcd_event_setup_received(0, (uint8_t*) setup_packet, true);
// Reset EP to NAK (in case it had been stalling)
ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK);
ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK);
ep_reg = ep_add_tx_dtog(ep_reg, 1);
ep_reg = ep_add_rx_dtog(ep_reg, 1);
ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK);
ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK);
ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_IN, 1);
ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_OUT, 1);
} else {
ep_reg &= USB_EPREG_MASK; // reversed all toggle
}
@ -404,15 +405,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) {
// prepared for status packet
btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE);
}
ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK);
ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK);
} else {
// Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always
if (!is_iso) {
uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt);
}
ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_VALID);
ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_VALID);
}
}
@ -594,9 +594,9 @@ void edpt0_open(uint8_t rhport) {
btable_set_addr(0, BTABLE_BUF_TX, pma_addr1);
uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK;
ep_reg |= USB_EP_CONTROL; // | USB_EP_CTR_RX | USB_EP_CTR_TX;
ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK);
ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK);
ep_reg |= USB_EP_CONTROL;
ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK);
ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK);
// no need to explicitly set DTOG bits since we aren't masked DTOG bit
// prepare for setup packet
@ -637,15 +637,16 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size;
xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx;
ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK);
ep_reg = ep_add_dtog(ep_reg, dir, 0);
// reserve other direction toggle bits
if (dir == TUSB_DIR_IN) {
ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK);
ep_reg = ep_add_tx_dtog(ep_reg, 0);
ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX);
} else {
ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK);
ep_reg = ep_add_rx_dtog(ep_reg, 0);
ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX);
}
pcd_set_endpoint(USB, ep_idx, ep_reg);
return true;
@ -669,28 +670,6 @@ void dcd_edpt_close_all(uint8_t rhport)
ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE;
}
/**
* Close an endpoint.
*
* This function may be called with interrupts enabled or disabled.
*
* This also clears transfers in progress, should there be any.
*/
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
{
(void)rhport;
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);
if (dir == TUSB_DIR_IN) {
pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS);
} else {
pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS);
}
}
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
(void)rhport;
@ -724,15 +703,11 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
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 = ep_add_tx_status(ep_reg, USB_EP_TX_DIS);
ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_DIS);
ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
// no need to explicitly set DTOG bits since we aren't masked DTOG bit
if (dir == TUSB_DIR_IN) {
ep_reg = ep_add_rx_dtog(ep_reg, 1);
} else {
ep_reg = ep_add_tx_dtog(ep_reg, 1);
}
ep_add_dtog(ep_reg, dir, 0);
ep_add_dtog(ep_reg, 1-dir, 1);
pcd_set_endpoint(USB, ep_idx, ep_reg);
@ -838,14 +813,15 @@ 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;
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);
// uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx);
if (dir == TUSB_DIR_IN) { // IN
if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) {
pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK);

View File

@ -140,6 +140,10 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct");
#define USB_EPRX_STAT 0x3000U
#endif
#ifndef USB_EPTX_STAT_Pos
#define USB_EPTX_STAT_Pos (4U)
#endif
#ifndef USB_EP_DTOG_TX_Pos
#define USB_EP_DTOG_TX_Pos (6U)
#endif
@ -148,6 +152,13 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct");
#define USB_EP_DTOG_RX_Pos (14U)
#endif
typedef enum {
EP_STAT_DISABLED = 0,
EP_STAT_STALL = 1,
EP_STAT_NAK = 2,
EP_STAT_VALID = 3
}ep_stat_t;
//--------------------------------------------------------------------+
// BTable
//--------------------------------------------------------------------+
@ -291,19 +302,12 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx,
pcd_set_endpoint(USBx, bEpIdx,regVal);
}
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_status(uint32_t reg, uint32_t state) {
return reg ^ state;
}
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint32_t state) {
return reg ^ state;
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) {
return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
}
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) {
return reg ^ (state << USB_EP_DTOG_TX_Pos);
}
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) {
return reg ^ (state << USB_EP_DTOG_RX_Pos);
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) {
return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
}
/**