Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spi_api.h Source File

spi_api.h

00001 
00002 /** \addtogroup hal */
00003 /** @{*/
00004 /* mbed Microcontroller Library
00005  * Copyright (c) 2006-2013 ARM Limited
00006  * SPDX-License-Identifier: Apache-2.0
00007  *
00008  * Licensed under the Apache License, Version 2.0 (the "License");
00009  * you may not use this file except in compliance with the License.
00010  * You may obtain a copy of the License at
00011  *
00012  *     http://www.apache.org/licenses/LICENSE-2.0
00013  *
00014  * Unless required by applicable law or agreed to in writing, software
00015  * distributed under the License is distributed on an "AS IS" BASIS,
00016  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00017  * See the License for the specific language governing permissions and
00018  * limitations under the License.
00019  */
00020 #ifndef MBED_SPI_API_H
00021 #define MBED_SPI_API_H
00022 
00023 #include "device.h"
00024 #include "pinmap.h"
00025 #include "hal/dma_api.h"
00026 #include "hal/buffer.h"
00027 
00028 #if DEVICE_SPI
00029 
00030 #define SPI_EVENT_ERROR       (1 << 1)
00031 #define SPI_EVENT_COMPLETE    (1 << 2)
00032 #define SPI_EVENT_RX_OVERFLOW (1 << 3)
00033 #define SPI_EVENT_ALL         (SPI_EVENT_ERROR | SPI_EVENT_COMPLETE | SPI_EVENT_RX_OVERFLOW)
00034 
00035 #define SPI_EVENT_INTERNAL_TRANSFER_COMPLETE (1 << 30) // Internal flag to report that an event occurred
00036 
00037 #define SPI_FILL_WORD         (0xFFFF)
00038 #define SPI_FILL_CHAR         (0xFF)
00039 
00040 #if DEVICE_SPI_ASYNCH
00041 /** Asynch SPI HAL structure
00042  */
00043 typedef struct {
00044     struct spi_s spi;        /**< Target specific SPI structure */
00045     struct buffer_s tx_buff; /**< Tx buffer */
00046     struct buffer_s rx_buff; /**< Rx buffer */
00047 } spi_t;
00048 
00049 #else
00050 /** Non-asynch SPI HAL structure
00051  */
00052 typedef struct spi_s spi_t;
00053 
00054 #endif
00055 
00056 typedef struct {
00057     int peripheral;
00058     PinName mosi_pin;
00059     int mosi_function;
00060     PinName miso_pin;
00061     int miso_function;
00062     PinName sclk_pin;
00063     int sclk_function;
00064     PinName ssel_pin;
00065     int ssel_function;
00066 } spi_pinmap_t;
00067 
00068 /**
00069  * Describes the capabilities of a SPI peripherals
00070  */
00071 typedef struct {
00072     /** Minimum frequency supported must be set by target device and it will be assessed during
00073      *  testing.
00074      */
00075     uint32_t    minimum_frequency;
00076     /** Maximum frequency supported must be set by target device and it will be assessed during
00077      *  testing.
00078      */
00079     uint32_t    maximum_frequency;
00080     /** Each bit represents the corresponding word length. lsb => 1bit, msb => 32bit. */
00081     uint32_t    word_length;
00082     uint16_t    slave_delay_between_symbols_ns; /**< specifies required number of ns between transmission of successive symbols in slave mode. */
00083     uint8_t     clk_modes; /**< specifies supported modes from spi_mode_t. Each bit represents the corresponding mode. */
00084     bool        support_slave_mode; /**< If true, the device can handle SPI slave mode using hardware management on the specified ssel pin. */
00085     bool        hw_cs_handle; /**< If true, in SPI master mode Chip Select can be handled by hardware. */
00086     bool        async_mode; /**< If true, in async mode is supported. */
00087 
00088 } spi_capabilities_t;
00089 
00090 #ifdef __cplusplus
00091 extern "C" {
00092 #endif
00093 
00094 /**
00095  * \defgroup hal_GeneralSPI SPI Configuration Functions
00096  *
00097  * # Defined behavior
00098  * * ::spi_init initializes the spi_t control structure
00099  * * ::spi_init configures the pins used by SPI
00100  * * ::spi_get_capabilities() fills the given `spi_capabilities_t` instance
00101  * * ::spi_get_capabilities() should consider the `ssel` pin when evaluation the `support_slave_mode` and `hw_cs_handle` capability
00102  * * ::spi_get_capabilities(): if the given `ssel` pin cannot be managed by hardware, `support_slave_mode` and `hw_cs_handle` should be false
00103  * * At least a symbol width of 8bit must be supported
00104  * * The supported frequency range must include the range [0.2..2] MHz
00105  * * ::spi_free returns the pins owned by the SPI object to their reset state
00106  * * ::spi_format sets the number of bits per frame
00107  * * ::spi_format configures clock polarity and phase
00108  * * ::spi_format configures master/slave mode
00109  * * ::spi_frequency sets the SPI baud rate
00110  * * ::spi_master_write writes a symbol out in master mode and receives a symbol
00111  * * ::spi_master_block_write writes `tx_length` words to the bus
00112  * * ::spi_master_block_write reads `rx_length` words from the bus
00113  * * ::spi_master_block_write returns the maximum of tx_length and rx_length
00114  * * ::spi_master_block_write specifies the write_fill which is default data transmitted while performing a read
00115  * * ::spi_get_module returns non-zero if a value is available to read from SPI channel, 0 otherwise
00116  * * ::spi_slave_read returns a received value out of the SPI receive buffer in slave mode
00117  * * ::spi_slave_read blocks until a value is available
00118  * * ::spi_slave_write writes a value to the SPI peripheral in slave mode
00119  * * ::spi_slave_write blocks until the SPI peripheral can be written to
00120  * * ::spi_busy returns non-zero if the peripheral is currently transmitting, 0 otherwise
00121  * * ::spi_master_transfer starts the SPI asynchronous transfer
00122  * * ::spi_master_transfer writes `tx_len` words to the bus
00123  * * ::spi_master_transfer reads `rx_len` words from the bus
00124  * * ::spi_master_transfer specifies the bit width of buffer words
00125  * * The callback given to ::spi_master_transfer is invoked when the transfer completes (with a success or an error)
00126  * * ::spi_master_transfer specifies the logical OR of events to be registered
00127  * * The ::spi_master_transfer function may use the `DMAUsage` hint to select the appropriate async algorithm
00128  * * ::spi_irq_handler_asynch reads the received values out of the RX FIFO
00129  * * ::spi_irq_handler_asynch writes values into the TX FIFO
00130  * * ::spi_irq_handler_asynch checks for transfer termination conditions, such as buffer overflows or transfer complete
00131  * * ::spi_irq_handler_asynch returns event flags if a transfer termination condition was met, otherwise 0
00132  * * ::spi_abort_asynch aborts an on-going async transfer
00133  * * ::spi_active returns non-zero if the SPI port is active or zero if it is not
00134  *
00135  * # Undefined behavior
00136  * * Calling ::spi_init multiple times on the same `spi_t` without ::spi_free
00137  * * Calling any function other than ::spi_init on a non-initialized or freed `spi_t`
00138  * * Passing pins that cannot be on the same peripheral
00139  * * Passing an invalid pointer as `obj` to any function
00140  * * Passing an invalid pointer as `handler` to ::spi_master_transfer
00141  * * Calling ::spi_abort while no async transfer is being processed (no transfer or a synchronous transfer)
00142  *
00143  * @{
00144  */
00145 
00146 /**
00147  * \defgroup hal_GeneralSPI_tests SPI hal tests
00148  * The SPI HAL tests ensure driver conformance to defined behaviour.
00149  *
00150  * To run the SPI hal tests use the command:
00151  *
00152  *     mbed test -t <toolchain> -m <target> -n tests-mbed_hal_fpga_ci_test_shield-spi
00153  *
00154  */
00155 
00156 #ifdef DEVICE_SPI_COUNT
00157 /**
00158  * Returns a variant of the SPIName enum uniquely identifying a SPI peripheral of the device.
00159  * @param[in]  mosi The pin to use for MOSI
00160  * @param[in]  miso The pin to use for MISO
00161  * @param[in]  sclk The pin to use for SCLK
00162  * @return     An SPI peripheral identifier
00163  */
00164 SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName mclk);
00165 #endif
00166 
00167 /**
00168  * Fills the given spi_capabilities_t structure with the capabilities of the given peripheral.
00169  */
00170 void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap);
00171 
00172 /** Initialize the SPI peripheral
00173  *
00174  * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
00175  * @param[out] obj  The SPI object to initialize
00176  * @param[in]  pinmap pointer to structure which holds static pinmap
00177  */
00178 void spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap);
00179 
00180 /** Initialize the SPI peripheral
00181  *
00182  * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
00183  * @param[out] obj  The SPI object to initialize
00184  * @param[in]  mosi The pin to use for MOSI
00185  * @param[in]  miso The pin to use for MISO
00186  * @param[in]  sclk The pin to use for SCLK
00187  * @param[in]  ssel The pin to use for SSEL
00188  */
00189 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel);
00190 
00191 /** Release a SPI object
00192  *
00193  * TODO: spi_free is currently unimplemented
00194  * This will require reference counting at the C++ level to be safe
00195  *
00196  * Return the pins owned by the SPI object to their reset state
00197  * Disable the SPI peripheral
00198  * Disable the SPI clock
00199  * @param[in] obj The SPI object to deinitialize
00200  */
00201 void spi_free(spi_t *obj);
00202 
00203 /** Configure the SPI format
00204  *
00205  * Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode.
00206  * The default bit order is MSB.
00207  * @param[in,out] obj   The SPI object to configure
00208  * @param[in]     bits  The number of bits per frame
00209  * @param[in]     mode  The SPI mode (clock polarity, phase, and shift direction)
00210  * @param[in]     slave Zero for master mode or non-zero for slave mode
00211  */
00212 void spi_format(spi_t *obj, int bits, int mode, int slave);
00213 
00214 /** Set the SPI baud rate
00215  *
00216  * Actual frequency may differ from the desired frequency due to available dividers and bus clock
00217  * Configures the SPI peripheral's baud rate
00218  * @param[in,out] obj The SPI object to configure
00219  * @param[in]     hz  The baud rate in Hz
00220  */
00221 void spi_frequency(spi_t *obj, int hz);
00222 
00223 /**@}*/
00224 /**
00225  * \defgroup SynchSPI Synchronous SPI Hardware Abstraction Layer
00226  * @{
00227  */
00228 
00229 /** Write a byte out in master mode and receive a value
00230  *
00231  * @param[in] obj   The SPI peripheral to use for sending
00232  * @param[in] value The value to send
00233  * @return Returns the value received during send
00234  */
00235 int  spi_master_write(spi_t *obj, int value);
00236 
00237 /** Write a block out in master mode and receive a value
00238  *
00239  *  The total number of bytes sent and received will be the maximum of
00240  *  tx_length and rx_length. The bytes written will be padded with the
00241  *  value 0xff.
00242  *
00243  * @param[in] obj        The SPI peripheral to use for sending
00244  * @param[in] tx_buffer  Pointer to the byte-array of data to write to the device
00245  * @param[in] tx_length  Number of bytes to write, may be zero
00246  * @param[in] rx_buffer  Pointer to the byte-array of data to read from the device
00247  * @param[in] rx_length  Number of bytes to read, may be zero
00248  * @param[in] write_fill Default data transmitted while performing a read
00249  * @returns
00250  *      The number of bytes written and read from the device. This is
00251  *      maximum of tx_length and rx_length.
00252  */
00253 int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill);
00254 
00255 /** Check if a value is available to read
00256  *
00257  * @param[in] obj The SPI peripheral to check
00258  * @return non-zero if a value is available
00259  */
00260 int  spi_slave_receive(spi_t *obj);
00261 
00262 /** Get a received value out of the SPI receive buffer in slave mode
00263  *
00264  * Blocks until a value is available
00265  * @param[in] obj The SPI peripheral to read
00266  * @return The value received
00267  */
00268 int  spi_slave_read(spi_t *obj);
00269 
00270 /** Write a value to the SPI peripheral in slave mode
00271  *
00272  * Blocks until the SPI peripheral can be written to
00273  * @param[in] obj   The SPI peripheral to write
00274  * @param[in] value The value to write
00275  */
00276 void spi_slave_write(spi_t *obj, int value);
00277 
00278 /** Checks if the specified SPI peripheral is in use
00279  *
00280  * @param[in] obj The SPI peripheral to check
00281  * @return non-zero if the peripheral is currently transmitting
00282  */
00283 int  spi_busy(spi_t *obj);
00284 
00285 /** Get the module number
00286  *
00287  * @param[in] obj The SPI peripheral to check
00288  * @return The module number
00289  */
00290 uint8_t spi_get_module(spi_t *obj);
00291 
00292 /** Get the pins that support SPI MOSI
00293  *
00294  * Return a PinMap array of pins that support SPI MOSI in
00295  * master mode. The array is terminated with {NC, NC, 0}.
00296  *
00297  * @return PinMap array
00298  */
00299 const PinMap *spi_master_mosi_pinmap(void);
00300 
00301 /** Get the pins that support SPI MISO
00302  *
00303  * Return a PinMap array of pins that support SPI MISO in
00304  * master mode. The array is terminated with {NC, NC, 0}.
00305  *
00306  * @return PinMap array
00307  */
00308 const PinMap *spi_master_miso_pinmap(void);
00309 
00310 /** Get the pins that support SPI CLK
00311  *
00312  * Return a PinMap array of pins that support SPI CLK in
00313  * master mode. The array is terminated with {NC, NC, 0}.
00314  *
00315  * @return PinMap array
00316  */
00317 const PinMap *spi_master_clk_pinmap(void);
00318 
00319 /** Get the pins that support SPI CS
00320  *
00321  * Return a PinMap array of pins that support SPI CS in
00322  * master mode. The array is terminated with {NC, NC, 0}.
00323  *
00324  * @return PinMap array
00325  */
00326 const PinMap *spi_master_cs_pinmap(void);
00327 
00328 /** Get the pins that support SPI MOSI
00329  *
00330  * Return a PinMap array of pins that support SPI MOSI in
00331  * slave mode. The array is terminated with {NC, NC, 0}.
00332  *
00333  * @return PinMap array
00334  */
00335 const PinMap *spi_slave_mosi_pinmap(void);
00336 
00337 /** Get the pins that support SPI MISO
00338  *
00339  * Return a PinMap array of pins that support SPI MISO in
00340  * slave mode. The array is terminated with {NC, NC, 0}.
00341  *
00342  * @return PinMap array
00343  */
00344 const PinMap *spi_slave_miso_pinmap(void);
00345 
00346 /** Get the pins that support SPI CLK
00347  *
00348  * Return a PinMap array of pins that support SPI CLK in
00349  * slave mode. The array is terminated with {NC, NC, 0}.
00350  *
00351  * @return PinMap array
00352  */
00353 const PinMap *spi_slave_clk_pinmap(void);
00354 
00355 /** Get the pins that support SPI CS
00356  *
00357  * Return a PinMap array of pins that support SPI CS in
00358  * slave mode. The array is terminated with {NC, NC, 0}.
00359  *
00360  * @return PinMap array
00361  */
00362 const PinMap *spi_slave_cs_pinmap(void);
00363 
00364 /**@}*/
00365 
00366 #if DEVICE_SPI_ASYNCH
00367 /**
00368  * \defgroup AsynchSPI Asynchronous SPI Hardware Abstraction Layer
00369  * @{
00370  */
00371 
00372 /** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff
00373  *
00374  * @param[in] obj       The SPI object that holds the transfer information
00375  * @param[in] tx        The transmit buffer
00376  * @param[in] tx_length The number of bytes to transmit
00377  * @param[in] rx        The receive buffer
00378  * @param[in] rx_length The number of bytes to receive
00379  * @param[in] bit_width The bit width of buffer words
00380  * @param[in] event     The logical OR of events to be registered
00381  * @param[in] handler   SPI interrupt handler
00382  * @param[in] hint      A suggestion for how to use DMA with this transfer
00383  */
00384 void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint8_t bit_width, uint32_t handler, uint32_t event, DMAUsage hint);
00385 
00386 /** The asynchronous IRQ handler
00387  *
00388  * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination
00389  * conditions, such as buffer overflows or transfer complete.
00390  * @param[in] obj     The SPI object that holds the transfer information
00391  * @return Event flags if a transfer termination condition was met; otherwise 0.
00392  */
00393 uint32_t spi_irq_handler_asynch(spi_t *obj);
00394 
00395 /** Attempts to determine if the SPI peripheral is already in use
00396  *
00397  * If a temporary DMA channel has been allocated, peripheral is in use.
00398  * If a permanent DMA channel has been allocated, check if the DMA channel is in use.  If not, proceed as though no DMA
00399  * channel were allocated.
00400  * If no DMA channel is allocated, check whether tx and rx buffers have been assigned.  For each assigned buffer, check
00401  * if the corresponding buffer position is less than the buffer length.  If buffers do not indicate activity, check if
00402  * there are any bytes in the FIFOs.
00403  * @param[in] obj The SPI object to check for activity
00404  * @return Non-zero if the SPI port is active or zero if it is not.
00405  */
00406 uint8_t spi_active(spi_t *obj);
00407 
00408 /** Abort an SPI transfer
00409  *
00410  * @param obj The SPI peripheral to stop
00411  */
00412 void spi_abort_asynch(spi_t *obj);
00413 
00414 
00415 #endif
00416 
00417 /**@}*/
00418 
00419 #ifdef __cplusplus
00420 }
00421 #endif // __cplusplus
00422 
00423 #endif // SPI_DEVICE
00424 
00425 #endif // MBED_SPI_API_H
00426 
00427 /** @}*/