Rahul Dahiya / Mbed OS STM32F7 Ethernet
Committer:
rahul_dahiya
Date:
Wed Jan 15 15:57:15 2020 +0530
Revision:
0:fb8047b156bb
STM32F7 LWIP

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rahul_dahiya 0:fb8047b156bb 1 /* mbed Microcontroller Library
rahul_dahiya 0:fb8047b156bb 2 * Copyright (c) 2006-2013 ARM Limited
rahul_dahiya 0:fb8047b156bb 3 *
rahul_dahiya 0:fb8047b156bb 4 * Licensed under the Apache License, Version 2.0 (the "License");
rahul_dahiya 0:fb8047b156bb 5 * you may not use this file except in compliance with the License.
rahul_dahiya 0:fb8047b156bb 6 * You may obtain a copy of the License at
rahul_dahiya 0:fb8047b156bb 7 *
rahul_dahiya 0:fb8047b156bb 8 * http://www.apache.org/licenses/LICENSE-2.0
rahul_dahiya 0:fb8047b156bb 9 *
rahul_dahiya 0:fb8047b156bb 10 * Unless required by applicable law or agreed to in writing, software
rahul_dahiya 0:fb8047b156bb 11 * distributed under the License is distributed on an "AS IS" BASIS,
rahul_dahiya 0:fb8047b156bb 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rahul_dahiya 0:fb8047b156bb 13 * See the License for the specific language governing permissions and
rahul_dahiya 0:fb8047b156bb 14 * limitations under the License.
rahul_dahiya 0:fb8047b156bb 15 */
rahul_dahiya 0:fb8047b156bb 16 #include "drivers/SPI.h"
rahul_dahiya 0:fb8047b156bb 17 #include "platform/mbed_critical.h"
rahul_dahiya 0:fb8047b156bb 18
rahul_dahiya 0:fb8047b156bb 19 #if DEVICE_SPI_ASYNCH
rahul_dahiya 0:fb8047b156bb 20 #include "platform/mbed_sleep.h"
rahul_dahiya 0:fb8047b156bb 21 #endif
rahul_dahiya 0:fb8047b156bb 22
rahul_dahiya 0:fb8047b156bb 23 #if DEVICE_SPI
rahul_dahiya 0:fb8047b156bb 24
rahul_dahiya 0:fb8047b156bb 25 namespace mbed {
rahul_dahiya 0:fb8047b156bb 26
rahul_dahiya 0:fb8047b156bb 27 #if DEVICE_SPI_ASYNCH && TRANSACTION_QUEUE_SIZE_SPI
rahul_dahiya 0:fb8047b156bb 28 CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> SPI::_transaction_buffer;
rahul_dahiya 0:fb8047b156bb 29 #endif
rahul_dahiya 0:fb8047b156bb 30
rahul_dahiya 0:fb8047b156bb 31 SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) :
rahul_dahiya 0:fb8047b156bb 32 _spi(),
rahul_dahiya 0:fb8047b156bb 33 #if DEVICE_SPI_ASYNCH
rahul_dahiya 0:fb8047b156bb 34 _irq(this),
rahul_dahiya 0:fb8047b156bb 35 _usage(DMA_USAGE_NEVER),
rahul_dahiya 0:fb8047b156bb 36 #endif
rahul_dahiya 0:fb8047b156bb 37 _bits(8),
rahul_dahiya 0:fb8047b156bb 38 _mode(0),
rahul_dahiya 0:fb8047b156bb 39 _hz(1000000),
rahul_dahiya 0:fb8047b156bb 40 _write_fill(SPI_FILL_CHAR) {
rahul_dahiya 0:fb8047b156bb 41 // No lock needed in the constructor
rahul_dahiya 0:fb8047b156bb 42
rahul_dahiya 0:fb8047b156bb 43 spi_init(&_spi, mosi, miso, sclk, ssel);
rahul_dahiya 0:fb8047b156bb 44 _acquire();
rahul_dahiya 0:fb8047b156bb 45 }
rahul_dahiya 0:fb8047b156bb 46
rahul_dahiya 0:fb8047b156bb 47 void SPI::format(int bits, int mode) {
rahul_dahiya 0:fb8047b156bb 48 lock();
rahul_dahiya 0:fb8047b156bb 49 _bits = bits;
rahul_dahiya 0:fb8047b156bb 50 _mode = mode;
rahul_dahiya 0:fb8047b156bb 51 // If changing format while you are the owner than just
rahul_dahiya 0:fb8047b156bb 52 // update format, but if owner is changed than even frequency should be
rahul_dahiya 0:fb8047b156bb 53 // updated which is done by acquire.
rahul_dahiya 0:fb8047b156bb 54 if (_owner == this) {
rahul_dahiya 0:fb8047b156bb 55 spi_format(&_spi, _bits, _mode, 0);
rahul_dahiya 0:fb8047b156bb 56 } else {
rahul_dahiya 0:fb8047b156bb 57 _acquire();
rahul_dahiya 0:fb8047b156bb 58 }
rahul_dahiya 0:fb8047b156bb 59 unlock();
rahul_dahiya 0:fb8047b156bb 60 }
rahul_dahiya 0:fb8047b156bb 61
rahul_dahiya 0:fb8047b156bb 62 void SPI::frequency(int hz) {
rahul_dahiya 0:fb8047b156bb 63 lock();
rahul_dahiya 0:fb8047b156bb 64 _hz = hz;
rahul_dahiya 0:fb8047b156bb 65 // If changing format while you are the owner than just
rahul_dahiya 0:fb8047b156bb 66 // update frequency, but if owner is changed than even frequency should be
rahul_dahiya 0:fb8047b156bb 67 // updated which is done by acquire.
rahul_dahiya 0:fb8047b156bb 68 if (_owner == this) {
rahul_dahiya 0:fb8047b156bb 69 spi_frequency(&_spi, _hz);
rahul_dahiya 0:fb8047b156bb 70 } else {
rahul_dahiya 0:fb8047b156bb 71 _acquire();
rahul_dahiya 0:fb8047b156bb 72 }
rahul_dahiya 0:fb8047b156bb 73 unlock();
rahul_dahiya 0:fb8047b156bb 74 }
rahul_dahiya 0:fb8047b156bb 75
rahul_dahiya 0:fb8047b156bb 76 SPI* SPI::_owner = NULL;
rahul_dahiya 0:fb8047b156bb 77 SingletonPtr<PlatformMutex> SPI::_mutex;
rahul_dahiya 0:fb8047b156bb 78
rahul_dahiya 0:fb8047b156bb 79 // ignore the fact there are multiple physical spis, and always update if it wasnt us last
rahul_dahiya 0:fb8047b156bb 80 void SPI::aquire() {
rahul_dahiya 0:fb8047b156bb 81 lock();
rahul_dahiya 0:fb8047b156bb 82 if (_owner != this) {
rahul_dahiya 0:fb8047b156bb 83 spi_format(&_spi, _bits, _mode, 0);
rahul_dahiya 0:fb8047b156bb 84 spi_frequency(&_spi, _hz);
rahul_dahiya 0:fb8047b156bb 85 _owner = this;
rahul_dahiya 0:fb8047b156bb 86 }
rahul_dahiya 0:fb8047b156bb 87 unlock();
rahul_dahiya 0:fb8047b156bb 88 }
rahul_dahiya 0:fb8047b156bb 89
rahul_dahiya 0:fb8047b156bb 90 // Note: Private function with no locking
rahul_dahiya 0:fb8047b156bb 91 void SPI::_acquire() {
rahul_dahiya 0:fb8047b156bb 92 if (_owner != this) {
rahul_dahiya 0:fb8047b156bb 93 spi_format(&_spi, _bits, _mode, 0);
rahul_dahiya 0:fb8047b156bb 94 spi_frequency(&_spi, _hz);
rahul_dahiya 0:fb8047b156bb 95 _owner = this;
rahul_dahiya 0:fb8047b156bb 96 }
rahul_dahiya 0:fb8047b156bb 97 }
rahul_dahiya 0:fb8047b156bb 98
rahul_dahiya 0:fb8047b156bb 99 int SPI::write(int value) {
rahul_dahiya 0:fb8047b156bb 100 lock();
rahul_dahiya 0:fb8047b156bb 101 _acquire();
rahul_dahiya 0:fb8047b156bb 102 int ret = spi_master_write(&_spi, value);
rahul_dahiya 0:fb8047b156bb 103 unlock();
rahul_dahiya 0:fb8047b156bb 104 return ret;
rahul_dahiya 0:fb8047b156bb 105 }
rahul_dahiya 0:fb8047b156bb 106
rahul_dahiya 0:fb8047b156bb 107 int SPI::write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
rahul_dahiya 0:fb8047b156bb 108 lock();
rahul_dahiya 0:fb8047b156bb 109 _acquire();
rahul_dahiya 0:fb8047b156bb 110 int ret = spi_master_block_write(&_spi, tx_buffer, tx_length, rx_buffer, rx_length, _write_fill);
rahul_dahiya 0:fb8047b156bb 111 unlock();
rahul_dahiya 0:fb8047b156bb 112 return ret;
rahul_dahiya 0:fb8047b156bb 113 }
rahul_dahiya 0:fb8047b156bb 114
rahul_dahiya 0:fb8047b156bb 115 void SPI::lock() {
rahul_dahiya 0:fb8047b156bb 116 _mutex->lock();
rahul_dahiya 0:fb8047b156bb 117 }
rahul_dahiya 0:fb8047b156bb 118
rahul_dahiya 0:fb8047b156bb 119 void SPI::unlock() {
rahul_dahiya 0:fb8047b156bb 120 _mutex->unlock();
rahul_dahiya 0:fb8047b156bb 121 }
rahul_dahiya 0:fb8047b156bb 122
rahul_dahiya 0:fb8047b156bb 123 void SPI::set_default_write_value(char data) {
rahul_dahiya 0:fb8047b156bb 124 lock();
rahul_dahiya 0:fb8047b156bb 125 _write_fill = data;
rahul_dahiya 0:fb8047b156bb 126 unlock();
rahul_dahiya 0:fb8047b156bb 127 }
rahul_dahiya 0:fb8047b156bb 128
rahul_dahiya 0:fb8047b156bb 129 #if DEVICE_SPI_ASYNCH
rahul_dahiya 0:fb8047b156bb 130
rahul_dahiya 0:fb8047b156bb 131 int SPI::transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event)
rahul_dahiya 0:fb8047b156bb 132 {
rahul_dahiya 0:fb8047b156bb 133 if (spi_active(&_spi)) {
rahul_dahiya 0:fb8047b156bb 134 return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, bit_width, callback, event);
rahul_dahiya 0:fb8047b156bb 135 }
rahul_dahiya 0:fb8047b156bb 136 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, bit_width, callback, event);
rahul_dahiya 0:fb8047b156bb 137 return 0;
rahul_dahiya 0:fb8047b156bb 138 }
rahul_dahiya 0:fb8047b156bb 139
rahul_dahiya 0:fb8047b156bb 140 void SPI::abort_transfer()
rahul_dahiya 0:fb8047b156bb 141 {
rahul_dahiya 0:fb8047b156bb 142 spi_abort_asynch(&_spi);
rahul_dahiya 0:fb8047b156bb 143 sleep_manager_unlock_deep_sleep();
rahul_dahiya 0:fb8047b156bb 144 #if TRANSACTION_QUEUE_SIZE_SPI
rahul_dahiya 0:fb8047b156bb 145 dequeue_transaction();
rahul_dahiya 0:fb8047b156bb 146 #endif
rahul_dahiya 0:fb8047b156bb 147 }
rahul_dahiya 0:fb8047b156bb 148
rahul_dahiya 0:fb8047b156bb 149
rahul_dahiya 0:fb8047b156bb 150 void SPI::clear_transfer_buffer()
rahul_dahiya 0:fb8047b156bb 151 {
rahul_dahiya 0:fb8047b156bb 152 #if TRANSACTION_QUEUE_SIZE_SPI
rahul_dahiya 0:fb8047b156bb 153 _transaction_buffer.reset();
rahul_dahiya 0:fb8047b156bb 154 #endif
rahul_dahiya 0:fb8047b156bb 155 }
rahul_dahiya 0:fb8047b156bb 156
rahul_dahiya 0:fb8047b156bb 157 void SPI::abort_all_transfers()
rahul_dahiya 0:fb8047b156bb 158 {
rahul_dahiya 0:fb8047b156bb 159 clear_transfer_buffer();
rahul_dahiya 0:fb8047b156bb 160 abort_transfer();
rahul_dahiya 0:fb8047b156bb 161 }
rahul_dahiya 0:fb8047b156bb 162
rahul_dahiya 0:fb8047b156bb 163 int SPI::set_dma_usage(DMAUsage usage)
rahul_dahiya 0:fb8047b156bb 164 {
rahul_dahiya 0:fb8047b156bb 165 if (spi_active(&_spi)) {
rahul_dahiya 0:fb8047b156bb 166 return -1;
rahul_dahiya 0:fb8047b156bb 167 }
rahul_dahiya 0:fb8047b156bb 168 _usage = usage;
rahul_dahiya 0:fb8047b156bb 169 return 0;
rahul_dahiya 0:fb8047b156bb 170 }
rahul_dahiya 0:fb8047b156bb 171
rahul_dahiya 0:fb8047b156bb 172 int SPI::queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event)
rahul_dahiya 0:fb8047b156bb 173 {
rahul_dahiya 0:fb8047b156bb 174 #if TRANSACTION_QUEUE_SIZE_SPI
rahul_dahiya 0:fb8047b156bb 175 transaction_t t;
rahul_dahiya 0:fb8047b156bb 176
rahul_dahiya 0:fb8047b156bb 177 t.tx_buffer = const_cast<void *>(tx_buffer);
rahul_dahiya 0:fb8047b156bb 178 t.tx_length = tx_length;
rahul_dahiya 0:fb8047b156bb 179 t.rx_buffer = rx_buffer;
rahul_dahiya 0:fb8047b156bb 180 t.rx_length = rx_length;
rahul_dahiya 0:fb8047b156bb 181 t.event = event;
rahul_dahiya 0:fb8047b156bb 182 t.callback = callback;
rahul_dahiya 0:fb8047b156bb 183 t.width = bit_width;
rahul_dahiya 0:fb8047b156bb 184 Transaction<SPI> transaction(this, t);
rahul_dahiya 0:fb8047b156bb 185 if (_transaction_buffer.full()) {
rahul_dahiya 0:fb8047b156bb 186 return -1; // the buffer is full
rahul_dahiya 0:fb8047b156bb 187 } else {
rahul_dahiya 0:fb8047b156bb 188 core_util_critical_section_enter();
rahul_dahiya 0:fb8047b156bb 189 _transaction_buffer.push(transaction);
rahul_dahiya 0:fb8047b156bb 190 if (!spi_active(&_spi)) {
rahul_dahiya 0:fb8047b156bb 191 dequeue_transaction();
rahul_dahiya 0:fb8047b156bb 192 }
rahul_dahiya 0:fb8047b156bb 193 core_util_critical_section_exit();
rahul_dahiya 0:fb8047b156bb 194 return 0;
rahul_dahiya 0:fb8047b156bb 195 }
rahul_dahiya 0:fb8047b156bb 196 #else
rahul_dahiya 0:fb8047b156bb 197 return -1;
rahul_dahiya 0:fb8047b156bb 198 #endif
rahul_dahiya 0:fb8047b156bb 199 }
rahul_dahiya 0:fb8047b156bb 200
rahul_dahiya 0:fb8047b156bb 201 void SPI::start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event)
rahul_dahiya 0:fb8047b156bb 202 {
rahul_dahiya 0:fb8047b156bb 203 sleep_manager_lock_deep_sleep();
rahul_dahiya 0:fb8047b156bb 204 _acquire();
rahul_dahiya 0:fb8047b156bb 205 _callback = callback;
rahul_dahiya 0:fb8047b156bb 206 _irq.callback(&SPI::irq_handler_asynch);
rahul_dahiya 0:fb8047b156bb 207 spi_master_transfer(&_spi, tx_buffer, tx_length, rx_buffer, rx_length, bit_width, _irq.entry(), event , _usage);
rahul_dahiya 0:fb8047b156bb 208 }
rahul_dahiya 0:fb8047b156bb 209
rahul_dahiya 0:fb8047b156bb 210 #if TRANSACTION_QUEUE_SIZE_SPI
rahul_dahiya 0:fb8047b156bb 211
rahul_dahiya 0:fb8047b156bb 212 void SPI::start_transaction(transaction_t *data)
rahul_dahiya 0:fb8047b156bb 213 {
rahul_dahiya 0:fb8047b156bb 214 start_transfer(data->tx_buffer, data->tx_length, data->rx_buffer, data->rx_length, data->width, data->callback, data->event);
rahul_dahiya 0:fb8047b156bb 215 }
rahul_dahiya 0:fb8047b156bb 216
rahul_dahiya 0:fb8047b156bb 217 void SPI::dequeue_transaction()
rahul_dahiya 0:fb8047b156bb 218 {
rahul_dahiya 0:fb8047b156bb 219 Transaction<SPI> t;
rahul_dahiya 0:fb8047b156bb 220 if (_transaction_buffer.pop(t)) {
rahul_dahiya 0:fb8047b156bb 221 SPI* obj = t.get_object();
rahul_dahiya 0:fb8047b156bb 222 transaction_t* data = t.get_transaction();
rahul_dahiya 0:fb8047b156bb 223 obj->start_transaction(data);
rahul_dahiya 0:fb8047b156bb 224 }
rahul_dahiya 0:fb8047b156bb 225 }
rahul_dahiya 0:fb8047b156bb 226
rahul_dahiya 0:fb8047b156bb 227 #endif
rahul_dahiya 0:fb8047b156bb 228
rahul_dahiya 0:fb8047b156bb 229 void SPI::irq_handler_asynch(void)
rahul_dahiya 0:fb8047b156bb 230 {
rahul_dahiya 0:fb8047b156bb 231 int event = spi_irq_handler_asynch(&_spi);
rahul_dahiya 0:fb8047b156bb 232 if (_callback && (event & SPI_EVENT_ALL)) {
rahul_dahiya 0:fb8047b156bb 233 sleep_manager_unlock_deep_sleep();
rahul_dahiya 0:fb8047b156bb 234 _callback.call(event & SPI_EVENT_ALL);
rahul_dahiya 0:fb8047b156bb 235 }
rahul_dahiya 0:fb8047b156bb 236 #if TRANSACTION_QUEUE_SIZE_SPI
rahul_dahiya 0:fb8047b156bb 237 if (event & (SPI_EVENT_ALL | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE)) {
rahul_dahiya 0:fb8047b156bb 238 // SPI peripheral is free (event happend), dequeue transaction
rahul_dahiya 0:fb8047b156bb 239 dequeue_transaction();
rahul_dahiya 0:fb8047b156bb 240 }
rahul_dahiya 0:fb8047b156bb 241 #endif
rahul_dahiya 0:fb8047b156bb 242 }
rahul_dahiya 0:fb8047b156bb 243
rahul_dahiya 0:fb8047b156bb 244 #endif
rahul_dahiya 0:fb8047b156bb 245
rahul_dahiya 0:fb8047b156bb 246 } // namespace mbed
rahul_dahiya 0:fb8047b156bb 247
rahul_dahiya 0:fb8047b156bb 248 #endif