Detailed description of S3C2410 IIC driver

Source: Internet
Author: User

Write a program, use the I2C interface of S3C2410 to read/write the serial EEPROM 24lc04 (I2C interface), write a set of data, read and display it, and check whether it is correct.

 

Analysis: the I2C of S3C2410 is the master device, and the I2C of EEPROM is the slave device. The operations are written and read by the master device.

(1) set I2C control registers

1) sending and receiving transmission: iiccon = 0b 1 0 1 0 1111 = 0xaf

Meaning: Answer enabling, clock dividing into iicclk = pclk/16, interrupt enabling, clearing the interrupt mark, and pre-dividing value 15.

2) receiving End transmission: iiccon = 0b 0 0 1 0 1111 = 0x2f

Meaning: no response (non-response), the clock frequency is iicclk = pclk/16, the interrupt enable, the interrupt mark is cleared, and the pre-division value is 15.

(2) I2C control status register

1) Send and start transmission in master mode

Iicstat = 0b 11 1 1 0 0 0 0 = 0xf0

2) transmission in master mode and transmission termination

Iicstat = 0b 11 0 1 0 0 0 = 0xd0

3) receives and starts transmission in master mode

Iicstat = 0b 10 1 1 0 0 0 0 = 0xb0

4) receive and End transmission in master mode

Iicstat = 0b 10 0 1 0 0 0 = 0x90

 

1. Write a single byte

(1) single-byte write operations:

The byte write operation starts with the start bit of the master device, followed by the four-bit control code. The next three bits are Block Addressing bits (devices without address input pins) or chip selection (devices with address input pins ). The master transmitter then sends the R/W Bit (which is a logical low level) to the bus. A validation bit is generated from the device in the ninth clock cycle. The second byte sent by the master device is the address byte. The 24xx device will confirm each address byte and lock the address bit into the internal address counter of the device. For a 24xx00 device, only four low bits of the address bytes are used. The value of 4-digit height can be any value. After the last address byte is sent, the 24xx device sends a confirmation signal ack. After receiving the confirmation signal, the master device sends a data word, which is written to the addressing storage location. 24xx
After the device sends a confirmation signal again, the master device generates a stop condition and starts the internal write cycle. During the write (internal write) period, 24xx does not confirm the command. Therefore, you must confirm the query.

(2) byte read Operations:

The random read operation allows the master device to access arbitrary memory in a random manner. You must set the address byte before executing this command. As part of the write operation, the address byte is set by sending the byte address to 24xx (R/W is set to '0 '). After the byte address is sent, the start condition is generated when the master device receives the confirmation signal. After the internal address counter is set, the write operation is terminated. The master device sends the control byte again, and the R/W Bit in the byte is set to '1 '. Then 24xx sends a confirmation signal and an 8-Bit Data byte. The master device does not confirm the data transmission, but generates a stop condition. 24xx means that data transmission is stopped. After the command is Randomly Read, add 1 to the internal address counter
Point to the next address.

(3) read/write operations:

Host sending mode (write): After data is sent, the I2C bus interface waits for the iicds (I2C Data shift register) to write new data. At this time, the SCL line remains low.

Write interruption TX: S3C2410X can be used to determine whether the current data bytes have been completely transferred and sent. After the CPU receives the interrupt request, it needs to write the next new data to the iicds again during the interrupt processing.

Host receiving mode: After the data is received, the I2C bus interface waits until the iicds register is read by the program. Before the data is read, the SCL line remains low.

Read interrupt RX: S3C2410X also uses the interrupt to determine whether new data is received. After the CPU receives the interrupt request, the interrupt handler reads data from iicds.

(4) control byte values:

The address of the retrieved device (A0) + operation control command (R/W ):

1) sent by the primary device: 0xa0; received by the primary device: 0xa1

2) 24lc04 contains 512 bytes, which are divided into 256 bytes and 256 bytes. The Byte addresses are 0xa0 and 0xa2 respectively.

(5) confirm the Query Process:

It is the entire byte write process, and the loop is the validation Query Process.

The device does not confirm the command during the write cycle, which can be used to determine when the write cycle is completed. If the master device has enabled the Stop Condition of the write command, the device starts the internal timed write cycle. You can confirm the query at any time. This includes the control byte used to write commands (R/W = 0) after the start condition is sent by the master device. If the device is still in the write cycle, no validation signal is returned. Once no confirmation signal is returned, the start position and control byte must be resent. If the write cycle ends, the device returns a confirmation signal and the master device can execute the next read or write command. See the flowchart. The cycle in the figure is used to detect the validation signal of internal write termination. The essence is to constantly query the status of riicstat [0.

It can be seen that after the write is completed, it is critical to confirm the query.

 

 

Lab source program:

# Include "def. H"

# Include "2410addr. H"

# Include "2410lib. H"

# Include <string. h>

# Include ".. \ Inc \ config. H"

Void wr24c04 (u32 slvaddr, u32 ADDR, u8 data );

Void rd24c04 (u32 slvaddr, u32 ADDR, u8 * data );

Void main (void)

{

Unsignedint I, J;

Static u8 data [256];

Target_init ();

Uart_printf ("[I2C test using at24c04] \ n ");

Rgpeup | = 0xc000; // 1100 prohibit pulling (floating), with external pulling

Rgpecon & = ~ 0xf0000000;

Rgpecon | = 0xa0000000; // gpe15: iicsda gpe14: iicscl

Riiccon = (1 <7) | (0 <6) | (1 <5) | (0xf); // 0xaf, allow response and interruption, clear existing interrupt // iicclk = pclk/16

Riicstat = 0x10; // I2C bus data transfer allowed Rx/TX

Uart_printf ("Write test data into at24c04 \ n ");

For (I = 0; I <256; I ++)

Wr24c04 (0xa0, (u8) I, I); // 0xa0: 24lc04 address, (u8) I: Address of the chip to which data is to be written, // I: data to be written

For (I = 0; I <256; I ++)

Data [I] = 0;

Uart_printf ("\ nread test data fromat24c04 \ n ");

For (I = 0; I <256; I ++)

Rd24c04 (0xa1, (u8) I, & Data [I]);

For (I = 0; I <16; I ++)

{

For (j = 0; j <16; j ++)

Uart_printf ("% 2x", data [I * 16 + J]);

Uart_printf ("\ n ");

}

Uart_printf ("OK! Write Data is same toread data! \ N ");

}

 

// Write a one-byte Function Definition

Void wr24c04 (u32 slvaddr, u32 ADDR, u8 data)

{

Riicds = slvaddr; // sets the control byte.

Riicstat = 0xf0; // start sending

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1); // check the response ACK

Riicds = ADDR; // set the address byte

Riiccon = 0xaf; // clear the interruption status

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1); // check the response ACK

Riicds = data; // send data

Riiccon = 0xaf; // clear the interruption status.

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1); // check the response ACK

Riicstat = 0xd0; // stop writing

Riiccon = 0xaf ;//

Delay (1); // wait for the end to take effect

While (1)

{

Riicds = slvaddr;

Riicstat = 0xf0;

Riiccon = 0xaf;

While (riiccon & 0x10) = 0 );

If (! (Riicstat & 0x1) // check the response ACK

Break;

}

Riicstat = 0xd0; // stop write

Riiccon = 0xaf;

Delay (1); // wait for the end to take effect

}

// Read one-byte Function Definition

Void rd24c04 (u32 slvaddr, u32 ADDR, u8 * Data)

{

Riicds = slvaddr; // sets the slave device address to control byte

Riicstat = 0xf0; // start sending s

While (riiccon & 0x10) = 0); // query the Tx interruption status

While (riicstat & 1 );

Riicds = ADDR; // sets the unit offset address, which is sent

Riiccon = 0xaf; // operation

While (riiccon & 0x10) = 0); // query if the Tx interrupt status is interrupted, the iiccl is pulled low and the IIC stops/stops transmission. To restore, clear riiccon [4.

While (riicstat & 1 );

Riicds = slvaddr;

Riicstat = 0xb0; // start read

Riiccon = 0xaf; // clear the interrupt conditions and resume IIC operations

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1 );

Riiccon = 0x2f; // clear the interrupt flag. The response is forbidden because only one byte is read.

While (riiccon & 0x10) = 0); // query the interrupt status

* Data = riicds; // read data after the CPU usage es the interrupt request, it shoshould // read the datafrom the iicds register.

Riicstat = 0x90; // stop reading

Riiccon = 0xaf; // clear the interrupt

Delay (1 );

}

 

 

Ii. Write multiple bytes

(1) page write operations:

 

 

(2) Multi-byte Writing Process:

Begin

Pages = 0

Total number of pages written = number of nodes to be written/pagesize (16)

While pages <Number of pages written on the entire page

{

Write data on the entire page

Pages ++

}

Number of bytes remaining for less than one page = number of bytes to be written % pagesize (16)

Write remaining bytes

End

 

(3) Cross-page issues during continuous writing:

The write control byte, word address byte, and First Data byte are sent to the 24xx device in the same way as the write single byte. The difference is that the master device sends data bytes to a whole page instead of the Stop condition. These data bytes are temporarily stored in the in-chip page buffer. After the master device sends a stop condition, the data

Will be written into the memory. Each time a word is received, the internal address counter adds one. If the master device has more than one page of data to send before the stop condition is generated, the address counter will flip and the previously written data will be overwritten.

Cover. For byte write operations, once the stop condition is received, the internal write cycle starts.

 

(4) solutions to cross-page Problems:

Two Parameters pages and I are introduced. Pages indicates the number of pages occupied, and I indicates the total number of bytes written.

Taking writing 51 bytes consecutively as an example: the first 48 bytes are written on the whole page, and the last 3 bytes are written on another page consecutively. Each time the address counter is flipped, ADDR is assigned the first address of the page. Therefore, each time a page is written outside, the stop signal is sent to start writing internally, and ADDR + = 16; this solves the problem of cross-page writing. Restart and write the next page. This loop.

 

Lab source program:

# Include "def. H"

# Include "2410addr. H"

# Include "2410lib. H"

# Include <string. h>

# Include ".. \ Inc \ config. H"

Void wr24c04 (u32 slvaddr, u32 ADDR, u8 data );

Void rd24c04 (u32 slvaddr, u32 ADDR, u8 * data );

Void start (u32 slvaddr );

Void internal_write (u32 slvaddr );

Void main (void)

{

Unsigned int I, J;

Staticu8 data [256];

Target_init ();

Uart_printf ("[I2C test using at24c04] \ n ");

Rgpeup | = 0xc000;

Rgpecon & = ~ 0xf0000000;

Rgpecon | = 0xa0000000;

Riiccon = (1 <7) | (0 <6) | (1 <5) | (0xf );

Riicstat = 0x10;

Uart_printf ("writetest data into at24c04 \ n ");

Wr24c04 (0xa0, 0, 1 );

For (I = 0; I <256; I ++)

Data [I] = 0;

Uart_printf ("\ nreadtest data from at24c04 \ n ");

For (I = 0; I <256; I ++)

Rd24c04 (0xa0, (u8) I, & Data [I]);

For (I = 0; I <16; I ++)

{

For (j = 0; j <16; j ++)

Uart_printf ("% 2x", data [I * 16 + J]);

Uart_printf ("\ n ");

}

Uart_printf ("OK! Write Data is same toread data! \ N ");

}

// Write function definition (write multiple bytes)

Void wr24c04 (u32 slvaddr, u32 ADDR, u8 data)

{

Intsize = 51; // The total number of bytes to be written

Intm, N, I = 0; // I indicates the number of bytes that have been written.

Intpage = 0;

N = size % 16;

M = size-N; // The total number of bytes written in full-page write mode.

While (page <size/16)

{

Start (0xa0 );

Riicds = ADDR; // set the unit offset address, send

Riiccon = 0xaf; // clear the interruption status

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1); // check the response ACK

While (M --)

{

If (I % 16 = 0) & (I! = 0) // prevents the first page from being written down

{

Internal_write (0xa0 );

// At This Point, write a single page of bytes into the eeprom array (write in)

ADDR + = 0x10;

Page ++;

// Restart

Start (0xa0 );

Riicds = ADDR; // set the unit offset address, send

Riiccon = 0xaf; // clear the interruption status

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1); // check the response ACK

}

Riicds = data; // send data

Riiccon = 0xaf; // clear the interruption status.

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1); // check the response ACK

I ++; // number of bytes written

}

Internal_write (0xa0 );

ADDR + = 0x10;

Page ++;

}

// The following programs write less than one page of byte data consecutively, or execute continuous write from this if the size is less than 16

Start (0xa0 );

Riicds = ADDR; // set the unit offset address, send

Riiccon = 0xaf; // clear the interruption status

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1); // check the response ACK

While (n --)

{

Riicds = data; // send data

Riiccon = 0xaf; // clear the interruption status.

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1); // check the response ACK

}

Internal_write (0xa0 );

Riicstat = 0xd0; // stop write

Riiccon = 0xaf;

Delay (1); // wait for the end to take effect

}

// Read one-byte Function Definition

Void rd24c04 (u32 slvaddr, u32 ADDR, u8 * Data)

{

Riicds = slvaddr; // sets the slave device address to control byte

Riicstat = 0xf0; // start sending s

While (riiccon & 0x10) = 0); // query the Tx interruption status

While (riicstat & 1 );

Riicds = ADDR; // sets the unit offset address, which is sent

Riiccon = 0xaf; // operation

While (riiccon & 0x10) = 0); // query if the Tx interrupt status is interrupted, the iicscl is pulled down and the IIC is stopped // transfer. To restore, clear riiccon [4.

While (riicstat & 1 );

Riicds = slvaddr;

Riicstat = 0xb0; // start read

Riiccon = 0xaf; // clear the interrupt conditions and resume IIC operations

While (riiccon & 0x10) = 0); // query the interrupt status

While (riicstat & 1 );

Riiccon = 0x2f; // clear the interrupt flag. The response is forbidden because only one byte is read.

While (riiccon & 0x10) = 0); // query the interrupt status

* Data = riicds; // read data after the CPU usage es theinterrupt request, it shoshould // read the data from the iicds register.

Riicstat = 0x90; // stop reading

Riiccon = 0xaf; // clear the interrupt

Delay (1 );

}

//************************************** *

Void start (u32 slvaddr)

{

Riicds = slvaddr; // sets the address of the slave device.

Riicstat = 0xf0; // start sending

While (riiccon & 0x10) = 0); // query the Tx interruption status

While (riicstat & 1); // check the response ACK

}

//************************************** **

Void internal_write (u32 slvaddr)

{

Riicstat = 0xd0; // stop write

Riiccon = 0xaf;

Delay (1 );

// Enable one-page write

While (1)

{

Riicds = slvaddr;

Riicstat = 0xf0; // start sending s

While (riiccon & 0x10) = 0 );

Riiccon = 0xaf; // clear the interrupt

If (! (Riicstat & 0x1) // check the response ACK

Break;

}

}

//************************************** *

Write 51 consecutive 1:

 

 

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.