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