The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Dependents:   hello SerialTestv11 SerialTestv12 Sierpinski ... more

mbed 2

This is the mbed 2 library. If you'd like to learn about Mbed OS please see the mbed-os docs.

Committer:
Anna Bridge
Date:
Fri Jun 22 15:38:59 2018 +0100
Revision:
169:a7c7b631e539
Parent:
165:d1b4690b3f8b
Child:
170:e95d10626187
mbed library. Release version 162

Who changed what in which revision?

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