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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 /** @}*/
Generated on Tue Jul 12 2022 13:54:51 by
