Serial Packet Handler
Dependencies: MbedJSONValue mbed
main.cpp@0:6080c5029b3f, 2018-01-15 (annotated)
- Committer:
- Arkadi
- Date:
- Mon Jan 15 10:40:06 2018 +0000
- Revision:
- 0:6080c5029b3f
- Child:
- 1:711a27baa42d
Serial Packet Handler
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Arkadi | 0:6080c5029b3f | 1 | //////////////////////////////////////// |
Arkadi | 0:6080c5029b3f | 2 | // Serial Packet - picojson // |
Arkadi | 0:6080c5029b3f | 3 | // Arkadiraf@gmail.com - 05/06/2017 // |
Arkadi | 0:6080c5029b3f | 4 | //////////////////////////////////////// |
Arkadi | 0:6080c5029b3f | 5 | /* |
Arkadi | 0:6080c5029b3f | 6 | Construct packet from uart and parse with json format |
Arkadi | 0:6080c5029b3f | 7 | json:<PACKET>\r\n |
Arkadi | 0:6080c5029b3f | 8 | */ |
Arkadi | 0:6080c5029b3f | 9 | |
Arkadi | 0:6080c5029b3f | 10 | /* |
Arkadi | 0:6080c5029b3f | 11 | Board : Nucleo STM32F446RE |
Arkadi | 0:6080c5029b3f | 12 | */ |
Arkadi | 0:6080c5029b3f | 13 | |
Arkadi | 0:6080c5029b3f | 14 | /* |
Arkadi | 0:6080c5029b3f | 15 | Pinout: |
Arkadi | 0:6080c5029b3f | 16 | PC - Serial 2 |
Arkadi | 0:6080c5029b3f | 17 | PA_2 (Tx) --> STLINK |
Arkadi | 0:6080c5029b3f | 18 | PA_3 (Rx) --> STLINK |
Arkadi | 0:6080c5029b3f | 19 | */ |
Arkadi | 0:6080c5029b3f | 20 | |
Arkadi | 0:6080c5029b3f | 21 | /////////////// |
Arkadi | 0:6080c5029b3f | 22 | // Libraries // |
Arkadi | 0:6080c5029b3f | 23 | /////////////// |
Arkadi | 0:6080c5029b3f | 24 | #include "mbed.h" |
Arkadi | 0:6080c5029b3f | 25 | #include "picojson.h" |
Arkadi | 0:6080c5029b3f | 26 | //#include "BufferedSerial.h" // uart handler library |
Arkadi | 0:6080c5029b3f | 27 | /////////////// |
Arkadi | 0:6080c5029b3f | 28 | // #defines // |
Arkadi | 0:6080c5029b3f | 29 | /////////////// |
Arkadi | 0:6080c5029b3f | 30 | |
Arkadi | 0:6080c5029b3f | 31 | #define DEBUG_MOD1 |
Arkadi | 0:6080c5029b3f | 32 | #define MSG_BUFFER_SIZE 512 |
Arkadi | 0:6080c5029b3f | 33 | #define HEADER_SIZE 5 |
Arkadi | 0:6080c5029b3f | 34 | #define FOOTER_SIZE 2 |
Arkadi | 0:6080c5029b3f | 35 | |
Arkadi | 0:6080c5029b3f | 36 | ///////////// |
Arkadi | 0:6080c5029b3f | 37 | // Objects // |
Arkadi | 0:6080c5029b3f | 38 | ///////////// |
Arkadi | 0:6080c5029b3f | 39 | |
Arkadi | 0:6080c5029b3f | 40 | // uart |
Arkadi | 0:6080c5029b3f | 41 | Serial pc(USBTX, USBRX); |
Arkadi | 0:6080c5029b3f | 42 | |
Arkadi | 0:6080c5029b3f | 43 | // digital output |
Arkadi | 0:6080c5029b3f | 44 | DigitalOut led(PA_5); |
Arkadi | 0:6080c5029b3f | 45 | /////////////// |
Arkadi | 0:6080c5029b3f | 46 | // variables // |
Arkadi | 0:6080c5029b3f | 47 | /////////////// |
Arkadi | 0:6080c5029b3f | 48 | |
Arkadi | 0:6080c5029b3f | 49 | // json buffer |
Arkadi | 0:6080c5029b3f | 50 | char json[MSG_BUFFER_SIZE]; |
Arkadi | 0:6080c5029b3f | 51 | |
Arkadi | 0:6080c5029b3f | 52 | // packet variables |
Arkadi | 0:6080c5029b3f | 53 | struct packetMSG_struct { |
Arkadi | 0:6080c5029b3f | 54 | // recieve message variables |
Arkadi | 0:6080c5029b3f | 55 | uint8_t header[HEADER_SIZE]; |
Arkadi | 0:6080c5029b3f | 56 | uint8_t footer[FOOTER_SIZE]; |
Arkadi | 0:6080c5029b3f | 57 | uint8_t syncIndex; // sync index for header / footer |
Arkadi | 0:6080c5029b3f | 58 | uint8_t syncFlag; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer |
Arkadi | 0:6080c5029b3f | 59 | // buffer |
Arkadi | 0:6080c5029b3f | 60 | uint16_t bufferIndex; // buffer index |
Arkadi | 0:6080c5029b3f | 61 | uint8_t buffer[MSG_BUFFER_SIZE]; |
Arkadi | 0:6080c5029b3f | 62 | } ; |
Arkadi | 0:6080c5029b3f | 63 | packetMSG_struct packetMSG; |
Arkadi | 0:6080c5029b3f | 64 | /////////////// |
Arkadi | 0:6080c5029b3f | 65 | // Functions // |
Arkadi | 0:6080c5029b3f | 66 | /////////////// |
Arkadi | 0:6080c5029b3f | 67 | |
Arkadi | 0:6080c5029b3f | 68 | // Serial Event function |
Arkadi | 0:6080c5029b3f | 69 | void rxCallback(void); |
Arkadi | 0:6080c5029b3f | 70 | |
Arkadi | 0:6080c5029b3f | 71 | // initialize packet struct |
Arkadi | 0:6080c5029b3f | 72 | void initPacket(void); |
Arkadi | 0:6080c5029b3f | 73 | //////////////////////// |
Arkadi | 0:6080c5029b3f | 74 | // Main Code Setup : // |
Arkadi | 0:6080c5029b3f | 75 | //////////////////////// |
Arkadi | 0:6080c5029b3f | 76 | int main() |
Arkadi | 0:6080c5029b3f | 77 | { |
Arkadi | 0:6080c5029b3f | 78 | // init packet: |
Arkadi | 0:6080c5029b3f | 79 | initPacket(); |
Arkadi | 0:6080c5029b3f | 80 | // init uart |
Arkadi | 0:6080c5029b3f | 81 | pc.baud(57600); |
Arkadi | 0:6080c5029b3f | 82 | // attach serial event interrupt |
Arkadi | 0:6080c5029b3f | 83 | pc.attach(&rxCallback, Serial::RxIrq); |
Arkadi | 0:6080c5029b3f | 84 | |
Arkadi | 0:6080c5029b3f | 85 | #ifdef DEBUG_MOD1 |
Arkadi | 0:6080c5029b3f | 86 | pc.printf("UART Test \r\n"); |
Arkadi | 0:6080c5029b3f | 87 | #endif |
Arkadi | 0:6080c5029b3f | 88 | /////////////////////// |
Arkadi | 0:6080c5029b3f | 89 | // Main Code Loop : // |
Arkadi | 0:6080c5029b3f | 90 | /////////////////////// |
Arkadi | 0:6080c5029b3f | 91 | while(1) { |
Arkadi | 0:6080c5029b3f | 92 | //sleep(); |
Arkadi | 0:6080c5029b3f | 93 | }// end main loop |
Arkadi | 0:6080c5029b3f | 94 | }// end main |
Arkadi | 0:6080c5029b3f | 95 | /////////////// |
Arkadi | 0:6080c5029b3f | 96 | // Functions // |
Arkadi | 0:6080c5029b3f | 97 | /////////////// |
Arkadi | 0:6080c5029b3f | 98 | |
Arkadi | 0:6080c5029b3f | 99 | // Serial Event function |
Arkadi | 0:6080c5029b3f | 100 | void rxCallback(void) |
Arkadi | 0:6080c5029b3f | 101 | { |
Arkadi | 0:6080c5029b3f | 102 | while (pc.readable()) { |
Arkadi | 0:6080c5029b3f | 103 | // read icoming |
Arkadi | 0:6080c5029b3f | 104 | led = !led; |
Arkadi | 0:6080c5029b3f | 105 | uint8_t in_byte = pc.getc(); |
Arkadi | 0:6080c5029b3f | 106 | #ifdef DEBUG_MOD1 |
Arkadi | 0:6080c5029b3f | 107 | pc.putc(in_byte); |
Arkadi | 0:6080c5029b3f | 108 | #endif |
Arkadi | 0:6080c5029b3f | 109 | // detect start message , end message |
Arkadi | 0:6080c5029b3f | 110 | switch (packetMSG.syncFlag) { |
Arkadi | 0:6080c5029b3f | 111 | // waiting for header |
Arkadi | 0:6080c5029b3f | 112 | case 0: { |
Arkadi | 0:6080c5029b3f | 113 | if (packetMSG.header[packetMSG.syncIndex] == in_byte) { |
Arkadi | 0:6080c5029b3f | 114 | packetMSG.syncIndex++; |
Arkadi | 0:6080c5029b3f | 115 | if (packetMSG.syncIndex == HEADER_SIZE) { // finish header SYNC |
Arkadi | 0:6080c5029b3f | 116 | packetMSG.syncFlag = 1; // start collecting data, wait for footer |
Arkadi | 0:6080c5029b3f | 117 | packetMSG.bufferIndex = 0; |
Arkadi | 0:6080c5029b3f | 118 | packetMSG.syncIndex=0; |
Arkadi | 0:6080c5029b3f | 119 | } |
Arkadi | 0:6080c5029b3f | 120 | } else { // reinit sync |
Arkadi | 0:6080c5029b3f | 121 | packetMSG.syncIndex=0; |
Arkadi | 0:6080c5029b3f | 122 | } |
Arkadi | 0:6080c5029b3f | 123 | //pc.printf("case 0 , %d \r\n",packetMSG.syncIndex); |
Arkadi | 0:6080c5029b3f | 124 | break; |
Arkadi | 0:6080c5029b3f | 125 | |
Arkadi | 0:6080c5029b3f | 126 | } // waiting for header |
Arkadi | 0:6080c5029b3f | 127 | |
Arkadi | 0:6080c5029b3f | 128 | // waiting for footer |
Arkadi | 0:6080c5029b3f | 129 | case 1: { |
Arkadi | 0:6080c5029b3f | 130 | // add byte to buffer |
Arkadi | 0:6080c5029b3f | 131 | packetMSG.buffer[packetMSG.bufferIndex] = in_byte; |
Arkadi | 0:6080c5029b3f | 132 | packetMSG.bufferIndex++; |
Arkadi | 0:6080c5029b3f | 133 | if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow |
Arkadi | 0:6080c5029b3f | 134 | // reset buffer |
Arkadi | 0:6080c5029b3f | 135 | packetMSG.bufferIndex = 0; |
Arkadi | 0:6080c5029b3f | 136 | packetMSG.syncIndex = 0; |
Arkadi | 0:6080c5029b3f | 137 | packetMSG.syncFlag = 0; |
Arkadi | 0:6080c5029b3f | 138 | } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved |
Arkadi | 0:6080c5029b3f | 139 | packetMSG.syncIndex++; |
Arkadi | 0:6080c5029b3f | 140 | packetMSG.syncFlag=2; // move to verify footer |
Arkadi | 0:6080c5029b3f | 141 | } |
Arkadi | 0:6080c5029b3f | 142 | //pc.printf("case 2 , %d \r\n",packetMSG.syncIndex); |
Arkadi | 0:6080c5029b3f | 143 | break; |
Arkadi | 0:6080c5029b3f | 144 | } // waiting for footer |
Arkadi | 0:6080c5029b3f | 145 | |
Arkadi | 0:6080c5029b3f | 146 | // verify footer |
Arkadi | 0:6080c5029b3f | 147 | case 2: { |
Arkadi | 0:6080c5029b3f | 148 | // add byte to buffer |
Arkadi | 0:6080c5029b3f | 149 | packetMSG.buffer[packetMSG.bufferIndex] = in_byte; |
Arkadi | 0:6080c5029b3f | 150 | packetMSG.bufferIndex++; |
Arkadi | 0:6080c5029b3f | 151 | if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow |
Arkadi | 0:6080c5029b3f | 152 | // reset buffer |
Arkadi | 0:6080c5029b3f | 153 | packetMSG.bufferIndex = 0; |
Arkadi | 0:6080c5029b3f | 154 | packetMSG.syncIndex = 0; |
Arkadi | 0:6080c5029b3f | 155 | packetMSG.syncFlag = 0; |
Arkadi | 0:6080c5029b3f | 156 | } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved |
Arkadi | 0:6080c5029b3f | 157 | packetMSG.syncIndex++; |
Arkadi | 0:6080c5029b3f | 158 | if (packetMSG.syncIndex == FOOTER_SIZE) { // finish footer SYNC |
Arkadi | 0:6080c5029b3f | 159 | packetMSG.syncFlag = 3; |
Arkadi | 0:6080c5029b3f | 160 | |
Arkadi | 0:6080c5029b3f | 161 | // copy packet to json buffer - failed attempt |
Arkadi | 0:6080c5029b3f | 162 | //char *json = (char*) malloc(packetMSG.bufferIndex+1); |
Arkadi | 0:6080c5029b3f | 163 | memcpy (&json, &packetMSG.buffer, packetMSG.bufferIndex); |
Arkadi | 0:6080c5029b3f | 164 | json[packetMSG.bufferIndex]=NULL; // end NULL to indicate end of string |
Arkadi | 0:6080c5029b3f | 165 | |
Arkadi | 0:6080c5029b3f | 166 | // copy packet to json buffer with sprintf |
Arkadi | 0:6080c5029b3f | 167 | //sprintf(json, "%.*s", packetMSG.bufferIndex, packetMSG.buffer ); |
Arkadi | 0:6080c5029b3f | 168 | |
Arkadi | 0:6080c5029b3f | 169 | // send msg to parse. |
Arkadi | 0:6080c5029b3f | 170 | pc.printf("%d, %.*s", packetMSG.bufferIndex ,packetMSG.bufferIndex, packetMSG.buffer ); |
Arkadi | 0:6080c5029b3f | 171 | pc.printf("%d, %s", sizeof(json), json); |
Arkadi | 0:6080c5029b3f | 172 | //free(json); |
Arkadi | 0:6080c5029b3f | 173 | // reset buffer |
Arkadi | 0:6080c5029b3f | 174 | packetMSG.bufferIndex = 0; |
Arkadi | 0:6080c5029b3f | 175 | packetMSG.syncIndex = 0; |
Arkadi | 0:6080c5029b3f | 176 | packetMSG.syncFlag = 0; |
Arkadi | 0:6080c5029b3f | 177 | } |
Arkadi | 0:6080c5029b3f | 178 | } else { // footer broke restart wait for footer |
Arkadi | 0:6080c5029b3f | 179 | packetMSG.syncFlag=1; |
Arkadi | 0:6080c5029b3f | 180 | // verify that it didnt broke on first footer char |
Arkadi | 0:6080c5029b3f | 181 | if (packetMSG.footer[0] == in_byte) { |
Arkadi | 0:6080c5029b3f | 182 | packetMSG.syncIndex=1; |
Arkadi | 0:6080c5029b3f | 183 | } else { |
Arkadi | 0:6080c5029b3f | 184 | packetMSG.syncIndex=0; |
Arkadi | 0:6080c5029b3f | 185 | } |
Arkadi | 0:6080c5029b3f | 186 | } |
Arkadi | 0:6080c5029b3f | 187 | break; |
Arkadi | 0:6080c5029b3f | 188 | |
Arkadi | 0:6080c5029b3f | 189 | } // verify footer |
Arkadi | 0:6080c5029b3f | 190 | default: { |
Arkadi | 0:6080c5029b3f | 191 | pc.printf("Sonmething went wrong \r\n"); |
Arkadi | 0:6080c5029b3f | 192 | break; |
Arkadi | 0:6080c5029b3f | 193 | } |
Arkadi | 0:6080c5029b3f | 194 | } // end switch |
Arkadi | 0:6080c5029b3f | 195 | }// end uart readable |
Arkadi | 0:6080c5029b3f | 196 | } // end rxCallback |
Arkadi | 0:6080c5029b3f | 197 | |
Arkadi | 0:6080c5029b3f | 198 | |
Arkadi | 0:6080c5029b3f | 199 | // initialize packet struct |
Arkadi | 0:6080c5029b3f | 200 | void initPacket(void) |
Arkadi | 0:6080c5029b3f | 201 | { |
Arkadi | 0:6080c5029b3f | 202 | // init variables to default: |
Arkadi | 0:6080c5029b3f | 203 | packetMSG.header[0] = 'j'; |
Arkadi | 0:6080c5029b3f | 204 | packetMSG.header[1] = 's'; |
Arkadi | 0:6080c5029b3f | 205 | packetMSG.header[2] = 'o'; |
Arkadi | 0:6080c5029b3f | 206 | packetMSG.header[3] = 'n'; |
Arkadi | 0:6080c5029b3f | 207 | packetMSG.header[4] = ':'; |
Arkadi | 0:6080c5029b3f | 208 | |
Arkadi | 0:6080c5029b3f | 209 | packetMSG.footer[0]= 13; // /r |
Arkadi | 0:6080c5029b3f | 210 | packetMSG.footer[1]= 10; // /n |
Arkadi | 0:6080c5029b3f | 211 | |
Arkadi | 0:6080c5029b3f | 212 | packetMSG.syncIndex=0; // sync index for header / footer |
Arkadi | 0:6080c5029b3f | 213 | packetMSG.syncFlag=0; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer |
Arkadi | 0:6080c5029b3f | 214 | packetMSG.bufferIndex=0; // buffer index |
Arkadi | 0:6080c5029b3f | 215 | } |