SPIWFF3DMA.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024-2025, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*!*****************************************************************************
33  * @file SPIWFF3DMA.h
34  *
35  * @brief SPI driver implementation for a Wi-Fi F3 device SPI
36  * controller using the DMA controller.
37  *
38  * # Driver include #
39  * The SPI header file should be included in an application as follows:
40  * @code
41  * #include <ti/drivers/SPI.h>
42  * #include <ti/drivers/spi/SPIWFF3DMA.h>
43  * #include <ti/drivers/dma/DMAWFF3.h>
44  * @endcode
45  *
46  * Refer to @ref SPI.h for a complete description of APIs.
47  *
48  * Note that the user also needs to include the DMAWFF3.h driver since the SPI
49  * uses DMA in order to improve throughput.
50  *
51  * # Overview #
52  * The general SPI API should be used in application code, i.e. SPI_open()
53  * should be used instead of SPIWFF3DMA_open(). The board file will define the
54  * device specific config, and casting in the general API will ensure that the
55  * correct device specific functions are called. This is also reflected in the
56  * example code in [Use Cases](@ref USE_CASES_SPI_WFF3).
57  *
58  * # General Behavior #
59  * Before using SPI on Wi-Fi F3 devices:
60  * - The SPI driver is initialized by calling SPI_init().
61  * - The SPI HW is configured and flags system dependencies (e.g. IOs, power,
62  * etc.) by calling SPI_open().
63  * - The SPI driver makes use of DMA in order to optimize throughput. This is
64  * handled directly by the SPI driver, so the application should never make
65  * any calls directly to the DMAWFF3.h driver.
66  * - This implementation supports queueing multiple transactions in callback
67  * mode. See the @ref USE_CASE_QUEUE_WFF3 "queueing example."
68  * - When queueing multiple transactions that should transfer one after the
69  * other, it is recommended to use the driver in 'manual start' mode by
70  * using the #SPIWFF3DMA_CMD_SET_MANUAL command. In this mode, the driver
71  * will not start any queued transfers until SPI_control() is called with
72  * the #SPIWFF3DMA_CMD_MANUAL_START command. This mode is off by default and
73  * can be disabled by using command #SPIWFF3DMA_CMD_CLR_MANUAL. See the
74  * @ref USE_CASE_MANUAL_START_WFF3 "Manual Start Example".
75  *
76  * The following is true for peripheral operation:
77  * - RX overrun IRQ, SPI and DMA modules are enabled by calling
78  SPI_transfer().
79  * - All received bytes are ignored after SPI_open() is called, until the
80  * first SPI_transfer().
81  * - If an RX overrun occurs or if SPI_transferCancel() is called, RX overrun
82  IRQ, SPI and DMA modules are disabled, TX and RX FIFOs are flushed and
83  all bytes are ignored.
84  * - After a successful transfer, RX overrun IRQ and SPI module remains
85  enabled and DMA module is disabled. SPI_transfer() must be called again
86  before RX FIFO fills up in order to avoid overflow. If the TX buffer
87  overflows, zeros will be output. It is safe to call another
88  SPI_transfer() from the transfer callback, see [Continuous Peripheral
89  Transfer] (@ref USE_CASE_CST_WFF3) use case below.
90  * - The SPI driver supports partial return, that can be used if the transfer
91  * size is unknown. If #SPIWFF3DMA_CMD_RETURN_PARTIAL_ENABLE is passed to
92  * SPI_control(), the transfer will end when chip select is deasserted. The
93  * #SPI_Transaction.status and the #SPI_Transaction.count will be updated to
94  * indicate whether the transfer ended due to a chip select deassertion and
95  * how many bytes were transferred. See [Peripheral Mode With Return
96  * Partial] (@ref USE_CASE_RP_WFF3) use case below.
97  * - When queueing several transactions if the first is a 'short' transaction
98  * (8 or fewer frames), it is required to use
99  * @ref USE_CASE_MANUAL_START_WFF3 "Manual Start mode."
100  *
101  * The following apply for controller operation:
102  * - SPI and DMA modules are enabled by calling SPI_transfer().
103  * - If the SPI_transfer() succeeds, SPI module is enabled and DMA module is
104  disabled.
105  * - If SPI_transferCancel() is called, SPI and DMA modules are disabled and
106  * TX and RX FIFOs are flushed.
107  *
108  * After SPI operation has ended:
109  * - Release system dependencies for SPI by calling SPI_close().
110  *
111  * The callback function is always called in a SWI context.
112  *
113  * # Error handling #
114  * If an RX overrun occurs during peripheral operation:
115  * - If a transfer is ongoing, all bytes received up until the error occurs
116  will be returned, with the error signaled in the #SPI_Transaction.status
117  field. RX overrun IRQ, SPI and DMA modules are then disabled, TX and RX
118  FIFOs are flushed and all bytes will be ignored until a new transfer is
119  issued.
120  * - If a transfer is not ongoing, RX overrun IRQ, SPI and DMA modules are
121  disabled, TX and RX FIFOs are flushed and all bytes will be ignored until
122  a new transfer is issued.
123  *
124  * # Timeout #
125  * Timeout can occur in #SPI_MODE_BLOCKING, there's no timeout in
126  #SPI_MODE_CALLBACK. When in #SPI_MODE_CALLBACK, the transfer must be
127  cancelled by calling SPI_transferCancel().@n If a timeout happens in either
128  #SPI_PERIPHERAL or #SPI_CONTROLLER mode, the receive buffer will contain the
129  bytes received up until the timeout occurred. The SPI transaction status will
130  be set to #SPI_TRANSFER_FAILED. The SPI transaction count will be set to the
131  number of bytes sent/received before timeout. The remaining bytes will be
132  flushed from the TX FIFO so that the subsequent transfer can be executed
133  correctly. Note that specifying a timeout prevents the driver from performing
134  a polling transfer when in peripheral mode.
135  *
136  * # Power Management #
137  * The TI-RTOS power management framework will try to put the device into the
138  most power efficient mode whenever possible. Please see the technical
139  reference manual for further details on each power mode.
140  *
141  * The SPIWFF3DMA.h driver is setting a power constraint during transfers to
142  keep the device out of sleep. When the transfer has finished, the power
143  constraint is released. The following statements are valid:
144  * - After SPI_open(): the device is still allowed to enter sleep.
145  * - In peripheral mode:
146  * - During SPI_transfer(): the device cannot enter sleep, only idle.
147  * - After an RX overflow: device is allowed to enter sleep.
148  * - After a successful SPI_transfer(): the device is allowed to enter
149  * sleep, but SPI module remains enabled.
150  * - _Note_: In peripheral mode, the device might enter sleep while a
151  byte is being transferred if SPI_transfer() is not called again after
152  a successful transfer. This could result in corrupt data being
153  transferred.
154  * - Application thread should typically either issue another transfer after
155  * SPI_transfer() completes successfully, or call SPI_transferCancel() to
156  * disable the SPI module and thus assuring that no data is received while
157  * entering sleep.
158  * - In controller mode:
159  * - During SPI_transfer(): the device cannot enter sleep, only idle.
160  * - After SPI_transfer() succeeds: the device can enter sleep.
161  * - If SPI_transferCancel() is called: the device can enter sleep.
162  *
163  * @note The external hardware connected to the SPI might have some pull
164  configured on the SPI lines. When the SPI is inactive, this might cause
165  leakage on the IO and the current consumption to increase. The application
166  must configure a pull configuration that aligns with the external hardware.
167  See [Ensure low power during inactive periods] (@ref USE_CASE_LPWR_WFF3) for
168  code example.
169  *
170  * # SPI details #
171  * ## Chip Select #
172  * This SPI controller supports a hardware chip select pin. Refer to the user
173  * manual on how this hardware chip select pin behaves in regards to the SPI
174  * frame format.
175  *
176  * <table>
177  * <tr>
178  * <th>Chip select type</th>
179  * <th>SPI_CONTROLLER mode</th>
180  * <th>SPI_PERIPHERAL mode</th>
181  * </tr>
182  * <tr>
183  * <td>Hardware chip select</td>
184  * <td>No action is needed by the application to select the peripheral.</td>
185  * <td>See the device documentation on it's chip select requirements.</td>
186  * </tr>
187  * <tr>
188  * <td>Software chip select</td>
189  * <td>The application is responsible to ensure that correct SPI peripheral is
190  * selected before performing a SPI_transfer().</td>
191  * <td>See the device documentation on it's chip select requirements.</td>
192  * </tr>
193  * </table>
194  *
195  * ### Multiple peripherals when operating in controller mode #
196  * In a scenario where the SPI module is operating in controller mode with
197  multiple SPI peripherals, the chip select pin can be reallocated at runtime
198  to select the appropriate peripheral device. See [Controller Mode With
199  Multiple Peripherals](@ref USE_CASE_MMMS_WFF3) use case below. This is only
200  relevant when chip select is a hardware chip select. Otherwise the
201  application can control the chip select pins directly using the GPIO driver.
202  *
203  * ## Data Frames #
204  *
205  * SPI data frames can be any size from 4-bits to 16-bits. If the dataSize in
206  * #SPI_Params is greater that 8-bits, then the SPIWFF3DMA driver
207  * implementation will assume that the #SPI_Transaction txBuf and rxBuf point
208  * to an array of 16-bit uint16_t elements.
209  *
210  * dataSize | buffer element size |
211  * -------- | ------------------- |
212  * 4-8 bits | uint8_t |
213  * 9-16 bits | uint16_t |
214  *
215  * ## Bit Rate ##
216  * When the SPI is configured as SPI peripheral, the maximum bit rate is 8MHz.
217  *
218  * When the SPI is configured as SPI controller, the maximum bit rate is 12MHz.
219  *
220  *
221  * ## DMA #
222  * ### Interrupts #
223  * The DMA module generates IRQs on the SPI interrupt vector. This driver
224  automatically installs a DMA aware Hwi (interrupt) to service the assigned
225  DMA channels.
226  *
227  * ### Transfer Size Limit #
228  *
229  * The DMA controller only supports data transfers of up to 16383 bytes.
230  * A transfer with more than 16383 bytes will be transmitted/received in
231  * multiple 16383 sized portions until all data has been transmitted/received.
232  *
233  * ### Scratch Buffers #
234  * A uint16_t scratch buffer is used to allow SPI_transfers where txBuf or
235  rxBuf are NULL. Rather than requiring txBuf or rxBuf to have a dummy buffer
236  of size of the transfer count, a single-word DMA accessible uint16_t
237  scratch buffer is used. When rxBuf is NULL, the DMA will transfer all the
238  received SPI data into the scratch buffer as a "bit-bucket". When txBuf is
239  NULL, the scratch buffer is initialized to defaultTxBufValue so the DMA
240  will send some known value. Each SPI driver instance uses its own scratch
241  buffer.
242  *
243  * ### TX and RX buffers #
244  * Before SPI_transfer, txBuf should be filled with the outgoing SPI data.
245  These data are sent out during the transfer, while the incoming data are
246  received into rxBuf. To save memory space, txBuf and rxBuf can be assigned
247  to the same buffer location. At the beginning of the transfer, this buffer
248  holds outgoing data. At the end of the transfer, the outgoing data are
249  overwritten and the buffer holds the received SPI data.
250  *
251  * ## Polling SPI transfers #
252  * When used in blocking mode small SPI transfers are can be done by polling
253  * the peripheral & sending data frame-by-frame. A controller device can
254  * perform the transfer immediately and return, but a peripheral will block
255  * until it receives the number of frames specified in the SPI_Transfer() call.
256  * The minDmaTransferSize field in the hardware attributes is the threshold; if
257  * the transaction count is below the threshold a polling transfer is
258  * performed; otherwise a DMA transfer is done. This is intended to reduce the
259  * overhead of setting up a DMA transfer to only send a few data frames.
260  *
261  * Notes:
262  * - Specifying a timeout prevents peripheral devices from using polling
263  transfers.
264  * - Keep in mind that during polling transfers the current task is still being
265  * executed; there is no context switch to another task.
266  *
267  * # Supported Functions #
268  * Generic API function | API function | Description
269  * ----------------------|------------------------------- |------------------------------------------------------------
270  * SPI_init() | SPIWFF3DMA_init() | Initialize SPI driver
271  * SPI_open() | SPIWFF3DMA_open() | Initialize SPI HW and set system dependencies
272  * SPI_close() | SPIWFF3DMA_close() | Disable SPI and DMA HW and release system dependencies
273  * SPI_control() | SPIWFF3DMA_control() | Configure an already opened SPI handle
274  * SPI_transfer() | SPIWFF3DMA_transfer() | Start transfer from SPI
275  * SPI_transferCancel() | SPIWFF3DMA_transferCancel() | Cancel ongoing transfer from SPI
276  *
277  * @note All calls should go through the generic API
278  *
279  * ## Use Cases @anchor USE_CASES_SPI_WFF3 ##
280  * ### Basic Peripheral Mode #
281  * Receive 100 bytes over SPI in #SPI_MODE_BLOCKING.
282  * @code
283  * SPI_Handle handle; SPI_Params params; SPI_Transaction transaction; uint8_t
284  * rxBuf[100]; // Receive buffer
285  *
286  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
287  * params.bitRate = 1000000; params.frameFormat = SPI_POL1_PHA1;
288  * params.mode = SPI_PERIPHERAL;
289  *
290  * // Configure the transaction transaction.count = 100; transaction.txBuf =
291  * NULL; transaction.rxBuf = rxBuf;
292  *
293  * // Open the SPI and perform the transfer handle = SPI_open(CONFIG_SPI,
294  * &params); SPI_transfer(handle, &transaction);
295  * @endcode
296  *
297  * ### Peripheral Mode With Return Partial @anchor USE_CASE_RP_WFF3 #
298  * This use case will perform a transfer in #SPI_MODE_BLOCKING until the wanted
299  amount of bytes is transferred or until chip select is deasserted by the SPI
300  controller. This SPI_transfer() call can be used when unknown amount of
301  bytes shall be transferred. Note: The partial return is also possible in
302  #SPI_MODE_CALLBACK mode. Note: Polling transfers are not available when
303  using return partial mode.
304  * @code
305  * SPI_Handle handle; SPI_Params params; SPI_Transaction transaction; uint8_t
306  * rxBuf[100]; // Receive buffer
307  *
308  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
309  * params.bitRate = 1000000; params.frameFormat = SPI_POL1_PHA1;
310  * params.mode = SPI_PERIPHERAL;
311  *
312  * // Configure the transaction transaction.count = 100; transaction.txBuf =
313  * NULL; transaction.rxBuf = rxBuf;
314  *
315  * // Open the SPI and initiate the partial read handle = SPI_open(CONFIG_SPI,
316  * &params);
317  *
318  * // Enable RETURN_PARTIAL SPI_control(handle,
319  * SPIWFF3DMA_RETURN_PARTIAL_ENABLE, NULL);
320  *
321  * // Begin transfer SPI_transfer(handle, &transaction);
322  * @endcode
323  *
324  * ### Continuous Peripheral Transfer In #SPI_MODE_CALLBACK @anchor USE_CASE_CST_WFF3 #
325  * This use case will configure the SPI driver to transfer continuously in
326  * #SPI_MODE_CALLBACK, 16 bytes at the time and echoing received data after
327  * every 16 bytes.
328  * @code
329  * // Callback function static void transferCallback(SPI_Handle handle,
330  * SPI_Transaction *transaction)
331  * {
332  * // Start another transfer
333  * SPI_transfer(handle, transaction);
334  * }
335  *
336  * static void taskFxn(uintptr_t a0, uintptr_t a1)
337  * {
338  * SPI_Handle handle;
339  * SPI_Params params;
340  * SPI_Transaction transaction;
341  * uint8_t buf[16]; // Receive and transmit buffer
342  *
343  * // Init SPI and specify non-default parameters
344  * SPI_Params_init(&params);
345  * params.bitRate = 1000000;
346  * params.frameFormat = SPI_POL1_PHA1;
347  * params.mode = SPI_PERIPHERAL;
348  * params.transferMode = SPI_MODE_CALLBACK;
349  * params.transferCallbackFxn = transferCallback;
350  *
351  * // Configure the transaction
352  * transaction.count = 16;
353  * transaction.txBuf = buf;
354  * transaction.rxBuf = buf;
355  *
356  * // Open the SPI and initiate the first transfer
357  * handle = SPI_open(CONFIG_SPI, &params);
358  * SPI_transfer(handle, &transaction);
359  *
360  * // Wait forever
361  * while(true);
362  * }
363  * @endcode
364  *
365  * ### Basic Controller Mode #
366  * This use case will configure a SPI controller to send the data in txBuf
367  while receiving data to rxBuf in BLOCKING_MODE.
368  * @code
369  * SPI_Handle handle; SPI_Params params; SPI_Transaction transaction; uint8_t
370  * txBuf[] = "Hello World"; // Transmit buffer uint8_t rxBuf[11];
371  * // Receive buffer
372  *
373  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
374  * params.bitRate = 1000000; params.frameFormat = SPI_POL1_PHA1;
375  * params.mode = SPI_CONTROLLER;
376  *
377  * // Configure the transaction transaction.count = sizeof(txBuf);
378  * transaction.txBuf = txBuf; transaction.rxBuf = rxBuf;
379  *
380  * // Open the SPI and perform the transfer handle = SPI_open(CONFIG_SPI,
381  * &params); SPI_transfer(handle, &transaction);
382  * @endcode
383  *
384  * ### Controller Mode With Multiple Peripherals @anchor USE_CASE_MMMS_WFF3 #
385  * This use case will configure a SPI controller to send data to one peripheral
386  and then to another in BLOCKING_MODE. It is assumed that SysConfig is
387  configured so that the two chip select pins have a default setting of a high
388  output and that the #SPIWFF3DMA_HWAttrs used points to one of them since the
389  SPI driver will revert to this default setting when switching the chip
390  select pin.
391  *
392  * @code
393  * // From ti_drivers_config.c // Use the sysconfig settings to make sure both
394  * pins are set to HIGH when not in use GPIO_PinConfig gpioPinConfigs[GPIO_NUMBER_OF_CONFIGS] = {
395  * ...
396  * GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH, // CONFIG_CSN_0
397  * ...
398  * GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH, // CONFIG_CSN_1
399  * }
400  *
401  * const SPIWFF3DMA_HWAttrs SPIWFF3DMAHWAttrs[CONFIG_SPI_COUNT] = { { // Use
402  * SPI1 module with default chip select on CONFIG_CSN_0
403  * .baseAddr = SPI1_BASE,
404  * .intNum = INT_SP_SPI_1_EVT_REQ,
405  * .intPriority = (~0),
406  * .swiPriority = 0,
407  * .powerID = PowerWFF3_PERIPH_SPI1,
408  * .defaultTxBufValue = 0xFF,
409  * .rxDmaChannel = 1,
410  * .txDmaChannel = 0,
411  * .minDmaTransferSize = 10,
412  * .picoPinMux = IOMUX_GPIO34PCFG_IOSEL_SEL_4,
413  * .pociPinMux = IOMUX_GPIO33PCFG_IOSEL_SEL_4,
414  * .sclkPinMux = IOMUX_GPIO32PCFG_IOSEL_SEL_4,
415  * .csnPinMux = IOMUX_GPIO31PCFG_IOSEL_SEL_4,
416  * .picoPin = CONFIG_GPIO_SPI_CONTROLLER_PICO,
417  * .pociPin = CONFIG_GPIO_SPI_CONTROLLER_POCI,
418  * .sclkPin = CONFIG_GPIO_SPI_CONTROLLER_SCLK,
419  * .csnPin = CONFIG_CSN_0,
420  * .csnSel = SPI_CSSEL_CS0,
421  * }
422  *
423  * // From your_application.c static void taskFxn(uintptr_t a0, uintptr_t a1)
424  * {
425  * SPI_Handle handle;
426  * SPI_Params params;
427  * SPI_Transaction transaction;
428  * uint_least8_t csnPin1 = CONFIG_CSN_1;
429  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
430  *
431  * // Init SPI and specify non-default parameters
432  * SPI_Params_init(&params);
433  * params.bitRate = 1000000;
434  * params.frameFormat = SPI_POL1_PHA1;
435  * params.mode = SPI_CONTROLLER;
436  *
437  * // Configure the transaction
438  * transaction.count = sizeof(txBuf);
439  * transaction.txBuf = txBuf;
440  * transaction.rxBuf = NULL;
441  *
442  * // Open the SPI and perform transfer to the first peripheral
443  * handle = SPI_open(CONFIG_SPI, &params);
444  * SPI_transfer(handle, &transaction);
445  *
446  * // Then switch chip select pin and perform transfer to the second
447  peripheral
448  SPI_control(handle, SPIWFF3DMA_SET_CSN_PIN, &csnPin1);
449  SPI_transfer(handle, &transaction);
450  * }
451  * @endcode
452  *
453  * ### Queueing Transactions in Callback Mode #
454  * @anchor USE_CASE_QUEUE_WFF3 Below is an example of queueing three
455  * transactions
456  * @code
457  * // SPI already opened in callback mode SPI_Transaction t0, t1, t2;
458  *
459  * t0.txBuf = txBuff0; t0.rxBuf = rxBuff0; t0.count = 2000;
460  *
461  * t1.txBuf = txBuff1; t1.rxBuf = rxBuff1; t1.count = 1000;
462  *
463  * t2.txBuf = txBuff2; t2.rxBuf = NULL; t2.count = 1000;
464  *
465  * bool transferOk = false;
466  *
467  * if (SPI_transfer(spiHandle, &t0)) { if (SPI_transfer(spiHandle, &t1)) {
468  * transferOk = SPI_transfer(spiHandle, &t2);
469  * }
470  * }
471  * }
472  *
473  * ### Ensure low power during inactive periods @anchor USE_CASE_LPWR_WFF3 #
474  * External hardware connected on the SPI, i.e. SPI controller/peripheral,
475  might have configured a pull on one or more of the SPI lines. Dependent on
476  the hardware, it might conflict with the pull used for the Wi-Fi F3
477  device SPI. To avoid increased leakage and ensure the lowest possible power
478  consumption when the SPI is inactive, the application must configure a
479  matching pull on the SPI IOs. An example of how this can be done is shown
480  below.
481  *
482  * @code
483  * SPI_Params params; SPI_Transaction transaction; uint8_t txBuf[] =
484  * "Heartbeat"; // Transmit buffer uint8_t rxBuf[9]; //
485  * Receive buffer uint32_t sleepDurationMs = 100;
486  *
487  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
488  * params.bitRate = 1000000; params.frameFormat = SPI_POL1_PHA1;
489  * params.mode = SPI_CONTROLLER;
490  *
491  * // Configure the transaction transaction.count = sizeof(txBuf);
492  * transaction.txBuf = txBuf; transaction.rxBuf = rxBuf;
493  *
494  * // Open the SPI and perform the transfer handle = SPI_open(CONFIG_SPI_0,
495  * &params);
496  *
497  * // Apply low power sleep pull config for POCI
498  * GPIO_setConfig(CONFIG_GPIO_SPI_0_POCI, GPIO_CFG_IN_PU);
499  *
500  * // Do forever while(1) { // Transfer data SPI_transfer(handle,
501  * &transaction); // Sleep Task_sleep(sleepDurationMs*100);
502  * }
503  * @endcode
504  *
505  * ### Wake Up On Chip Select Deassertion In Peripheral Mode Using #SPI_MODE_CALLBACK #
506  * This example demonstrates using a GPIO callback on Chip Select to wake up
507  the device to allow low power modes while waiting for a chip select edge.
508  *
509  * In sysconfig or the board file, the CSN GPIO should be configured as
510  * input/pull up with an interrupt on falling edge. Otherwise, SPI_close() will
511  * reset the pin to the wrong settings and you may see line glitches.
512  *
513  * *Note: The SPI controller must allow enough time between deasserting the
514  chip select and the start of the transaction for the SPI peripheral to wake
515  up and open up the SPI driver.
516  *
517  * @code
518  * // Global variables SPI_Handle spiHandle SPI_Params spiParams;
519  * SPI_Transaction spiTransaction; const uint8_t transferSize = 8; uint8_t
520  * txBuf[8];
521  *
522  * // Chip select callback static void chipSelectCallback(uint_least8_t)
523  * {
524  * // Open SPI driver, which will override any previous GPIO configuration
525  * spiHandle = SPI_open(CONFIG_SPI, &spiParams);
526  * // Issue the transfer
527  * SPI_transfer(spiHandle, &spiTransaction);
528  * }
529  *
530  * // SPI transfer callback static void transferCallback(SPI_Handle handle,
531  * SPI_Transaction *transaction)
532  * {
533  * // Close the SPI driver
534  * SPI_close(handle);
535  *
536  * // Note: SPI_close() will reset the pin configuration, so it is
537  important to
538  // set the default values correctly in sysconfig. We just need to set
539  the
540  // callback and enable the falling edge interrupt
541  *
542  * GPIO_setCallback(CS_PIN_INDEX, chipSelectCallback);
543  * GPIO_enableInt(CS_PIN_INDEX);
544  * }
545  *
546  * // From your_application.c static void taskFxn(uintptr_t a0, uintptr_t a1)
547  * {
548  * uint8_t i;
549  *
550  * // Setup SPI params
551  * SPI_Params_init(&spiParams);
552  * spiParams.bitRate = 1000000;
553  * spiParams.frameFormat = SPI_POL1_PHA1;
554  * spiParams.mode = SPI_PERIPHERAL;
555  * spiParams.dataSize = transferSize;
556  * spiParams.transferMode = SPI_MODE_CALLBACK;
557  * spiParams.transferCallbackFxn = transferCallback;
558  *
559  * // Setup SPI transaction
560  * spiTransaction.arg = NULL;
561  * spiTransaction.count = transferSize;
562  * spiTransaction.txBuf = txBuf;
563  * spiTransaction.rxBuf = txBuf;
564  *
565  * // First echo message
566  * for (i = 0; i < transferSize; i++) {
567  * txBuf[i] = i;
568  * }
569  *
570  * // Configure chip select callback
571  * GPIO_setCallback(CS_PIN_INDEX, chipSelectCallback);
572  * GPIO_enableInt(CS_PIN_INDEX);
573  *
574  * // Wait forever
575  * while(true);
576  * }
577  * @endcode
578  *
579  * <hr>
580  */
581 
582 #ifndef ti_drivers_spi_SPIWFF3DMA__include
583 #define ti_drivers_spi_SPIWFF3DMA__include
584 
585 #include <ti/devices/DeviceFamily.h>
586 #include DeviceFamily_constructPath(driverlib/spi.h)
587 
588 #include <stdint.h>
589 #include <ti/drivers/SPI.h>
591 #include <ti/drivers/dma/DMAWFF3.h>
592 #include <ti/drivers/Power.h>
593 
594 #include <ti/drivers/dpl/HwiP.h>
596 #include <ti/drivers/dpl/SwiP.h>
597 
598 #ifdef __cplusplus
599 extern "C" {
600 #endif
601 
612 /* Add SPIWFF3DMA_STATUS_* macros here */
613 
634 #define SPIWFF3DMA_CMD_RETURN_PARTIAL_ENABLE (SPI_CMD_RESERVED + 0)
635 
643 #define SPIWFF3DMA_CMD_RETURN_PARTIAL_DISABLE (SPI_CMD_RESERVED + 1)
644 
651 #define SPIWFF3DMA_CMD_SET_CSN_PIN (SPI_CMD_RESERVED + 2)
652 
658 #define SPIWFF3DMA_CMD_CLEAR_CSN_PIN (SPI_CMD_RESERVED + 3)
659 
673 #define SPIWFF3DMA_CMD_SET_MANUAL (SPI_CMD_RESERVED + 4)
674 
684 #define SPIWFF3DMA_CMD_CLR_MANUAL (SPI_CMD_RESERVED + 5)
685 
696 #define SPIWFF3DMA_CMD_MANUAL_START (SPI_CMD_RESERVED + 6)
697 
717 #define SPIWFF3DMA_CMD_SET_SAMPLE_DELAY (SPI_CMD_RESERVED + 7)
718 
721 /* BACKWARDS COMPATIBILITY */
722 #define SPIWFF3DMA_RETURN_PARTIAL_ENABLE SPIWFF3DMA_CMD_RETURN_PARTIAL_ENABLE
723 #define SPIWFF3DMA_RETURN_PARTIAL_DISABLE SPIWFF3DMA_CMD_RETURN_PARTIAL_DISABLE
724 #define SPIWFF3DMA_SET_CSN_PIN SPIWFF3DMA_CMD_SET_CSN_PIN
725 /* END BACKWARDS COMPATIBILITY */
726 
732 extern const SPI_FxnTable SPIWFF3DMA_fxnTable;
733 
743 typedef enum
744 {
748 
756 typedef enum
757 {
762 
833 typedef struct
834 {
836  uint32_t baseAddr;
843  uint32_t swiPriority;
845  uint32_t rxDmaChannel;
847  uint32_t txDmaChannel;
849  int32_t pociPinMux;
851  int32_t picoPinMux;
853  int32_t sclkPinMux;
855  int32_t csnPinMux;
857  uint32_t csnSel;
867  uint8_t intNum;
879  uint8_t intPriority;
881  PowerWFF3_Resource powerID;
883  uint_least8_t picoPin;
885  uint_least8_t pociPin;
887  uint_least8_t sclkPin;
889  uint_least8_t csnPin;
891 
897 typedef struct
898 {
903 
908 
909  size_t framesQueued;
911  size_t transferSize;
912 
913  /* Used for SPI TX by DMA - from a RAM buffer to SPI TX register */
917  /* Used for SPI RX by DMA - from SPI RX register to a RAM buffer */
921 
922  uint32_t bitRate;
923  uint32_t dataSize;
924  uint32_t transferTimeout;
925  uint32_t busyBit;
926  uint32_t dsample;
927 
928  uint16_t rxScratchBuf;
929  uint16_t txScratchBuf;
930 
933  uint8_t format;
934  uint_least8_t csnPin;
936  bool isOpen;
939 
940 #ifdef __cplusplus
941 }
942 #endif
943 
944 #endif /* ti_drivers_spi_SPIWFF3DMA__include */
GPIO driver implementation for WiFi F3 devices.
void * dmaTxSrcAddr
Definition: SPIWFF3DMA.h:914
SwiP_Struct swi
Definition: SPIWFF3DMA.h:901
SPIWFF3DMA_ReturnPartial
Definition: SPIWFF3DMA.h:756
void * dmaRxDstAddr
Definition: SPIWFF3DMA.h:919
HwiP structure.
Definition: HwiP.h:166
Serial Peripheral Interface (SPI) Driver Interface.
void(* SPI_CallbackFxn)(SPI_Handle handle, SPI_Transaction *transaction)
The definition of a callback function used by the SPI driver when used in SPI_MODE_CALLBACK.
Definition: SPI.h:587
uint_least8_t picoPin
Definition: SPIWFF3DMA.h:883
SPI_Transaction * tailPtr
Definition: SPIWFF3DMA.h:906
const SPI_FxnTable SPIWFF3DMA_fxnTable
Definition: SPIWFF3DMA.h:746
uint16_t rxScratchBuf
Definition: SPIWFF3DMA.h:928
uint8_t intPriority
SPIWFF3DMA Peripheral&#39;s interrupt priority.
Definition: SPIWFF3DMA.h:879
SPI_TransferMode
SPI transfer mode determines the whether the SPI controller operates synchronously or asynchronously...
Definition: SPI.h:624
Power Manager.
uint32_t bitRate
Definition: SPIWFF3DMA.h:922
uint32_t swiPriority
SPI SWI priority. The higher the number, the higher the priority. The minimum is 0 and the maximum is...
Definition: SPIWFF3DMA.h:843
SPIWFF3DMA_FrameSize
Definition: SPIWFF3DMA.h:743
bool manualStart
Definition: SPIWFF3DMA.h:937
size_t transferSize
Definition: SPIWFF3DMA.h:911
SPIWFF3DMA Hardware attributes.
Definition: SPIWFF3DMA.h:833
uint32_t dataSize
Definition: SPIWFF3DMA.h:923
Definition: SPIWFF3DMA.h:760
size_t framesQueued
Definition: SPIWFF3DMA.h:909
size_t dmaTxTransferSize
Definition: SPIWFF3DMA.h:916
SPI_Mode mode
Definition: SPIWFF3DMA.h:932
SPI_CallbackFxn transferCallbackFxn
Definition: SPIWFF3DMA.h:904
uint16_t txScratchBuf
Definition: SPIWFF3DMA.h:929
Semaphore module for the RTOS Porting Interface.
The definition of a SPI function table that contains the required set of functions to control a speci...
Definition: SPI.h:714
Power_NotifyObj spiPostObj
Definition: SPIWFF3DMA.h:900
size_t framesTransferred
Definition: SPIWFF3DMA.h:910
uint32_t csnSel
Definition: SPIWFF3DMA.h:857
uint8_t format
Definition: SPIWFF3DMA.h:933
uint_least8_t sclkPin
Definition: SPIWFF3DMA.h:887
SPI_TransferMode transferMode
Definition: SPIWFF3DMA.h:931
uint_least8_t csnPin
Definition: SPIWFF3DMA.h:934
uint32_t busyBit
Definition: SPIWFF3DMA.h:925
SPIWFF3DMA_ReturnPartial returnPartial
Definition: SPIWFF3DMA.h:935
HwiP_Struct hwi
Definition: SPIWFF3DMA.h:899
uint32_t baseAddr
SPI Peripheral&#39;s base address.
Definition: SPIWFF3DMA.h:836
uint_least8_t csnPin
Definition: SPIWFF3DMA.h:889
int32_t sclkPinMux
Definition: SPIWFF3DMA.h:853
SPI_Transaction * headPtr
Definition: SPIWFF3DMA.h:905
Software Interrupt module for the RTOS Porting Interface.
A SPI_Transaction data structure is used with SPI_transfer(). It indicates how many SPI_FrameFormat f...
Definition: SPI.h:565
SemaphoreP_Struct transferComplete
Definition: SPIWFF3DMA.h:902
Power notify object structure.
Definition: Power.h:441
int32_t csnPinMux
Definition: SPIWFF3DMA.h:855
SPI_Mode
Definitions for various SPI modes of operation.
Definition: SPI.h:592
int32_t pociPinMux
Definition: SPIWFF3DMA.h:849
uint8_t txChannelEvtMux
Definition: SPIWFF3DMA.h:863
uint32_t rxDmaChannel
Definition: SPIWFF3DMA.h:845
size_t dmaRxTransferSize
Definition: SPIWFF3DMA.h:920
PowerWFF3_Resource powerID
Definition: SPIWFF3DMA.h:881
Definition: SPIWFF3DMA.h:745
uint32_t txDmaChannel
Definition: SPIWFF3DMA.h:847
bool isOpen
Definition: SPIWFF3DMA.h:936
SPIWFF3DMA Object.
Definition: SPIWFF3DMA.h:897
uint16_t defaultTxBufValue
Definition: SPIWFF3DMA.h:861
void * dmaTxDstAddr
Definition: SPIWFF3DMA.h:915
uint32_t dsample
Definition: SPIWFF3DMA.h:926
int32_t picoPinMux
Definition: SPIWFF3DMA.h:851
uint_least8_t pociPin
Definition: SPIWFF3DMA.h:885
DMAWFF3 driver implementation.
void * dmaRxSrcAddr
Definition: SPIWFF3DMA.h:918
uint32_t minDmaTransferSize
Definition: SPIWFF3DMA.h:859
Hardware Interrupt module for the RTOS Porting Interface.
SPI_Transaction * completedTransfers
Definition: SPIWFF3DMA.h:907
Definition: SPIWFF3DMA.h:758
SemaphoreP structure.
Definition: SwiP.h:68
uint32_t transferTimeout
Definition: SPIWFF3DMA.h:924
SemaphoreP structure.
Definition: SemaphoreP.h:84
uint8_t rxChannelEvtMux
Definition: SPIWFF3DMA.h:865
uint8_t intNum
Definition: SPIWFF3DMA.h:867
Definition: SPIWFF3DMA.h:759
© Copyright 1995-2026, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale