Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

who can help me about I2C

Altera_Forum
Honored Contributor II
1,365 Views

http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/huh.gif  

I &#39;m test the EEPROM of I2C interface,and meet a problem. I use the "opencores I2C master " module. 

 

step 1, I write a byte, then read it, it&#39;s right. 

step2, I write 8 bytes into the EEPROM, using step1 

step3, I use "sequential read command "to continously read the data which been witen into eeprom by step2! Only the last byte is right, the bytes all are error before the last byte!
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
389 Views

feiwu, What device are you writing to. 24C32 or similar? 

 

I am not familiar with the opencores i2c module, but I know I2c eeproms well. 

Are you allowing time between your write cycles. If you write your data in separate bus cycles (i.e. start-transactions-stop), then the device will detach itself from the I2C bus until it has completed its memory write cycle. You must wait until this is complete before writing the next byte. This can be done in 2 ways: 

1. pause or sleep for the manufactures maximum specified time period (typically around 10mS). 

2. attempt to address the device until it returns an acknowledge (called acknowledge polling). 

 

1 is the easiest to implement but 2 is more time efficient because the true time can be much less than the worst-case time. 

 

You can also write up to 32 bytes at once provided the address locations are all within the same page boundary (i.e. address bit 5 upwards are the same), but you must still perform the above wait afterwards.
0 Kudos
Altera_Forum
Honored Contributor II
389 Views

Hi Cliff, 

I&#39;m sorry, I&#39;m a fresher to the website! 

You understood me well, and I have added the address! 

But I only can read the last byte by "sequential read command " 

 

Where can I down load some cource code about I2C?
0 Kudos
Altera_Forum
Honored Contributor II
389 Views

Can you provide some more detailed information? 

Are you able to determine how the module is accessing the I2c bus (e.g. start, read, write, stop sequences) 

Perhaps you could post a section of your code showing the problem.
0 Kudos
Altera_Forum
Honored Contributor II
389 Views

TO:feiwu 

 

hello,I am testing the I2c,my ip core hasn&#39;t hal susport. 

 

if you have .gave me a ip core. 

 

thank you! 

 

zhx_shi@163.com
0 Kudos
Altera_Forum
Honored Contributor II
389 Views

For the IP core ,you could download the NIOS2 linux1.3 , then set up the nios2linux 1.3 and you could see the IP core in SOPC builder! 

 

List is my soyurce code for test IIC , help me! 

 

I2C_prescale=ALT_CPU_FREQ/(5*100000)-1;//ALT_CPU_FREQ is in "system.h" 

IOWR(I2C_BASE,I2C_PRERlo,I2C_prescale);  

IOWR(I2C_BASE,I2C_PRERhi,I2C_prescale>>8); // high 8 bits 

 

PRERhi=IORD(I2C_BASE,I2C_PRERhi);//read again 

printf(" again PRERhi=%d\n",PRERhi); 

PRERlo=IORD(I2C_BASE,I2C_PRERlo); 

printf("again PRERlo=%d\n",PRERlo); 

//enable I2C 

CTR=IORD(I2C_BASE,I2C_CTR); 

printf("CTR=%2x\n",CTR); 

IOWR(I2C_BASE,I2C_CTR,0x80);  

CTR=IORD(I2C_BASE,I2C_CTR); 

printf("CTR=%2x\n",CTR); 

 

 

for(j=1;j<=8;j++) 

printf("IIC test=%2x\n",j); 

 

//slect device 

CSR=IORD(I2C_BASE,I2C_CSR); 

printf("1 CSR=%2x\n",CSR); 

IOWR(I2C_BASE,I2C_DATA,E2PROM_ADDR); //ob1010000 0 ,prepare the data first 

IOWR(I2C_BASE,I2C_CSR,0x91); //STA,WR,IACK ,start transferring 

//select memory  

 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02) 

printf("2 busy CSR=%2x\n",CSR) ; //tip=1 :when transferring data 

 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80) 

printf("3 no ack CSR=%2x\n",CSR) ; //rxack=0: Acknowledge received 

 

IOWR(I2C_BASE,I2C_DATA,eeprom_a+j);  

IOWR(I2C_BASE,I2C_CSR,0x11); //WR,IACK 

CSR=IORD(I2C_BASE,I2C_CSR); 

printf("4 CSR=%2x\n",CSR); 

//write data and terminate 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02) 

printf("5 busy CSR=%2x\n",CSR) ; //tip=1 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80) 

printf("6 no ack CSR=%2x\n",CSR) ; //rxack=0 

//j=1; 

IOWR(I2C_BASE,I2C_DATA,eeprom_d+j);  

IOWR(I2C_BASE,I2C_CSR,0x51); //STO,WR,IACK 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02) //tip=1 

printf("7 busy CSR=%2x\n",CSR); 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80) //rxack=0 

printf("8 no ack CSR=%2x\n",CSR); 

 

i = 0; 

while (i<200000) 

i++; 

i = 0; 

while (i<200000) 

i++; 

CSR=IORD(I2C_BASE,I2C_CSR); 

printf("9 CSR=%2x\n",CSR);  

/////////////////////////////////////////////////////////////// 

//read back 

///////////////////////////////////// 

//slect device COMMAND 1 

IOWR(I2C_BASE,I2C_DATA,E2PROM_ADDR); 

IOWR(I2C_BASE,I2C_CSR,0x91); //STA,WR,IACK 

//select memory  

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02); //tip=1 

printf("10 CSR=%2x\n",CSR); //rxack=0 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80); //rxack=0 

IOWR(I2C_BASE,I2C_DATA,eeprom_a+j-1);  

IOWR(I2C_BASE,I2C_CSR,0x11); //WR,IACK 

//select device and READ COMMAND 2 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02); //tip=1 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80); //rxack=0 

IOWR(I2C_BASE,I2C_DATA,E2PROM_ADDR+1); //device address and READ 

IOWR(I2C_BASE,I2C_CSR,0x91); //re-STA,WR,IACK 

//read data and terminate  

 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02) //tip=1 

printf(" test1 CSR=%2x\n",CSR);  

CSR=IORD(I2C_BASE,I2C_CSR); 

printf(" test2 CSR=%2x\n",CSR);  

 

 

IOWR(I2C_BASE,I2C_CSR,0x21); //RD,ACK,IACK (0b0010 0001) 

 

while (i<50000) 

i++; 

 

Readdata_I2C_B=0x00; 

Readdata_I2C_B=IORD(I2C_BASE,I2C_DATA); 

 

printf(" Readdata_I2C_B=%2x\n",Readdata_I2C_B); //rxack=0 

 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02); //tip=1 

printf(" test3 CSR=%2x\n",CSR); //rxack=0 

//2005,07,20 shield 

//while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80); //rxack=0 maybe not need the lopp 

//2005,07,20  

IOWR(I2C_BASE,I2C_CSR,0x69); //STO,RD,NACK,IACK (0b01101001) 

 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02); //tip=1 

// while((CSR=(I2C_BASE,I2C_CSR))&0x80)  

printf(" 11 CSR=%2x\n",CSR); //rxack=0 

Readdata_I2C=0x00; 

Readdata_I2C=IORD(I2C_BASE,I2C_DATA); 

 

 

 

if(Readdata_I2C==(eeprom_d+j)) 

printf("write data= %2x Readdata_I2C=%2x\n OK\n!",eeprom_d+j,Readdata_I2C); 

else 

printf("write data= %2x Readdata_I2C=%2x\n ERROR!\n",eeprom_d+j,Readdata_I2C); 

i = 0; 

while (i<200000) 

i++; 

i = 0; 

while (i<200000) 

i++; 

 

} // Have been tested OK ! 

 

 

 

 

// continuous read 8 bytes data by "sequential read " command 

 

printf(" IIC continously read test\n"); //rxack=0 

//slect device COMMAND 1 

IOWR(I2C_BASE,I2C_DATA,E2PROM_ADDR); 

IOWR(I2C_BASE,I2C_CSR,0x91); //STA,WR,IACK 

//select memory  

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02); //tip=1 

printf("c1 CSR=%2x\n",CSR); //rxack=0 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80); //rxack=0 

IOWR(I2C_BASE,I2C_DATA,eeprom_a); // from first address 

IOWR(I2C_BASE,I2C_CSR,0x11); //WR,IACK 

//select device and READ COMMAND 2 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02); //tip=1 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80); //rxack=0 

IOWR(I2C_BASE,I2C_DATA,E2PROM_ADDR+1); //device address and READ 

IOWR(I2C_BASE,I2C_CSR,0x91); //re-STA,WR,IACK 

//read data and terminate  

// prepare to get date 

 

// need judge ACK 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02); //tip=1 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x80); //rxack=0 

 

for(j=1;j<=6;j++) // when I change the loop number, the last byte is always right 

CSR=IORD(I2C_BASE,I2C_CSR); 

printf(" C2 CSR=%2x\n",CSR);  

 

while(((CSR=IORD(I2C_BASE,I2C_CSR))&0x02)== 0x20) //tip=1 

printf(" C3 CSR=%2x\n",CSR);  

CSR=IORD(I2C_BASE,I2C_CSR); 

printf(" C4 CSR=%2x\n",CSR);  

 

 

IOWR(I2C_BASE,I2C_CSR,0x21); //ACK,IACK (0b0010 0001) 

 

 

Readdata_I2C_B=0x00; 

Readdata_I2C_B=IORD(I2C_BASE,I2C_DATA); 

 

printf(" data= %2x Readdata_I2C_B=%2x\n OK!",j,Readdata_I2C_B); 

 

} // read 6 bytes ,all is error 

 

 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02) //tip=1 

printf(" C5 CSR=%2x\n",CSR); //rxack=0 

IOWR(I2C_BASE,I2C_CSR,0x69); // STO,RD,NACK,IACK (0b01101001) 

 

while((CSR=IORD(I2C_BASE,I2C_CSR))&0x02); //tip=1 

printf(" C6 CSR=%2x\n",CSR); //rxack=0 

Readdata_I2C=0x00; 

Readdata_I2C=IORD(I2C_BASE,I2C_DATA); // the last byte is OK! 

 

printf("data = 8 Readdata_I2C=%2x\n OK!",Readdata_I2C);
0 Kudos
Altera_Forum
Honored Contributor II
389 Views

feiwu, 

I cannot see anything obviously wrong with your code. 

 

What eeprom addresses are you writing to (your vaiable eeprom_a)? 

 

It is strange that you are getting correct results in the first section but not in the second. In fact, you are actually using sequential read in both sections. You are reading the address just before the one just written with an ACK, followed by the actual location with a NACK. The is perfectly valid. 

 

You appear to be only reading back 7 bytes in your second section. 

 

One comment I would make is that you are performing a long delay using a counting loop. Have you checked that this is actually giving sufficient delay, since clock speed, processor type and optimization level can effect this. After your write operation you must wait for about 10mS before attempting any further comms with your eeprom. You might want to consider using usleep(), since this will give a known delay.  

 

I may be worth looking at what is happening on the i2c pins using an oscilloscope or use Signal-Tap to analyse the real time activity.
0 Kudos
Reply