I2C (vi)--s3c2440 access the EEPROM using the I2C interface

Source: Internet
Author: User
Tags ack volatile

After reading the I2C official agreement document, take s3c2440 and EEPROM to verify it.

Originally want to use s3c2440 SDA and SCL pin Gpio to simulate, but in the absence of an oscilloscope for a week, how can not come out, finally or give up. Even reference to Linux under the i2c-algo-bit.c and I2C-GPIO.C, Still not tuned out. If there is an oscilloscope, it may soon be possible to find the cause, and now have no idea where the problem is. In fact, the purpose of using GPIO to simulate I2C is very simple, in a simple and profound way to understand I2C.

Since this road can not go for a while, the second, with s3c2440 I2C interface to access the EEPROM, as long as the datasheet to do, basically do not have to consider timing slightly.

Starting from the datasheet of s3c2440 and at24c02a:

S3c2440 's introduction is actually very simple, Iic-bus interface has four modes of operation:

Master transmitter Mode
Master Receive mode
Slave transmitter Mode
Slave Receive mode

But in fact, we only use M-TX and M-rx, because in the s3c2440 and EEPROM connection, there is no way to s3c2440 as a slave.

Then s3c2440 's datasheet copy some of the content from the I2C protocol document: Start termination conditions \ Data transmission Format \ack\ Read and write operations \ Bus quorum \ Termination conditions, and so on. It's better to look at the I2C protocol documentation.

I2c-bus configuration:

In order to control the SCL frequency, a 4bit divider can be controlled in the Iiccon. The Iicadd registers are used to hold the Iic-bus interface address, which is practically useless and requires no address only when accessing the device. And here s3c2440 is the main device.

Before each IIC Tx/rx operation, do the following:

If necessary, write from address to Iicadd

Set Iiccon registers (enables interrupts, defines the SCL cycle)

Set Iicstat to enable serial output

Then there is the flowchart of the M-TX and M-rx mode of operation, followed by the code in strict accordance with this diagram. There is no screenshot here.

The description of the register is probably as follows:

#define RIICCON (* (volatile unsigned *) 0x54000000)
/**********************
[7]:ack Enable Bit
[6]:tx clock Source Selection 0:iicclk = pclk/16 1:IICCLK = pclk/512
[5]:tx/rx Interrupt
[4]:INTERRUPT PENDING FLAG!!!!
[3:0]:tx Clock = iicclk/(iiccon[3:0]+1)
**********************/
#define RIICSTAT (* (volatile unsigned *) 0x54000004)
/**********
[7:6]:10:m-rx 11:m-tx
[5]:busy signal status/start STOP Conditon!!!
[4]:serial output enable/disable bit 1:enable
[3]:IIC arbitration procedure status flag bit | | Which didn ' t used
[2]:ADDRESS-AS-SLAVE STATUS Flag!!!
[1]:address Zero status flag
[0]:last-received bit status flag 0:ack 1:nack
**********/
#define RIICADD (* (volatile unsigned *) 0x54000008)
/*********
* [7:1]:slave address can be written only when the Iicstat output disable. Can be read at any time.
* ************/
#define RIICDS (* (volatile unsigned *) 0x5400000c)
/**************
* [7:0]:8bit Data shift reg for Iic-bus tx/rx operation. Iicstat can write only if the output of Iicds is available. You can read it at any time.
* *************/
#define RIICLC (* (volatile unsigned *) 0x54000010)
/**************
* This register is used for multiple hosts and is temporarily unavailable
* ************/


Look below AT24C02A's datasheet:

at24c02a:2k capacity, 32pages, each page8 byte, a total of 256 bytes. Read and write requires 8bit of Word address.

AT24C02A's address is from the following figure:


So the address is what we see 0XA0,A2 A1 A0 because of the low level of the three pins on the schematic diagram.

Write operation:

Example of a graph written in bytes:

Combined with s3c2440 's M-TX mode, the code operates as follows:

void i_write (unsigned int slvaddr, unsigned char addr, unsigned char data) {unsigned int ack;
	Init (SLVADDR);  Riicstat |= 0x3<<6;  Configure M Tx Mode Riicds = slvaddr;//0xa0; Write slave address to Iicds riiccon&=~0x10;  Clear pending bit riicstat = 0xf0;
	(m/t start)//the data of the IICDS is transmitted uart_sendbyte (' a '); while ((Riiccon & 1<<4) = = 0);//udelay (a)//ack period and then interrupt is pending if ((Riicstat & 0x01)    ==0) uart_sendbyte (' Y ');//ack = 0;    Received answer else Uart_sendbyte (' n ');//ack = 1;
	No answer Riicds = addr; riiccon&=~0x10;
	Clear pending bit//the data of the Iicds is shifted to SDA Uart_sendbyte (' B '); while ((Riiccon & 1<<4) = = 0);//udelay (a)//ack period and then interrupt is pending if ((Riicstat & 0x01) = =    0) uart_sendbyte (' Y ');//ack = 0;    Received answer else Uart_sendbyte (' n ');//ack = 1;
	No answer Riicds = data; riiccon&=~0x10; Clear pending bit//the data of the IICDS is SHIfted to SDA Uart_sendbyte (' C '); while ((Riiccon & 1<<4) = = 0);//udelay (a)//ack period and then interrupt is pending if ((Riicstat & 0x01) = =    0) uart_sendbyte (' Y ');//ack = 0;    Received answer else Uart_sendbyte (' n ');//ack = 1; No answer Riicstat = 0xd0;
	Write (m/t stop to iicstat)//riiccon = 0xe0; riiccon&=~0x10;
	Clear pending bit uart_sendbyte (' d ');

while ((Riicstat & 1<<5) = = 1);
 }

Read operation:

Take a randomly read graph as an example:



Random reads are complicated because the previous dummy write uses the M-TX mode, and the actual read operation is M-RX mode. Combined with the s3c2440 mode operation flowchart, the code is as follows:

unsigned char i_read (unsigned int slvaddr, unsigned char addr) {unsigned char data;
	int ack;
	Init (SLVADDR);  Riicstat |= 0x3<<6;  Configure M Tx Mode Riicds = slvaddr;//0xa0; Write slave address to Iicds riiccon&=~0x10;  Clear pending bit riicstat = 0xf0; (m/t start)//the data of the IICDS is transmitted while (Riiccon & 1<<4) = = 0)//udelay (a)//ack period an    D then interrupt is pending if ((Riicstat & 0x01) ==0) uart_sendbyte (' Y ');//ack = 0;    Received answer else Uart_sendbyte (' n ');//ack = 1;
	No answer Riicds = addr; riiccon&=~0x10; Clear pending bit//the data of the Iicds is shifted to SDA while ((Riiccon & 1<<4) = = 0);//udelay    Period and then interrupt is pending if (Riicstat & 0x01) ==0) uart_sendbyte (' Y ');//ack = 0;    Received answer else Uart_sendbyte (' n ');//ack = 1;
	No response init (SLVADDR);
	Riicstat &= ~ (0x1<<6);//configure M Rx mode riicstat |= 0x1<<7;  Riicstat |= 0x2<<6;Configure M Rx Mode Riicds = slvaddr; riiccon&=~0x10;  Clear pending bit riicstat = 0xb0; (m/r Start)//the data of Iicds (slave address) was transmitted while (Riiccon & 1<<4) = = 0);//udelay Rt_sendbyte (' o ');//ack period and then interrupt is pending:: if (Riicstat & 0x01) ==0) uart_sendbyte (' Y ');//ack = 0    ;    Received answer else Uart_sendbyte (' n ');//ack = 1;
	No answer data = Riicds;
	if (data==160) uart_sendbyte (' O '); riiccon&=~0x10; Clear pending bit//SDA is shifted to Iicds while (Riiccon & 1<<4) = = 0)//udelay (a)//ack period and then    Interrupt is Pending if (Riicstat & 0x01) ==0) uart_sendbyte (' Y ');//ack = 0;    Received answer else Uart_sendbyte (' n ');//ack = 1;
	No answer data = Riicds;
	if (data==160) uart_sendbyte (' O '); riiccon&=~0x10; Clear pending bit//SDA is shifted to Iicds while (Riiccon & 1<<4) = = 0)//udelay (a)//ack period and then Interrupt is Pending if (Riicstat & 0x01) ==0) uart_seNdbyte (' y ');//ack = 0;    Received answer else Uart_sendbyte (' n ');//ack = 1;
	No answer uart_sendbyte (' a ');
	Riicstat = 0x90;
	Uart_sendbyte (' B '); riiccon&=~0x10;
	Clear pending bit uart_sendbyte (' C ');
	while ((Riicstat & 1<<5) = = 1) uart_sendbyte (' O ');
	Uart_sendbyte (' d ');
	
return data; }

The other read and write operations of this EEPROM and so forth.

Finally, make a summary:

1. When a single writing section and random reading should be Gayan, the verification process found that in the two time between writing sections, the delay of 100US, in the second writing section of the time will not receive an ACK. It is normal to change the delay to 1000US.

2.IICDS reading and writing must be done before clearly IIC interrupt pending bit, which appears in the code:

	Riicds = slvaddr;
	riiccon&=~0x10; Clear Pending bit
3. Reading the data may read to 160, that is, 0xa0, no relationship, read more bytes is the data.         4.IICCON registers 5bit is the TX/RX interrupt enable/disable bit. And the first 4bit is interrupt pending flag. It is worth noting that the 2nd and 5th of the notes in the note after the register: A. A byte of data received and received complete; b. Universal broadcast or match from address; C. Bus quorum failure if IICCON[5]=0,IICCON[4]         will not operate properly. So even without IIC interruption, it is recommended to iiccon[5]=1.         To the point, in fact, there is no need to use IIC interruption, I mean that in the s3c2440 interrupt system on the IIC operation does not change, but iiccon[5]=1. So how do you know to send and receive. while ((Riiccon & 1<<4) = = 0);//udelay (a)//ack period and then interrupt is pending
if ((Riicstat & 0x01) ==0)
Uart_sendbyte (' y ');//ack = 0; Received answer
Else
Uart_sendbyte (' n ');//ack = 1; No answer.

Just the above code is OK, and by polling Iiccon's 4bit to view the ACK period and then interrupt is pending.

Of course, if you use interrupt System IIC interrupt is also possible, one is interrupt mode, one is polling way, here feel little difference.

About I2C bare metal end, but Gpio simulation I2C has been brooding AH ~ ~

In the work, Linux has done with the I2C subsystem with GPIO simulation I2C. That as long as the configuration of the Gpio input and output, structure data structure, drive can work, have to admire the powerful subsystem. Because the previous blog has analyzed both the file system and the device model, But not for specific subsystems did analysis, over time to analyze the Linux I2C, learning C language is how to achieve some of the characteristics of OOP, experience good code design ideas.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.