support library for C027 helper functions for Buffer Pipes, Buffered Serial Port (rtos capable) and GPS parsing. It includes modem APIs for USSD, SMS and Sockets.

Fork of C027_Support by u-blox

Files at this revision

API Documentation at this revision

Comitter:
mazgch
Date:
Sun Nov 10 16:39:42 2013 +0000
Parent:
8:2435cdff8015
Child:
10:3f1c13a8763d
Commit message:
update support library (tx pipe)

Changed in this revision

GPS.cpp Show annotated file Show diff for this revision Revisions of this file
GPS.h Show annotated file Show diff for this revision Revisions of this file
Pipe.h Show annotated file Show diff for this revision Revisions of this file
SerialPipe.cpp Show annotated file Show diff for this revision Revisions of this file
SerialPipe.h Show annotated file Show diff for this revision Revisions of this file
--- a/GPS.cpp	Sat Nov 09 13:31:49 2013 +0000
+++ b/GPS.cpp	Sun Nov 10 16:39:42 2013 +0000
@@ -6,26 +6,34 @@
 {
     int unkn = 0;
     int sz = pipe->size();
+    int fr = pipe->free();
     if (len > sz)
         len = sz;
     while (len > 0)
     {
         // NMEA protocol
         int nmea = _parseNmea(pipe,len);
-        if ((nmea != NOT_FOUND) && (unkn > 0))  return unkn;
-        if (nmea == WAIT)                       return WAIT;
-        if (nmea > 0)                           return NMEA | pipe->get(buf,nmea);
+        if ((nmea != NOT_FOUND) && (unkn > 0))  
+            return unkn;
+        if (nmea == WAIT && fr)                       
+            return WAIT;
+        if (nmea > 0)                           
+            return NMEA | pipe->get(buf,nmea);
         // UBX protocol
         int ubx = _parseUbx(pipe,len);
-        if ((ubx != NOT_FOUND) && (unkn > 0))   return unkn;
-        if (ubx == WAIT)                        return WAIT;
-        if (ubx > 0)                            return UBX | pipe->get(buf,ubx);
+        if ((ubx != NOT_FOUND) && (unkn > 0))   
+            return unkn;
+        if (ubx == WAIT && fr)                        
+            return WAIT;
+        if (ubx > 0)                            
+            return UBX | pipe->get(buf,ubx);
         // UNKNOWN
         *buf++ = pipe->getc();
         unkn ++;
         len--;
     }
-    if (unkn != NOT_FOUND)                      return unkn; 
+    if (unkn != NOT_FOUND)                      
+        return unkn; 
     return WAIT;
 }
 
@@ -201,48 +209,36 @@
 // Serial Implementation 
 // ----------------------------------------------------------------
 
-GPSSerial::GPSSerial(PinName tx /*= GPSTXD*/, PinName rx /*= GPSRXD*/, int baudrate /*= GPSBAUD*/) : 
-            Serial(tx, rx, "gps"), _pipe(256)
+GPSSerial::GPSSerial(PinName tx /*= GPSTXD*/, PinName rx /*= GPSRXD*/, int baudrate /*= GPSBAUD*/,
+            int rxSize /*= 256*/, int txSize /*= 128*/) : 
+            SerialPipe(tx, rx, rxSize, txSize, "gps")
 {
-    attach(this, &GPSSerial::serialRxIrq, RxIrq);
     baud(baudrate);
 }
 
-GPSSerial::~GPSSerial(void)
-{
-    attach(NULL, RxIrq);
-}
-
-void GPSSerial::serialRxIrq(void)
-{
-    while (serial_readable(&_serial))
-        _pipe.putc(serial_getc(&_serial));
-}
-
 int GPSSerial::getMessage(char* buf, int len)
 {
-    return _getMessage(&_pipe, buf, len);   
+    return _getMessage(&_pipeRx, buf, len);   
 }
 
 char GPSSerial::next(void)
 { 
-    return _pipe.next(); 
+    return _pipeRx.next(); 
 }
 
 int GPSSerial::_send(const void* buf, int len)   
 { 
-    for (int i = 0; i < len; i ++)
-        putc(((char*)buf)[i]); 
-    return len; 
+    return put((const char*)buf, len, true/*=blocking*/); 
 }
 
 // ----------------------------------------------------------------
 // I2C Implementation 
 // ----------------------------------------------------------------
 
-GPSI2C::GPSI2C(PinName sda /*= GPSSDA*/, PinName scl /*= GPSSCL*/) : 
+GPSI2C::GPSI2C(PinName sda /*= GPSSDA*/, PinName scl /*= GPSSCL*/,
+            int rxSize /*= 256*/) : 
             I2C(sda,scl),
-            _pipe(256)
+            _pipe(rxSize)
 {
     found = false;
 }
--- a/GPS.h	Sat Nov 09 13:31:49 2013 +0000
+++ b/GPS.h	Sun Nov 10 16:39:42 2013 +0000
@@ -5,6 +5,9 @@
 #include "SerialPipe.h"
 #include "C027_PinNames.h"
 
+#define RX_SIZE 256
+#define TX_SIZE 128
+
 class GPSParser
 {
 public:
@@ -33,24 +36,23 @@
     static const char toHex[16];
 };
 
-class GPSSerial : public Serial, public GPSParser
+class GPSSerial : public SerialPipe, public GPSParser
 {
 public:
-    GPSSerial(PinName tx = GPSTXD, PinName rx = GPSRXD, int baudrate = GPSBAUD);
-    virtual ~GPSSerial(void);
+    GPSSerial(PinName tx = GPSTXD, PinName rx = GPSRXD, int baudrate = GPSBAUD,
+              int rxSize = RX_SIZE, int txSize = TX_SIZE);
     
     virtual int getMessage(char* buf, int len);
 protected:
-    void serialRxIrq(void);
     virtual char next(void);
     virtual int _send(const void* buf, int len);
-    Pipe<char> _pipe;
 };
 
 class GPSI2C : public I2C, public GPSParser
 {
 public: 
-    GPSI2C(PinName sda = GPSSDA, PinName scl = GPSSCL);
+    GPSI2C(PinName sda = GPSSDA, PinName scl = GPSSCL,
+           int rxSize = RX_SIZE);
     bool detect(void);
     
     virtual int getMessage(char* buf, int len);
@@ -59,6 +61,8 @@
     virtual int sendUbx(unsigned char cls, unsigned char id, const void* buf, int len);
 protected:
     virtual char next(void);
+    bool writeable(void) { return true; }
+    bool putc(int c)     { char ch = c; return send(&ch, 1); }
     virtual int _send(const void* buf, int len);
     int _get(char* buf, int len);                 // read the NMEA or UBX stream
     
--- a/Pipe.h	Sat Nov 09 13:31:49 2013 +0000
+++ b/Pipe.h	Sun Nov 10 16:39:42 2013 +0000
@@ -7,126 +7,150 @@
     inline int _inc(int i, int n = 1)
     {
         i += n;
-        if (i >= s)
-            i -= s;
+        if (i >= _s)
+            i -= _s;
         return i;
     }
 public:
-    Pipe(int n, T* p = NULL)
+    Pipe(int n, T* b = NULL)
     {
-        a = p ? NULL : new T[n];
-        r = 0;
-        w = 0;
-        b = p ? p : a;
-        s = n;
+        _a = b ? NULL : new T[n];
+        _r = 0;
+        _w = 0;
+        _b = b ? b : _a;
+        _s = n;
     }    
     virtual ~Pipe()
     {
-        if (a) 
-            delete [] a;
+        if (_a) 
+            delete [] _a;
     }
     // writing thread
     bool writeable(void) // = not full
     {
-        int i = _inc(w);
-        return (i = r);
+        return free() > 0;
     }
     int free(void)      // number of elements that can be added
     {
-        int t = r - w;
-        if (t <= 0)
-            t += s;
-        return t - 1;
+        int s = _r - _w;
+        if (s <= 0)
+            s += _s;
+        return s - 1;
     }
     void putc(T c)
     {
-        int i = w;
+        int i = _w;
         int j = i;
         i = _inc(i);
-        //assert(i != r);
-        b[j] = c;
-        w = i;   
+        while (i == _r) // = !writeable() 
+            /*wait for space*/;
+        _b[j] = c;
+        _w = i;   
     }
-    int put(T* p, int n)
+    int put(const T* p, int n, bool t = false)
     {
-        int f = free();
-        if (f < n)
-            n = f;
-        if (n)
+        int c = n;
+        while (c)
         {
-            int m = s - w;
-            if (m > n)
-                m = n;
-            memcpy(&b[w], &p[0], m);
-            int t = n - m;
-            if (t)
+            int f;
+            for (;;) // wait for space
             {
-                memcpy(&b[0], &p[m], t);
-                w = t;
+                f = free();
+                if (f)  break;        // data avail
+                if (!t) return n - c; // no more space and not blocking
             }
-            else 
-                w = _inc(w,m);
+            // check free space
+            if (c < f) f = c;
+            int w = _w;
+            int m = _s - w; 
+            // check wrap
+            if (f > m) f = m;
+            memcpy(&_b[w], p, f);
+            _w = _inc(w, f);
+            c -= f;
+            p += f;
         }
-        return n;
+        return n - c;
     }
     // reading thread 
     // --------------------------------------------------------
     //! check if there are any values available
     bool readable(void) // = not empty
     {
-        return (r != w);
+        return (_r != _w);
     }
     //! get the number of values avialable in the buffer 
     virtual int size(void)
     {
-        int t = w - r;
-        if (t < 0)
-            t += s;
-        return t;
+        int s = _w - _r;
+        if (s < 0)
+            s += _s;
+        return s;
     }
     //! get a value from buffer (this function will block if no values available)
     T getc(void)
     {
-        //while (r == w)
-        //    /* just wait until w changes*/;
-        T t = b[r];
-        r = _inc(r);
+        int r = _r;
+        while (r == _w) // = !readable()
+            /*wait for data*/;
+        T t = _b[r];
+        _r = _inc(r);
         return t;
     }
-    // get values from buffer (if the buffer has less values, only the values avilable are returned)
-    virtual int get(T* p, int n)
+    //! get values from buffer
+    virtual int get(T* p, int n, bool t = false)
     {
-        int f = size();
-        if (f < n)
-            n = f;
-        if (n)
+        int c = n;
+        while (c)
         {
-            int m = s - r;
-            if (m > n)
-                m = n;
-            memcpy(&p[0], &b[r], m);
-            int t = n - m;
-            if (t)
+            int f;
+            for (;;) // wait for data
             {
-                memcpy(&p[m] ,&b[0], t);
-                r = t;
+                f = size();
+                if (f)  break;        // free space
+                if (!t) return n - c; // no space and not blocking
             }
-            else 
-                r = _inc(r,m);
+            // check available data
+            if (c < f) f = c;
+            int r = _r;
+            int m = _s - r; 
+            // check wrap
+            if (f > m) f = m;
+            memcpy(p, &_b[r], f);
+            _r = _inc(r, f);
+            c -= f;
+            p += f;
         }
-        return n;
+        return n - c;
     }
+    
     // the following functions are useful if you like to inspect or parse the buffer
-    virtual int start(void) { o = r; return size(); }               // reset the parsing index and return the number of available elments
-    virtual T next(void)    { T t = b[o]; o = _inc(o); return t; }  // get the next element and increment
-    virtual void done(void) { r = o; }                              // commit the index 
+    
+    //! reset the parsing index and return the number of available elments 
+    virtual int start(void) 
+    {
+        _o = _r; 
+        return size(); 
+    }
+    //! get the next element and increment 
+    virtual T next(void)
+    {
+        int o = _o;
+        T t = _b[o]; 
+        _o = _inc(o); 
+        return t; 
+    }
+    //! commit the index 
+    virtual void done(void) 
+    {
+        _r = _o; 
+    } 
     
 private:
-    // buffer
-    T*            b; //!< buffer
-    T*            a; //!< allocated buffer
-    int           s; //!< size of buffer (s - 1) elements can be stored
-    volatile int  w; //! write index 
-    volatile int  r; //! read index 
-    int           o; //! offest index used by parsing functions  
+    T*            _b; //!< buffer
+    T*            _a; //!< allocated buffer
+    int           _s; //!< size of buffer (s - 1) elements can be stored
+    volatile int  _w; //!< write index 
+    volatile int  _r; //!< read index 
+    int           _o; //!< offest index used by parsing functions  
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialPipe.cpp	Sun Nov 10 16:39:42 2013 +0000
@@ -0,0 +1,98 @@
+#pragma once 
+
+#include "SerialPipe.h"
+
+SerialPipe::SerialPipe(PinName tx, PinName rx, int rxSize, int txSize, const char* name) 
+    : Serial(tx,rx,name), _pipeRx(rxSize), _pipeTx(txSize)
+{
+    attach(this, &SerialPipe::rxIrqBuf, RxIrq);
+    attach(this, &SerialPipe::txIrqBuf, TxIrq);
+}
+
+SerialPipe::~SerialPipe(void)
+{
+    attach(NULL, RxIrq);
+    attach(NULL, TxIrq);
+}
+
+// tx channel
+int SerialPipe::put(const char* b, int s, bool t)    
+{ 
+    int c = 0;
+    while (s && t)
+    {
+        c += _pipeTx.put(b, s, false);
+        b ++;
+        s --;
+        // give a chance to start tx
+        __disable_irq();
+        txIrqBuf();
+        __enable_irq();
+    }
+    return c;
+}
+
+void SerialPipe::txIrqBuf(void)
+{
+    while (serial_writable(&_serial) && _pipeTx.readable())
+        serial_putc(&_serial, _pipeTx.getc());
+}
+
+// rx channel
+int SerialPipe::readable(void)                      
+{ 
+    return _pipeRx.readable(); 
+} 
+
+int SerialPipe::getc(void)                          
+{ 
+    return _pipeRx.getc(); 
+} 
+
+int SerialPipe::get(char* b, int s, bool t) 
+{ 
+    return _pipeRx.get(b,s,t); 
+}
+
+void SerialPipe::rxIrqBuf(void)
+{
+    while (serial_readable(&_serial))
+    {
+        char ch = serial_getc(&_serial);
+        if (_pipeRx.writeable())
+            _pipeRx.putc(ch);
+        else 
+            /* overflow */;
+    }
+}
+
+// -----------------------------------------------------------------------
+
+SerialPipeEx::SerialPipeEx(PinName tx, PinName rx, int rxSize, int txSize, const char* name) 
+    : SerialPipe(tx,rx,rxSize,txSize,name)
+{}
+
+int SerialPipeEx::getLine(char* b, int s)
+{
+    int o = 0;
+    int i = 0;
+    int l = _pipeRx.start();
+    while ((i < l) && (o < s))
+    {
+        int t = _pipeRx.next();
+        i ++;
+        if (t == '\r')     // terminate commands with carriage return
+        {
+             _pipeRx.done();
+             return o;          // if enter send the zero char
+        }
+        else if (t == '\n')     // skip/filter new line 
+             /* skip */;
+        else if (t != '\b')     // normal char (no backspace)
+            b[o++] = t;
+        else if (o > 0)         // backspace
+            o --;               // remove it
+    }
+    o = 0;
+    return WAIT;
+}
--- a/SerialPipe.h	Sat Nov 09 13:31:49 2013 +0000
+++ b/SerialPipe.h	Sun Nov 10 16:39:42 2013 +0000
@@ -2,66 +2,34 @@
 
 #include "mbed.h"
 #include "Pipe.h"
-#include <ctype.h>
 
 class SerialPipe : public Serial
 {
-protected:
-    Pipe<char> _pipe;
+public:
+    SerialPipe(PinName tx, PinName rx, int rxSize = 128, int txSize = 128, const char* name = NULL);
+    virtual ~SerialPipe(void);
+    // tx channel
+    int put(const char* b, int s, bool t = false) ;
+    // rx channel
+    int readable(void);
+    int getc(void);
+    int get(char* b, int s, bool t = false);
 private:
-    void rxIrqBuf(void)
-    {
-        while (serial_readable(&_serial))
-            _pipe.putc(serial_getc(&_serial));
-    }
-public:
-    SerialPipe(PinName tx, PinName rx, int rxSize = 128, const char* name = NULL) 
-        : Serial(tx,rx,name), _pipe(rxSize)
-    {
-        attach(this, &SerialPipe::rxIrqBuf, RxIrq);
-    }
-    virtual ~SerialPipe(void)
-    {
-        attach(NULL, RxIrq);
-    }
-    // tx channel
-    int writeBuf(char* b, int s)    
-    { 
-        for (int i = 0; i < s; i ++)
-            putc(b[i]);
-        return s; 
-    }
-    // rx channel
-    int readable(void)              { return _pipe.readable() ? 1 : 0; } 
-    int getc(void)                  { return _pipe.getc(); } 
-    int readBuf(char* b, int s)     { return _pipe.get(b,s); }
+    void rxIrqBuf(void);
+    void txIrqBuf(void);
+protected:
+    Pipe<char> _pipeRx;
+    Pipe<char> _pipeTx;
+};
 
-    #define WAIT      -1
-    #define NOT_FOUND  0
+#define WAIT      -1
+#define NOT_FOUND  0
+
+// -----------------------------------------------------------------------
 
-    // special parsing
-    int getLine(char* b, int s)
-    {
-        int o = 0;
-        int i = 0;
-        int l = _pipe.start();
-        while ((i < l) && (o < s))
-        {
-            int t = _pipe.next();
-            i ++;
-            if (t == '\r')     // terminate commands with carriage return
-            {
-                 _pipe.done();
-                 return o;          // if enter send the zero char
-            }
-            else if (t == '\n')     // skip/filter new line 
-                 /* skip */;
-            else if (t != '\b')     // normal char (no backspace)
-                b[o++] = t;
-            else if (o > 0)         // backspace
-                o --;               // remove it
-        }
-        o = 0;
-        return WAIT;
-    }
+class SerialPipeEx : public SerialPipe
+{
+public:
+    SerialPipeEx(PinName tx, PinName rx, int rxSize = 128, int txSize = 128, const char* name = NULL);
+    int getLine(char* b, int s);
 };