Problem with SPI...

stefanoxjx
Posts: 25
Joined: Mon Feb 12, 2018 6:26 pm

Problem with SPI...

Postby stefanoxjx » Sat Feb 24, 2018 8:59 pm

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
Last edited by stefanoxjx on Sat Mar 03, 2018 5:28 pm, edited 1 time in total.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Problemi with SPI...

Postby kolban » Sat Feb 24, 2018 9:27 pm

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

stefanoxjx
Posts: 25
Joined: Mon Feb 12, 2018 6:26 pm

Re: Problemi with SPI...

Postby stefanoxjx » Mon Feb 26, 2018 9:03 am

Yes, I know, but I asked it because if on Arduino I execute only

Code: Select all

	SPI.begin();			// Init SPI bus
	mfrc522.PCD_Init();		// Init MFRC522
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

stefanoxjx
Posts: 25
Joined: Mon Feb 12, 2018 6:26 pm

Re: Problemi with SPI...

Postby stefanoxjx » Tue Feb 27, 2018 4:12 pm

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

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Problemi with SPI...

Postby ESP_Sprite » Thu Mar 01, 2018 1:32 am

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.

stefanoxjx
Posts: 25
Joined: Mon Feb 12, 2018 6:26 pm

Re: Problemi with SPI...

Postby stefanoxjx » Fri Mar 02, 2018 10:55 am

Hi, I tried to connect an Arduino configured to slave and data sent from esp is received.

Who is online

Users browsing this forum: No registered users and 103 guests