mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-10 03:44:22 +00:00
fsdev improve ep bit manipulation
This commit is contained in:
parent
271e2a30e1
commit
af8609e96e
@ -353,11 +353,11 @@ static void handle_ctr_rx(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_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK);
|
||||
ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK);
|
||||
ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK);
|
||||
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);
|
||||
ep_add_dtog(&ep_reg, TUSB_DIR_IN, 1);
|
||||
ep_add_dtog(&ep_reg, TUSB_DIR_OUT, 1);
|
||||
} else {
|
||||
ep_reg &= USB_EPREG_MASK; // reversed all toggle
|
||||
}
|
||||
@ -395,14 +395,14 @@ static void handle_ctr_rx(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_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK);
|
||||
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_status(ep_reg, TUSB_DIR_OUT, EP_STAT_VALID);
|
||||
ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,8 +579,8 @@ void edpt0_open(uint8_t rhport) {
|
||||
|
||||
uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK;
|
||||
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);
|
||||
ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK);
|
||||
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
|
||||
@ -623,8 +623,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
|
||||
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_dtog(ep_reg, dir, 0);
|
||||
ep_add_status(&ep_reg, dir, EP_STAT_NAK);
|
||||
ep_add_dtog(&ep_reg, dir, 0);
|
||||
|
||||
// reserve other direction toggle bits
|
||||
if (dir == TUSB_DIR_IN) {
|
||||
@ -694,10 +694,10 @@ 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_status(ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
|
||||
ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
|
||||
ep_reg = ep_add_dtog(ep_reg, dir, 0);
|
||||
ep_reg = ep_add_dtog(ep_reg, 1-dir, 1);
|
||||
ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
|
||||
ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
|
||||
ep_add_dtog(&ep_reg, dir, 0);
|
||||
ep_add_dtog(&ep_reg, 1-dir, 1);
|
||||
|
||||
ep_write(ep_idx, ep_reg);
|
||||
|
||||
@ -707,7 +707,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
|
||||
// Currently, single-buffered, and only 64 bytes at a time (max)
|
||||
static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
|
||||
uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
|
||||
uint16_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX;
|
||||
uint32_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX;
|
||||
bool const is_iso = ep_is_iso(ep_reg);
|
||||
|
||||
uint8_t buf_id;
|
||||
@ -727,8 +727,8 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
|
||||
xfer->queued_len = (uint16_t)(xfer->queued_len + len);
|
||||
|
||||
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN);
|
||||
ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_VALID);
|
||||
ep_reg = ep_clear_ctr(ep_reg, TUSB_DIR_IN);
|
||||
ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID);
|
||||
ep_clear_ctr(&ep_reg, TUSB_DIR_IN);
|
||||
|
||||
dcd_int_disable(0);
|
||||
ep_write(ep_ix, ep_reg);
|
||||
@ -748,9 +748,9 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) {
|
||||
dcd_transmit_packet(xfer, ep_idx);
|
||||
} else {
|
||||
uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size);
|
||||
uint16_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX;
|
||||
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); // keep CTR TX, clear CTR RX
|
||||
ep_reg = ep_add_status(ep_reg, dir, EP_STAT_VALID);
|
||||
uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; // keep CTR TX, clear CTR RX
|
||||
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir);
|
||||
ep_add_status(&ep_reg, dir, EP_STAT_VALID);
|
||||
|
||||
if (ep_is_iso(ep_reg)) {
|
||||
btable_set_rx_bufsize(ep_idx, 0, cnt);
|
||||
@ -801,7 +801,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
|
||||
uint32_t ep_reg = ep_read(ep_idx);
|
||||
ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits
|
||||
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir);
|
||||
ep_reg = ep_add_status(ep_reg, dir, EP_STAT_STALL);
|
||||
ep_add_status(&ep_reg, dir, EP_STAT_STALL);
|
||||
|
||||
ep_write(ep_idx, ep_reg);
|
||||
}
|
||||
@ -818,9 +818,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
|
||||
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir);
|
||||
|
||||
if (!ep_is_iso(ep_reg)) {
|
||||
ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK);
|
||||
ep_add_status(&ep_reg, dir, EP_STAT_NAK);
|
||||
}
|
||||
ep_reg = ep_add_dtog(ep_reg, dir, 0); // Reset to DATA0
|
||||
ep_add_dtog(&ep_reg, dir, 0); // Reset to DATA0
|
||||
|
||||
ep_write(ep_idx, ep_reg);
|
||||
}
|
||||
|
@ -75,10 +75,9 @@ enum {
|
||||
|
||||
// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either
|
||||
// 16-bit or 32-bit depending on FSDEV_BUS_32BIT.
|
||||
// 0: TX (IN), 1: RX (OUT)
|
||||
typedef union {
|
||||
// 0: TX (IN), 1: RX (OUT)
|
||||
|
||||
// strictly 16-bit access (could be 32-bit aligned)
|
||||
// data is strictly 16-bit access (address could be 32-bit aligned)
|
||||
struct {
|
||||
volatile pma_aligned uint16_t addr;
|
||||
volatile pma_aligned uint16_t count;
|
||||
@ -181,16 +180,16 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) {
|
||||
return FSDEV_REG->ep[ep_id].reg;
|
||||
}
|
||||
|
||||
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 void ep_add_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) {
|
||||
*reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
|
||||
}
|
||||
|
||||
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)));
|
||||
TU_ATTR_ALWAYS_INLINE static inline void ep_add_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) {
|
||||
*reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) {
|
||||
return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
|
||||
TU_ATTR_ALWAYS_INLINE static inline void ep_clear_ctr(uint32_t* reg, tusb_dir_t dir) {
|
||||
*reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user