Hideaki Tai / IM920
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers IM920.h Source File

IM920.h

00001 #pragma once
00002 #include "mbed.h"
00003 #include <queue>
00004 
00005     #define kAsciiCR    0x0D
00006     #define kAsciiLF    0x0A
00007     
00008 class IM920 : public Serial
00009 {
00010     typedef enum StateIm920 {
00011         kStateNode = 0,
00012         kStateParentId,
00013         kStateRssi,
00014         kStateData,
00015         kStateCRLF
00016     } StateIm920;
00017     
00018     typedef struct Im920Packet {
00019         int node;
00020         int parent_id;
00021         int rssi;
00022         int data[8];
00023     } Im920Packet;
00024     
00025     typedef struct Im920PacketAscii {
00026         char node[3];
00027         char parent_id[5];
00028         char rssi[3];
00029         char data[8][3];
00030     } Im920PacketAscii;
00031 
00032 public:
00033 
00034     IM920(PinName tx, PinName rx, int baudrate)
00035     : mbed::Serial(tx, rx)
00036     , pc(NULL)
00037     {
00038         this->baud(baudrate);
00039         this->attach(this, &IM920::push_byte);
00040     }
00041     virtual ~IM920()
00042     {
00043         if (pc) delete pc;
00044     }
00045     
00046     void push_byte() { byte_buff.push(this->getc()); }
00047     void pop_byte() { byte_buff.pop(); }
00048     
00049     void pop() { readBuffer_.pop(); }
00050     
00051     int  available()      { return (int)readBuffer_.size(); }
00052     
00053     void dump()
00054     {
00055         while(byte_buff.size())
00056         {
00057             if(pc) pc->printf("%c", (char)byte_buff.front());
00058             byte_buff.pop();
00059         }
00060     }
00061 
00062     virtual void setDebugSerial(Serial* s) { pc = s; }
00063     
00064     void send(const char* format) 
00065     { this->Serial::printf(format); }
00066     template <typename A>
00067     void send(const char* format, A &a) 
00068     { this->Serial::printf(format, a); }
00069     template <typename A, typename B>
00070     void send(const char* format, A &a, B &b) 
00071     { this->Serial::printf(format, a, b); }
00072     template <typename A, typename B, typename C>
00073     void send(const char* format, A &a, B &b, C &c) 
00074     { this->Serial::printf(format, a, b, c); }
00075     
00076     const Im920Packet& getPacket() { return readBuffer_.front(); }
00077     const int&  getNwNode()      { return readBuffer_.front().node; }
00078     const int&  getNwParentId()  { return readBuffer_.front().parent_id; }
00079     const int&  getNwRssi()      { return readBuffer_.front().rssi; }
00080     const int* getDataPtr()     { return (int*)readBuffer_.front().data; }
00081     uint8_t  getData(int idx) { return readBuffer_.front().data[idx]; }
00082     
00083     void enableWriteFlash() { send("ENWR\r\n"); }
00084     void disableWriteFlash() { send("DSWR\r\n"); }
00085     void deleteParentId() { send("ERID\r\n"); }
00086     void writeParentId(int id) { send("SRID %04x\r\n", id); }
00087     void requestParentId() { send("RRID\r\n"); }
00088     void writeWirelessPower(int n) { send("STPO %1d\r\n", n); }
00089     void writeWirelessSpeed(int n) { send("STRT %1d\r\n", n); }
00090     void writeBaudrate(int n) { send("SBRT %1d\r\n", n); }
00091     void writeChannel(int n) { send("STCH %02d\r\n", n); }
00092     void reset() { send("SRST\r\n"); }
00093     
00094     void dumpPacket()
00095     {
00096         if(available())
00097         {
00098             if(pc)
00099             {
00100                 Im920Packet& p = readBuffer_.front();
00101                 pc->printf("packet dump >> %02x,%04x,%02x:", p.node, p.parent_id, p.rssi);
00102                 for (int i=0; i<7; i++) pc->printf("%02x,", p.data[i]);
00103                 pc->printf("%02x\r\n", p.data[7]);
00104             }
00105             readBuffer_.pop();
00106         }
00107         else
00108             if(pc) pc->printf("[Error] No Packet Available!!\n");
00109     }
00110     
00111     void parse()
00112     {
00113         if (byte_buff.size() <= 0)  return;
00114 
00115         static bool bUnderParsing = false;
00116         static int cnt = 0;
00117         static int dcnt = 0;
00118         static Im920PacketAscii pa;
00119         static StateIm920 state = kStateNode;
00120 
00121         while (byte_buff.size() > 0)
00122         {
00123             char data = (char)byte_buff.front();
00124             
00125             if (isCorrupted((int)data)) {
00126                 state = kStateNode;
00127                 bUnderParsing = false;
00128                 return;
00129             }
00130             
00131             if (!bUnderParsing)
00132             {
00133                 for (int i=0; i<5; i++) pa.parent_id[i] = (char)0;
00134                 for (int i=0; i<3; i++) {
00135                     pa.node[i] = pa.rssi[i] = (char)0;
00136                     for (int j=0; j<8; j++) pa.data[j][i] = (char)0;
00137                 }
00138                 dcnt = cnt = 0;
00139                 bUnderParsing = true;
00140             }
00141 
00142             switch(state)
00143             {
00144                 case kStateNode:
00145                 {
00146                     if (data == ',') {
00147                         state = kStateParentId;
00148                         dcnt = cnt = 0;
00149                     } else {
00150                         pa.node[cnt++] = data;
00151                     }
00152                     break;
00153                 }
00154                 case kStateParentId:
00155                 {
00156                     if (data == ',') {
00157                         state = kStateRssi;
00158                         dcnt = cnt = 0;
00159                     } else {
00160                         pa.parent_id[cnt++] = data;
00161                     }
00162                     break;
00163                 }
00164                 case kStateRssi:
00165                 {
00166                     if (data == ':') {
00167                         state = kStateData;
00168                         dcnt = cnt = 0;
00169                     } else {
00170                         pa.rssi[cnt++] = data;
00171                     }
00172                     break;
00173                 }
00174                 case kStateData:
00175                 {
00176                     if (data == ',') {
00177                         ++dcnt;
00178                         cnt = 0;
00179                     } else if (data == (char)kAsciiCR) {
00180                         state = kStateCRLF;
00181                     } else {
00182                         pa.data[dcnt][cnt++] = data;
00183                     }
00184                     break;
00185                 }
00186                 case kStateCRLF:
00187                 {
00188                     if (data == (char)kAsciiLF)
00189                     {
00190                         Im920Packet p;
00191                         p.node = (int)strtol(pa.node, NULL, 16);
00192                         p.parent_id = (int)strtol(pa.parent_id, NULL, 16);
00193                         p.rssi = (int)strtol(pa.rssi, NULL, 16);
00194                         for (int i = 0; i < 8; i++) {
00195                             p.data[i] = (int)strtol(pa.data[i], NULL, 16);
00196                         }
00197                         readBuffer_.push(p);
00198 //        std::queue<int>().swap(q)
00199                     }
00200                     else
00201                     {
00202                         if(pc) pc->printf("invalid data order!!!\n");
00203                     }
00204                     state = kStateNode;
00205                     bUnderParsing = false;
00206                     dcnt = cnt = 0;
00207                     
00208                     break;
00209                 }
00210                 default:
00211                 {
00212                     state = kStateNode;
00213                     bUnderParsing = false;
00214                     dcnt = cnt = 0;
00215                     break;
00216                 }
00217             }
00218             pop_byte();
00219         }
00220     }    
00221 
00222     
00223 private:
00224     bool isCorrupted(int ascii)
00225     {
00226         bool isCRLF = ((ascii == 13) || (ascii == 10)) ? true : false;
00227         bool isPunctuation = ((ascii == 44) || (ascii == 58)) ? true : false;
00228         bool is0to9 = ((ascii >= 48) && (ascii <= 57)) ? true : false;
00229         bool isAtoF = ((ascii >= 65) && (ascii <= 70)) ? true : false;
00230         if (!(isCRLF || isPunctuation || is0to9 || isAtoF)) {
00231             if(pc) pc->printf("Invalid Ascii!\r\n");
00232             return true;
00233         }
00234         return false;
00235     }
00236     
00237     queue<uint8_t> byte_buff;
00238     queue<Im920Packet> readBuffer_;
00239     Serial* pc;
00240 };
00241 
00242