- 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 <blocking_io/blocking_fifo.h>
|
||||||
|
|
||||||
|
#include <cmsis_gcc.h>
|
||||||
|
|
||||||
// state
|
// state
|
||||||
static USB_CdcState cdcs = { 0 };
|
static USB_CdcState cdcs = { 0 };
|
||||||
static uint8_t tx_buffer[USB_CDC_PCKT_BUFSIZE];
|
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++) {
|
for (uint8_t i = 0; i < USB_NUM_OF_ENDPOINTS; i++) {
|
||||||
USBDRV_EpConfig *cfg = &gs.ep_IN[i];
|
USBDRV_EpConfig *cfg = &gs.ep_IN[i];
|
||||||
if (cfg->is_configured) {
|
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_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->fifo_address = next_fifo_addr; // store FIFO address
|
||||||
cfg->zlp_next = false; // clear ZLP next
|
cfg->zlp_next = false; // clear ZLP next
|
||||||
next_fifo_addr += cfg->fifo_size; // advance next address
|
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);
|
WRITE_FIELD(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_TXFNUM, ep);
|
||||||
|
|
||||||
// store Tx FIFO size
|
// 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
|
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
|
*(USB_pDIEPTXF[ep]) = tx_fifo_config; // save
|
||||||
|
|
||||||
// enable interrupt
|
// enable interrupt
|
||||||
SET_BIT(USBD->DAINTMSK, 1 << ep);
|
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
|
// determine final write size
|
||||||
uint32_t freeSize = 0;
|
uint32_t freeSize = 0;
|
||||||
if (len > 0) { // only poll DTXFSTS if (len > 0) (see datasheet)
|
// if (len > 0) { // only poll DTXFSTS if (len > 0) (see datasheet)
|
||||||
freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
|
freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
|
||||||
}
|
//}
|
||||||
uint16_t writeSize = MIN(freeSize, len); // limit transmit size to free size
|
uint16_t writeSize = MIN(freeSize, len); // limit transmit size to free size
|
||||||
|
|
||||||
// calculate packet count based on max packet 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);
|
gs.ep_IN[ep].zlp_next = (writeSize > 0) && ((writeSize % mps) == 0);
|
||||||
|
|
||||||
// program DIEPTSIZ with transfer length
|
// 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
|
// enable endpoint and cancel responding NAK
|
||||||
SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK);
|
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
|
// push the remaining partial dword
|
||||||
uint8_t rem_bytes = len & 0b11;
|
uint8_t rem_bytes = writeSize & 0b11;
|
||||||
if (rem_bytes > 0) {
|
if (rem_bytes > 0) {
|
||||||
uint32_t rem_dword = 0;
|
uint32_t rem_dword = 0;
|
||||||
uint16_t rem_start = len - rem_bytes;
|
uint16_t rem_start = writeSize - rem_bytes;
|
||||||
for (int16_t i = len - 1; i >= rem_start; i--) {
|
for (int16_t i = writeSize - 1; i >= rem_start; i--) {
|
||||||
rem_dword = (rem_dword << 8) | data[i];
|
rem_dword = (rem_dword << 8) | data[i];
|
||||||
}
|
}
|
||||||
*p = rem_dword;
|
*p = rem_dword;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user