,,

Fork of Application by Daniel Sygut

Committer:
Zaitsev
Date:
Thu Feb 15 14:29:23 2018 +0000
Revision:
15:2a20c3d2616e
Parent:
10:41552d038a69
j

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Zaitsev 10:41552d038a69 1 /* mbed Microcontroller Library
Zaitsev 10:41552d038a69 2 * Copyright (c) 2006-2015 ARM Limited
Zaitsev 10:41552d038a69 3 *
Zaitsev 10:41552d038a69 4 * Licensed under the Apache License, Version 2.0 (the "License");
Zaitsev 10:41552d038a69 5 * you may not use this file except in compliance with the License.
Zaitsev 10:41552d038a69 6 * You may obtain a copy of the License at
Zaitsev 10:41552d038a69 7 *
Zaitsev 10:41552d038a69 8 * http://www.apache.org/licenses/LICENSE-2.0
Zaitsev 10:41552d038a69 9 *
Zaitsev 10:41552d038a69 10 * Unless required by applicable law or agreed to in writing, software
Zaitsev 10:41552d038a69 11 * distributed under the License is distributed on an "AS IS" BASIS,
Zaitsev 10:41552d038a69 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Zaitsev 10:41552d038a69 13 * See the License for the specific language governing permissions and
Zaitsev 10:41552d038a69 14 * limitations under the License.
Zaitsev 10:41552d038a69 15 */
Zaitsev 10:41552d038a69 16 #ifndef MBED_SPI_H
Zaitsev 10:41552d038a69 17 #define MBED_SPI_H
Zaitsev 10:41552d038a69 18
Zaitsev 10:41552d038a69 19 #include "platform/platform.h"
Zaitsev 10:41552d038a69 20
Zaitsev 10:41552d038a69 21 #if DEVICE_SPI
Zaitsev 10:41552d038a69 22
Zaitsev 10:41552d038a69 23 #include "platform/PlatformMutex.h"
Zaitsev 10:41552d038a69 24 #include "hal/spi_api.h"
Zaitsev 10:41552d038a69 25 #include "platform/SingletonPtr.h"
Zaitsev 10:41552d038a69 26
Zaitsev 10:41552d038a69 27 #if DEVICE_SPI_ASYNCH
Zaitsev 10:41552d038a69 28 #include "platform/CThunk.h"
Zaitsev 10:41552d038a69 29 #include "hal/dma_api.h"
Zaitsev 10:41552d038a69 30 #include "platform/CircularBuffer.h"
Zaitsev 10:41552d038a69 31 #include "platform/FunctionPointer.h"
Zaitsev 10:41552d038a69 32 #include "platform/Transaction.h"
Zaitsev 10:41552d038a69 33 #endif
Zaitsev 10:41552d038a69 34
Zaitsev 10:41552d038a69 35 namespace mbed {
Zaitsev 10:41552d038a69 36 /** \addtogroup drivers */
Zaitsev 10:41552d038a69 37 /** @{*/
Zaitsev 10:41552d038a69 38
Zaitsev 10:41552d038a69 39 /** A SPI Master, used for communicating with SPI slave devices
Zaitsev 10:41552d038a69 40 *
Zaitsev 10:41552d038a69 41 * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz
Zaitsev 10:41552d038a69 42 *
Zaitsev 10:41552d038a69 43 * Most SPI devices will also require Chip Select and Reset signals. These
Zaitsev 10:41552d038a69 44 * can be controlled using <DigitalOut> pins
Zaitsev 10:41552d038a69 45 *
Zaitsev 10:41552d038a69 46 * @Note Synchronization level: Thread safe
Zaitsev 10:41552d038a69 47 *
Zaitsev 10:41552d038a69 48 * Example:
Zaitsev 10:41552d038a69 49 * @code
Zaitsev 10:41552d038a69 50 * // Send a byte to a SPI slave, and record the response
Zaitsev 10:41552d038a69 51 *
Zaitsev 10:41552d038a69 52 * #include "mbed.h"
Zaitsev 10:41552d038a69 53 *
Zaitsev 10:41552d038a69 54 * // hardware ssel (where applicable)
Zaitsev 10:41552d038a69 55 * //SPI device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
Zaitsev 10:41552d038a69 56 *
Zaitsev 10:41552d038a69 57 * // software ssel
Zaitsev 10:41552d038a69 58 * SPI device(p5, p6, p7); // mosi, miso, sclk
Zaitsev 10:41552d038a69 59 * DigitalOut cs(p8); // ssel
Zaitsev 10:41552d038a69 60 *
Zaitsev 10:41552d038a69 61 * int main() {
Zaitsev 10:41552d038a69 62 * // hardware ssel (where applicable)
Zaitsev 10:41552d038a69 63 * //int response = device.write(0xFF);
Zaitsev 10:41552d038a69 64 *
Zaitsev 10:41552d038a69 65 * device.lock();
Zaitsev 10:41552d038a69 66 * // software ssel
Zaitsev 10:41552d038a69 67 * cs = 0;
Zaitsev 10:41552d038a69 68 * int response = device.write(0xFF);
Zaitsev 10:41552d038a69 69 * cs = 1;
Zaitsev 10:41552d038a69 70 * device.unlock();
Zaitsev 10:41552d038a69 71 *
Zaitsev 10:41552d038a69 72 * }
Zaitsev 10:41552d038a69 73 * @endcode
Zaitsev 10:41552d038a69 74 */
Zaitsev 10:41552d038a69 75 class SPI {
Zaitsev 10:41552d038a69 76
Zaitsev 10:41552d038a69 77 public:
Zaitsev 10:41552d038a69 78
Zaitsev 10:41552d038a69 79 /** Create a SPI master connected to the specified pins
Zaitsev 10:41552d038a69 80 *
Zaitsev 10:41552d038a69 81 * mosi or miso can be specfied as NC if not used
Zaitsev 10:41552d038a69 82 *
Zaitsev 10:41552d038a69 83 * @param mosi SPI Master Out, Slave In pin
Zaitsev 10:41552d038a69 84 * @param miso SPI Master In, Slave Out pin
Zaitsev 10:41552d038a69 85 * @param sclk SPI Clock pin
Zaitsev 10:41552d038a69 86 * @param ssel SPI chip select pin
Zaitsev 10:41552d038a69 87 */
Zaitsev 10:41552d038a69 88 SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel=NC);
Zaitsev 10:41552d038a69 89
Zaitsev 10:41552d038a69 90 /** Configure the data transmission format
Zaitsev 10:41552d038a69 91 *
Zaitsev 10:41552d038a69 92 * @param bits Number of bits per SPI frame (4 - 16)
Zaitsev 10:41552d038a69 93 * @param mode Clock polarity and phase mode (0 - 3)
Zaitsev 10:41552d038a69 94 *
Zaitsev 10:41552d038a69 95 * @code
Zaitsev 10:41552d038a69 96 * mode | POL PHA
Zaitsev 10:41552d038a69 97 * -----+--------
Zaitsev 10:41552d038a69 98 * 0 | 0 0
Zaitsev 10:41552d038a69 99 * 1 | 0 1
Zaitsev 10:41552d038a69 100 * 2 | 1 0
Zaitsev 10:41552d038a69 101 * 3 | 1 1
Zaitsev 10:41552d038a69 102 * @endcode
Zaitsev 10:41552d038a69 103 */
Zaitsev 10:41552d038a69 104 void format(int bits, int mode = 0);
Zaitsev 10:41552d038a69 105
Zaitsev 10:41552d038a69 106 /** Set the spi bus clock frequency
Zaitsev 10:41552d038a69 107 *
Zaitsev 10:41552d038a69 108 * @param hz SCLK frequency in hz (default = 1MHz)
Zaitsev 10:41552d038a69 109 */
Zaitsev 10:41552d038a69 110 void frequency(int hz = 1000000);
Zaitsev 10:41552d038a69 111
Zaitsev 10:41552d038a69 112 /** Write to the SPI Slave and return the response
Zaitsev 10:41552d038a69 113 *
Zaitsev 10:41552d038a69 114 * @param value Data to be sent to the SPI slave
Zaitsev 10:41552d038a69 115 *
Zaitsev 10:41552d038a69 116 * @returns
Zaitsev 10:41552d038a69 117 * Response from the SPI slave
Zaitsev 10:41552d038a69 118 */
Zaitsev 10:41552d038a69 119 virtual int write(int value);
Zaitsev 10:41552d038a69 120
Zaitsev 10:41552d038a69 121 /** Acquire exclusive access to this SPI bus
Zaitsev 10:41552d038a69 122 */
Zaitsev 10:41552d038a69 123 virtual void lock(void);
Zaitsev 10:41552d038a69 124
Zaitsev 10:41552d038a69 125 /** Release exclusive access to this SPI bus
Zaitsev 10:41552d038a69 126 */
Zaitsev 10:41552d038a69 127 virtual void unlock(void);
Zaitsev 10:41552d038a69 128
Zaitsev 10:41552d038a69 129 #if DEVICE_SPI_ASYNCH
Zaitsev 10:41552d038a69 130
Zaitsev 10:41552d038a69 131 /** Start non-blocking SPI transfer using 8bit buffers.
Zaitsev 10:41552d038a69 132 *
Zaitsev 10:41552d038a69 133 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
Zaitsev 10:41552d038a69 134 * the default SPI value is sent
Zaitsev 10:41552d038a69 135 * @param tx_length The length of TX buffer in bytes
Zaitsev 10:41552d038a69 136 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
Zaitsev 10:41552d038a69 137 * received data are ignored
Zaitsev 10:41552d038a69 138 * @param rx_length The length of RX buffer in bytes
Zaitsev 10:41552d038a69 139 * @param callback The event callback function
Zaitsev 10:41552d038a69 140 * @param event The logical OR of events to modify. Look at spi hal header file for SPI events.
Zaitsev 10:41552d038a69 141 * @return Zero if the transfer has started, or -1 if SPI peripheral is busy
Zaitsev 10:41552d038a69 142 */
Zaitsev 10:41552d038a69 143 template<typename Type>
Zaitsev 10:41552d038a69 144 int transfer(const Type *tx_buffer, int tx_length, Type *rx_buffer, int rx_length, const event_callback_t& callback, int event = SPI_EVENT_COMPLETE) {
Zaitsev 10:41552d038a69 145 if (spi_active(&_spi)) {
Zaitsev 10:41552d038a69 146 return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event);
Zaitsev 10:41552d038a69 147 }
Zaitsev 10:41552d038a69 148 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event);
Zaitsev 10:41552d038a69 149 return 0;
Zaitsev 10:41552d038a69 150 }
Zaitsev 10:41552d038a69 151
Zaitsev 10:41552d038a69 152 /** Abort the on-going SPI transfer, and continue with transfer's in the queue if any.
Zaitsev 10:41552d038a69 153 */
Zaitsev 10:41552d038a69 154 void abort_transfer();
Zaitsev 10:41552d038a69 155
Zaitsev 10:41552d038a69 156 /** Clear the transaction buffer
Zaitsev 10:41552d038a69 157 */
Zaitsev 10:41552d038a69 158 void clear_transfer_buffer();
Zaitsev 10:41552d038a69 159
Zaitsev 10:41552d038a69 160 /** Clear the transaction buffer and abort on-going transfer.
Zaitsev 10:41552d038a69 161 */
Zaitsev 10:41552d038a69 162 void abort_all_transfers();
Zaitsev 10:41552d038a69 163
Zaitsev 10:41552d038a69 164 /** Configure DMA usage suggestion for non-blocking transfers
Zaitsev 10:41552d038a69 165 *
Zaitsev 10:41552d038a69 166 * @param usage The usage DMA hint for peripheral
Zaitsev 10:41552d038a69 167 * @return Zero if the usage was set, -1 if a transaction is on-going
Zaitsev 10:41552d038a69 168 */
Zaitsev 10:41552d038a69 169 int set_dma_usage(DMAUsage usage);
Zaitsev 10:41552d038a69 170
Zaitsev 10:41552d038a69 171 protected:
Zaitsev 10:41552d038a69 172 /** SPI IRQ handler
Zaitsev 10:41552d038a69 173 *
Zaitsev 10:41552d038a69 174 */
Zaitsev 10:41552d038a69 175 void irq_handler_asynch(void);
Zaitsev 10:41552d038a69 176
Zaitsev 10:41552d038a69 177 /** Common transfer method
Zaitsev 10:41552d038a69 178 *
Zaitsev 10:41552d038a69 179 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
Zaitsev 10:41552d038a69 180 * the default SPI value is sent
Zaitsev 10:41552d038a69 181 * @param tx_length The length of TX buffer in bytes
Zaitsev 10:41552d038a69 182 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
Zaitsev 10:41552d038a69 183 * received data are ignored
Zaitsev 10:41552d038a69 184 * @param rx_length The length of RX buffer in bytes
Zaitsev 10:41552d038a69 185 * @param bit_width The buffers element width
Zaitsev 10:41552d038a69 186 * @param callback The event callback function
Zaitsev 10:41552d038a69 187 * @param event The logical OR of events to modify
Zaitsev 10:41552d038a69 188 * @return Zero if the transfer has started or was added to the queue, or -1 if SPI peripheral is busy/buffer is full
Zaitsev 10:41552d038a69 189 */
Zaitsev 10:41552d038a69 190 int 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);
Zaitsev 10:41552d038a69 191
Zaitsev 10:41552d038a69 192 /**
Zaitsev 10:41552d038a69 193 *
Zaitsev 10:41552d038a69 194 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
Zaitsev 10:41552d038a69 195 * the default SPI value is sent
Zaitsev 10:41552d038a69 196 * @param tx_length The length of TX buffer in bytes
Zaitsev 10:41552d038a69 197 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
Zaitsev 10:41552d038a69 198 * received data are ignored
Zaitsev 10:41552d038a69 199 * @param rx_length The length of RX buffer in bytes
Zaitsev 10:41552d038a69 200 * @param bit_width The buffers element width
Zaitsev 10:41552d038a69 201 * @param callback The event callback function
Zaitsev 10:41552d038a69 202 * @param event The logical OR of events to modify
Zaitsev 10:41552d038a69 203 * @return Zero if a transfer was added to the queue, or -1 if the queue is full
Zaitsev 10:41552d038a69 204 */
Zaitsev 10:41552d038a69 205 int 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);
Zaitsev 10:41552d038a69 206
Zaitsev 10:41552d038a69 207 /** Configures a callback, spi peripheral and initiate a new transfer
Zaitsev 10:41552d038a69 208 *
Zaitsev 10:41552d038a69 209 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
Zaitsev 10:41552d038a69 210 * the default SPI value is sent
Zaitsev 10:41552d038a69 211 * @param tx_length The length of TX buffer in bytes
Zaitsev 10:41552d038a69 212 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
Zaitsev 10:41552d038a69 213 * received data are ignored
Zaitsev 10:41552d038a69 214 * @param rx_length The length of RX buffer in bytes
Zaitsev 10:41552d038a69 215 * @param bit_width The buffers element width
Zaitsev 10:41552d038a69 216 * @param callback The event callback function
Zaitsev 10:41552d038a69 217 * @param event The logical OR of events to modify
Zaitsev 10:41552d038a69 218 */
Zaitsev 10:41552d038a69 219 void 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);
Zaitsev 10:41552d038a69 220
Zaitsev 10:41552d038a69 221 #if TRANSACTION_QUEUE_SIZE_SPI
Zaitsev 10:41552d038a69 222
Zaitsev 10:41552d038a69 223 /** Start a new transaction
Zaitsev 10:41552d038a69 224 *
Zaitsev 10:41552d038a69 225 * @param data Transaction data
Zaitsev 10:41552d038a69 226 */
Zaitsev 10:41552d038a69 227 void start_transaction(transaction_t *data);
Zaitsev 10:41552d038a69 228
Zaitsev 10:41552d038a69 229 /** Dequeue a transaction
Zaitsev 10:41552d038a69 230 *
Zaitsev 10:41552d038a69 231 */
Zaitsev 10:41552d038a69 232 void dequeue_transaction();
Zaitsev 10:41552d038a69 233 static CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> _transaction_buffer;
Zaitsev 10:41552d038a69 234 #endif
Zaitsev 10:41552d038a69 235
Zaitsev 10:41552d038a69 236 #endif
Zaitsev 10:41552d038a69 237
Zaitsev 10:41552d038a69 238 public:
Zaitsev 10:41552d038a69 239 virtual ~SPI() {
Zaitsev 10:41552d038a69 240 }
Zaitsev 10:41552d038a69 241
Zaitsev 10:41552d038a69 242 protected:
Zaitsev 10:41552d038a69 243 spi_t _spi;
Zaitsev 10:41552d038a69 244
Zaitsev 10:41552d038a69 245 #if DEVICE_SPI_ASYNCH
Zaitsev 10:41552d038a69 246 CThunk<SPI> _irq;
Zaitsev 10:41552d038a69 247 event_callback_t _callback;
Zaitsev 10:41552d038a69 248 DMAUsage _usage;
Zaitsev 10:41552d038a69 249 #endif
Zaitsev 10:41552d038a69 250
Zaitsev 10:41552d038a69 251 void aquire(void);
Zaitsev 10:41552d038a69 252 static SPI *_owner;
Zaitsev 10:41552d038a69 253 static SingletonPtr<PlatformMutex> _mutex;
Zaitsev 10:41552d038a69 254 int _bits;
Zaitsev 10:41552d038a69 255 int _mode;
Zaitsev 10:41552d038a69 256 int _hz;
Zaitsev 10:41552d038a69 257 };
Zaitsev 10:41552d038a69 258
Zaitsev 10:41552d038a69 259 } // namespace mbed
Zaitsev 10:41552d038a69 260
Zaitsev 10:41552d038a69 261 #endif
Zaitsev 10:41552d038a69 262
Zaitsev 10:41552d038a69 263 #endif
Zaitsev 10:41552d038a69 264
Zaitsev 10:41552d038a69 265 /** @}*/