Simon - I have knocked up a quick circular buffer class that sits on top of Serial. I'm aiming to make a drop-in replacement for Serial that just exploits the new interrupt to provide an input buffer.
Sadly, my app dies completly whenever I get an interrupt. I don't really know whether to think that it is a bug of mine or an issue with the method form of your new interrupt.
Could you cast an eye over this, and see if you think the interrupt part ought to work ?
Thanks,
Richard
#pragma once
class SerialBuffered : public Serial
{
public:
SerialBuffered( uint16_t bufferSize, PinName rx, PinName tx );
virtual ~SerialBuffered();
uint8_t getc();
int readable();
private:
void handleInterrupt();
uint8_t *m_buff; // points at a circular buffer, containing data from m_contentStart, for m_contentSize bytes, wrapping when you get to the end
uint16_t m_contentStart;
uint16_t m_contentSize;
uint16_t m_buffSize;
};
#include "mbed.h"
#include "SerialBuffered.h"
Serial loggerSerial(USBTX, USBRX);
SerialBuffered::SerialBuffered( uint16_t bufferSize, PinName rx, PinName tx ) : Serial( rx, tx )
{
m_buffSize = 0;
m_contentStart = 0;
m_contentSize = 0;
attach( this, &SerialBuffered::handleInterrupt );
m_buff = (uint8_t *) malloc( bufferSize );
if( m_buff == NULL )
{
loggerSerial.printf("SerialBuffered - failed to alloc buffer size %d\r\n", (int) bufferSize );
}
else
{
m_buffSize = bufferSize;
}
}
SerialBuffered::~SerialBuffered()
{
if( m_buff )
free( m_buff );
}
uint8_t SerialBuffered::getc()
{
while( m_contentSize == 0 )
{
wait_ms( 1 );
}
uint8_t result = m_buff[m_contentStart];
m_contentStart = ( m_contentStart + 1 ) % m_buffSize;
m_contentSize --;
return result;
}
int SerialBuffered::readable()
{
return m_contentSize > 0 ;
}
void SerialBuffered::handleInterrupt()
{
while( Serial::readable())
{
if( m_contentSize >= m_buffSize )
{
loggerSerial.printf("SerialBuffered - buffer overrun, data lost!\r\n" );
}
else
{
uint16_t offset = ( m_contentStart + m_contentSize ) % m_buffSize;
m_buff[ offset ] = Serial::getc();
m_contentSize ++;
}
}
}
Simon - you mentioned that you were working on an interrupt-driven UART a few days ago - I'd just like to underscore my interest in a thing of that nature.
As my camera-based experiment has expanded, I am having more and more trouble keeping up with the serial stream from the camera. I need to read 5k bytes in a chunk, ideally at 115200 baud, and I am finding that any tracing at all during that period causes bytes to be lost.
And, as I am now doing some servo-driving work in a Ticker interrupt, i have other code that needs debugging going on at more or less the same time.
I'm sure I shall muddle through for now, but when you get our interrupt-UART going I'll be very happy to make use of it.
Thanks!
Richard