mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-19 06:40:45 +00:00
refactor btable_set_rx_bufsize()
This commit is contained in:
parent
6771ef35d9
commit
749f092174
@ -370,7 +370,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
|
||||
|
||||
if (wEPRegVal & USB_EP_SETUP) {
|
||||
/* Setup packet */
|
||||
uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex);
|
||||
uint32_t count = btable_get_count(EPindex, BTABLE_BUF_RX);
|
||||
// Setup packet should always be 8 bytes. If not, ignore it, and try again.
|
||||
if (count == 8) {
|
||||
// Must reset EP to NAK (in case it had been stalling)
|
||||
@ -387,13 +387,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
|
||||
pcd_rx_dtog(USB, 0);
|
||||
}
|
||||
|
||||
uint16_t rx_addr = btable_get_addr(EPindex, BTABLE_BUF_RX);
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true);
|
||||
dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + rx_addr), true);
|
||||
#else
|
||||
// The setup_received function uses memcpy, so this must first copy the setup data into
|
||||
// user memory, to allow for the 32-bit access that memcpy performs.
|
||||
uint8_t userMemBuf[8];
|
||||
dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8);
|
||||
dcd_read_packet_memory(userMemBuf, rx_addr, 8);
|
||||
dcd_event_setup_received(0, (uint8_t*) userMemBuf, true);
|
||||
#endif
|
||||
}
|
||||
@ -434,7 +435,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
|
||||
if ((wEPRegVal & USB_EP_TYPE_MASK) != USB_EP_ISOCHRONOUS) {
|
||||
uint16_t remaining = xfer->total_len - xfer->queued_len;
|
||||
uint16_t cnt = tu_min16(remaining, xfer->max_packet_size);
|
||||
pcd_set_ep_rx_cnt(USB, EPindex, cnt);
|
||||
btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, cnt);
|
||||
}
|
||||
pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID);
|
||||
}
|
||||
@ -445,7 +446,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
|
||||
// (Based on the docs, it seems SETUP will always be accepted after CTR is cleared)
|
||||
if (ep_addr == 0u) {
|
||||
// Always be prepared for a status packet...
|
||||
pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE);
|
||||
btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE);
|
||||
pcd_clear_rx_ep_ctr(USB, EPindex);
|
||||
}
|
||||
}
|
||||
@ -651,11 +652,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
|
||||
uint16_t pma_addr = dcd_pma_alloc(buffer_size, false);
|
||||
|
||||
if (dir == TUSB_DIR_IN) {
|
||||
pcd_set_ep_tx_address(USB, ep_idx, pma_addr);
|
||||
btable_set_addr(ep_idx, BTABLE_BUF_TX, pma_addr);
|
||||
pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK);
|
||||
pcd_clear_tx_dtog(USB, ep_idx);
|
||||
} else {
|
||||
pcd_set_ep_rx_address(USB, ep_idx, pma_addr);
|
||||
btable_set_addr(ep_idx, BTABLE_BUF_RX, pma_addr);
|
||||
pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK);
|
||||
pcd_clear_rx_dtog(USB, ep_idx);
|
||||
}
|
||||
@ -771,7 +772,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
|
||||
if (is_iso) {
|
||||
buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0;
|
||||
} else {
|
||||
buf_id = 0;
|
||||
buf_id = BTABLE_BUF_TX;
|
||||
}
|
||||
uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id);
|
||||
btable_set_count(ep_ix, buf_id, len);
|
||||
@ -806,10 +807,10 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr)
|
||||
uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx);
|
||||
|
||||
if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) {
|
||||
pcd_set_ep_rx_dbuf0_cnt(USB, ep_idx, cnt);
|
||||
pcd_set_ep_rx_dbuf1_cnt(USB, ep_idx, cnt);
|
||||
btable_set_rx_bufsize(ep_idx, 0, cnt);
|
||||
btable_set_rx_bufsize(ep_idx, 1, cnt);
|
||||
} else {
|
||||
pcd_set_ep_rx_cnt(USB, ep_idx, cnt);
|
||||
btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt);
|
||||
}
|
||||
|
||||
pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID);
|
||||
|
@ -62,6 +62,11 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b
|
||||
#define pma_aligned
|
||||
#endif
|
||||
|
||||
enum {
|
||||
BTABLE_BUF_TX = 0,
|
||||
BTABLE_BUF_RX = 1
|
||||
};
|
||||
|
||||
// hardware limit endpoint
|
||||
#define FSDEV_EP_COUNT 8
|
||||
|
||||
@ -105,20 +110,6 @@ static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR;
|
||||
typedef uint16_t fsdev_bus_t;
|
||||
// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden)
|
||||
static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR;
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) {
|
||||
size_t total_word_offset = (((USBx)->BTABLE)>>1) + x;
|
||||
total_word_offset *= FSDEV_PMA_STRIDE;
|
||||
return &(pma[total_word_offset]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Aligned buffer size according to hardware */
|
||||
@ -205,100 +196,47 @@ 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 btable_get_count(uint32_t ep_id, uint8_t is_rx) {
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) {
|
||||
uint16_t count;
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
count = (FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr >> 16);
|
||||
count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16);
|
||||
#else
|
||||
count = FSDEV_BTABLE->ep16[ep_id][is_rx].count;
|
||||
count = FSDEV_BTABLE->ep16[ep_id][buf_id].count;
|
||||
#endif
|
||||
return count & 0x3FFU;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t is_rx) {
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
return FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr & 0x0000FFFFu;
|
||||
return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu;
|
||||
#else
|
||||
return FSDEV_BTABLE->ep16[ep_id][is_rx].addr;
|
||||
return FSDEV_BTABLE->ep16[ep_id][buf_id].addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief gets counter of the tx buffer.
|
||||
* @param USBx USB peripheral instance register address.
|
||||
* @param bEpIdx Endpoint Number.
|
||||
* @retval Counter value
|
||||
*/
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
(void) USBx;
|
||||
return btable_get_count(bEpIdx, 0);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
(void) USBx;
|
||||
return btable_get_count(bEpIdx, 1);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
(void) USBx;
|
||||
return btable_get_addr(bEpIdx, 0);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
(void) USBx;
|
||||
return btable_get_addr(bEpIdx, 1);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) {
|
||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr;
|
||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
|
||||
count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu);
|
||||
FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr;
|
||||
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
|
||||
#else
|
||||
FSDEV_BTABLE->ep16[ep_id][is_rx].addr = addr;
|
||||
FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t byte_count) {
|
||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr;
|
||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
|
||||
count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16);
|
||||
FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr;
|
||||
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
|
||||
#else
|
||||
uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][is_rx].count;
|
||||
uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count;
|
||||
cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU);
|
||||
FSDEV_BTABLE->ep16[ep_id][is_rx].count = cnt;
|
||||
FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) {
|
||||
(void) USBx;
|
||||
btable_set_addr(bEpIdx, 0, addr);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) {
|
||||
(void) USBx;
|
||||
btable_set_addr(bEpIdx, 1, addr);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) {
|
||||
(void) USBx;
|
||||
btable_set_count(bEpIdx, 0, wCount);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx,
|
||||
uint32_t blocksize, uint32_t numblocks) {
|
||||
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26);
|
||||
#else
|
||||
volatile uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u);
|
||||
*pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) {
|
||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) {
|
||||
wCount = pcd_aligned_buffer_size(wCount);
|
||||
|
||||
/* We assume that the buffer size is already aligned to hardware requirements. */
|
||||
@ -309,19 +247,17 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx,
|
||||
TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/);
|
||||
|
||||
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
||||
pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks);
|
||||
}
|
||||
uint16_t bl_nb = (blocksize << 15) | ((numblocks - blocksize) << 10);
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) {
|
||||
pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount);
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
|
||||
count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu);
|
||||
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
|
||||
#else
|
||||
FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) {
|
||||
pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount);
|
||||
}
|
||||
|
||||
#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt
|
||||
|
||||
/**
|
||||
* @brief sets the status for tx transfer (bits STAT_TX[1:0]).
|
||||
* @param USBx USB peripheral instance register address.
|
||||
|
Loading…
x
Reference in New Issue
Block a user