Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

i2c protocol software implementation

Status
Not open for further replies.

Fan174

Member level 2
Member level 2
Joined
Mar 27, 2018
Messages
51
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
413
Good evening to all

There are so many document's available on the internet for I2C communication and I have spend hard time to understand I2C software protocol

I am not looking for any code. I want to understand how does it work so I made one flow chart that explain my understanding

I have attached PDF file and I am looking one guide who can help me with my flow chart.
 

Attachments

  • i2c1.pdf
    173.4 KB · Views: 129

Hi,

This is not a general I2C communication flow chart.

It as a dedicated DS1307 I2C communication.
Thus please refer to the DS1307 datasheet. There are three figures (4, 5 and 6). Please say which one you want to implement. Then compare them step by step with your flow chart.

There are mistakes. But you did a good job. Drawing the flow chart is the best way to really understand the interface.
I also like your naming:
"Generate" is a bit manipulating process
"Send" is an 8 bit shift process (I´m not sure you are aware of this, because of the right bottom part)
"Get" is a one bit read process

Confusing is the right bottom part. With "i<7"...
Here - I think - is a mistake. I can just guess that this should be the inner loop of the "send" process.

Also note:
* In the DS1307 datasheet figures there is only one "I2C Start" per figure, but your flow chart includes three "I2C Start" procedures.
* At "data write" procedures the SLAVE needs to set ACK.
* At "data read" procedures the MASTER needs to set ACK except the last one. --> you additionally need to implement "SET ACK"

***
To prevent you from the most often made I2C implementation mistake:
Mind: I2C never sets an output HIGH. A HIGH is generated by an external pullup resistor and the I/O set to HIGH_IMPEDANCE.
Valid output states: DRIVE_LOW or HIGH_IMPEDANCE.

Klaus
 
  • Like
Reactions: Fan174

    Fan174

    Points: 2
    Helpful Answer Positive Rating
Hi,

This is not a general I2C communication flow chart.

It as a dedicated DS1307 I2C communication.
Thus please refer to the DS1307 datasheet. There are three figures (4, 5 and 6). Please say which one you want to implement. Then compare them step by step with your flow chart.

@KlausST I am really sorry for not defining title clearly. I am not very good in english. I want to learn i2C bit banging

I want to implement figure 6.

Hi,There are mistakes. But you did a good job. Drawing the flow chart is the best way to really understand the interface.

.
Thanks for encourage me to make flow chart. There are the different opinion in every link I will look each problem step by step

so can you point my some mistake so I can improve flow chart
 

Attachments

  • Data read ds1307.jpg
    Data read ds1307.jpg
    46.5 KB · Views: 132

Your flowchart is wrong. It generates new start with register address, however start has to be send exclusively before the slave address.

I suggest to refer to the original Philips/NXP I2C specification. **broken link removed**
 
  • Like
Reactions: Fan174

    Fan174

    Points: 2
    Helpful Answer Positive Rating
Hi,

How I´d check it step by step:

Klaus
 

Attachments

  • i2c1_mod.pdf
    218.8 KB · Views: 112
  • Like
Reactions: Fan174

    Fan174

    Points: 2
    Helpful Answer Positive Rating
Your flowchart is wrong. It generates new start with register address, however start has to be send exclusively before the slave address.

I suggest to refer to the original Philips/NXP I2C specification. **broken link removed**
I saw datasheet and I am making flow chart for figure 9

I have attached new flow chart

Does it match with figure 9 ?

- - - Updated - - -

Hi,

How I´d check it step by step:

Klaus
I have modified flow chart according to figure 6

I don't understand if I get Ack How to read data n to Data n+x

Please see my Flow chart I2C 4
 

Attachments

  • i2c2.pdf
    171 KB · Views: 109
  • i2c4.pdf
    169.4 KB · Views: 103

Get philips(nxp) AN10216.pdf. The proper protocol is given on page. 11.
Make a flowchart for the specified one.
 

Hi,

How I´d check it step by step:

Klaus

@KlausST I need your help,

I do not understand how to implement below in flow chart

DATA TRANSFERRED (X+1 BYTES + ACKNOWLEDGE); NOTE: LAST DATA BYTE IS FOLLOWED BY A NOT ACKNOWLEDGE (A) SIGNAL)

My flow chart is incomplete, after ACK I have to read many bytes how to do that
 

Hi,

Reading an 8 bit wide "data" byte is similar to
outputting an 8 bit "word address" or sending the 8bit "slave address + R/W".

it is a loop running 8 times per byte: like this.
* n= 8
Loop:
* SCL = 0
* wait (during this phase the master or slave OUTPUTS data)
* SCL = 1
* wait
* READ state of SDA = data bit "n-1 of a byte" (MSB first)
* n = n -1
if n>= 0 goto LOOP
(now you have 8 bits = 1 byte read)
***
then you have to do the 9´th bit communication for ACK

***

run this for as many bytes you want to read.

***************************
wait time: if you want about 400kHz bit rate, then one bit time is 2.5us. Since you have two waits per bit the wait time should be about 1.25us

******
refer to UM10204, Fig 38 for timing.
refer to UM10204, Fig 5 for SDA and SCL sates

******
Mind
* idle sate is: SCL = 1 and SDA = 1
* Before performing an "I2C_START" be sure that the bus is in idle sate. If it is not in idle state: perform an "I2C_STOP" before the "I2C_START"
* A single bit communication starts with SCL=1 and ends with SCL=1. This is also true for a ACK communication ans well as a 8 bit data communication.
* to end a communication always perform an I2C_STOP

Klaus
 
  • Like
Reactions: Fan174

    Fan174

    Points: 2
    Helpful Answer Positive Rating
Hi,

Reading an 8 bit wide "data" byte is similar to
outputting an 8 bit "word address" or sending the 8bit "slave address + R/W".

it is a loop running 8 times per byte: like this.

Klaus

Thanks Klaus, That's excellent explanation

I have modified my flaw chart to read many bytes @KlausST Please see attached flow diagram

I am not very good at Embedded c programming.

This is my attempt to store the byte using array pointer in c language

Code:
#include<stdio.h>

int main(void)
{
    int array[8]= {5, 4, 6, 8, 9, 7, 8, 8};
	
    int *pointer = &array[0];
    
	int i;
  
    for( i = 0; i < 8; i++ )
        printf("\n Array[%d] is %d ",i,*(pointer+i));
   
    
	for( i = 0; i < 8; i++)
        printf("\n %d at %u ",*(pointer+i),(pointer+i));
   
    return 0;
}

Output of code

Array[0] is 5
Array[1] is 4
Array[2] is 6
Array[3] is 8
Array[4] is 9
Array[5] is 7
Array[6] is 8
Array[7] is 8

5 at 6422280
4 at 6422284
6 at 6422288
8 at 6422292
9 at 6422296
7 at 6422300
8 at 6422304
8 at 6422308
 

Attachments

  • I2c5.pdf
    173.9 KB · Views: 96
Last edited:

Hi,

you forgot about ACK after each byte.
I now marked it red in my post#9
Please read the recommended documents.

I am not very good at Embedded c programming.
I´can read a bit, but can't write at all....


Klaus
 

Hi,

you forgot about ACK after each byte.
I now marked it red in my post#9
Please read the recommended documents.

Klaus

Please take a look at new flow chart. I have added Ack after each byte. Let me know if I am making mistake somewhere

Hi,
I´can read a bit, but can't write at all....

Klaus
I understand I am making flow chart to understand basic first. Once I complete flow chart then I will try to convert it into program
 

Attachments

  • i2c6.pdf
    174 KB · Views: 107

Correct, except for: You are reading 9 bytes instead of 8. And you miss to generate the NACK after last byte.
 

Correct, except for: You are reading 9 bytes instead of 8. And you miss to generate the NACK after last byte.

Thanks for pointing mistake

see the new flow chart Does it look's okay
 

Attachments

  • SPI7.pdf
    173.9 KB · Views: 121

Looks good now
Then I would try next step. I have to write code for each box in flow chart

according to Datasheet AN10216-01 I2C

START and STOP Conditions

START: A HIGH to LOW transition on the SDA line while SCL is HIGH

STOP: A LOW to HIGH transition on the SDA line while SCL is HIGH

pseudo code : This code will not compile and run. It's just for understanding

Code:
SDA        PIN1

SCL        PIN2  

define High  1

define Low   0

void Generate_I2C_Start ();    //Declare the function  

void Generate_I2C_Stop ();    //Declare the function  

void main (void)   //start from here 
{
     while (1)  //infinite Loop
   {
        Generate_I2C_Start ();  //generate i2c start conditions 
   }
}

according to this A HIGH to LOW transition on the SDA line while SCL is HIGH

What would be routine Generate_I2C_Start (); ?
 
Last edited:

Which processor are you working with?

Driving SCL or SDA to high level is done by tri-stating the port pin. Except for peripherals with open drain pin like 8051 this needs programming the direction register.


Code C - [expand]
1
2
3
4
5
6
7
8
// assumed state before start
SDA = Z;
SCL = Z;
// Generate start
SDA = 0;
delay;
SCL = 0;
delay;

 

Which processor are you working with?

Driving SCL or SDA to high level is done by tri-stating the port pin. Except for peripherals with open drain pin like 8051 this needs programming the direction register.
Hi FvM,

I would prefer 8051

This is new version of pseudo code It's little bit different then the original flow chart



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#define SDA P2_1        /* Set P2.1 = SDA */
#define SCL P2_2        /* Set P2.2 = SCL */
 
define High  1
 
define Low   0
 
void I2C_Initialize (void)     //Declare the function
void I2C_Delay (N)             //Declare the function
void Generate_I2C_Start ();    //Declare the function  
 
void Generate_I2C_Stop ();    //Declare the function  
 
void main (void)   //start from here 
{
     while (1)  //infinite Loop
     
   {
        I2C_Initialize ();     //  idle sate is: SCL = 1 and SDA = 1
        Generate_I2C_Start ();  //generate i2c start conditions 
   }
}
 
// This function give N nuber of delay 
void I2C_Delay(int N)      
{
    unsigned int i;
 
    for( i= 0; i < N; i++);
}
 
// Initialize idle sate is: SCL = 1 and SDA = 1
void I2C_Initialize (void) 
 
{
     SCL = 1   // set SCL pin to High
     SDA = 1   // Set SDA pin to High 
}
 
//generate i2c start conditions 
void Generate_I2C_Start (void)
{
    SDA = Low;  // Clear SDA Pin
    I2C_Delay(2);  //Required delay
    SCL = Low;   // Clear SCL Pin
    I2C_Delay(2);  //Required delay
}

 
Last edited:

Hi,

please don´t get sloppy now. Stay focussed. Read our posts.

from post#2:
To prevent you from the most often made I2C implementation mistake:
Mind: I2C never sets an output HIGH. A HIGH is generated by an external pullup resistor and the I/O set to HIGH_IMPEDANCE.
Valid output states: DRIVE_LOW or HIGH_IMPEDANCE.

from post#9:
* Before performing an "I2C_START" be sure that the bus is in idle sate. If it is not in idle state: perform an "I2C_STOP" before the "I2C_START"

Klaus
 

@KlausST , @FvM

I am still stuck to convert block into coding. Can you give some hint's how to go for further process
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top