I2C Simulation

Forum for problems or queries regarding Flowcode Comms Components. Eg LIN, I2C, SPI, RS232, CAN, IrDA etc

Moderators: Benj, Mods

Post Reply
Ralph
Posts: 18
Joined: Tue Mar 04, 2008 11:32 pm
Contact:

I2C Simulation

Post by Ralph »

Hi,
Is there any way to simulate a full I2C bidirectional communication link using Flowcode to test the program?

Also, do you have any additional I2C program examples and documentation for the I2C component?

Thank you,
Ralph

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: I2C Simulation

Post by Benj »

Hello Ralph

The I2C is currently only operational in master mode via Flowcode. This means that you cannot currently use it as a bus between two microcontrollers. Maybe the RS232 or SPI bus would be ok for you to use.

You can use Flowcode to test your programs by queing up bytes in the component receive buffer.

Ralph
Posts: 18
Joined: Tue Mar 04, 2008 11:32 pm
Contact:

Re: I2C Simulation

Post by Ralph »

Hi Ben,
The master mode is what I need.
What I am trying to do is communicate with a Smart Battery over the SMBUS. The battery can be a master for event driven messages, however it will act as a slave when polled for data. That is how I intend to use it.

The battery pack is the nl2044hd22 manufactured by Inspired Energy (http://www.inspired-energy.com). From their data sheet the read word protocol is below.

http://www.inspired-energy.com/Standard ... NL2044.htm NL2044HD22 (High Current Discharge version) Engineering data sheet, page 12.
____________________________
3.3.4.2.Read Word
Reading data is slightly more complex than writing data. First the host must write a command to the slave device.
Then it must follow that command with a repeated start condition to denote a read from that device's address. The
slave then returns two bytes of data.
Note that there is not a stop condition before the repeated start condition, and that a "Not Acknowledge" signifies
the end of the read transfer.

I couldn't figure out how to paste in the "Read Word" bit definition image from the data sheet, so here goes:

Bits Descritpion
1 Start
7 Battery Address
1 Write
1 Ack
8 Command Code
1 Ack
1 Start
7 Battery Address
1 Read
1 Ack
8 Data Byte Low
1 Ack
8 Data Byte High
1 Ack

Read Word Protocol
SMBus Host (master) Smart Battery (slave)
____________________________________________
What I have tried is:
1. MI2C_Init
2. MI2C_Start
3. MI2C_Transmit_Byte (0x16 is the address with the LSB=0)
4. MI2C_Transmit_Byte (0x09 is the Command Code for reading the voltage)
5. MI2C_Start_Restart
6. MI2C_Transmit_Byte (0x17 is the address with the LSB=1)
7. MI2C_Receive_Btye (I set the “Last(BYTE)=1 and a variable “LOW” for the return value)
8. MI2C_Receive_Btye (I set the “Last(BYTE)=0 and a variable “HIGH” for the return value)
9. MI2C_Stop

I am receiving ACKs when addressing the battery and sending the command code, however, I can not receive any data.
I’m not sure if the problem is with sending the command code or the receive command.
My understanding of communicating with a slave is that the master generates the clock on the SCL line and the slave returns the data during this period on the SDA line.

Does the PIC generate the clock during the “MI2C_Receive_Btye” command?
What is the purpose of the “Last(BYTE)” field in the “MI2C_Receive_Btye” command?

Do you have any thoughts on my communication problem? Any help would be much appreciated.

Thank you,
Ralph

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: I2C Simulation

Post by Benj »

Hello Ralph

The last byte variable tells the I2C slave device that no more bytes will be read. So you will need to send a 0 for the first byte and a 1 for the second byte.

Also have you used pull up resistors on the line. The I2C driver cannot pull up the line to +5V so it requires the two pull up resistors.

Ralph
Posts: 18
Joined: Tue Mar 04, 2008 11:32 pm
Contact:

Re: I2C Simulation

Post by Ralph »

Hi Ben,
You are correct! I sent a a 0 for the first byte and a 1 for the second byte and received the correct data.

Now I have another question regarding processing the data received. Since I am receivig the data in a High Byte and a Low Byte I need to combond them to be a useful number. For example, the battery voltage is sent in mV from the battery:

High Byte = 64
Low Byte = 119

Normally I would do the following to get the correct number:

Voltage = (High Byte * 256)+Low Byte ==> (64*256)+119 = 16536 mV

Using this equation I run into a problem as the answer is limited to 1 byte, or 256.

How would you do this operation?

Thank you,
Ralph

Ralph
Posts: 18
Joined: Tue Mar 04, 2008 11:32 pm
Contact:

Re: I2C Simulation

Post by Ralph »

Follow-on to above:
For the voltage example I could just use the high byte and loose some resolution, however, for other fields I need all 16 bits.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: I2C Simulation

Post by Benj »

Hello Ralph

Thats great news glad its working correctly for you now.

You could simply fit the 16 bit number into a INT variable.

Eg.

High Byte = 64
Low Byte = 119
Result Int = ( High Byte << 8 ) + Low Byte

Ralph
Posts: 18
Joined: Tue Mar 04, 2008 11:32 pm
Contact:

Re: I2C Simulation

Post by Ralph »

Thanks Ben! The INT Variable worked.

Now I have a question for display purposes.

The INT output that I display is 16536 mV. Now if I want to convert the number to volts I would divide by 1000. If I do this, the number calculated is 16 since it won't calculate decimals.
How can I split the number for display purposes. For example, the right 3 digits = variable 1 and the left 2 digits = variable 2.

Then I could display:

Variable 2 "." Variable 1 ==> 16.536 Volts.

Thanks again,
Ralph

Sean
Valued Contributor
Valued Contributor
Posts: 548
Joined: Tue Jun 26, 2007 11:23 am
Has thanked: 6 times
Been thanked: 44 times
Contact:

Re: I2C Simulation

Post by Sean »

hello Ralph,

I have attached a simple demonstration program that converts a mV value into a voltage display. Leading zeros must be inserted into the fractional part of the display if it is less than 3 digits long.
mV2V.fcf
(5 KiB) Downloaded 565 times
A similar technique - using spaces - can be used to justify the entire number based on the length of the integer part.

Ralph
Posts: 18
Joined: Tue Mar 04, 2008 11:32 pm
Contact:

Re: I2C Simulation

Post by Ralph »

Thank you!

Post Reply