Backup 1

Committer:
borlanic
Date:
Tue Apr 24 11:45:18 2018 +0000
Revision:
0:02dd72d1d465
BaBoRo_test2 - backup 1

Who changed what in which revision?

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