Mistake on this page?
Report an issue in GitHub or email us
spi_api.h
1 
2 /** \addtogroup hal */
3 /** @{*/
4 /* mbed Microcontroller Library
5  * Copyright (c) 2006-2013 ARM Limited
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 #ifndef MBED_SPI_API_H
21 #define MBED_SPI_API_H
22 
23 #include "device.h"
24 #include "pinmap.h"
25 #include "hal/dma_api.h"
26 #include "hal/buffer.h"
27 
28 #if DEVICE_SPI
29 
30 #define SPI_EVENT_ERROR (1 << 1)
31 #define SPI_EVENT_COMPLETE (1 << 2)
32 #define SPI_EVENT_RX_OVERFLOW (1 << 3)
33 #define SPI_EVENT_ALL (SPI_EVENT_ERROR | SPI_EVENT_COMPLETE | SPI_EVENT_RX_OVERFLOW)
34 
35 #define SPI_EVENT_INTERNAL_TRANSFER_COMPLETE (1 << 30) // Internal flag to report that an event occurred
36 
37 #define SPI_FILL_WORD (0xFFFF)
38 #define SPI_FILL_CHAR (0xFF)
39 
40 #if DEVICE_SPI_ASYNCH
41 /** Asynch SPI HAL structure
42  */
43 typedef struct {
44  struct spi_s spi; /**< Target specific SPI structure */
45  struct buffer_s tx_buff; /**< Tx buffer */
46  struct buffer_s rx_buff; /**< Rx buffer */
47 } spi_t;
48 
49 #else
50 /** Non-asynch SPI HAL structure
51  */
52 typedef struct spi_s spi_t;
53 
54 #endif
55 
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
60 /**
61  * \defgroup hal_GeneralSPI SPI Configuration Functions
62  *
63  * # Defined behavior
64  * * ::spi_init initializes the spi_t control structure
65  * * ::spi_init configures the pins used by SPI
66  * * ::spi_free returns the pins owned by the SPI object to their reset state
67  * * ::spi_format sets the number of bits per frame
68  * * ::spi_format configures clock polarity and phase
69  * * ::spi_format configures master/slave mode
70  * * ::spi_frequency sets the SPI baud rate
71  * * ::spi_master_write writes a symbol out in master mode and receives a symbol
72  * * ::spi_master_block_write writes `tx_length` words to the bus
73  * * ::spi_master_block_write reads `rx_length` words from the bus
74  * * ::spi_master_block_write returns the maximum of tx_length and rx_length
75  * * ::spi_master_block_write specifies the write_fill which is default data transmitted while performing a read
76  * * ::spi_get_module returns non-zero if a value is available to read from SPI channel, 0 otherwise
77  * * ::spi_slave_read returns a received value out of the SPI receive buffer in slave mode
78  * * ::spi_slave_read blocks until a value is available
79  * * ::spi_slave_write writes a value to the SPI peripheral in slave mode
80  * * ::spi_slave_write blocks until the SPI peripheral can be written to
81  * * ::spi_busy returns non-zero if the peripheral is currently transmitting, 0 otherwise
82  * * ::spi_master_transfer starts the SPI asynchronous transfer
83  * * ::spi_master_transfer writes `tx_len` words to the bus
84  * * ::spi_master_transfer reads `rx_len` words from the bus
85  * * ::spi_master_transfer specifies the bit width of buffer words
86  * * The callback given to ::spi_master_transfer is invoked when the transfer completes (with a success or an error)
87  * * ::spi_master_transfer specifies the logical OR of events to be registered
88  * * The ::spi_master_transfer function may use the `DMAUsage` hint to select the appropriate async algorithm
89  * * ::spi_irq_handler_asynch reads the received values out of the RX FIFO
90  * * ::spi_irq_handler_asynch writes values into the TX FIFO
91  * * ::spi_irq_handler_asynch checks for transfer termination conditions, such as buffer overflows or transfer complete
92  * * ::spi_irq_handler_asynch returns event flags if a transfer termination condition was met, otherwise 0
93  * * ::spi_abort_asynch aborts an on-going async transfer
94  * * ::spi_active returns non-zero if the SPI port is active or zero if it is not
95  *
96  * # Undefined behavior
97  * * Calling ::spi_init multiple times on the same `spi_t` without ::spi_free
98  * * Calling any function other than ::spi_init on a non-initialized or freed `spi_t`
99  * * Passing pins that cannot be on the same peripheral
100  * * Passing an invalid pointer as `obj` to any function
101  * * Passing an invalid pointer as `handler` to ::spi_master_transfer
102  * * Calling ::spi_abort while no async transfer is being processed (no transfer or a synchronous transfer)
103  *
104  * @{
105  */
106 
107 /**
108  * \defgroup hal_GeneralSPI_tests SPI hal tests
109  * The SPI HAL tests ensure driver conformance to defined behaviour.
110  *
111  * To run the SPI hal tests use the command:
112  *
113  * mbed test -t <toolchain> -m <target> -n tests-mbed_hal_fpga_ci_test_shield-spi
114  *
115  */
116 
117 #ifdef DEVICE_SPI_COUNT
118 /**
119  * Returns a variant of the SPIName enum uniquely identifying a SPI peripheral of the device.
120  * @param[in] mosi The pin to use for MOSI
121  * @param[in] miso The pin to use for MISO
122  * @param[in] sclk The pin to use for SCLK
123  * @return An SPI peripheral identifier
124  */
125 SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName mclk);
126 #endif
127 
128 /** Initialize the SPI peripheral
129  *
130  * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
131  * @param[out] obj The SPI object to initialize
132  * @param[in] mosi The pin to use for MOSI
133  * @param[in] miso The pin to use for MISO
134  * @param[in] sclk The pin to use for SCLK
135  * @param[in] ssel The pin to use for SSEL
136  */
137 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel);
138 
139 /** Release a SPI object
140  *
141  * TODO: spi_free is currently unimplemented
142  * This will require reference counting at the C++ level to be safe
143  *
144  * Return the pins owned by the SPI object to their reset state
145  * Disable the SPI peripheral
146  * Disable the SPI clock
147  * @param[in] obj The SPI object to deinitialize
148  */
149 void spi_free(spi_t *obj);
150 
151 /** Configure the SPI format
152  *
153  * Set the number of bits per frame, configure clock polarity and phase, shift order and master/slave mode.
154  * The default bit order is MSB.
155  * @param[in,out] obj The SPI object to configure
156  * @param[in] bits The number of bits per frame
157  * @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
158  * @param[in] slave Zero for master mode or non-zero for slave mode
159  */
160 void spi_format(spi_t *obj, int bits, int mode, int slave);
161 
162 /** Set the SPI baud rate
163  *
164  * Actual frequency may differ from the desired frequency due to available dividers and bus clock
165  * Configures the SPI peripheral's baud rate
166  * @param[in,out] obj The SPI object to configure
167  * @param[in] hz The baud rate in Hz
168  */
169 void spi_frequency(spi_t *obj, int hz);
170 
171 /**@}*/
172 /**
173  * \defgroup SynchSPI Synchronous SPI Hardware Abstraction Layer
174  * @{
175  */
176 
177 /** Write a byte out in master mode and receive a value
178  *
179  * @param[in] obj The SPI peripheral to use for sending
180  * @param[in] value The value to send
181  * @return Returns the value received during send
182  */
183 int spi_master_write(spi_t *obj, int value);
184 
185 /** Write a block out in master mode and receive a value
186  *
187  * The total number of bytes sent and received will be the maximum of
188  * tx_length and rx_length. The bytes written will be padded with the
189  * value 0xff.
190  *
191  * @param[in] obj The SPI peripheral to use for sending
192  * @param[in] tx_buffer Pointer to the byte-array of data to write to the device
193  * @param[in] tx_length Number of bytes to write, may be zero
194  * @param[in] rx_buffer Pointer to the byte-array of data to read from the device
195  * @param[in] rx_length Number of bytes to read, may be zero
196  * @param[in] write_fill Default data transmitted while performing a read
197  * @returns
198  * The number of bytes written and read from the device. This is
199  * maximum of tx_length and rx_length.
200  */
201 int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill);
202 
203 /** Check if a value is available to read
204  *
205  * @param[in] obj The SPI peripheral to check
206  * @return non-zero if a value is available
207  */
208 int spi_slave_receive(spi_t *obj);
209 
210 /** Get a received value out of the SPI receive buffer in slave mode
211  *
212  * Blocks until a value is available
213  * @param[in] obj The SPI peripheral to read
214  * @return The value received
215  */
216 int spi_slave_read(spi_t *obj);
217 
218 /** Write a value to the SPI peripheral in slave mode
219  *
220  * Blocks until the SPI peripheral can be written to
221  * @param[in] obj The SPI peripheral to write
222  * @param[in] value The value to write
223  */
224 void spi_slave_write(spi_t *obj, int value);
225 
226 /** Checks if the specified SPI peripheral is in use
227  *
228  * @param[in] obj The SPI peripheral to check
229  * @return non-zero if the peripheral is currently transmitting
230  */
231 int spi_busy(spi_t *obj);
232 
233 /** Get the module number
234  *
235  * @param[in] obj The SPI peripheral to check
236  * @return The module number
237  */
238 uint8_t spi_get_module(spi_t *obj);
239 
240 /** Get the pins that support SPI MOSI
241  *
242  * Return a PinMap array of pins that support SPI MOSI in
243  * master mode. The array is terminated with {NC, NC, 0}.
244  *
245  * @return PinMap array
246  */
247 const PinMap *spi_master_mosi_pinmap(void);
248 
249 /** Get the pins that support SPI MISO
250  *
251  * Return a PinMap array of pins that support SPI MISO in
252  * master mode. The array is terminated with {NC, NC, 0}.
253  *
254  * @return PinMap array
255  */
256 const PinMap *spi_master_miso_pinmap(void);
257 
258 /** Get the pins that support SPI CLK
259  *
260  * Return a PinMap array of pins that support SPI CLK in
261  * master mode. The array is terminated with {NC, NC, 0}.
262  *
263  * @return PinMap array
264  */
265 const PinMap *spi_master_clk_pinmap(void);
266 
267 /** Get the pins that support SPI CS
268  *
269  * Return a PinMap array of pins that support SPI CS in
270  * master mode. The array is terminated with {NC, NC, 0}.
271  *
272  * @return PinMap array
273  */
274 const PinMap *spi_master_cs_pinmap(void);
275 
276 /** Get the pins that support SPI MOSI
277  *
278  * Return a PinMap array of pins that support SPI MOSI in
279  * slave mode. The array is terminated with {NC, NC, 0}.
280  *
281  * @return PinMap array
282  */
283 const PinMap *spi_slave_mosi_pinmap(void);
284 
285 /** Get the pins that support SPI MISO
286  *
287  * Return a PinMap array of pins that support SPI MISO in
288  * slave mode. The array is terminated with {NC, NC, 0}.
289  *
290  * @return PinMap array
291  */
292 const PinMap *spi_slave_miso_pinmap(void);
293 
294 /** Get the pins that support SPI CLK
295  *
296  * Return a PinMap array of pins that support SPI CLK in
297  * slave mode. The array is terminated with {NC, NC, 0}.
298  *
299  * @return PinMap array
300  */
301 const PinMap *spi_slave_clk_pinmap(void);
302 
303 /** Get the pins that support SPI CS
304  *
305  * Return a PinMap array of pins that support SPI CS in
306  * slave mode. The array is terminated with {NC, NC, 0}.
307  *
308  * @return PinMap array
309  */
310 const PinMap *spi_slave_cs_pinmap(void);
311 
312 /**@}*/
313 
314 #if DEVICE_SPI_ASYNCH
315 /**
316  * \defgroup AsynchSPI Asynchronous SPI Hardware Abstraction Layer
317  * @{
318  */
319 
320 /** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff
321  *
322  * @param[in] obj The SPI object that holds the transfer information
323  * @param[in] tx The transmit buffer
324  * @param[in] tx_length The number of bytes to transmit
325  * @param[in] rx The receive buffer
326  * @param[in] rx_length The number of bytes to receive
327  * @param[in] bit_width The bit width of buffer words
328  * @param[in] event The logical OR of events to be registered
329  * @param[in] handler SPI interrupt handler
330  * @param[in] hint A suggestion for how to use DMA with this transfer
331  */
332 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);
333 
334 /** The asynchronous IRQ handler
335  *
336  * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination
337  * conditions, such as buffer overflows or transfer complete.
338  * @param[in] obj The SPI object that holds the transfer information
339  * @return Event flags if a transfer termination condition was met; otherwise 0.
340  */
341 uint32_t spi_irq_handler_asynch(spi_t *obj);
342 
343 /** Attempts to determine if the SPI peripheral is already in use
344  *
345  * If a temporary DMA channel has been allocated, peripheral is in use.
346  * If a permanent DMA channel has been allocated, check if the DMA channel is in use. If not, proceed as though no DMA
347  * channel were allocated.
348  * If no DMA channel is allocated, check whether tx and rx buffers have been assigned. For each assigned buffer, check
349  * if the corresponding buffer position is less than the buffer length. If buffers do not indicate activity, check if
350  * there are any bytes in the FIFOs.
351  * @param[in] obj The SPI object to check for activity
352  * @return Non-zero if the SPI port is active or zero if it is not.
353  */
354 uint8_t spi_active(spi_t *obj);
355 
356 /** Abort an SPI transfer
357  *
358  * @param obj The SPI peripheral to stop
359  */
360 void spi_abort_asynch(spi_t *obj);
361 
362 
363 #endif
364 
365 /**@}*/
366 
367 #ifdef __cplusplus
368 }
369 #endif // __cplusplus
370 
371 #endif // SPI_DEVICE
372 
373 #endif // MBED_SPI_API_H
374 
375 /** @}*/
uint8_t spi_active(spi_t *obj)
Attempts to determine if the SPI peripheral is already in use.
const PinMap * spi_master_mosi_pinmap(void)
Get the pins that support SPI MOSI.
Generic buffer structure.
Definition: buffer.h:27
uint32_t spi_irq_handler_asynch(spi_t *obj)
The asynchronous IRQ handler.
void spi_slave_write(spi_t *obj, int value)
Write a value to the SPI peripheral in slave mode.
void spi_format(spi_t *obj, int bits, int mode, int slave)
Configure the SPI format.
void spi_frequency(spi_t *obj, int hz)
Set the SPI baud rate.
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)
Begin the SPI transfer.
const PinMap * spi_master_miso_pinmap(void)
Get the pins that support SPI MISO.
const PinMap * spi_master_cs_pinmap(void)
Get the pins that support SPI CS.
const PinMap * spi_master_clk_pinmap(void)
Get the pins that support SPI CLK.
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
Initialize the SPI peripheral.
int spi_slave_read(spi_t *obj)
Get a received value out of the SPI receive buffer in slave mode.
void spi_free(spi_t *obj)
Release a SPI object.
int spi_master_write(spi_t *obj, int value)
Write a byte out in master mode and receive a value.
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, char write_fill)
Write a block out in master mode and receive a value.
const PinMap * spi_slave_cs_pinmap(void)
Get the pins that support SPI CS.
const PinMap * spi_slave_mosi_pinmap(void)
Get the pins that support SPI MOSI.
Definition: pinmap.h:30
void spi_abort_asynch(spi_t *obj)
Abort an SPI transfer.
int spi_slave_receive(spi_t *obj)
Check if a value is available to read.
const PinMap * spi_slave_clk_pinmap(void)
Get the pins that support SPI CLK.
uint8_t spi_get_module(spi_t *obj)
Get the module number.
const PinMap * spi_slave_miso_pinmap(void)
Get the pins that support SPI MISO.
int spi_busy(spi_t *obj)
Checks if the specified SPI peripheral is in use.
Asynch SPI HAL structure.
Definition: spi_api.h:43
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.