/* STM32 Blue Pill project using the STM32 Arduino Core (stm32duino) */
#include <Wire.h>
#include "Adafruit_PN532.h" // Your manually added library files
// Define I2C pins (though Wire library handles these by default for I2C1)
// #define PN532_SDA PB7 // Not needed for constructor, but good for reference
// #define PN532_SCL PB6 // Not needed for constructor, but good for reference
// Define pins for IRQ and RST (these MUST be provided to the constructor)
// Choose any available GPIO pins on the STM32 that are not used for other purposes.
// For example:
#define PN532_IRQ (PA0)
#define PN532_RST (PA1) // Or use the STM32's actual NRST pin if desired and appropriate
// Instantiate the PN532 object for I2C communication.
// The library will use the default 'Wire' object for I2C.
Adafruit_PN532 nfc(PN532_IRQ, PN532_RST);
// A tiny mapping table: UID[4] → filename
struct Mapping { uint8_t uid[4]; const char* file; };
Mapping table[] = {
{{0xDE,0xAD,0xBE,0xEF}, "audio1.wav"},
{{0xCA,0xFE,0xBA,0xBE}, "audio2.wav"}
};
const int tableSize = sizeof(table) / sizeof(table[0]);
// --- Variables for simulated UID cycling ---
unsigned long lastTagChangeTime = 0;
int currentTableIndex = 0;
bool tagIsVirtuallyPresent = false;
void setup() {
Serial.begin(115200);
// while (!Serial); // Not strictly needed for UART on Blue Pill
Serial.println("Initializing PN532 over I2C...");
// Wire.begin(); // Usually called by STM32duino core, but can be explicit.
nfc.begin(); // This initializes the PN532 library
uint32_t versiondata = nfc.getFirmwareVersion();
Serial.println(versiondata);
if (!versiondata) {
Serial.println(" ERROR: Didn't find PN532 board. Check I2C connections, IRQ/RST pin definitions, and library setup.");
Serial.println(" Ensure VCC/GND for PN532 are also connected.");
while (1); // Halt
}
Serial.print(" Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
Serial.print(" Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);
nfc.SAMConfig(); // Configure board to read ISO14443A tags
Serial.println("PN532 Configured. Simulating tag reads...");
lastTagChangeTime = millis();
}
void loop() {
uint8_t success_read;
uint8_t uid_buffer[7];
uint8_t uid_length;
// Simulate presenting a new tag every 3-5 seconds
if (millis() - lastTagChangeTime > 3000) { // Shortened for faster testing
tagIsVirtuallyPresent = true;
Serial.println("\n--- Simulating NEW TAG ---");
lastTagChangeTime = millis();
}
if (tagIsVirtuallyPresent) {
// --- SIMULATED UID INJECTION (because custom chip has no internal logic for read) ---
Serial.print("Injecting simulated UID: ");
memcpy(uid_buffer, table[currentTableIndex].uid, 4);
uid_length = 4;
for (int i = 0; i < uid_length; i++) { Serial.printf("%02X ", uid_buffer[i]); }
Serial.println();
success_read = 1; // Force success for the lookup part
// --- END OF SIMULATED UID INJECTION ---
// --- IF YOU WERE USING AN OFFICIAL WOKWI PN532 COMPONENT, YOU'D DO THIS INSTEAD: ---
// Serial.println("Attempting to read NFC tag...");
// success_read = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid_buffer, &uid_length, 50); // 50ms timeout
// --- END OF OFFICIAL COMPONENT READ ---
if (success_read) {
// This part will execute due to forced success_read = 1 above
// Serial.println(" Tag 'read' successfully!");
// Serial.print(" UID Length: "); Serial.print(uid_length, DEC); Serial.println(" bytes");
// Serial.print(" UID Value: ");
// for (int i = 0; i < uid_length; i++) {
// Serial.print(" 0x");
// if (uid_buffer[i] < 0x10) Serial.print("0");
// Serial.print(uid_buffer[i], HEX);
// }
// Serial.println(""); // Already printed during injection
const char* fname = "UNKNOWN";
for (int i = 0; i < tableSize; ++i) {
if (uid_length >= 4 && memcmp(table[i].uid, uid_buffer, 4) == 0) {
fname = table[i].file;
break;
}
}
Serial.print(" Mapped to: ");
Serial.println(fname);
currentTableIndex = (currentTableIndex + 1) % tableSize;
} else {
Serial.println(" No tag 'read'."); // This won't be hit with current forced success
}
tagIsVirtuallyPresent = false;
}
}