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.
I2C.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 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 "drivers/I2C.h" 00017 00018 #if DEVICE_I2C 00019 00020 #if DEVICE_I2C_ASYNCH 00021 #include "platform/mbed_power_mgmt.h" 00022 #endif 00023 00024 namespace mbed { 00025 00026 I2C *I2C::_owner = NULL; 00027 SingletonPtr<PlatformMutex> I2C::_mutex; 00028 00029 I2C::I2C(PinName sda, PinName scl) : 00030 #if DEVICE_I2C_ASYNCH 00031 _irq(this), _usage(DMA_USAGE_NEVER), _deep_sleep_locked(false), 00032 #endif 00033 _i2c(), _hz(100000) 00034 { 00035 // No lock needed in the constructor 00036 00037 // The init function also set the frequency to 100000 00038 i2c_init(&_i2c, sda, scl); 00039 00040 // Used to avoid unnecessary frequency updates 00041 _owner = this; 00042 } 00043 00044 void I2C::frequency(int hz) 00045 { 00046 lock(); 00047 _hz = hz; 00048 00049 // We want to update the frequency even if we are already the bus owners 00050 i2c_frequency(&_i2c, _hz); 00051 00052 // Updating the frequency of the bus we become the owners of it 00053 _owner = this; 00054 unlock(); 00055 } 00056 00057 void I2C::aquire() 00058 { 00059 lock(); 00060 if (_owner != this) { 00061 i2c_frequency(&_i2c, _hz); 00062 _owner = this; 00063 } 00064 unlock(); 00065 } 00066 00067 // write - Master Transmitter Mode 00068 int I2C::write(int address, const char *data, int length, bool repeated) 00069 { 00070 lock(); 00071 aquire(); 00072 00073 int stop = (repeated) ? 0 : 1; 00074 int written = i2c_write(&_i2c, address, data, length, stop); 00075 00076 unlock(); 00077 return length != written; 00078 } 00079 00080 int I2C::write(int data) 00081 { 00082 lock(); 00083 int ret = i2c_byte_write(&_i2c, data); 00084 unlock(); 00085 return ret; 00086 } 00087 00088 // read - Master Receiver Mode 00089 int I2C::read(int address, char *data, int length, bool repeated) 00090 { 00091 lock(); 00092 aquire(); 00093 00094 int stop = (repeated) ? 0 : 1; 00095 int read = i2c_read(&_i2c, address, data, length, stop); 00096 00097 unlock(); 00098 return length != read; 00099 } 00100 00101 int I2C::read(int ack) 00102 { 00103 lock(); 00104 int ret; 00105 if (ack) { 00106 ret = i2c_byte_read(&_i2c, 0); 00107 } else { 00108 ret = i2c_byte_read(&_i2c, 1); 00109 } 00110 unlock(); 00111 return ret; 00112 } 00113 00114 void I2C::start(void) 00115 { 00116 lock(); 00117 i2c_start(&_i2c); 00118 unlock(); 00119 } 00120 00121 void I2C::stop(void) 00122 { 00123 lock(); 00124 i2c_stop(&_i2c); 00125 unlock(); 00126 } 00127 00128 void I2C::lock() 00129 { 00130 _mutex->lock(); 00131 } 00132 00133 void I2C::unlock() 00134 { 00135 _mutex->unlock(); 00136 } 00137 00138 #if DEVICE_I2C_ASYNCH 00139 00140 int I2C::transfer(int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event, bool repeated) 00141 { 00142 lock(); 00143 if (i2c_active(&_i2c)) { 00144 unlock(); 00145 return -1; // transaction ongoing 00146 } 00147 lock_deep_sleep(); 00148 aquire(); 00149 00150 _callback = callback; 00151 int stop = (repeated) ? 0 : 1; 00152 _irq.callback(&I2C::irq_handler_asynch); 00153 i2c_transfer_asynch(&_i2c, (void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length, address, stop, _irq.entry(), event, _usage); 00154 unlock(); 00155 return 0; 00156 } 00157 00158 void I2C::abort_transfer(void) 00159 { 00160 lock(); 00161 i2c_abort_asynch(&_i2c); 00162 unlock_deep_sleep(); 00163 unlock(); 00164 } 00165 00166 void I2C::irq_handler_asynch(void) 00167 { 00168 int event = i2c_irq_handler_asynch(&_i2c); 00169 if (_callback && event) { 00170 _callback.call(event); 00171 } 00172 if (event) { 00173 unlock_deep_sleep(); 00174 } 00175 00176 } 00177 00178 void I2C::lock_deep_sleep() 00179 { 00180 if (_deep_sleep_locked == false) { 00181 sleep_manager_lock_deep_sleep(); 00182 _deep_sleep_locked = true; 00183 } 00184 } 00185 00186 void I2C::unlock_deep_sleep() 00187 { 00188 if (_deep_sleep_locked == true) { 00189 sleep_manager_unlock_deep_sleep(); 00190 _deep_sleep_locked = false; 00191 } 00192 } 00193 00194 #endif 00195 00196 } // namespace mbed 00197 00198 #endif
Generated on Tue Jul 12 2022 20:52:44 by
1.7.2