icE1usb fw: Better flow regulation mechanism
* FIFO target level : - The '8 * 16' makes no sense as the FIFO was 128 so this is the "full" case and could never be that high. - We tighten up the margin around 5 * 16 which is the "target" level for the FIFO * FIFO size : We also increase the FIFO size to 256 frames. This doesn't actually affect latency since the target level is the same, but it allows more leeway to recover without data loss in case something goes wrong. * Ticks : We don't bother using ticks ... the current algo wasn't working (or rather not doing anything all that useful), because the difference between USB clock and E1 clock is tiny and measured over 1 ms, it's not meaningful. So for the time being we just sent the nominal rate biased with the FIFO level to keep it on target and this seems to work fine. It'd be nice to have a good long term estimate of the rate to minimize the jitter, but it doesn't seem to be strictly required for operation for now. * Misc cleanup : Just do all in one function instead of splitting the check if BD needs refill and the actual refill. This gets rid of sporadic 'TX FIFO Overflow' conditions by properly handling the case where we have a bit too much data. Signed-off-by: Sylvain Munaut <tnt@246tNt.com> Change-Id: Ibd3bc9080961cc56093e43ab9a824840e84c24d2
This commit is contained in:
parent
0abe343d92
commit
2de84f804e
|
@ -273,8 +273,8 @@ e1_init(int port, uint16_t rx_cr, uint16_t tx_cr)
|
|||
memset(e1, 0x00, sizeof(struct e1_state));
|
||||
|
||||
/* Reset FIFOs */
|
||||
e1f_reset(&e1->rx.fifo, (256 * port) + 0, 128);
|
||||
e1f_reset(&e1->tx.fifo, (256 * port) + 128, 128);
|
||||
e1f_reset(&e1->rx.fifo, (512 * port) + 0, 256);
|
||||
e1f_reset(&e1->tx.fifo, (512 * port) + 256, 256);
|
||||
|
||||
/* Enable Rx */
|
||||
e1->rx.cr = E1_RX_CR_ENABLE | rx_cr;
|
||||
|
|
|
@ -74,30 +74,25 @@ _ifnum2port(uint8_t bInterfaceNumber)
|
|||
static void
|
||||
_usb_fill_feedback_ep(int port)
|
||||
{
|
||||
static uint16_t ticks_prev = 0;
|
||||
uint16_t ticks;
|
||||
uint32_t val = 8192;
|
||||
unsigned int level;
|
||||
volatile struct usb_ep *ep_regs;
|
||||
volatile struct usb_ep *ep_regs = _get_ep_regs(USB_EP_E1_FB(port));
|
||||
|
||||
/* Compute real E1 tick count (with safety against bad values) */
|
||||
ticks = e1_tick_read(port);
|
||||
val = (ticks - ticks_prev) & 0xffff;
|
||||
ticks_prev = ticks;
|
||||
if ((val < 7168) | (val > 9216))
|
||||
val = 8192;
|
||||
/* Always ensure we're ready to send */
|
||||
if ((ep_regs->bd[0].csr & USB_BD_STATE_MSK) != USB_BD_STATE_RDY_DATA)
|
||||
{
|
||||
uint32_t val = 8192;
|
||||
|
||||
/* Bias depending on TX fifo level */
|
||||
level = e1_tx_level(port);
|
||||
if (level < (3 * 16))
|
||||
val += 256;
|
||||
else if (level > (8 * 16))
|
||||
val -= 256;
|
||||
/* Add instant bias depending on TX fifo level */
|
||||
unsigned int level = e1_tx_level(port);
|
||||
|
||||
/* Prepare buffer */
|
||||
ep_regs = _get_ep_regs(USB_EP_E1_FB(port));
|
||||
usb_data_write(ep_regs->bd[0].ptr, &val, 4);
|
||||
ep_regs->bd[0].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(3);
|
||||
if (level < (4 * 16))
|
||||
val += 256;
|
||||
else if (level > (6 * 16))
|
||||
val -= 256;
|
||||
|
||||
/* Fill buffer and submit it */
|
||||
usb_data_write(ep_regs->bd[0].ptr, &val, 4);
|
||||
ep_regs->bd[0].csr = USB_BD_STATE_RDY_DATA | USB_BD_LEN(3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,12 +207,7 @@ refill:
|
|||
}
|
||||
|
||||
/* Feedback endpoint */
|
||||
ep_regs = _get_ep_regs(USB_EP_E1_FB(port));
|
||||
|
||||
if ((ep_regs->bd[0].csr & USB_BD_STATE_MSK) != USB_BD_STATE_RDY_DATA)
|
||||
{
|
||||
_usb_fill_feedback_ep(port);
|
||||
}
|
||||
_usb_fill_feedback_ep(port);
|
||||
}
|
||||
|
||||
static enum usb_fnd_resp
|
||||
|
|
Loading…
Reference in New Issue