From 8dab83dad60e46386c4008c1791725ae754d1712 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Thu, 20 Apr 2023 15:18:00 +0200 Subject: [PATCH] Refactor, add initial PN532 support --- AfRApay.MateCard/include/cardReader.h | 34 -------- AfRApay.MateCard/include/oled.h | 22 +++-- AfRApay.MateCard/include/readers.h | 58 +++++++++++++ AfRApay.MateCard/include/utils.h | 5 ++ AfRApay.MateCard/include/vars.h | 11 ++- AfRApay.MateCard/platformio.ini | 1 + AfRApay.MateCard/src/cardReader.cpp | 54 ------------ AfRApay.MateCard/src/main.cpp | 103 +++++++++++++++-------- AfRApay.MateCard/src/oled.cpp | 86 ++++++++++++------- AfRApay.MateCard/src/readers/mfrc522.cpp | 31 +++++++ AfRApay.MateCard/src/readers/pn532.cpp | 53 ++++++++++++ AfRApay.MateCard/src/readers/rdm6300.cpp | 37 ++++++++ 12 files changed, 339 insertions(+), 156 deletions(-) delete mode 100644 AfRApay.MateCard/include/cardReader.h create mode 100644 AfRApay.MateCard/include/readers.h delete mode 100644 AfRApay.MateCard/src/cardReader.cpp create mode 100644 AfRApay.MateCard/src/readers/mfrc522.cpp create mode 100644 AfRApay.MateCard/src/readers/pn532.cpp create mode 100644 AfRApay.MateCard/src/readers/rdm6300.cpp diff --git a/AfRApay.MateCard/include/cardReader.h b/AfRApay.MateCard/include/cardReader.h deleted file mode 100644 index 608951c..0000000 --- a/AfRApay.MateCard/include/cardReader.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include -#include -#include - -class CardReader { -public: - virtual bool canHaveUnstableIdentifier() = 0; - virtual bool isNewCardPresent() = 0; - virtual String getCardUid() = 0; - virtual void reset() = 0; -}; - -class MFRC522CardReader : public CardReader { -private: - MFRC522* iReader; -public: - explicit MFRC522CardReader(MFRC522* reader); - bool canHaveUnstableIdentifier() override; - bool isNewCardPresent() override; - String getCardUid() override; - void reset() override; -}; - -class RDM6300CardReader : public CardReader { -private: - Rdm6300* iReader; -public: - explicit RDM6300CardReader(Rdm6300* reader); - bool canHaveUnstableIdentifier() override; - bool isNewCardPresent() override; - String getCardUid() override; - void reset() override; -}; diff --git a/AfRApay.MateCard/include/oled.h b/AfRApay.MateCard/include/oled.h index 6176b16..06c2cd7 100644 --- a/AfRApay.MateCard/include/oled.h +++ b/AfRApay.MateCard/include/oled.h @@ -4,8 +4,20 @@ #include "logos.h" #include "utils.h" -void drawLogo(U8G2 u8g2, e_logo logo); -void drawStatusText(U8G2 u8g2, const String& status, const String& statusRightAligned = ""); - -void updateOLED(U8G2 u8g2, e_state state, const String& statusText, const String& statusTextRightAligned = ""); -void updateOLED(const U8G2& u8g2, e_state state); +class OLED { +private: + U8G2 u8g2; + String revision; + void drawCurvedLineV(int xStart, int yStart, int vert, int horiz); + void drawCurvedLine(int xStart, int yStart, int horiz, int vert); + void drawLogoAfraPay(); + void drawLogoBitmap(int width, int height, unsigned char bits[], int yOffset = 0); + void drawFullScreenText(const String& textTop, const String& textBottom); +public: + explicit OLED(U8G2 u8g2); + void begin(); + void drawLogo(e_logo logo); + void drawStatusText(const String& status, const String& statusRightAligned = ""); + void updateOLED(e_state state, const String& statusText, const String& statusTextRightAligned = ""); + void updateOLED(e_state state); +}; diff --git a/AfRApay.MateCard/include/readers.h b/AfRApay.MateCard/include/readers.h new file mode 100644 index 0000000..769451a --- /dev/null +++ b/AfRApay.MateCard/include/readers.h @@ -0,0 +1,58 @@ +#pragma once +#include +#include +#include +#include + +class Reader { +public: + virtual bool canHaveUnstableIdentifier() = 0; + virtual bool isNewCardPresent() = 0; + virtual String getCardUid() = 0; + virtual void begin() = 0; + virtual void reset() = 0; + virtual void init() = 0; + virtual void end() = 0; +}; + +class MFRC522Reader : public Reader { +private: + MFRC522* mfrc522; +public: + explicit MFRC522Reader(byte chipSelectPin, byte resetPowerDownPin); + bool canHaveUnstableIdentifier() override; + bool isNewCardPresent() override; + String getCardUid() override; + void reset() override; + void init() override; +}; + +class RDM6300Reader : public Reader { +private: + Rdm6300* rdm6300; + int pin; +public: + explicit RDM6300Reader(int pin); + bool canHaveUnstableIdentifier() override; + bool isNewCardPresent() override; + String getCardUid() override; + void reset() override; + void init() override; +}; + +class PN532Reader : public Reader { +private: + Adafruit_PN532* pn532; + uint8_t uid[7]; + uint8_t uidLength; +public: + static volatile int irq; + explicit PN532Reader(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss); + bool canHaveUnstableIdentifier() override; + bool isNewCardPresent() override; + String getCardUid() override; + void begin() override; + void reset() override; + void init() override; + void end() override; +}; diff --git a/AfRApay.MateCard/include/utils.h b/AfRApay.MateCard/include/utils.h index 0c3b1fe..d23f568 100644 --- a/AfRApay.MateCard/include/utils.h +++ b/AfRApay.MateCard/include/utils.h @@ -22,3 +22,8 @@ enum e_state { STATE_RESULT_FAILURE, STATE_RESULT_DISPLAY, }; + +enum e_scanstate { + SCANSTATE_IDLE, + SCANSTATE_ACTIVE, +}; diff --git a/AfRApay.MateCard/include/vars.h b/AfRApay.MateCard/include/vars.h index a83ed80..f968f77 100644 --- a/AfRApay.MateCard/include/vars.h +++ b/AfRApay.MateCard/include/vars.h @@ -10,13 +10,21 @@ #ifndef AFRAPAY_GIT_COMMIT #define AFRAPAY_GIT_COMMIT "unknown" #endif + +/* + * We're using an Az-Delivery ESP-32 Kit: + * Product: https://web.archive.org/web/20230420182915/https://www.azdelivery.de/en/products/esp32-developmentboard + * Pinout: https://web.archive.org/web/20210901112537/https://cdn.shopify.com/s/files/1/1509/1638/files/ESP-32_NodeMCU_Developmentboard_Pinout.pdf + * Datasheet: https://web.archive.org/web/20221209154701/https://cdn.shopify.com/s/files/1/1509/1638/files/ESP-32_NodeMCU_Developmentboard_Schematic_korr.pdf?v=1666000508 + */ + //MFRC522 pinout (front) 3V3 RST GND IRQ MISO MOSI SCK SDA //MFRC522 pinout (rear) SDA SCK MOSI MISO IRQ GND RST 3V3 #define PIN_HSPI_RST 4 #define PIN_HSPI_MISO 12 #define PIN_HSPI_MOSI 13 #define PIN_HSPI_SCLK 14 -#define PIN_HSPI_SS 15 +#define PIN_HSPI_CS0 15 //CS0 (Chip Select 0) = SS channel 0 #define PIN_HWSERIAL_RX 16 #define PIN_HWSERIAL_TX 17 #define PIN_BUZZER 19 @@ -26,3 +34,4 @@ #define PIN_INTERRUPT_BALANCE 25 #define PIN_INTERRUPT_LINK 33 #define PIN_INTERRUPT_CANCEL 32 +#define PIN_INTERRUPT_IRQ_PN532 27 diff --git a/AfRApay.MateCard/platformio.ini b/AfRApay.MateCard/platformio.ini index 99c6c64..86843d2 100644 --- a/AfRApay.MateCard/platformio.ini +++ b/AfRApay.MateCard/platformio.ini @@ -23,6 +23,7 @@ lib_deps = mcxiaoke/ESPDateTime@^1.0.4 arduino12/rdm6300@^2.0.0 bblanchon/ArduinoJson@^6.20.0 + adafruit/Adafruit PN532@^1.3.0 check_tool = clangtidy check_flags = clangtidy: --config-file=.clang-tidy diff --git a/AfRApay.MateCard/src/cardReader.cpp b/AfRApay.MateCard/src/cardReader.cpp deleted file mode 100644 index df24a6c..0000000 --- a/AfRApay.MateCard/src/cardReader.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include "utils.h" -#include "cardReader.h" - -MFRC522CardReader::MFRC522CardReader(MFRC522* reader) { - iReader = reader; -} - -bool MFRC522CardReader::isNewCardPresent() { - return iReader->PICC_IsNewCardPresent() && iReader->PICC_ReadCardSerial(); -} - -String MFRC522CardReader::getCardUid() { - return byteArrayAsHexString(iReader->uid.uidByte, iReader->uid.size); -} - -void MFRC522CardReader::reset() { - iReader->PCD_AntennaOff(); - iReader->PCD_Init(); - iReader->PCD_AntennaOn(); -} - -inline bool MFRC522CardReader::canHaveUnstableIdentifier() { - return true; -} - -RDM6300CardReader::RDM6300CardReader(Rdm6300* reader) { - iReader = reader; -} - -bool RDM6300CardReader::isNewCardPresent() { - return iReader->get_new_tag_id(); -} - -String RDM6300CardReader::getCardUid() { - auto uid = iReader->get_tag_id(); - char buf[16]; - sprintf(buf, "%010u", uid); - return {buf}; -} - -void RDM6300CardReader::reset() { - /* - * We don't need to do anything here - * RDM6300 readers don't report a new card as present til the old card is removed and re-presented - */ -} - -inline bool RDM6300CardReader::canHaveUnstableIdentifier() { - // As far as I am aware, there are no 125khz tags with unstable identifiers - return false; -} diff --git a/AfRApay.MateCard/src/main.cpp b/AfRApay.MateCard/src/main.cpp index 2ca800a..dad9590 100644 --- a/AfRApay.MateCard/src/main.cpp +++ b/AfRApay.MateCard/src/main.cpp @@ -6,40 +6,44 @@ #include #include #include -#include #include #include -#include #include "wifiFix.h" #include "pitches.h" #include "utils.h" #include "oled.h" -#include "cardReader.h" +#include "readers.h" #include "vars.h" -U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); -MFRC522 mfrc522(PIN_HSPI_SS, PIN_HSPI_RST); +OLED oled(U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE)); WiFiClient* wifi = new WiFiClientFixed(); HTTPClient* http = new HTTPClient(); -Rdm6300 rdm6300; -auto mfrc522reader = MFRC522CardReader(&mfrc522); -auto rdm6300reader = RDM6300CardReader(&rdm6300); -CardReader* readers[2] = {&mfrc522reader, &rdm6300reader}; +Reader* readers[] = { + //new MFRC522CardReader(PIN_HSPI_SS, PIN_HSPI_RST), + new PN532Reader(PIN_HSPI_SCLK, PIN_HSPI_MISO, PIN_HSPI_MOSI, PIN_HSPI_CS0), + //new RDM6300Reader(PIN_HWSERIAL_RX) +}; e_state state = STATE_IDLE; +e_scanstate scanstate = SCANSTATE_IDLE; String apiUrl = ""; const int gTimeout = 5000; const int scanTimeout = 15000; -CardReader* scannedCardReader; +Reader* scannedCardReader; String scannedCardId = ""; String lastStatusText = ""; + volatile bool interruptFired = false; unsigned long timer = 0; +void IRAM_ATTR PN532_IRQ() { + PN532Reader::irq++; +} + void IRAM_ATTR TransactInterruptHandler() { if (interruptFired || state != STATE_IDLE || digitalRead(PIN_INTERRUPT_TRANSACT)) { return; @@ -73,28 +77,58 @@ void IRAM_ATTR CancelInterruptHandler() { bool cooldownCheck(long timeout) { if (millis() - timer > timeout) { state = STATE_IDLE; - updateOLED(u8g2, state); + oled.updateOLED(state); return true; } return false; } +void updateCardscan() { + switch (state) { + case STATE_TRANSACT_CARDSCAN: + case STATE_LINK_CARD_SCAN: + case STATE_LINK_CARD_RESCAN: + case STATE_BALANCE_CARDSCAN: + if (scanstate == SCANSTATE_ACTIVE) + return; + + for (Reader* reader : readers) { + reader->begin(); + } + scanstate = SCANSTATE_ACTIVE; + break; + case STATE_IDLE: + case STATE_TRANSACT_VERIFY: + case STATE_LINK_VERIFY: + case STATE_BALANCE_VERIFY: + case STATE_RESULT_SUCCESS: + case STATE_RESULT_FAILURE: + case STATE_RESULT_DISPLAY: + if (scanstate == SCANSTATE_IDLE) + return; + + for (Reader* reader : readers) { + reader->end(); + } + scanstate = SCANSTATE_IDLE; + break; + } +} + void setup() { Serial.begin(115200); + oled.begin(); Serial2.begin(115200, SERIAL_8N1, PIN_HWSERIAL_RX, PIN_HWSERIAL_TX); SPI.begin(PIN_HSPI_SCLK, PIN_HSPI_MISO, PIN_HSPI_MOSI); ledcSetup(0, 5000, 12); + pinMode(PIN_INTERRUPT_IRQ_PN532, INPUT_PULLUP); pinMode(PIN_INTERRUPT_TRANSACT, INPUT_PULLUP); pinMode(PIN_INTERRUPT_BALANCE, INPUT_PULLUP); pinMode(PIN_INTERRUPT_CANCEL, INPUT_PULLUP); pinMode(PIN_INTERRUPT_LINK, INPUT_PULLUP); - u8g2.begin(); - drawLogo(u8g2, LOGO_MATECARD); - u8g2.sendBuffer(); - SPIFFS.begin(true); WiFiSettings.hostname = "afrapay-"; apiUrl = WiFiSettings.string("AfRApay.Web API", "http://192.168.50.170:5296"); @@ -103,14 +137,15 @@ void setup() { else WiFiSettings.connect(); - rdm6300.begin(PIN_HWSERIAL_RX); - rdm6300.set_tag_timeout(65); - mfrc522.PCD_Init(); - mfrc522.PCD_DumpVersionToSerial(); + for (Reader* reader : readers) { + reader->init(); + } + DateTime.setTimeZone(TZ_Europe_Berlin); DateTime.begin(); - updateOLED(u8g2, state); + oled.updateOLED(state); + attachInterrupt(PIN_INTERRUPT_IRQ_PN532, PN532_IRQ, FALLING); attachInterrupt(PIN_INTERRUPT_TRANSACT, TransactInterruptHandler, FALLING); attachInterrupt(PIN_INTERRUPT_BALANCE, BalanceInterruptHandler, FALLING); attachInterrupt(PIN_INTERRUPT_CANCEL, CancelInterruptHandler, FALLING); @@ -119,13 +154,15 @@ void setup() { void loop() { if (WiFiClass::status() != WL_CONNECTED) { - updateOLED(u8g2, state, "WiFi disconnected :("); + oled.updateOLED(state, "WiFi disconnected :("); state = STATE_IDLE; WiFi.reconnect(); delay(50); return; } + updateCardscan(); + if (interruptFired) { timer = millis(); interruptFired = false; @@ -133,10 +170,10 @@ void loop() { switch (state) { case STATE_IDLE: - updateOLED(u8g2, state); + oled.updateOLED(state); break; case STATE_TRANSACT_CARDSCAN: - for (CardReader* reader : readers) { + for (Reader* reader : readers) { if (reader->isNewCardPresent()) { scannedCardId = reader->getCardUid(); lastStatusText = "Card #" + scannedCardId; @@ -146,11 +183,11 @@ void loop() { } } if (!cooldownCheck(scanTimeout)) { - updateOLED(u8g2, state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer))); + oled.updateOLED(state, String("1.50€"), String(cooldownSecondsRemaining(scanTimeout, timer))); } break; case STATE_TRANSACT_VERIFY: - updateOLED(u8g2, state, lastStatusText); + oled.updateOLED(state, lastStatusText); tone(PIN_BUZZER, NOTE_A5, 25); tone(PIN_BUZZER, NOTE_NONE, 150); lastStatusText = cardTransaction(wifi, http, apiUrl, scannedCardId, "-150"); @@ -167,7 +204,7 @@ void loop() { timer = millis(); return; case STATE_LINK_CARD_SCAN: - for (CardReader* reader : readers) { + for (Reader* reader : readers) { if (reader->isNewCardPresent()) { scannedCardReader = reader; scannedCardId = reader->getCardUid(); @@ -185,7 +222,7 @@ void loop() { } } if (!cooldownCheck(scanTimeout)) { - updateOLED(u8g2, state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer))); + oled.updateOLED(state, "Link", String(cooldownSecondsRemaining(scanTimeout, timer))); } break; case STATE_LINK_CARD_RESCAN: @@ -202,11 +239,11 @@ void loop() { } } if (!cooldownCheck(scanTimeout)) { - updateOLED(u8g2, state, "Link - rescan", String(cooldownSecondsRemaining(scanTimeout, timer))); + oled.updateOLED(state, "Link - rescan ", String(cooldownSecondsRemaining(scanTimeout, timer))); } break; case STATE_LINK_VERIFY: - updateOLED(u8g2, state, lastStatusText); + oled.updateOLED(state, lastStatusText); tone(PIN_BUZZER, NOTE_A5, 25); tone(PIN_BUZZER, NOTE_NONE, 150); lastStatusText = cardLink(wifi, http, apiUrl, scannedCardId); @@ -225,7 +262,7 @@ void loop() { timer = millis(); return; case STATE_BALANCE_CARDSCAN: - for (CardReader* reader : readers) { + for (Reader* reader : readers) { if (reader->isNewCardPresent()) { scannedCardId = reader->getCardUid(); lastStatusText = "Card #" + scannedCardId; @@ -234,11 +271,11 @@ void loop() { } } if (!cooldownCheck(scanTimeout)) { - updateOLED(u8g2, state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer))); + oled.updateOLED(state, "Balance", String(cooldownSecondsRemaining(scanTimeout, timer))); } break; case STATE_BALANCE_VERIFY: - updateOLED(u8g2, state, lastStatusText); + oled.updateOLED(state, lastStatusText); tone(PIN_BUZZER, NOTE_A5, 25); tone(PIN_BUZZER, NOTE_NONE, 150); lastStatusText = cardBalance(wifi, http, apiUrl, scannedCardId); @@ -261,7 +298,7 @@ void loop() { case STATE_RESULT_FAILURE: case STATE_RESULT_DISPLAY: if (!cooldownCheck(gTimeout)) { - updateOLED(u8g2, state, lastStatusText, String(cooldownSecondsRemaining(gTimeout, timer))); + oled.updateOLED(state, lastStatusText, String(cooldownSecondsRemaining(gTimeout, timer))); } break; } diff --git a/AfRApay.MateCard/src/oled.cpp b/AfRApay.MateCard/src/oled.cpp index 2ab0cae..61ce708 100644 --- a/AfRApay.MateCard/src/oled.cpp +++ b/AfRApay.MateCard/src/oled.cpp @@ -1,12 +1,38 @@ #include #include + +#include #include "Arduino.h" #include "U8g2lib.h" #include "logos.h" #include "utils.h" #include "vars.h" +#include "oled.h" -void drawCurvedLineV(U8G2 u8g2, int xStart, int yStart, int vert, int horiz) { +OLED::OLED(U8G2 u8g2) { + this->u8g2 = std::move(u8g2); +} + +void OLED::begin() { + u8g2.begin(); + u8g2.setFont(u8g2_font_bpixel_te); + u8g2_uint_t maxLength = 127 - u8g2.getUTF8Width("00:00:00 "); + + if (u8g2.getUTF8Width(AFRAPAY_GIT_BRANCH "-" AFRAPAY_GIT_COMMIT) < maxLength) { + revision = AFRAPAY_GIT_BRANCH "-" AFRAPAY_GIT_COMMIT; + } + else if (u8g2.getUTF8Width(AFRAPAY_GIT_BRANCH) < maxLength) { + revision = AFRAPAY_GIT_BRANCH; + } + else if (u8g2.getUTF8Width(AFRAPAY_GIT_COMMIT) < maxLength) { + revision = AFRAPAY_GIT_COMMIT; + } + + drawLogo(LOGO_MATECARD); + u8g2.sendBuffer(); +} + +void OLED::drawCurvedLineV(int xStart, int yStart, int vert, int horiz) { u8g2.drawVLine(xStart, yStart + 1, vert); u8g2.drawVLine(xStart + 1, yStart, vert); @@ -14,7 +40,7 @@ void drawCurvedLineV(U8G2 u8g2, int xStart, int yStart, int vert, int horiz) { u8g2.drawHLine(xStart + 1, yStart + vert + 1, horiz); } -void drawCurvedLine(U8G2 u8g2, int xStart, int yStart, int horiz, int vert) { +void OLED::drawCurvedLine(int xStart, int yStart, int horiz, int vert) { u8g2.drawHLine(xStart, yStart, horiz); u8g2.drawHLine(xStart, yStart + 1, horiz); @@ -22,7 +48,7 @@ void drawCurvedLine(U8G2 u8g2, int xStart, int yStart, int horiz, int vert) { u8g2.drawVLine(xStart + horiz + 1, yStart + 1, vert); } -void drawLogoAfraPay(U8G2 u8g2) { +void OLED::drawLogoAfraPay() { u8g2.setFontMode(1); u8g2.setFontDirection(0); @@ -39,42 +65,42 @@ void drawLogoAfraPay(U8G2 u8g2) { //u8g2.drawHLine(0, yOffset-12, xOffset); //u8g2.drawHLine(127-xOffset-1, yOffset, xOffset); - drawCurvedLineV(u8g2, xOffset + 69, yOffset, 7, 32); - drawCurvedLine(u8g2, xOffset + 73, yOffset - 8, 28, 15); + drawCurvedLineV(xOffset + 69, yOffset, 7, 32); + drawCurvedLine(xOffset + 73, yOffset - 8, 28, 15); u8g2.drawPixel(xOffset + 101, yOffset + 7); } -void drawLogoBitmap(U8G2 u8g2, int width, int height, unsigned char bits[], int yOffset = 0) { +void OLED::drawLogoBitmap(int width, int height, unsigned char bits[], int yOffset) { int offset = (128 - width) / 2; u8g2.drawXBM(offset, yOffset, width, height, bits); } -void drawLogo(U8G2 u8g2, e_logo logo) { +void OLED::drawLogo(e_logo logo) { switch (logo) { case LOGO_AFRAPAY: - drawLogoAfraPay(u8g2); + drawLogoAfraPay(); break; case LOGO_CONTACTLESS: - drawLogoBitmap(u8g2, contactless_width, contactless_height, contactless_bits); + drawLogoBitmap( contactless_width, contactless_height, contactless_bits); break; case LOGO_MATECARD: - drawLogoBitmap(u8g2, matecard_width, matecard_height, matecard_bits, 5); + drawLogoBitmap(matecard_width, matecard_height, matecard_bits, 5); u8g2.setFont(u8g2_font_bpixeldouble_tr); u8g2.drawStr((126 - u8g2.getStrWidth("matecard")) / 2, 57, "matecard"); break; case LOGO_PENDING: - drawLogoBitmap(u8g2, pending_width, pending_height, pending_bits, 5); + drawLogoBitmap(pending_width, pending_height, pending_bits, 5); break; case LOGO_SUCCESS: - drawLogoBitmap(u8g2, success_width, success_height, success_bits, 5); + drawLogoBitmap(success_width, success_height, success_bits, 5); break; case LOGO_FAILURE: - drawLogoBitmap(u8g2, failure_width, failure_height, failure_bits, 5); + drawLogoBitmap(failure_width, failure_height, failure_bits, 5); break; } } -void drawStatusText(U8G2 u8g2, const String& status, const String& statusRightAligned = "") { +void OLED::drawStatusText(const String& status, const String& statusRightAligned) { u8g2.setFont(u8g2_font_bpixel_te); u8g2.drawUTF8(0, 61, status.c_str()); @@ -84,52 +110,54 @@ void drawStatusText(U8G2 u8g2, const String& status, const String& statusRightAl } } -void drawFullScreenText(U8G2 u8g2, const String& textTop, const String& textBottom) { +void OLED::drawFullScreenText(const String& textTop, const String& textBottom) { u8g2.setFont(u8g2_font_chargen_92_tr); u8g2.drawUTF8((127-u8g2.getUTF8Width(textTop.c_str()))/2, 13, textTop.c_str()); u8g2.setFont(u8g2_font_maniac_te); u8g2.drawUTF8((127-u8g2.getUTF8Width(textBottom.c_str()))/2, 45, textBottom.c_str()); } -void updateOLED(U8G2 u8g2, e_state state, const String& statusText, const String& statusTextRightAligned = "") { +void OLED::updateOLED(e_state state, const String& statusText, const String& statusTextRightAligned) { u8g2.clearBuffer(); switch (state) { case STATE_IDLE: - drawLogo(u8g2, LOGO_AFRAPAY); + drawLogo(LOGO_AFRAPAY); break; case STATE_TRANSACT_CARDSCAN: case STATE_BALANCE_CARDSCAN: case STATE_LINK_CARD_SCAN: case STATE_LINK_CARD_RESCAN: - drawLogo(u8g2, LOGO_CONTACTLESS); + drawLogo(LOGO_CONTACTLESS); break; case STATE_RESULT_SUCCESS: - drawLogo(u8g2, LOGO_SUCCESS); + drawLogo(LOGO_SUCCESS); break; case STATE_RESULT_FAILURE: - drawLogo(u8g2, LOGO_FAILURE); + drawLogo(LOGO_FAILURE); break; case STATE_RESULT_DISPLAY: - drawFullScreenText(u8g2, splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "€"); - drawStatusText(u8g2, splitString(statusText, ':', 2), statusTextRightAligned); + drawFullScreenText(splitString(statusText, ':', 0), splitString(statusText, ':', 1) + "€"); + drawStatusText(splitString(statusText, ':', 2), statusTextRightAligned); u8g2.sendBuffer(); return; case STATE_TRANSACT_VERIFY: case STATE_BALANCE_VERIFY: case STATE_LINK_VERIFY: - drawLogo(u8g2, LOGO_PENDING); + drawLogo(LOGO_PENDING); break; } - drawStatusText(u8g2, statusText, statusTextRightAligned); + drawStatusText(statusText, statusTextRightAligned); u8g2.sendBuffer(); } -void updateOLED(const U8G2& u8g2, e_state state) { +void OLED::updateOLED(e_state state) { String time = DateTime.format(DateFormatter::TIME_ONLY); - if (!digitalRead(PIN_INTERRUPT_CANCEL) || millis()%20000 < 10000) - updateOLED(u8g2, state, time, AFRAPAY_GIT_COMMIT); - else - updateOLED(u8g2, state, time, WiFi.localIP().toString()); + if (!digitalRead(PIN_INTERRUPT_CANCEL) || millis()%20000 < 10000) { + updateOLED(state, time, revision); + } + else { + updateOLED(state, time, WiFi.localIP().toString()); + } } diff --git a/AfRApay.MateCard/src/readers/mfrc522.cpp b/AfRApay.MateCard/src/readers/mfrc522.cpp new file mode 100644 index 0000000..7495c0b --- /dev/null +++ b/AfRApay.MateCard/src/readers/mfrc522.cpp @@ -0,0 +1,31 @@ +#include +#include "MFRC522.h" +#include "utils.h" +#include "readers.h" + +MFRC522Reader::MFRC522Reader(byte chipSelectPin, byte resetPowerDownPin) { + mfrc522 = new MFRC522(chipSelectPin, resetPowerDownPin); +} + +bool MFRC522Reader::isNewCardPresent() { + return mfrc522->PICC_IsNewCardPresent() && mfrc522->PICC_ReadCardSerial(); +} + +String MFRC522Reader::getCardUid() { + return byteArrayAsHexString(mfrc522->uid.uidByte, mfrc522->uid.size); +} + +void MFRC522Reader::reset() { + mfrc522->PCD_AntennaOff(); + mfrc522->PCD_Init(); + mfrc522->PCD_AntennaOn(); +} + +inline bool MFRC522Reader::canHaveUnstableIdentifier() { + return true; +} + +void MFRC522Reader::init() { + mfrc522->PCD_Init(); + mfrc522->PCD_DumpVersionToSerial(); +} diff --git a/AfRApay.MateCard/src/readers/pn532.cpp b/AfRApay.MateCard/src/readers/pn532.cpp new file mode 100644 index 0000000..3610728 --- /dev/null +++ b/AfRApay.MateCard/src/readers/pn532.cpp @@ -0,0 +1,53 @@ +#include +#include "utils.h" +#include "readers.h" +#include "vars.h" + +volatile int PN532Reader::irq = 0; + +PN532Reader::PN532Reader(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t ss) { + pn532 = new Adafruit_PN532(clk, miso, mosi, ss); +} + +void PN532Reader::begin() { + pn532->begin(); + irq = 0; + pn532->startPassiveTargetIDDetection(PN532_MIFARE_ISO14443A); +} + +void PN532Reader::end() { + pn532->sendCommandCheckAck(new byte[1]{PN532_COMMAND_POWERDOWN}, 1, 1); +} + +bool PN532Reader::isNewCardPresent() { + return irq > 1; +} + +String PN532Reader::getCardUid() { + pn532->readDetectedPassiveTargetID(uid, &uidLength); + Serial.println(byteArrayAsHexString(uid, uidLength)); + return byteArrayAsHexString(uid, uidLength); +} + +void PN532Reader::reset() { + this->end(); + this->begin(); +} + +inline bool PN532Reader::canHaveUnstableIdentifier() { + return true; +} + +void PN532Reader::init() { + pn532->begin(); + uint32_t version = pn532->getFirmwareVersion(); + if (!version) { + Serial.print("Couldn't find PN53x board"); + return; + //esp_restart(); + } + + Serial.print("Found chip PN5"); Serial.println((version>>24) & 0xFF, HEX); + Serial.print("Firmware ver. "); Serial.print((version>>16) & 0xFF, DEC); + Serial.print('.'); Serial.println((version>>8) & 0xFF, DEC); +} diff --git a/AfRApay.MateCard/src/readers/rdm6300.cpp b/AfRApay.MateCard/src/readers/rdm6300.cpp new file mode 100644 index 0000000..11de7e5 --- /dev/null +++ b/AfRApay.MateCard/src/readers/rdm6300.cpp @@ -0,0 +1,37 @@ +#include +#include "rdm6300.h" +#include "utils.h" +#include "readers.h" + +RDM6300Reader::RDM6300Reader(int pin) { + this->pin = pin; + rdm6300 = new Rdm6300; +} + +bool RDM6300Reader::isNewCardPresent() { + return rdm6300->get_new_tag_id(); +} + +String RDM6300Reader::getCardUid() { + auto uid = rdm6300->get_tag_id(); + char buf[16]; + sprintf(buf, "%010u", uid); + return {buf}; +} + +void RDM6300Reader::reset() { + /* + * We don't need to do anything here + * RDM6300 readers don't report a new card as present til the old card is removed and re-presented + */ +} + +inline bool RDM6300Reader::canHaveUnstableIdentifier() { + // As far as I am aware, there are no 125khz tags with unstable identifiers + return false; +} + +void RDM6300Reader::init() { + rdm6300->begin(pin); + rdm6300->set_tag_timeout(65); +}