Pin assignment ST25DV Arduino

Post here first, or if you can't find a relevant section!
Post Reply
CorvoAttano
Posts: 6
Joined: Fri Aug 05, 2022 11:07 am

Pin assignment ST25DV Arduino

Post by CorvoAttano »

I am trying to program a Raspberry Pi Pico with Arduino in order to control the ST25DV NFC chip. I want to use the stm32duino ST25DV library.

I have a question about the pin assignment in the ST25DV_HelloWorld.ino program.

I am using the ST25DV 8-pins package and according to the datasheet there is no LPD pin so I do not understand what pin to assign to the variable LPD_PIN in the program. I tried using the V_EH pin and assigning to LPD_PIN the corresponding pin of the microcontroller but this results in "System Init failed!" in the serial monitor.

I have searched in the stm32duino/ST25DV documentation but have not found anything relevant to this topic.

Can somebody help me with this issue?
cparata
Posts: 7
Joined: Tue Aug 09, 2022 7:53 am

Re: Pin assignment ST25DV Arduino

Post by cparata »

Hello @CorvoAttano ,
could you try to assign a whatever not connected pin of the MCU as LPD_PIN (not the V_EH one)? The library was developed for the 12-pin package, so I'm not sure that it can work also for the 8-pin package.
Best Regards,
Carlo
CorvoAttano
Posts: 6
Joined: Fri Aug 05, 2022 11:07 am

Re: Pin assignment ST25DV Arduino

Post by CorvoAttano »

Hello Carlo,

Thank you for your response.

Yes I have assigned arbitrary non connected pins of the microcontroller to variables GPO_PIN and LPD_PIN as shown in the Arduino code below :

Code: Select all

#define SerialPort Serial

// Please define the pin and wire instance used for your board
#define GPO_PIN 1
#define LPD_PIN 2
#define SDA_PIN 8
#define SCL_PIN 9

#define WireNFC Wire1
To determine the SDA_PIN and SCL_PIN variables values, I read documentation about pins for the RP2040 and the correspondence with my µC (the "WizFi-EVB-Pico") and their numbering correspondence in Arduino (using arduino-pico library). From this information, I chose the first configuration of pins for I2C comm. (there are two possible configurations) which is to connect SDA to pin 8 and SCL to pin 9 on the µC and I guess that corresponds to Wire1.

Then I tried the following setup to test the I2C comm.:

Code: Select all

void setup() {
  const char uri_write_message[] = "st.com/st25";       // Uri message to write in the tag
  const char uri_write_protocol[] = URI_ID_0x01_STRING; // Uri protocol to write in the tag
  String uri_write = String(uri_write_protocol) + String(uri_write_message);
  String uri_read;

  // Initialize serial for output.
  SerialPort.begin(9600);

  while (!SerialPort) delay(10);

  delay(5000);

  int st25dv_begin = st25dv.begin(GPO_PIN, LPD_PIN, &WireNFC);

  SerialPort.println(st25dv_begin);
  SerialPort.println(TEST);
  }
I noticed the begin function returns another value than NDEF_OK which means that the system init failed. Next I try to see why.

The code below is the begin function. Following up, we notice that begin returns what BSP_NFCTAG_Init returns.

Code: Select all

int ST25DV::begin(uint8_t gpo, uint8_t lpd, TwoWire *pwire)
{
  int ret = NDEF_OK;
  uint8_t test;

  _pwire = pwire;

  _gpo = gpo;
  _lpd = lpd;

  ret = BSP_NFCTAG_Init();
  if (ret != NDEF_OK) {
    return ret;
  }
/*
  BSP_NFCTAG_GetExtended_Drv()->ResetMBEN_Dyn();
  if (NfcType5_NDEFDetection() != NDEF_OK) {
    CCFileStruct.MagicNumber = NFCT5_MAGICNUMBER_E1_CCFILE;
    CCFileStruct.Version = NFCT5_VERSION_V1_0;
    CCFileStruct.MemorySize = (ST25DV_MAX_SIZE / 8) & 0xFF;
    CCFileStruct.TT5Tag = 0x05;
     Init of the Type Tag 5 component (M24LR)
    ret = NfcType5_TT5Init();
    if (ret != NDEF_OK) {
      return ret;
    }
  }
*/
  return ret;
}
So I tried analyzing BSP_NFCTAG_Init (below). Here I did two tests :
# First test :
## I did not comment anything in this function
## I defined a global variable TEST to look at nfctag_id variable in the function
## I uploaded the program on the µC and read the serial monitor : it shows 0 (=0x00) which is neither I_AM_ST25DV04 or I_AM_ST25DV64 so I guess it means the µC doesn't "see" the ST25DV that I connected via I2C (I searched the ST25DV04K datasheet and did not find information about these identifiers)
# Second test :
## I commented the last part of the function (from TEST and so on) so I actually look at the result from St25Dv_i2c_Drv.Init()
## I kept the I2C wires connected, I uploaded the program on the µC and read the serial monitor : it shows 0 (=NDEF_OK=NFCTAG_OK)
## I disconnected the I2C wires, I uploaded the program on the µC and read the serial monitor : it still shows 0 (=NDEF_OK=NFCTAG_OK)
Unfortunately, I cannot access this function St25Dv_i2c_Drv.Init() and I am not sure what it actually means but so I don't know if this second test was actually relevant or not.

Code: Select all

NFCTAG_StatusTypeDef BSP_NFCTAG_Init()
{
  uint8_t nfctag_id = 0;

  if (!NfctagInitialized) {
    if (St25Dv_i2c_Drv.Init == NULL) {
      return NFCTAG_ERROR;
    }
    /* ST25DV Init */
    if (St25Dv_i2c_Drv.Init() != NFCTAG_OK) {
      return NFCTAG_ERROR;
    }
    /* Check ST25DV driver ID */
    
    St25Dv_i2c_Drv.ReadID(&nfctag_id);

    TEST = nfctag_id;

    if ((nfctag_id == I_AM_ST25DV04) || (nfctag_id == I_AM_ST25DV64)) {
      NfctagInitialized = 1;
      Nfctag_Drv = &St25Dv_i2c_Drv;
      Nfctag_Drv->pData = &St25Dv_i2c_ExtDrv;
    } else {
      Nfctag_Drv = NULL;
      NfctagInitialized = 0;
      return NFCTAG_ERROR;
    }
  }
  return NFCTAG_OK;
}
Thanks if you read until here. Please let me know if you have any idea how to solve this problem.
cparata
Posts: 7
Joined: Tue Aug 09, 2022 7:53 am

Re: Pin assignment ST25DV Arduino

Post by cparata »

Hello @CorvoAttano ,
It is not clear to me what is the hardware board that you are using with the ST25DV component. Anyway, please check that the I2C Pull-Up resistors are connected to the I2C pins of your board, otherwise you need to add them externally.
Best Regards,
Carlo
CorvoAttano
Posts: 6
Joined: Fri Aug 05, 2022 11:07 am

Re: Pin assignment ST25DV Arduino

Post by CorvoAttano »

Hello,

I am using the WizFi360-EVB-Pico microcontroller (https://docs.wiznet.io/Product/Open-Sou ... -evb-pico/) which is based on a RP2040. Yes I connected 10KOhms pull-up resistors externally (from both I2C pins to VCC).

Actually, I have written another simple program to test the I2C link by scanning addresses.

Code: Select all

#include <Wire.h>

void setup()
{
  Wire.begin();

  Serial.begin(9600);
}

void loop()
{
  int error;
  int address;
  int devices = 0;

  Serial.println("Devices found:");

  for(address = 1; address < 127; address++ ) 
  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
  
  if (devices == 0)
    Serial.println("No I2C devices found");

  delay(5000);           
}
# When the I2C link is connected I get:
Devices found:
0x2D
0x53
0x57
# When I disconnect the pull-resistors and the I2C link is connected I get:
Devices found:
0x2D
0x53
0x57
# When I disconnect the I2C I get:
Devices found:
No I2C devices found

So actually this test shows that when the I2C is connected (with or without pull-up resistors) the I2C scan finds 3 devices which is normal according to ST25DV04K datasheet and when the I2C is disconnected the I2C scans 0 devices. Therefore, the I2C actually works. So there must be something wrong with the ST25DV_HelloWorld.ino program or maybe this program is not suitable for 8-pin ST25DV component.

Unfortunately, in the mean time, I got another completely unrelated issue: I was just normally compiling and uploading to the board when suddently, when compiling another time, I got this error message :

Code: Select all

Alternatives for @C: []
cc1plus.exe: error: too many filenames given; type 'cc1plus.exe --help' for usageResolveLibrary(@C)
followed by a "virus and threat protection" notification (I am using Windows10)
And now when I try again I always get this error message.
So I have to first resolve this issue for which I believe there is a solution here : viewtopic.php?t=1138.

Thank you for taking your time to read all this.
cparata
Posts: 7
Joined: Tue Aug 09, 2022 7:53 am

Re: Pin assignment ST25DV Arduino

Post by cparata »

Hi @CorvoAttano ,
if the results on I2C tests are the same when Pull-up resistors are mounted or unmounted, it means that maybe your board already has them on board.
Reading the datasheet of the component:
Device reset in I²C mode
In order to prevent inadvertent write operations during power-up, a power-on reset (POR) circuit is included. At
power-up (continuous rise of VCC), the ST25DVxxx does not respond to any I²C instruction until VCC has reached
the power-on reset threshold voltage (this threshold is lower than the minimum VCC operating voltage defined in
Table 243. I2C operating conditions). When VCC passes over the POR threshold, the device is reset and enters
the Standby power mode. However, the device must not be accessed until VCC has reached a valid and stable
VCC voltage within the specified [VCC(min), VCC(max)] range and t_boot time necessary to ST25DVxxx set-up has
passed. In the version supporting LPD pin, the boot will take place only when LPD goes low.
It seems that the component takes a while to get the I2C working so maybe you can add a delay of some milliseconds in:

Code: Select all

NFCTAG_StatusTypeDef ST25DV_IO_Init(void)
{
  if (st25dv._pwire == NULL) {
    return NFCTAG_ERROR;
  }

  st25dv.ST25DV_GPO_Init();
  st25dv.ST25DV_LPD_Init();

  st25dv.ST25DV_I2C_Init();
  st25dv.ST25DV_SelectI2cSpeed(3);

  return NFCTAG_OK;
}
between st25dv.ST25DV_LPD_Init(); and st25dv.ST25DV_I2C_Init();

The device has 2 different I2C address according if you access data registers or system registers (respectively 0xA6 and 0xAE). In your test, you read 0x53 and 0x57 that are 0xA6 and 0xAE right-shifted by 1. So, it seems that you are quite aligned with the library. let's see if the delay can help.
Best Regards,
Carlo
CorvoAttano
Posts: 6
Joined: Fri Aug 05, 2022 11:07 am

Re: Pin assignment ST25DV Arduino

Post by CorvoAttano »

Hello, @cparata,

(I have solved the other unrelated issue)

As you suggested, I tried adding a delay in the function

Code: Select all

NFCTAG_StatusTypeDef ST25DV_IO_Init(void)
as shown here

Code: Select all

NFCTAG_StatusTypeDef ST25DV_IO_Init(void)
{
  if (st25dv._pwire == NULL) {
    return NFCTAG_ERROR;
  }

  st25dv.ST25DV_GPO_Init();  
  st25dv.ST25DV_LPD_Init();

  double time_delay_ms = 100;
  double time_ref = time(0) + time_delay_ms/1000;
  while(time(0) < time_ref);

  st25dv.ST25DV_I2C_Init();
  st25dv.ST25DV_SelectI2cSpeed(3);

  return NFCTAG_OK;
}
But this does not change the output of:

Code: Select all

St25Dv_i2c_Drv.ReadID(&nfctag_id);
However, I see more clearly how the library works now.

Using a global variable ret_g, I determined that in the function below, the line

Code: Select all

ret = st25dv._pwire->endTransmission(true);
returns 4 which corresponds to NFCTAG_ERROR and according to the comment in the code it would mean that the address is not OK. What should I change for the address to be OK?

Code: Select all

NFCTAG_StatusTypeDef ST25DV_IO_MemRead(uint8_t *const pData, const uint8_t DevAddr, const uint16_t TarAddr, const uint16_t Size)
{
  int i = 0;
  uint8_t ret = 4;
  uint8_t Addr = DevAddr >> 1;
  char tmp[4];

  if (st25dv._pwire == NULL) {
    return NFCTAG_ERROR;
  }

  if (_serial != NULL) {
    //  _serial->println(SP);
    _serial->print("  r ");
    sprintf(tmp, "%02X", Addr);
    _serial->print(tmp);
    _serial->print("@");
    sprintf(tmp, "%02X", TarAddr >> 8);
    _serial->print(tmp);
    sprintf(tmp, "%02X", TarAddr & 0xFF);
    _serial->print(tmp);
    _serial->print(":");
    _serial->println(Size);
  }
  st25dv._pwire->beginTransmission(Addr);    // Get the slave's attention, tell it we're sending a command byte
  st25dv._pwire->write(TarAddr >> 8);           //  The command byte, sets pointer to register with address of 0x32
  st25dv._pwire->write(TarAddr & 0xFF);         //  The command byte, sets pointer to register with address of 0x32
  ret = st25dv._pwire->endTransmission(true);
  ret_g = ret;
  // Address is not OK
  if (ret != 0) {
    return NFCTAG_ConvertStatus(ret);
  }
  ...
  }
Thank you for helping me.
cparata
Posts: 7
Joined: Tue Aug 09, 2022 7:53 am

Re: Pin assignment ST25DV Arduino

Post by cparata »

Hello @CorvoAttano ,
the

Code: Select all

St25Dv_i2c_Drv.ReadID(&nfctag_id);
should return in your case 0x24.
For the delay you could use directly

Code: Select all

delay(100);
but, as you said, it seems that this in not the issue.
It's like the I2C commands are managed in a different way between Pico MCU and STM32 MCU. Tomorrow I will start my summer vacations, so I will be off for 2 weeks. Anyway, when I will come back in September, I will give a try on 8-pin ST25DV component that I have in a STM32 based board and I let you know my outcomes. If the library will work on STM32 board, it means that the issue could be in the Wire library implementation to support I2C peripheral in the Pico board. I let you know in September.
Best Regards,
Carlo
CorvoAttano
Posts: 6
Joined: Fri Aug 05, 2022 11:07 am

Re: Pin assignment ST25DV Arduino

Post by CorvoAttano »

Hello @cparata,

Ok, I will look into the Wire library implementation for Pico.

Have nice holidays!
cparata
Posts: 7
Joined: Tue Aug 09, 2022 7:53 am

Re: Pin assignment ST25DV Arduino

Post by cparata »

Hello @CorvoAttano ,
sorry to come back to you so late, but finally I was able to do a test on my side. Basically, I noticed that the library is not able to manage correctly the Wire instance that you can pass in the .begin API because I guess we have an hardcoded instance of the NFC tag (the variable st25dv) where by default it is passed as argument the Wire instance.
The only solution that I found on my side is to force the new SDA and SCL in the Wire instance before calling st25dv.begin().
So I just used:

Wire.setSDA(<SDA_pin>);
Wire.setSCL(<SCL_pin>);

and in this way I was able to read the NFC tag without any issue.
I think that this library needs a rework in order to be more reusable. I hope that my tip can help you.
Best Regards,
Carlo
Post Reply

Return to “General discussion”