vvvv
Revision 9:e7a5959ffae1, committed 2013-11-10
- 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
--- 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); };