EEP fORK

Dependencies:   BLE_API mbed nRF51822

Fork of MCS_LRF by Farshad N

Revision:
6:09cdafc3ffeb
Parent:
5:207d4b6dface
Child:
7:8a23a257b66a
--- a/main.cpp	Fri Oct 16 03:10:47 2015 +0000
+++ b/main.cpp	Mon Nov 09 04:47:27 2015 +0000
@@ -19,6 +19,9 @@
 #include "BLE.h"
 #include "DeviceInformationService.h"
 #include "UARTService.h"
+#include "CircularBuffer.h"
+
+#undef BLE_DEBUG_OUTPUT
 
 #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
 * it will have an impact on code-size and power consumption. */
@@ -31,7 +34,6 @@
 #define DEBUG(...) { pc.printf(__VA_ARGS__); }
 #else
 #define DEBUG(...) /* nothing */
-#define TRACE(...)
 #endif /* #if NEED_CONSOLE_OUTPUT */
 
 #if NEED_PARSE_TRACE
@@ -46,9 +48,9 @@
 
 DigitalOut trigger(p18);
 
-#undef NORDIC  // is board nordic DK?
+#define NORDIC  // is board nordic DK?
 
-#if NORDIC
+#ifdef NORDIC
 DigitalOut connectionLed(p21);
 DigitalOut triggerLed(p22);
 DigitalOut shutdown(p20);  // for nordic DK
@@ -106,15 +108,17 @@
     READIG_TAG_CRC
 } packetState_e;
 
+//CircularBuffer cb;
+
 static uint8_t tagEPC[TAG_EPC_BUF_SIZE] = {0};
 static packetState_e state = AWAITING_PREAMBLE;
 static uint8_t tagBufIndex = 0;
-//static uint8_t skip = 0;
+static uint8_t skip = 0;
 static uint16_t tagLen = 0;
 //static uint16_t dataLen = 0;
 
 // the preamble before 96 bit EPC tag data- we look for this before reading the EPC data 
-static uint8_t preamble[] = {0x00, 0x80, 0x30, 0x00};
+static uint8_t preamble[] = {0x00, 0x80};
 static uint8_t preambleIdx = 0;
 
 // commmands to initialize the Nano RFID reader- sniffied from coms going from the base edge device to the Nano reader
@@ -181,137 +185,11 @@
     connectionLed = isConnected;
 }
 
-static void sendBLENotification()
-{
-    uint8_t buf[READ_BUF_SIZE];
-    uint8_t offset = 0;
-    memcpy(buf, &tagIdCmd, sizeof(uint16_t));       // command
-    offset+=sizeof(uint16_t);
-    memcpy(&buf[offset], &tagLen, sizeof(uint16_t));     // length of array
-    offset+=sizeof(uint16_t);
-    memcpy(&buf[offset], &tagEPC, tagLen);              // tag EPC
-    offset+= tagLen;
-    ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), buf, offset);
-}
-
-
-static void processData(const GattWriteCallbackParams *params)
-{
-    if(params->len >= 2) {
-        uint16_t command = params->data[0] + (params->data[1] << 8);
-        bool isSetCmd = (command & SET_PARAM_CMD_MASK) == SET_PARAM_CMD_MASK;
-        DEBUG("command: %d   \r\n", command);
-
-        switch(command & ~SET_PARAM_CMD_MASK) {
-            case tagIdCmd:
-                if(!isSetCmd && params->len == 2) {
-                    // form the reply to send
-                    DEBUG("CMD is GET code\n\r");
-                    // TODO can do a trigger for a new read before transimiting, For now just send the latest read
-                    sendBLENotification();
-                }
-                break;
-
-            case hardwareTriggerCmd:
-                if(isSetCmd && params->len == 3) {
-                    DEBUG("CMD is SET hardwareTriggerCmd\n\r");
-                    trigger = 0;
-                    triggerLed = 1;
-                    wait_ms(100);
-                    trigger = 1;
-                    triggerLed = 0;
-                }
-                break;
-
-            case softwareTriggerCmd:
-                if(isSetCmd && params->len == 3) {      // TODO this command does not need a value
-                    DEBUG("CMD is SET softwareTriggerCmd\n\r");
-                    triggerLed = 1;
-                    for(int i = 0; i < sizeof(readCommands) / sizeof(command_t); i++) {
-                        uint8_t* d = readCommands[i].data;
-                        uint8_t len = readCommands[i].len;
-                        for(int j = 0; j < len; j++) {
-                            // DEBUG("%02X ", d[j]);
-                            reader.putc(d[j]);
-                        }
-                        wait_ms(readCommands[i].delayms);                        
-                        DEBUG("\r\n ");
-                    }
-                    triggerLed = 0;
-                }
-                break;
-
-            default:
-                break;
-        }
-    }
-}
-
-void onDataWritten(const GattWriteCallbackParams *params)
-{
-    if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
-        uint16_t bytesRead = params->len;
-        DEBUG("received %u bytes\n\r", bytesRead);
-        for(int i = 0; i < bytesRead; i++) {
-            DEBUG("0x%X ", params->data[i]);
-        }
-        DEBUG("\n\r", bytesRead);
-
-        // echo?
-        // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
-
-        processData(params);
-    }
-}
-
-// State machine to parse the tag data received from serial port. It only looks for EPC data in the packet
-static void parsePacket(uint8_t d)
-{
-    //  TRACE("%02X ", d);
-    tagLen = 12;
-    switch (state) {
-        case AWAITING_PREAMBLE:
-            if(d == preamble[preambleIdx]) {
-                preambleIdx++;
-                if(preambleIdx == sizeof(preamble)) {
-                    state = READING_TAG_EPC;
-                }
-            } else {
-                preambleIdx = 0;
-            }
-            break;
-
-        case READING_TAG_EPC:
-            if(tagBufIndex < tagLen) {
-                tagEPC[tagBufIndex++] = d;
-                TRACE("%02X ", d);
-            } else {
-                // don't worry about CRC for now
-                state = AWAITING_PREAMBLE;
-                preambleIdx = 0;
-                tagBufIndex = 0;
-                TRACE("AWAITING_PREAMBLE \r\n");
-
-                TRACE("TAG EPC: ============\r\n");
-                for(int i = 0; i < tagLen; i++) {
-                    TRACE("%02X ", tagEPC[i]);
-                    //      pc.printf("%02X ", tagEPC[i]);
-                }
-                // pc.printf("\r\n");
-
-                sendBLENotification();
-                triggerLed = 0;
-            }
-
-            break;
-    }
-}
-
 
 //// State machine to parse the tag data received from serial port. It only looks for EPC data in the packet
 //static void parsePacket_2(uint8_t d)
 //{
-//  //  TRACE("%02X ", d);
+////  //  TRACE("%02X ", d);
 //    switch (state) {
 //        case AWAITING_HEADER:
 //            if(d == HEADER_FLAG) {
@@ -375,14 +253,16 @@
 //            break;
 //
 //        case AWAITING_PC_WORD:
-//            if((tagLen == 8 && d == BIT_64_TAG_PC_WORD) || (tagLen == 12 && d == BIT_96_TAG_PC_WORD)) {
+////            if((tagLen == 8 && d == BIT_64_TAG_PC_WORD) || (tagLen == 12 && d == BIT_96_TAG_PC_WORD)) 
+//                {
 //                state = READING_TAG_EPC;
 //                tagBufIndex = 0;
 //                TRACE("READING_TAG_EPC \r\n");
 //                skip = 0;
-//            } else {
-//                state = AWAITING_HEADER;
-//            }
+//            } 
+//            //else {
+////                state = AWAITING_HEADER;
+////            }
 //            break;
 //
 //        case READING_TAG_EPC:
@@ -409,18 +289,234 @@
 //    }
 //}
 
+uint16_t idx = 0;
+const uint16_t storeSize = 300;
+uint8_t store[storeSize];
+bool reading = false;
+bool sending = false;
 
+typedef enum{
+    PS_FIRST_AND_ONLY =     0b0000000000000000,
+    PS_FIRST_AND_NOT_LAST = 0b0010000000000000,
+    PS_LAST =               0b0100000000000000,
+    PS_MIDDLE =             0b0110000000000000
+} PacketStatus_e;
+
+static PacketStatus_e packetStatus = PS_FIRST_AND_ONLY;
+
+static void sendOverBLE(uint16_t cmd, uint8_t data[], uint16_t len, PacketStatus_e status){
+    
+    if(len > 16){ 
+        // this is a problem
+    }
+    
+    uint8_t buf[len + 4];        // should set it to the max single packet size
+    uint8_t offset = 0;
+    uint16_t tmp = cmd | (uint16_t)status;
+    memcpy(buf, &tmp, sizeof(uint16_t));       // command
+    offset+=sizeof(uint16_t);
+    memcpy(&buf[offset], &len, sizeof(uint16_t));     // length of array
+    offset+=sizeof(uint16_t);
+    memcpy(&buf[offset], &data[0], len);              // data
+    offset+= len;
+    ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), buf, offset);
+}
+
+static void sendPacketOverBLE(uint16_t cmd, uint8_t data[], uint16_t len)
+{
+    uint8_t nPackets = (len / 17) + 1;
+    uint8_t remainingPackets = nPackets;
+    uint16_t offset = 0;
+    bool first = true;
+    const uint8_t maxDataPayload = 16;   // max is 20 but we are sending a command (2) plus the length (2)
+
+    do {
+        if(nPackets == 1) {
+            // first and only
+            packetStatus = PS_FIRST_AND_ONLY;
+            sendOverBLE(cmd, &data[offset], len, packetStatus);
+            remainingPackets = 0;
+        } else if(remainingPackets == 1) {
+            // last one
+            packetStatus = PS_LAST;
+            sendOverBLE(cmd, &data[offset], len-offset, packetStatus);
+            remainingPackets = 0;
+        } else if(remainingPackets > 1 && first == true) {
+            // first and more to come
+            packetStatus = PS_FIRST_AND_NOT_LAST;
+            sendOverBLE(cmd, &data[offset], maxDataPayload, packetStatus);
+            offset += maxDataPayload;
+            remainingPackets -= 1;
+            first = false;
+        } else if(remainingPackets > 1 && first == false) {
+            // middle
+            packetStatus = PS_MIDDLE;
+            sendOverBLE(cmd, &data[offset], maxDataPayload, packetStatus);
+            offset += maxDataPayload;
+            remainingPackets -= 1;
+        }
+        
+        wait_ms(50);        // 40ms delay seems to be a limit
+    } while (remainingPackets > 0);
+}
+
+
+static void processData(const GattWriteCallbackParams *params)
+{
+    if(params->len >= 2) {
+        uint16_t command = params->data[0] + (params->data[1] << 8);
+        bool isSetCmd = (command & SET_PARAM_CMD_MASK) == SET_PARAM_CMD_MASK;
+        DEBUG("command: %d   \r\n", command);
+
+        switch(command & ~SET_PARAM_CMD_MASK) {
+            case tagIdCmd:
+                if(!isSetCmd && params->len == 2) {
+                    // form the reply to send
+                    DEBUG("CMD is GET code\n\r");
+                    // TODO can do a trigger for a new read before transimiting, For now just send the latest read
+                     sendPacketOverBLE(tagIdCmd, tagEPC, tagLen);
+                }
+                break;
+
+            case hardwareTriggerCmd:
+                if(isSetCmd && params->len == 3) {
+                    DEBUG("CMD is SET hardwareTriggerCmd\n\r");
+                    trigger = 0;
+                    triggerLed = 1;
+                    wait_ms(100);
+                    trigger = 1;
+                    triggerLed = 0;
+                }
+                break;
+
+            case softwareTriggerCmd:
+                if(isSetCmd && params->len == 3) {      // TODO this command does not need a value
+                    DEBUG("CMD is SET softwareTriggerCmd\n\r");
+                    triggerLed = 1;
+                    for(int i = 0; i < sizeof(readCommands) / sizeof(command_t); i++) {
+                        uint8_t* d = readCommands[i].data;
+                        uint8_t len = readCommands[i].len;
+                        for(int j = 0; j < len; j++) {
+                            // DEBUG("%02X ", d[j]);
+                            reader.putc(d[j]);
+                        }
+                        wait_ms(readCommands[i].delayms);                        
+                        DEBUG("\r\n ");
+                    }
+                    triggerLed = 0;
+                }
+                break;
+
+            default:
+                break;
+        }
+    }
+}
+
+void onDataWritten(const GattWriteCallbackParams *params)
+{
+    if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
+        uint16_t bytesRead = params->len;
+        DEBUG("received %u bytes\n\r", bytesRead);
+        for(int i = 0; i < bytesRead; i++) {
+            DEBUG("0x%X ", params->data[i]);
+        }
+        DEBUG("\n\r", bytesRead);
+
+        // echo?
+        // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
+
+        processData(params);
+    }
+}
+
+// State machine to parse the tag data received from serial port. It only looks for EPC data in the packet
+static void parsePacket(uint8_t d)
+{
+    TRACE("%02X ", d);
+
+    tagLen = 12;
+    switch (state) {
+        case AWAITING_PREAMBLE:
+            // if(d == preamble[preambleIdx] || preambleIdx > 1) {
+            if(d == preamble[preambleIdx]) {
+                preambleIdx++;
+                if(preambleIdx == sizeof(preamble)) {
+                    state = READING_TAG_EPC;
+                    skip = 0;
+                }
+            } else {
+                preambleIdx = 0;
+            }
+            break;
+
+        case READING_TAG_EPC:
+            if(++skip > SKIP_TO_TAG_EPC) {
+                if(tagBufIndex < tagLen) {
+                    tagEPC[tagBufIndex++] = d;
+                    TRACE("%02X ", d);
+                } else {
+                    // don't worry about CRC for now
+                    state = AWAITING_PREAMBLE;
+                    preambleIdx = 0;
+                    tagBufIndex = 0;
+                    TRACE("AWAITING_PREAMBLE \r\n");
+
+                    TRACE("TAG EPC: ============\r\n");
+                    for(int i = 0; i < tagLen; i++) {
+                        TRACE("%02X ", tagEPC[i]);
+                        //      pc.printf("%02X ", tagEPC[i]);
+                    }
+                    // pc.printf("\r\n");
+
+                    sendPacketOverBLE(tagIdCmd, tagEPC, tagLen);
+                    triggerLed = 0;
+                }
+            }
+
+            break;
+    }
+}
+
+
+uint16_t length;
+//uint8_t tempBuf[1000];
 void periodicCallback(void)
 {
-    triggerLed = 0;
+    #ifdef BLE_DEBUG_OUTPUT
+    //for( idx = 0; idx < 64; idx++){         // 64 is the limit
+//        store[idx] = idx;
+//    }
+     
+    if(reading == false) {
+        if(idx > 0) {
+            sending = true;
+            length = idx;            
+            //memcpy(&tempBuf[0], &store[0], idx);                    
+            sendPacketOverBLE(tagIdCmd, store, idx);
+            idx = 0;        // now that we have sent this, reset the index
+        }
+    }
+#endif
+
+    sending = false;
 }
 
 // this is an ISR, so do not spend too much time here and be careful with printing debug info
 void readerCallback()
-{
+{    
     // Note: Need to actually read from the serial to clear the RX interrupt
-    while(reader.readable()) {
-        parsePacket(reader.getc());
+    if(sending == false) {
+        reading = true;
+        while(reader.readable()) {
+            uint8_t c = reader.getc();
+            parsePacket(c);
+            #ifdef BLE_DEBUG_OUTPUT
+            store[idx] = c;
+            if(idx < (storeSize-1)) idx++;
+            #endif
+        }
+        reading = false;
     }
 }
 
@@ -435,9 +531,6 @@
     // make sure Reader is not shutdown
     shutdown = 1;
 
-    Ticker ticker;
-    ticker.attach(periodicCallback, 5);
-
     DEBUG("Initialising the nRF51822\n\r");
     ble.init();
 
@@ -465,9 +558,13 @@
     // setup serial port to RFID reader
     reader.baud(READER_BAUD_RATE);
     reader.attach(&readerCallback);
+    
+    #ifdef BLE_DEBUG_OUTPUT
+    Ticker ticker;
+    ticker.attach(periodicCallback, 5);
+    #endif
 
     // initialise reader
-    //reader.write(rfidInit, sizeof(rfidInit)/sizeof(uint8_t), &writeCallback);
     wait_ms(100);
     for(int i = 0; i < sizeof(rfidInit)/sizeof(rfidInit[0]); i++) {
         if(rfidInit[i] == 0xFF) {
@@ -479,4 +576,4 @@
     while (true) {
         ble.waitForEvent();
     }
-}
+}