correct the fifo_available comparison (words not byte)
This commit is contained in:
@@ -853,21 +853,21 @@ static void handle_epin_irq(uint8_t rhport) {
|
|||||||
const uint16_t remain_bytes = epin->dieptsiz_bm.xfer_size;
|
const uint16_t remain_bytes = epin->dieptsiz_bm.xfer_size;
|
||||||
|
|
||||||
// Packet can not be larger than ep max size
|
// Packet can not be larger than ep max size
|
||||||
const uint16_t packet_size = tu_min16(remain_bytes, xfer->max_size);
|
const uint16_t xact_bytes = tu_min16(remain_bytes, xfer->max_size);
|
||||||
|
|
||||||
// It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current
|
// It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current
|
||||||
// EP has to be checked if the buffer can take another WHOLE packet
|
// EP has to be checked if the buffer can take another WHOLE packet
|
||||||
if (packet_size > ((epin->dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) {
|
if (xact_bytes > ((epin->dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push packet to Tx-FIFO
|
// Push packet to Tx-FIFO
|
||||||
if (xfer->ff) {
|
if (xfer->ff) {
|
||||||
volatile uint32_t* tx_fifo = dwc2->fifo[n];
|
volatile uint32_t* tx_fifo = dwc2->fifo[n];
|
||||||
tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*) (uintptr_t) tx_fifo, packet_size);
|
tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*) (uintptr_t) tx_fifo, xact_bytes);
|
||||||
} else {
|
} else {
|
||||||
dfifo_write_packet(dwc2, n, xfer->buffer, packet_size);
|
dfifo_write_packet(dwc2, n, xfer->buffer, xact_bytes);
|
||||||
xfer->buffer += packet_size;
|
xfer->buffer += xact_bytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -463,6 +463,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
|||||||
TU_ASSERT(ep_id < CFG_TUH_DWC2_ENDPOINT_MAX);
|
TU_ASSERT(ep_id < CFG_TUH_DWC2_ENDPOINT_MAX);
|
||||||
hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
|
hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
|
||||||
dwc2_channel_char_t* hcchar_bm = &edpt->hcchar_bm;
|
dwc2_channel_char_t* hcchar_bm = &edpt->hcchar_bm;
|
||||||
|
bool const is_period = edpt_is_periodic(hcchar_bm->ep_type);
|
||||||
|
|
||||||
uint8_t ch_id = channel_alloc(dwc2);
|
uint8_t ch_id = channel_alloc(dwc2);
|
||||||
TU_ASSERT(ch_id < 16); // all channel are in used
|
TU_ASSERT(ch_id < 16); // all channel are in used
|
||||||
@@ -487,7 +488,9 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
|||||||
// TODO support split transaction
|
// TODO support split transaction
|
||||||
channel->hcsplt = edpt->hcsplt;
|
channel->hcsplt = edpt->hcsplt;
|
||||||
|
|
||||||
hcchar_bm->odd_frame = 1 - (dwc2->hfnum & 1); // transfer on next frame
|
if (is_period) {
|
||||||
|
hcchar_bm->odd_frame = 1 - (dwc2->hfnum & 1); // transfer on next frame
|
||||||
|
}
|
||||||
hcchar_bm->ep_dir = ep_dir; // control endpoint can switch direction
|
hcchar_bm->ep_dir = ep_dir; // control endpoint can switch direction
|
||||||
channel->hcchar = (edpt->hcchar & ~HCCHAR_CHENA); // restore hcchar but don't enable yet
|
channel->hcchar = (edpt->hcchar & ~HCCHAR_CHENA); // restore hcchar but don't enable yet
|
||||||
|
|
||||||
@@ -508,8 +511,6 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
|||||||
channel->hcintmsk = hcintmsk;
|
channel->hcintmsk = hcintmsk;
|
||||||
dwc2->haintmsk |= TU_BIT(ch_id);
|
dwc2->haintmsk |= TU_BIT(ch_id);
|
||||||
|
|
||||||
bool const is_period = edpt_is_periodic(hcchar_bm->ep_type);
|
|
||||||
|
|
||||||
// enable channel for slave mode:
|
// enable channel for slave mode:
|
||||||
// - OUT: it will enable corresponding FIFO channel
|
// - OUT: it will enable corresponding FIFO channel
|
||||||
// - IN : it will write an IN request to the Non-periodic Request Queue, this will have dwc2 trying to send
|
// - IN : it will write an IN request to the Non-periodic Request Queue, this will have dwc2 trying to send
|
||||||
@@ -771,7 +772,8 @@ bool handle_channel_slave_out(dwc2_regs_t* dwc2, uint8_t ch_id, bool is_period,
|
|||||||
xfer->result = XFER_RESULT_FAILED;
|
xfer->result = XFER_RESULT_FAILED;
|
||||||
is_notify = true;
|
is_notify = true;
|
||||||
} else {
|
} else {
|
||||||
// Re-initialize Channel (Do ping protocol for HS)
|
// Got here due to NAK probably, retry channel (Do ping protocol for HS)
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (hcint & HCINT_ACK) {
|
} else if (hcint & HCINT_ACK) {
|
||||||
xfer->err_count = 0;
|
xfer->err_count = 0;
|
||||||
@@ -827,24 +829,22 @@ bool handle_txfifo_empty(dwc2_regs_t* dwc2, bool is_periodic) {
|
|||||||
const uint8_t max_channel = DWC2_CHANNEL_COUNT(dwc2);
|
const uint8_t max_channel = DWC2_CHANNEL_COUNT(dwc2);
|
||||||
for (uint8_t ch_id = 0; ch_id < max_channel; ch_id++) {
|
for (uint8_t ch_id = 0; ch_id < max_channel; ch_id++) {
|
||||||
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
||||||
if (xfer->allocated) {
|
dwc2_channel_t* channel = &dwc2->channel[ch_id];
|
||||||
dwc2_channel_t* channel = &dwc2->channel[ch_id];
|
const dwc2_channel_char_t hcchar_bm = channel->hcchar_bm;
|
||||||
const dwc2_channel_char_t hcchar_bm = channel->hcchar_bm;
|
if (hcchar_bm.ep_dir == TUSB_DIR_OUT) {
|
||||||
if (hcchar_bm.ep_dir == TUSB_DIR_OUT) {
|
const uint16_t remain_packets = channel->hctsiz_bm.packet_count;
|
||||||
const uint16_t remain_packets = channel->hctsiz_bm.packet_count;
|
for (uint16_t i = 0; i < remain_packets; i++) {
|
||||||
for (uint16_t i = 0; i < remain_packets; i++) {
|
const uint16_t remain_bytes = (uint16_t) channel->hctsiz_bm.xfer_size;
|
||||||
const uint16_t remain_bytes = (uint16_t) channel->hctsiz_bm.xfer_size;
|
const uint16_t xact_bytes = tu_min16(remain_bytes, hcchar_bm.ep_size);
|
||||||
const uint16_t xact_bytes = tu_min16(remain_bytes, hcchar_bm.ep_size);
|
|
||||||
|
|
||||||
// check if there is enough space in FIFO and RequestQueue.
|
// check if there is enough space in FIFO and RequestQueue.
|
||||||
// Packet's last word written to FIFO will trigger a request queue
|
// Packet's last word written to FIFO will trigger a request queue
|
||||||
if ((xact_bytes > txsts_bm->fifo_available) && (txsts_bm->req_queue_available > 0)) {
|
if ((xact_bytes > (txsts_bm->fifo_available << 2)) && (txsts_bm->req_queue_available > 0)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
dfifo_write_packet(dwc2, ch_id, xfer->buffer, xact_bytes);
|
|
||||||
xfer->buffer += xact_bytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dfifo_write_packet(dwc2, ch_id, xfer->buffer, xact_bytes);
|
||||||
|
xfer->buffer += xact_bytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user