- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/huh.gif
I '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'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!Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Cliff,
I'm sorry, I'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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TO:feiwu
hello,I am testing the I2c,my ip core hasn't hal susport. if you have .gave me a ip core. thank you! zhx_shi@163.com- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page