This fork captures the mbed lib v125 for ease of integration into older projects.

Fork of mbed-dev by mbed official

Committer:
apluscw
Date:
Fri Jul 20 21:24:42 2018 +0000
Revision:
187:92cbb9eec47b
Mbed library with source code from mbed lib v125. Posted to ease integration with some older projects.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
apluscw 187:92cbb9eec47b 1 /* mbed Microcontroller Library
apluscw 187:92cbb9eec47b 2 * Copyright (c) 2006-2015 ARM Limited
apluscw 187:92cbb9eec47b 3 *
apluscw 187:92cbb9eec47b 4 * Licensed under the Apache License, Version 2.0 (the "License");
apluscw 187:92cbb9eec47b 5 * you may not use this file except in compliance with the License.
apluscw 187:92cbb9eec47b 6 * You may obtain a copy of the License at
apluscw 187:92cbb9eec47b 7 *
apluscw 187:92cbb9eec47b 8 * http://www.apache.org/licenses/LICENSE-2.0
apluscw 187:92cbb9eec47b 9 *
apluscw 187:92cbb9eec47b 10 * Unless required by applicable law or agreed to in writing, software
apluscw 187:92cbb9eec47b 11 * distributed under the License is distributed on an "AS IS" BASIS,
apluscw 187:92cbb9eec47b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
apluscw 187:92cbb9eec47b 13 * See the License for the specific language governing permissions and
apluscw 187:92cbb9eec47b 14 * limitations under the License.
apluscw 187:92cbb9eec47b 15 */
apluscw 187:92cbb9eec47b 16 #include "I2C.h"
apluscw 187:92cbb9eec47b 17
apluscw 187:92cbb9eec47b 18 #if DEVICE_I2C
apluscw 187:92cbb9eec47b 19
apluscw 187:92cbb9eec47b 20 namespace mbed {
apluscw 187:92cbb9eec47b 21
apluscw 187:92cbb9eec47b 22 I2C *I2C::_owner = NULL;
apluscw 187:92cbb9eec47b 23 SingletonPtr<PlatformMutex> I2C::_mutex;
apluscw 187:92cbb9eec47b 24
apluscw 187:92cbb9eec47b 25 I2C::I2C(PinName sda, PinName scl) :
apluscw 187:92cbb9eec47b 26 #if DEVICE_I2C_ASYNCH
apluscw 187:92cbb9eec47b 27 _irq(this), _usage(DMA_USAGE_NEVER),
apluscw 187:92cbb9eec47b 28 #endif
apluscw 187:92cbb9eec47b 29 _i2c(), _hz(100000) {
apluscw 187:92cbb9eec47b 30 // No lock needed in the constructor
apluscw 187:92cbb9eec47b 31
apluscw 187:92cbb9eec47b 32 // The init function also set the frequency to 100000
apluscw 187:92cbb9eec47b 33 i2c_init(&_i2c, sda, scl);
apluscw 187:92cbb9eec47b 34
apluscw 187:92cbb9eec47b 35 // Used to avoid unnecessary frequency updates
apluscw 187:92cbb9eec47b 36 _owner = this;
apluscw 187:92cbb9eec47b 37 }
apluscw 187:92cbb9eec47b 38
apluscw 187:92cbb9eec47b 39 void I2C::frequency(int hz) {
apluscw 187:92cbb9eec47b 40 lock();
apluscw 187:92cbb9eec47b 41 _hz = hz;
apluscw 187:92cbb9eec47b 42
apluscw 187:92cbb9eec47b 43 // We want to update the frequency even if we are already the bus owners
apluscw 187:92cbb9eec47b 44 i2c_frequency(&_i2c, _hz);
apluscw 187:92cbb9eec47b 45
apluscw 187:92cbb9eec47b 46 // Updating the frequency of the bus we become the owners of it
apluscw 187:92cbb9eec47b 47 _owner = this;
apluscw 187:92cbb9eec47b 48 unlock();
apluscw 187:92cbb9eec47b 49 }
apluscw 187:92cbb9eec47b 50
apluscw 187:92cbb9eec47b 51 void I2C::aquire() {
apluscw 187:92cbb9eec47b 52 lock();
apluscw 187:92cbb9eec47b 53 if (_owner != this) {
apluscw 187:92cbb9eec47b 54 i2c_frequency(&_i2c, _hz);
apluscw 187:92cbb9eec47b 55 _owner = this;
apluscw 187:92cbb9eec47b 56 }
apluscw 187:92cbb9eec47b 57 unlock();
apluscw 187:92cbb9eec47b 58 }
apluscw 187:92cbb9eec47b 59
apluscw 187:92cbb9eec47b 60 // write - Master Transmitter Mode
apluscw 187:92cbb9eec47b 61 int I2C::write(int address, const char* data, int length, bool repeated) {
apluscw 187:92cbb9eec47b 62 lock();
apluscw 187:92cbb9eec47b 63 aquire();
apluscw 187:92cbb9eec47b 64
apluscw 187:92cbb9eec47b 65 int stop = (repeated) ? 0 : 1;
apluscw 187:92cbb9eec47b 66 int written = i2c_write(&_i2c, address, data, length, stop);
apluscw 187:92cbb9eec47b 67
apluscw 187:92cbb9eec47b 68 unlock();
apluscw 187:92cbb9eec47b 69 return length != written;
apluscw 187:92cbb9eec47b 70 }
apluscw 187:92cbb9eec47b 71
apluscw 187:92cbb9eec47b 72 int I2C::write(int data) {
apluscw 187:92cbb9eec47b 73 lock();
apluscw 187:92cbb9eec47b 74 int ret = i2c_byte_write(&_i2c, data);
apluscw 187:92cbb9eec47b 75 unlock();
apluscw 187:92cbb9eec47b 76 return ret;
apluscw 187:92cbb9eec47b 77 }
apluscw 187:92cbb9eec47b 78
apluscw 187:92cbb9eec47b 79 // read - Master Reciever Mode
apluscw 187:92cbb9eec47b 80 int I2C::read(int address, char* data, int length, bool repeated) {
apluscw 187:92cbb9eec47b 81 lock();
apluscw 187:92cbb9eec47b 82 aquire();
apluscw 187:92cbb9eec47b 83
apluscw 187:92cbb9eec47b 84 int stop = (repeated) ? 0 : 1;
apluscw 187:92cbb9eec47b 85 int read = i2c_read(&_i2c, address, data, length, stop);
apluscw 187:92cbb9eec47b 86
apluscw 187:92cbb9eec47b 87 unlock();
apluscw 187:92cbb9eec47b 88 return length != read;
apluscw 187:92cbb9eec47b 89 }
apluscw 187:92cbb9eec47b 90
apluscw 187:92cbb9eec47b 91 int I2C::read(int ack) {
apluscw 187:92cbb9eec47b 92 lock();
apluscw 187:92cbb9eec47b 93 int ret;
apluscw 187:92cbb9eec47b 94 if (ack) {
apluscw 187:92cbb9eec47b 95 ret = i2c_byte_read(&_i2c, 0);
apluscw 187:92cbb9eec47b 96 } else {
apluscw 187:92cbb9eec47b 97 ret = i2c_byte_read(&_i2c, 1);
apluscw 187:92cbb9eec47b 98 }
apluscw 187:92cbb9eec47b 99 unlock();
apluscw 187:92cbb9eec47b 100 return ret;
apluscw 187:92cbb9eec47b 101 }
apluscw 187:92cbb9eec47b 102
apluscw 187:92cbb9eec47b 103 void I2C::start(void) {
apluscw 187:92cbb9eec47b 104 lock();
apluscw 187:92cbb9eec47b 105 i2c_start(&_i2c);
apluscw 187:92cbb9eec47b 106 unlock();
apluscw 187:92cbb9eec47b 107 }
apluscw 187:92cbb9eec47b 108
apluscw 187:92cbb9eec47b 109 void I2C::stop(void) {
apluscw 187:92cbb9eec47b 110 lock();
apluscw 187:92cbb9eec47b 111 i2c_stop(&_i2c);
apluscw 187:92cbb9eec47b 112 unlock();
apluscw 187:92cbb9eec47b 113 }
apluscw 187:92cbb9eec47b 114
apluscw 187:92cbb9eec47b 115 void I2C::lock() {
apluscw 187:92cbb9eec47b 116 _mutex->lock();
apluscw 187:92cbb9eec47b 117 }
apluscw 187:92cbb9eec47b 118
apluscw 187:92cbb9eec47b 119 void I2C::unlock() {
apluscw 187:92cbb9eec47b 120 _mutex->unlock();
apluscw 187:92cbb9eec47b 121 }
apluscw 187:92cbb9eec47b 122
apluscw 187:92cbb9eec47b 123 #if DEVICE_I2C_ASYNCH
apluscw 187:92cbb9eec47b 124
apluscw 187:92cbb9eec47b 125 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)
apluscw 187:92cbb9eec47b 126 {
apluscw 187:92cbb9eec47b 127 lock();
apluscw 187:92cbb9eec47b 128 if (i2c_active(&_i2c)) {
apluscw 187:92cbb9eec47b 129 unlock();
apluscw 187:92cbb9eec47b 130 return -1; // transaction ongoing
apluscw 187:92cbb9eec47b 131 }
apluscw 187:92cbb9eec47b 132 aquire();
apluscw 187:92cbb9eec47b 133
apluscw 187:92cbb9eec47b 134 _callback = callback;
apluscw 187:92cbb9eec47b 135 int stop = (repeated) ? 0 : 1;
apluscw 187:92cbb9eec47b 136 _irq.callback(&I2C::irq_handler_asynch);
apluscw 187:92cbb9eec47b 137 i2c_transfer_asynch(&_i2c, (void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length, address, stop, _irq.entry(), event, _usage);
apluscw 187:92cbb9eec47b 138 unlock();
apluscw 187:92cbb9eec47b 139 return 0;
apluscw 187:92cbb9eec47b 140 }
apluscw 187:92cbb9eec47b 141
apluscw 187:92cbb9eec47b 142 void I2C::abort_transfer(void)
apluscw 187:92cbb9eec47b 143 {
apluscw 187:92cbb9eec47b 144 lock();
apluscw 187:92cbb9eec47b 145 i2c_abort_asynch(&_i2c);
apluscw 187:92cbb9eec47b 146 unlock();
apluscw 187:92cbb9eec47b 147 }
apluscw 187:92cbb9eec47b 148
apluscw 187:92cbb9eec47b 149 void I2C::irq_handler_asynch(void)
apluscw 187:92cbb9eec47b 150 {
apluscw 187:92cbb9eec47b 151 int event = i2c_irq_handler_asynch(&_i2c);
apluscw 187:92cbb9eec47b 152 if (_callback && event) {
apluscw 187:92cbb9eec47b 153 _callback.call(event);
apluscw 187:92cbb9eec47b 154 }
apluscw 187:92cbb9eec47b 155
apluscw 187:92cbb9eec47b 156 }
apluscw 187:92cbb9eec47b 157
apluscw 187:92cbb9eec47b 158
apluscw 187:92cbb9eec47b 159 #endif
apluscw 187:92cbb9eec47b 160
apluscw 187:92cbb9eec47b 161 } // namespace mbed
apluscw 187:92cbb9eec47b 162
apluscw 187:92cbb9eec47b 163 #endif