init

Dependencies:   mbed

Committer:
Nathan Yonkee
Date:
Fri Mar 02 07:16:49 2018 -0700
Revision:
10:46a4cf51ee38
Parent:
9:d58e77ebd769
remove mbed-os

Who changed what in which revision?

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