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/platform.h" 00020 00021 #if defined (DEVICE_SPI) || defined(DOXYGEN_ONLY) 00022 00023 #include "platform/PlatformMutex.h" 00024 #include "hal/spi_api.h" 00025 #include "platform/SingletonPtr.h" 00026 #include "platform/NonCopyable.h" 00027 00028 #if DEVICE_SPI_ASYNCH 00029 #include "platform/CThunk.h" 00030 #include "hal/dma_api.h" 00031 #include "platform/CircularBuffer.h" 00032 #include "platform/FunctionPointer.h" 00033 #include "platform/Transaction.h" 00034 #endif 00035 00036 namespace mbed { 00037 /** \addtogroup drivers */ 00038 00039 /** A SPI Master, used for communicating with SPI slave devices. 00040 * 00041 * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz. 00042 * 00043 * Most SPI devices will also require Chip Select and Reset signals. These 00044 * can be controlled using DigitalOut pins. 00045 * 00046 * @note Synchronization level: Thread safe 00047 * 00048 * Example of how to send a byte to a SPI slave and record the response: 00049 * @code 00050 * #include "mbed.h" 00051 * 00052 * SPI device(SPI_MOSI, SPI_MISO, SPI_SCLK) 00053 * 00054 * DigitalOut chip_select(SPI_CS); 00055 * 00056 * int main() { 00057 * device.lock(); 00058 * chip_select = 0; 00059 * 00060 * int response = device.write(0xFF); 00061 * 00062 * chip_select = 1; 00063 * device.unlock(); 00064 * } 00065 * @endcode 00066 * 00067 * Example using hardware Chip Select line: 00068 * @code 00069 * #include "mbed.h" 00070 * 00071 * SPI device(SPI_MOSI, SPI_MISO, SPI_SCLK, SPI_CS) 00072 * 00073 * int main() { 00074 * device.lock(); 00075 * int response = device.write(0xFF); 00076 * device.unlock(); 00077 * } 00078 * @endcode 00079 * @ingroup drivers 00080 */ 00081 class SPI : private NonCopyable<SPI> { 00082 00083 public: 00084 00085 /** Create a SPI master connected to the specified pins. 00086 * 00087 * @note You can specify mosi or miso as NC if not used. 00088 * 00089 * @param mosi SPI Master Out, Slave In pin. 00090 * @param miso SPI Master In, Slave Out pin. 00091 * @param sclk SPI Clock pin. 00092 * @param ssel SPI Chip Select pin. 00093 */ 00094 SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel = NC); 00095 virtual ~SPI(); 00096 00097 /** Configure the data transmission format. 00098 * 00099 * @param bits Number of bits per SPI frame (4 - 16). 00100 * @param mode Clock polarity and phase mode (0 - 3). 00101 * 00102 * @code 00103 * mode | POL PHA 00104 * -----+-------- 00105 * 0 | 0 0 00106 * 1 | 0 1 00107 * 2 | 1 0 00108 * 3 | 1 1 00109 * @endcode 00110 */ 00111 void format(int bits, int mode = 0); 00112 00113 /** Set the SPI bus clock frequency. 00114 * 00115 * @param hz Clock frequency in Hz (default = 1MHz). 00116 */ 00117 void frequency(int hz = 1000000); 00118 00119 /** Write to the SPI Slave and return the response. 00120 * 00121 * @param value Data to be sent to the SPI slave. 00122 * 00123 * @return Response from the SPI slave. 00124 */ 00125 virtual int write(int value); 00126 00127 /** Write to the SPI Slave and obtain the response. 00128 * 00129 * The total number of bytes sent and received will be the maximum of 00130 * tx_length and rx_length. The bytes written will be padded with the 00131 * value 0xff. 00132 * 00133 * @param tx_buffer Pointer to the byte-array of data to write to the device. 00134 * @param tx_length Number of bytes to write, may be zero. 00135 * @param rx_buffer Pointer to the byte-array of data to read from the device. 00136 * @param rx_length Number of bytes to read, may be zero. 00137 * @return 00138 * The number of bytes written and read from the device. This is 00139 * maximum of tx_length and rx_length. 00140 */ 00141 virtual int write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length); 00142 00143 /** Acquire exclusive access to this SPI bus. 00144 */ 00145 virtual void lock(void); 00146 00147 /** Release exclusive access to this SPI bus. 00148 */ 00149 virtual void unlock(void); 00150 00151 /** Set default write data. 00152 * SPI requires the master to send some data during a read operation. 00153 * Different devices may require different default byte values. 00154 * For example: A SD Card requires default bytes to be 0xFF. 00155 * 00156 * @param data Default character to be transmitted during a read operation. 00157 */ 00158 void set_default_write_value(char data); 00159 00160 #if DEVICE_SPI_ASYNCH 00161 00162 /** Start non-blocking SPI transfer using 8bit buffers. 00163 * 00164 * This function locks the deep sleep until any event has occurred. 00165 * 00166 * @param tx_buffer The TX buffer with data to be transferred. If NULL is passed, 00167 * the default SPI value is sent. 00168 * @param tx_length The length of TX buffer in bytes. 00169 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00170 * received data are ignored. 00171 * @param rx_length The length of RX buffer in bytes. 00172 * @param callback The event callback function. 00173 * @param event The event mask of events to modify. @see spi_api.h for SPI events. 00174 * 00175 * @return Operation result. 00176 * @retval 0 If the transfer has started. 00177 * @retval -1 If SPI peripheral is busy. 00178 */ 00179 template<typename Type> 00180 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) 00181 { 00182 if (spi_active(&_spi)) { 00183 return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type) * 8, callback, event); 00184 } 00185 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type) * 8, callback, event); 00186 return 0; 00187 } 00188 00189 /** Abort the on-going SPI transfer, and continue with transfers in the queue, if any. 00190 */ 00191 void abort_transfer(); 00192 00193 /** Clear the queue of transfers. 00194 */ 00195 void clear_transfer_buffer(); 00196 00197 /** Clear the queue of transfers and abort the on-going transfer. 00198 */ 00199 void abort_all_transfers(); 00200 00201 /** Configure DMA usage suggestion for non-blocking transfers. 00202 * 00203 * @param usage The usage DMA hint for peripheral. 00204 * 00205 * @return Result of the operation. 00206 * @retval 0 The usage was set. 00207 * @retval -1 Usage cannot be set as there is an ongoing transaction. 00208 */ 00209 int set_dma_usage(DMAUsage usage); 00210 00211 protected: 00212 /** SPI interrupt handler. 00213 */ 00214 void irq_handler_asynch(void); 00215 00216 /** Start the transfer or put it on the queue. 00217 * 00218 * @param tx_buffer The TX buffer with data to be transferred. If NULL is passed, 00219 * the default SPI value is sent 00220 * @param tx_length The length of TX buffer in bytes. 00221 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00222 * received data are ignored. 00223 * @param rx_length The length of RX buffer in bytes. 00224 * @param bit_width The buffers element width in bits. 00225 * @param callback The event callback function. 00226 * @param event The event mask of events to modify. 00227 * 00228 * @return Operation success. 00229 * @retval 0 A transfer was started or added to the queue. 00230 * @retval -1 Transfer can't be added because queue is full. 00231 */ 00232 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); 00233 00234 /** Put a transfer on the transfer queue. 00235 * 00236 * @param tx_buffer The TX buffer with data to be transferred. If NULL is passed, 00237 * the default SPI value is sent. 00238 * @param tx_length The length of TX buffer in bytes. 00239 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00240 * received data are ignored. 00241 * @param rx_length The length of RX buffer in bytes. 00242 * @param bit_width The buffers element width in bits. 00243 * @param callback The event callback function. 00244 * @param event The event mask of events to modify. 00245 * 00246 * @return Operation success. 00247 * @retval 0 A transfer was added to the queue. 00248 * @retval -1 Transfer can't be added because queue is full. 00249 */ 00250 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); 00251 00252 /** Configure a callback, SPI peripheral, and initiate a new transfer. 00253 * 00254 * @param tx_buffer The TX buffer with data to be transferred. If NULL is passed, 00255 * the default SPI value is sent. 00256 * @param tx_length The length of TX buffer in bytes. 00257 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00258 * received data are ignored. 00259 * @param rx_length The length of RX buffer in bytes. 00260 * @param bit_width The buffers element width. 00261 * @param callback The event callback function. 00262 * @param event The event mask of events to modify. 00263 */ 00264 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); 00265 00266 #if !defined(DOXYGEN_ONLY) 00267 00268 private: 00269 /** Lock deep sleep only if it is not yet locked */ 00270 void lock_deep_sleep(); 00271 00272 /** Unlock deep sleep in case it is locked */ 00273 void unlock_deep_sleep(); 00274 00275 00276 #if TRANSACTION_QUEUE_SIZE_SPI 00277 00278 /** Start a new transaction. 00279 * 00280 * @param data Transaction data. 00281 */ 00282 void start_transaction(transaction_t *data); 00283 00284 /** Dequeue a transaction and start the transfer if there was one pending. 00285 */ 00286 void dequeue_transaction(); 00287 00288 /* Queue of pending transfers */ 00289 static CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> _transaction_buffer; 00290 #endif 00291 00292 #endif //!defined(DOXYGEN_ONLY) 00293 00294 #endif //DEVICE_SPI_ASYNCH 00295 00296 #if !defined(DOXYGEN_ONLY) 00297 00298 protected: 00299 /* Internal SPI object identifying the resources */ 00300 spi_t _spi; 00301 00302 #if DEVICE_SPI_ASYNCH 00303 /* Interrupt */ 00304 CThunk<SPI> _irq; 00305 /* Interrupt handler callback */ 00306 event_callback_t _callback; 00307 /* Current preferred DMA mode @see dma_api.h */ 00308 DMAUsage _usage; 00309 /* Current sate of the sleep manager */ 00310 bool _deep_sleep_locked; 00311 #endif 00312 00313 /* Take over the physical SPI and apply our settings (thread safe) */ 00314 void aquire(void); 00315 /* Current user of the SPI */ 00316 static SPI *_owner; 00317 /* Used by lock and unlock for thread safety */ 00318 static SingletonPtr<PlatformMutex> _mutex; 00319 /* Size of the SPI frame */ 00320 int _bits; 00321 /* Clock polairy and phase */ 00322 int _mode; 00323 /* Clock frequency */ 00324 int _hz; 00325 /* Default character used for NULL transfers */ 00326 char _write_fill; 00327 00328 private: 00329 /** Private acquire function without locking/unlocking. 00330 * Implemented in order to avoid duplicate locking and boost performance. 00331 */ 00332 void _acquire(void); 00333 00334 #endif //!defined(DOXYGEN_ONLY) 00335 }; 00336 00337 } // namespace mbed 00338 00339 #endif 00340 00341 #endif
Generated on Tue Jul 12 2022 20:52:57 by
1.7.2