You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/08/03 15:44:17 UTC
[incubator-nuttx] branch master updated: risc-v/mpfs: usb: configure fifos properly
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e0291b1ce8 risc-v/mpfs: usb: configure fifos properly
e0291b1ce8 is described below
commit e0291b1ce843e5abcf78364524b6ff7ac0e5f367
Author: Eero Nurkkala <ee...@offcode.fi>
AuthorDate: Wed Aug 3 16:12:49 2022 +0300
risc-v/mpfs: usb: configure fifos properly
RX_FIFO_ADDRs and TX_FIFO_ADDR were misconfigured. These addresses
overlapped causing data corruption during high USB loads. For
example, data corruption was present during the following conditions:
1. Composite USB driver was used (CDC/ACM + Mass storage)
2. /dev/ttyACM0 was accessed instantly from Linux side when
starting up.
3. Training data was sent to /dev/ttyACM0 from NuttX from the
very beginning periodically.
It was observed that while Mass storage was negotiating, sometimes
data sent from NuttX to Linux via CDC/ACM was corrupt, although it
was sent properly on the TX fifo.
Also, don't access TXCSRL_REG_EPN_TX_FIFO_NE_MASK for EP0 as it's
not applicable.
Signed-off-by: Eero Nurkkala <ee...@offcode.fi>
---
arch/risc-v/src/mpfs/mpfs_usb.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/arch/risc-v/src/mpfs/mpfs_usb.c b/arch/risc-v/src/mpfs/mpfs_usb.c
index 6590838ab3..471a1fbb99 100755
--- a/arch/risc-v/src/mpfs/mpfs_usb.c
+++ b/arch/risc-v/src/mpfs/mpfs_usb.c
@@ -590,12 +590,15 @@ static void mpfs_write_tx_fifo(const void *in_data, uint32_t length,
/* Poll mode: wait for fifo empty first */
- do
+ if (epno > EP0)
{
- tx_csr = getreg16(MPFS_USB_ENDPOINT(epno) +
- MPFS_USB_ENDPOINT_TX_CSR_OFFSET);
+ do
+ {
+ tx_csr = getreg16(MPFS_USB_ENDPOINT(epno) +
+ MPFS_USB_ENDPOINT_TX_CSR_OFFSET);
+ }
+ while (tx_csr & TXCSRL_REG_EPN_TX_FIFO_NE_MASK);
}
- while (tx_csr & TXCSRL_REG_EPN_TX_FIFO_NE_MASK);
/* Send 32-bit words first */
@@ -1156,8 +1159,6 @@ static void mpfs_ep_set_fifo_size(uint8_t epno, uint8_t in,
if (in)
{
- i |= (1 << 4); /* Double buffering */
-
mpfs_putreg8(i, MPFS_USB_TX_FIFO_SIZE);
}
else
@@ -1240,7 +1241,13 @@ static int mpfs_ep_configure_internal(struct mpfs_ep_s *privep,
mpfs_ep_set_fifo_size(epno, 0, maxpacket);
- mpfs_putreg16(desc->addr, MPFS_USB_TX_FIFO_ADDR);
+ /* Give EP0 64 bytes (8*8) and configure 512 bytes for TX fifo.
+ * This is a pointer to internal RAM where the data should be
+ * stored. It must not overlap with other EPs or it will cause
+ * corruption. One unit is 8 bytes, so 8 is 8*8 = 64 bytes.
+ */
+
+ mpfs_putreg16(8 + (64 * epno * 2), MPFS_USB_TX_FIFO_ADDR);
/* Disable double buffering */
@@ -1280,7 +1287,10 @@ static int mpfs_ep_configure_internal(struct mpfs_ep_s *privep,
RXCSRL_REG_EPN_RX_PKT_RDY_MASK);
mpfs_ep_set_fifo_size(epno, dirin, maxpacket);
- mpfs_putreg16(desc->addr, MPFS_USB_RX_FIFO_ADDR);
+
+ /* Give EP0 64 bytes (8*8) and configure 512 bytes for RX fifo */
+
+ mpfs_putreg16(8 + 64 + (64 * epno * 2), MPFS_USB_RX_FIFO_ADDR);
/* Disable double buffering for RX, will run into trouble with it.
* The host will send faster than we can handle and all packets