9 years ago.

I2C -Pmbus Problem LPC1768

Hi Everybody,

I'm trying to simulate a PMBus error, with a LPC1768. Basically the TSU_STA, (Repeated start condition), I try to put a delay, between the ack - Start, but the clock goes low level as you can see in the image,

Does anybody know, How i can configure the I2c Registers to keep it high?

Thanks,

Carlos

/media/uploads/carlos_powervation/1.jpg

Question relating to:

1 Answer

9 years ago.

Hard to tell what is going on from this picture due to low resolution. Looks like the master sends some data (2 bytes) and then generates a new start condition (SDA High, SCL goes low), the SCL probably stays low because the master does not send anything else afterwards. The other possibility is that some slave is pulling SCL low. Show code that you are using to get more help.

Hi Wim,

I think, it stays low, because I put a delay, (wait_us), I want to put a delay, to test TSU_STA for PMBus spec. test, but with the clock in high level. I don't know how the register should be configure I put the code, it's to simple,. I will put it in next post,

posted by Carlos Rodriguez 24 Apr 2015

void write(int address, const char* data, int length) {

send start condition LPC_I2C1->I2CONSET = 0x20;

block until interrupt while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

i2stat should be 0x08. could check if (LPC_I2C1->I2STAT != 0x08) { printf("START %x\r\n",LPC_I2C1->I2STAT); stop if failed LPC_I2C1->I2CONSET = 0x10; }

clear start condition LPC_I2C1->I2CONCLR = 0x20;

load i2dat LPC_I2C1->I2DAT = address <<1;

reset si LPC_I2C1->I2CONCLR = 0x08;

block until interrupt while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

i2stat should be ack received if (LPC_I2C1->I2STAT != 0x18) { printf("ADD %x\r\n",LPC_I2C1->I2STAT); stop LPC_I2C1->I2CONSET = 0x10; }

for (int i=0; i<length; i++) {

load i2dat LPC_I2C1->I2DAT = data[i];

reset si LPC_I2C1->I2CONCLR = 0x08;

block until interrupt while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

i2stat should be ack received if (LPC_I2C1->I2STAT != 0x28) { printf("DATA%d %x\r\n",i,LPC_I2C1->I2STAT); stop LPC_I2C1->I2CONSET = 0x10; } }

stop LPC_I2C1->I2CONSET = 0x10;

delay_us(100);

reset si LPC_I2C1->I2CONCLR = 0x08;

read(0x10, "c", 1); }

posted by Carlos Rodriguez 24 Apr 2015

void read(int address, char* data, int length) {

MASTER RECEIVER

send start condition LPC_I2C1->I2CONSET = 0x20;

block until interrupt while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

i2stat should be 0x08. could check /*if (LPC_I2C1->I2STAT != 0x08) { printf("RSTART %x\r\n",LPC_I2C1->I2STAT); stop if failed LPC_I2C1->I2CONSET = 0x10; }*/

clear start condition LPC_I2C1->I2CONCLR = 0x20;

load i2dat with read bit set LPC_I2C1->I2DAT = address << 1| 0x01;

reset si LPC_I2C1->I2CONCLR = 0x08;

block until interrupt while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

i2stat should be 0x40 - ack received if (LPC_I2C1->I2STAT != 0x40) { printf("RADD %x\r\n",LPC_I2C1->I2STAT); stop LPC_I2C1->I2CONSET = 0x10; }

for (int i=0; i<length-1; i++) {

ack next byte LPC_I2C1->I2CONSET = 0x4;

reset si LPC_I2C1->I2CONCLR = 0x08;

block until interrupt while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

i2stat should be 0x50, byte received, ack sent if (LPC_I2C1->I2STAT != 0x50) { printf("rDATA%d %x\r\n",i,LPC_I2C1->I2STAT); stop LPC_I2C1->I2CONSET = 0x10; return ; }

data[i] = LPC_I2C1->I2DAT; }

last byte nack next byte LPC_I2C1->I2CONCLR = 0x4;

reset si LPC_I2C1->I2CONCLR = 0x08;

block until interrupt while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

i2stat should be 0x58, byte received, nack sent if (LPC_I2C1->I2STAT != 0x58) { printf("lastd %x\r\n",LPC_I2C1->I2STAT); stop LPC_I2C1->I2CONSET = 0x10; return ; }

data[length-1] = LPC_I2C1->I2DAT;

stop LPC_I2C1->I2CONSET = 0x10;

reset si LPC_I2C1->I2CONCLR = 0x08; }

posted by Carlos Rodriguez 24 Apr 2015

This code is hard to read. Please use <<code>> and <</code>> around posted code to format it properly. You are obviously not using the mbed library code for I2C but accessing the hardware at low level. Maybe you should give the lib a try first. It should be possible to have a delay between one message and the following repeated start. Something like

i2c.start();
i2c.write(byte);
i2c.write(byte);
wait_us(100);
i2c.start();
etc.

Note that printf instructions will cause a very long delay compared to your I2C bitrate and could hold up SCL for some time before it finishes..

I have never used the SMBus protocol so not really sure what sequence you need to generate for your tests.

posted by Wim Huiskamp 24 Apr 2015