@@ -39,7 +39,10 @@ static void _copy_out_of_fifo(void) {
3939 req_len = USB_SERIAL_JTAG_BUF_SIZE ;
4040 }
4141 uint8_t rx_buf [USB_SERIAL_JTAG_BUF_SIZE ];
42+
43+ // Read up to req_len bytes. Does not block.
4244 size_t len = usb_serial_jtag_ll_read_rxfifo (rx_buf , req_len );
45+
4346 for (size_t i = 0 ; i < len ; ++ i ) {
4447 if (rx_buf [i ] == mp_interrupt_char ) {
4548 mp_sched_keyboard_interrupt ();
@@ -62,7 +65,9 @@ static void usb_serial_jtag_isr_handler(void *arg) {
6265 }
6366
6467 if (flags & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT ) {
68+ // New bytes are in the FIFO. Read them and check for keyboard interrupt.
6569 usb_serial_jtag_ll_clr_intsts_mask (USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT );
70+ // This is executed at interrupt level, so we don't explicitly need to make it atomic.
6671 _copy_out_of_fifo ();
6772 port_wake_main_task_from_isr ();
6873 }
@@ -81,28 +86,41 @@ bool usb_serial_jtag_connected(void) {
8186}
8287
8388char usb_serial_jtag_read_char (void ) {
84- if (ringbuf_num_filled (& ringbuf ) == 0 && !usb_serial_jtag_ll_rxfifo_data_available ()) {
89+ uint32_t num_filled = ringbuf_num_filled (& ringbuf );
90+
91+ if (num_filled == 0 && !usb_serial_jtag_ll_rxfifo_data_available ()) {
8592 return -1 ;
8693 }
8794 char c = -1 ;
88- if (ringbuf_num_filled (& ringbuf ) > 0 ) {
95+
96+ if (num_filled > 0 ) {
97+ common_hal_mcu_disable_interrupts ();
8998 c = ringbuf_get (& ringbuf );
99+ common_hal_mcu_enable_interrupts ();
100+
101+ num_filled -- ;
90102 }
103+
91104 // Maybe re-enable the recv interrupt if we've emptied the ringbuf.
92- if (ringbuf_num_filled ( & ringbuf ) == 0 ) {
105+ if (num_filled == 0 ) {
93106 usb_serial_jtag_ll_disable_intr_mask (USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT );
94107 _copy_out_of_fifo ();
95- usb_serial_jtag_ll_ena_intr_mask ( USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT );
108+
96109 // May have only been ctrl-c.
97110 if (c == -1 && ringbuf_num_filled (& ringbuf ) > 0 ) {
98111 c = ringbuf_get (& ringbuf );
99112 }
113+ usb_serial_jtag_ll_ena_intr_mask (USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT );
100114 }
101115 return c ;
102116}
103117
104118uint32_t usb_serial_jtag_bytes_available (void ) {
105- return ringbuf_num_filled (& ringbuf ) + usb_serial_jtag_ll_rxfifo_data_available ();
119+ // Atomically get the number of bytes in the ringbuf plus what is not yet in the ringbuf.
120+ common_hal_mcu_disable_interrupts ();
121+ const uint32_t count = ringbuf_num_filled (& ringbuf ) + usb_serial_jtag_ll_rxfifo_data_available ();
122+ common_hal_mcu_enable_interrupts ();
123+ return count ;
106124}
107125
108126void usb_serial_jtag_write (const char * text , uint32_t length ) {
0 commit comments