I2C Over USB Application using LPC1347 and LPCOpen

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C Over USB Application using LPC1347 and LPCOpen

1,723 Views
rocketbot27
Contributor I

kerryzhou

LPC1347 LPCOpen usbd_rom_hid_i2c example code

Hello,

For my project I am using an LPC1347 development board. I am trying to achieve an I2C communication with a Microchip 256K I2C Serial EEPROM over USB. The functionality is as such : from my host (desktop computer) I can issue a command to write data to any of the address in the EEPROM and read the data back from any of the register. For this I used the already existing example code given in the LPCOpen libraries. 

The communication takes place successfully however I am unable to understand a few things. Whenever I send an out report to the device (LPC1347 dev. board) to initialize the I2C, I receive an IN Report with successful initialization and then four other IN reports in which the host requesting resets whereas I immediately send an OUT request to read a register. I do get the read data in the IN report after sending the read request but there are four reset requests in between the two. 

Also, there are four resets after the IN report corresponding to a read operation is received.

I would like to know why the reset operation takes place. I understand that the host repeatedly polls the device.

Any help would be really appreciated. 

Thank you

Madhukar

Labels (4)
0 Kudos
3 Replies

1,629 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Madhukar Arora ,

  Thanks for your trust, I am already not support the LPC product anymore, I mainly support the NXP I.MX RT and the kinetis product now. So, about your new LPC question, our LPC engineer will help you, please keep patient, thanks a lot for your understanding.

Best Regards,

Kerry

0 Kudos

1,629 Views
Omar_Anguiano
NXP TechSupport
NXP TechSupport

Hello Madhukar Arora

 

The reset request in the hid_i2c clears all the control/status flags. This means that the device will abort and flush all the pending requests of the device.

 

Let me know if this is helpful, if you have more questions do not hesitate to ask me.

Best regards,

Omar

0 Kudos

1,629 Views
rocketbot27
Contributor I

Hello Omar,
Thank you for your reply. I understand that the reset requests clears all the request and control/status flags.

However, I don't understand why there is a reset request automatically sent after I send a request to initialize the I2C. 

Attached is a source file I am using to communicate with the EEPROM from the host {LINUX MACHINE} over USB I2C bridge. 

/**
* @ Author : Madhukar Arora
* @ Brief : Testing the LPC1347 as a HID.
*
*/

#include "host_hid.h"
#include "hidraw.h"
#include <inttypes.h>

//request for out_report
#define HOST_REQ_RESET (40) /* host requesting reset automatically */
#define REQ_HID_I2C_INIT (1) /* host requesting initialization of I2C */
#define REQ_HID_I2C_DEINIT (2) /* host requesting denitialization of I2C*/
#define REQ_HID_I2C_WRITE (3) /* host requesting an I2C Write*/
#define REQ_HID_I2C_READ (4) /* host requesting an I2C Read*/
#define REQ_HID_I2C_DEVICE_XFER (5) /*host requesting an I2C Transfer, handles read and write condition*/

const char *device = "/dev/hidraw8";

const char *bus_str(int bus);

#define REPORT_HEAD_SIZE (4) //size of out structure without any data

struct out_report
{
uint8_t length;
uint8_t transId;
uint8_t sesId;
uint8_t req;
uint32_t data[64];
};

struct in_report
{
uint8_t length;
uint8_t transId;
uint8_t sesId;
uint8_t resp;
uint32_t data[64];
};

struct out_report out_rep;

int main(void)
{

int fd = -1; //file descriptor for hid device
int i, err = 0;
char buff[256];

struct hidraw_report_descriptor rpt_desc;

struct hidraw_devinfo info;

if ((fd = open(device, O_RDWR)) < 0)
{

perror("Failed to Open the Device");
exit(1);
}

// Get size of Report Descriptor
err = ioctl(fd, HIDIOCGRDESCSIZE, &rpt_desc.size);

if (err < 0)
{
perror("Error getting descriptor size");
}
else
{
printf("Report Descriptor Size: %d\n", rpt_desc.size);
}

// Get report descriptor

err = ioctl(fd, HIDIOCGRDESC, &rpt_desc);

if (err < 0)
{
perror("Error getting report descriptor");
}
else
{
printf("Report Descriptor \n");
for (i = 0; i < rpt_desc.size; i++)
{
printf("%hhx ", rpt_desc.value[i]);
}
}

// Get raw info

err = ioctl(fd, HIDIOCGRAWINFO, &info);

if (err < 0)
{
perror("Error getting raw info");
}

else
{
printf("\nRAW INFO \n");
printf("Bus Type : %d %s \n", info.bustype, bus_str(info.bustype));
printf("Vendor Information: 0x%04hx \n", info.vendor);
printf("Product Information: 0x%04hx \n", info.product);
}

// HID get raw name

err = ioctl(fd, HIDIOCGRAWNAME(256), buff);

if (err < 0)
{
perror("Error getting raw name");
}

else
{
printf("Raw Name : %s\n", buff);
}

// HID get raw physical address

err = ioctl(fd, HIDIOCGRAWPHYS(256), buff);

if (err < 0)
{
perror("Error getting raw physical address");
}

else
{
printf("Physical Address : %s\n", buff);
}

/* write */
out_rep.length = REPORT_HEAD_SIZE;
out_rep.transId = 1;
out_rep.sesId = 1;
out_rep.req = REQ_HID_I2C_INIT;

out_rep.data[0] = 100000;

out_rep.length += (sizeof(out_rep.data) / sizeof(out_rep.data[0]));

printf("LENGTH OF OUT REPORT %" PRIu8 "\n", out_rep.length);

err = write(fd, &out_rep, sizeof(struct out_report));

if (err < 0)
{
printf("Error : %d\n", errno);
perror("Error writing data packet");
}
else
{
printf("write wrote %d bytes\n", err);
}

/* read */

err = 0;
int j = 0;
while ((err == 0) || (j % 4 != 0))
{
j++;
err = read(fd, buff, 256);

if (err < 0)
{
printf("Error :%d\n", errno);
perror("read failed!");
}
else
{
struct in_report *in_rep = (struct in_report *)buff;
if (in_rep->resp != HOST_REQ_RESET)
{

printf("in_report length %" PRIu8 "\n", in_rep->length);
printf("in_report transId %" PRIu8 "\n", in_rep->transId);
printf("in_report sesId %" PRIu8 "\n", in_rep->sesId);
printf("in_report resp %" PRIu8 "\n", in_rep->resp);
for (i = 4; i < in_rep->length; i++)
{
printf("%c ", buff[i]);
}
printf("\n");
}
}
}

printf("Reading data from a register in the EEPROM\n\n");
out_rep.length = REPORT_HEAD_SIZE;
out_rep.transId = 1;
out_rep.sesId = 1;
out_rep.req = REQ_HID_I2C_DEVICE_XFER;

out_rep.data[0] = 2; //txlength
out_rep.data[1] = 1; //rxlen
out_rep.data[2] = 0; //no options
out_rep.data[3] = 0x50; //slave addr
out_rep.data[4] = 0x00;
out_rep.data[5] = 0x02;

out_rep.length += (sizeof(out_rep.data) / sizeof(out_rep.data[0]));

err = write(fd, &out_rep, sizeof(struct out_report));

if (err < 0)
{
printf("Error : %d\n", errno);
perror("Error writing data packet");
}
else
{
printf("write wrote %d bytes\n", err);
}

/* read */
err = 0;
j = 0;
while ((err == 0) || (j % 4 != 0))
{
j++;
err = read(fd, buff, 256);

if (err < 0)
{
printf("Error :%d\n", errno);
perror("read failed!");
}
else
{
struct in_report *in_rep = (struct in_report *)buff;
if (in_rep->resp != HOST_REQ_RESET)
{
printf("in_report length %" PRIu8 "\n", in_rep->length);
printf("in_report transId %" PRIu8 "\n", in_rep->transId);
printf("in_report sesId %" PRIu8 "\n", in_rep->sesId);
printf("in_report resp %" PRIu8 "\n", in_rep->resp);
for (i = 4; i < in_rep->length; i++)
{
printf("%c ", buff[i]);
}
printf("\n");
}
}
}

close(fd);
}

const char *bus_str(int bus)
{
switch (bus)
{
case BUS_USB:
return "USB";
break;
case BUS_HIL:
return "HIL";
break;
case BUS_BLUETOOTH:
return "Bluetooth";
break;
case BUS_VIRTUAL:
return "Virtual";
break;
default:
return "Other";
break;
}
}
0 Kudos