Improve CDC read code

Read CDC data from USB FIFO on demand instead of in ISR.
Remove superfluous ring buffer.

Signed-off-by: Paul Brook <paul@nowt.org>
This commit is contained in:
Paul Brook 2014-03-21 18:43:19 +00:00 committed by Cristian Maglie
parent b57b2ae3c1
commit 5962f155f7
3 changed files with 13 additions and 58 deletions

View File

@ -23,21 +23,6 @@
#if defined(USBCON) #if defined(USBCON)
#ifdef CDC_ENABLED #ifdef CDC_ENABLED
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
struct ring_buffer
{
unsigned char buffer[SERIAL_BUFFER_SIZE];
volatile int head;
volatile int tail;
};
ring_buffer cdc_rx_buffer = { { 0 }, 0, 0};
typedef struct typedef struct
{ {
u32 dwDTERate; u32 dwDTERate;
@ -129,7 +114,6 @@ bool WEAK CDC_Setup(Setup& setup)
} }
int _serialPeek = -1;
void Serial_::begin(unsigned long baud_count) void Serial_::begin(unsigned long baud_count)
{ {
} }
@ -142,55 +126,29 @@ void Serial_::end(void)
{ {
} }
void Serial_::accept(void)
{
ring_buffer *buffer = &cdc_rx_buffer;
int i = (unsigned int)(buffer->head+1) % 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 we have room to store a byte
while (i != buffer->tail) {
int c = USB_Recv(CDC_RX);
if (c == -1)
break; // no more data
buffer->buffer[buffer->head] = c;
buffer->head = i;
i = (unsigned int)(buffer->head+1) % SERIAL_BUFFER_SIZE;
}
}
int Serial_::available(void) int Serial_::available(void)
{ {
ring_buffer *buffer = &cdc_rx_buffer; if (peek_buffer >= 0) {
return (unsigned int)(SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % SERIAL_BUFFER_SIZE; return 1;
}
return USB_Available(CDC_RX);
} }
int Serial_::peek(void) int Serial_::peek(void)
{ {
ring_buffer *buffer = &cdc_rx_buffer; if (peek_buffer < 0)
if (buffer->head == buffer->tail) { peek_buffer = USB_Recv(CDC_RX);
return -1; return peek_buffer;
} else {
return buffer->buffer[buffer->tail];
}
} }
int Serial_::read(void) int Serial_::read(void)
{ {
ring_buffer *buffer = &cdc_rx_buffer; if (peek_buffer >= 0) {
// if the head isn't ahead of the tail, we don't have any characters int c = peek_buffer;
if (buffer->head == buffer->tail) { peek_buffer = -1;
return -1;
} else {
unsigned char c = buffer->buffer[buffer->tail];
buffer->tail = (unsigned int)(buffer->tail + 1) % SERIAL_BUFFER_SIZE;
return c; return c;
} }
return USB_Recv(CDC_RX);
} }
void Serial_::flush(void) void Serial_::flush(void)

View File

@ -28,14 +28,13 @@ extern USBDevice_ USBDevice;
class Serial_ : public Stream class Serial_ : public Stream
{ {
private: private:
ring_buffer *_cdc_rx_buffer; int peek_buffer;
public: public:
void begin(unsigned long); void begin(unsigned long);
void begin(unsigned long, uint8_t); void begin(unsigned long, uint8_t);
void end(void); void end(void);
virtual int available(void); virtual int available(void);
virtual void accept(void);
virtual int peek(void); virtual int peek(void);
virtual int read(void); virtual int read(void);
virtual void flush(void); virtual void flush(void);

View File

@ -614,8 +614,6 @@ ISR(USB_GEN_vect)
{ {
#ifdef CDC_ENABLED #ifdef CDC_ENABLED
USB_Flush(CDC_TX); // Send a tx frame if found USB_Flush(CDC_TX); // Send a tx frame if found
if (USB_Available(CDC_RX)) // Handle received bytes (if any)
Serial.accept();
#endif #endif
// check whether the one-shot period has elapsed. if so, turn off the LED // check whether the one-shot period has elapsed. if so, turn off the LED