temp

Dependencies:   mbed SDFileSystem MS5607 ADXL345_I2C FATFileSystem

Committer:
IKobayashi
Date:
Mon Mar 16 23:37:42 2020 +0900
Revision:
0:c88c3b616c00
copy

Who changed what in which revision?

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