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.
Dependencies: nRF51_Vdd TextLCD BME280
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 15:15:59 by
