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):
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() {}
sketck translated for esp-idf (it doesn't work):
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()
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