Home arrow Support arrow Forums

Luminary Micro Forums

swieser

Fresh Boarder

2008/11/19 17:41

I2C module/state macine issues

Hello,
I have quite a problem with my I2C module.

I'm reading a value in a device register on the bus. I thus have the following protocol:

Address+Write | Register | Adress+Read | Data
Master Master Master Slave

This protocl works fine and I successfully read the data in the register. Now the problem is when I place this in a while loop, because the second time I try to send data, the Data Register(I2CMDR) is impossible to update. I thus think tis is a problem related to the state machine of the I2C, as when in the receive state maybe writing this register is not allowed.

But this is the values I write in the I2CMCS register and the state in which the module should be, and I find no errors:


Master Idle State -> Write, RUN+START
-> Master Transmit State -> Read, RUN+START+STOP
-> Master Idle State

So at the end of the loop, the I2C should be in an Idle state, allowing writing on the I2CMDR register right? What I am missing then?

login or register to reply

VIKTOR_BUCHER

Fresh Boarder

2008/11/20 06:43

Re:I2C module/state macine issues

I don't know if this would help you but here it goes :

What I found is that after writing to I2CMCS (control)you should wait some time before reading I2CMCS (status) because the status take some time to reflect the actual state of the bus. I put 3 __nop() instructions before reading the status.


Obs.: I don't use Luminary library. I use MDK3.24


Regards

Viktor

login or register to reply

swieser

Fresh Boarder

2008/11/20 11:19

Re:I2C module/state macine issues

Actually it didn't help. I tried adding delays before and after writing the register, but it seems remaining as in "read-only". What can I do to change that or to force the state machine of the module / reset the module??

EDIT: Ok, it finnally worked, and this is the line that was the cause of the problem:

HWREG(I2C0_MASTER_BASE + I2C_O_MDR)&= 0xFFFFFF00;
HWREG(I2C0_MASTER_BASE + I2C_O_MDR)|= u8RegAddr;

I was trying to unchange the reserved bits by using masks, but actually, this doesn't work, and by replacing these two lines by
HWREG(I2C0_MASTER_BASE + I2C_O_MDR)= u8RegAddr;

The memory keeps unchanged, but the data send on the bus is correct.

Can someone explain me what's behind this? Because even if now I have something working I don't understand why.


Post edited by: swieser, at: 2008/11/20 11:19

Post edited by: swieser, at: 2008/11/20 11:36

login or register to reply

slandrum

Gold Boarder

2008/11/20 12:01

Re:I2C module/state macine issues

HWREG(I2C0_MASTER_BASE + I2C_O_MDR)&= 0xFFFFFF00;

HWREG(I2C0_MASTER_BASE + I2C_O_MDR)|= u8RegAddr;

The reason the above didn't work is that you were writing to the register twice, the first time with a value that you really didn't want to put in the data register.

If you wanted to do read/modify/write, the correct way to do it is:

HWREG(I2C0_MASTER_BASE + I2C_O_MDR) = (HWREG(I2C0_MASTER_BASE + I2C_O_MDR) & 0xffffff00) | u8RegAddr;

This will only write to the register once.

login or register to reply