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