cancel
Showing results for 
Search instead for 
Did you mean: 

How to read data from user area of st25dvo4k using read(2) system call?

Mpraj.19
Associate II

st25dv04k is interfaced with i.mx6. we install kernal version 4.9.88-10182-gec7d7d8-dirty on i.mx6. i written below code in c.

#include <stdio.h>

#include <sys/ioctl.h>

#include <fcntl.h>

#include <unistd.h>

#include <time.h>

#include <netinet/in.h>

#include <linux/i2c-dev.h>

#define ADDRESS 0x53

int main() {

 int fd;

unsigned char buffer[3];

unsigned char buffer1[2];

 if ((fd = open("/dev/i2c-2", O_RDWR)) < 0) { printf("Couldn't open device! %d\n", fd); return 1; }

 if (ioctl(fd, I2C_SLAVE, ADDRESS) < 0)   

{

printf("Couldn't find device on address!\n"); return 1;

}

buffer[0] = 0x00;

buffer[1] = 0x00;

buffer[2] = 0x65;

if (write(fd, buffer, 3) != 3)

{

printf("ERROR HANDLING: i2c transcations failed\n");

}

else

printf("i2c write success\n");

usleep(5000);

buffer1[0] = 0x00;

buffer1[1] = 0x00;

//buffer1[2] = 0x65;

if(read(fd, buffer1, 2) != 2)

{

   printf("Failed to read from the i2c bus.\n\n");

}

else {

   printf("Successful read\n");

    printf("Value: %02x\n\n", buffer1[0]);

    printf("Value: %02x\n\n", buffer1[1]);

}

 close(fd);

 return 0;

}

//////////////////////

q] what to write in above code to read value from register address of 2 byte?

q] is this right approach to read and write ? if not then what chage i need to do in above code for write in user area?

q] what ndef sequence byte i need to write in above code for send 'text data' ?

q] my main aim is to write data in nfc tag ic st25dv04k. that ic is work as slave. our master is second i.mx6 board. when tag connected to slave ic . when master comes near this tag i need to send written text data to master. so what to approach in above code?

i hope you not send any link. i want code development help. i don't want to use any driver.

Thanks for help and support.

1 ACCEPTED SOLUTION

Accepted Solutions
Ronald B.
Associate III

Dear Mpraj.19,

Before answering your questions, please note that the ST25DV-I2C I2C operation is described in DS10925 at chapter 6 (addressing bytes, START and STOP conditions).

Please also note that what you are implementing is already available in file Drivers/BSP/Linux/st25dv-i2c_linux.c from the STSW-ST25DV007 package (available on st.com) and shoud be reusable on any Linux platform.

Then regarding your code code:

  1. The "write" will write byte 0x65 at address 0.
  2. The read function will trigger a "current address read" sequence of the ST25DV-I2C (see figure 29 of DS10925), and the current address is the byte next after the last byte you wrote (i.e. at address 1), as a result the read will return 2 bytes from address 1 and 2.

To read back the written data, you need to trigger the "Random address read" sequence (decribed in figure 29 of DS10925 as well).

This can be achieved using an ioctl(filehande, I2C_RDWR, &payload);

payload being an i2c_rdwr_ioctl_data structure with 2 partial messages:

  • a write of 2 bytes for the memory address
  • Chained with a read of 1 byte (without re-presenting the device address)

Code extracted from Drivers/BSP/Linux/st25dv-i2c_linux.c

 struct i2c_msg messages[2] = {

    {

      .addr = DevAddr >>1,

      .buf = regAddr,

      .len = 2,

      .flags = 0,

    },

    {

      .addr = DevAddr >>1,

      .buf = pData,

      .len = Length,

      .flags = I2C_M_RD | I2C_M_NOSTART,

    }

  };

 struct i2c_rdwr_ioctl_data payload = {

    .msgs = messages,

    .nmsgs = 2,

  };

  ret = ioctl(filehandle, I2C_RDWR, &payload);

  if (ret < 0) {

    ret = -errno;

    printf("\r\nError %d while reading @%X (devAddr=%X)\r\n", ret,Reg,DevAddr);

    return ret;

  }

For more details on I2C sequences and flags, you can take a look to this link: https://www.kernel.org/doc/Documentation/i2c/i2c-protocol

Then regarding the NDEF Text, The STSW-ST25DV007 package provides a Middleware for building NDEF messages.

You can take a look at the NDEF_URI or NDEF_BLUETOOTH projects as examples (The provided middleware allows to build NDEF Text records as well).

For instance, in NDEF_URI project, just replace the NDEF_WriteURI(&URI) by:

#include "lib_NDEF_Text.h"

NDEF_WriteText( "This will be formatted as a NDEF Text record" );

Regards,

View solution in original post

5 REPLIES 5
Brian TIDAL
ST Employee

Hi,

maybe this post can help you :

https://community.nxp.com/t5/i-MX-Processors/I2C-READ-and-WRITE/td-p/295146. I would suggest to enter your questions into this community to get the most appropriate answers to your questions.

Also, see https://www.kernel.org/doc/html/latest/i2c/dev-interface.html if you want to use read an write, In particular "You need to load module i2c-dev for this"

Anyway, I would recommend to use the ST25DV-I2C Linux user space driver as already answered to your various last posts.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Ronald B.
Associate III

Dear Mpraj.19,

Before answering your questions, please note that the ST25DV-I2C I2C operation is described in DS10925 at chapter 6 (addressing bytes, START and STOP conditions).

Please also note that what you are implementing is already available in file Drivers/BSP/Linux/st25dv-i2c_linux.c from the STSW-ST25DV007 package (available on st.com) and shoud be reusable on any Linux platform.

Then regarding your code code:

  1. The "write" will write byte 0x65 at address 0.
  2. The read function will trigger a "current address read" sequence of the ST25DV-I2C (see figure 29 of DS10925), and the current address is the byte next after the last byte you wrote (i.e. at address 1), as a result the read will return 2 bytes from address 1 and 2.

To read back the written data, you need to trigger the "Random address read" sequence (decribed in figure 29 of DS10925 as well).

This can be achieved using an ioctl(filehande, I2C_RDWR, &payload);

payload being an i2c_rdwr_ioctl_data structure with 2 partial messages:

  • a write of 2 bytes for the memory address
  • Chained with a read of 1 byte (without re-presenting the device address)

Code extracted from Drivers/BSP/Linux/st25dv-i2c_linux.c

 struct i2c_msg messages[2] = {

    {

      .addr = DevAddr >>1,

      .buf = regAddr,

      .len = 2,

      .flags = 0,

    },

    {

      .addr = DevAddr >>1,

      .buf = pData,

      .len = Length,

      .flags = I2C_M_RD | I2C_M_NOSTART,

    }

  };

 struct i2c_rdwr_ioctl_data payload = {

    .msgs = messages,

    .nmsgs = 2,

  };

  ret = ioctl(filehandle, I2C_RDWR, &payload);

  if (ret < 0) {

    ret = -errno;

    printf("\r\nError %d while reading @%X (devAddr=%X)\r\n", ret,Reg,DevAddr);

    return ret;

  }

For more details on I2C sequences and flags, you can take a look to this link: https://www.kernel.org/doc/Documentation/i2c/i2c-protocol

Then regarding the NDEF Text, The STSW-ST25DV007 package provides a Middleware for building NDEF messages.

You can take a look at the NDEF_URI or NDEF_BLUETOOTH projects as examples (The provided middleware allows to build NDEF Text records as well).

For instance, in NDEF_URI project, just replace the NDEF_WriteURI(&URI) by:

#include "lib_NDEF_Text.h"

NDEF_WriteText( "This will be formatted as a NDEF Text record" );

Regards,

is it possible to get this driver file ' Drivers/BSP/Linux/st25dv-i2c_linux.c from the STSW-ST25DV007 package' github ?

As per your reply i have done changes in main.c

-----------------------------------

#include <stdlib.h>

#include <stdint.h>

#include <stdio.h>

#include <errno.h>

#include <sys/types.h>

#include "assert.h"

#include <fcntl.h>

/* GPO Event Management*/

#include <time.h>

#include <fcntl.h>

#include <signal.h>

#include <pthread.h>

#include <linux/input.h>

#include <sys/select.h>

#include "unistd.h"

#include "bsp_nfctag.h"

#include "lib_NDEF.h"

#include "lib_NDEF_URI.h"

#include "tagtype5_wrapper.h"

#include "lib_NDEF_Text.h"

int main (void)

{

 uint8_t i = 0;

   int32_t status = -1;

   uint16_t timeout = 1000;

   uint8_t ID = 0;

   sURI_Info URI;

 /* Prepare URI NDEF message content */

 strcpy(URI.protocol,URI_ID_0x01_STRING);

 strcpy(URI.URI_Message,"st.com");

 strcpy(URI.Information,"\0");

 /* Init of the Type Tag 5 component (ST25DV-I2C) */

 while (BSP_NFCTAG_Init(0) != NFCTAG_OK);

 NfcTag_SelectProtocol(NFCTAG_TYPE5);

 printf("ST25DV-I2C init done\r\n");

   /* Check if no NDEF detected, init mem in Tag Type 5 */

 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 */

   while( NfcType5_TT5Init( ) != NFCTAG_OK );

 }

 printf("NDEF tag init done\r\n");

 /* First write NDEF */

// while (NDEF_WriteURI(&URI) != NFCTAG_OK);

 while (NDEF_WriteText( "This will be formatted as a NDEF Text record" ) != NFCTAG_OK);

 printf("\r\nNDEF URI has been written to the ST25DV-I2C\r\nRead it with a NFC enabled smartphone or a NFC reader\r\n");

 return 0;

}

------------------------------

After implementing that i got below error.

what i have to do for remove below error ?

-----------------------------------------------------------------------------------

root@var-som-mx6:/home/user/nfc/Projects/NDEF_URI# make

cc -pthread -ISrc -I../../Drivers/BSP/Linux/ -I../../Drivers/BSP/Components/st25dv-i2c -I../../Middlewares/ST/lib_nfc/lib_NDEF/Core/inc -I../../Middlewares/ST/lib_nfc/Common/inc -c -o Src/main.o Src/main.c

g++ -ISrc -I../../Drivers/BSP/Linux/ -I../../Drivers/BSP/Components/st25dv-i2c -I../../Middlewares/ST/lib_nfc/lib_NDEF/Core/inc -I../../Middlewares/ST/lib_nfc/Common/inc -lpthread Src/main.o Src/lib_NDEF_config.o ../../Drivers/BSP/Components/st25dv-i2c/st25dv.o ../../Drivers/BSP/Components/st25dv-i2c/st25dv_reg.o ../../Drivers/BSP/Linux/st25dv-i2c-gpo.o ../../Drivers/BSP/Linux/st25dv-i2c_linux.o ../../Drivers/BSP/Linux/bsp_nfctag.o ../../Drivers/BSP/Linux/st25dv-i2c-lpd.o ../../Middlewares/ST/lib_nfc/lib_NDEF/Core/src/tagtype3_wrapper.o ../../Middlewares/ST/lib_nfc/lib_NDEF/Core/src/lib_NDEF_URI.o ../../Middlewares/ST/lib_nfc/lib_NDEF/Core/src/lib_NDEF.o ../../Middlewares/ST/lib_nfc/lib_NDEF/Core/src/tagtype4_wrapper.o ../../Middlewares/ST/lib_nfc/lib_NDEF/Core/src/lib_wrapper.o ../../Middlewares/ST/lib_nfc/lib_NDEF/Core/src/tagtype5_wrapper.o -pthread -o st25dv-i2c_ndef_uri

Src/main.o: In function `main':

main.c:(.text+0xc0): undefined reference to `NDEF_WriteText'

collect2: error: ld returned 1 exit status

Makefile:40: recipe for target 'st25dv-i2c_ndef_uri' failed

make: *** [st25dv-i2c_ndef_uri] Error 1

-------------------------------------------------------------------

I have solved that issue by adding lib_NDEF_Text.c file in makefile script.

Thanks St community.