1
0
Fork 0
Projet_Barbapapa_Firmware/include/RFID.h
trotFunky 85e3295f40 RFID: Clean up and generalize
Add a constant for the ID block used and replace it.

Clean up some comments and clarify expectations.

readBlock() did not properly halt tags after errors and the else
clause was superfluous. Properly handle error status.

Move currentActiveTags to be static and initialize it.
This allows for keeping track of max/current tags accross multiple instances.
2024-01-06 00:15:48 +00:00

103 lines
2.9 KiB
C++

//
// Created by trotfunky on 10/09/23.
//
#ifndef JIN_BARBAPAPA_RFID_H
#define JIN_BARBAPAPA_RFID_H
#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Metro.h>
#include <MFRC522v2.h>
#include <MFRC522DriverPinSimple.h>
#include <MFRC522DriverSPI.h>
#include "IDs.h"
#include "Pinout.h"
/***
* Linked list containing the uids of the tags and the corresponding IDs.
*/
struct uidNode {
MFRC522Constants::Uid uid{};
uidNode* next = nullptr;
// IDs should be positive integers < 127 as the sign bit is used for direction.
int8_t tag_ID = 0;
};
class RFID {
public:
static constexpr int maxTags = 2;
/***
* Use the main SPI port and NFC chip select by default, but allow choosing
* an alternate chip select and/or SPI bus if needed to allow multiple
* RFID readers in parallel.
*/
explicit RFID(const uint8_t chipSelect = pin_NFC1_CS, SPIClass &spiBus = SPI) :
driverPin(chipSelect), driverSpi(driverPin, spiBus),
mfrc(driverSpi), comData{}, sd(SD) {};
void init();
/***
* Check if any new tags are present or have left. Only one event is reported
* at a time, another call would be needed to get eventual concurrent events.
* This updates the respective lists and returns the ID with the direction
* of the change.
* @return 0 if no change, ID if new tag detected, ID & sign bit if the tag left.
*/
int8_t checkTags();
private:
static const byte tagIdBlock = 0x11;
/* Used for "encrypted" communication with the tags. */
static MFRC522Constants::MIFARE_Key defaultKey;
static int currentActiveTags;
/*
* The linked list tracking active tags.
* It is statically allocated so that the memory footprint is constant.
*/
uidNode activeTagsArray[maxTags];
uidNode* activeTags = nullptr;
uidNode* nextFreeTagSlot = activeTagsArray;
MFRC522DriverPinSimple driverPin;
MFRC522DriverSPI driverSpi;
MFRC522 mfrc;
/*
* Array used to read and write blocks to the tags. Blocks are 16 bytes but
* during reads a two-bytes CRC is added.
*/
byte comData[18];
SDClass &sd;
Metro checkGoneTimer{250};
/***
* Add a tag to the static linked list.
* @return The new node, or nullptr if all nodes are allocated.
*/
uidNode* addActiveTag(const MFRC522Constants::Uid &newTagUid);
/***
* Remove goneNode from the list and optionally update its predecessor.
* @param goneNode Node to remove from the list.
* @param previousNode Node to update, can be nullptr if goneNode is the head.
*/
void removeActiveTag(uidNode* goneNode, uidNode* previousNode);
/**
* Read block at blockADdr from tagUid and return if the read succeeded or not.
* The read block will be in comData.
* The tag needs to be already woken up.
* @param tagUid Uid of the tag to be read.
* @param blockAddr Address of the block to be read.
* @return True if read succeeded, false otherwise.
*/
bool readBlock(MFRC522Constants::Uid &tagUid, byte blockAddr);
};
#endif //JIN_BARBAPAPA_RFID_H