- USB driver: TX FIFO overpushing fixed
- USB driver: TX FIFO allocated address must be in WORDs (fixed)
This commit is contained in:
parent
8ef6249e01
commit
db4e59cfd9
@ -8,6 +8,8 @@
|
||||
|
||||
#include <blocking_io/blocking_fifo.h>
|
||||
|
||||
#include <cmsis_gcc.h>
|
||||
|
||||
// state
|
||||
static USB_CdcState cdcs = { 0 };
|
||||
static uint8_t tx_buffer[USB_CDC_PCKT_BUFSIZE];
|
||||
|
@ -62,7 +62,7 @@ typedef struct {
|
||||
|
||||
// ----------------
|
||||
|
||||
#define USB_CDC_PCKT_BUFSIZE (64)
|
||||
#define USB_CDC_PCKT_BUFSIZE (72)
|
||||
|
||||
// ----------------
|
||||
|
||||
|
26
usb_driver.c
26
usb_driver.c
@ -265,10 +265,10 @@ void usbdrv_build_fifo() {
|
||||
for (uint8_t i = 0; i < USB_NUM_OF_ENDPOINTS; i++) {
|
||||
USBDRV_EpConfig *cfg = &gs.ep_IN[i];
|
||||
if (cfg->is_configured) {
|
||||
cfg->fifo_size = CEIL4(MAX(USB_MIN_GROSS_TX_FIFO_SIZE, cfg->max_packet_size)); // correct FIFO size if necessary
|
||||
cfg->fifo_address = next_fifo_addr; // store FIFO address
|
||||
cfg->zlp_next = false; // clear ZLP next
|
||||
next_fifo_addr += cfg->fifo_size; // advance next address
|
||||
cfg->fifo_size = CEIL4(MAX(USB_MIN_GROSS_TX_FIFO_SIZE, 2 * cfg->max_packet_size + USB_FIFO_MARGIN)); // correct FIFO size if necessary
|
||||
cfg->fifo_address = next_fifo_addr; // store FIFO address
|
||||
cfg->zlp_next = false; // clear ZLP next
|
||||
next_fifo_addr += cfg->fifo_size; // advance next address
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,8 +346,8 @@ void usbdrv_configure_endpoint(uint8_t ep, uint8_t dir, const USBDRV_EpConfig *c
|
||||
WRITE_FIELD(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_TXFNUM, ep);
|
||||
|
||||
// store Tx FIFO size
|
||||
uint32_t tx_fifo_config = ((cfg->fifo_size >> 2) << USB_OTG_DIEPTXF_INEPTXFD_Pos) | cfg->fifo_address; // combine size in DWORDs and address
|
||||
*(USB_pDIEPTXF[ep]) = tx_fifo_config; // save
|
||||
uint32_t tx_fifo_config = ((cfg->fifo_size >> 2) << USB_OTG_DIEPTXF_INEPTXFD_Pos) | (cfg->fifo_address >> 2); // combine size in DWORDs and address
|
||||
*(USB_pDIEPTXF[ep]) = tx_fifo_config; // save
|
||||
|
||||
// enable interrupt
|
||||
SET_BIT(USBD->DAINTMSK, 1 << ep);
|
||||
@ -477,9 +477,9 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
|
||||
|
||||
// determine final write size
|
||||
uint32_t freeSize = 0;
|
||||
if (len > 0) { // only poll DTXFSTS if (len > 0) (see datasheet)
|
||||
freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
|
||||
}
|
||||
// if (len > 0) { // only poll DTXFSTS if (len > 0) (see datasheet)
|
||||
freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
|
||||
//}
|
||||
uint16_t writeSize = MIN(freeSize, len); // limit transmit size to free size
|
||||
|
||||
// calculate packet count based on max packet size
|
||||
@ -493,7 +493,7 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
|
||||
gs.ep_IN[ep].zlp_next = (writeSize > 0) && ((writeSize % mps) == 0);
|
||||
|
||||
// program DIEPTSIZ with transfer length
|
||||
USBINEP[ep].DIEPTSIZ = (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | writeSize;
|
||||
USBINEP[ep].DIEPTSIZ = (packet_count << USB_OTG_DIEPTSIZ_MULCNT_Pos) | (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | writeSize;
|
||||
|
||||
// enable endpoint and cancel responding NAK
|
||||
SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK);
|
||||
@ -511,11 +511,11 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
|
||||
}
|
||||
|
||||
// push the remaining partial dword
|
||||
uint8_t rem_bytes = len & 0b11;
|
||||
uint8_t rem_bytes = writeSize & 0b11;
|
||||
if (rem_bytes > 0) {
|
||||
uint32_t rem_dword = 0;
|
||||
uint16_t rem_start = len - rem_bytes;
|
||||
for (int16_t i = len - 1; i >= rem_start; i--) {
|
||||
uint16_t rem_start = writeSize - rem_bytes;
|
||||
for (int16_t i = writeSize - 1; i >= rem_start; i--) {
|
||||
rem_dword = (rem_dword << 8) | data[i];
|
||||
}
|
||||
*p = rem_dword;
|
||||
|
Loading…
x
Reference in New Issue
Block a user