C027_Support library plus AT Comand for dialing.
Fork of C027_Support_New by
SerialPipe.h
- Committer:
- mazgch
- Date:
- 2013-10-20
- Revision:
- 0:cb2d45baaca3
- Child:
- 2:b6012cd91657
File content as of revision 0:cb2d45baaca3:
#pragma once #include "Pipe.h" #include <ctype.h> class SerialPipe : public Serial { protected: Pipe<char> rxPipe; private: void rxIrqBuf(void) { while (serial_readable(&_serial)) rxPipe.putc(serial_getc(&_serial)); } public: SerialPipe(PinName tx, PinName rx, int rxSize = 128, const char* name = NULL) : Serial(tx,rx,name), rxPipe(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 rxPipe.readable() ? 1 : 0; } int getc(void) { return rxPipe.getc(); } int readBuf(char* b, int s) { return rxPipe.get(b,s); } #define WAIT -1 #define NOT_FOUND 0 // special parsing int getLine(char* b, int s) { int o = 0; int i = 0; int l = rxPipe.start(); while ((i < l) && (o < s)) { int t = rxPipe.next(); i ++; if (t == '\r') // terminate commands with carriage return { rxPipe.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; } static const char toHex[16]; #define UBX 0x100000 #define NMEA 0x200000 #define LENGTH(x) (x & 0x00FFFF) #define PROTOCOL(x) (x & 0xFF0000) // NMEA int parseNmea(int l) { int o = 0; rxPipe.start(); if (++o > l) return WAIT; if ('$' != rxPipe.next()) return NOT_FOUND; for (;;) { if (++o > l) return WAIT; int t = rxPipe.next(); if ('\n' == t) return o; if (!isprint(t) && '\r'!= t) return NOT_FOUND; } } const char* findNmeaItemPos(int i, const char* s, const char* e) { // find the start for (; (s < e) && (i > 0); s ++) { if (*s == ',') i --; } // found and check bounds if ((i == 0) && (s < e) && (*s != ',') && (*s != '*') && (*s != '\r') && (*s != '\n')) return s; else return NULL; } bool getNmeaItem(int i, char* b, int s, double& v) { char* e = &b[s]; const char* p = findNmeaItemPos(i, b, e); // find the start if (!p || (e <= p)) return false; char* t; // M$ specific - because the strtod function uses a strlen we make sure that // the string is zero terminated, this ensures correct behaviour of the function char ch = e[-1]; e[-1] = '\0'; v = strtod(p, &t); // restore the last character e[-1] = ch; return (t > p); } bool getNmeaItem(int i, const char* b, int s, int& v, int x /*=10*/) { const char* e = &b[s]; const char* p = findNmeaItemPos(i, b, e); // find the start if (!p) return false; char* t; v = (int)strtol(p, &t, x); return (t > p); } bool getNmeaItem(int i, const char* b, int s, char& ch) { const char* e = &b[s]; const char* p = findNmeaItemPos(i, b, e); // find the start if (!p) return false; // skip leading spaces while ((p < e) && isspace(*p)) p++; // check bound if ((p < e) && (*p != ',') && (*p != '*') && (*p != '\r') && (*p != '\n')) { ch = *p; return true; } return false; } int putNmea(const char* b, int len) { putc('$'); int c = 0; for (int i = 0; i < len; i ++) { int t = *b++; putc(t); c ^= t; } putc('*'); putc(toHex[(c >> 4) & 0xF]); putc(toHex[(c >> 0) & 0xF]); putc('\r'); putc('\n'); return len + 6; } int parseUbx(int l) { int o = 0; rxPipe.start(); if (++o > l) return WAIT; if ('\xB5' != rxPipe.next()) return NOT_FOUND; if (++o > l) return WAIT; if ('b' != rxPipe.next()) return NOT_FOUND; o += 4; if (o > l) return WAIT; int i,j,ca,cb; i = rxPipe.next(); ca = i; cb = ca; // cls i = rxPipe.next(); ca += i; cb += ca; // id i = rxPipe.next(); ca += i; cb += ca; // len_lsb j = rxPipe.next(); ca += j; cb += ca; // len_msb j = i + (j << 8); while (j--) { if (++o > l) return WAIT; i = rxPipe.next(); ca += i; cb += ca; } ca &= 0xFF; cb &= 0xFF; if (++o > l) return WAIT; if (ca != rxPipe.next()) return NOT_FOUND; if (++o > l) return WAIT; if (cb != rxPipe.next()) return NOT_FOUND; return o; } int putUbx(const unsigned char cls, unsigned char id, unsigned char* b, int len) { putc('\xB5'); // 'µ' putc('b'); int ca = cls, cb = cls; putc(cls); ca += id; cb += ca; putc(id); int t = (len >> 0) & 0xFF; ca += t; cb += ca; putc(t); t = (len >> 8) & 0xFF; ca += t; cb += ca; putc(t); for (int i = 0; i < len; i ++) { t = *b++; ca += t; cb += ca; putc(t); } putc(ca & 0xFF); putc(cb & 0xFF); return len + 8; } int getGPS(char* b, int s) { int g = 0; int l = rxPipe.size(); if (s > l) s = l; while (s > 0) { // NMEA protocol int n = parseNmea(s); if (n == WAIT) return g ? g : WAIT; if (n != NOT_FOUND) { if (g != NOT_FOUND) return g; else return NMEA | rxPipe.get(b,n); } // UBX protocol int u = parseUbx(s); if (u == WAIT) return g ? g : WAIT; if (u != NOT_FOUND) { if (g != NOT_FOUND) return g; else return UBX | rxPipe.get(b,u); } // UNKNOWN *b++ = rxPipe.getc(); g ++; s--; } if (g != NOT_FOUND) return g; return WAIT; } }; const char SerialPipe::toHex[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };