inport from local

Dependents:   Hobbyking_Cheetah_0511

Committer:
NYX
Date:
Mon Mar 16 06:35:48 2020 +0000
Revision:
0:85b3fd62ea1a
reinport to mbed;

Who changed what in which revision?

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