RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

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