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 SWM_Map SWM_I2C_SDA[] = { 00022 {7, 24}, 00023 }; 00024 00025 static const SWM_Map SWM_I2C_SCL[] = { 00026 {8, 0}, 00027 }; 00028 00029 static uint8_t repeated_start = 0; 00030 00031 #define I2C_DAT(x) (x->i2c->MSTDAT) 00032 #define I2C_STAT(x) ((x->i2c->STAT >> 1) & (0x07)) 00033 00034 static inline int i2c_status(i2c_t *obj) { 00035 return I2C_STAT(obj); 00036 } 00037 00038 // Wait until the Serial Interrupt (SI) is set 00039 static int i2c_wait_SI(i2c_t *obj) { 00040 int timeout = 0; 00041 while (!(obj->i2c->STAT & (1 << 0))) { 00042 timeout++; 00043 if (timeout > 100000) return -1; 00044 } 00045 return 0; 00046 } 00047 00048 static inline void i2c_interface_enable(i2c_t *obj) { 00049 obj->i2c->CFG |= (1 << 0); 00050 } 00051 00052 static inline void i2c_power_enable(i2c_t *obj) { 00053 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); 00054 LPC_SYSCON->PRESETCTRL &= ~(0x1<<6); 00055 LPC_SYSCON->PRESETCTRL |= (0x1<<6); 00056 } 00057 00058 void i2c_init(i2c_t *obj, PinName sda, PinName scl) { 00059 obj->i2c = (LPC_I2C_TypeDef *)LPC_I2C; 00060 00061 const SWM_Map *swm; 00062 uint32_t regVal; 00063 00064 swm = &SWM_I2C_SDA[0]; 00065 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); 00066 LPC_SWM->PINASSIGN[swm->n] = regVal | (sda << swm->offset); 00067 00068 swm = &SWM_I2C_SCL[0]; 00069 regVal = LPC_SWM->PINASSIGN[swm->n] & ~(0xFF << swm->offset); 00070 LPC_SWM->PINASSIGN[swm->n] = regVal | (scl << swm->offset); 00071 00072 // enable power 00073 i2c_power_enable(obj); 00074 // set default frequency at 100k 00075 i2c_frequency(obj, 100000); 00076 i2c_interface_enable(obj); 00077 } 00078 00079 inline int i2c_start(i2c_t *obj) { 00080 int status = 0; 00081 if (repeated_start) { 00082 obj->i2c->MSTCTL = (1 << 1) | (1 << 0); 00083 repeated_start = 0; 00084 } else { 00085 obj->i2c->MSTCTL = (1 << 1); 00086 } 00087 return status; 00088 } 00089 00090 inline int i2c_stop(i2c_t *obj) { 00091 obj->i2c->MSTCTL = (1 << 2) | (1 << 0); 00092 while ((obj->i2c->STAT & ((1 << 0) | (7 << 1))) != ((1 << 0) | (0 << 1))){ 00093 timeout++; 00094 if(timeout > 10000) return -1; 00095 } 00096 return 0; 00097 } 00098 00099 00100 static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { 00101 // write the data 00102 I2C_DAT(obj) = value; 00103 00104 if (!addr) 00105 obj->i2c->MSTCTL = (1 << 0); 00106 00107 // wait and return status 00108 i2c_wait_SI(obj); 00109 return i2c_status(obj); 00110 } 00111 00112 static inline int i2c_do_read(i2c_t *obj, int last) { 00113 // wait for it to arrive 00114 i2c_wait_SI(obj); 00115 if (!last) 00116 obj->i2c->MSTCTL = (1 << 0); 00117 00118 // return the data 00119 return (I2C_DAT(obj) & 0xFF); 00120 } 00121 00122 void i2c_frequency(i2c_t *obj, int hz) { 00123 // No peripheral clock divider on the M0 00124 uint32_t PCLK = SystemCoreClock; 00125 00126 uint32_t clkdiv = PCLK / (hz * 4) - 1; 00127 00128 obj->i2c->DIV = clkdiv; 00129 obj->i2c->MSTTIME = 0; 00130 } 00131 00132 // The I2C does a read or a write as a whole operation 00133 // There are two types of error conditions it can encounter 00134 // 1) it can not obtain the bus 00135 // 2) it gets error responses at part of the transmission 00136 // 00137 // We tackle them as follows: 00138 // 1) we retry until we get the bus. we could have a "timeout" if we can not get it 00139 // which basically turns it in to a 2) 00140 // 2) on error, we use the standard error mechanisms to report/debug 00141 // 00142 // Therefore an I2C transaction should always complete. If it doesn't it is usually 00143 // because something is setup wrong (e.g. wiring), and we don't need to programatically 00144 // check for that 00145 00146 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { 00147 int count, status; 00148 00149 i2c_start(obj); 00150 00151 status = i2c_do_write(obj, (address | 0x01), 1); 00152 if (status != 0x01) { 00153 i2c_stop(obj); 00154 return status; 00155 } 00156 00157 // Read in all except last byte 00158 for (count = 0; count < (length - 1); count++) { 00159 int value = i2c_do_read(obj, 0); 00160 status = i2c_status(obj); 00161 if (status != 0x00) { 00162 i2c_stop(obj); 00163 return status; 00164 } 00165 data[count] = (char) value; 00166 } 00167 00168 // read in last byte 00169 int value = i2c_do_read(obj, 1); 00170 status = i2c_status(obj); 00171 if (status != 0x01) { 00172 i2c_stop(obj); 00173 return status; 00174 } 00175 00176 data[count] = (char) value; 00177 00178 // If not repeated start, send stop. 00179 if (stop) { 00180 i2c_stop(obj); 00181 } else { 00182 repeated_start = 1; 00183 } 00184 00185 return 0; 00186 } 00187 00188 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { 00189 int i, status; 00190 00191 i2c_start(obj); 00192 00193 status = i2c_do_write(obj, (address & 0xFE), 1); 00194 if (status != 0x02) { 00195 i2c_stop(obj); 00196 return status; 00197 } 00198 00199 for (i=0; i<length; i++) { 00200 status = i2c_do_write(obj, data[i], 0); 00201 if (status != 0x02) { 00202 i2c_stop(obj); 00203 return status; 00204 } 00205 } 00206 00207 // If not repeated start, send stop. 00208 if (stop) { 00209 i2c_stop(obj); 00210 } else { 00211 repeated_start = 1; 00212 } 00213 00214 return 0; 00215 } 00216 00217 void i2c_reset(i2c_t *obj) { 00218 i2c_stop(obj); 00219 } 00220 00221 int i2c_byte_read(i2c_t *obj, int last) { 00222 return (i2c_do_read(obj, last) & 0xFF); 00223 } 00224 00225 int i2c_byte_write(i2c_t *obj, int data) { 00226 int ack; 00227 int status = i2c_do_write(obj, (data & 0xFF), 0); 00228 00229 switch(status) { 00230 case 2: 00231 ack = 1; 00232 break; 00233 default: 00234 ack = 0; 00235 break; 00236 } 00237 00238 return ack; 00239 }
Generated on Tue Jul 12 2022 13:47:01 by 1.7.2