mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-17 05:32:55 +08:00
improve set endpoint
This commit is contained in:
parent
b15814b2f9
commit
1cf8e34ae5
@ -616,24 +616,24 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
|
||||
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
|
||||
(void)rhport;
|
||||
uint8_t const ep_addr = desc_ep->bEndpointAddress;
|
||||
uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer);
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
const uint16_t packet_size = tu_edpt_packet_size(desc_ep);
|
||||
uint32_t wType;
|
||||
|
||||
uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer);
|
||||
TU_ASSERT(ep_idx < FSDEV_EP_COUNT);
|
||||
|
||||
uint32_t ep_reg = FSDEV_REG->ep[ep_idx].reg & ~USB_EPREG_MASK;
|
||||
ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_RX | USB_EP_CTR_TX;
|
||||
|
||||
// Set type
|
||||
switch (desc_ep->bmAttributes.xfer) {
|
||||
case TUSB_XFER_CONTROL:
|
||||
wType = USB_EP_CONTROL;
|
||||
ep_reg |= USB_EP_CONTROL;
|
||||
break;
|
||||
case TUSB_XFER_BULK:
|
||||
wType = USB_EP_CONTROL;
|
||||
ep_reg |= USB_EP_CONTROL; // FIXME should it be bulk?
|
||||
break;
|
||||
|
||||
case TUSB_XFER_INTERRUPT:
|
||||
wType = USB_EP_INTERRUPT;
|
||||
ep_reg |= USB_EP_INTERRUPT;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -641,25 +641,24 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
|
||||
TU_ASSERT(false);
|
||||
}
|
||||
|
||||
pcd_set_eptype(USB, ep_idx, wType);
|
||||
pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr));
|
||||
|
||||
/* Create a packet memory buffer area. */
|
||||
uint16_t pma_addr = dcd_pma_alloc(packet_size, false);
|
||||
|
||||
if (dir == TUSB_DIR_IN) {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
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_ptr(ep_addr)->ep_idx = ep_idx;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -731,7 +730,8 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin
|
||||
uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress;
|
||||
uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx;
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc);
|
||||
|
||||
xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(p_endpoint_desc);
|
||||
|
||||
pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS);
|
||||
pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS);
|
||||
@ -747,7 +747,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin
|
||||
pcd_tx_dtog(USB, ep_idx);
|
||||
}
|
||||
|
||||
xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -55,28 +55,29 @@
|
||||
|
||||
#define FSDEV_PMA_SIZE (512u)
|
||||
|
||||
#if 1
|
||||
// volatile 32-bit aligned
|
||||
#define _va32 volatile TU_ATTR_ALIGNED(4)
|
||||
#define _vaa32 volatile TU_ATTR_ALIGNED(4)
|
||||
|
||||
typedef struct {
|
||||
_va32 uint16_t EP0R; // 00: USB Endpoint 0 register
|
||||
_va32 uint16_t EP1R; // 04: USB Endpoint 1 register
|
||||
_va32 uint16_t EP2R; // 08: USB Endpoint 2 register
|
||||
_va32 uint16_t EP3R; // 0C: USB Endpoint 3 register
|
||||
_va32 uint16_t EP4R; // 10: USB Endpoint 4 register
|
||||
_va32 uint16_t EP5R; // 14: USB Endpoint 5 register
|
||||
_va32 uint16_t EP6R; // 18: USB Endpoint 6 register
|
||||
_va32 uint16_t EP7R; // 1C: USB Endpoint 7 register
|
||||
_va32 uint16_t RESERVED7[16]; // Reserved
|
||||
_va32 uint16_t CNTR; // 40: Control register
|
||||
_va32 uint16_t ISTR; // 44: Interrupt status register
|
||||
_va32 uint16_t FNR; // 48: Frame number register
|
||||
_va32 uint16_t DADDR; // 4C: Device address register
|
||||
_va32 uint16_t BTABLE; // 50: Buffer Table address register
|
||||
_vaa32 uint16_t EP0R; // 00: USB Endpoint 0 register
|
||||
_vaa32 uint16_t EP1R; // 04: USB Endpoint 1 register
|
||||
_vaa32 uint16_t EP2R; // 08: USB Endpoint 2 register
|
||||
_vaa32 uint16_t EP3R; // 0C: USB Endpoint 3 register
|
||||
_vaa32 uint16_t EP4R; // 10: USB Endpoint 4 register
|
||||
_vaa32 uint16_t EP5R; // 14: USB Endpoint 5 register
|
||||
_vaa32 uint16_t EP6R; // 18: USB Endpoint 6 register
|
||||
_vaa32 uint16_t EP7R; // 1C: USB Endpoint 7 register
|
||||
_vaa32 uint16_t RESERVED7[16]; // Reserved
|
||||
_vaa32 uint16_t CNTR; // 40: Control register
|
||||
_vaa32 uint16_t ISTR; // 44: Interrupt status register
|
||||
_vaa32 uint16_t FNR; // 48: Frame number register
|
||||
_vaa32 uint16_t DADDR; // 4C: Device address register
|
||||
_vaa32 uint16_t BTABLE; // 50: Buffer Table address register
|
||||
} USB_TypeDef;
|
||||
#endif
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(USB_TypeDef) == 0x54, "Size is not correct");
|
||||
TU_VERIFY_STATIC(offsetof(USB_TypeDef, CNTR) == 0x40, "Wrong offset");
|
||||
#define FSDEV_REG_BASE 0x40005C00UL
|
||||
|
||||
#define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */
|
||||
#define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */
|
||||
|
@ -95,9 +95,8 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE
|
||||
|
||||
#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE))
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BTable
|
||||
//--------------------------------------------------------------------+
|
||||
// volatile 32-bit aligned
|
||||
#define _va32 volatile TU_ATTR_ALIGNED(4)
|
||||
|
||||
// The fsdev_bus_t type can be used for both register and PMA access necessities
|
||||
// For type-safety create a new macro for the volatile address of PMAADDR
|
||||
@ -112,6 +111,39 @@ typedef uint16_t fsdev_bus_t;
|
||||
static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
// _va32 fsdev_bus_t EP0R; // 00: USB Endpoint 0 register
|
||||
// _va32 fsdev_bus_t EP1R; // 04: USB Endpoint 1 register
|
||||
// _va32 fsdev_bus_t EP2R; // 08: USB Endpoint 2 register
|
||||
// _va32 fsdev_bus_t EP3R; // 0C: USB Endpoint 3 register
|
||||
// _va32 fsdev_bus_t EP4R; // 10: USB Endpoint 4 register
|
||||
// _va32 fsdev_bus_t EP5R; // 14: USB Endpoint 5 register
|
||||
// _va32 fsdev_bus_t EP6R; // 18: USB Endpoint 6 register
|
||||
// _va32 fsdev_bus_t EP7R; // 1C: USB Endpoint 7 register
|
||||
struct {
|
||||
_va32 fsdev_bus_t reg;
|
||||
}ep[FSDEV_EP_COUNT];
|
||||
|
||||
_va32 uint32_t RESERVED7[8]; // Reserved
|
||||
_va32 fsdev_bus_t CNTR; // 40: Control register
|
||||
_va32 fsdev_bus_t ISTR; // 44: Interrupt status register
|
||||
_va32 fsdev_bus_t FNR; // 48: Frame number register
|
||||
_va32 fsdev_bus_t DADDR; // 4C: Device address register
|
||||
_va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only)
|
||||
_va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only)
|
||||
_va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only)
|
||||
} fsdev_regs_t;
|
||||
|
||||
TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset");
|
||||
TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct");
|
||||
|
||||
#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE)
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BTable
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
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][buf_id].count_addr & 0x0000FFFFu;
|
||||
@ -191,24 +223,13 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
volatile uint32_t *reg = (volatile uint32_t *)(USB_DRD_BASE + bEpIdx*4);
|
||||
*reg = wRegValue;
|
||||
#else
|
||||
volatile uint16_t *reg = (volatile uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
|
||||
*reg = (uint16_t)wRegValue;
|
||||
#endif
|
||||
FSDEV_REG->ep[bEpIdx].reg = (fsdev_bus_t) wRegValue;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
volatile const uint32_t *reg = (volatile const uint32_t *)(USB_DRD_BASE + bEpIdx*4);
|
||||
#else
|
||||
volatile const uint16_t *reg = (volatile const uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
|
||||
#endif
|
||||
return *reg;
|
||||
return FSDEV_REG->ep[bEpIdx].reg;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -262,6 +283,21 @@ 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 | ((reg ^ state) & USB_EPTX_STAT);
|
||||
}
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint32_t state) {
|
||||
return reg | ((reg ^ state) & USB_EPRX_STAT);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) {
|
||||
return reg | ((reg ^ state) & USB_EP_DTOG_TX);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) {
|
||||
return reg | ((reg ^ state) & USB_EP_DTOG_RX);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the status for tx transfer (bits STAT_TX[1:0]).
|
||||
* @param USBx USB peripheral instance register address.
|
||||
@ -293,10 +329,10 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
return (regVal & USB_EPRX_STAT) >> (12u);
|
||||
}
|
||||
//TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
// return (regVal & USB_EPRX_STAT) >> (12u);
|
||||
//}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
@ -326,20 +362,20 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx,
|
||||
}
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal |= USB_EP_KIND;
|
||||
regVal &= USB_EPREG_MASK;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPKIND_MASK;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
//TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
// regVal |= USB_EP_KIND;
|
||||
// regVal &= USB_EPREG_MASK;
|
||||
// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
// pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
//}
|
||||
//
|
||||
//TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
// regVal &= USB_EPKIND_MASK;
|
||||
// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
// pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
//}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#if CFG_TUSB_MCU == OPT_MCU_STM32F0
|
||||
#include "stm32f0xx.h"
|
||||
#define FSDEV_PMA_SIZE (1024u)
|
||||
#define FSDEV_REG_BASE USB_BASE
|
||||
// F0x2 models are crystal-less
|
||||
// All have internal D+ pull-up
|
||||
// 070RB: 2 x 16 bits/word memory LPM Support, BCD Support
|
||||
@ -193,6 +194,22 @@
|
||||
// This includes U0
|
||||
#endif
|
||||
|
||||
#if defined(USB_BASE)
|
||||
#define FSDEV_REG_BASE USB_BASE
|
||||
#elif defined(USB_DRD_BASE)
|
||||
#define FSDEV_REG_BASE USB_DRD_BASE
|
||||
#else
|
||||
#error "FSDEV_REG_BASE not defined"
|
||||
#endif
|
||||
|
||||
#ifndef USB_EPTX_STAT
|
||||
#define USB_EPTX_STAT 0x0030U
|
||||
#endif
|
||||
|
||||
#ifndef USB_EPRX_STAT
|
||||
#define USB_EPRX_STAT 0x3000U
|
||||
#endif
|
||||
|
||||
// This checks if the device has "LPM"
|
||||
#if defined(USB_ISTR_L1REQ)
|
||||
#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ)
|
||||
|
Loading…
x
Reference in New Issue
Block a user