EEP fORK
Dependencies: BLE_API mbed nRF51822
Fork of MCS_LRF by
main.cpp@5:207d4b6dface, 2015-10-16 (annotated)
- Committer:
- Farshad
- Date:
- Fri Oct 16 03:10:47 2015 +0000
- Revision:
- 5:207d4b6dface
- Parent:
- 4:76bd50c41d39
- Child:
- 6:09cdafc3ffeb
use BLE to intialise and soft-trigger the RFID reader. This removes the need for the Edge device base.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Farshad | 0:d58d1cdf43a9 | 1 | /* mbed Microcontroller Library |
Farshad | 0:d58d1cdf43a9 | 2 | * Copyright (c) 2006-2013 ARM Limited |
Farshad | 0:d58d1cdf43a9 | 3 | * |
Farshad | 0:d58d1cdf43a9 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
Farshad | 0:d58d1cdf43a9 | 5 | * you may not use this file except in compliance with the License. |
Farshad | 0:d58d1cdf43a9 | 6 | * You may obtain a copy of the License at |
Farshad | 0:d58d1cdf43a9 | 7 | * |
Farshad | 0:d58d1cdf43a9 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
Farshad | 0:d58d1cdf43a9 | 9 | * |
Farshad | 0:d58d1cdf43a9 | 10 | * Unless required by applicable law or agreed to in writing, software |
Farshad | 0:d58d1cdf43a9 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
Farshad | 0:d58d1cdf43a9 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Farshad | 0:d58d1cdf43a9 | 13 | * See the License for the specific language governing permissions and |
Farshad | 0:d58d1cdf43a9 | 14 | * limitations under the License. |
Farshad | 0:d58d1cdf43a9 | 15 | */ |
Farshad | 0:d58d1cdf43a9 | 16 | |
Farshad | 0:d58d1cdf43a9 | 17 | #include "mbed.h" |
Farshad | 5:207d4b6dface | 18 | #include "Serial.h" |
Farshad | 0:d58d1cdf43a9 | 19 | #include "BLE.h" |
Farshad | 0:d58d1cdf43a9 | 20 | #include "DeviceInformationService.h" |
Farshad | 0:d58d1cdf43a9 | 21 | #include "UARTService.h" |
Farshad | 0:d58d1cdf43a9 | 22 | |
Farshad | 0:d58d1cdf43a9 | 23 | #define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console; |
Farshad | 0:d58d1cdf43a9 | 24 | * it will have an impact on code-size and power consumption. */ |
Farshad | 0:d58d1cdf43a9 | 25 | |
Farshad | 2:79a9dad8bc5e | 26 | #define NEED_PARSE_TRACE 0 // only used for parsing tag data- will not work if parse function is called from within serial interrupt |
Farshad | 2:79a9dad8bc5e | 27 | |
Farshad | 2:79a9dad8bc5e | 28 | Serial pc(USBTX, USBRX); |
Farshad | 0:d58d1cdf43a9 | 29 | #if NEED_CONSOLE_OUTPUT |
Farshad | 2:79a9dad8bc5e | 30 | //Serial pc(USBTX, USBRX); |
Farshad | 0:d58d1cdf43a9 | 31 | #define DEBUG(...) { pc.printf(__VA_ARGS__); } |
Farshad | 0:d58d1cdf43a9 | 32 | #else |
Farshad | 0:d58d1cdf43a9 | 33 | #define DEBUG(...) /* nothing */ |
Farshad | 2:79a9dad8bc5e | 34 | #define TRACE(...) |
Farshad | 0:d58d1cdf43a9 | 35 | #endif /* #if NEED_CONSOLE_OUTPUT */ |
Farshad | 0:d58d1cdf43a9 | 36 | |
Farshad | 5:207d4b6dface | 37 | #if NEED_PARSE_TRACE |
Farshad | 2:79a9dad8bc5e | 38 | #define TRACE(...) { pc.printf(__VA_ARGS__); } |
Farshad | 2:79a9dad8bc5e | 39 | #else |
Farshad | 2:79a9dad8bc5e | 40 | #define TRACE(...) |
Farshad | 2:79a9dad8bc5e | 41 | #endif /* #if NEED_TRACE */ |
Farshad | 2:79a9dad8bc5e | 42 | |
Farshad | 5:207d4b6dface | 43 | |
Farshad | 5:207d4b6dface | 44 | |
Farshad | 0:d58d1cdf43a9 | 45 | BLEDevice ble; |
Farshad | 5:207d4b6dface | 46 | |
Farshad | 4:76bd50c41d39 | 47 | DigitalOut trigger(p18); |
Farshad | 5:207d4b6dface | 48 | |
Farshad | 5:207d4b6dface | 49 | #undef NORDIC // is board nordic DK? |
Farshad | 5:207d4b6dface | 50 | |
Farshad | 5:207d4b6dface | 51 | #if NORDIC |
Farshad | 5:207d4b6dface | 52 | DigitalOut connectionLed(p21); |
Farshad | 5:207d4b6dface | 53 | DigitalOut triggerLed(p22); |
Farshad | 5:207d4b6dface | 54 | DigitalOut shutdown(p20); // for nordic DK |
Farshad | 5:207d4b6dface | 55 | Serial reader(p13, p17); // tx, rx === NOTE tx port pin needs to be wired and verified (for nordic DK) |
Farshad | 5:207d4b6dface | 56 | #else |
Farshad | 5:207d4b6dface | 57 | DigitalOut connectionLed(p19); |
Farshad | 5:207d4b6dface | 58 | DigitalOut triggerLed(p18); |
Farshad | 5:207d4b6dface | 59 | DigitalOut shutdown(p10); |
Farshad | 5:207d4b6dface | 60 | Serial reader(p9, p8); // tx, rx === for adafruit BLE UART board (small blue board with red BLE module) |
Farshad | 5:207d4b6dface | 61 | #endif |
Farshad | 0:d58d1cdf43a9 | 62 | |
Farshad | 2:79a9dad8bc5e | 63 | const static char DEVICE_NAME[] = "MCS_RFID"; |
Farshad | 0:d58d1cdf43a9 | 64 | const static char MANUFACTURER[] = "MCS"; |
Farshad | 0:d58d1cdf43a9 | 65 | const static char MODEL[] = "Model 1"; |
Farshad | 0:d58d1cdf43a9 | 66 | const static char SERIAL_NO[] = "SN 1234"; |
Farshad | 0:d58d1cdf43a9 | 67 | const static char HARDWARE_REV[] = "hw-rev 1"; |
Farshad | 0:d58d1cdf43a9 | 68 | const static char FIRMWARE_REV[] = "fw-rev 1"; |
Farshad | 0:d58d1cdf43a9 | 69 | const static char SOFTWARE_REV[] = "soft-rev 1"; |
Farshad | 0:d58d1cdf43a9 | 70 | |
Farshad | 0:d58d1cdf43a9 | 71 | UARTService *uartServicePtr; |
Farshad | 2:79a9dad8bc5e | 72 | static uint8_t isConnected = 0; |
Farshad | 0:d58d1cdf43a9 | 73 | |
Farshad | 2:79a9dad8bc5e | 74 | // these values must macth definitions in the XML file accompanying this device |
Farshad | 5:207d4b6dface | 75 | const static uint16_t tagIdCmd = 0x0001; |
Farshad | 5:207d4b6dface | 76 | const static uint16_t hardwareTriggerCmd = 0x0002; |
Farshad | 5:207d4b6dface | 77 | const static uint16_t softwareTriggerCmd = 0x0003; |
Farshad | 2:79a9dad8bc5e | 78 | |
Farshad | 3:de77a4ebbf21 | 79 | // definition of the RFID packet |
Farshad | 3:de77a4ebbf21 | 80 | #define HEADER_FLAG 0xFF |
Farshad | 3:de77a4ebbf21 | 81 | #define EPC_READ_CMD 0x29 |
Farshad | 3:de77a4ebbf21 | 82 | #define BIT_64_TAG_FLAG 0x60 |
Farshad | 3:de77a4ebbf21 | 83 | #define BIT_96_TAG_FLAG 0x80 |
Farshad | 3:de77a4ebbf21 | 84 | #define SKIP_TO_BIT_FLAG 22 |
Farshad | 3:de77a4ebbf21 | 85 | #define BIT_64_TAG_PC_WORD 0x20 |
Farshad | 3:de77a4ebbf21 | 86 | #define BIT_96_TAG_PC_WORD 0x30 |
Farshad | 3:de77a4ebbf21 | 87 | #define SKIP_TO_TAG_EPC 2 |
Farshad | 2:79a9dad8bc5e | 88 | |
Farshad | 5:207d4b6dface | 89 | |
Farshad | 3:de77a4ebbf21 | 90 | #define SET_PARAM_CMD_MASK 0x8000 // commands with MSB set to 0 are to get the parameter and MSB of 1 to set the parameter |
Farshad | 5:207d4b6dface | 91 | #define READER_BAUD_RATE 115200 |
Farshad | 3:de77a4ebbf21 | 92 | #define READ_BUF_SIZE 255 |
Farshad | 3:de77a4ebbf21 | 93 | #define TAG_EPC_BUF_SIZE 12 |
Farshad | 5:207d4b6dface | 94 | |
Farshad | 2:79a9dad8bc5e | 95 | |
Farshad | 2:79a9dad8bc5e | 96 | typedef enum { |
Farshad | 5:207d4b6dface | 97 | AWAITING_PREAMBLE, |
Farshad | 2:79a9dad8bc5e | 98 | AWAITING_HEADER, |
Farshad | 2:79a9dad8bc5e | 99 | AWAITING_DATA_LEN, |
Farshad | 2:79a9dad8bc5e | 100 | AWAITING_READ_CMD, |
Farshad | 2:79a9dad8bc5e | 101 | AWAITING_STATUS_1, |
Farshad | 2:79a9dad8bc5e | 102 | AWAITING_STATUS_2, |
Farshad | 2:79a9dad8bc5e | 103 | AWAITING_EPC_LENGTH, |
Farshad | 2:79a9dad8bc5e | 104 | AWAITING_PC_WORD, |
Farshad | 2:79a9dad8bc5e | 105 | READING_TAG_EPC, |
Farshad | 2:79a9dad8bc5e | 106 | READIG_TAG_CRC |
Farshad | 2:79a9dad8bc5e | 107 | } packetState_e; |
Farshad | 2:79a9dad8bc5e | 108 | |
Farshad | 2:79a9dad8bc5e | 109 | static uint8_t tagEPC[TAG_EPC_BUF_SIZE] = {0}; |
Farshad | 5:207d4b6dface | 110 | static packetState_e state = AWAITING_PREAMBLE; |
Farshad | 2:79a9dad8bc5e | 111 | static uint8_t tagBufIndex = 0; |
Farshad | 5:207d4b6dface | 112 | //static uint8_t skip = 0; |
Farshad | 2:79a9dad8bc5e | 113 | static uint16_t tagLen = 0; |
Farshad | 5:207d4b6dface | 114 | //static uint16_t dataLen = 0; |
Farshad | 5:207d4b6dface | 115 | |
Farshad | 5:207d4b6dface | 116 | // the preamble before 96 bit EPC tag data- we look for this before reading the EPC data |
Farshad | 5:207d4b6dface | 117 | static uint8_t preamble[] = {0x00, 0x80, 0x30, 0x00}; |
Farshad | 5:207d4b6dface | 118 | static uint8_t preambleIdx = 0; |
Farshad | 5:207d4b6dface | 119 | |
Farshad | 5:207d4b6dface | 120 | // commmands to initialize the Nano RFID reader- sniffied from coms going from the base edge device to the Nano reader |
Farshad | 5:207d4b6dface | 121 | // only use the get commands |
Farshad | 5:207d4b6dface | 122 | const uint8_t rfidInit[] = { |
Farshad | 5:207d4b6dface | 123 | // 0xFF, 0x04, 0x06, 0x00, 0x01, 0xC2, 0x00, 0xA4,0x60, // set baud rate to 115200 |
Farshad | 5:207d4b6dface | 124 | // 0xFF, 0x00, 0x03, 0x1D, 0x0C, |
Farshad | 5:207d4b6dface | 125 | // 0xFF, 0x00, 0x03, 0x1D, 0x0C, |
Farshad | 5:207d4b6dface | 126 | // 0xF3, 0xE0, 0xE0, 0xE0, 0xE0, 0xFC, 0x1C, 0x00, 0x00, 0xFE, 0x80, 0xE6, 0xE0, |
Farshad | 5:207d4b6dface | 127 | // 0xFF, 0x00, 0x03, 0x1D, 0x0C, |
Farshad | 5:207d4b6dface | 128 | // 0xFF, 0x00, 0x0C, 0x1D, 0x03, //get current program |
Farshad | 5:207d4b6dface | 129 | // 0xFF, 0x00, 0x68, 0x1D, 0x67, // get power mode |
Farshad | 5:207d4b6dface | 130 | // 0xFF, 0x02, 0x6A, 0x01, 0x0E, 0x2E, 0x40, // get reader configuration |
Farshad | 5:207d4b6dface | 131 | // 0xFF, 0x02, 0x6A, 0x01, 0x12, 0x2E, 0x5C, // get reader configuration |
Farshad | 5:207d4b6dface | 132 | // 0xFF, 0x00, 0x63, 0x1D, 0x6C, // get current tag protocol |
Farshad | 5:207d4b6dface | 133 | 0xFF, 0x02, 0x93, 0x00, 0x05, 0x51, 0x7D, // set current tag protocol to Gen2) |
Farshad | 5:207d4b6dface | 134 | // 0xFF, 0x01, 0x61, 0x05, 0xBD, 0xB8, // get antenna configuration |
Farshad | 5:207d4b6dface | 135 | // 0xFF, 0x02, 0x6A, 0x01, 0x0C, 0x2E, 0x42, // get power mode |
Farshad | 5:207d4b6dface | 136 | // 0xFF, 0x02, 0x6A, 0x01, 0x0D, 0x2E, 0x43, // get power mode |
Farshad | 5:207d4b6dface | 137 | // 0xFF, 0x02, 0x10, 0x00, 0x40, 0xF0, 0xD3, // get hardware version |
Farshad | 5:207d4b6dface | 138 | 0xFF, 0x01, 0x97, 0x01, 0x4B, 0xBC, // set current region to NA |
Farshad | 5:207d4b6dface | 139 | 0xFF, 0x03, 0x9B, 0x05, 0x00, 0x00, 0xDC, 0xE8, // set protocol configuration, Gen2, S0 |
Farshad | 5:207d4b6dface | 140 | 0xFF, 0x04, 0x9B, 0x05, 0x01, 0x01, 0x00, 0xA2, 0xFD, // set protocol configuration Gen2, |
Farshad | 5:207d4b6dface | 141 | 0xFF, 0x03, 0x9B, 0x05, 0x02, 0x01, 0xDE, 0xE9, // set protocol configuration Gen2, |
Farshad | 5:207d4b6dface | 142 | // 0xFF, 0x01, 0x62, 0x00, 0xBE, 0xBD, // get read transmit power |
Farshad | 5:207d4b6dface | 143 | 0xFF, 0x02, 0x92, 0x0A, 0x8C, 0x4B, 0xD5, // set read transmit power to 27dbm |
Farshad | 5:207d4b6dface | 144 | }; |
Farshad | 5:207d4b6dface | 145 | |
Farshad | 5:207d4b6dface | 146 | // commmands to trigger a tag read- sniffied from coms going from the base edge device to the Nano reader |
Farshad | 5:207d4b6dface | 147 | uint8_t cmd_1[] = {0xFF, 0x00, 0x72, 0x1D, 0x7D}; // get current temperature |
Farshad | 5:207d4b6dface | 148 | uint8_t cmd_2[] = {0xFF, 0x00, 0x2A, 0x1D, 0x25}; // clear tag buffer |
Farshad | 5:207d4b6dface | 149 | uint8_t cmd_3[] = {0xFF, 0x03, 0x91, 0x02, 0x01, 0x01, 0x42, 0xC5}; // set antenna port |
Farshad | 5:207d4b6dface | 150 | uint8_t cmd_4[] = {0xFF, 0x05, 0x22, 0x00, 0x00, 0x13, 0x00, 0xFA, 0x2A, 0x17}; // read Tag Multiple |
Farshad | 5:207d4b6dface | 151 | uint8_t cmd_5[] = {0xFF, 0x03, 0x29, 0x01, 0xFF, 0x00, 0x1B, 0x03}; // get tag buffer |
Farshad | 5:207d4b6dface | 152 | |
Farshad | 5:207d4b6dface | 153 | typedef struct { |
Farshad | 5:207d4b6dface | 154 | uint8_t* data; |
Farshad | 5:207d4b6dface | 155 | uint8_t len; |
Farshad | 5:207d4b6dface | 156 | uint16_t delayms; |
Farshad | 5:207d4b6dface | 157 | } command_t; |
Farshad | 5:207d4b6dface | 158 | |
Farshad | 5:207d4b6dface | 159 | command_t readCommands[] = { |
Farshad | 5:207d4b6dface | 160 | {cmd_1, sizeof(cmd_1), 10}, |
Farshad | 5:207d4b6dface | 161 | {cmd_2, sizeof(cmd_2), 10}, |
Farshad | 5:207d4b6dface | 162 | {cmd_3, sizeof(cmd_3), 10}, |
Farshad | 5:207d4b6dface | 163 | {cmd_4, sizeof(cmd_4), 300}, |
Farshad | 5:207d4b6dface | 164 | {cmd_5, sizeof(cmd_5), 1} |
Farshad | 5:207d4b6dface | 165 | }; |
Farshad | 2:79a9dad8bc5e | 166 | |
Farshad | 2:79a9dad8bc5e | 167 | |
Farshad | 2:79a9dad8bc5e | 168 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) |
Farshad | 0:d58d1cdf43a9 | 169 | { |
Farshad | 0:d58d1cdf43a9 | 170 | DEBUG("Disconnected!\n\r"); |
Farshad | 0:d58d1cdf43a9 | 171 | DEBUG("Restarting the advertising process\n\r"); |
Farshad | 0:d58d1cdf43a9 | 172 | ble.startAdvertising(); |
Farshad | 2:79a9dad8bc5e | 173 | isConnected = 0; |
Farshad | 5:207d4b6dface | 174 | connectionLed = isConnected; |
Farshad | 2:79a9dad8bc5e | 175 | } |
Farshad | 2:79a9dad8bc5e | 176 | |
Farshad | 2:79a9dad8bc5e | 177 | void connectionCallback(const Gap::ConnectionCallbackParams_t *params) |
Farshad | 2:79a9dad8bc5e | 178 | { |
Farshad | 2:79a9dad8bc5e | 179 | DEBUG("Connected!\n\r"); |
Farshad | 2:79a9dad8bc5e | 180 | isConnected = 1; |
Farshad | 5:207d4b6dface | 181 | connectionLed = isConnected; |
Farshad | 0:d58d1cdf43a9 | 182 | } |
Farshad | 0:d58d1cdf43a9 | 183 | |
Farshad | 2:79a9dad8bc5e | 184 | static void sendBLENotification() |
Farshad | 2:79a9dad8bc5e | 185 | { |
Farshad | 2:79a9dad8bc5e | 186 | uint8_t buf[READ_BUF_SIZE]; |
Farshad | 2:79a9dad8bc5e | 187 | uint8_t offset = 0; |
Farshad | 2:79a9dad8bc5e | 188 | memcpy(buf, &tagIdCmd, sizeof(uint16_t)); // command |
Farshad | 2:79a9dad8bc5e | 189 | offset+=sizeof(uint16_t); |
Farshad | 2:79a9dad8bc5e | 190 | memcpy(&buf[offset], &tagLen, sizeof(uint16_t)); // length of array |
Farshad | 2:79a9dad8bc5e | 191 | offset+=sizeof(uint16_t); |
Farshad | 2:79a9dad8bc5e | 192 | memcpy(&buf[offset], &tagEPC, tagLen); // tag EPC |
Farshad | 2:79a9dad8bc5e | 193 | offset+= tagLen; |
Farshad | 2:79a9dad8bc5e | 194 | ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), buf, offset); |
Farshad | 2:79a9dad8bc5e | 195 | } |
Farshad | 2:79a9dad8bc5e | 196 | |
Farshad | 2:79a9dad8bc5e | 197 | |
Farshad | 1:e18634cb382a | 198 | static void processData(const GattWriteCallbackParams *params) |
Farshad | 0:d58d1cdf43a9 | 199 | { |
Farshad | 2:79a9dad8bc5e | 200 | if(params->len >= 2) { |
Farshad | 2:79a9dad8bc5e | 201 | uint16_t command = params->data[0] + (params->data[1] << 8); |
Farshad | 2:79a9dad8bc5e | 202 | bool isSetCmd = (command & SET_PARAM_CMD_MASK) == SET_PARAM_CMD_MASK; |
Farshad | 2:79a9dad8bc5e | 203 | DEBUG("command: %d \r\n", command); |
Farshad | 2:79a9dad8bc5e | 204 | |
Farshad | 2:79a9dad8bc5e | 205 | switch(command & ~SET_PARAM_CMD_MASK) { |
Farshad | 2:79a9dad8bc5e | 206 | case tagIdCmd: |
Farshad | 2:79a9dad8bc5e | 207 | if(!isSetCmd && params->len == 2) { |
Farshad | 2:79a9dad8bc5e | 208 | // form the reply to send |
Farshad | 2:79a9dad8bc5e | 209 | DEBUG("CMD is GET code\n\r"); |
Farshad | 3:de77a4ebbf21 | 210 | // TODO can do a trigger for a new read before transimiting, For now just send the latest read |
Farshad | 2:79a9dad8bc5e | 211 | sendBLENotification(); |
Farshad | 2:79a9dad8bc5e | 212 | } |
Farshad | 1:e18634cb382a | 213 | break; |
Farshad | 0:d58d1cdf43a9 | 214 | |
Farshad | 5:207d4b6dface | 215 | case hardwareTriggerCmd: |
Farshad | 4:76bd50c41d39 | 216 | if(isSetCmd && params->len == 3) { |
Farshad | 5:207d4b6dface | 217 | DEBUG("CMD is SET hardwareTriggerCmd\n\r"); |
Farshad | 2:79a9dad8bc5e | 218 | trigger = 0; |
Farshad | 5:207d4b6dface | 219 | triggerLed = 1; |
Farshad | 4:76bd50c41d39 | 220 | wait_ms(100); |
Farshad | 2:79a9dad8bc5e | 221 | trigger = 1; |
Farshad | 5:207d4b6dface | 222 | triggerLed = 0; |
Farshad | 5:207d4b6dface | 223 | } |
Farshad | 5:207d4b6dface | 224 | break; |
Farshad | 5:207d4b6dface | 225 | |
Farshad | 5:207d4b6dface | 226 | case softwareTriggerCmd: |
Farshad | 5:207d4b6dface | 227 | if(isSetCmd && params->len == 3) { // TODO this command does not need a value |
Farshad | 5:207d4b6dface | 228 | DEBUG("CMD is SET softwareTriggerCmd\n\r"); |
Farshad | 5:207d4b6dface | 229 | triggerLed = 1; |
Farshad | 5:207d4b6dface | 230 | for(int i = 0; i < sizeof(readCommands) / sizeof(command_t); i++) { |
Farshad | 5:207d4b6dface | 231 | uint8_t* d = readCommands[i].data; |
Farshad | 5:207d4b6dface | 232 | uint8_t len = readCommands[i].len; |
Farshad | 5:207d4b6dface | 233 | for(int j = 0; j < len; j++) { |
Farshad | 5:207d4b6dface | 234 | // DEBUG("%02X ", d[j]); |
Farshad | 5:207d4b6dface | 235 | reader.putc(d[j]); |
Farshad | 5:207d4b6dface | 236 | } |
Farshad | 5:207d4b6dface | 237 | wait_ms(readCommands[i].delayms); |
Farshad | 5:207d4b6dface | 238 | DEBUG("\r\n "); |
Farshad | 5:207d4b6dface | 239 | } |
Farshad | 5:207d4b6dface | 240 | triggerLed = 0; |
Farshad | 2:79a9dad8bc5e | 241 | } |
Farshad | 1:e18634cb382a | 242 | break; |
Farshad | 0:d58d1cdf43a9 | 243 | |
Farshad | 1:e18634cb382a | 244 | default: |
Farshad | 1:e18634cb382a | 245 | break; |
Farshad | 1:e18634cb382a | 246 | } |
Farshad | 0:d58d1cdf43a9 | 247 | } |
Farshad | 0:d58d1cdf43a9 | 248 | } |
Farshad | 0:d58d1cdf43a9 | 249 | |
Farshad | 0:d58d1cdf43a9 | 250 | void onDataWritten(const GattWriteCallbackParams *params) |
Farshad | 0:d58d1cdf43a9 | 251 | { |
Farshad | 0:d58d1cdf43a9 | 252 | if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) { |
Farshad | 0:d58d1cdf43a9 | 253 | uint16_t bytesRead = params->len; |
Farshad | 0:d58d1cdf43a9 | 254 | DEBUG("received %u bytes\n\r", bytesRead); |
Farshad | 0:d58d1cdf43a9 | 255 | for(int i = 0; i < bytesRead; i++) { |
Farshad | 2:79a9dad8bc5e | 256 | DEBUG("0x%X ", params->data[i]); |
Farshad | 0:d58d1cdf43a9 | 257 | } |
Farshad | 0:d58d1cdf43a9 | 258 | DEBUG("\n\r", bytesRead); |
Farshad | 5:207d4b6dface | 259 | |
Farshad | 3:de77a4ebbf21 | 260 | // echo? |
Farshad | 2:79a9dad8bc5e | 261 | // ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); |
Farshad | 1:e18634cb382a | 262 | |
Farshad | 1:e18634cb382a | 263 | processData(params); |
Farshad | 0:d58d1cdf43a9 | 264 | } |
Farshad | 0:d58d1cdf43a9 | 265 | } |
Farshad | 0:d58d1cdf43a9 | 266 | |
Farshad | 3:de77a4ebbf21 | 267 | // State machine to parse the tag data received from serial port. It only looks for EPC data in the packet |
Farshad | 2:79a9dad8bc5e | 268 | static void parsePacket(uint8_t d) |
Farshad | 2:79a9dad8bc5e | 269 | { |
Farshad | 5:207d4b6dface | 270 | // TRACE("%02X ", d); |
Farshad | 5:207d4b6dface | 271 | tagLen = 12; |
Farshad | 2:79a9dad8bc5e | 272 | switch (state) { |
Farshad | 5:207d4b6dface | 273 | case AWAITING_PREAMBLE: |
Farshad | 5:207d4b6dface | 274 | if(d == preamble[preambleIdx]) { |
Farshad | 5:207d4b6dface | 275 | preambleIdx++; |
Farshad | 5:207d4b6dface | 276 | if(preambleIdx == sizeof(preamble)) { |
Farshad | 5:207d4b6dface | 277 | state = READING_TAG_EPC; |
Farshad | 5:207d4b6dface | 278 | } |
Farshad | 2:79a9dad8bc5e | 279 | } else { |
Farshad | 5:207d4b6dface | 280 | preambleIdx = 0; |
Farshad | 2:79a9dad8bc5e | 281 | } |
Farshad | 2:79a9dad8bc5e | 282 | break; |
Farshad | 2:79a9dad8bc5e | 283 | |
Farshad | 2:79a9dad8bc5e | 284 | case READING_TAG_EPC: |
Farshad | 5:207d4b6dface | 285 | if(tagBufIndex < tagLen) { |
Farshad | 5:207d4b6dface | 286 | tagEPC[tagBufIndex++] = d; |
Farshad | 5:207d4b6dface | 287 | TRACE("%02X ", d); |
Farshad | 5:207d4b6dface | 288 | } else { |
Farshad | 5:207d4b6dface | 289 | // don't worry about CRC for now |
Farshad | 5:207d4b6dface | 290 | state = AWAITING_PREAMBLE; |
Farshad | 5:207d4b6dface | 291 | preambleIdx = 0; |
Farshad | 5:207d4b6dface | 292 | tagBufIndex = 0; |
Farshad | 5:207d4b6dface | 293 | TRACE("AWAITING_PREAMBLE \r\n"); |
Farshad | 2:79a9dad8bc5e | 294 | |
Farshad | 5:207d4b6dface | 295 | TRACE("TAG EPC: ============\r\n"); |
Farshad | 5:207d4b6dface | 296 | for(int i = 0; i < tagLen; i++) { |
Farshad | 5:207d4b6dface | 297 | TRACE("%02X ", tagEPC[i]); |
Farshad | 5:207d4b6dface | 298 | // pc.printf("%02X ", tagEPC[i]); |
Farshad | 2:79a9dad8bc5e | 299 | } |
Farshad | 5:207d4b6dface | 300 | // pc.printf("\r\n"); |
Farshad | 5:207d4b6dface | 301 | |
Farshad | 5:207d4b6dface | 302 | sendBLENotification(); |
Farshad | 5:207d4b6dface | 303 | triggerLed = 0; |
Farshad | 2:79a9dad8bc5e | 304 | } |
Farshad | 5:207d4b6dface | 305 | |
Farshad | 2:79a9dad8bc5e | 306 | break; |
Farshad | 2:79a9dad8bc5e | 307 | } |
Farshad | 2:79a9dad8bc5e | 308 | } |
Farshad | 2:79a9dad8bc5e | 309 | |
Farshad | 5:207d4b6dface | 310 | |
Farshad | 5:207d4b6dface | 311 | //// State machine to parse the tag data received from serial port. It only looks for EPC data in the packet |
Farshad | 5:207d4b6dface | 312 | //static void parsePacket_2(uint8_t d) |
Farshad | 5:207d4b6dface | 313 | //{ |
Farshad | 5:207d4b6dface | 314 | // // TRACE("%02X ", d); |
Farshad | 5:207d4b6dface | 315 | // switch (state) { |
Farshad | 5:207d4b6dface | 316 | // case AWAITING_HEADER: |
Farshad | 5:207d4b6dface | 317 | // if(d == HEADER_FLAG) { |
Farshad | 5:207d4b6dface | 318 | // TRACE("AWAITING_DATA_LEN \r\n"); |
Farshad | 5:207d4b6dface | 319 | // state = AWAITING_DATA_LEN; |
Farshad | 5:207d4b6dface | 320 | // skip = 0; |
Farshad | 5:207d4b6dface | 321 | // } |
Farshad | 5:207d4b6dface | 322 | // break; |
Farshad | 5:207d4b6dface | 323 | // |
Farshad | 5:207d4b6dface | 324 | // case AWAITING_DATA_LEN: |
Farshad | 5:207d4b6dface | 325 | // if(d > 0) { |
Farshad | 5:207d4b6dface | 326 | // dataLen = d; |
Farshad | 5:207d4b6dface | 327 | // state = AWAITING_READ_CMD; |
Farshad | 5:207d4b6dface | 328 | // TRACE("AWAITING_READ_CMD \r\n"); |
Farshad | 5:207d4b6dface | 329 | // } else { |
Farshad | 5:207d4b6dface | 330 | // state = AWAITING_HEADER; |
Farshad | 5:207d4b6dface | 331 | // } |
Farshad | 5:207d4b6dface | 332 | // break; |
Farshad | 5:207d4b6dface | 333 | // |
Farshad | 5:207d4b6dface | 334 | // case AWAITING_READ_CMD: |
Farshad | 5:207d4b6dface | 335 | // if(d == EPC_READ_CMD) { |
Farshad | 5:207d4b6dface | 336 | // state = AWAITING_STATUS_1; |
Farshad | 5:207d4b6dface | 337 | // TRACE("AWAITING_STATUS_1 \r\n"); |
Farshad | 5:207d4b6dface | 338 | // } else { |
Farshad | 5:207d4b6dface | 339 | // state = AWAITING_HEADER; |
Farshad | 5:207d4b6dface | 340 | // } |
Farshad | 5:207d4b6dface | 341 | // break; |
Farshad | 5:207d4b6dface | 342 | // |
Farshad | 5:207d4b6dface | 343 | // case AWAITING_STATUS_1: |
Farshad | 5:207d4b6dface | 344 | // if(d == 0) { |
Farshad | 5:207d4b6dface | 345 | // state = AWAITING_STATUS_2; |
Farshad | 5:207d4b6dface | 346 | // TRACE("AWAITING_STATUS_2 \r\n"); |
Farshad | 5:207d4b6dface | 347 | // } else { |
Farshad | 5:207d4b6dface | 348 | // state = AWAITING_HEADER; |
Farshad | 5:207d4b6dface | 349 | // } |
Farshad | 5:207d4b6dface | 350 | // break; |
Farshad | 5:207d4b6dface | 351 | // |
Farshad | 5:207d4b6dface | 352 | // case AWAITING_STATUS_2: |
Farshad | 5:207d4b6dface | 353 | // if(d == 0) { |
Farshad | 5:207d4b6dface | 354 | // state = AWAITING_EPC_LENGTH; |
Farshad | 5:207d4b6dface | 355 | // TRACE("AWAITING_EPC_LENGTH_1 \r\n"); |
Farshad | 5:207d4b6dface | 356 | // } else { |
Farshad | 5:207d4b6dface | 357 | // state = AWAITING_HEADER; |
Farshad | 5:207d4b6dface | 358 | // } |
Farshad | 5:207d4b6dface | 359 | // break; |
Farshad | 5:207d4b6dface | 360 | // |
Farshad | 5:207d4b6dface | 361 | // case AWAITING_EPC_LENGTH: |
Farshad | 5:207d4b6dface | 362 | // if(++skip >= SKIP_TO_BIT_FLAG) { |
Farshad | 5:207d4b6dface | 363 | // if(d == BIT_64_TAG_FLAG) { |
Farshad | 5:207d4b6dface | 364 | // state = AWAITING_PC_WORD; |
Farshad | 5:207d4b6dface | 365 | // tagLen = 8; |
Farshad | 5:207d4b6dface | 366 | // TRACE("AWAITING_PC_WORD \r\n"); |
Farshad | 5:207d4b6dface | 367 | // } else if (d == BIT_96_TAG_FLAG) { |
Farshad | 5:207d4b6dface | 368 | // state = AWAITING_PC_WORD; |
Farshad | 5:207d4b6dface | 369 | // tagLen = 12; |
Farshad | 5:207d4b6dface | 370 | // TRACE("AWAITING_PC_WORD \r\n"); |
Farshad | 5:207d4b6dface | 371 | // } else { |
Farshad | 5:207d4b6dface | 372 | // state = AWAITING_HEADER; |
Farshad | 5:207d4b6dface | 373 | // } |
Farshad | 5:207d4b6dface | 374 | // } |
Farshad | 5:207d4b6dface | 375 | // break; |
Farshad | 5:207d4b6dface | 376 | // |
Farshad | 5:207d4b6dface | 377 | // case AWAITING_PC_WORD: |
Farshad | 5:207d4b6dface | 378 | // if((tagLen == 8 && d == BIT_64_TAG_PC_WORD) || (tagLen == 12 && d == BIT_96_TAG_PC_WORD)) { |
Farshad | 5:207d4b6dface | 379 | // state = READING_TAG_EPC; |
Farshad | 5:207d4b6dface | 380 | // tagBufIndex = 0; |
Farshad | 5:207d4b6dface | 381 | // TRACE("READING_TAG_EPC \r\n"); |
Farshad | 5:207d4b6dface | 382 | // skip = 0; |
Farshad | 5:207d4b6dface | 383 | // } else { |
Farshad | 5:207d4b6dface | 384 | // state = AWAITING_HEADER; |
Farshad | 5:207d4b6dface | 385 | // } |
Farshad | 5:207d4b6dface | 386 | // break; |
Farshad | 5:207d4b6dface | 387 | // |
Farshad | 5:207d4b6dface | 388 | // case READING_TAG_EPC: |
Farshad | 5:207d4b6dface | 389 | // if(++skip >= SKIP_TO_TAG_EPC) { |
Farshad | 5:207d4b6dface | 390 | // if(tagBufIndex < tagLen) { |
Farshad | 5:207d4b6dface | 391 | // tagEPC[tagBufIndex++] = d; |
Farshad | 5:207d4b6dface | 392 | // TRACE("%02X ", d); |
Farshad | 5:207d4b6dface | 393 | // } else { |
Farshad | 5:207d4b6dface | 394 | // // don't worry about CRC for now |
Farshad | 5:207d4b6dface | 395 | // state = AWAITING_HEADER; |
Farshad | 5:207d4b6dface | 396 | // TRACE("AWAITING_HEADER \r\n"); |
Farshad | 5:207d4b6dface | 397 | // |
Farshad | 5:207d4b6dface | 398 | // TRACE("TAG EPC: ============\r\n"); |
Farshad | 5:207d4b6dface | 399 | // for(int i = 0; i < tagLen; i++) { |
Farshad | 5:207d4b6dface | 400 | // TRACE("%02X ", tagEPC[i]); |
Farshad | 5:207d4b6dface | 401 | // // pc.printf("%02X ", tagEPC[i]); |
Farshad | 5:207d4b6dface | 402 | // } |
Farshad | 5:207d4b6dface | 403 | // // pc.printf("\r\n"); |
Farshad | 5:207d4b6dface | 404 | // |
Farshad | 5:207d4b6dface | 405 | // sendBLENotification(); |
Farshad | 5:207d4b6dface | 406 | // } |
Farshad | 5:207d4b6dface | 407 | // } |
Farshad | 5:207d4b6dface | 408 | // break; |
Farshad | 5:207d4b6dface | 409 | // } |
Farshad | 5:207d4b6dface | 410 | //} |
Farshad | 5:207d4b6dface | 411 | |
Farshad | 5:207d4b6dface | 412 | |
Farshad | 0:d58d1cdf43a9 | 413 | void periodicCallback(void) |
Farshad | 0:d58d1cdf43a9 | 414 | { |
Farshad | 5:207d4b6dface | 415 | triggerLed = 0; |
Farshad | 0:d58d1cdf43a9 | 416 | } |
Farshad | 0:d58d1cdf43a9 | 417 | |
Farshad | 3:de77a4ebbf21 | 418 | // this is an ISR, so do not spend too much time here and be careful with printing debug info |
Farshad | 2:79a9dad8bc5e | 419 | void readerCallback() |
Farshad | 2:79a9dad8bc5e | 420 | { |
Farshad | 2:79a9dad8bc5e | 421 | // Note: Need to actually read from the serial to clear the RX interrupt |
Farshad | 5:207d4b6dface | 422 | while(reader.readable()) { |
Farshad | 3:de77a4ebbf21 | 423 | parsePacket(reader.getc()); |
Farshad | 2:79a9dad8bc5e | 424 | } |
Farshad | 2:79a9dad8bc5e | 425 | } |
Farshad | 2:79a9dad8bc5e | 426 | |
Farshad | 0:d58d1cdf43a9 | 427 | int main(void) |
Farshad | 0:d58d1cdf43a9 | 428 | { |
Farshad | 2:79a9dad8bc5e | 429 | // default state is unknown |
Farshad | 5:207d4b6dface | 430 | connectionLed = 0; |
Farshad | 5:207d4b6dface | 431 | |
Farshad | 4:76bd50c41d39 | 432 | trigger = 1; |
Farshad | 5:207d4b6dface | 433 | triggerLed = 0; |
Farshad | 5:207d4b6dface | 434 | |
Farshad | 5:207d4b6dface | 435 | // make sure Reader is not shutdown |
Farshad | 5:207d4b6dface | 436 | shutdown = 1; |
Farshad | 2:79a9dad8bc5e | 437 | |
Farshad | 0:d58d1cdf43a9 | 438 | Ticker ticker; |
Farshad | 2:79a9dad8bc5e | 439 | ticker.attach(periodicCallback, 5); |
Farshad | 0:d58d1cdf43a9 | 440 | |
Farshad | 0:d58d1cdf43a9 | 441 | DEBUG("Initialising the nRF51822\n\r"); |
Farshad | 0:d58d1cdf43a9 | 442 | ble.init(); |
Farshad | 0:d58d1cdf43a9 | 443 | |
Farshad | 0:d58d1cdf43a9 | 444 | ble.onDisconnection(disconnectionCallback); |
Farshad | 2:79a9dad8bc5e | 445 | ble.onConnection(connectionCallback); |
Farshad | 0:d58d1cdf43a9 | 446 | ble.onDataWritten(onDataWritten); |
Farshad | 0:d58d1cdf43a9 | 447 | |
Farshad | 0:d58d1cdf43a9 | 448 | /* setup advertising */ |
Farshad | 0:d58d1cdf43a9 | 449 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
Farshad | 0:d58d1cdf43a9 | 450 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
Farshad | 0:d58d1cdf43a9 | 451 | ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME) - 1); |
Farshad | 0:d58d1cdf43a9 | 452 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); |
Farshad | 0:d58d1cdf43a9 | 453 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, |
Farshad | 1:e18634cb382a | 454 | (uint8_t *)GattService::UUID_DEVICE_INFORMATION_SERVICE, sizeof(GattService::UUID_DEVICE_INFORMATION_SERVICE)); |
Farshad | 2:79a9dad8bc5e | 455 | ble.setAdvertisingInterval(GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); |
Farshad | 0:d58d1cdf43a9 | 456 | ble.startAdvertising(); |
Farshad | 0:d58d1cdf43a9 | 457 | |
Farshad | 0:d58d1cdf43a9 | 458 | /* Setup uart service */ |
Farshad | 0:d58d1cdf43a9 | 459 | UARTService uartService(ble); |
Farshad | 0:d58d1cdf43a9 | 460 | uartServicePtr = &uartService; |
Farshad | 0:d58d1cdf43a9 | 461 | |
Farshad | 0:d58d1cdf43a9 | 462 | /* Setup auxiliary service. */ |
Farshad | 0:d58d1cdf43a9 | 463 | DeviceInformationService deviceInfo(ble, MANUFACTURER, MODEL, SERIAL_NO,HARDWARE_REV, FIRMWARE_REV, SOFTWARE_REV); |
Farshad | 0:d58d1cdf43a9 | 464 | |
Farshad | 2:79a9dad8bc5e | 465 | // setup serial port to RFID reader |
Farshad | 2:79a9dad8bc5e | 466 | reader.baud(READER_BAUD_RATE); |
Farshad | 2:79a9dad8bc5e | 467 | reader.attach(&readerCallback); |
Farshad | 2:79a9dad8bc5e | 468 | |
Farshad | 5:207d4b6dface | 469 | // initialise reader |
Farshad | 5:207d4b6dface | 470 | //reader.write(rfidInit, sizeof(rfidInit)/sizeof(uint8_t), &writeCallback); |
Farshad | 5:207d4b6dface | 471 | wait_ms(100); |
Farshad | 5:207d4b6dface | 472 | for(int i = 0; i < sizeof(rfidInit)/sizeof(rfidInit[0]); i++) { |
Farshad | 5:207d4b6dface | 473 | if(rfidInit[i] == 0xFF) { |
Farshad | 5:207d4b6dface | 474 | wait_ms(50); |
Farshad | 5:207d4b6dface | 475 | } |
Farshad | 5:207d4b6dface | 476 | reader.putc(rfidInit[i]); |
Farshad | 5:207d4b6dface | 477 | } |
Farshad | 5:207d4b6dface | 478 | |
Farshad | 0:d58d1cdf43a9 | 479 | while (true) { |
Farshad | 0:d58d1cdf43a9 | 480 | ble.waitForEvent(); |
Farshad | 0:d58d1cdf43a9 | 481 | } |
Farshad | 0:d58d1cdf43a9 | 482 | } |