@@ -155,18 +155,39 @@ void Serial_::end(void)
155155
156156void Serial_::accept (void )
157157{
158+ static uint32_t guard = 0 ;
159+
160+ // synchronized access to guard
161+ do {
162+ if (__LDREXW (&guard) != 0 ) {
163+ __CLREX ();
164+ return ; // busy
165+ }
166+ } while (__STREXW (1 , &guard) != 0 ); // retry until write succeed
167+
158168 ring_buffer *buffer = &cdc_rx_buffer;
159- uint32_t c = USBD_Recv (CDC_RX);
160169 uint32_t i = (uint32_t )(buffer->head +1 ) % CDC_SERIAL_BUFFER_SIZE;
161170
162171 // if we should be storing the received character into the location
163172 // just before the tail (meaning that the head would advance to the
164173 // current location of the tail), we're about to overflow the buffer
165174 // and so we don't write the character or advance the head.
166- if (i != buffer->tail ) {
175+ while (i != buffer->tail ) {
176+ uint32_t c;
177+ if (!USBD_Available (CDC_RX)) {
178+ udd_ack_fifocon (CDC_RX);
179+ break ;
180+ }
181+ c = USBD_Recv (CDC_RX);
182+ // c = UDD_Recv8(CDC_RX & 0xF);
167183 buffer->buffer [buffer->head ] = c;
168184 buffer->head = i;
185+
186+ i = (i + 1 ) % CDC_SERIAL_BUFFER_SIZE;
169187 }
188+
189+ // release the guard
190+ guard = 0 ;
170191}
171192
172193int Serial_::available (void )
@@ -202,6 +223,8 @@ int Serial_::read(void)
202223 {
203224 unsigned char c = buffer->buffer [buffer->tail ];
204225 buffer->tail = (unsigned int )(buffer->tail + 1 ) % CDC_SERIAL_BUFFER_SIZE;
226+ if (USBD_Available (CDC_RX))
227+ accept ();
205228 return c;
206229 }
207230}
0 commit comments