drivers/usbdev: Correct input flow control logic when watermarks are not enabled. Problem not by and change based on suggestion by Juha Niskanen.
This commit is contained in:
parent
477a8d1aa7
commit
85a1a3cc98
@ -518,7 +518,7 @@ if SERIAL_IFLOWCONTROL_WATERMARKS
|
|||||||
config SERIAL_IFLOWCONTROL_LOWER_WATERMARK
|
config SERIAL_IFLOWCONTROL_LOWER_WATERMARK
|
||||||
int "RX lower Watermark (percent)"
|
int "RX lower Watermark (percent)"
|
||||||
default 10
|
default 10
|
||||||
range 0 100
|
range 1 99
|
||||||
---help---
|
---help---
|
||||||
Call the rxflowcontrol method then there are this amount (or or less)
|
Call the rxflowcontrol method then there are this amount (or or less)
|
||||||
data buffered in the serial drivers RX buffer. This is expressed
|
data buffered in the serial drivers RX buffer. This is expressed
|
||||||
@ -528,7 +528,7 @@ config SERIAL_IFLOWCONTROL_LOWER_WATERMARK
|
|||||||
config SERIAL_IFLOWCONTROL_UPPER_WATERMARK
|
config SERIAL_IFLOWCONTROL_UPPER_WATERMARK
|
||||||
int "RX upper Watermark (percent)"
|
int "RX upper Watermark (percent)"
|
||||||
default 90
|
default 90
|
||||||
range 0 100
|
range 1 99
|
||||||
---help---
|
---help---
|
||||||
Call the rxflowcontrol method then there are this amount (or more)
|
Call the rxflowcontrol method then there are this amount (or more)
|
||||||
data buffered in the serial drivers RX buffer. This is expressed
|
data buffered in the serial drivers RX buffer. This is expressed
|
||||||
|
@ -70,6 +70,24 @@
|
|||||||
|
|
||||||
#define uart_putc(ch) up_putc(ch)
|
#define uart_putc(ch) up_putc(ch)
|
||||||
|
|
||||||
|
/* Check watermark levels */
|
||||||
|
|
||||||
|
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && \
|
||||||
|
defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS)
|
||||||
|
# if CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK < 1
|
||||||
|
# warning CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK too small
|
||||||
|
# endif
|
||||||
|
# if CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK > 99
|
||||||
|
# warning CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK too large
|
||||||
|
# endif
|
||||||
|
# if CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK >= CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK
|
||||||
|
# warning CONFIG_SERIAL_IFLOWCONTROL_LOWER_WATERMARK too large
|
||||||
|
# warning Must be less than CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Timing */
|
||||||
|
|
||||||
#define HALF_SECOND_MSEC 500
|
#define HALF_SECOND_MSEC 500
|
||||||
#define HALF_SECOND_USEC 500000L
|
#define HALF_SECOND_USEC 500000L
|
||||||
|
|
||||||
@ -995,7 +1013,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
|||||||
(void)uart_rxflowcontrol(dev, nbuffered, false);
|
(void)uart_rxflowcontrol(dev, nbuffered, false);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* If the RX buffer empty */
|
/* Is the RX buffer empty? */
|
||||||
|
|
||||||
if (rxbuf->head == rxbuf->tail)
|
if (rxbuf->head == rxbuf->tail)
|
||||||
{
|
{
|
||||||
|
@ -515,7 +515,10 @@ static int cdcacm_recvpacket(FAR struct cdcacm_dev_s *priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
|
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
|
||||||
/* Pre-calcuate the watermark level that we will need to test against. */
|
/* Pre-calcuate the watermark level that we will need to test against.
|
||||||
|
* Note that the range of the the upper watermark is from 1 to 99 percent
|
||||||
|
* and that the actual capacity of the RX biffer is (recv->size - 1).
|
||||||
|
*/
|
||||||
|
|
||||||
watermark = (CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK * recv->size) / 100;
|
watermark = (CONFIG_SERIAL_IFLOWCONTROL_UPPER_WATERMARK * recv->size) / 100;
|
||||||
#endif
|
#endif
|
||||||
@ -535,8 +538,8 @@ static int cdcacm_recvpacket(FAR struct cdcacm_dev_s *priv,
|
|||||||
|
|
||||||
while (nexthead != recv->tail && nbytes < reqlen)
|
while (nexthead != recv->tail && nbytes < reqlen)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && \
|
||||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS
|
defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS)
|
||||||
unsigned int nbuffered;
|
unsigned int nbuffered;
|
||||||
|
|
||||||
/* How many bytes are buffered */
|
/* How many bytes are buffered */
|
||||||
@ -565,21 +568,6 @@ static int cdcacm_recvpacket(FAR struct cdcacm_dev_s *priv,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/* Check if RX buffer is full and allow serial low-level driver to pause
|
|
||||||
* processing. This allows proper utilization of hardware flow control.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (nexthead == rxbuf->tail)
|
|
||||||
{
|
|
||||||
if (cdcuart_rxflowcontrol(&priv->serdev, recv->size, true))
|
|
||||||
{
|
|
||||||
/* Low-level driver activated RX flow control, exit loop now. */
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copy one byte to the head of the circular RX buffer */
|
/* Copy one byte to the head of the circular RX buffer */
|
||||||
@ -604,10 +592,23 @@ static int cdcacm_recvpacket(FAR struct cdcacm_dev_s *priv,
|
|||||||
|
|
||||||
recv->head = currhead;
|
recv->head = currhead;
|
||||||
|
|
||||||
|
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && \
|
||||||
|
!defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS)
|
||||||
|
/* Check if RX buffer became full and allow serial low-level driver to
|
||||||
|
* pause processing. This allows proper utilization of hardware flow
|
||||||
|
* control when there are no watermarks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (nexthead == recv->tail)
|
||||||
|
{
|
||||||
|
(void)cdcuart_rxflowcontrol(&priv->serdev, recv->size, true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If data was added to the incoming serial buffer, then wake up any
|
/* If data was added to the incoming serial buffer, then wake up any
|
||||||
* threads is waiting for incoming data. If we are running in an interrupt
|
* threads is waiting for incoming data. If we are running in an interrupt
|
||||||
* handler, then the serial driver will not run until the interrupt handler
|
* handler, then the serial driver will not run until the interrupt
|
||||||
* returns.
|
* handler returns.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (nbytes > 0)
|
if (nbytes > 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user