Includes library modifications to allow access to AIN_4 (AIN_0 / 5)

Committer:
bryantaylor
Date:
Tue Sep 20 21:26:12 2016 +0000
Revision:
0:eafc3fd41f75
hackathon

Who changed what in which revision?

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