Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

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