SPILPF3DMA.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022-2023 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 SPILPF3DMA.h
34  *
35  * @brief SPI driver implementation for a Low Power F3 device SPI
36  * controller using the UDMA 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> #include <ti/drivers/spi/SPILPF3DMA.h> #include
42  * <ti/drivers/dma/UDMALPF3.h>
43  * @endcode
44  *
45  * Refer to @ref SPI.h for a complete description of APIs.
46  *
47  * Note that the user also needs to include the UDMALPF3.h driver since the SPI
48  * uses uDMA in order to improve throughput.
49  *
50  * # Overview #
51  * The general SPI API should be used in application code, i.e. SPI_open()
52  * should be used instead of SPILPF3DMA_open(). The board file will define the
53  * device specific config, and casting in the general API will ensure that the
54  * correct device specific functions are called. This is also reflected in the
55  * example code in [Use Cases](@ref USE_CASES_SPI_23X0).
56  *
57  * # General Behavior #
58  * Before using SPI on Low Power F3 devices:
59  * - The SPI driver is initialized by calling SPI_init().
60  * - The SPI HW is configured and flags system dependencies (e.g. IOs, power,
61  * etc.) by calling SPI_open().
62  * - The SPI driver makes use of DMA in order to optimize throughput. This is
63  * handled directly by the SPI driver, so the application should never make
64  * any calls directly to the UDMALPF3.h driver.
65  * - This implementation supports queueing multiple transactions in callback
66  * mode. See the @ref USE_CASE_QUEUE_23X0 "queueing example."
67  * - When queueing multiple transactions that should transfer one after the
68  * other, it is recommended to use the driver in 'manual start' mode by
69  * using the #SPILPF3DMA_CMD_SET_MANUAL command. In this mode, the driver
70  * will not start any queued transfers until SPI_control() is called with
71  * the #SPILPF3DMA_CMD_MANUAL_START command. This mode is off by default and
72  * can be disabled by using command #SPILPF3DMA_CMD_CLR_MANUAL. See the
73  * @ref USE_CASE_MANUAL_START_23X0 "Manual Start Example".
74  *
75  * The following is true for peripheral operation:
76  * - RX overrun IRQ, SPI and UDMA modules are enabled by calling
77  SPI_transfer().
78  * - All received bytes are ignored after SPI_open() is called, until the
79  * first SPI_transfer().
80  * - If an RX overrun occurs or if SPI_transferCancel() is called, RX overrun
81  IRQ, SPI and UDMA modules are disabled, TX and RX FIFOs are flushed and
82  all bytes are ignored.
83  * - After a successful transfer, RX overrun IRQ and SPI module remains
84  enabled and UDMA module is disabled. SPI_transfer() must be called again
85  before RX FIFO fills up in order to avoid overflow. If the TX buffer
86  overflows, zeros will be output. It is safe to call another
87  SPI_transfer() from the transfer callback, see [Continuous Peripheral
88  Transfer] (@ref USE_CASE_CST_23X0) use case below.
89  * - The SPI driver supports partial return, that can be used if the transfer
90  * size is unknown. If #SPILPF3DMA_CMD_RETURN_PARTIAL_ENABLE is passed to
91  * SPI_control(), the transfer will end when chip select is deasserted. The
92  * #SPI_Transaction.status and the #SPI_Transaction.count will be updated to
93  * indicate whether the transfer ended due to a chip select deassertion and
94  * how many bytes were transferred. See [Peripheral Mode With Return
95  * Partial] (@ref USE_CASE_RP_23X0) use case below.
96  * - When queueing several transactions if the first is a 'short' transaction
97  * (8 or fewer frames), it is required to use
98  * @ref USE_CASE_MANUAL_START_23X0 "Manual Start mode."
99  *
100  * The following apply for controller operation:
101  * - SPI and UDMA modules are enabled by calling SPI_transfer().
102  * - If the SPI_transfer() succeeds, SPI module is enabled and UDMA module is
103  disabled.
104  * - If SPI_transferCancel() is called, SPI and UDMA modules are disabled and
105  * TX and RX FIFOs are flushed.
106  *
107  * After SPI operation has ended:
108  * - Release system dependencies for SPI by calling SPI_close().
109  *
110  * The callback function is always called in a SWI context.
111  *
112  * # Error handling #
113  * If an RX overrun occurs during peripheral operation:
114  * - If a transfer is ongoing, all bytes received up until the error occurs
115  will be returned, with the error signaled in the #SPI_Transaction.status
116  field. RX overrun IRQ, SPI and UDMA modules are then disabled, TX and RX
117  FIFOs are flushed and all bytes will be ignored until a new transfer is
118  issued.
119  * - If a transfer is not ongoing, RX overrun IRQ, SPI and UDMA modules are
120  disabled, TX and RX FIFOs are flushed and all bytes will be ignored until
121  a new transfer is issued.
122  *
123  * # Timeout #
124  * Timeout can occur in #SPI_MODE_BLOCKING, there's no timeout in
125  #SPI_MODE_CALLBACK. When in #SPI_MODE_CALLBACK, the transfer must be
126  cancelled by calling SPI_transferCancel().@n If a timeout happens in either
127  #SPI_PERIPHERAL or #SPI_CONTROLLER mode, the receive buffer will contain the
128  bytes received up until the timeout occurred. The SPI transaction status will
129  be set to #SPI_TRANSFER_FAILED. The SPI transaction count will be set to the
130  number of bytes sent/received before timeout. The remaining bytes will be
131  flushed from the TX FIFO so that the subsequent transfer can be executed
132  correctly. Note that specifying a timeout prevents the driver from performing
133  a polling transfer when in peripheral mode.
134  *
135  * # Power Management #
136  * The TI-RTOS power management framework will try to put the device into the
137  most power efficient mode whenever possible. Please see the technical
138  reference manual for further details on each power mode.
139  *
140  * The SPILPF3DMA.h driver is setting a power constraint during transfers to
141  keep the device out of standby. When the transfer has finished, the power
142  constraint is released. The following statements are valid:
143  * - After SPI_open(): the device is still allowed to enter standby.
144  * - In peripheral mode:
145  * - During SPI_transfer(): the device cannot enter standby, only idle.
146  * - After an RX overflow: device is allowed to enter standby.
147  * - After a successful SPI_transfer(): the device is allowed to enter
148  * standby, but SPI module remains enabled.
149  * - _Note_: In peripheral mode, the device might enter standby while a
150  byte is being transferred if SPI_transfer() is not called again after
151  a successful transfer. This could result in corrupt data being
152  transferred.
153  * - Application thread should typically either issue another transfer after
154  * SPI_transfer() completes successfully, or call SPI_transferCancel() to
155  * disable the SPI module and thus assuring that no data is received while
156  * entering standby.
157  * - In controller mode:
158  * - During SPI_transfer(): the device cannot enter standby, only idle.
159  * - After SPI_transfer() succeeds: the device can enter standby.
160  * - If SPI_transferCancel() is called: the device can enter standby.
161  *
162  * @note The external hardware connected to the SPI might have some pull
163  configured on the SPI lines. When the SPI is inactive, this might cause
164  leakage on the IO and the current consumption to increase. The application
165  must configure a pull configuration that aligns with the external hardware.
166  See [Ensure low power during inactive periods] (@ref USE_CASE_LPWR_23X0) for
167  code example.
168  *
169  * # SPI details #
170  * ## Chip Select #
171  * This SPI controller supports a hardware chip select pin. Refer to the user
172  * manual on how this hardware chip select pin behaves in regards to the SPI
173  * frame format.
174  *
175  * <table>
176  * <tr>
177  * <th>Chip select type</th>
178  * <th>SPI_CONTROLLER mode</th>
179  * <th>SPI_PERIPHERAL mode</th>
180  * </tr>
181  * <tr>
182  * <td>Hardware chip select</td>
183  * <td>No action is needed by the application to select the peripheral.</td>
184  * <td>See the device documentation on it's chip select requirements.</td>
185  * </tr>
186  * <tr>
187  * <td>Software chip select</td>
188  * <td>The application is responsible to ensure that correct SPI peripheral is
189  * selected before performing a SPI_transfer().</td>
190  * <td>See the device documentation on it's chip select requirements.</td>
191  * </tr>
192  * </table>
193  *
194  * ### Multiple peripherals when operating in controller mode #
195  * In a scenario where the SPI module is operating in controller mode with
196  multiple SPI peripherals, the chip select pin can be reallocated at runtime
197  to select the appropriate peripheral device. See [Controller Mode With
198  Multiple Peripherals](@ref USE_CASE_MMMS_23X0) use case below. This is only
199  relevant when chip select is a hardware chip select. Otherwise the
200  application can control the chip select pins directly using the GPIO driver.
201  *
202  * ## Data Frames #
203  *
204  * SPI data frames can be any size from 4-bits to 16-bits. If the dataSize in
205  * #SPI_Params is greater that 8-bits, then the SPILPF3DMA driver
206  * implementation will assume that the #SPI_Transaction txBuf and rxBuf point
207  * to an array of 16-bit uint16_t elements.
208  *
209  * dataSize | buffer element size |
210  * -------- | ------------------- |
211  * 4-8 bits | uint8_t |
212  * 9-16 bits | uint16_t |
213  *
214  * ## Bit Rate ##
215  * When the SPI is configured as SPI peripheral, the maximum bit rate is 8MHz.
216  *
217  * When the SPI is configured as SPI controller, the maximum bit rate is 12MHz.
218  *
219  *
220  * ## UDMA #
221  * ### Interrupts #
222  * The UDMA module generates IRQs on the SPI interrupt vector. This driver
223  automatically installs a UDMA aware Hwi (interrupt) to service the assigned
224  UDMA channels.
225  *
226  * ### Transfer Size Limit #
227  *
228  * The UDMA controller only supports data transfers of up to 1024 data frames.
229  * A transfer with more than 1024 frames will be transmitted/received in
230  * multiple 1024 sized portions until all data has been transmitted/received. A
231  * data frame can be 4 to 16 bits in length.
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 UDMA accessible uint16_t
237  scratch buffer is used. When rxBuf is NULL, the UDMA 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 uDMA
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() | SPICC26X4DMA_init() | Initialize SPI driver
271  * SPI_open() | SPICC26X4DMA_open() | Initialize SPI HW and set system dependencies
272  * SPI_close() | SPICC26X4DMA_close() | Disable SPI and UDMA HW and release system dependencies
273  * SPI_control() | SPICC26X4DMA_control() | Configure an already opened SPI handle
274  * SPI_transfer() | SPICC26X4DMA_transfer() | Start transfer from SPI
275  * SPI_transferCancel() | SPICC26X4DMA_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_23X0 ##
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_23X0 #
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  * SPILPF3DMA_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_23X0 #
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_23X0 #
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 #SPILPF3DMA_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[31] = {
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 SPILPF3DMA_HWAttrs SPILPF3DMAHWAttrs[CONFIG_SPI_COUNT] = { { // Use
402  * SPI0 module with default chip select on CONFIG_CSN_0 .baseAddr = SPI0_BASE,
403  * .intNum = INT_SPI0_COMB, .intPriority = (~0), .swiPriority = 0, .powerID =
404  * PowerLPF3_PERIPH_SPI0, .defaultTxBufValue = 0xFF, .rxChannelBitMask =
405  * UDMA_CHANNEL_1_M, .txChannelBitMask = UDMA_CHANNEL_0_M, .rxChannelEvtMux =
406  * EVTSVT_DMACH1SEL_IPID_SPI0RXTRG, .txChannelEvtMux =
407  * EVTSVT_DMACH0SEL_IPID_SPI0TXTRG, .dmaTxTableEntryPri =
408  * &dmaChannel0ControlTableEntry, .dmaRxTableEntryPri =
409  * &dmaChannel1ControlTableEntry, .dmaTxTableEntryAlt =
410  * &dmaChannel0AltControlTableEntry, .dmaRxTableEntryAlt =
411  * &dmaChannel1AltControlTableEntry, .minDmaTransferSize = 10, .picoPinMux =
412  * GPIO_MUX_PORTCFG_PFUNC2, .pociPinMux = GPIO_MUX_PORTCFG_PFUNC1,
413  * .sclkPinMux = GPIO_MUX_PORTCFG_PFUNC4, .csnPinMux =
414  * GPIO_MUX_PORTCFG_PFUNC1, .picoPin = CONFIG_GPIO_SPI_CONTROLLER_PICO,
415  * .pociPin = CONFIG_GPIO_SPI_CONTROLLER_POCI, .sclkPin =
416  * CONFIG_GPIO_SPI_CONTROLLER_SCLK, .csnPin = CONFIG_SPI_CSN_0,
417  * }
418  *
419  * // From your_application.c static void taskFxn(uintptr_t a0, uintptr_t a1)
420  * {
421  * SPI_Handle handle;
422  * SPI_Params params;
423  * SPI_Transaction transaction;
424  * uint_least8_t csnPin1 = CONFIG_CSN_1;
425  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
426  *
427  * // Init SPI and specify non-default parameters
428  * SPI_Params_init(&params);
429  * params.bitRate = 1000000;
430  * params.frameFormat = SPI_POL1_PHA1;
431  * params.mode = SPI_CONTROLLER;
432  *
433  * // Configure the transaction
434  * transaction.count = sizeof(txBuf);
435  * transaction.txBuf = txBuf;
436  * transaction.rxBuf = NULL;
437  *
438  * // Open the SPI and perform transfer to the first peripheral
439  * handle = SPI_open(CONFIG_SPI, &params);
440  * SPI_transfer(handle, &transaction);
441  *
442  * // Then switch chip select pin and perform transfer to the second
443  peripheral
444  SPI_control(handle, SPILPF3DMA_SET_CSN_PIN, &csnPin1);
445  SPI_transfer(handle, &transaction);
446  * }
447  * @endcode
448  *
449  * ### Queueing Transactions in Callback Mode #
450  * @anchor USE_CASE_QUEUE_23X0 Below is an example of queueing three
451  * transactions
452  * @code
453  * // SPI already opened in callback mode SPI_Transaction t0, t1, t2;
454  *
455  * t0.txBuf = txBuff0; t0.rxBuf = rxBuff0; t0.count = 2000;
456  *
457  * t1.txBuf = txBuff1; t1.rxBuf = rxBuff1; t1.count = 1000;
458  *
459  * t2.txBuf = txBuff2; t2.rxBuf = NULL; t2.count = 1000;
460  *
461  * bool transferOk = false;
462  *
463  * if (SPI_transfer(spiHandle, &t0)) { if (SPI_transfer(spiHandle, &t1)) {
464  * transferOk = SPI_transfer(spiHandle, &t2);
465  * }
466  * }
467  * }
468  * @endcode
469  *
470  * ### Queueing in Manual Start Mode#
471  * This example shows a peripheral device queueing two transactions that will
472  * complete one after the other. From the controller's perspective there will
473  * be one long transfer.
474  * @note Manual mode also works while the device is in #SPI_CONTROLLER mode.
475  The control call to MANUAL_START will start the transfers.
476  *
477  * @warning Manual start mode should not be enabled or disabled while a
478  * transaction is in progress.
479  *
480  * @anchor USE_CASE_MANUAL_START_23X0
481  * @code
482  * SPI_Handle spi; SPI_Params params; SPI_Transaction t0, t1; uint8_t status =
483  * SPI_STATUS_SUCCESS;
484  *
485  * SPI_Params_init(&params); params.mode = SPI_PERIPHERAL; spi =
486  * SPI_open(CONFIG_SPI, &params);
487  *
488  * if (spi == NULL) { exit(0);
489  * }
490  *
491  * // Enable manual start mode SPI_control(spi, SPILPF3DMA_CMD_SET_MANUAL,
492  * NULL);
493  *
494  * // Queue transactions t0.txBuf = txBuff0; t0.rxBuf = rxBuff0; t0.count =
495  * 2000; if (!SPI_transfer(spi, &t0)) { status = SPI_STATUS_FAIL;
496  * }
497  *
498  * t1.txBuf = txBuff1; t1.rxBuf = rxBuff1; t1.count = 1000; if
499  * (!SPI_transfer(spi, &t1)) { status = SPI_STATUS_FAIL;
500  * }
501  *
502  * // Enable the transfers if (status == SPI_STATUS_SUCCESS) { SPI_control(spi,
503  * SPILPF3DMA_CMD_MANUAL_START, NULL);
504  * }
505  * else { status = SPI_STATUS_FAILURE;
506  * }
507  *
508  * // At this point the peripheral is ready for the controller to start the
509  transfer // Assume the callback implementation (not shown) posts a semaphore
510  when // the last transaction completes sem_wait(&spiSemaphore);
511  *
512  * // Disable manual start mode SPI_control(spi, SPILPF3DMA_CMD_CLR_MANUAL,
513  * NULL);
514  *
515  * @endcode
516  *
517  * ### Ensure low power during inactive periods @anchor USE_CASE_LPWR_23X0 #
518  * External hardware connected on the SPI, i.e. SPI controller/peripheral,
519  might have configured a pull on one or more of the SPI lines. Dependent on
520  the hardware, it might conflict with the pull used for the Low Power F3
521  device SPI. To avoid increased leakage and ensure the lowest possible power
522  consumption when the SPI is inactive, the application must configure a
523  matching pull on the SPI IOs. An example of how this can be done is shown
524  below.
525  *
526  * @code
527  * SPI_Params params; SPI_Transaction transaction; uint8_t txBuf[] =
528  * "Heartbeat"; // Transmit buffer uint8_t rxBuf[9]; //
529  * Receive buffer uint32_t standbyDurationMs = 100;
530  *
531  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
532  * params.bitRate = 1000000; params.frameFormat = SPI_POL1_PHA1;
533  * params.mode = SPI_CONTROLLER;
534  *
535  * // Configure the transaction transaction.count = sizeof(txBuf);
536  * transaction.txBuf = txBuf; transaction.rxBuf = rxBuf;
537  *
538  * // Open the SPI and perform the transfer handle = SPI_open(CONFIG_SPI_0,
539  * &params);
540  *
541  * // Apply low power sleep pull config for POCI
542  * GPIO_setConfig(CONFIG_GPIO_SPI_0_POCI, GPIO_CFG_IN_PU);
543  *
544  * // Do forever while(1) { // Transfer data SPI_transfer(handle,
545  * &transaction); // Sleep Task_sleep(standbyDurationMs*100);
546  * }
547  * @endcode
548  *
549  * ### Wake Up On Chip Select Deassertion In Peripheral Mode Using #SPI_MODE_CALLBACK #
550  * This example demonstrates using a GPIO callback on Chip Select to wake up
551  the device to allow low power modes while waiting for a chip select edge.
552  *
553  * In sysconfig or the board file, the CSN GPIO should be configured as
554  * input/pull up with an interrupt on falling edge. Otherwise, SPI_close() will
555  * reset the pin to the wrong settings and you may see line glitches.
556  *
557  * *Note: The SPI controller must allow enough time between deasserting the
558  chip select and the start of the transaction for the SPI peripheral to wake
559  up and open up the SPI driver.
560  *
561  * @code
562  * // Global variables SPI_Handle spiHandle SPI_Params spiParams;
563  * SPI_Transaction spiTransaction; const uint8_t transferSize = 8; uint8_t
564  * txBuf[8];
565  *
566  * // Chip select callback static void chipSelectCallback(uint_least8_t)
567  * {
568  * // Open SPI driver, which will override any previous GPIO configuration
569  * spiHandle = SPI_open(CONFIG_SPI, &spiParams);
570  * // Issue the transfer
571  * SPI_transfer(spiHandle, &spiTransaction);
572  * }
573  *
574  * // SPI transfer callback static void transferCallback(SPI_Handle handle,
575  * SPI_Transaction *transaction)
576  * {
577  * // Close the SPI driver
578  * SPI_close(handle);
579  *
580  * // Note: SPI_close() will reset the pin configuration, so it is
581  important to
582  // set the default values correctly in sysconfig. We just need to set
583  the
584  // callback and enable the falling edge interrupt
585  *
586  * GPIO_setCallback(CS_PIN_INDEX, chipSelectCallback);
587  * GPIO_enableInt(CS_PIN_INDEX);
588  * }
589  *
590  * // From your_application.c static void taskFxn(uintptr_t a0, uintptr_t a1)
591  * {
592  * uint8_t i;
593  *
594  * // Setup SPI params
595  * SPI_Params_init(&spiParams);
596  * spiParams.bitRate = 1000000;
597  * spiParams.frameFormat = SPI_POL1_PHA1;
598  * spiParams.mode = SPI_PERIPHERAL;
599  * spiParams.dataSize = transferSize;
600  * spiParams.transferMode = SPI_MODE_CALLBACK;
601  * spiParams.transferCallbackFxn = transferCallback;
602  *
603  * // Setup SPI transaction
604  * spiTransaction.arg = NULL;
605  * spiTransaction.count = transferSize;
606  * spiTransaction.txBuf = txBuf;
607  * spiTransaction.rxBuf = txBuf;
608  *
609  * // First echo message
610  * for (i = 0; i < transferSize; i++) {
611  * txBuf[i] = i;
612  * }
613  *
614  * // Configure chip select callback
615  * GPIO_setCallback(CS_PIN_INDEX, chipSelectCallback);
616  * GPIO_enableInt(CS_PIN_INDEX);
617  *
618  * // Wait forever
619  * while(true);
620  * }
621  * @endcode
622  *
623  * <hr>
624  */
625 
626 #ifndef ti_drivers_spi_SPILPF3DMA__include
627 #define ti_drivers_spi_SPILPF3DMA__include
628 
629 #include <stdint.h>
630 #include <ti/drivers/SPI.h>
632 #include <ti/drivers/dma/UDMALPF3.h>
633 #include <ti/drivers/Power.h>
634 
635 #include <ti/drivers/dpl/HwiP.h>
636 #include <ti/drivers/dpl/SemaphoreP.h>
637 #include <ti/drivers/dpl/SwiP.h>
638 
639 #ifdef __cplusplus
640 extern "C" {
641 #endif
642 
653 /* Add SPILPF3DMA_STATUS_* macros here */
654 
675 #define SPILPF3DMA_CMD_RETURN_PARTIAL_ENABLE (SPI_CMD_RESERVED + 0)
676 
684 #define SPILPF3DMA_CMD_RETURN_PARTIAL_DISABLE (SPI_CMD_RESERVED + 1)
685 
692 #define SPILPF3DMA_CMD_SET_CSN_PIN (SPI_CMD_RESERVED + 2)
693 
699 #define SPILPF3DMA_CMD_CLEAR_CSN_PIN (SPI_CMD_RESERVED + 3)
700 
714 #define SPILPF3DMA_CMD_SET_MANUAL (SPI_CMD_RESERVED + 4)
715 
725 #define SPILPF3DMA_CMD_CLR_MANUAL (SPI_CMD_RESERVED + 5)
726 
737 #define SPILPF3DMA_CMD_MANUAL_START (SPI_CMD_RESERVED + 6)
738 
758 #define SPILPF3DMA_CMD_SET_SAMPLE_DELAY (SPI_CMD_RESERVED + 7)
759 
762 /* BACKWARDS COMPATIBILITY */
763 #define SPILPF3DMA_RETURN_PARTIAL_ENABLE SPILPF3DMA_CMD_RETURN_PARTIAL_ENABLE
764 #define SPILPF3DMA_RETURN_PARTIAL_DISABLE SPILPF3DMA_CMD_RETURN_PARTIAL_DISABLE
765 #define SPILPF3DMA_SET_CSN_PIN SPILPF3DMA_CMD_SET_CSN_PIN
766 /* END BACKWARDS COMPATIBILITY */
767 
773 extern const SPI_FxnTable SPILPF3DMA_fxnTable;
774 
784 typedef enum
785 {
789 
797 typedef enum
798 {
803 
858 typedef struct
859 {
861  uint32_t baseAddr;
863  uint8_t intNum;
875  uint8_t intPriority;
882  uint32_t swiPriority;
884  uint8_t powerID;
896  volatile uDMAControlTableEntry *dmaTxTableEntryPri;
898  volatile uDMAControlTableEntry *dmaRxTableEntryPri;
900  volatile uDMAControlTableEntry *dmaTxTableEntryAlt;
902  volatile uDMAControlTableEntry *dmaRxTableEntryAlt;
904  int32_t pociPinMux;
906  int32_t picoPinMux;
908  int32_t sclkPinMux;
910  int32_t csnPinMux;
912  uint_least8_t picoPin;
914  uint_least8_t pociPin;
916  uint_least8_t sclkPin;
918  uint_least8_t csnPin;
919 
923 
929 typedef struct
930 {
931  HwiP_Struct hwi;
933  SwiP_Struct swi;
934  SemaphoreP_Struct transferComplete;
935 
940 
941  size_t framesQueued;
945 
946  uint32_t activeChannel;
947  uint32_t bitRate;
948  uint32_t dataSize;
949  uint32_t transferTimeout;
950  uint32_t busyBit;
951  uint32_t dsample;
952 
953  uint16_t rxScratchBuf;
954  uint16_t txScratchBuf;
955 
958  uint8_t format;
959  uint_least8_t csnPin;
961  bool isOpen;
964 
965 #ifdef __cplusplus
966 }
967 #endif
968 
969 #endif /* ti_drivers_spi_SPILPF3DMA__include */
uint32_t busyBit
Definition: SPILPF3DMA.h:950
volatile uDMAControlTableEntry * dmaTxTableEntryAlt
Definition: SPILPF3DMA.h:900
uint16_t rxScratchBuf
Definition: SPILPF3DMA.h:953
volatile uDMAControlTableEntry * dmaTxTableEntryPri
Definition: SPILPF3DMA.h:896
Definition: SPILPF3DMA.h:787
volatile uDMAControlTableEntry * dmaRxTableEntryPri
Definition: SPILPF3DMA.h:898
SPI_Transaction * headPtr
Definition: SPILPF3DMA.h:937
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:592
SPI_Transaction * tailPtr
Definition: SPILPF3DMA.h:938
Power_NotifyObj spiPostObj
Definition: SPILPF3DMA.h:932
size_t framesQueued
Definition: SPILPF3DMA.h:941
volatile uDMAControlTableEntry * dmaRxTableEntryAlt
Definition: SPILPF3DMA.h:902
SPI_TransferMode
SPI transfer mode determines the whether the SPI controller operates synchronously or asynchronously...
Definition: SPI.h:629
uint16_t txScratchBuf
Definition: SPILPF3DMA.h:954
SPI_Transaction * completedTransfers
Definition: SPILPF3DMA.h:939
Power Manager.
size_t priTransferSize
Definition: SPILPF3DMA.h:943
SPI_CallbackFxn transferCallbackFxn
Definition: SPILPF3DMA.h:936
uint_least8_t picoPin
Definition: SPILPF3DMA.h:912
uint32_t baseAddr
SPI Peripheral&#39;s base address.
Definition: SPILPF3DMA.h:861
size_t altTransferSize
Definition: SPILPF3DMA.h:944
uint32_t txChannelBitMask
Definition: SPILPF3DMA.h:890
SemaphoreP_Struct transferComplete
Definition: SPILPF3DMA.h:934
Definition: SPILPF3DMA.h:799
uint32_t bitRate
Definition: SPILPF3DMA.h:947
uint32_t activeChannel
Definition: SPILPF3DMA.h:946
HwiP_Struct hwi
Definition: SPILPF3DMA.h:931
uint32_t dsample
Definition: SPILPF3DMA.h:951
uint32_t dataSize
Definition: SPILPF3DMA.h:948
const SPI_FxnTable SPILPF3DMA_fxnTable
The definition of a SPI function table that contains the required set of functions to control a speci...
Definition: SPI.h:718
uint32_t rxChannelBitMask
Definition: SPILPF3DMA.h:888
uint32_t transferTimeout
Definition: SPILPF3DMA.h:949
int32_t sclkPinMux
Definition: SPILPF3DMA.h:908
int32_t csnPinMux
Definition: SPILPF3DMA.h:910
uint8_t txChannelEvtMux
Definition: SPILPF3DMA.h:892
SPILPF3DMA_FrameSize
Definition: SPILPF3DMA.h:784
SPILPF3DMA Object.
Definition: SPILPF3DMA.h:929
SwiP_Struct swi
Definition: SPILPF3DMA.h:933
uint8_t powerID
Definition: SPILPF3DMA.h:884
Definition: SPILPF3DMA.h:786
A SPI_Transaction data structure is used with SPI_transfer(). It indicates how many SPI_FrameFormat f...
Definition: SPI.h:570
Power notify object structure.
Definition: Power.h:445
GPIO driver implementation for Low Power F3 devices.
SPI_Mode
Definitions for various SPI modes of operation.
Definition: SPI.h:597
uint8_t intNum
Definition: SPILPF3DMA.h:863
uint8_t rxChannelEvtMux
Definition: SPILPF3DMA.h:894
Definition: SPILPF3DMA.h:800
bool isOpen
Definition: SPILPF3DMA.h:961
uint_least8_t sclkPin
Definition: SPILPF3DMA.h:916
int32_t pociPinMux
Definition: SPILPF3DMA.h:904
SPI_TransferMode transferMode
Definition: SPILPF3DMA.h:956
Definition: SPILPF3DMA.h:801
uint8_t format
Definition: SPILPF3DMA.h:958
SPILPF3DMA_ReturnPartial returnPartial
Definition: SPILPF3DMA.h:960
uint_least8_t pociPin
Definition: SPILPF3DMA.h:914
SPILPF3DMA Hardware attributes.
Definition: SPILPF3DMA.h:858
uint8_t intPriority
SPILPF3DMA Peripheral&#39;s interrupt priority.
Definition: SPILPF3DMA.h:875
int32_t picoPinMux
Definition: SPILPF3DMA.h:906
size_t framesTransferred
Definition: SPILPF3DMA.h:942
UDMALPF3 driver implementation.
uint_least8_t csnPin
Definition: SPILPF3DMA.h:959
SPI_Mode mode
Definition: SPILPF3DMA.h:957
uint16_t defaultTxBufValue
Definition: SPILPF3DMA.h:886
uint_least8_t csnPin
Definition: SPILPF3DMA.h:918
uint32_t swiPriority
SPI SWI priority. The higher the number, the higher the priority. The minimum is 0 and the maximum is...
Definition: SPILPF3DMA.h:882
bool manualStart
Definition: SPILPF3DMA.h:962
SPILPF3DMA_ReturnPartial
Definition: SPILPF3DMA.h:797
uint32_t minDmaTransferSize
Definition: SPILPF3DMA.h:921
© Copyright 1995-2023, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale