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.
myi2c_api.c
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2013 Nordic Semiconductor 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 "mbed_assert.h" 00017 #include "myi2c_api.h" 00018 #include "cmsis.h" 00019 #include "pinmap.h" 00020 00021 static const PinMap PinMap_I2C_SDA[] = { 00022 {p22, I2C_0, 1}, 00023 {p13, I2C_1, 2}, 00024 {NC, NC, 0} 00025 }; 00026 00027 static const PinMap PinMap_I2C_SCL[] = { 00028 {p21, I2C_0, 1}, 00029 {p15, I2C_1, 2}, 00030 {NC, NC, 0} 00031 }; 00032 00033 uint8_t addrSet = 0; 00034 00035 void i2c_interface_enable(i2c_t *obj) 00036 { 00037 obj->i2c->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos); 00038 } 00039 00040 void twi_master_init(i2c_t *obj, PinName sda, PinName scl, int frequency) 00041 { 00042 NRF_GPIO->PIN_CNF[scl] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | 00043 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | 00044 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | 00045 (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | 00046 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)); 00047 00048 NRF_GPIO->PIN_CNF[sda] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | 00049 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | 00050 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | 00051 (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | 00052 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)); 00053 00054 obj->i2c->PSELSCL = scl; 00055 obj->i2c->PSELSDA = sda; 00056 // set default frequency at 100k 00057 i2c_frequency(obj, frequency); 00058 i2c_interface_enable(obj); 00059 } 00060 00061 void i2c_init(i2c_t *obj, PinName sda, PinName scl) 00062 { 00063 // determine the SPI to use 00064 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); 00065 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); 00066 I2CName i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl); 00067 obj->i2c = (NRF_TWI_Type *)i2c; 00068 00069 MBED_ASSERT((int)obj->i2c != NC); 00070 00071 obj->scl = scl; 00072 obj->sda = sda; 00073 obj->i2c->EVENTS_ERROR = 0; 00074 obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; 00075 obj->i2c->POWER = 0; 00076 00077 for (int i = 0; i<100; i++) { 00078 } 00079 00080 obj->i2c->POWER = 1; 00081 twi_master_init(obj, sda, scl, 100000); 00082 } 00083 00084 void i2c_reset(i2c_t *obj) 00085 { 00086 obj->i2c->EVENTS_ERROR = 0; 00087 obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; 00088 obj->i2c->POWER = 0; 00089 for (int i = 0; i<100; i++) { 00090 } 00091 00092 obj->i2c->POWER = 1; 00093 twi_master_init(obj, obj->sda, obj->scl, obj->freq); 00094 } 00095 00096 int i2c_start(i2c_t *obj) 00097 { 00098 int status = 0; 00099 i2c_reset(obj); 00100 addrSet = 0; 00101 return status; 00102 } 00103 00104 int i2c_stop(i2c_t *obj) 00105 { 00106 int timeOut = 100000; 00107 obj->i2c->EVENTS_STOPPED = 0; 00108 // write the stop bit 00109 obj->i2c->TASKS_STOP = 1; 00110 while (!obj->i2c->EVENTS_STOPPED) { 00111 timeOut--; 00112 if (timeOut<0) { 00113 return 1; 00114 } 00115 } 00116 addrSet = 0; 00117 i2c_reset(obj); 00118 return 0; 00119 } 00120 00121 int i2c_do_write(i2c_t *obj, int value) 00122 { 00123 int timeOut = 100000; 00124 obj->i2c->TXD = value; 00125 while (!obj->i2c->EVENTS_TXDSENT) { 00126 timeOut--; 00127 if (timeOut<0) { 00128 return 1; 00129 } 00130 } 00131 obj->i2c->EVENTS_TXDSENT = 0; 00132 return 0; 00133 } 00134 00135 int i2c_do_read(i2c_t *obj, char *data, int last) 00136 { 00137 int timeOut = 100000; 00138 00139 if (last) { 00140 obj->i2c->TASKS_STOP = 1; 00141 } 00142 while (!obj->i2c->EVENTS_RXDREADY) { 00143 timeOut--; 00144 if (timeOut<0) { 00145 return 1; 00146 } 00147 } 00148 obj->i2c->EVENTS_RXDREADY = 0; 00149 00150 *data = obj->i2c->RXD; 00151 00152 for (int i = 0; i<320; i++) { 00153 } 00154 00155 obj->i2c->TASKS_RESUME = 1; 00156 00157 return 0; 00158 } 00159 00160 void i2c_frequency(i2c_t *obj, int hz) 00161 { 00162 if (hz<250000) { 00163 obj->freq = 100000; 00164 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos); 00165 } else if (hz<400000) { 00166 obj->freq = 250000; 00167 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K250 << TWI_FREQUENCY_FREQUENCY_Pos); 00168 } else { 00169 obj->freq = 400000; 00170 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos); 00171 } 00172 } 00173 00174 int checkError(i2c_t *obj) 00175 { 00176 if (obj->i2c->EVENTS_ERROR == 1) { 00177 if (obj->i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) { 00178 obj->i2c->EVENTS_ERROR = 0; 00179 obj->i2c->TASKS_STOP = 1; 00180 return I2C_ERROR_BUS_BUSY; 00181 } 00182 00183 obj->i2c->EVENTS_ERROR = 0; 00184 obj->i2c->TASKS_STOP = 1; 00185 return I2C_ERROR_NO_SLAVE; 00186 } 00187 return 0; 00188 } 00189 00190 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) 00191 { 00192 int status, count, errorResult; 00193 obj->i2c->ADDRESS = (address >> 1); 00194 obj->i2c->SHORTS = 0; 00195 obj->i2c->EVENTS_RXDREADY = 0; 00196 obj->i2c->TASKS_STARTRX = 1; 00197 00198 // Read in all except last byte 00199 for (count = 0; count < (length - 1); count++) { 00200 status = i2c_do_read(obj, &data[count], 0); 00201 if (status) { 00202 errorResult = checkError(obj); 00203 i2c_reset(obj); 00204 if (errorResult<0) { 00205 return errorResult; 00206 } 00207 return count; 00208 } 00209 } 00210 00211 // read in last byte 00212 status = i2c_do_read(obj, &data[length - 1], 1); 00213 if (status) { 00214 i2c_reset(obj); 00215 return length - 1; 00216 } 00217 // If not repeated start, send stop. 00218 if (stop) { 00219 while (!obj->i2c->EVENTS_STOPPED) { 00220 } 00221 obj->i2c->EVENTS_STOPPED = 0; 00222 } 00223 return length; 00224 } 00225 00226 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) 00227 { 00228 int status, errorResult; 00229 obj->i2c->ADDRESS = (address >> 1); 00230 obj->i2c->SHORTS = 0; 00231 obj->i2c->TASKS_STARTTX = 1; 00232 00233 for (int i = 0; i<length; i++) { 00234 status = i2c_do_write(obj, data[i]); 00235 if (status) { 00236 i2c_reset(obj); 00237 errorResult = checkError(obj); 00238 if (errorResult<0) { 00239 return errorResult; 00240 } 00241 return i; 00242 } 00243 } 00244 00245 // If not repeated start, send stop. 00246 if (stop) { 00247 if (i2c_stop(obj)) { 00248 return I2C_ERROR_NO_SLAVE; 00249 } 00250 } 00251 return length; 00252 } 00253 00254 int i2c_byte_read(i2c_t *obj, int last) 00255 { 00256 char data; 00257 int status; 00258 00259 status = i2c_do_read(obj, &data, last); 00260 if (status) { 00261 i2c_reset(obj); 00262 } 00263 return data; 00264 } 00265 00266 int i2c_byte_write(i2c_t *obj, int data) 00267 { 00268 int status = 0; 00269 if (!addrSet) { 00270 addrSet = 1; 00271 obj->i2c->ADDRESS = (data >> 1); 00272 00273 if (data & 1) { 00274 obj->i2c->EVENTS_RXDREADY = 0; 00275 obj->i2c->TASKS_STARTRX = 1; 00276 } else { 00277 obj->i2c->TASKS_STARTTX = 1; 00278 } 00279 } else { 00280 status = i2c_do_write(obj, data); 00281 if (status) { 00282 i2c_reset(obj); 00283 } 00284 } 00285 return (1 - status); 00286 }
Generated on Tue Jul 12 2022 20:04:43 by
