@@ -155,18 +155,39 @@ void Serial_::end(void)
155
155
156
156
void Serial_::accept (void )
157
157
{
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
+
158
168
ring_buffer *buffer = &cdc_rx_buffer;
159
- uint32_t c = USBD_Recv (CDC_RX);
160
169
uint32_t i = (uint32_t )(buffer->head +1 ) % CDC_SERIAL_BUFFER_SIZE;
161
170
162
171
// if we should be storing the received character into the location
163
172
// just before the tail (meaning that the head would advance to the
164
173
// current location of the tail), we're about to overflow the buffer
165
174
// 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);
167
183
buffer->buffer [buffer->head ] = c;
168
184
buffer->head = i;
185
+
186
+ i = (i + 1 ) % CDC_SERIAL_BUFFER_SIZE;
169
187
}
188
+
189
+ // release the guard
190
+ guard = 0 ;
170
191
}
171
192
172
193
int Serial_::available (void )
@@ -202,6 +223,8 @@ int Serial_::read(void)
202
223
{
203
224
unsigned char c = buffer->buffer [buffer->tail ];
204
225
buffer->tail = (unsigned int )(buffer->tail + 1 ) % CDC_SERIAL_BUFFER_SIZE;
226
+ if (USBD_Available (CDC_RX))
227
+ accept ();
205
228
return c;
206
229
}
207
230
}
0 commit comments