Skip to content

Commit d905df5

Browse files
Merge pull request #2 from joetde/dev/stm32f_rx_large_buffer
Support multi-packet rx isochronous transfers
2 parents 2bd325a + 6e38d1d commit d905df5

File tree

1 file changed

+50
-5
lines changed

1 file changed

+50
-5
lines changed

Drivers/STM32F_FS/usbd_drv_stm32f_fs.c

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,7 @@ typedef struct usbd_drv_data_ep { /* ---------- DE
506506
CPU_INT16U EP_PktXferLen[STM32F_FS_NBR_CHANNEL]; /* EPs current xfer len. */
507507
CPU_INT08U *EP_AppBufPtr[STM32F_FS_NBR_CHANNEL]; /* Ptr to app buffer. */
508508
CPU_INT16U EP_AppBufLen[STM32F_FS_NBR_CHANNEL]; /* Len of app buffer. */
509+
CPU_INT16U EP_AppBufBlk[STM32F_FS_NBR_CHANNEL]; /* Number of packets remaining to read. */
509510
CPU_INT32U EP_SetupBuf[2u]; /* Buffer that contains setup pkt. */
510511
CPU_INT16U DrvType; /* STM32F_FS/ STM32F_OTG_FS/ EFM32_OTG_FS/ XMC_OTG_FS */
511512
} USBD_DRV_DATA_EP;
@@ -1416,7 +1417,9 @@ static void USBD_DrvEP_Close (USBD_DRV *p_drv,
14161417
*
14171418
* Return(s) : Number of bytes that can be handled in one transfer.
14181419
*
1419-
* Note(s) : none.
1420+
* Note(s) : (1) Isochronous endpoints will allow larger buffers than the packet size in
1421+
* order to deliver better performance. In the case of larger buffers, those
1422+
* will be filled by multiple FIFO calls without notifying the application until full.
14201423
*********************************************************************************************************
14211424
*/
14221425

@@ -1465,9 +1468,13 @@ static CPU_INT32U USBD_DrvEP_RxStart (USBD_DRV *p_drv,
14651468

14661469
p_drv_data->EP_AppBufPtr[ep_phy_nbr] = p_buf;
14671470
p_drv_data->EP_AppBufLen[ep_phy_nbr] = ep_pkt_len;
1471+
p_drv_data->EP_AppBufBlk[ep_phy_nbr] = 0;
14681472

14691473
ep_type = USBD_GET_EP_TYPE(ctl_reg);
14701474
if (ep_type == USBD_EP_TYPE_ISOC) { /* Check if EP is type is Isochronous */
1475+
p_drv_data->EP_AppBufLen[ep_phy_nbr] = buf_len; /* Isochronous endpoints allow larger buffers, see (1) */
1476+
p_drv_data->EP_AppBufBlk[ep_phy_nbr] = (buf_len + (p_drv_data->EP_MaxPktSize[ep_phy_nbr] - 1u))
1477+
/ p_drv_data->EP_MaxPktSize[ep_phy_nbr];
14711478
if ((p_reg->DSTS & (1U << 8)) == 0U) {
14721479
ctl_reg |= STM32F_FS_DxEPCTLx_BIT_SODDFRM;
14731480

@@ -1485,7 +1492,7 @@ static CPU_INT32U USBD_DrvEP_RxStart (USBD_DRV *p_drv,
14851492

14861493
*p_err = USBD_ERR_NONE;
14871494

1488-
return (ep_pkt_len);
1495+
return (p_drv_data->EP_AppBufLen[ep_phy_nbr]);
14891496
}
14901497

14911498

@@ -2072,6 +2079,7 @@ static void STM32_RxFIFO_Rd (USBD_DRV *p_drv)
20722079
{
20732080
CPU_INT08U ep_log_nbr;
20742081
CPU_INT08U ep_phy_nbr;
2082+
CPU_INT08U ep_type;
20752083
CPU_INT08U pkt_stat;
20762084
CPU_INT08U byte_rem;
20772085
CPU_INT08U word_cnt;
@@ -2082,6 +2090,7 @@ static void STM32_RxFIFO_Rd (USBD_DRV *p_drv)
20822090
CPU_INT32U data;
20832091
USBD_DRV_DATA_EP *p_drv_data;
20842092
USBD_STM32F_FS_REG *p_reg;
2093+
CPU_INT32U ctl_reg;
20852094

20862095

20872096
p_reg = (USBD_STM32F_FS_REG *)p_drv->CfgPtr->BaseAddr;
@@ -2150,7 +2159,35 @@ static void STM32_RxFIFO_Rd (USBD_DRV *p_drv)
21502159
}
21512160
}
21522161

2153-
p_drv_data->EP_AppBufPtr[ep_phy_nbr] = (CPU_INT08U *)0;
2162+
if (p_drv_data->EP_AppBufBlk[ep_phy_nbr]) { /* Multi-packet transfer. */
2163+
p_drv_data->EP_AppBufBlk[ep_phy_nbr]--;
2164+
p_drv_data->EP_AppBufPtr[ep_phy_nbr] += byte_cnt;
2165+
/* If more packets are expected, continue listening. */
2166+
if (p_drv_data->EP_AppBufBlk[ep_phy_nbr] != 0) {
2167+
ctl_reg = p_reg->DOEP[ep_log_nbr].CTLx;
2168+
2169+
ep_type = USBD_GET_EP_TYPE(ctl_reg);
2170+
if (ep_type == USBD_EP_TYPE_ISOC) {
2171+
if ((p_reg->DSTS & (1U << 8)) == 0U) {
2172+
ctl_reg |= STM32F_FS_DxEPCTLx_BIT_SODDFRM;
2173+
2174+
} else {
2175+
ctl_reg |= STM32F_FS_DxEPCTLx_BIT_SEVNFRM;
2176+
}
2177+
}
2178+
2179+
/* Clear EP NAK and enable EP for receiving */
2180+
ctl_reg |= STM32F_FS_DxEPCTLx_BIT_CNAK | STM32F_FS_DxEPCTLx_BIT_EPENA;
2181+
2182+
p_reg->DOEP[ep_log_nbr].CTLx = ctl_reg;
2183+
2184+
/* Clear output interrupt since more data is expected */
2185+
DEF_BIT_CLR(p_reg->GINTMSK, STM32F_FS_GINTMSK_BIT_OEPINT);
2186+
}
2187+
}
2188+
if (p_drv_data->EP_AppBufBlk[ep_phy_nbr] == 0) {
2189+
p_drv_data->EP_AppBufPtr[ep_phy_nbr] = (CPU_INT08U *)0;
2190+
}
21542191
} else { /* See Note (1). */
21552192
word_cnt = (byte_cnt + 3u) / 4u;
21562193
for (i = 0u; i < word_cnt; i++) {
@@ -2252,8 +2289,10 @@ static void STM32_EP_OutProcess (USBD_DRV *p_drv)
22522289
CPU_INT32U ep_int_stat;
22532290
CPU_INT32U dev_ep_int;
22542291
CPU_INT32U ep_log_nbr;
2292+
CPU_INT08U ep_phy_nbr;
22552293
USBD_DRV_DATA_EP *p_drv_data;
22562294
USBD_STM32F_FS_REG *p_reg;
2295+
CPU_BOOLEAN ep_rx_cmpl;
22572296

22582297

22592298
p_reg = (USBD_STM32F_FS_REG *)p_drv->CfgPtr->BaseAddr;
@@ -2262,11 +2301,15 @@ static void STM32_EP_OutProcess (USBD_DRV *p_drv)
22622301

22632302
while (dev_ep_int != DEF_BIT_NONE) {
22642303
ep_log_nbr = (CPU_INT08U)(31u - CPU_CntLeadZeros32(dev_ep_int & 0x0000FFFFu));
2304+
ep_phy_nbr = USBD_EP_ADDR_TO_PHY(USBD_EP_LOG_TO_ADDR_OUT(ep_log_nbr));
22652305
ep_int_stat = p_reg->DOEP[ep_log_nbr].INTx; /* Read OUT EP interrupt status */
2306+
ep_rx_cmpl = p_drv_data->EP_AppBufBlk[ep_phy_nbr] == 0 ? DEF_TRUE : DEF_FALSE;
22662307

22672308
/* Check if EP transfer completed occurred */
22682309
if (DEF_BIT_IS_SET(ep_int_stat, STM32F_FS_DOEPINTx_BIT_XFRC)) {
2269-
USBD_EP_RxCmpl(p_drv, ep_log_nbr);
2310+
if (ep_rx_cmpl) { /* Check if EP has more data to receive */
2311+
USBD_EP_RxCmpl(p_drv, ep_log_nbr);
2312+
}
22702313
/* Clear EP transfer complete interrupt */
22712314
DEF_BIT_SET(p_reg->DOEP[ep_log_nbr].INTx, STM32F_FS_DOEPINTx_BIT_XFRC);
22722315
}
@@ -2280,7 +2323,9 @@ static void STM32_EP_OutProcess (USBD_DRV *p_drv)
22802323
DEF_BIT_SET(p_reg->DOEP[0u].CTLx, STM32F_FS_DxEPCTLx_BIT_EPENA);
22812324
}
22822325

2283-
DEF_BIT_SET(p_reg->DOEP[ep_log_nbr].CTLx, STM32F_FS_DxEPCTLx_BIT_SNAK);
2326+
if (ep_rx_cmpl) { /* Only set EP in NAK mode if no more data is expected */
2327+
DEF_BIT_SET(p_reg->DOEP[ep_log_nbr].CTLx, STM32F_FS_DxEPCTLx_BIT_SNAK);
2328+
}
22842329

22852330
dev_ep_int = p_reg->DAINT >> 16u; /* Read all Device OUT Endpoint interrupt */
22862331
}

0 commit comments

Comments
 (0)