Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SPI.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #ifndef MBED_SPI_H 00017 #define MBED_SPI_H 00018 00019 #include "platform.h" 00020 00021 #if DEVICE_SPI 00022 00023 #include "PlatformMutex.h" 00024 #include "spi_api.h" 00025 #include "SingletonPtr.h" 00026 00027 #if DEVICE_SPI_ASYNCH 00028 #include "CThunk.h" 00029 #include "dma_api.h" 00030 #include "CircularBuffer.h" 00031 #include "FunctionPointer.h" 00032 #include "Transaction.h" 00033 #endif 00034 00035 namespace mbed { 00036 00037 /** A SPI Master, used for communicating with SPI slave devices 00038 * 00039 * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz 00040 * 00041 * Most SPI devices will also require Chip Select and Reset signals. These 00042 * can be controlled using <DigitalOut> pins 00043 * 00044 * @Note Synchronization level: Thread safe 00045 * 00046 * Example: 00047 * @code 00048 * // Send a byte to a SPI slave, and record the response 00049 * 00050 * #include "mbed.h" 00051 * 00052 * // hardware ssel (where applicable) 00053 * //SPI device(p5, p6, p7, p8); // mosi, miso, sclk, ssel 00054 * 00055 * // software ssel 00056 * SPI device(p5, p6, p7); // mosi, miso, sclk 00057 * DigitalOut cs(p8); // ssel 00058 * 00059 * int main() { 00060 * // hardware ssel (where applicable) 00061 * //int response = device.write(0xFF); 00062 * 00063 * device.lock(); 00064 * // software ssel 00065 * cs = 0; 00066 * int response = device.write(0xFF); 00067 * cs = 1; 00068 * device.unlock(); 00069 * 00070 * } 00071 * @endcode 00072 */ 00073 class SPI { 00074 00075 public: 00076 00077 /** Create a SPI master connected to the specified pins 00078 * 00079 * mosi or miso can be specfied as NC if not used 00080 * 00081 * @param mosi SPI Master Out, Slave In pin 00082 * @param miso SPI Master In, Slave Out pin 00083 * @param sclk SPI Clock pin 00084 * @param ssel SPI chip select pin 00085 */ 00086 SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel=NC); 00087 00088 /** Configure the data transmission format 00089 * 00090 * @param bits Number of bits per SPI frame (4 - 16) 00091 * @param mode Clock polarity and phase mode (0 - 3) 00092 * 00093 * @code 00094 * mode | POL PHA 00095 * -----+-------- 00096 * 0 | 0 0 00097 * 1 | 0 1 00098 * 2 | 1 0 00099 * 3 | 1 1 00100 * @endcode 00101 */ 00102 void format(int bits, int mode = 0); 00103 00104 /** Set the spi bus clock frequency 00105 * 00106 * @param hz SCLK frequency in hz (default = 1MHz) 00107 */ 00108 void frequency(int hz = 1000000); 00109 00110 /** Write to the SPI Slave and return the response 00111 * 00112 * @param value Data to be sent to the SPI slave 00113 * 00114 * @returns 00115 * Response from the SPI slave 00116 */ 00117 virtual int write(int value); 00118 00119 /** Acquire exclusive access to this SPI bus 00120 */ 00121 virtual void lock(void); 00122 00123 /** Release exclusive access to this SPI bus 00124 */ 00125 virtual void unlock(void); 00126 00127 #if DEVICE_SPI_ASYNCH 00128 00129 /** Start non-blocking SPI transfer using 8bit buffers. 00130 * 00131 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00132 * the default SPI value is sent 00133 * @param tx_length The length of TX buffer in bytes 00134 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00135 * received data are ignored 00136 * @param rx_length The length of RX buffer in bytes 00137 * @param callback The event callback function 00138 * @param event The logical OR of events to modify. Look at spi hal header file for SPI events. 00139 * @return Zero if the transfer has started, or -1 if SPI peripheral is busy 00140 */ 00141 template<typename Type> 00142 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) { 00143 if (spi_active(&_spi)) { 00144 return queue_transfer (tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event); 00145 } 00146 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event); 00147 return 0; 00148 } 00149 00150 /** Abort the on-going SPI transfer, and continue with transfer's in the queue if any. 00151 */ 00152 void abort_transfer(); 00153 00154 /** Clear the transaction buffer 00155 */ 00156 void clear_transfer_buffer(); 00157 00158 /** Clear the transaction buffer and abort on-going transfer. 00159 */ 00160 void abort_all_transfers(); 00161 00162 /** Configure DMA usage suggestion for non-blocking transfers 00163 * 00164 * @param usage The usage DMA hint for peripheral 00165 * @return Zero if the usage was set, -1 if a transaction is on-going 00166 */ 00167 int set_dma_usage(DMAUsage usage); 00168 00169 protected: 00170 /** SPI IRQ handler 00171 * 00172 */ 00173 void irq_handler_asynch(void); 00174 00175 /** Common transfer method 00176 * 00177 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00178 * the default SPI value is sent 00179 * @param tx_length The length of TX buffer in bytes 00180 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00181 * received data are ignored 00182 * @param rx_length The length of RX buffer in bytes 00183 * @param bit_width The buffers element width 00184 * @param callback The event callback function 00185 * @param event The logical OR of events to modify 00186 * @return Zero if the transfer has started or was added to the queue, or -1 if SPI peripheral is busy/buffer is full 00187 */ 00188 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); 00189 00190 /** 00191 * 00192 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00193 * the default SPI value is sent 00194 * @param tx_length The length of TX buffer in bytes 00195 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00196 * received data are ignored 00197 * @param rx_length The length of RX buffer in bytes 00198 * @param bit_width The buffers element width 00199 * @param callback The event callback function 00200 * @param event The logical OR of events to modify 00201 * @return Zero if a transfer was added to the queue, or -1 if the queue is full 00202 */ 00203 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); 00204 00205 /** Configures a callback, spi peripheral and initiate a new transfer 00206 * 00207 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00208 * the default SPI value is sent 00209 * @param tx_length The length of TX buffer in bytes 00210 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00211 * received data are ignored 00212 * @param rx_length The length of RX buffer in bytes 00213 * @param bit_width The buffers element width 00214 * @param callback The event callback function 00215 * @param event The logical OR of events to modify 00216 */ 00217 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); 00218 00219 #if TRANSACTION_QUEUE_SIZE_SPI 00220 00221 /** Start a new transaction 00222 * 00223 * @param data Transaction data 00224 */ 00225 void start_transaction(transaction_t *data); 00226 00227 /** Dequeue a transaction 00228 * 00229 */ 00230 void dequeue_transaction(); 00231 static CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> _transaction_buffer; 00232 #endif 00233 00234 #endif 00235 00236 public: 00237 virtual ~SPI() { 00238 } 00239 00240 protected: 00241 spi_t _spi; 00242 00243 #if DEVICE_SPI_ASYNCH 00244 CThunk<SPI> _irq; 00245 event_callback_t _callback; 00246 DMAUsage _usage; 00247 #endif 00248 00249 void aquire(void); 00250 static SPI *_owner; 00251 static SingletonPtr<PlatformMutex> _mutex; 00252 int _bits; 00253 int _mode; 00254 int _hz; 00255 }; 00256 00257 } // namespace mbed 00258 00259 #endif 00260 00261 #endif
Generated on Tue Jul 12 2022 22:19:21 by
