mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
[P111] Enable support for configurable SPI bus (and reformat source)
This commit is contained in:
+24
-23
@@ -29,11 +29,12 @@ MFRC522::MFRC522( uint8_t resetPowerDownPin ///< Arduino pin connected to MFRC52
|
||||
* Prepares the output pins.
|
||||
*/
|
||||
MFRC522::MFRC522( uint8_t chipSelectPin, ///< Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
|
||||
uint8_t resetPowerDownPin ///< Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low). If there is no connection from the CPU to NRSTPD, set this to UINT8_MAX. In this case, only soft reset will be used in PCD_Init().
|
||||
) {
|
||||
_chipSelectPin = chipSelectPin;
|
||||
_resetPowerDownPin = resetPowerDownPin;
|
||||
} // End constructor
|
||||
uint8_t resetPowerDownPin, ///< Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low). If there is no connection from the CPU to NRSTPD, set this to UINT8_MAX. In this case, only soft reset will be used in PCD_Init().
|
||||
SPIClass& spi) :
|
||||
_chipSelectPin(chipSelectPin),
|
||||
_resetPowerDownPin(resetPowerDownPin),
|
||||
_spi(spi)
|
||||
{} // End constructor
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// Basic interface functions for communicating with the MFRC522
|
||||
@@ -46,12 +47,12 @@ MFRC522::MFRC522( uint8_t chipSelectPin, ///< Arduino pin connected to MFRC522'
|
||||
void MFRC522::PCD_WriteRegister( PCD_Register reg, ///< The register to write to. One of the PCD_Register enums.
|
||||
uint8_t value ///< The value to write.
|
||||
) {
|
||||
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
|
||||
_spi.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
|
||||
digitalWrite(_chipSelectPin, LOW); // Select slave
|
||||
SPI.transfer(reg); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
SPI.transfer(value);
|
||||
_spi.transfer(reg); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
_spi.transfer(value);
|
||||
digitalWrite(_chipSelectPin, HIGH); // Release slave again
|
||||
SPI.endTransaction(); // Stop using the SPI bus
|
||||
_spi.endTransaction(); // Stop using the SPI bus
|
||||
} // End PCD_WriteRegister()
|
||||
|
||||
/**
|
||||
@@ -62,14 +63,14 @@ void MFRC522::PCD_WriteRegister( PCD_Register reg, ///< The register to write to
|
||||
uint8_t count, ///< The number of bytes to write to the register
|
||||
uint8_t *values ///< The values to write. Byte array.
|
||||
) {
|
||||
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
|
||||
_spi.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
|
||||
digitalWrite(_chipSelectPin, LOW); // Select slave
|
||||
SPI.transfer(reg); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
_spi.transfer(reg); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
for (uint8_t index = 0; index < count; index++) {
|
||||
SPI.transfer(values[index]);
|
||||
_spi.transfer(values[index]);
|
||||
}
|
||||
digitalWrite(_chipSelectPin, HIGH); // Release slave again
|
||||
SPI.endTransaction(); // Stop using the SPI bus
|
||||
_spi.endTransaction(); // Stop using the SPI bus
|
||||
} // End PCD_WriteRegister()
|
||||
|
||||
/**
|
||||
@@ -79,12 +80,12 @@ void MFRC522::PCD_WriteRegister( PCD_Register reg, ///< The register to write to
|
||||
uint8_t MFRC522::PCD_ReadRegister( PCD_Register reg ///< The register to read from. One of the PCD_Register enums.
|
||||
) {
|
||||
uint8_t value;
|
||||
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
|
||||
_spi.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
|
||||
digitalWrite(_chipSelectPin, LOW); // Select slave
|
||||
SPI.transfer(0x80 | reg); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
value = SPI.transfer(0); // Read the value back. Send 0 to stop reading.
|
||||
_spi.transfer(0x80 | reg); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
value = _spi.transfer(0); // Read the value back. Send 0 to stop reading.
|
||||
digitalWrite(_chipSelectPin, HIGH); // Release slave again
|
||||
SPI.endTransaction(); // Stop using the SPI bus
|
||||
_spi.endTransaction(); // Stop using the SPI bus
|
||||
return value;
|
||||
} // End PCD_ReadRegister()
|
||||
|
||||
@@ -103,26 +104,26 @@ void MFRC522::PCD_ReadRegister( PCD_Register reg, ///< The register to read from
|
||||
//Serial.print(F("Reading ")); Serial.print(count); Serial.println(F(" bytes from register."));
|
||||
uint8_t address = 0x80 | reg; // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
|
||||
uint8_t index = 0; // Index in values array.
|
||||
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
|
||||
_spi.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
|
||||
digitalWrite(_chipSelectPin, LOW); // Select slave
|
||||
count--; // One read is performed outside of the loop
|
||||
SPI.transfer(address); // Tell MFRC522 which address we want to read
|
||||
_spi.transfer(address); // Tell MFRC522 which address we want to read
|
||||
if (rxAlign) { // Only update bit positions rxAlign..7 in values[0]
|
||||
// Create bit mask for bit positions rxAlign..7
|
||||
uint8_t mask = (0xFF << rxAlign) & 0xFF;
|
||||
// Read value and tell that we want to read the same address again.
|
||||
uint8_t value = SPI.transfer(address);
|
||||
uint8_t value = _spi.transfer(address);
|
||||
// Apply mask to both current value of values[0] and the new data in value.
|
||||
values[0] = (values[0] & ~mask) | (value & mask);
|
||||
index++;
|
||||
}
|
||||
while (index < count) {
|
||||
values[index] = SPI.transfer(address); // Read value and tell that we want to read the same address again.
|
||||
values[index] = _spi.transfer(address); // Read value and tell that we want to read the same address again.
|
||||
index++;
|
||||
}
|
||||
values[index] = SPI.transfer(0); // Read the final byte. Send 0 to stop reading.
|
||||
values[index] = _spi.transfer(0); // Read the final byte. Send 0 to stop reading.
|
||||
digitalWrite(_chipSelectPin, HIGH); // Release slave again
|
||||
SPI.endTransaction(); // Stop using the SPI bus
|
||||
_spi.endTransaction(); // Stop using the SPI bus
|
||||
} // End PCD_ReadRegister()
|
||||
|
||||
/**
|
||||
|
||||
@@ -293,7 +293,7 @@ public:
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
MFRC522();
|
||||
MFRC522(uint8_t resetPowerDownPin);
|
||||
MFRC522(uint8_t chipSelectPin, uint8_t resetPowerDownPin);
|
||||
MFRC522(uint8_t chipSelectPin, uint8_t resetPowerDownPin, SPIClass& spi = SPI);
|
||||
virtual ~MFRC522() {};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -389,6 +389,7 @@ public:
|
||||
protected:
|
||||
uint8_t _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
|
||||
uint8_t _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
|
||||
SPIClass& _spi = SPI;
|
||||
StatusCode MIFARE_TwoStepHelper(uint8_t command, uint8_t blockAddr, int32_t data);
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
// #######################################################################################################
|
||||
|
||||
/** Changelog:
|
||||
* 2025-08-13 tonhuisman: Enable use of secondary SPI bus
|
||||
* 2025-06-14 tonhuisman: Add support for Custom Value Type per task value
|
||||
* 2025-01-12 tonhuisman: Add support for MQTT AutoDiscovery (not supported for RFID)
|
||||
* Update changelog
|
||||
@@ -45,6 +46,7 @@ boolean Plugin_111(uint8_t function, struct EventStruct *event, String& string)
|
||||
dev.ValueCount = 1;
|
||||
dev.SendDataOption = true;
|
||||
dev.CustomVTypeVar = true;
|
||||
dev.SpiBusSelect = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -161,7 +163,8 @@ boolean Plugin_111(uint8_t function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
initPluginTaskData(event->TaskIndex, new (std::nothrow) P111_data_struct(P111_CS_PIN, P111_RST_PIN, P111_IRQ_PIN));
|
||||
const uint8_t spi_bus = Settings.getSPIBusForTask(event->TaskIndex);
|
||||
initPluginTaskData(event->TaskIndex, new (std::nothrow) P111_data_struct(P111_CS_PIN, P111_RST_PIN, P111_IRQ_PIN, spi_bus));
|
||||
P111_data_struct *P111_data = static_cast<P111_data_struct *>(getPluginTaskData(event->TaskIndex));
|
||||
|
||||
if (nullptr != P111_data) {
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
|
||||
# include <MFRC522.h>
|
||||
|
||||
P111_data_struct::P111_data_struct(int8_t csPin,
|
||||
int8_t rstPin,
|
||||
int8_t irqPin)
|
||||
: mfrc522(nullptr), _csPin(csPin), _rstPin(rstPin), _irqPin(irqPin)
|
||||
P111_data_struct::P111_data_struct(int8_t csPin,
|
||||
int8_t rstPin,
|
||||
int8_t irqPin,
|
||||
uint8_t spi_bus)
|
||||
: mfrc522(nullptr), _csPin(csPin), _rstPin(rstPin), _irqPin(irqPin), _spi_bus(spi_bus)
|
||||
{}
|
||||
|
||||
P111_data_struct::~P111_data_struct() {
|
||||
@@ -28,12 +29,17 @@ P111_data_struct::~P111_data_struct() {
|
||||
void P111_data_struct::init() {
|
||||
delete mfrc522;
|
||||
|
||||
mfrc522 = new (std::nothrow) MFRC522(_csPin, _rstPin); // Instantiate a MFRC522
|
||||
// Instantiate a MFRC522
|
||||
mfrc522 = new (std::nothrow) MFRC522(_csPin, _rstPin
|
||||
# ifdef ESP32
|
||||
, 0 == _spi_bus ? SPI : SPI1
|
||||
# endif // ifdef ESP32
|
||||
);
|
||||
|
||||
if (mfrc522 != nullptr) {
|
||||
mfrc522->PCD_Init(); // Initialize MFRC522 reader
|
||||
mfrc522->PCD_Init(); // Initialize MFRC522 reader
|
||||
mfrc522->PCD_WriteRegister(MFRC522::ComIEnReg, 0b10100000); // enable receiver interrupt
|
||||
mfrc522->PCD_WriteRegister(MFRC522::DivIEnReg, 0x80); // Set as CMOS output pin
|
||||
mfrc522->PCD_WriteRegister(MFRC522::DivIEnReg, 0x80); // Set as CMOS output pin
|
||||
initPhase = P111_initPhases::Ready;
|
||||
|
||||
if (validGpio(_irqPin)) {
|
||||
@@ -134,7 +140,7 @@ bool P111_data_struct::reset(int8_t csPin,
|
||||
(initPhase == P111_initPhases::Ready)) {
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
addLogMove(
|
||||
LOG_LEVEL_INFO,
|
||||
LOG_LEVEL_INFO,
|
||||
concat(F("MFRC522: Reset on pin: "), resetPin));
|
||||
}
|
||||
|
||||
@@ -161,9 +167,9 @@ bool P111_data_struct::reset(int8_t csPin,
|
||||
pinMode(csPin, OUTPUT);
|
||||
digitalWrite(csPin, LOW);
|
||||
|
||||
mfrc522->PCD_Init(csPin, resetPin); // Init MFRC522 module
|
||||
mfrc522->PCD_Init(csPin, resetPin); // Init MFRC522 module
|
||||
mfrc522->PCD_WriteRegister(MFRC522::ComIEnReg, 0b10100000); // enable receiver interrupt
|
||||
mfrc522->PCD_WriteRegister(MFRC522::DivIEnReg, 0x80); // Set as CMOS output pin
|
||||
mfrc522->PCD_WriteRegister(MFRC522::DivIEnReg, 0x80); // Set as CMOS output pin
|
||||
|
||||
// If you set Antenna Gain to Max it will increase reading distance
|
||||
mfrc522->PCD_SetAntennaGain(mfrc522->RxGain_max);
|
||||
@@ -232,23 +238,25 @@ uint8_t P111_data_struct::readPassiveTargetID(uint8_t *uid,
|
||||
*uidLength = 4;
|
||||
|
||||
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG))
|
||||
{
|
||||
PrintToString p2str;
|
||||
mfrc522->PICC_DumpToSerial(&(mfrc522->uid), p2str);
|
||||
|
||||
if (p2str.length()) {
|
||||
addLog(LOG_LEVEL_DEBUG, concat(F("MFRC522: "), p2str.get()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif // ifndef BUILD_NO_DEBUG
|
||||
|
||||
|
||||
mfrc522->PICC_HaltA(); // Stop reading
|
||||
return P111_NO_ERROR;
|
||||
}
|
||||
|
||||
void P111_data_struct::mfrc522_interrupt(P111_data_struct * self)
|
||||
void P111_data_struct::mfrc522_interrupt(P111_data_struct *self)
|
||||
{
|
||||
self->_irq_pin_time_micros = getMicros64();
|
||||
}
|
||||
@@ -272,11 +280,11 @@ bool P111_data_struct::loop(struct EventStruct *event) {
|
||||
return success;
|
||||
}
|
||||
|
||||
counter++; // This variable replaces a static variable in the original implementation
|
||||
const bool ComIrqReg_bits = (mfrc522->PCD_ReadRegister(MFRC522::ComIrqReg) & (1<<5)) != 0;
|
||||
counter++; // This variable replaces a static variable in the original implementation
|
||||
const bool ComIrqReg_bits = (mfrc522->PCD_ReadRegister(MFRC522::ComIrqReg) & (1 << 5)) != 0;
|
||||
mfrc522->PCD_WriteRegister(MFRC522::ComIrqReg, 0x34);
|
||||
|
||||
if (counter >= 10 || ComIrqReg_bits) { // Only every 3rd 0.1 second we do a read
|
||||
if ((counter >= 10) || ComIrqReg_bits) { // Only every 3rd 0.1 second we do a read
|
||||
counter = 0;
|
||||
|
||||
uint32_t key = P111_NO_KEY;
|
||||
@@ -346,24 +354,28 @@ bool P111_data_struct::plugin_fifty_per_second(struct EventStruct *event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_irq_pin_time_micros > _last_served_irq_pin_time_micros) {
|
||||
_last_served_irq_pin_time_micros = _irq_pin_time_micros;
|
||||
//addLog(LOG_LEVEL_INFO, F("P111: acting on interrupt"));
|
||||
|
||||
// addLog(LOG_LEVEL_INFO, F("P111: acting on interrupt"));
|
||||
loop(event);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
String P111_data_struct::PCD_getVersion(uint8_t& v) {
|
||||
v = 0xFF;
|
||||
|
||||
if (mfrc522) {
|
||||
v = mfrc522->PCD_ReadRegister(MFRC522::VersionReg);
|
||||
if (v != 0xFF && v != 0) {
|
||||
|
||||
if ((v != 0xFF) && (v != 0)) {
|
||||
// Human readable version.
|
||||
String res = concat(formatToHex(v, 2), F(" = "));
|
||||
switch(v) {
|
||||
|
||||
switch (v) {
|
||||
case 0xb2:
|
||||
res += F("FM17522_1");
|
||||
break;
|
||||
@@ -395,5 +407,4 @@ String P111_data_struct::PCD_getVersion(uint8_t& v) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
|
||||
|
||||
#endif // ifdef USES_P111
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
# include <MFRC522.h>
|
||||
|
||||
# include "../Globals/SPI1.h"
|
||||
|
||||
# define P111_CS_PIN PIN(0)
|
||||
# define P111_RST_PIN PIN(1)
|
||||
# define P111_IRQ_PIN PIN(2)
|
||||
@@ -31,15 +33,16 @@ enum class P111_initPhases : uint8_t {
|
||||
};
|
||||
|
||||
struct P111_data_struct : public PluginTaskData_base {
|
||||
P111_data_struct(int8_t csPin,
|
||||
int8_t rstPin,
|
||||
int8_t irqPin);
|
||||
P111_data_struct(int8_t csPin,
|
||||
int8_t rstPin,
|
||||
int8_t irqPin,
|
||||
uint8_t spi_bus);
|
||||
P111_data_struct() = delete;
|
||||
virtual ~P111_data_struct();
|
||||
|
||||
void init();
|
||||
bool plugin_ten_per_second(struct EventStruct *event);
|
||||
bool plugin_fifty_per_second(struct EventStruct *event);
|
||||
void init();
|
||||
bool plugin_ten_per_second(struct EventStruct *event);
|
||||
bool plugin_fifty_per_second(struct EventStruct *event);
|
||||
|
||||
String PCD_getVersion(uint8_t& v);
|
||||
|
||||
@@ -51,21 +54,22 @@ private:
|
||||
|
||||
uint8_t counter = 0;
|
||||
|
||||
String getCardName();
|
||||
uint8_t readCardStatus(uint32_t *key,
|
||||
bool *removedTag);
|
||||
bool reset(int8_t csPin,
|
||||
int8_t resetPin);
|
||||
uint8_t readPassiveTargetID(uint8_t *uid,
|
||||
uint8_t *uidLength);
|
||||
String getCardName();
|
||||
uint8_t readCardStatus(uint32_t *key,
|
||||
bool *removedTag);
|
||||
bool reset(int8_t csPin,
|
||||
int8_t resetPin);
|
||||
uint8_t readPassiveTargetID(uint8_t *uid,
|
||||
uint8_t *uidLength);
|
||||
|
||||
static void mfrc522_interrupt(P111_data_struct * self);
|
||||
static void mfrc522_interrupt(P111_data_struct *self);
|
||||
|
||||
int32_t timeToWait = 0;
|
||||
|
||||
int8_t _csPin;
|
||||
int8_t _rstPin;
|
||||
int8_t _irqPin;
|
||||
int8_t _csPin;
|
||||
int8_t _rstPin;
|
||||
int8_t _irqPin;
|
||||
uint8_t _spi_bus;
|
||||
|
||||
uint8_t errorCount = 0;
|
||||
bool removedState = true; // On startup, there will usually not be a tag nearby
|
||||
|
||||
Reference in New Issue
Block a user