Thanks, that's useful... I'm not sure I'm using the instructions exactly right but the following seems to work:
void Serial_::accept(void)
{
static uint8_t r=0;
int t=__LDREXB(&r);
if(t)return;
if(__STREXB(1,&r))return;
ring_buffer *buffer = &cdc_rx_buffer;
uint32_t i = (uint32_t)(buffer->head+1) % CDC_SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
while (i != buffer->tail) {
uint32_t c;
if (!USBD_Available(CDC_RX)) {
udd_ack_fifocon(CDC_RX);
break;
}
c = USBD_Recv(CDC_RX);
// c = UDD_Recv8(CDC_RX & 0xF);
buffer->buffer[buffer->head] = c;
buffer->head = i;
i = (i + 1) % CDC_SERIAL_BUFFER_SIZE;
}
r=0;
}
(cmaglie - I just saw your code, looks good, I'll try it out)
It's not amazingly fast (I am getting a 7MByte file through in about 50s) but it is reliable - no diff in 50MBytes of testing so far