Hi, I'm trying to use MFCRC522 whith this code: https://github.com/blmhemu/ESP32-MFRC522.
It doesn't work, but after a lot of tests without satisfaction, I've tried to analyze the signal with the osccilloscope.
The result is that the signals are flat in all SPI configured pins.
So, I've wired the MFRC522 to Arduino and I've tested it with another library definitely working.
On arduino, the oscilloscope shows me all signals working (square wave).
I don't understand why.
Looking another software writed for esp-idf that use SPI, all the APIs call seems correct.
Unfortunately, I haven't another SPI peripheral (not MFRC522) to make test.
There is any method to verify if SPI work fine?
Thanks a lot.
Best regards.
Stefano
Problem with SPI...
-
- Posts: 25
- Joined: Mon Feb 12, 2018 6:26 pm
Problem with SPI...
Last edited by stefanoxjx on Sat Mar 03, 2018 5:28 pm, edited 1 time in total.
Re: Problemi with SPI...
Unfortunately because code exists on Github doesn't necessarily mean that it is currently working or fully tested. You might want to contact the author of that code and ask for clarification of its state.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
-
- Posts: 25
- Joined: Mon Feb 12, 2018 6:26 pm
Re: Problemi with SPI...
Yes, I know, but I asked it because if on Arduino I execute only
I already see the signal in MISO pin.
On ESP32 the signal is always flat and then I tought that can be a wrong initialization of SPI bus and not a problem into the code.
Stefano
Code: Select all
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
On ESP32 the signal is always flat and then I tought that can be a wrong initialization of SPI bus and not a problem into the code.
Stefano
-
- Posts: 25
- Joined: Mon Feb 12, 2018 6:26 pm
Re: Problemi with SPI...
After 3 days of tests, I haven't solved.
The latest test that I made is to write a little sketch for arduino reduced to minimum as possible and when I've seen that it work on arduino, I'had translate it for esp-idf.
Arduino sketch (it works fine):
sketck translated for esp-idf (it doesn't work):
The sketch uploaded to arduino returns version 0x12 and the esp-idf sketch return always 0x0.
Maybe I did something wrong in the esp-idf version?
What do you think?
Thanks.
Regards
Stefano
The latest test that I made is to write a little sketch for arduino reduced to minimum as possible and when I've seen that it work on arduino, I'had translate it for esp-idf.
Arduino sketch (it works fine):
Code: Select all
#include <SPI.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
#define MOSI_PIN 11
#define MISO_PIN 12
#define SCK_PIN 13
#define MFRC522_SPICLOCK SPI_CLOCK_DIV4
const uint8_t CommandReg=0x01 << 1;
const uint8_t TxModeReg=0x12 << 1; // defines transmission data rate and framing
const uint8_t RxModeReg=0x13 << 1; // defines reception data rate and framing
const uint8_t ModWidthReg=0x24 << 1; // controls the ModWidth setting?
const uint8_t TModeReg=0x2A << 1; // defines settings for the internal timer
const uint8_t TPrescalerReg=0x2B << 1; // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
const uint8_t TReloadRegH=0x2C << 1; // defines the 16-bit timer reload value
const uint8_t TReloadRegL=0x2D << 1;
const uint8_t TxASKReg=0x15 << 1; // controls the setting of the transmission modulation
const uint8_t ModeReg=0x11 << 1; // defines general modes for transmitting and receiving
const uint8_t VersionReg=0x37 << 1; // shows the software version
const uint8_t SoftReset=0x0F; // resets the MFRC522
void setup()
{
Serial.begin(9600);
while(!Serial);
SPI.begin();
RC522Init();
DumpVersionToSerial();
}
void WriteRegister(uint8_t reg, uint8_t value)
{
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0));
digitalWrite(SS_PIN, LOW);
SPI.transfer(reg);
SPI.transfer(value);
digitalWrite(SS_PIN, HIGH);
SPI.endTransaction(); // Stop using the SPI bus
}
void RC522Init()
{
bool hardReset = false;
// Set the chipSelectPin as digital output, do not select the slave yet
pinMode(SS_PIN, OUTPUT);
digitalWrite(SS_PIN, HIGH);
// If a valid pin number has been set, pull device out of power down / reset state.
if (RST_PIN != UINT8_MAX)
{
// Set the resetPowerDownPin as digital output, do not reset or power down.
pinMode(RST_PIN, OUTPUT);
if (digitalRead(RST_PIN) == LOW)
{ // The MFRC522 chip is in power down mode.
digitalWrite(RST_PIN, HIGH); // Exit power down mode. This triggers a hard reset.
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74μs. Let us be generous: 50ms.
delay(50);
hardReset = true;
}
}
if (!hardReset)
{
WriteRegister(CommandReg, SoftReset); // Issue the SoftReset command.
delay(50);
while (ReadRegister(CommandReg) & (1<<4)) {}
}
// Reset baud rates
WriteRegister(TxModeReg, 0x00);
WriteRegister(RxModeReg, 0x00);
// Reset ModWidthReg
WriteRegister(ModWidthReg, 0x26);
// When communicating with a PICC we need a timeout if something goes wrong.
// f_timer = 13.56 MHz / (2*TPreScaler+1) where TPreScaler = [TPrescaler_Hi:TPrescaler_Lo].
// TPrescaler_Hi are the four low bits in TModeReg. TPrescaler_Lo is TPrescalerReg.
WriteRegister(TModeReg, 0x80); // TAuto=1; timer starts automatically at the end of the transmission in all communication modes at all speeds
WriteRegister(TPrescalerReg, 0xA9); // TPreScaler = TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25μs.
WriteRegister(TReloadRegH, 0x03); // Reload timer with 0x3E8 = 1000, ie 25ms before timeout.
WriteRegister(TReloadRegL, 0xE8);
WriteRegister(TxASKReg, 0x40); // Default 0x00. Force a 100 % ASK modulation independent of the ModGsPReg register setting
WriteRegister(ModeReg, 0x3D); // Default 0x3F. Set the preset value for the CRC coprocessor for the CalcCRC command to 0x6363 (ISO 14443-3 part 6.2.4)
}
uint8_t ReadRegister(uint8_t reg)
{
uint8_t value;
SPI.beginTransaction(SPISettings(MFRC522_SPICLOCK, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
digitalWrite(SS_PIN, 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.
digitalWrite(SS_PIN, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
return value;
}
void DumpVersionToSerial()
{
// Get the MFRC522 firmware version
uint8_t v = ReadRegister(VersionReg);
Serial.print(F("Firmware Version: 0x"));
Serial.print(v, HEX);
// Lookup which version
switch(v) {
case 0x88: Serial.println(F(" = (clone)")); break;
case 0x90: Serial.println(F(" = v0.0")); break;
case 0x91: Serial.println(F(" = v1.0")); break;
case 0x92: Serial.println(F(" = v2.0")); break;
default: Serial.println(F(" = (unknown)"));
}
// When 0x00 or 0xFF is returned, communication probably failed
if ((v == 0x00) || (v == 0xFF))
Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?"));
} // End PCD_DumpVersionToSerial()
void loop() {}
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/spi_master.h"
#include "soc/gpio_struct.h"
#include "driver/gpio.h"
void WriteRegister(uint8_t reg, uint8_t value);
uint8_t ReadRegister(uint8_t reg);
void RC522Init(void);
void DumpVersionToSerial(void);
#define RST_PIN 18 // Configurable, see typical pin layout above
#define SS_PIN 22 // Configurable, see typical pin layout above
#define MOSI_PIN 23
#define MISO_PIN 25
#define SCK_PIN 19
//#define MFRC522_SPICLOCK SPI_CLOCK_DIV4
const uint8_t CommandReg = 0x01 << 1;
const uint8_t TxModeReg = 0x12 << 1; // defines transmission data rate and framing
const uint8_t RxModeReg = 0x13 << 1; // defines reception data rate and framing
const uint8_t ModWidthReg = 0x24 << 1; // controls the ModWidth setting?
const uint8_t TModeReg = 0x2A << 1; // defines settings for the internal timer
const uint8_t TPrescalerReg = 0x2B << 1; // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
const uint8_t TReloadRegH = 0x2C << 1; // defines the 16-bit timer reload value
const uint8_t TReloadRegL = 0x2D << 1;
const uint8_t TxASKReg = 0x15 << 1; // controls the setting of the transmission modulation
const uint8_t ModeReg = 0x11 << 1; // defines general modes for transmitting and receiving
const uint8_t VersionReg = 0x37 << 1; // shows the software version
const uint8_t SoftReset = 0x0F; // resets the MFRC522
spi_device_handle_t spi;
void app_main(void)
{
esp_err_t ret;
spi_bus_config_t buscfg;
buscfg.miso_io_num = MISO_PIN;
buscfg.mosi_io_num = MOSI_PIN;
buscfg.sclk_io_num = SCK_PIN;
buscfg.quadwp_io_num = -1;
buscfg.quadhd_io_num = -1;
buscfg.max_transfer_sz = 0;
spi_device_interface_config_t devcfg;
devcfg.command_bits = 0;
devcfg.address_bits = 8;
devcfg.dummy_bits = 0;
devcfg.mode = 0;
devcfg.duty_cycle_pos = 128;
devcfg.cs_ena_pretrans = 0;
devcfg.cs_ena_posttrans = 0;
devcfg.clock_speed_hz = 1000000;
devcfg.spics_io_num = SS_PIN;
devcfg.flags = 0;
devcfg.queue_size = 7;
devcfg.pre_cb = 0;
devcfg.post_cb = 0;
gpio_pad_select_gpio(RST_PIN);
gpio_set_direction(RST_PIN, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(SS_PIN);
gpio_set_direction(SS_PIN, GPIO_MODE_OUTPUT);
//Initialize the SPI bus
ret = spi_bus_initialize(HSPI_HOST, &buscfg, 0);
ret = spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
RC522Init();
DumpVersionToSerial();
}
void WriteRegister(uint8_t reg, uint8_t value)
{
esp_err_t ret;
gpio_set_level(SS_PIN, 0);
spi_transaction_t trans;
trans.flags = SPI_TRANS_USE_TXDATA;
trans.cmd = 0;
trans.addr = reg & 0x7F;
trans.length = 8;
trans.rxlength = 0;
trans.user = 0;
trans.tx_data[0] = value;
trans.rx_buffer = NULL;
ret = spi_device_transmit(spi, &trans);
gpio_set_level(SS_PIN, 1);
}
void RC522Init()
{
bool hardReset = false;
// Set the chipSelectPin as digital output, do not select the slave yet
gpio_set_level(SS_PIN, 1);
// If a valid pin number has been set, pull device out of power down / reset state.
if (RST_PIN != UINT8_MAX)
{
// Set the resetPowerDownPin as digital output, do not reset or power down.
//pinMode(RST_PIN, OUTPUT);
if (gpio_get_level(RST_PIN) == 0)
{ // The MFRC522 chip is in power down mode.
gpio_set_level(RST_PIN, 1); // Exit power down mode. This triggers a hard reset.
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74μs. Let us be generous: 50ms.
vTaskDelay(50 / portTICK_PERIOD_MS);
hardReset = true;
}
}
if (!hardReset)
{
WriteRegister(CommandReg, SoftReset); // Issue the SoftReset command.
vTaskDelay(50 / portTICK_PERIOD_MS);
while (ReadRegister(CommandReg) & (1 << 4))
{
}
}
// Reset baud rates
WriteRegister(TxModeReg, 0x00);
WriteRegister(RxModeReg, 0x00);
// Reset ModWidthReg
WriteRegister(ModWidthReg, 0x26);
// When communicating with a PICC we need a timeout if something goes wrong.
// f_timer = 13.56 MHz / (2*TPreScaler+1) where TPreScaler = [TPrescaler_Hi:TPrescaler_Lo].
// TPrescaler_Hi are the four low bits in TModeReg. TPrescaler_Lo is TPrescalerReg.
WriteRegister(TModeReg, 0x80); // TAuto=1; timer starts automatically at the end of the transmission in all communication modes at all speeds
WriteRegister(TPrescalerReg, 0xA9); // TPreScaler = TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25μs.
WriteRegister(TReloadRegH, 0x03); // Reload timer with 0x3E8 = 1000, ie 25ms before timeout.
WriteRegister(TReloadRegL, 0xE8);
WriteRegister(TxASKReg, 0x40); // Default 0x00. Force a 100 % ASK modulation independent of the ModGsPReg register setting
WriteRegister(ModeReg, 0x3D); // Default 0x3F. Set the preset value for the CRC coprocessor for the CalcCRC command to 0x6363 (ISO 14443-3 part 6.2.4)
} //
uint8_t ReadRegister(uint8_t reg)
{
esp_err_t ret;
gpio_set_level(SS_PIN, 0); // Select slave
spi_transaction_t trans;
trans.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
trans.cmd = 0;
trans.addr = reg | 0x80;
trans.length = 8;
trans.rxlength = 8;
trans.user = 0;
trans.tx_data[0] = 0x00;
ret = spi_device_transmit(spi, &trans);
gpio_set_level(SS_PIN, 1); // Release slave again
return ret;
}
void DumpVersionToSerial()
{
// Get the MFRC522 firmware version
uint8_t v = ReadRegister(VersionReg);
printf("Firmware Version: 0x");
printf("%x\n", v);
// Lookup which version
switch (v)
{
case 0x88:
printf(" = (clone)");
break;
case 0x90:
printf(" = v0.0");
break;
case 0x91:
printf(" = v1.0");
break;
case 0x92:
printf(" = v2.0");
break;
default:
printf(" = (unknown)");
}
// When 0x00 or 0xFF is returned, communication probably failed
if ((v == 0x00) || (v == 0xFF))
printf("WARNING: Communication failure, is the MFRC522 properly connected?");
} // End PCD_DumpVersionToSerial()
Maybe I did something wrong in the esp-idf version?
What do you think?
Thanks.
Regards
Stefano
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Problemi with SPI...
It's pretty hard to diagnose this problem with only 'it doesn't receive the right number' as the symptom... have you tried connecting a logic analyzer or 'scope to the wires and seeing if you can diagnose the problem from there? If so, it may be helpful to post your findings with that as well.
-
- Posts: 25
- Joined: Mon Feb 12, 2018 6:26 pm
Re: Problemi with SPI...
Hi, I tried to connect an Arduino configured to slave and data sent from esp is received.
Who is online
Users browsing this forum: Gaston1980 and 141 guests