From 1ac3082d7cb8ef4b10651594a3e68b83f32d7d50 Mon Sep 17 00:00:00 2001 From: David Sullivan <david.sullivan1@motorolasolutions.com> Date: Thu, 4 May 2023 14:51:38 -0500 Subject: [PATCH] adding project source code --- nfc_and_servo/.gitignore | 6 + nfc_and_servo/README.md | 3 + nfc_and_servo/include/README | 39 ++++ nfc_and_servo/include/door.h | 9 + nfc_and_servo/include/nfc_read.h | 40 ++++ nfc_and_servo/include/utils.h | 14 ++ nfc_and_servo/lib/README | 46 +++++ nfc_and_servo/platformio.ini | 19 ++ nfc_and_servo/src/door.cpp | 21 +++ nfc_and_servo/src/main.cpp | 164 ++++++++++++++++ nfc_and_servo/src/nfc_read.cpp | 311 +++++++++++++++++++++++++++++++ nfc_and_servo/src/utils.cpp | 57 ++++++ nfc_and_servo/test/README | 11 ++ 13 files changed, 740 insertions(+) create mode 100644 nfc_and_servo/.gitignore create mode 100644 nfc_and_servo/README.md create mode 100644 nfc_and_servo/include/README create mode 100644 nfc_and_servo/include/door.h create mode 100644 nfc_and_servo/include/nfc_read.h create mode 100644 nfc_and_servo/include/utils.h create mode 100644 nfc_and_servo/lib/README create mode 100644 nfc_and_servo/platformio.ini create mode 100644 nfc_and_servo/src/door.cpp create mode 100644 nfc_and_servo/src/main.cpp create mode 100644 nfc_and_servo/src/nfc_read.cpp create mode 100644 nfc_and_servo/src/utils.cpp create mode 100644 nfc_and_servo/test/README diff --git a/nfc_and_servo/.gitignore b/nfc_and_servo/.gitignore new file mode 100644 index 0000000..beaaf8a --- /dev/null +++ b/nfc_and_servo/.gitignore @@ -0,0 +1,6 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch +.vscode/extensions.json diff --git a/nfc_and_servo/README.md b/nfc_and_servo/README.md new file mode 100644 index 0000000..91cc3cd --- /dev/null +++ b/nfc_and_servo/README.md @@ -0,0 +1,3 @@ +# Microcontroller Code to Run the Project +- This is the source code for the project +- the src/ directory contains all of the logic for reading, storing and verifying RFID cards, along with locking and unlocking the door by communicating with the servo motor diff --git a/nfc_and_servo/include/README b/nfc_and_servo/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/nfc_and_servo/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/nfc_and_servo/include/door.h b/nfc_and_servo/include/door.h new file mode 100644 index 0000000..c1b8060 --- /dev/null +++ b/nfc_and_servo/include/door.h @@ -0,0 +1,9 @@ +#include <Servo.h> +#include <Arduino.h> + +#define DOOR_MAX_POS 180 +#define DOOR_MIN_POS 0 +#define DOOR_PIN D3 + +void unlockDoor(void); +void lockDoor(void); \ No newline at end of file diff --git a/nfc_and_servo/include/nfc_read.h b/nfc_and_servo/include/nfc_read.h new file mode 100644 index 0000000..a7026e0 --- /dev/null +++ b/nfc_and_servo/include/nfc_read.h @@ -0,0 +1,40 @@ +//include arduino libraries and util functions +#include "utils.h" + +// include NFC libraries +// #include "nfc_utils.h" +#include "rfal_nfc.h" +#include "rfal_rfst25r95.h" +#include "ndef_class.h" + +// define pins used by system +#define SPI_MOSI D11 +#define SPI_MISO D12 +#define SPI_SCK D13 +#define CS_PIN D10 +#define IRQ_IN_PIN D8 +#define IRQ_OUT_PIN D2 +#define INTERFACE_PIN D9 + +// define read states +#define DEMO_ST_NOTINIT 0 +#define DEMO_ST_START_DISCOVERY 1 +#define DEMO_ST_DISCOVERY 2 + +// define read feature +#define NDEF_DEMO_READ 0U + +// maximum amount of features (only using read, set to 1) +#define NDEF_DEMO_MAX_FEATURES 1U + +#define NDEF_LED_BLINK_DURATION 250U +#define DEMO_ST_MANUFACTURER_ID 0x02U + +typedef struct { + char *tag_type; + char *nfcUID; +} reader_response_t; + +reader_response_t readNFCUID(void); +void initDevice(void); + diff --git a/nfc_and_servo/include/utils.h b/nfc_and_servo/include/utils.h new file mode 100644 index 0000000..fa453c8 --- /dev/null +++ b/nfc_and_servo/include/utils.h @@ -0,0 +1,14 @@ +#pragma once +#include <Arduino.h> +#include <SPI.h> + +#define LED_A_PIN D7 +#define LED_B_PIN D6 +#define LED_F_PIN D5 +#define LED_V_PIN D4 +#define MAX_HEX_STR 4 +#define MAX_HEX_STR_LENGTH 128 + +void ledsOn(void); +void ledsOff(void); +char *hex2str(unsigned char *data, size_t dataLen); \ No newline at end of file diff --git a/nfc_and_servo/lib/README b/nfc_and_servo/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/nfc_and_servo/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include <Foo.h> +#include <Bar.h> + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/nfc_and_servo/platformio.ini b/nfc_and_servo/platformio.ini new file mode 100644 index 0000000..cc3c980 --- /dev/null +++ b/nfc_and_servo/platformio.ini @@ -0,0 +1,19 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nucleo_f401re] +platform = ststm32 +board = nucleo_f401re +framework = arduino +monitor_speed = 115200 +lib_deps = + stm32duino/STM32duino NFC-RFAL@^1.0.1 + stm32duino/STM32duino ST25R95@^1.0.0 + khoih-prog/FlashStorage_STM32@^1.2.0 diff --git a/nfc_and_servo/src/door.cpp b/nfc_and_servo/src/door.cpp new file mode 100644 index 0000000..2dc5c6a --- /dev/null +++ b/nfc_and_servo/src/door.cpp @@ -0,0 +1,21 @@ +#include "door.h" + +static Servo servo; + +void unlockDoor(void) +{ + servo.attach(DOOR_PIN); + for(int pos = DOOR_MAX_POS; pos >= DOOR_MIN_POS; pos--) + { + servo.write(pos); + } +} + +void lockDoor(void) +{ + servo.attach(DOOR_PIN); + for(int pos = DOOR_MIN_POS; pos >= DOOR_MAX_POS; pos++) + { + servo.write(pos); + } +} \ No newline at end of file diff --git a/nfc_and_servo/src/main.cpp b/nfc_and_servo/src/main.cpp new file mode 100644 index 0000000..e5b51df --- /dev/null +++ b/nfc_and_servo/src/main.cpp @@ -0,0 +1,164 @@ +#include "nfc_read.h" +#include "door.h" +#include <FlashStorage_STM32.h> + +#define PASSIVE_ISO_DEP_LEN 14 +#define MAX_NUM_KEYS 10 +#define NUM_KEYS_INDEX 200 + +static bool verifyUID(const char *uid); + +static void addKeyToMemory(const char* uid); + +static void interruptCallback(void); + +/** + * numkeys becomes a global variable held in ram rather than something written to flash memory + * this simplifies the operation of adding keys as fewer writes to flash are required and indexing is simplified + * BENEFITS: fewer writes to flash memory(increased longevity), simplified memory indexing + * COSTS: more refresh cycles necessary for RAM, decrease the life of the ram, also increased + * dependency on global variables reduces encapsulation somewhat +*/ +static int numkeys = 0; + +void setup() { + // put your setup code here, to run once: + Serial.begin(115200); // setting baudrate + delay(1000); + + + pinMode(LED_A_PIN, OUTPUT); + pinMode(LED_B_PIN, OUTPUT); + pinMode(LED_F_PIN, OUTPUT); + pinMode(LED_V_PIN, OUTPUT); + pinMode(USER_BTN, INPUT); + + attachInterrupt(digitalPinToInterrupt(USER_BTN), interruptCallback, RISING); + + // /* check state of the push button when not pressed */ + Serial.println("Welcome to X-NUCLEO-NFC03A1"); + Serial.print(numkeys); + initDevice(); + delay(1000); + reader_response_t readerResponse = readNFCUID(); + delay(1000); + if (readerResponse.nfcUID && readerResponse.tag_type) + { + Serial.println("received uid"); + delay(1000); + Serial.write(readerResponse.nfcUID); + Serial.write(readerResponse.tag_type); + delay(1000); + addKeyToMemory(readerResponse.nfcUID); + } + else + { + Serial.print("no UID received"); + } + + // Serial.print("Going to unlock the door"); + // Serial.print("\r\n"); + // delay(2000); + // unlockDoor(); + // Serial.print("Unlocked the Door"); + // Serial.print("\r\n"); + // delay(3000); + // Serial.print("Locking Door"); + // Serial.print("\r\n"); + // lockDoor(); + // Serial.print("Locked Door, ending execution"); + // Serial.print("\r\n"); +} + +void loop() { + // put your main code here, to run repeatedly: + reader_response_t readerResponse = readNFCUID(); + + if(readerResponse.nfcUID && readerResponse.tag_type) + { + if (verifyUID(readerResponse.nfcUID) == true) + { + Serial.print("valid uid"); + Serial.print("\r\n"); + Serial.print("running unlock door"); + Serial.print("\r\n"); + unlockDoor(); + delay(1000); + Serial.print("unlocked door"); + Serial.print("\r\n"); + delay(6000); + Serial.print("locking door"); + Serial.print("\r\n"); + lockDoor(); + delay(1000); + Serial.print("locked door"); + Serial.print("\r\n"); + } + else + { + Serial.print("uid not found"); + Serial.print("\r\n"); + } + } + else + { + Serial.print("no uid received"); + Serial.print("\r\n"); + } +} + +static bool verifyUID(const char *uid) +{ + + int increaseIndex = PASSIVE_ISO_DEP_LEN * sizeof(char); + for (int i = 0; i < 10 * increaseIndex; i+= increaseIndex) + { + char* eeprom_uid; + Serial.print("Reading from memory"); + EEPROM.get(i, eeprom_uid); + delay(1000); + Serial.write(eeprom_uid); + if (strncmp(uid, eeprom_uid, strlen(uid)) == 0) + { + return true; + } + else + { + continue; + } + } + return false; +} + +static void addKeyToMemory(const char* uid) +{ + delay(500); + Serial.print(numkeys); + if(numkeys < 10){ + EEPROM.put(numkeys * PASSIVE_ISO_DEP_LEN * sizeof(char), uid); + delay(500); + numkeys++; + delay(500); + Serial.print("Successfully added keys"); + } + else + { + Serial.print("Could not add key"); + } +} + +static void interruptCallback(void) +{ + Serial.write("add a new key to memory\r\n"); + reader_response_t readerResponse = readNFCUID(); + if(readerResponse.nfcUID && readerResponse.tag_type) + { + Serial.write("writing key to memory\r\n"); + addKeyToMemory(readerResponse.nfcUID); + Serial.write("key has been written to memory, returning to normal flow \r\n"); + } + else + { + Serial.write("new key could not be read\r\n"); + } +} diff --git a/nfc_and_servo/src/nfc_read.cpp b/nfc_and_servo/src/nfc_read.cpp new file mode 100644 index 0000000..30c16c5 --- /dev/null +++ b/nfc_and_servo/src/nfc_read.cpp @@ -0,0 +1,311 @@ +#include "nfc_read.h" + +static uint8_t state = DEMO_ST_NOTINIT; +static uint8_t ndefDemoFeature = NDEF_DEMO_READ; +static uint8_t ndefDemoPrevFeature = 0xFF; +static uint8_t NFCID3[] = {0x01, 0xFE, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}; +static uint8_t GB[] = {0x46, 0x66, 0x6d, 0x01, 0x01, 0x11, 0x02, 0x02, 0x07, 0x80, 0x03, 0x02, 0x00, 0x03, 0x04, 0x01, 0x32, 0x07, 0x01, 0x03}; +static rfalNfcDiscoverParam discParam; +static SPIClass dev_spi(SPI_MOSI, SPI_MISO, SPI_SCK); +static RfalRfST25R95Class rfst25r95(&dev_spi, CS_PIN, IRQ_IN_PIN, IRQ_OUT_PIN, INTERFACE_PIN); +static RfalNfcClass rfal_nfc(&rfst25r95); +static NdefClass ndef(&rfal_nfc); +static uint32_t timer; +static uint32_t timerLed; +static bool ledOn; +static const uint8_t *ndefDemoFeatureDescription[] = { + (uint8_t *)"1. Tap a tag to read its content"}; + +void initDevice(void) +{ + dev_spi.begin(); + + if (rfal_nfc.rfalNfcInitialize() == ERR_NONE) + { + discParam.compMode = RFAL_COMPLIANCE_MODE_NFC; + discParam.devLimit = 1U; + discParam.nfcfBR = RFAL_BR_212; + discParam.ap2pBR = RFAL_BR_424; + + ST_MEMCPY(&discParam.nfcid3, NFCID3, sizeof(NFCID3)); + ST_MEMCPY(&discParam.GB, GB, sizeof(GB)); + discParam.GBLen = sizeof(GB); + + discParam.notifyCb = NULL; + discParam.totalDuration = 100U; + discParam.wakeupEnabled = false; + discParam.wakeupConfigDefault = true; + discParam.techs2Find = (RFAL_NFC_POLL_TECH_A | RFAL_NFC_POLL_TECH_B | RFAL_NFC_POLL_TECH_F | RFAL_NFC_POLL_TECH_V | RFAL_NFC_POLL_TECH_ST25TB); + + state = DEMO_ST_START_DISCOVERY; + } +} + +reader_response_t readNFCUID(void) +{ + while (true) + { + static rfalNfcDevice *nfcDevice; + + rfalNfcaSensRes sensRes; + rfalNfcaSelRes selRes; + + rfalNfcbSensbRes sensbRes; + uint8_t sensbResLen; + + uint8_t devCnt = 0; + rfalFeliCaPollRes cardList[1]; + uint8_t collisions = 0U; + rfalNfcfSensfRes *sensfRes; + + rfalNfcvInventoryRes invRes; + uint8_t rcvdLen; + char *uidData = nullptr; + + rfal_nfc.rfalNfcWorker(); + + if (ndefDemoFeature != ndefDemoPrevFeature) + { + ndefDemoPrevFeature = ndefDemoFeature; + Serial.print((char *)ndefDemoFeatureDescription[ndefDemoFeature]); + Serial.print("\r\n"); + } + switch (state) + { + case DEMO_ST_START_DISCOVERY: + ledsOff(); + + rfal_nfc.rfalNfcDeactivate(false); + rfal_nfc.rfalNfcDiscover(&discParam); + + state = DEMO_ST_DISCOVERY; + break; + + case DEMO_ST_DISCOVERY: + if (rfalNfcIsDevActivated(rfal_nfc.rfalNfcGetState())) + { + rfal_nfc.rfalNfcGetActiveDevice(&nfcDevice); + + ledsOff(); + + delay(50); + ndefDemoPrevFeature = 0xFF; /* Force Display of prompt */ + reader_response_t readerResponse = {nullptr, nullptr}; + switch (nfcDevice->type) + { + case RFAL_NFC_LISTEN_TYPE_NFCA: + digitalWrite(LED_A_PIN, HIGH); + switch (nfcDevice->dev.nfca.type) + { + case RFAL_NFCA_T1T: + { + Serial.print("ISO14443A/Topaz (NFC-A T1T) TAG found. UID: "); + readerResponse.tag_type = "ISO1443A/Topaz (NFC-A T1T)"; + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + rfal_nfc.rfalNfcaPollerSleep(); + break; + } + + case RFAL_NFCA_T4T: + Serial.print("NFCA PASSIVE ISO-DEP device found. UID: "); + readerResponse.tag_type = "NFCA PASSIVE ISO-DEP"; + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + // demoNdef(nfcDevice); + rfal_nfc.rfalIsoDepDeselect(); + break; + + case RFAL_NFCA_T4T_NFCDEP: + case RFAL_NFCA_NFCDEP: + { + Serial.print("NFCA Passive P2P device found. NFCID: "); + char tagType[] = "NFCA Passive P2P"; + // readerResponse.tag_type = "NFCA Passive P2P"; + readerResponse.tag_type = tagType; + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + // demoP2P(); + break; + } + + default: + Serial.print("ISO14443A/NFC-A card found. UID: "); + readerResponse.tag_type = "ISO1443A/NFC-A"; + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + // demoNdef(nfcDevice); + rfal_nfc.rfalNfcaPollerSleep(); + break; + } + Serial.print("Operation completed\r\nTag can be removed from the field\r\n"); + uidData = hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen); + rfal_nfc.rfalNfcDeactivate(true); + // return uidData; + readerResponse.nfcUID = uidData; + return readerResponse; + rfal_nfc.rfalNfcaPollerInitialize(); + while (rfal_nfc.rfalNfcaPollerCheckPresence(RFAL_14443A_SHORTFRAME_CMD_WUPA, &sensRes) == ERR_NONE) + { + if (((nfcDevice->dev.nfca.type == RFAL_NFCA_T1T) && + (!rfalNfcaIsSensResT1T(&sensRes))) || + ((nfcDevice->dev.nfca.type != RFAL_NFCA_T1T) && + (rfal_nfc.rfalNfcaPollerSelect(nfcDevice->dev.nfca.nfcId1, + nfcDevice->dev.nfca.nfcId1Len, &selRes) != ERR_NONE))) + { + break; + } + rfal_nfc.rfalNfcaPollerSleep(); + delay(130); + } + break; + + case RFAL_NFC_LISTEN_TYPE_NFCB: + + Serial.print("ISO14443B/NFC-B card found. UID: "); + readerResponse.tag_type = "ISO14443B/NFC-B"; + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + // uidData = hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen); + digitalWrite(LED_B_PIN, HIGH); + // rfal_nfc.rfalNfcDeactivate(true); + // return uidData; + + if (rfalNfcbIsIsoDepSupported(&nfcDevice->dev.nfcb)) + { + // demoNdef(nfcDevice); + rfal_nfc.rfalIsoDepDeselect(); + } + else + { + rfal_nfc.rfalNfcbPollerSleep(nfcDevice->dev.nfcb.sensbRes.nfcid0); + } + /* Loop until tag is removed from the field */ + Serial.print("Operation completed\r\nTag can be removed from the field\r\n"); + uidData = hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen); + rfal_nfc.rfalNfcDeactivate(true); + // return uidData; + readerResponse.nfcUID = uidData; + return readerResponse; + rfal_nfc.rfalNfcbPollerInitialize(); + while (rfal_nfc.rfalNfcbPollerCheckPresence(RFAL_NFCB_SENS_CMD_ALLB_REQ, RFAL_NFCB_SLOT_NUM_1, &sensbRes, &sensbResLen) == ERR_NONE) + { + if (ST_BYTECMP(sensbRes.nfcid0, nfcDevice->dev.nfcb.sensbRes.nfcid0, RFAL_NFCB_NFCID0_LEN) != 0) + { + break; + } + rfal_nfc.rfalNfcbPollerSleep(nfcDevice->dev.nfcb.sensbRes.nfcid0); + delay(130); + } + break; + + case RFAL_NFC_LISTEN_TYPE_NFCF: + + if (rfalNfcfIsNfcDepSupported(&nfcDevice->dev.nfcf)) + { + Serial.print("NFCF Passive P2P device found. NFCID: "); + readerResponse.tag_type = "NFCF Passive P2P device"; + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + // demoP2P(); + } + else + { + Serial.print("Felica/NFC-F card found. UID: "); + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + // demoNdef(nfcDevice); + } + + digitalWrite(LED_F_PIN, HIGH); + /* Loop until tag is removed from the field */ + Serial.print("Operation completed\r\nTag can be removed from the field\r\n"); + uidData = hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen); + rfal_nfc.rfalNfcDeactivate(true); + // return uidData; + readerResponse.nfcUID = uidData; + return readerResponse; + devCnt = 1; + rfal_nfc.rfalNfcfPollerInitialize(RFAL_BR_212); + while (rfal_nfc.rfalNfcfPollerPoll(RFAL_FELICA_1_SLOT, RFAL_NFCF_SYSTEMCODE, RFAL_FELICA_POLL_RC_NO_REQUEST, cardList, &devCnt, &collisions) == ERR_NONE) + { + /* Skip the length field byte */ + sensfRes = (rfalNfcfSensfRes *)&((uint8_t *)cardList)[1]; + if (ST_BYTECMP(sensfRes->NFCID2, nfcDevice->dev.nfcf.sensfRes.NFCID2, RFAL_NFCF_NFCID2_LEN) != 0) + { + break; + } + delay(130); + } + break; + + case RFAL_NFC_LISTEN_TYPE_NFCV: + { + uint8_t devUID[RFAL_NFCV_UID_LEN]; + + ST_MEMCPY(devUID, nfcDevice->nfcid, nfcDevice->nfcidLen); /* Copy the UID into local var */ + REVERSE_BYTES(devUID, RFAL_NFCV_UID_LEN); /* Reverse the UID for display purposes */ + Serial.print("ISO15693/NFC-V card found. UID: "); + readerResponse.tag_type = "ISO15693/NFC-V"; + Serial.print(hex2str(devUID, RFAL_NFCV_UID_LEN)); + Serial.print("\r\n"); + uidData = hex2str(devUID, RFAL_NFCV_UID_LEN); + + digitalWrite(LED_V_PIN, HIGH); + + + // demoNdef(nfcDevice); + + /* Loop until tag is removed from the field */ + Serial.print("Operation completed\r\nTag can be removed from the field\r\n"); + // uidData = nfcDevice->nfcid; + rfal_nfc.rfalNfcDeactivate(true); + readerResponse.nfcUID = uidData; + // return uidData; + return readerResponse; + rfal_nfc.rfalNfcvPollerInitialize(); + while (rfal_nfc.rfalNfcvPollerInventory(RFAL_NFCV_NUM_SLOTS_1, RFAL_NFCV_UID_LEN * 8U, nfcDevice->dev.nfcv.InvRes.UID, &invRes, (uint16_t *)&rcvdLen) == ERR_NONE) + { + delay(130); + } + } + break; + + case RFAL_NFC_LISTEN_TYPE_ST25TB: + + Serial.print("ST25TB card found. UID: "); + readerResponse.tag_type = "ST25TB"; + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + readerResponse.nfcUID = hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen); + return readerResponse; + digitalWrite(LED_B_PIN, HIGH); + break; + + case RFAL_NFC_LISTEN_TYPE_AP2P: + + Serial.print("NFC Active P2P device found. NFCID3: "); + readerResponse.tag_type = "NFC Active P2P"; + Serial.print(hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen)); + Serial.print("\r\n"); + readerResponse.nfcUID = hex2str(nfcDevice->nfcid, nfcDevice->nfcidLen); + return readerResponse; + // demoP2P(); + break; + + default: + break; + } + + rfal_nfc.rfalNfcDeactivate(true); + delay(500); + state = DEMO_ST_START_DISCOVERY; + } + break; + + case DEMO_ST_NOTINIT: + default: + break; + } + } +} \ No newline at end of file diff --git a/nfc_and_servo/src/utils.cpp b/nfc_and_servo/src/utils.cpp new file mode 100644 index 0000000..ac59126 --- /dev/null +++ b/nfc_and_servo/src/utils.cpp @@ -0,0 +1,57 @@ +#include "utils.h" +#include "nfc_utils.h" + +char hexStr[MAX_HEX_STR][MAX_HEX_STR_LENGTH]; +uint8_t hexStrIdx = 0; + +void ledsOn(void) +{ + digitalWrite(LED_A_PIN, HIGH); + digitalWrite(LED_B_PIN, HIGH); + digitalWrite(LED_F_PIN, HIGH); + digitalWrite(LED_V_PIN, HIGH); +} + +void ledsOff(void) +{ + digitalWrite(LED_A_PIN, LOW); + digitalWrite(LED_B_PIN, LOW); + digitalWrite(LED_F_PIN, LOW); + digitalWrite(LED_V_PIN, LOW); +} + +char *hex2str(unsigned char *data, size_t dataLen) +{ + unsigned char *pin = data; + const char *hex = "0123456789ABCDEF"; + char *pout = hexStr[hexStrIdx]; + uint8_t i = 0; + uint8_t idx = hexStrIdx; + size_t len; + + if (dataLen == 0) + { + pout[0] = 0; + } + else + { + /* Trim data taht doesn't fit in buffer */ + len = MIN(dataLen, (MAX_HEX_STR_LENGTH / 2)); + + for(; i < (len - 1); ++i) + { + *pout++ = hex[(*pin >> 4) & 0xF]; + *pout++ = hex[(*pin++) & 0xF]; + *pout = 0; + } + *pout++ = hex[(*pin >> 4) & 0xF]; + *pout++ = hex[(*pin) & 0xF]; + *pout = 0; + } + + hexStrIdx++; + hexStrIdx %= MAX_HEX_STR; + + return hexStr[idx]; + +} \ No newline at end of file diff --git a/nfc_and_servo/test/README b/nfc_and_servo/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/nfc_and_servo/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html -- GitLab