2424 */
2525
2626#include <pico/stdlib.h>
27- #include "hardware/uart.h"
2827#include "FreeRTOS.h"
2928#include "task.h"
3029#include "tusb.h"
@@ -51,9 +50,6 @@ static volatile uint tx_led_debounce;
5150static uint rx_led_debounce ;
5251#endif
5352
54- // Guesstimate FIFO space per task wakeup
55- static volatile uint32_t chars_per_interval ;
56-
5753void cdc_uart_init (void ) {
5854 gpio_set_function (PROBE_UART_TX , GPIO_FUNC_UART );
5955 gpio_set_function (PROBE_UART_RX , GPIO_FUNC_UART );
@@ -102,29 +98,9 @@ bool cdc_task(void)
10298 static uint cdc_tx_oe = 0 ;
10399 uint rx_len = 0 ;
104100 bool keep_alive = false;
105- uart_hw_t * uart_hw = uart_get_hw (PROBE_UART_INTERFACE );
106101
107102 // Consume uart fifo regardless even if not connected
108- if (uart_hw -> ris & UART_UARTRIS_RXRIS_BITS ) {
109- // Burst 16 chars - don't use SDK wrapper as it tests RXFE every time
110- rx_buf [rx_len ++ ] = uart_hw -> dr ;
111- rx_buf [rx_len ++ ] = uart_hw -> dr ;
112- rx_buf [rx_len ++ ] = uart_hw -> dr ;
113- rx_buf [rx_len ++ ] = uart_hw -> dr ;
114- rx_buf [rx_len ++ ] = uart_hw -> dr ;
115- rx_buf [rx_len ++ ] = uart_hw -> dr ;
116- rx_buf [rx_len ++ ] = uart_hw -> dr ;
117- rx_buf [rx_len ++ ] = uart_hw -> dr ;
118- rx_buf [rx_len ++ ] = uart_hw -> dr ;
119- rx_buf [rx_len ++ ] = uart_hw -> dr ;
120- rx_buf [rx_len ++ ] = uart_hw -> dr ;
121- rx_buf [rx_len ++ ] = uart_hw -> dr ;
122- rx_buf [rx_len ++ ] = uart_hw -> dr ;
123- rx_buf [rx_len ++ ] = uart_hw -> dr ;
124- rx_buf [rx_len ++ ] = uart_hw -> dr ;
125- rx_buf [rx_len ++ ] = uart_hw -> dr ;
126- }
127- while (uart_is_readable (PROBE_UART_INTERFACE ) && (rx_len < sizeof (rx_buf ))) {
103+ while (uart_is_readable (PROBE_UART_INTERFACE ) && (rx_len < sizeof (rx_buf ))) {
128104 rx_buf [rx_len ++ ] = uart_getc (PROBE_UART_INTERFACE );
129105 }
130106
@@ -156,16 +132,16 @@ bool cdc_task(void)
156132 }
157133
158134 /* Reading from a firehose and writing to a FIFO. */
159- /* Data available? */
160135 size_t watermark = MIN (tud_cdc_available (), sizeof (tx_buf ));
161136 if (watermark > 0 ) {
162137 size_t tx_len ;
163138#ifdef PROBE_UART_TX_LED
164139 gpio_put (PROBE_UART_TX_LED , 1 );
165140 tx_led_debounce = debounce_ticks ;
166141#endif
167- /* Poke a reasonable number of bytes in */
168- tx_len = tud_cdc_read (tx_buf , MIN (chars_per_interval , watermark ));
142+ /* Batch up to half a FIFO of data - don't clog up on RX */
143+ watermark = MIN (watermark , 16 );
144+ tx_len = tud_cdc_read (tx_buf , watermark );
169145 uart_write_blocking (PROBE_UART_INTERFACE , tx_buf , tx_len );
170146 } else {
171147#ifdef PROBE_UART_TX_LED
@@ -202,13 +178,16 @@ bool cdc_task(void)
202178
203179void cdc_thread (void * ptr )
204180{
181+ BaseType_t delayed ;
205182 last_wake = xTaskGetTickCount ();
206183 bool keep_alive ;
207184 /* Threaded with a polling interval that scales according to linerate */
208185 while (1 ) {
209186 keep_alive = cdc_task ();
210187 if (!keep_alive ) {
211- xTaskDelayUntil (& last_wake , interval );
188+ delayed = xTaskDelayUntil (& last_wake , interval );
189+ if (delayed == pdFALSE )
190+ last_wake = xTaskGetTickCount ();
212191 }
213192 }
214193}
@@ -217,27 +196,17 @@ void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* line_coding)
217196{
218197 uart_parity_t parity ;
219198 uint data_bits , stop_bits ;
220- uint32_t micros , rtos_period ;
221-
222- rtos_period = (1000 * 1000 ) / configTICK_RATE_HZ ;
223199 /* Set the tick thread interval to the amount of time it takes to
224200 * fill up half a FIFO. Millis is too coarse for integer divide.
225201 */
226- micros = (1000 * 1000 * 10 ) / MAX (line_coding -> bit_rate , 1 );
227- interval = MAX (1 , (micros * 16 ) / rtos_period );
228- // For very fast baudrates, guesstimate how much the TX FIFO will empty each time
229- chars_per_interval = (uint32_t ) (((float )interval * (float )rtos_period ) / ((float )micros ));
230- if (chars_per_interval == 0 )
231- chars_per_interval ++ ;
232-
233- debounce_ticks = MAX (1 , configTICK_RATE_HZ / (interval * DEBOUNCE_MS ));
234- probe_info ("New baud rate %ld micros %ld interval %lu chars per %lu\n" ,
235- line_coding -> bit_rate , micros , interval , chars_per_interval );
236-
202+ uint32_t micros = (1000 * 1000 * 16 * 10 ) / MAX (line_coding -> bit_rate , 1 );
237203 /* Modifying state, so park the thread before changing it. */
238204 if (tud_cdc_connected ())
239205 vTaskSuspend (uart_taskhandle );
240-
206+ interval = MAX (1 , micros / ((1000 * 1000 ) / configTICK_RATE_HZ ));
207+ debounce_ticks = MAX (1 , configTICK_RATE_HZ / (interval * DEBOUNCE_MS ));
208+ probe_info ("New baud rate %ld micros %ld interval %lu\n" ,
209+ line_coding -> bit_rate , micros , interval );
241210 uart_deinit (PROBE_UART_INTERFACE );
242211 tud_cdc_write_clear ();
243212 tud_cdc_read_flush ();
0 commit comments