mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-21 03:40:52 +00:00
remove all pcd ep read, modify write
This commit is contained in:
parent
8139840d7a
commit
3156f1c4a7
@ -286,21 +286,15 @@ static void handle_bus_reset(uint8_t rhport) {
|
|||||||
|
|
||||||
// Handle CTR interrupt for the TX/IN direction
|
// Handle CTR interrupt for the TX/IN direction
|
||||||
static void dcd_ep_ctr_tx_handler(uint32_t ep_id) {
|
static void dcd_ep_ctr_tx_handler(uint32_t ep_id) {
|
||||||
uint32_t wEPRegVal = pcd_get_endpoint(USB, ep_id);
|
uint32_t ep_reg = pcd_get_endpoint(USB, ep_id) & USB_EPREG_MASK;
|
||||||
uint8_t ep_addr = (wEPRegVal & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK;
|
|
||||||
|
|
||||||
// Verify the CTR_TX bit is set. This was in the ST Micro code,
|
// Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary?
|
||||||
// but I'm not sure it's actually necessary?
|
TU_VERIFY(ep_reg & USB_EP_CTR_TX, );
|
||||||
if ((wEPRegVal & USB_EP_CTR_TX) == 0U) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear int flag */
|
|
||||||
pcd_clear_tx_ep_ctr(USB, ep_id);
|
|
||||||
|
|
||||||
|
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_addr);
|
||||||
|
|
||||||
if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) {
|
if (ep_is_iso(ep_reg)) {
|
||||||
// Ignore spurious interrupts that we don't schedule
|
// Ignore spurious interrupts that we don't schedule
|
||||||
// host can send IN token while there is no data to send, since ISO does not have NAK
|
// host can send IN token while there is no data to send, since ISO does not have NAK
|
||||||
// this will result to zero length packet --> trigger interrupt (which cannot be masked)
|
// this will result to zero length packet --> trigger interrupt (which cannot be masked)
|
||||||
@ -308,14 +302,19 @@ static void dcd_ep_ctr_tx_handler(uint32_t ep_id) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xfer->iso_in_sending = false;
|
xfer->iso_in_sending = false;
|
||||||
uint8_t buf_id = (wEPRegVal & USB_EP_DTOG_TX) ? 0 : 1;
|
uint8_t buf_id = (ep_reg & USB_EP_DTOG_TX) ? 0 : 1;
|
||||||
btable_set_count(ep_id, buf_id, 0);
|
btable_set_count(ep_id, buf_id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((xfer->total_len != xfer->queued_len)) {
|
if (xfer->total_len != xfer->queued_len) {
|
||||||
dcd_transmit_packet(xfer, ep_id);
|
dcd_transmit_packet(xfer, ep_id); // also clear CTR bit
|
||||||
} else {
|
} else {
|
||||||
dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true);
|
dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true);
|
||||||
|
|
||||||
|
// Clear CTR TX and reserved CTR RX
|
||||||
|
ep_reg = (ep_reg & ~USB_EP_CTR_TX) | USB_EP_CTR_RX;
|
||||||
|
|
||||||
|
pcd_set_endpoint(USB, ep_id, ep_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,15 +342,13 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t ep_reg = pcd_get_endpoint(USB, ep_id);
|
uint32_t ep_reg = pcd_get_endpoint(USB, ep_id);
|
||||||
uint8_t ep_addr = ep_reg & USB_EPADDR_FIELD;
|
|
||||||
|
|
||||||
// Verify the CTR_RX bit is set. This was in the ST Micro code,
|
// Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary?
|
||||||
// but I'm not sure it's actually necessary?
|
TU_VERIFY(ep_reg & USB_EP_CTR_RX, );
|
||||||
if ((ep_reg & USB_EP_CTR_RX) == 0U) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear RX CTR and reserved TX CTR
|
uint8_t const ep_addr = ep_reg & USB_EPADDR_FIELD;
|
||||||
|
|
||||||
|
// Clear CTR RX and reserved CTR TX
|
||||||
ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_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) {
|
||||||
@ -688,8 +685,6 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
|
|||||||
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_ptr(ep_addr)->ep_idx = ep_idx;
|
||||||
|
|
||||||
pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,13 +710,9 @@ 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)
|
// Currently, single-buffered, and only 64 bytes at a time (max)
|
||||||
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) {
|
||||||
uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len);
|
uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
|
||||||
if (len > xfer->max_packet_size) {
|
uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix) | EP_CTR_TXRX;
|
||||||
len = xfer->max_packet_size;
|
bool const is_iso = ep_is_iso(ep_reg);
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix);
|
|
||||||
bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS;
|
|
||||||
|
|
||||||
uint8_t buf_id;
|
uint8_t buf_id;
|
||||||
if (is_iso) {
|
if (is_iso) {
|
||||||
@ -739,8 +730,12 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
|
|||||||
}
|
}
|
||||||
xfer->queued_len = (uint16_t)(xfer->queued_len + len);
|
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);
|
||||||
|
|
||||||
dcd_int_disable(0);
|
dcd_int_disable(0);
|
||||||
pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID);
|
pcd_set_endpoint(USB, ep_ix, ep_reg);
|
||||||
if (is_iso) {
|
if (is_iso) {
|
||||||
xfer->iso_in_sending = true;
|
xfer->iso_in_sending = true;
|
||||||
}
|
}
|
||||||
@ -758,7 +753,9 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) {
|
|||||||
dcd_transmit_packet(xfer, ep_idx);
|
dcd_transmit_packet(xfer, ep_idx);
|
||||||
} else {
|
} else {
|
||||||
uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size);
|
uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size);
|
||||||
uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx);
|
uint16_t ep_reg = pcd_get_endpoint(USB, 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);
|
||||||
|
|
||||||
if (ep_is_iso(ep_reg)) {
|
if (ep_is_iso(ep_reg)) {
|
||||||
btable_set_rx_bufsize(ep_idx, 0, cnt);
|
btable_set_rx_bufsize(ep_idx, 0, cnt);
|
||||||
@ -767,7 +764,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) {
|
|||||||
btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt);
|
btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID);
|
pcd_set_endpoint(USB, ep_idx, ep_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -141,17 +141,20 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct");
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USB_EPTX_STAT_Pos
|
#ifndef USB_EPTX_STAT_Pos
|
||||||
#define USB_EPTX_STAT_Pos (4U)
|
#define USB_EPTX_STAT_Pos 4u
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USB_EP_DTOG_TX_Pos
|
#ifndef USB_EP_DTOG_TX_Pos
|
||||||
#define USB_EP_DTOG_TX_Pos (6U)
|
#define USB_EP_DTOG_TX_Pos 6u
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USB_EP_DTOG_RX_Pos
|
#ifndef USB_EP_CTR_TX_Pos
|
||||||
#define USB_EP_DTOG_RX_Pos (14U)
|
#define USB_EP_CTR_TX_Pos 7u
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EP_STAT_DISABLED = 0,
|
EP_STAT_DISABLED = 0,
|
||||||
EP_STAT_STALL = 1,
|
EP_STAT_STALL = 1,
|
||||||
@ -244,34 +247,23 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u
|
|||||||
// Endpoint
|
// Endpoint
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) {
|
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t ep_id, uint32_t value) {
|
||||||
(void) USBx;
|
(void) USBx;
|
||||||
FSDEV_REG->ep[bEpIdx].reg = (fsdev_bus_t) wRegValue;
|
FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear)
|
||||||
(void) USBx;
|
//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) {
|
||||||
return FSDEV_REG->ep[bEpIdx].reg;
|
// value |= USB_EP_CTR_RX | USB_EP_CTR_TX;
|
||||||
}
|
// if (clear_ctr_mask) {
|
||||||
|
// value &= ~clear_ctr_mask;
|
||||||
//TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) {
|
// }
|
||||||
// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value;
|
// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) {
|
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t ep_id) {
|
||||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
(void) USBx;
|
||||||
regVal &= (uint32_t)USB_EP_T_MASK;
|
return FSDEV_REG->ep[ep_id].reg;
|
||||||
regVal |= wType;
|
|
||||||
regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high
|
|
||||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
|
||||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
|
||||||
regVal &= USB_EPREG_MASK;
|
|
||||||
regVal &= ~USB_EP_CTR_TX;
|
|
||||||
regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0)
|
|
||||||
pcd_set_endpoint(USBx, bEpIdx,regVal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) {
|
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) {
|
||||||
@ -282,41 +274,14 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_
|
|||||||
return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
|
return 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 bool ep_is_iso(uint32_t reg) {
|
TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) {
|
||||||
return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS;
|
return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief sets the status for tx transfer (bits STAT_TX[1:0]).
|
|
||||||
* @param USBx USB peripheral instance register address.
|
|
||||||
* @param bEpIdx Endpoint Number.
|
|
||||||
* @param wState new state
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) {
|
|
||||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
|
||||||
regVal &= USB_EPTX_DTOGMASK;
|
|
||||||
regVal ^= wState;
|
|
||||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
|
||||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief sets the status for rx transfer (bits STAT_TX[1:0])
|
|
||||||
* @param USBx USB peripheral instance register address.
|
|
||||||
* @param bEpIdx Endpoint Number.
|
|
||||||
* @param wState new state
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) {
|
|
||||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
|
||||||
regVal &= USB_EPRX_DTOGMASK;
|
|
||||||
regVal ^= wState;
|
|
||||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
|
||||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user