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: 00049 * @code 00050 * // Send a byte to a SPI slave, and record the response 00051 * 00052 * #include "mbed.h" 00053 * 00054 * // hardware ssel (where applicable) 00055 * //SPI device(p5, p6, p7, p8); // mosi, miso, sclk, ssel 00056 * 00057 * // software ssel 00058 * SPI device(p5, p6, p7); // mosi, miso, sclk 00059 * DigitalOut cs(p8); // ssel 00060 * 00061 * int main() { 00062 * // hardware ssel (where applicable) 00063 * //int response = device.write(0xFF); 00064 * 00065 * device.lock(); 00066 * // software ssel 00067 * cs = 0; 00068 * int response = device.write(0xFF); 00069 * cs = 1; 00070 * device.unlock(); 00071 * 00072 * } 00073 * @endcode 00074 * @ingroup drivers 00075 */ 00076 class SPI : private NonCopyable<SPI> { 00077 00078 public: 00079 00080 /** Create a SPI master connected to the specified pins 00081 * 00082 * mosi or miso can be specified as NC if not used 00083 * 00084 * @param mosi SPI Master Out, Slave In pin 00085 * @param miso SPI Master In, Slave Out pin 00086 * @param sclk SPI Clock pin 00087 * @param ssel SPI chip select pin 00088 */ 00089 SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel = NC); 00090 00091 /** Configure the data transmission format 00092 * 00093 * @param bits Number of bits per SPI frame (4 - 16) 00094 * @param mode Clock polarity and phase mode (0 - 3) 00095 * 00096 * @code 00097 * mode | POL PHA 00098 * -----+-------- 00099 * 0 | 0 0 00100 * 1 | 0 1 00101 * 2 | 1 0 00102 * 3 | 1 1 00103 * @endcode 00104 */ 00105 void format(int bits, int mode = 0); 00106 00107 /** Set the spi bus clock frequency 00108 * 00109 * @param hz SCLK frequency in hz (default = 1MHz) 00110 */ 00111 void frequency(int hz = 1000000); 00112 00113 /** Write to the SPI Slave and return the response 00114 * 00115 * @param value Data to be sent to the SPI slave 00116 * 00117 * @returns 00118 * Response from the SPI slave 00119 */ 00120 virtual int write(int value); 00121 00122 /** Write to the SPI Slave and obtain the response 00123 * 00124 * The total number of bytes sent and received will be the maximum of 00125 * tx_length and rx_length. The bytes written will be padded with the 00126 * value 0xff. 00127 * 00128 * @param tx_buffer Pointer to the byte-array of data to write to the device 00129 * @param tx_length Number of bytes to write, may be zero 00130 * @param rx_buffer Pointer to the byte-array of data to read from the device 00131 * @param rx_length Number of bytes to read, may be zero 00132 * @returns 00133 * The number of bytes written and read from the device. This is 00134 * maximum of tx_length and rx_length. 00135 */ 00136 virtual int write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length); 00137 00138 /** Acquire exclusive access to this SPI bus 00139 */ 00140 virtual void lock(void); 00141 00142 /** Release exclusive access to this SPI bus 00143 */ 00144 virtual void unlock(void); 00145 00146 /** Set default write data 00147 * SPI requires the master to send some data during a read operation. 00148 * Different devices may require different default byte values. 00149 * For example: A SD Card requires default bytes to be 0xFF. 00150 * 00151 * @param data Default character to be transmitted while read operation 00152 */ 00153 void set_default_write_value(char data); 00154 00155 #if DEVICE_SPI_ASYNCH 00156 00157 /** Start non-blocking SPI transfer using 8bit buffers. 00158 * 00159 * This function locks the deep sleep until any event has occurred 00160 * 00161 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00162 * the default SPI value is sent 00163 * @param tx_length The length of TX buffer in bytes 00164 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00165 * received data are ignored 00166 * @param rx_length The length of RX buffer in bytes 00167 * @param callback The event callback function 00168 * @param event The logical OR of events to modify. Look at spi hal header file for SPI events. 00169 * @return Zero if the transfer has started, or -1 if SPI peripheral is busy 00170 */ 00171 template<typename Type> 00172 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) 00173 { 00174 if (spi_active(&_spi)) { 00175 return queue_transfer (tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type) * 8, callback, event); 00176 } 00177 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type) * 8, callback, event); 00178 return 0; 00179 } 00180 00181 /** Abort the on-going SPI transfer, and continue with transfer's in the queue if any. 00182 */ 00183 void abort_transfer(); 00184 00185 /** Clear the transaction buffer 00186 */ 00187 void clear_transfer_buffer(); 00188 00189 /** Clear the transaction buffer and abort on-going transfer. 00190 */ 00191 void abort_all_transfers(); 00192 00193 /** Configure DMA usage suggestion for non-blocking transfers 00194 * 00195 * @param usage The usage DMA hint for peripheral 00196 * @return Zero if the usage was set, -1 if a transaction is on-going 00197 */ 00198 int set_dma_usage(DMAUsage usage); 00199 00200 protected: 00201 /** SPI IRQ handler 00202 * 00203 */ 00204 void irq_handler_asynch(void); 00205 00206 /** Common transfer method 00207 * 00208 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00209 * the default SPI value is sent 00210 * @param tx_length The length of TX buffer in bytes 00211 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00212 * received data are ignored 00213 * @param rx_length The length of RX buffer in bytes 00214 * @param bit_width The buffers element width 00215 * @param callback The event callback function 00216 * @param event The logical OR of events to modify 00217 * @return Zero if the transfer has started or was added to the queue, or -1 if SPI peripheral is busy/buffer is full 00218 */ 00219 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); 00220 00221 /** 00222 * 00223 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00224 * the default SPI value is sent 00225 * @param tx_length The length of TX buffer in bytes 00226 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00227 * received data are ignored 00228 * @param rx_length The length of RX buffer in bytes 00229 * @param bit_width The buffers element width 00230 * @param callback The event callback function 00231 * @param event The logical OR of events to modify 00232 * @return Zero if a transfer was added to the queue, or -1 if the queue is full 00233 */ 00234 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); 00235 00236 /** Configures a callback, spi peripheral and initiate a new transfer 00237 * 00238 * @param tx_buffer The TX buffer with data to be transfered. 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 00245 * @param callback The event callback function 00246 * @param event The logical OR of events to modify 00247 */ 00248 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); 00249 00250 private: 00251 /** Lock deep sleep only if it is not yet locked */ 00252 void lock_deep_sleep(); 00253 00254 /** Unlock deep sleep in case it is locked */ 00255 void unlock_deep_sleep(); 00256 00257 00258 #if TRANSACTION_QUEUE_SIZE_SPI 00259 00260 /** Start a new transaction 00261 * 00262 * @param data Transaction data 00263 */ 00264 void start_transaction(transaction_t *data); 00265 00266 /** Dequeue a transaction 00267 * 00268 */ 00269 void dequeue_transaction(); 00270 static CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> _transaction_buffer; 00271 #endif 00272 00273 #endif 00274 00275 public: 00276 virtual ~SPI() 00277 { 00278 } 00279 00280 protected: 00281 spi_t _spi; 00282 00283 #if DEVICE_SPI_ASYNCH 00284 CThunk<SPI> _irq; 00285 event_callback_t _callback; 00286 DMAUsage _usage; 00287 bool _deep_sleep_locked; 00288 #endif 00289 00290 void aquire(void); 00291 static SPI *_owner; 00292 static SingletonPtr<PlatformMutex> _mutex; 00293 int _bits; 00294 int _mode; 00295 int _hz; 00296 char _write_fill; 00297 00298 private: 00299 /* Private acquire function without locking/unlocking 00300 * Implemented in order to avoid duplicate locking and boost performance 00301 */ 00302 void _acquire(void); 00303 }; 00304 00305 } // namespace mbed 00306 00307 #endif 00308 00309 #endif
Generated on Tue Jul 12 2022 13:53:16 by
1.7.2