11// SPDX-License-Identifier: MIT
22/*
33 * Copyright 2021 Álvaro Fernández Rojas <[email protected] > 4+ * Cleanup/modifications Copyright 2023 Andrew J. Kroll <xxxajk at gmail>
5+ *
46 */
57
68#include <hardware/irq.h>
1921
2022#define BUFFER_SIZE 2560
2123
24+ #define UART0_TX 16
25+ #define UART0_RX 17
26+
27+ #define UART1_TX 4
28+ #define UART1_RX 5
29+
2230#define DEF_BIT_RATE 115200
2331#define DEF_STOP_BITS 1
2432#define DEF_PARITY 0
@@ -52,18 +60,20 @@ const uart_id_t UART_ID[CFG_TUD_CDC] = {
5260 .inst = uart0 ,
5361 .irq = UART0_IRQ ,
5462 .irq_fn = & uart0_irq_fn ,
55- .tx_pin = 16 ,
56- .rx_pin = 17 ,
57- }, {
63+ .tx_pin = UART0_TX ,
64+ .rx_pin = UART0_RX ,
65+ },
66+ {
5867 .inst = uart1 ,
5968 .irq = UART1_IRQ ,
6069 .irq_fn = & uart1_irq_fn ,
61- .tx_pin = 4 ,
62- .rx_pin = 5 ,
70+ .tx_pin = UART1_TX ,
71+ .rx_pin = UART1_RX ,
6372 }
6473};
6574
6675uart_data_t UART_DATA [CFG_TUD_CDC ];
76+ volatile bool ready = false;
6777
6878static inline uint databits_usb2uart (uint8_t data_bits )
6979{
@@ -151,21 +161,41 @@ void usb_write_bytes(uint8_t itf)
151161{
152162 uart_data_t * ud = & UART_DATA [itf ];
153163
154- if (ud -> uart_pos &&
155- mutex_try_enter (& ud -> uart_mtx , NULL )) {
156- uint32_t count ;
164+ if (ud -> uart_pos ) {
165+ if (mutex_try_enter (& ud -> uart_mtx , NULL )) {
166+ uint32_t count = tud_cdc_n_write (itf , ud -> uart_buffer , ud -> uart_pos );
167+ // horrible! should use ring buffers!!
168+ if (count < ud -> uart_pos ) {
169+ memmove (ud -> uart_buffer , & ud -> uart_buffer [count ], ud -> uart_pos - count );
170+ }
171+ ud -> uart_pos -= count ;
172+ mutex_exit (& ud -> uart_mtx );
157173
158- count = tud_cdc_n_write ( itf , ud -> uart_buffer , ud -> uart_pos );
159- if ( count < ud -> uart_pos )
160- memmove ( ud -> uart_buffer , & ud -> uart_buffer [ count ],
161- ud -> uart_pos - count );
162- ud -> uart_pos -= count ;
174+ if ( count )
175+ tud_cdc_n_write_flush ( itf );
176+ }
177+ }
178+ }
163179
164- mutex_exit (& ud -> uart_mtx );
180+ void tud_cdc_send_break_cb (uint8_t itf , uint16_t duration_ms )
181+ {
182+ const uart_id_t * ui = & UART_ID [itf ];
183+ uart_data_t * ud = & UART_DATA [itf ];
165184
166- if (count )
167- tud_cdc_n_write_flush (itf );
185+ // is mutex for tx even needed??
186+ //mutex_enter_blocking(&ud->lc_mtx);
187+
188+ if (duration_ms == 0xffff ) {
189+ uart_set_break (ui -> inst , true);
190+ } else if (duration_ms == 0x0000 ) {
191+ uart_set_break (ui -> inst , false);
192+ } else {
193+ // should be correct for non-compliant stacks?
194+ uart_set_break (ui -> inst , true);
195+ sleep_ms (duration_ms );
196+ uart_set_break (ui -> inst , false);
168197 }
198+ //mutex_exit(&ud->lc_mtx);
169199}
170200
171201void usb_cdc_process (uint8_t itf )
@@ -183,14 +213,18 @@ void usb_cdc_process(uint8_t itf)
183213void core1_entry (void )
184214{
185215 tusb_init ();
216+ ready = true;
186217
187- while (1 ) {
218+ while (1 ) {
188219 int itf ;
189- int con = 0 ;
190-
191220 tud_task ();
192221
222+ if (tud_ready ()) { // we need to ignore DTR on the CDC side
223+ for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
193224 for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
225+ if (tud_cdc_n_connected (itf )) {
226+ con = 1 ;
227+ for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
194228 if (tud_cdc_n_connected (itf )) {
195229 con = 1 ;
196230 usb_cdc_process (itf );
@@ -209,12 +243,12 @@ static inline void uart_read_bytes(uint8_t itf)
209243 if (uart_is_readable (ui -> inst )) {
210244 mutex_enter_blocking (& ud -> uart_mtx );
211245
212- while (uart_is_readable (ui -> inst ) &&
213- (ud -> uart_pos < BUFFER_SIZE )) {
246+ if (ud -> uart_pos < BUFFER_SIZE ) {
214247 ud -> uart_buffer [ud -> uart_pos ] = uart_getc (ui -> inst );
215248 ud -> uart_pos ++ ;
249+ } else {
250+ uart_getc (ui -> inst ); // drop it on the floor
216251 }
217-
218252 mutex_exit (& ud -> uart_mtx );
219253 }
220254}
@@ -233,22 +267,17 @@ void uart_write_bytes(uint8_t itf)
233267{
234268 uart_data_t * ud = & UART_DATA [itf ];
235269
236- if (ud -> usb_pos &&
237- mutex_try_enter (& ud -> usb_mtx , NULL )) {
270+ if (ud -> usb_pos && mutex_try_enter (& ud -> usb_mtx , NULL )) {
238271 const uart_id_t * ui = & UART_ID [itf ];
239- uint32_t count = 0 ;
240272
241- while (uart_is_writable (ui -> inst ) &&
242- count < ud -> usb_pos ) {
243- uart_putc_raw (ui -> inst , ud -> usb_buffer [count ]);
244- count ++ ;
273+ // horrible! should use ring buffers!!
274+ if (uart_is_writable (ui -> inst )) { // && count < ud->usb_pos) {
275+ uart_putc_raw (ui -> inst , ud -> usb_buffer [0 ]);
276+ if (ud -> usb_pos > 1 ) {
277+ memmove (ud -> usb_buffer , & ud -> usb_buffer [1 ], ud -> usb_pos - 1 );
278+ }
279+ ud -> usb_pos -- ;
245280 }
246-
247- if (count < ud -> usb_pos )
248- memmove (ud -> usb_buffer , & ud -> usb_buffer [count ],
249- ud -> usb_pos - count );
250- ud -> usb_pos -= count ;
251-
252281 mutex_exit (& ud -> usb_mtx );
253282 }
254283}
@@ -261,6 +290,7 @@ void init_uart_data(uint8_t itf)
261290 /* Pinmux */
262291 gpio_set_function (ui -> tx_pin , GPIO_FUNC_UART );
263292 gpio_set_function (ui -> rx_pin , GPIO_FUNC_UART );
293+ gpio_pull_up (ui -> rx_pin ); // important missed detail, prevents connection glitches
264294
265295 /* USB CDC LC */
266296 ud -> usb_lc .bit_rate = DEF_BIT_RATE ;
@@ -287,34 +317,51 @@ void init_uart_data(uint8_t itf)
287317 uart_init (ui -> inst , ud -> usb_lc .bit_rate );
288318 uart_set_hw_flow (ui -> inst , false, false);
289319 uart_set_format (ui -> inst , databits_usb2uart (ud -> usb_lc .data_bits ),
290- stopbits_usb2uart (ud -> usb_lc .stop_bits ),
291- parity_usb2uart (ud -> usb_lc .parity ));
320+ stopbits_usb2uart (ud -> usb_lc .stop_bits ),
321+ parity_usb2uart (ud -> usb_lc .parity ));
292322 uart_set_fifo_enabled (ui -> inst , false);
293-
323+ uart_set_translate_crlf ( ui -> inst , false);
294324 /* UART RX Interrupt */
295325 irq_set_exclusive_handler (ui -> irq , ui -> irq_fn );
296- irq_set_enabled (ui -> irq , true);
297- uart_set_irq_enables (ui -> inst , true, false);
298326}
299327
300- int main (void )
301- {
328+ void start_uarts () {
329+ uint8_t itf ;
330+ for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
331+ init_uart_data (itf );
332+ }
333+
334+ // enable ISRs
335+ for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
336+ const uart_id_t * ui = & UART_ID [itf ];
337+ irq_set_enabled (ui -> irq , true);
338+ uart_set_irq_enables (ui -> inst , true, false);
339+ }
340+ }
341+
342+ int main (void ) {
302343 int itf ;
303344
345+ multicore_reset_core1 ();
346+
304347 usbd_serial_init ();
305348
306- for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ )
307- init_uart_data (itf );
349+ start_uarts ();
308350
309351 gpio_init (LED_PIN );
310352 gpio_set_dir (LED_PIN , GPIO_OUT );
311353
312354 multicore_launch_core1 (core1_entry );
313-
314- while (1 ) {
315- for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
316- update_uart_cfg (itf );
317- uart_write_bytes (itf );
355+ do {
356+ sleep_us (1 );
357+ } while (!ready );
358+
359+ while (1 ) {
360+ if (tud_ready ()) {
361+ for (itf = 0 ; itf < CFG_TUD_CDC ; itf ++ ) {
362+ update_uart_cfg (itf );
363+ uart_write_bytes (itf );
364+ }
318365 }
319366 }
320367
0 commit comments