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 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { 00205 int count, status; 00206 00207 status = i2c_start(obj); 00208 00209 if ((status != 0x10) && (status != 0x08)) { 00210 i2c_stop(obj); 00211 return status; 00212 } 00213 00214 status = i2c_do_write(obj, (address | 0x01), 1); 00215 if (status != 0x40) { 00216 i2c_stop(obj); 00217 return status; 00218 } 00219 00220 // Read in all except last byte 00221 for (count = 0; count < (length - 1); count++) { 00222 int value = i2c_do_read(obj, 0); 00223 status = i2c_status(obj); 00224 if (status != 0x50) { 00225 i2c_stop(obj); 00226 return status; 00227 } 00228 data[count] = (char) value; 00229 } 00230 00231 // read in last byte 00232 int value = i2c_do_read(obj, 1); 00233 status = i2c_status(obj); 00234 if (status != 0x58) { 00235 i2c_stop(obj); 00236 return status; 00237 } 00238 00239 data[count] = (char) value; 00240 00241 // If not repeated start, send stop. 00242 if (stop) { 00243 i2c_stop(obj); 00244 } 00245 00246 return 0; 00247 } 00248 00249 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { 00250 int i, status; 00251 00252 status = i2c_start(obj); 00253 00254 if ((status != 0x10) && (status != 0x08)) { 00255 i2c_stop(obj); 00256 return status; 00257 } 00258 00259 status = i2c_do_write(obj, (address & 0xFE), 1); 00260 if (status != 0x18) { 00261 i2c_stop(obj); 00262 return status; 00263 } 00264 00265 for (i=0; i<length; i++) { 00266 status = i2c_do_write(obj, data[i], 0); 00267 if (status != 0x28) { 00268 i2c_stop(obj); 00269 return status; 00270 } 00271 } 00272 00273 // clearing the serial interrupt here might cause an unintended rewrite of the last byte 00274 // see also issue report https://mbed.org/users/mbed_official/code/mbed/issues/1 00275 // i2c_clear_SI(obj); 00276 00277 // If not repeated start, send stop. 00278 if (stop) { 00279 i2c_stop(obj); 00280 } 00281 00282 return 0; 00283 } 00284 00285 void i2c_reset(i2c_t *obj) { 00286 i2c_stop(obj); 00287 } 00288 00289 int i2c_byte_read(i2c_t *obj, int last) { 00290 return (i2c_do_read(obj, last) & 0xFF); 00291 } 00292 00293 int i2c_byte_write(i2c_t *obj, int data) { 00294 int ack; 00295 int status = i2c_do_write(obj, (data & 0xFF), 0); 00296 00297 switch(status) { 00298 case 0x18: case 0x28: // Master transmit ACKs 00299 ack = 1; 00300 break; 00301 00302 case 0x40: // Master receive address transmitted ACK 00303 ack = 1; 00304 break; 00305 00306 case 0xB8: // Slave transmit ACK 00307 ack = 1; 00308 break; 00309 00310 default: 00311 ack = 0; 00312 break; 00313 } 00314 00315 return ack; 00316 } 00317 00318 void i2c_slave_mode(i2c_t *obj, int enable_slave) { 00319 if (enable_slave != 0) { 00320 i2c_conclr(obj, 1, 1, 1, 0); 00321 i2c_conset(obj, 0, 0, 0, 1); 00322 } else { 00323 i2c_conclr(obj, 1, 1, 1, 1); 00324 } 00325 } 00326 00327 int i2c_slave_receive(i2c_t *obj) { 00328 int status; 00329 int retval; 00330 00331 status = i2c_status(obj); 00332 switch(status) { 00333 case 0x60: retval = 3; break; 00334 case 0x70: retval = 2; break; 00335 case 0xA8: retval = 1; break; 00336 default : retval = 0; break; 00337 } 00338 00339 return(retval); 00340 } 00341 00342 int i2c_slave_read(i2c_t *obj, char *data, int length) { 00343 int count = 0; 00344 int status; 00345 00346 do { 00347 i2c_clear_SI(obj); 00348 i2c_wait_SI(obj); 00349 status = i2c_status(obj); 00350 if((status == 0x80) || (status == 0x90)) { 00351 data[count] = I2C_DAT(obj) & 0xFF; 00352 } 00353 count++; 00354 } while (((status == 0x80) || (status == 0x90) || 00355 (status == 0x060) || (status == 0x70)) && (count < length)); 00356 00357 if(status != 0xA0) { 00358 i2c_stop(obj); 00359 } 00360 00361 i2c_clear_SI(obj); 00362 00363 return (count - 1); 00364 } 00365 00366 int i2c_slave_write(i2c_t *obj, const char *data, int length) { 00367 int count = 0; 00368 int status; 00369 00370 if(length <= 0) { 00371 return(0); 00372 } 00373 00374 do { 00375 status = i2c_do_write(obj, data[count], 0); 00376 count++; 00377 } while ((count < length) && (status == 0xB8)); 00378 00379 if((status != 0xC0) && (status != 0xC8)) { 00380 i2c_stop(obj); 00381 } 00382 00383 i2c_clear_SI(obj); 00384 00385 return(count); 00386 } 00387 00388 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { 00389 uint32_t addr; 00390 00391 if ((idx >= 0) && (idx <= 3)) { 00392 addr = ((uint32_t)obj->i2c) + I2C_addr_offset[0][idx]; 00393 *((uint32_t *) addr) = address & 0xFF; 00394 } 00395 }
Generated on Tue Jul 12 2022 13:47:01 by
1.7.2
