Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI.h Source File

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