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.
Fork of mbed-dev by
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 "spi_api.h" 00024 00025 #if DEVICE_SPI_ASYNCH 00026 #include "CThunk.h" 00027 #include "dma_api.h" 00028 #include "CircularBuffer.h" 00029 #include "FunctionPointer.h" 00030 #include "Transaction.h" 00031 #endif 00032 00033 namespace mbed { 00034 00035 /** A SPI Master, used for communicating with SPI slave devices 00036 * 00037 * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz 00038 * 00039 * Most SPI devices will also require Chip Select and Reset signals. These 00040 * can be controlled using <DigitalOut> pins 00041 * 00042 * Example: 00043 * @code 00044 * // Send a byte to a SPI slave, and record the response 00045 * 00046 * #include "mbed.h" 00047 * 00048 * // hardware ssel (where applicable) 00049 * //SPI device(p5, p6, p7, p8); // mosi, miso, sclk, ssel 00050 * 00051 * // software ssel 00052 * SPI device(p5, p6, p7); // mosi, miso, sclk 00053 * DigitalOut cs(p8); // ssel 00054 * 00055 * int main() { 00056 * // hardware ssel (where applicable) 00057 * //int response = device.write(0xFF); 00058 * 00059 * // software ssel 00060 * cs = 0; 00061 * int response = device.write(0xFF); 00062 * cs = 1; 00063 * } 00064 * @endcode 00065 */ 00066 class SPI { 00067 00068 public: 00069 00070 /** Create a SPI master connected to the specified pins 00071 * 00072 * mosi or miso can be specfied as NC if not used 00073 * 00074 * @param mosi SPI Master Out, Slave In pin 00075 * @param miso SPI Master In, Slave Out pin 00076 * @param sclk SPI Clock pin 00077 * @param ssel SPI chip select pin 00078 */ 00079 SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel=NC); 00080 00081 /** Configure the data transmission format 00082 * 00083 * @param bits Number of bits per SPI frame (4 - 16) 00084 * @param mode Clock polarity and phase mode (0 - 3) 00085 * 00086 * @code 00087 * mode | POL PHA 00088 * -----+-------- 00089 * 0 | 0 0 00090 * 1 | 0 1 00091 * 2 | 1 0 00092 * 3 | 1 1 00093 * @endcode 00094 */ 00095 void format(int bits, int mode = 0); 00096 00097 /** Set the spi bus clock frequency 00098 * 00099 * @param hz SCLK frequency in hz (default = 1MHz) 00100 */ 00101 void frequency(int hz = 1000000); 00102 00103 /** Write to the SPI Slave and return the response 00104 * 00105 * @param value Data to be sent to the SPI slave 00106 * 00107 * @returns 00108 * Response from the SPI slave 00109 */ 00110 virtual int write(int value); 00111 00112 #if DEVICE_SPI_ASYNCH 00113 00114 /** Start non-blocking SPI transfer using 8bit buffers. 00115 * 00116 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00117 * the default SPI value is sent 00118 * @param tx_length The length of TX buffer in bytes 00119 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00120 * received data are ignored 00121 * @param rx_length The length of RX buffer in bytes 00122 * @param callback The event callback function 00123 * @param event The logical OR of events to modify. Look at spi hal header file for SPI events. 00124 * @return Zero if the transfer has started, or -1 if SPI peripheral is busy 00125 */ 00126 template<typename Type> 00127 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) { 00128 if (spi_active(&_spi)) { 00129 return queue_transfer (tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event); 00130 } 00131 start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event); 00132 return 0; 00133 } 00134 00135 /** Abort the on-going SPI transfer, and continue with transfer's in the queue if any. 00136 */ 00137 void abort_transfer(); 00138 00139 /** Clear the transaction buffer 00140 */ 00141 void clear_transfer_buffer(); 00142 00143 /** Clear the transaction buffer and abort on-going transfer. 00144 */ 00145 void abort_all_transfers(); 00146 00147 /** Configure DMA usage suggestion for non-blocking transfers 00148 * 00149 * @param usage The usage DMA hint for peripheral 00150 * @return Zero if the usage was set, -1 if a transaction is on-going 00151 */ 00152 int set_dma_usage(DMAUsage usage); 00153 00154 protected: 00155 /** SPI IRQ handler 00156 * 00157 */ 00158 void irq_handler_asynch(void); 00159 00160 /** Common transfer method 00161 * 00162 * @param tx_buffer The TX buffer with data to be transfered. If NULL is passed, 00163 * the default SPI value is sent 00164 * @param tx_length The length of TX buffer in bytes 00165 * @param rx_buffer The RX buffer which is used for received data. If NULL is passed, 00166 * received data are ignored 00167 * @param rx_length The length of RX buffer in bytes 00168 * @param bit_width The buffers element width 00169 * @param callback The event callback function 00170 * @param event The logical OR of events to modify 00171 * @return Zero if the transfer has started or was added to the queue, or -1 if SPI peripheral is busy/buffer is full 00172 */ 00173 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); 00174 00175 /** 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 a transfer was added to the queue, or -1 if the queue is full 00187 */ 00188 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); 00189 00190 /** Configures a callback, spi peripheral and initiate a new transfer 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 */ 00202 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); 00203 00204 #if TRANSACTION_QUEUE_SIZE_SPI 00205 00206 /** Start a new transaction 00207 * 00208 * @param data Transaction data 00209 */ 00210 void start_transaction(transaction_t *data); 00211 00212 /** Dequeue a transaction 00213 * 00214 */ 00215 void dequeue_transaction(); 00216 static CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> _transaction_buffer; 00217 #endif 00218 00219 #endif 00220 00221 public: 00222 virtual ~SPI() { 00223 } 00224 00225 protected: 00226 spi_t _spi; 00227 00228 #if DEVICE_SPI_ASYNCH 00229 CThunk<SPI> _irq; 00230 event_callback_t _callback; 00231 DMAUsage _usage; 00232 #endif 00233 00234 void aquire(void); 00235 static SPI *_owner; 00236 int _bits; 00237 int _mode; 00238 int _hz; 00239 }; 00240 00241 } // namespace mbed 00242 00243 #endif 00244 00245 #endif
Generated on Tue Jul 12 2022 18:56:14 by
