fix for mbed lib issue 3 (i2c problem) see also https://mbed.org/users/mbed_official/code/mbed/issues/3 affected implementations: LPC812, LPC11U24, LPC1768, LPC2368, LPC4088
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