Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
i2c_api.c
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "i2c_api.h" 00017 #include "cmsis.h" 00018 #include "pinmap.h" 00019 #include "error.h" 00020 00021 static const PinMap PinMap_I2C_SDA[] = { 00022 {P0_0 , I2C_1, 3}, 00023 {P0_10, I2C_2, 2}, 00024 {P0_19, I2C_1, 3}, 00025 {P0_27, I2C_0, 1}, 00026 {P1_15, I2C_2, 3}, 00027 {P1_30, I2C_0, 4}, 00028 {P2_14, I2C_1, 2}, 00029 {P2_30, I2C_2, 2}, 00030 {P4_20, I2C_2, 4}, 00031 {P5_2, I2C_0, 5}, 00032 {NC , NC , 0} 00033 }; 00034 00035 static const PinMap PinMap_I2C_SCL[] = { 00036 {P0_1 , I2C_1, 3}, 00037 {P0_11, I2C_2, 2}, 00038 {P0_20, I2C_1, 3}, 00039 {P0_28, I2C_0, 1}, 00040 {P1_31, I2C_0, 4}, 00041 {P2_15, I2C_1, 2}, 00042 {P2_31, I2C_2, 2}, 00043 {P4_21, I2C_2, 2}, 00044 {P4_29, I2C_2, 4}, 00045 {P5_3, I2C_0, 5}, 00046 {NC , NC, 0} 00047 }; 00048 00049 #define I2C_CONSET(x) (x->i2c->CONSET) 00050 #define I2C_CONCLR(x) (x->i2c->CONCLR) 00051 #define I2C_STAT(x) (x->i2c->STAT) 00052 #define I2C_DAT(x) (x->i2c->DAT) 00053 #define I2C_SCLL(x, val) (x->i2c->SCLL = val) 00054 #define I2C_SCLH(x, val) (x->i2c->SCLH = val) 00055 00056 static const uint32_t I2C_addr_offset[2][4] = { 00057 {0x0C, 0x20, 0x24, 0x28}, 00058 {0x30, 0x34, 0x38, 0x3C} 00059 }; 00060 00061 static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { 00062 I2C_CONCLR(obj) = (start << 5) 00063 | (stop << 4) 00064 | (interrupt << 3) 00065 | (acknowledge << 2); 00066 } 00067 00068 static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { 00069 I2C_CONSET(obj) = (start << 5) 00070 | (stop << 4) 00071 | (interrupt << 3) 00072 | (acknowledge << 2); 00073 } 00074 00075 // Clear the Serial Interrupt (SI) 00076 static inline void i2c_clear_SI(i2c_t *obj) { 00077 i2c_conclr(obj, 0, 0, 1, 0); 00078 } 00079 00080 static inline int i2c_status(i2c_t *obj) { 00081 return I2C_STAT(obj); 00082 } 00083 00084 // Wait until the Serial Interrupt (SI) is set 00085 static int i2c_wait_SI(i2c_t *obj) { 00086 int timeout = 0; 00087 while (!(I2C_CONSET(obj) & (1 << 3))) { 00088 timeout++; 00089 if (timeout > 100000) return -1; 00090 } 00091 return 0; 00092 } 00093 00094 static inline void i2c_interface_enable(i2c_t *obj) { 00095 I2C_CONSET(obj) = 0x40; 00096 } 00097 00098 static inline void i2c_power_enable(i2c_t *obj) { 00099 switch ((int)obj->i2c) { 00100 case I2C_0: LPC_SC->PCONP |= 1 << 7; break; 00101 case I2C_1: LPC_SC->PCONP |= 1 << 19; break; 00102 case I2C_2: LPC_SC->PCONP |= 1 << 26; break; 00103 } 00104 } 00105 00106 void i2c_init(i2c_t *obj, PinName sda, PinName scl) { 00107 // determine the SPI to use 00108 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); 00109 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); 00110 obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); 00111 if ((int)obj->i2c == NC) { 00112 error("I2C pin mapping failed"); 00113 } 00114 00115 // enable power 00116 i2c_power_enable(obj); 00117 00118 // set default frequency at 100k 00119 i2c_frequency(obj, 100000); 00120 i2c_conclr(obj, 1, 1, 1, 1); 00121 i2c_interface_enable(obj); 00122 00123 pinmap_pinout(sda, PinMap_I2C_SDA); 00124 pinmap_pinout(scl, PinMap_I2C_SCL); 00125 } 00126 00127 inline int i2c_start(i2c_t *obj) { 00128 int status = 0; 00129 // 8.1 Before master mode can be entered, I2CON must be initialised to: 00130 // - I2EN STA STO SI AA - - 00131 // - 1 0 0 0 x - - 00132 // if AA = 0, it can't enter slave mode 00133 i2c_conclr(obj, 1, 1, 1, 1); 00134 00135 // The master mode may now be entered by setting the STA bit 00136 // this will generate a start condition when the bus becomes free 00137 i2c_conset(obj, 1, 0, 0, 1); 00138 00139 i2c_wait_SI(obj); 00140 status = i2c_status(obj); 00141 00142 // Clear start bit now transmitted, and interrupt bit 00143 i2c_conclr(obj, 1, 0, 0, 0); 00144 return status; 00145 } 00146 00147 inline int i2c_stop(i2c_t *obj) { 00148 // write the stop bit 00149 i2c_conset(obj, 0, 1, 0, 0); 00150 i2c_clear_SI(obj); 00151 00152 // wait for STO bit to reset 00153 int timeout = 0; 00154 while(I2C_CONSET(obj) & (1 << 4)){ 00155 timeout++; 00156 if(timeout > 10000) return -1; 00157 } 00158 return 0; 00159 } 00160 00161 00162 static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { 00163 // write the data 00164 I2C_DAT(obj) = value; 00165 00166 // clear SI to init a send 00167 i2c_clear_SI(obj); 00168 00169 // wait and return status 00170 i2c_wait_SI(obj); 00171 return i2c_status(obj); 00172 } 00173 00174 static inline int i2c_do_read(i2c_t *obj, int last) { 00175 // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) 00176 if(last) { 00177 i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK 00178 } else { 00179 i2c_conset(obj, 0, 0, 0, 1); // send a ACK 00180 } 00181 00182 // accept byte 00183 i2c_clear_SI(obj); 00184 00185 // wait for it to arrive 00186 i2c_wait_SI(obj); 00187 00188 // return the data 00189 return (I2C_DAT(obj) & 0xFF); 00190 } 00191 00192 void i2c_frequency(i2c_t *obj, int hz) { 00193 uint32_t PCLK = PeripheralClock ; 00194 uint32_t pulse = PCLK / (hz * 2); 00195 00196 // I2C Rate 00197 I2C_SCLL(obj, pulse); 00198 I2C_SCLH(obj, pulse); 00199 } 00200 00201 // The I2C does a read or a write as a whole operation 00202 // There are two types of error conditions it can encounter 00203 // 1) it can not obtain the bus 00204 // 2) it gets error responses at part of the transmission 00205 // 00206 // We tackle them as follows: 00207 // 1) we retry until we get the bus. we could have a "timeout" if we can not get it 00208 // which basically turns it in to a 2) 00209 // 2) on error, we use the standard error mechanisms to report/debug 00210 // 00211 // Therefore an I2C transaction should always complete. If it doesn't it is usually 00212 // because something is setup wrong (e.g. wiring), and we don't need to programatically 00213 // check for that 00214 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { 00215 int count, status; 00216 00217 status = i2c_start(obj); 00218 00219 if ((status != 0x10) && (status != 0x08)) { 00220 i2c_stop(obj); 00221 return status; 00222 } 00223 00224 status = i2c_do_write(obj, (address | 0x01), 1); 00225 if (status != 0x40) { 00226 i2c_stop(obj); 00227 return status; 00228 } 00229 00230 // Read in all except last byte 00231 for (count = 0; count < (length - 1); count++) { 00232 int value = i2c_do_read(obj, 0); 00233 status = i2c_status(obj); 00234 if (status != 0x50) { 00235 i2c_stop(obj); 00236 return status; 00237 } 00238 data[count] = (char) value; 00239 } 00240 00241 // read in last byte 00242 int value = i2c_do_read(obj, 1); 00243 status = i2c_status(obj); 00244 if (status != 0x58) { 00245 i2c_stop(obj); 00246 return status; 00247 } 00248 00249 data[count] = (char) value; 00250 00251 // If not repeated start, send stop. 00252 if (stop) { 00253 i2c_stop(obj); 00254 } 00255 00256 return 0; 00257 } 00258 00259 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { 00260 int i, status; 00261 00262 status = i2c_start(obj); 00263 00264 if ((status != 0x10) && (status != 0x08)) { 00265 i2c_stop(obj); 00266 return status; 00267 } 00268 00269 status = i2c_do_write(obj, (address & 0xFE), 1); 00270 if (status != 0x18) { 00271 i2c_stop(obj); 00272 return status; 00273 } 00274 00275 for (i=0; i<length; i++) { 00276 status = i2c_do_write(obj, data[i], 0); 00277 if (status != 0x28) { 00278 i2c_stop(obj); 00279 return status; 00280 } 00281 } 00282 00283 // clearing the serial interrupt here might cause an unintended rewrite of the last byte 00284 // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 00285 // i2c_clear_SI(obj); 00286 00287 // If not repeated start, send stop. 00288 if (stop) { 00289 i2c_stop(obj); 00290 } 00291 00292 return 0; 00293 } 00294 00295 void i2c_reset(i2c_t *obj) { 00296 i2c_stop(obj); 00297 } 00298 00299 int i2c_byte_read(i2c_t *obj, int last) { 00300 return (i2c_do_read(obj, last) & 0xFF); 00301 } 00302 00303 int i2c_byte_write(i2c_t *obj, int data) { 00304 int ack; 00305 int status = i2c_do_write(obj, (data & 0xFF), 0); 00306 00307 switch(status) { 00308 case 0x18: case 0x28: // Master transmit ACKs 00309 ack = 1; 00310 break; 00311 00312 case 0x40: // Master receive address transmitted ACK 00313 ack = 1; 00314 break; 00315 00316 case 0xB8: // Slave transmit ACK 00317 ack = 1; 00318 break; 00319 00320 default: 00321 ack = 0; 00322 break; 00323 } 00324 00325 return ack; 00326 } 00327 00328 void i2c_slave_mode(i2c_t *obj, int enable_slave) { 00329 if (enable_slave != 0) { 00330 i2c_conclr(obj, 1, 1, 1, 0); 00331 i2c_conset(obj, 0, 0, 0, 1); 00332 } else { 00333 i2c_conclr(obj, 1, 1, 1, 1); 00334 } 00335 } 00336 00337 int i2c_slave_receive(i2c_t *obj) { 00338 int status; 00339 int retval; 00340 00341 status = i2c_status(obj); 00342 switch(status) { 00343 case 0x60: retval = 3; break; 00344 case 0x70: retval = 2; break; 00345 case 0xA8: retval = 1; break; 00346 default : retval = 0; break; 00347 } 00348 00349 return(retval); 00350 } 00351 00352 int i2c_slave_read(i2c_t *obj, char *data, int length) { 00353 int count = 0; 00354 int status; 00355 00356 do { 00357 i2c_clear_SI(obj); 00358 i2c_wait_SI(obj); 00359 status = i2c_status(obj); 00360 if((status == 0x80) || (status == 0x90)) { 00361 data[count] = I2C_DAT(obj) & 0xFF; 00362 } 00363 count++; 00364 } while (((status == 0x80) || (status == 0x90) || 00365 (status == 0x060) || (status == 0x70)) && (count < length)); 00366 00367 if(status != 0xA0) { 00368 i2c_stop(obj); 00369 } 00370 00371 i2c_clear_SI(obj); 00372 00373 return (count - 1); 00374 } 00375 00376 int i2c_slave_write(i2c_t *obj, const char *data, int length) { 00377 int count = 0; 00378 int status; 00379 00380 if(length <= 0) { 00381 return(0); 00382 } 00383 00384 do { 00385 status = i2c_do_write(obj, data[count], 0); 00386 count++; 00387 } while ((count < length) && (status == 0xB8)); 00388 00389 if((status != 0xC0) && (status != 0xC8)) { 00390 i2c_stop(obj); 00391 } 00392 00393 i2c_clear_SI(obj); 00394 00395 return(count); 00396 } 00397 00398 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { 00399 uint32_t addr; 00400 00401 if ((idx >= 0) && (idx <= 3)) { 00402 addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; 00403 *((uint32_t *) addr) = address & 0xFF; 00404 addr = ((uint32_t)obj->i2c) + I2C_addr_offset[1][idx]; 00405 *((uint32_t *) addr) = mask & 0xFE; 00406 } 00407 }
Generated on Tue Jul 12 2022 13:47:01 by
1.7.2
