Linux I2C bare metal driver analysis, i2c bare metal

Source: Internet
Author: User

Linux I2C bare metal driver resolution (to), i2c bare metal
1. hardware features

1.1 Overview

The I2C bus is a two-line serial bus developed by Philips. The two cables are the clock line (SCL) and two-way data line (SDA ). The I2C bus only requires two wires, so it consumes less space on the circuit board. The problem is that the bandwidth is narrow. The maximum transmission rate of I2C in standard mode is kb/s, and that of I2C in fast mode is kb/s. It is half duplex.

In embedded systems, I2C is widely used. Most controllers integrate I2C bus and are generally used for communication with RTC, EEPROM, smart battery circuits, sensors, LCD and other similar devices.

 

1.2 I2C bus transmission time series

 

1.3 I2C bus Signal Status

1. Idle status: Both SDA and SCL are high;

2. Start condition (S): In high-power mode, SDA changes from high level to low level to start data transmission;

3. End condition (P): In high-power mode, SDA changes from low-level to high-level and ends data transmission;

4. Data is valid: SDA remains stable and data is valid during the high-level period of the SCL. SDA changes can only occur during the low-level period of the SCL;

5. ACK signal: An ACK signal is generated for each byte of data received by the receiver during data transmission. A specific low-level pulse is sent to the receiver, indicating that the data has been received.

 

1.4 slave device address


The I2C bus uses a 7-bit address from the device, and the last one is the read/write control bit. Is the schematic diagram of the eeprom. We can calculate its address as 0x50.

 

1.5 I2C read/write mode

Multi-byte write Sequence

Multi-byte read Sequence

For more information, see datasheet.

Appendix: ok6410 bare metal I2C code.

1 # define INTPND (* (volatile unsigned long *) 0x4a000010) 2 # define SRCPND (* (volatile unsigned long *) 0x4a000000) 3 # define INTMSK (* (volatile unsigned long *) 0x4a000008) 4 # define GPECON (* (volatile unsigned long *) 0x56000040) 5 # define GPEUP (* (volatile unsigned long *) 0x56000048) 6 7 # define IICCON (* (volatile unsigned char *) 0x54000000) 8 # define IICSTAT (* (volatile unsigned char *) 0x54000004) 9 # defi Ne IICDS (* (volatile unsigned char *) 0x5400000C) 10 11 # define SLAVE_WRITE_ADD 0xa0/* when writing data; Direction bit (0th bits) 0 */12 # define SLAVE_READ_ADD 0xa1/* when reading data, the direction (0th bits) is 1 */13 14 15 void delay (int I) 16 {17 int j = 0; 18 while (I --) 19 {20 for (j = 0; j <100; j ++) 21 {22; 23} 24} 25} 26 27 28 void i2c_init () 29 {30 // 1.a initialization interrupt 31 INTPND |=( 1 <27 ); 32 SRCPND | = (1 <27); 33 INTMSK & = ~ (1 <27); 34 35 IICCON | = (1 <5); 36 37 // 1. B sets the scl clock 38 IICCON & = ~ (1 <6); 39 IICCON & = ~ (0xf <0); 40 IICCON | = (0x5 <0); 41 42 // 2. set IICSTAT 43 IICCON |=( 1 <4); 44 45 // 3. set the pin function 46 GPECON |=( 0x2 <28) | (0x2 <30); 47 GPEUP |=( 0x3 <14 ); 48 49 // 4. allow ACK 50 IICCON | = (1 <7); 51} 52 53 54 void write_byte (unsigned char xchar, unsigned char daddr) 55 {56/* when writing data, each time a data is sent, an ACK is received, resulting in an interruption 57 * the interruption is cleared after the data is written to the next sending */58 59 // 1. set the processor as the master device + sending mode 60 IICSTAT |=( 3 <6); 61 62 // 2. write the device address to the IICDS register. 63 IICDS = SLAVE_WRITE_ADD; 64 65 // clear interrupt 66 IICCON & = ~ (1 <4); 67 68 // 3. write 0xF0 write iicstat m/T Start 69 IICSTAT = 0xF0; 70 71 // 4. wait for ACK to generate 72 while (IICCON & (1 <4) = 0) 73 delay (100 ); 74 75 // 5.1 write the byte address to the IICDS register 76 IICDS = daddr; 77 78 79 // 5.2 clear the interrupt 80 IICCON & = ~ (1 <4); 81 82 // 5.3 wait for ACK to generate 83 while (IICCON & (1 <4) = 0) 84 delay (100 ); 85 86 // 6. write the byte data to be transmitted to IICDS register 87 IICDS = xchar; 88 89 // 7. clear interrupt 90 IICCON & = ~ (1 <4); 91 92 // 8. wait for ACk to generate 93 while (IICCON & (1 <4) = 0) 94 delay (100); 95 96 // 9. write 0xD0 to IICSTAT 97 IICSTAT = 0xD0; 98 99 // 10. clear interrupt 100 IICCON & = ~ (1 <4); 101 102 delay (100); 103} 104 void read_data (unsigned char * buf, unsigned char daddr, int length) /* combined with the eeprom manual */106 {107/* generates an interrupt for each received data */108 109 int j = 0; 110 unsigned char unusedata; 111 112/1. set the processor as the master device + sending mode 113 IICSTAT |=( 3 <6); 114 115 // 2. write the address from the device to the IICDS register 116 IICDS = SLAVE_WRITE_ADD; 117 118 // clear the interrupt 119 IICCON & = ~ (1 <4); 120 121 // 3. write 0xF0 write iicstat m/T-Start122 IICSTAT = 0xF0; 123 124 // 4. wait for ACK to generate 125 while (IICCON & (1 <4) = 0) 126 delay (100 ); 127 128 // 5.1 write the internal address of the eeprom 129 IICDS = daddr; 130 131 132 // 5.2 clear the interrupt 133 IICCON & = ~ (1 <4); 134 135/5.3 wait for ACK to generate 136 while (IICCON & (1 <4) = 0) 137 delay (100 ); 138 139/*************** eeprom code **************/140 /**** *********************************/141 /*** * 144 IICSTAT & = ~ (3 <6); 145 IICSTAT | = (2 <6); 146 147 148 // 2. the write operation is interrupted after the device address is successfully sent from the device address to the IICDS/* from the device address, so you need to clear the interrupt */149 IICDS = SLAVE_READ_ADD; 150 // clear the interrupt 151 IICCON & = ~ (1 <4); 152 153 154 // 3. write 0xB0 to IICSTAT and start receiving. Each time a data packet is received, an interruption occurs. 155 IICSTAT = 0xb0; 156 157 // 158 while waiting for interruption (IICCON & (1 <4 )) = 0) 159 delay (100); 160 161 # if 0 162/*** Write Device internal address ***/163 IICDS = daddr; 164 IICCON & = ~ (1 <4); 165 while (IICCON & (1 <4) = 0) 166 {167 delay (100 ); 168} 169 # endif 170 171 // *** the first 1st bytes received are discarded invalid! 172 unusedata = IICDS; 173 IICCON & = ~ (1 <4); 174 while (IICCON & (1 <4) = 0) 175 delay (100); 176 177 178 179 for (j = 0; j <length; j ++) 180 {181 if (j = (length-1) 182 {183 IICCON & = ~ (1 <7); 184} 185 186 // 5.1 retrieve data from IICDS 187 buf [j] = IICDS; 188 189/5.2 clear interrupt 190 IICCON & = ~ (1 <4); 191 192 // 4. wait 193 while (IICCON & (1 <4) = 0) 194 delay (100 ); 195} 196 197 198 // write 0x90 to IICSTAT199 IICSTAT = 0x90; 200 201 202 // clear interrupt 203 IICCON & = ~ (1 <4); 204} 205 void i2c_test () 206 {207 int I = 0; 208 unsigned char sbuf [209] = {0 }; 210 unsigned char dbuf [256] = {0}; 211 212 i2c_init (); 213 214 for (I = 0; I <256; I ++) 215 {216 sbuf [I] = I + 1; 217 dbuf [I] = 0; 218} 219 printf ("dbuf befor I2C read: \ r \ n "); 221 for (I = 0; I <256; I ++) 222 {223 if (I % 8 = 0) 224 printf ("\ r \ n "); /**/225 226 printf ("% d \ t", dbuf [I]);/* t-space */227} 228 229 for (I = 0; I <256; I ++) 230 write _ Byte (sbuf [I], I); 231 232 printf ("i2c reading, plese wait! \ N \ r "); 233 234 read_data (dbuf, 0,256); 235 236 printf (" dbuf after I2C read: \ r \ n "); 237 238 for (I = 0; I <256; I ++) 239 {240 if (I % 8 = 0) 241 printf ("\ r \ n "); 242 243 printf ("% d \ t", dbuf [I]); 244} 245}

 

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.