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_sleep.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), 00032 #endif 00033 _i2c(), _hz(100000) { 00034 // No lock needed in the constructor 00035 00036 // The init function also set the frequency to 100000 00037 i2c_init(&_i2c, sda, scl); 00038 00039 // Used to avoid unnecessary frequency updates 00040 _owner = this; 00041 } 00042 00043 void I2C::frequency(int hz) { 00044 lock(); 00045 _hz = hz; 00046 00047 // We want to update the frequency even if we are already the bus owners 00048 i2c_frequency(&_i2c, _hz); 00049 00050 // Updating the frequency of the bus we become the owners of it 00051 _owner = this; 00052 unlock(); 00053 } 00054 00055 void I2C::aquire() { 00056 lock(); 00057 if (_owner != this) { 00058 i2c_frequency(&_i2c, _hz); 00059 _owner = this; 00060 } 00061 unlock(); 00062 } 00063 00064 // write - Master Transmitter Mode 00065 int I2C::write(int address, const char* data, int length, bool repeated) { 00066 lock(); 00067 aquire(); 00068 00069 int stop = (repeated) ? 0 : 1; 00070 int written = i2c_write(&_i2c, address, data, length, stop); 00071 00072 unlock(); 00073 return length != written; 00074 } 00075 00076 int I2C::write(int data) { 00077 lock(); 00078 int ret = i2c_byte_write(&_i2c, data); 00079 unlock(); 00080 return ret; 00081 } 00082 00083 // read - Master Reciever Mode 00084 int I2C::read(int address, char* data, int length, bool repeated) { 00085 lock(); 00086 aquire(); 00087 00088 int stop = (repeated) ? 0 : 1; 00089 int read = i2c_read(&_i2c, address, data, length, stop); 00090 00091 unlock(); 00092 return length != read; 00093 } 00094 00095 int I2C::read(int ack) { 00096 lock(); 00097 int ret; 00098 if (ack) { 00099 ret = i2c_byte_read(&_i2c, 0); 00100 } else { 00101 ret = i2c_byte_read(&_i2c, 1); 00102 } 00103 unlock(); 00104 return ret; 00105 } 00106 00107 void I2C::start(void) { 00108 lock(); 00109 i2c_start(&_i2c); 00110 unlock(); 00111 } 00112 00113 void I2C::stop(void) { 00114 lock(); 00115 i2c_stop(&_i2c); 00116 unlock(); 00117 } 00118 00119 void I2C::lock() { 00120 _mutex->lock(); 00121 } 00122 00123 void I2C::unlock() { 00124 _mutex->unlock(); 00125 } 00126 00127 #if DEVICE_I2C_ASYNCH 00128 00129 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) 00130 { 00131 lock(); 00132 if (i2c_active(&_i2c)) { 00133 unlock(); 00134 return -1; // transaction ongoing 00135 } 00136 sleep_manager_lock_deep_sleep(); 00137 aquire(); 00138 00139 _callback = callback; 00140 int stop = (repeated) ? 0 : 1; 00141 _irq.callback(&I2C::irq_handler_asynch); 00142 i2c_transfer_asynch(&_i2c, (void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length, address, stop, _irq.entry(), event, _usage); 00143 unlock(); 00144 return 0; 00145 } 00146 00147 void I2C::abort_transfer(void) 00148 { 00149 lock(); 00150 i2c_abort_asynch(&_i2c); 00151 sleep_manager_unlock_deep_sleep(); 00152 unlock(); 00153 } 00154 00155 void I2C::irq_handler_asynch(void) 00156 { 00157 int event = i2c_irq_handler_asynch(&_i2c); 00158 if (_callback && event) { 00159 _callback.call(event); 00160 } 00161 if (event) { 00162 sleep_manager_unlock_deep_sleep(); 00163 } 00164 00165 } 00166 00167 00168 #endif 00169 00170 } // namespace mbed 00171 00172 #endif
Generated on Thu Jul 14 2022 14:36:16 by
