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