summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinhard Panhuber <[email protected]>2021-02-17 20:46:31 +0100
committerReinhard Panhuber <[email protected]>2021-02-17 20:46:31 +0100
commit2d7b61972c669040c494899509b02bde49728a65 (patch)
tree3ad53a7f152fb5f084c2a6f6d2317f66b79a85d8
parentc87357c0257251f2cecfe83a29035648c5a47662 (diff)
Implement dcd_edpt_iso_xfer() for dcd_stm32_fsdev
Implemented a special copy strategy to copy directly from the FIFO. This function, however, is untested and should be regarded as unreliable until somebody was able to test it
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c148
1 files changed, 144 insertions, 4 deletions
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
index 18f0bc8e1..9d813d4a5 100644
--- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
@@ -102,6 +102,7 @@
*/
#include "tusb_option.h"
+#include "common/tusb_fifo.h"
#if defined(STM32F102x6) || defined(STM32F102xB) || \
defined(STM32F103x6) || defined(STM32F103xB) || \
@@ -165,6 +166,7 @@ TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligne
typedef struct
{
uint8_t * buffer;
+ tu_fifo_t * ff;
uint16_t total_len;
uint16_t queued_len;
uint16_t pma_ptr;
@@ -195,7 +197,9 @@ static void dcd_pma_alloc_reset(void);
static uint16_t dcd_pma_alloc(uint8_t ep_addr, size_t length);
static void dcd_pma_free(uint8_t ep_addr);
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes);
+static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes);
static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes);
+static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes);
// Using a function due to better type checks
// This seems better than having to do type casts everywhere else
@@ -476,8 +480,16 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
if (count != 0U)
{
- dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]),
- *pcd_ep_rx_address_ptr(USB,EPindex), count);
+ if (xfer->ff)
+ {
+ dcd_read_packet_memory_ff(xfer->ff, *pcd_ep_rx_address_ptr(USB,EPindex), count);
+ }
+ else
+ {
+ dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]),
+ *pcd_ep_rx_address_ptr(USB,EPindex), count);
+ }
+
xfer->queued_len = (uint16_t)(xfer->queued_len + count);
}
@@ -804,7 +816,14 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix)
len = xfer->max_packet_size;
}
uint16_t oldAddr = *pcd_ep_tx_address_ptr(USB,ep_ix);
- dcd_write_packet_memory(oldAddr, &(xfer->buffer[xfer->queued_len]), len);
+ if (xfer->ff)
+ {
+ dcd_write_packet_memory_ff(xfer->ff, oldAddr, len);
+ }
+ else
+ {
+ dcd_write_packet_memory(oldAddr, &(xfer->buffer[xfer->queued_len]), len);
+ }
xfer->queued_len = (uint16_t)(xfer->queued_len + len);
pcd_set_ep_tx_cnt(USB,ep_ix,len);
@@ -821,6 +840,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
xfer_ctl_t * xfer = xfer_ctl_ptr(epnum,dir);
xfer->buffer = buffer;
+ xfer->ff = NULL;
xfer->total_len = total_bytes;
xfer->queued_len = 0;
@@ -847,6 +867,37 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
return true;
}
+bool dcd_edpt_iso_xfer (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+{
+ (void) rhport;
+
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ xfer_ctl_t * xfer = xfer_ctl_ptr(epnum,dir);
+
+ xfer->buffer = NULL;
+ xfer->ff = ff;
+ xfer->total_len = total_bytes;
+ xfer->queued_len = 0;
+
+ if ( dir == TUSB_DIR_OUT )
+ {
+ if(total_bytes > xfer->max_packet_size)
+ {
+ pcd_set_ep_rx_cnt(USB,epnum,xfer->max_packet_size);
+ } else {
+ pcd_set_ep_rx_cnt(USB,epnum,total_bytes);
+ }
+ pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID);
+ }
+ else // IN
+ {
+ dcd_transmit_packet(xfer,epnum);
+ }
+ return true;
+}
+
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
{
(void)rhport;
@@ -921,7 +972,52 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, si
}
/**
- * @brief Copy a buffer from user memory area to packet memory area (PMA).
+ * @brief Copy from FIFO to packet memory area (PMA).
+ * Uses byte-access of system memory and 16-bit access of packet memory
+ * @param wNBytes no. of bytes to be copied.
+ * @retval None
+ */
+
+// THIS FUNCTION IS UNTESTED
+
+static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes)
+{
+ // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
+ // Check for first linear part
+ void *__restrict src;
+ uint16_t len = tu_fifo_get_linear_read_info(ff, 0, &src, wNBytes); // We want to read from the FIFO
+ TU_VERIFY(len && dcd_write_packet_memory(dst, src, len)); // and write it into the PMA
+ tu_fifo_advance_read_pointer(ff, len);
+
+ // Check for wrapped part
+ if (len < wNBytes)
+ {
+ // Get remaining wrapped length
+ uint16_t len2 = tu_fifo_get_linear_read_info(ff, 0, &src, wNBytes - len);
+ TU_VERIFY(len2);
+
+ // Update destination pointer
+ dst += len;
+
+ // Since PMA is accessed 16-bit wise we need to handle the case when a 16 bit value was split
+ if (len % 2) // If len is uneven there is a byte left to copy
+ {
+ // Since PMA can accessed only 16 bit-wise we copy the last byte again
+ tu_fifo_backward_read_pointer(ff, 1); // Move one byte back and copy two bytes for the PMA
+ pma[PMA_STRIDE*(dst>>1)] = tu_fifo_read_n(ff, 2); // Since EP FIFOs must be of item size 1 this is safe to do
+ dst++;
+ len2--;
+ }
+
+ TU_VERIFY(dcd_write_packet_memory(dst, src, len2));
+ tu_fifo_advance_write_pointer(ff, len2);
+ }
+
+ return true;
+}
+
+/**
+ * @brief Copy a buffer from packet memory area (PMA) to user memory area.
* Uses byte-access of system memory and 16-bit access of packet memory
* @param wNBytes no. of bytes to be copied.
* @retval None
@@ -955,5 +1051,49 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN
return true;
}
+/**
+ * @brief Copy a buffer from user packet memory area (PMA) to FIFO.
+ * Uses byte-access of system memory and 16-bit access of packet memory
+ * @param wNBytes no. of bytes to be copied.
+ * @retval None
+ */
+
+// THIS FUNCTION IS UNTESTED
+
+static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes)
+{
+ // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
+ // Check for first linear part
+ void *__restrict dst;
+ uint16_t len = tu_fifo_get_linear_write_info(ff, 0, &dst, wNBytes);
+ TU_VERIFY(len && dcd_read_packet_memory(dst, src, len));
+ tu_fifo_advance_write_pointer(ff, len);
+
+ // Check for wrapped part
+ if (len < wNBytes)
+ {
+ // Get remaining wrapped length
+ uint16_t len2 = tu_fifo_get_linear_write_info(ff, 0, &dst, wNBytes - len);
+ TU_VERIFY(len2);
+
+ // Update source pointer
+ src += len;
+
+ // Since PMA is accessed 16-bit wise we need to handle the case when a 16 bit value was split
+ if (len % 2) // If len is uneven there is a byte left to copy
+ {
+ uint32_t temp = pma[PMA_STRIDE*(src>>1)];
+ *((uint8_t *)dst++) = ((temp >> 8) & 0xFF);
+ src++;
+ len2--;
+ }
+
+ TU_VERIFY(dcd_read_packet_memory(dst, src, len2));
+ tu_fifo_advance_write_pointer(ff, len2);
+ }
+
+ return true;
+}
+
#endif