Serial buffer problem

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
pd0wm
Date:
Mon Oct 11 18:46:18 2010 +0000
Commit message:

Changed in this revision

SerialBuffered.cpp Show annotated file Show diff for this revision Revisions of this file
SerialBuffered.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.cpp	Mon Oct 11 18:46:18 2010 +0000
@@ -0,0 +1,108 @@
+
+#include "mbed.h"
+#include "SerialBuffered.h"
+ 
+extern Serial loggerSerial;
+ 
+SerialBuffered::SerialBuffered( size_t bufferSize, PinName tx, PinName rx ) : Serial(  tx,  rx ) 
+{
+    m_buffSize = 0;
+    m_contentStart = 0;
+    m_contentEnd = 0;
+    m_timeout = 1.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 );
+}
+
+void SerialBuffered::setTimeout( float seconds )
+{
+    m_timeout = seconds;
+}
+    
+size_t SerialBuffered::readBytes( uint8_t *bytes, size_t requested )
+{
+    int i = 0;
+
+    for( ; i < requested; )
+    {
+        int c = getc();
+        if( c < 0 )
+            break;
+        bytes[i] = c;
+        i++;
+    }
+    
+    return i;
+        
+}
+
+
+int SerialBuffered::getc()
+{
+    m_timer.reset();
+    m_timer.start();
+    while( m_contentStart == m_contentEnd )
+    {
+      
+
+        wait_ms( 1 );
+        if( m_timeout > 0 &&  m_timer.read() > m_timeout )
+            return EOF;
+    }
+
+    m_timer.stop();
+   
+    uint8_t result = m_buff[m_contentStart++];
+    m_contentStart =  m_contentStart % m_buffSize;
+
+   
+    return result;    
+}
+
+
+int SerialBuffered::readable()
+{
+    return m_contentStart != m_contentEnd ;
+}
+
+void SerialBuffered::handleInterrupt()
+{
+    
+    while( Serial::readable())
+    {
+        if( m_contentStart == (m_contentEnd +1) % m_buffSize)
+        {
+           loggerSerial.printf("SerialBuffered - buffer overrun, data lost!\r\n" );
+           Serial::getc();
+
+        }
+        else
+        {
+          
+            m_buff[ m_contentEnd ++ ] = Serial::getc();
+            m_contentEnd = m_contentEnd % m_buffSize;
+            
+           
+           
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.h	Mon Oct 11 18:46:18 2010 +0000
@@ -0,0 +1,39 @@
+#pragma once
+
+// This is a buffered serial reading class, using the serial interrupt introduced in mbed library version 18 on 17/11/09
+
+// In the simplest case, construct it with a buffer size at least equal to the largest message you 
+// expect your program to receive in one go.
+
+class SerialBuffered : public Serial
+{
+public:
+    SerialBuffered( size_t bufferSize, PinName tx, PinName rx );
+    virtual ~SerialBuffered();
+    
+    int getc();     // will block till the next character turns up, or return -1 if there is a timeout
+    
+    int readable(); // returns 1 if there is a character available to read, 0 otherwise
+    
+    void setTimeout( float seconds );    // maximum time in seconds that getc() should block 
+                                         // while waiting for a character
+                                         // Pass -1 to disable the timeout.
+    
+    size_t readBytes( uint8_t *bytes, size_t requested );    // read requested bytes into a buffer, 
+                                                             // return number actually read, 
+                                                             // which may be less than requested if there has been a timeout
+    
+
+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;   // index of first bytes of content
+    uint16_t  m_contentEnd;     // index of bytes after last byte of content
+    uint16_t m_buffSize;
+    float m_timeout;
+    Timer m_timer;
+
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Oct 11 18:46:18 2010 +0000
@@ -0,0 +1,21 @@
+#include "mbed.h"
+#include "SerialBuffered.h"
+
+
+Serial loggerSerial(USBTX, USBRX);
+
+
+DigitalOut uart_activity(LED2);
+
+int main() {
+    SerialBuffered *b = new SerialBuffered( 1001, p28, p27);
+    b->baud( 9600 );
+    b->setTimeout( 5 );
+    while (1) {
+        if (b.readable()) {
+            loggerSerial.putc(b.getc());
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Oct 11 18:46:18 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e