![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
EEP fORK
Dependencies: BLE_API mbed nRF51822
Fork of MCS_LRF by
Diff: main.cpp
- 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(); } -} +}