SPICC26X4DMA.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 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 SPICC26X4DMA.h
34  *
35  * @brief SPI driver implementation for a CC26X4 SPI controller using
36  * 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>
42  * #include <ti/drivers/spi/SPICC26X4DMA.h>
43  * #include <ti/drivers/dma/UDMACC26XX.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 UDMACC26XX.h driver since the
49  * SPI uses uDMA 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 SPICC26X4DMA_open(). The board file will define the device
54  * specific config, and casting in the general API will ensure that the correct
55  * device specific functions are called.
56  * This is also reflected in the example code in [Use Cases](@ref USE_CASES_SPI_X4).
57  *
58  * # General Behavior #
59  * Before using SPI on CC26X4:
60  * - The SPI driver is initialized by calling SPI_init().
61  * - The SPI HW is configured and flags system dependencies (e.g. IOs,
62  * power, etc.) by calling SPI_open().
63  * - The SPI driver makes use of DMA in order to optimize throughput.
64  * This is handled directly by the SPI driver, so the application should never
65  * make any calls directly to the UDMACC26XX.h driver.
66  * - This implementation supports queueing multiple transactions in callback
67  * mode. See the @ref USE_CASE_QUEUE_X4 "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 using
70  * the #SPICC26X4DMA_CMD_SET_MANUAL command. In this mode, the driver will
71  * not start any queued transfers until SPI_control() is called with the
72  * #SPICC26X4DMA_CMD_MANUAL_START command. This mode is off by default and
73  * can be disabled by using command #SPICC26X4DMA_CMD_CLR_MANUAL. See the
74  * @ref USE_CASE_MANUAL_START_X4 "Manual Start Example".
75  *
76  * The following is true for slave operation:
77  * - RX overrun IRQ, SPI and UDMA modules are enabled by calling SPI_transfer().
78  * - All received bytes are ignored after SPI_open() is called, until
79  * the first SPI_transfer().
80  * - If an RX overrun occurs or if SPI_transferCancel() is called, RX overrun IRQ, SPI and UDMA
81  * modules are disabled, TX and RX FIFOs are flushed and all bytes are ignored.
82  * - After a successful transfer, RX overrun IRQ and SPI module remains enabled and UDMA module is disabled.
83  * SPI_transfer() must be called again before RX FIFO fills up in order to
84  * avoid overflow. If the TX buffer overflows, zeros will be output.
85  * It is safe to call another SPI_transfer() from the transfer callback,
86  * see [Continuous Slave Transfer] (@ref USE_CASE_CST_X4) use case below.
87  * - The SPI driver supports partial return, that can be used if the
88  * transfer size is unknown. If #SPICC26X4DMA_CMD_RETURN_PARTIAL_ENABLE is
89  * passed to SPI_control(), the transfer will end when chip select is
90  * deasserted. The #SPI_Transaction.status and the #SPI_Transaction.count
91  * will be updated to indicate whether the transfer ended due to a chip
92  * select deassertion and how many bytes were transferred. See
93  * [Slave Mode With Return Partial] (@ref USE_CASE_RP_X4) use case below.
94  * - When queueing several transactions if the first is a 'short'
95  * transaction (8 or fewer frames), it is required to use
96  * @ref USE_CASE_MANUAL_START_X4 "Manual Start mode."
97  *
98  * The following apply for master operation:
99  * - SPI and UDMA modules are enabled by calling SPI_transfer().
100  * - If the SPI_transfer() succeeds, SPI module is enabled and UDMA module is disabled.
101  * - If SPI_transferCancel() is called, SPI and UDMA modules are disabled and
102  * TX and RX FIFOs are flushed.
103  *
104  * After SPI operation has ended:
105  * - Release system dependencies for SPI by calling SPI_close().
106  *
107  * The callback function is always called in a SWI context.
108  *
109  * # Error handling #
110  * If an RX overrun occurs during slave operation:
111  * - If a transfer is ongoing, all bytes received up until the error occurs will be returned, with the
112  * error signaled in the #SPI_Transaction.status field. RX overrun IRQ, SPI and UDMA modules are then disabled,
113  * TX and RX FIFOs are flushed and all bytes will be ignored until a new transfer is issued.
114  * - If a transfer is not ongoing, RX overrun IRQ, SPI and UDMA modules are disabled,
115  * TX and RX FIFOs are flushed and all bytes will be ignored until a new transfer is issued.
116  *
117  * # Timeout #
118  * Timeout can occur in #SPI_MODE_BLOCKING, there's no timeout in #SPI_MODE_CALLBACK.
119  * When in #SPI_MODE_CALLBACK, the transfer must be cancelled by calling SPI_transferCancel().@n
120  * If a timeout happens in either #SPI_SLAVE or #SPI_MASTER mode,
121  * the receive buffer will contain the bytes received up until the timeout occurred.
122  * The SPI transaction status will be set to #SPI_TRANSFER_FAILED.
123  * The SPI transaction count will be set to the number of bytes sent/received before timeout.
124  * The remaining bytes will be flushed from the TX FIFO so that the subsequent transfer
125  * can be executed correctly. Note that specifying a timeout prevents the
126  * driver from performing a polling transfer when in slave mode.
127  *
128  * # Power Management #
129  * The TI-RTOS power management framework will try to put the device into the most
130  * power efficient mode whenever possible. Please see the technical reference
131  * manual for further details on each power mode.
132  *
133  * The SPICC26X4DMA.h driver is setting a power constraint during transfers to keep
134  * the device out of standby. When the transfer has finished, the power
135  * constraint is released.
136  * The following statements are valid:
137  * - After SPI_open(): the device is still allowed to enter standby.
138  * - In slave mode:
139  * - During SPI_transfer(): the device cannot enter standby, only idle.
140  * - After an RX overflow: device is allowed to enter standby.
141  * - After a successful SPI_transfer(): the device is allowed
142  * to enter standby, but SPI module remains enabled.
143  * - _Note_: In slave mode, the device might enter standby while a byte is being
144  * transferred if SPI_transfer() is not called again after a successful
145  * transfer. This could result in corrupt data being transferred.
146  * - Application thread should typically either issue another transfer after
147  * SPI_transfer() completes successfully, or call
148  * SPI_transferCancel() to disable the SPI module and thus assuring that no data
149  * is received while entering standby.
150  * .
151  * - In master mode:
152  * - During SPI_transfer(): the device cannot enter standby, only idle.
153  * - After SPI_transfer() succeeds: the device can enter standby.
154  * - If SPI_transferCancel() is called: the device can enter standby.
155  *
156  * @note The external hardware connected to the SPI might have some pull configured on the
157  * SPI lines. When the SPI is inactive, this might cause leakage on the IO and the
158  * current consumption to increase. The application must configure a pull configuration
159  * that aligns with the external hardware.
160  * See [Ensure low power during inactive periods] (@ref USE_CASE_LPWR_X4) for code example.
161  *
162  * # SPI details #
163  * ## Chip Select #
164  * This SPI controller supports a hardware chip select pin. Refer to the
165  * user manual on how this hardware chip select pin behaves in regards
166  * to the SPI frame format.
167  *
168  * <table>
169  * <tr>
170  * <th>Chip select type</th>
171  * <th>SPI_MASTER mode</th>
172  * <th>SPI_SLAVE mode</th>
173  * </tr>
174  * <tr>
175  * <td>Hardware chip select</td>
176  * <td>No action is needed by the application to select the peripheral.</td>
177  * <td>See the device documentation on it's chip select requirements.</td>
178  * </tr>
179  * <tr>
180  * <td>Software chip select</td>
181  * <td>The application is responsible to ensure that correct SPI slave is
182  * selected before performing a SPI_transfer().</td>
183  * <td>See the device documentation on it's chip select requirements.</td>
184  * </tr>
185  * </table>
186  *
187  * ### Multiple slaves when operating in master mode #
188  * In a scenario where the SPI module is operating in master mode with multiple
189  * SPI slaves, the chip select pin can be reallocated at runtime to select the
190  * appropriate slave device. See [Master Mode With Multiple Slaves](@ref USE_CASE_MMMS_X4) use case below.
191  * This is only relevant when chip select is a hardware chip select. Otherwise the application
192  * can control the chip select pins directly using the GPIO driver.
193  *
194  * ## Data Frames #
195  *
196  * SPI data frames can be any size from 4-bits to 16-bits. If the dataSize in
197  * #SPI_Params is greater that 8-bits, then the SPICC26X4DMA driver
198  * implementation will assume that the #SPI_Transaction txBuf and rxBuf
199  * point to an array of 16-bit uint16_t elements.
200  *
201  * dataSize | buffer element size |
202  * -------- | ------------------- |
203  * 4-8 bits | uint8_t |
204  * 9-16 bits | uint16_t |
205  *
206  * ## Bit Rate ##
207  * When the SPI is configured as SPI slave, the maximum bit rate is 8MHz.
208  *
209  * When the SPI is configured as SPI master, the maximum bit rate is 12MHz.
210  *
211  *
212  * ## UDMA #
213  * ### Interrupts #
214  * The UDMA module generates IRQs on the SPI interrupt vector. This driver automatically
215  * installs a UDMA aware Hwi (interrupt) to service the assigned UDMA channels.
216  *
217  * ### Transfer Size Limit #
218  *
219  * The UDMA controller only supports data transfers of up to 1024 data frames.
220  * A transfer with more than 1024 frames will be transmitted/received in
221  * multiple 1024 sized portions until all data has been transmitted/received.
222  * A data frame can be 4 to 16 bits in length.
223  *
224  * ### Scratch Buffers #
225  * A uint16_t scratch buffer is used to allow SPI_transfers where txBuf or rxBuf
226  * are NULL. Rather than requiring txBuf or rxBuf to have a dummy buffer of size
227  * of the transfer count, a single-word UDMA accessible uint16_t scratch buffer is used.
228  * When rxBuf is NULL, the UDMA will transfer all the received SPI data into the
229  * scratch buffer as a "bit-bucket".
230  * When txBuf is NULL, the scratch buffer is initialized to defaultTxBufValue
231  * so the uDMA will send some known value.
232  * Each SPI driver instance uses its own scratch buffer.
233  *
234  * ### TX and RX buffers #
235  * Before SPI_transfer, txBuf should be filled with the outgoing SPI data. These
236  * data are sent out during the transfer, while the incoming data are received
237  * into rxBuf. To save memory space, txBuf and rxBuf can be assigned to the same
238  * buffer location. At the beginning of the transfer, this buffer holds outgoing
239  * data. At the end of the transfer, the outgoing data are overwritten and
240  * the buffer holds the received SPI data.
241  *
242  * ## Polling SPI transfers #
243  * When used in blocking mode small SPI transfers are can be done by polling
244  * the peripheral & sending data frame-by-frame. A master device can perform
245  * the transfer immediately and return, but a slave will block until it
246  * receives the number of frames specified in the SPI_Transfer() call.
247  * The minDmaTransferSize field in the hardware attributes is
248  * the threshold; if the transaction count is below the threshold a polling
249  * transfer is performed; otherwise a DMA transfer is done. This is intended
250  * to reduce the overhead of setting up a DMA transfer to only send a few
251  * data frames.
252  *
253  * Notes:
254  * - Specifying a timeout prevents slave devices from using polling transfers.
255  * - Keep in mind that during polling transfers the current task
256  * is still being executed; there is no context switch to another task.
257  *
258  * # Supported Functions #
259  * | Generic API function | API function | Description |
260  * |-----------------------|------------------------------- |-------------------------------------------------------------|
261  * | SPI_init() | SPICC26X4DMA_init() | Initialize SPI driver |
262  * | SPI_open() | SPICC26X4DMA_open() | Initialize SPI HW and set system dependencies |
263  * | SPI_close() | SPICC26X4DMA_close() | Disable SPI and UDMA HW and release system dependencies |
264  * | SPI_control() | SPICC26X4DMA_control() | Configure an already opened SPI handle |
265  * | SPI_transfer() | SPICC26X4DMA_transfer() | Start transfer from SPI |
266  * | SPI_transferCancel() | SPICC26X4DMA_transferCancel() | Cancel ongoing transfer from SPI |
267  *
268  * @note All calls should go through the generic API
269  *
270  * ## Use Cases @anchor USE_CASES_SPI_X4 ##
271  * ### Basic Slave Mode #
272  * Receive 100 bytes over SPI in #SPI_MODE_BLOCKING.
273  * @code
274  * SPI_Handle handle;
275  * SPI_Params params;
276  * SPI_Transaction transaction;
277  * uint8_t rxBuf[100]; // Receive buffer
278  *
279  * // Init SPI and specify non-default parameters
280  * SPI_Params_init(&params);
281  * params.bitRate = 1000000;
282  * params.frameFormat = SPI_POL1_PHA1;
283  * params.mode = SPI_SLAVE;
284  *
285  * // Configure the transaction
286  * transaction.count = 100;
287  * transaction.txBuf = NULL;
288  * transaction.rxBuf = rxBuf;
289  *
290  * // Open the SPI and perform the transfer
291  * handle = SPI_open(CONFIG_SPI, &params);
292  * SPI_transfer(handle, &transaction);
293  * @endcode
294  *
295  * ### Slave Mode With Return Partial @anchor USE_CASE_RP_X4 #
296  * This use case will perform a transfer in #SPI_MODE_BLOCKING until the wanted amount of bytes is
297  * transferred or until chip select is deasserted by the SPI master.
298  * This SPI_transfer() call can be used when unknown amount of bytes shall
299  * be transferred.
300  * Note: The partial return is also possible in #SPI_MODE_CALLBACK mode.
301  * Note: Polling transfers are not available when using return partial mode.
302  * @code
303  * SPI_Handle handle;
304  * SPI_Params params;
305  * SPI_Transaction transaction;
306  * uint8_t rxBuf[100]; // Receive buffer
307  *
308  * // Init SPI and specify non-default parameters
309  * SPI_Params_init(&params);
310  * params.bitRate = 1000000;
311  * params.frameFormat = SPI_POL1_PHA1;
312  * params.mode = SPI_SLAVE;
313  *
314  * // Configure the transaction
315  * transaction.count = 100;
316  * transaction.txBuf = NULL;
317  * transaction.rxBuf = rxBuf;
318  *
319  * // Open the SPI and initiate the partial read
320  * handle = SPI_open(CONFIG_SPI, &params);
321  *
322  * // Enable RETURN_PARTIAL
323  * SPI_control(handle, SPICC26X4DMA_RETURN_PARTIAL_ENABLE, NULL);
324  *
325  * // Begin transfer
326  * SPI_transfer(handle, &transaction);
327  * @endcode
328  *
329  * ### Continuous Slave Transfer In #SPI_MODE_CALLBACK @anchor USE_CASE_CST_X4 #
330  * This use case will configure the SPI driver to transfer continuously in
331  * #SPI_MODE_CALLBACK, 16 bytes at the time and echoing received data after every
332  * 16 bytes.
333  * @code
334  * // Callback function
335  * static void transferCallback(SPI_Handle handle, SPI_Transaction *transaction)
336  * {
337  * // Start another transfer
338  * SPI_transfer(handle, transaction);
339  * }
340  *
341  * static void taskFxn(uintptr_t a0, uintptr_t a1)
342  * {
343  * SPI_Handle handle;
344  * SPI_Params params;
345  * SPI_Transaction transaction;
346  * uint8_t buf[16]; // Receive and transmit buffer
347  *
348  * // Init SPI and specify non-default parameters
349  * SPI_Params_init(&params);
350  * params.bitRate = 1000000;
351  * params.frameFormat = SPI_POL1_PHA1;
352  * params.mode = SPI_SLAVE;
353  * params.transferMode = SPI_MODE_CALLBACK;
354  * params.transferCallbackFxn = transferCallback;
355  *
356  * // Configure the transaction
357  * transaction.count = 16;
358  * transaction.txBuf = buf;
359  * transaction.rxBuf = buf;
360  *
361  * // Open the SPI and initiate the first transfer
362  * handle = SPI_open(CONFIG_SPI, &params);
363  * SPI_transfer(handle, &transaction);
364  *
365  * // Wait forever
366  * while(true);
367  * }
368  * @endcode
369  *
370  * ### Basic Master Mode #
371  * This use case will configure a SPI master to send the data in txBuf while receiving data to rxBuf in
372  * BLOCKING_MODE.
373  * @code
374  * SPI_Handle handle;
375  * SPI_Params params;
376  * SPI_Transaction transaction;
377  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
378  * uint8_t rxBuf[11]; // Receive buffer
379  *
380  * // Init SPI and specify non-default parameters
381  * SPI_Params_init(&params);
382  * params.bitRate = 1000000;
383  * params.frameFormat = SPI_POL1_PHA1;
384  * params.mode = SPI_MASTER;
385  *
386  * // Configure the transaction
387  * transaction.count = sizeof(txBuf);
388  * transaction.txBuf = txBuf;
389  * transaction.rxBuf = rxBuf;
390  *
391  * // Open the SPI and perform the transfer
392  * handle = SPI_open(CONFIG_SPI, &params);
393  * SPI_transfer(handle, &transaction);
394  * @endcode
395  *
396  * ### Master Mode With Multiple Slaves @anchor USE_CASE_MMMS_X4 #
397  * This use case will configure a SPI master to send data to one slave and then to another in
398  * BLOCKING_MODE. It is assumed that SysConfig is configured so that the two chip select
399  * pins have a default setting of a high output and that the #SPICC26X4DMA_HWAttrs used points
400  * to one of them since the SPI driver will revert to this default setting when switching the
401  * chip select pin.
402  *
403  * @code
404  * // From ti_drivers_config.c
405  * // Use the sysconfig settings to make sure both pins are set to HIGH when not in use
406  * GPIO_PinConfig gpioPinConfigs[31] = {
407  * ...
408  * GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH, // CONFIG_CSN_0
409  * ...
410  * GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH, // CONFIG_CSN_1
411  * }
412  *
413  * const SPICC26X4DMA_HWAttrs SPICC26X4DMAHWAttrs[CC2650_SPICOUNT] = {
414  * { // Use SPI0 module with default chip select on CONFIG_CSN_0
415  * .baseAddr = SSI0_BASE,
416  * .intNum = INT_SSI0,
417  * .intPriority = ~0,
418  * .swiPriority = 0,
419  * .defaultTxBufValue = 0,
420  * .powerMngrId = PERIPH_SSI0,
421  * .rxChannelIndex = UDMA_CHAN_SSI0_RX,
422  * .txChannelIndex = UDMA_CHAN_SSI0_TX,
423  * .mosiPin = CONFIG_SPI0_MOSI,
424  * .misoPin = CONFIG_SPI0_MISO,
425  * .clkPin = CONFIG_SPI0_CLK,
426  * .csnPin = CONFIG_CSN_0
427  * }
428  *
429  * // From your_application.c
430  * static void taskFxn(uintptr_t a0, uintptr_t a1)
431  * {
432  * SPI_Handle handle;
433  * SPI_Params params;
434  * SPI_Transaction transaction;
435  * uint_least8_t csnPin1 = CONFIG_CSN_1;
436  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
437  *
438  * // Init SPI and specify non-default parameters
439  * SPI_Params_init(&params);
440  * params.bitRate = 1000000;
441  * params.frameFormat = SPI_POL1_PHA1;
442  * params.mode = SPI_MASTER;
443  *
444  * // Configure the transaction
445  * transaction.count = sizeof(txBuf);
446  * transaction.txBuf = txBuf;
447  * transaction.rxBuf = NULL;
448  *
449  * // Open the SPI and perform transfer to the first slave
450  * handle = SPI_open(CONFIG_SPI, &params);
451  * SPI_transfer(handle, &transaction);
452  *
453  * // Then switch chip select pin and perform transfer to the second slave
454  * SPI_control(handle, SPICC26X4DMA_SET_CSN_PIN, &csnPin1);
455  * SPI_transfer(handle, &transaction);
456  * }
457  * @endcode
458  *
459  * ### Queueing Transactions in Callback Mode #
460  * @anchor USE_CASE_QUEUE_X4
461  * Below is an example of queueing three transactions
462  * @code
463  * // SPI already opened in callback mode
464  * SPI_Transaction t0, t1, t2;
465  *
466  * t0.txBuf = txBuff0;
467  * t0.rxBuf = rxBuff0;
468  * t0.count = 2000;
469  *
470  * t1.txBuf = txBuff1;
471  * t1.rxBuf = rxBuff1;
472  * t1.count = 1000;
473  *
474  * t2.txBuf = txBuff2;
475  * t2.rxBuf = NULL;
476  * t2.count = 1000;
477  *
478  * bool transferOk = false;
479  *
480  * if (SPI_transfer(spiHandle, &t0)) {
481  * if (SPI_transfer(spiHandle, &t1)) {
482  * transferOk = SPI_transfer(spiHandle, &t2);
483  * }
484  * }
485  * }
486  * @endcode
487  *
488  * ### Queueing in Manual Start Mode#
489  * This example shows a slave device queueing two transactions that will
490  * complete one after the other. From the master's perspective there will be
491  * one long transfer.
492  * @note Manual mode also works while the device is in #SPI_MASTER mode. The
493  * control call to MANUAL_START will start the transfers.
494  *
495  * @warning Manual start mode should not be enabled or disabled while a
496  * transaction is in progress.
497  *
498  * @anchor USE_CASE_MANUAL_START_X4
499  * @code
500  * SPI_Handle spi;
501  * SPI_Params params;
502  * SPI_Transaction t0, t1;
503  * uint8_t status = SPI_STATUS_SUCCESS;
504  *
505  * SPI_Params_init(&params);
506  * params.mode = SPI_SLAVE;
507  * spi = SPI_open(CONFIG_SPI, &params);
508  *
509  * if (spi == NULL) {
510  * exit(0);
511  * }
512  *
513  * // Enable manual start mode
514  * SPI_control(spi, SPICC26X4DMA_CMD_SET_MANUAL, NULL);
515  *
516  * // Queue transactions
517  * t0.txBuf = txBuff0;
518  * t0.rxBuf = rxBuff0;
519  * t0.count = 2000;
520  * if (!SPI_transfer(spi, &t0)) {
521  * status = SPI_STATUS_FAIL;
522  * }
523  *
524  * t1.txBuf = txBuff1;
525  * t1.rxBuf = rxBuff1;
526  * t1.count = 1000;
527  * if (!SPI_transfer(spi, &t1)) {
528  * status = SPI_STATUS_FAIL;
529  * }
530  *
531  * // Enable the transfers
532  * if (status == SPI_STATUS_SUCCESS) {
533  * SPI_control(spi, SPICC26X4DMA_CMD_MANUAL_START, NULL);
534  * }
535  * else {
536  * status = SPI_STATUS_FAILURE;
537  * }
538  *
539  * // At this point the slave is ready for the master to start the transfer
540  * // Assume the callback implementation (not shown) posts a semaphore when
541  * // the last transaction completes
542  * sem_wait(&spiSemaphore);
543  *
544  * // Disable manual start mode
545  * SPI_control(spi, SPICC26X4DMA_CMD_CLR_MANUAL, NULL);
546  *
547  * @endcode
548  *
549  * ### Ensure low power during inactive periods @anchor USE_CASE_LPWR_X4 #
550  * External hardware connected on the SPI, i.e. SPI host/slave, might have configured
551  * a pull on one or more of the SPI lines. Dependent on the hardware, it might conflict
552  * with the pull used for the CC26X4 SPI. To avoid increased leakage and ensure the lowest
553  * possible power consumption when the SPI is inactive, the application must configure a
554  * matching pull on the SPI IOs. An example of how this can be done is shown below.
555  *
556  * @code
557  * PIN_Handle pinHandle;
558  * SPI_Handle handle;
559  * SPI_Params params;
560  * SPI_Transaction transaction;
561  * uint8_t txBuf[] = "Heartbeat"; // Transmit buffer
562  * uint8_t rxBuf[9]; // Receive buffer
563  * uint32_t standbyDurationMs = 100;
564  *
565  * // Init SPI and specify non-default parameters
566  * SPI_Params_init(&params);
567  * params.bitRate = 1000000;
568  * params.frameFormat = SPI_POL1_PHA1;
569  * params.mode = SPI_MASTER;
570  *
571  * // Configure the transaction
572  * transaction.count = sizeof(txBuf);
573  * transaction.txBuf = txBuf;
574  * transaction.rxBuf = rxBuf;
575  *
576  * // Open the SPI and perform the transfer
577  * handle = SPI_open(CONFIG_SPI_0, &params);
578  *
579  * // Apply low power sleep pull config for MISO
580  * GPIO_setConfig(CONFIG_GPIO_SPI_0_MISO, GPIO_CFG_IN_PU);
581  *
582  * // Do forever
583  * while(1) {
584  * // Transfer data
585  * SPI_transfer(handle, &transaction);
586  * // Sleep
587  * Task_sleep(standbyDurationMs*100);
588  * }
589  * @endcode
590  *
591  * ### Wake Up On Chip Select Deassertion In Slave Mode Using #SPI_MODE_CALLBACK #
592  * This example demonstrates using a GPIO callback on Chip Select to wake up the device
593  * to allow low power modes while waiting for a chip select edge.
594  *
595  * In sysconfig or the board file, the CSN GPIO should be configured
596  * as input/pull up with an interrupt on falling edge. Otherwise, SPI_close()
597  * will reset the pin to the wrong settings and you may see line glitches.
598  *
599  * *Note: The SPI master must allow enough time between deasserting the chip select and the
600  * start of the transaction for the SPI slave to wake up and open up the SPI driver.
601  *
602  * @code
603  * // Global variables
604  * SPI_Handle spiHandle
605  * SPI_Params spiParams;
606  * SPI_Transaction spiTransaction;
607  * const uint8_t transferSize = 8;
608  * uint8_t txBuf[8];
609  *
610  * // Chip select callback
611  * static void chipSelectCallback(uint_least8_t)
612  * {
613  * // Open SPI driver, which will override any previous GPIO configuration
614  * spiHandle = SPI_open(CONFIG_SPI, &spiParams);
615  * // Issue the transfer
616  * SPI_transfer(spiHandle, &spiTransaction);
617  * }
618  *
619  * // SPI transfer callback
620  * static void transferCallback(SPI_Handle handle, SPI_Transaction *transaction)
621  * {
622  * // Close the SPI driver
623  * SPI_close(handle);
624  *
625  * // Note: SPI_close() will reset the pin configuration, so it is important to
626  * // set the default values correctly in sysconfig. We just need to set the
627  * // callback and enable the falling edge interrupt
628  *
629  * GPIO_setCallback(CS_PIN_INDEX, chipSelectCallback);
630  * GPIO_enableInt(CS_PIN_INDEX);
631  * }
632  *
633  * // From your_application.c
634  * static void taskFxn(uintptr_t a0, uintptr_t a1)
635  * {
636  * uint8_t i;
637  *
638  * // Setup SPI params
639  * SPI_Params_init(&spiParams);
640  * spiParams.bitRate = 1000000;
641  * spiParams.frameFormat = SPI_POL1_PHA1;
642  * spiParams.mode = SPI_SLAVE;
643  * spiParams.dataSize = transferSize;
644  * spiParams.transferMode = SPI_MODE_CALLBACK;
645  * spiParams.transferCallbackFxn = transferCallback;
646  *
647  * // Setup SPI transaction
648  * spiTransaction.arg = NULL;
649  * spiTransaction.count = transferSize;
650  * spiTransaction.txBuf = txBuf;
651  * spiTransaction.rxBuf = txBuf;
652  *
653  * // First echo message
654  * for (i = 0; i < transferSize; i++) {
655  * txBuf[i] = i;
656  * }
657  *
658  * // Configure chip select callback
659  * GPIO_setCallback(CS_PIN_INDEX, chipSelectCallback);
660  * GPIO_enableInt(CS_PIN_INDEX);
661  *
662  * // Wait forever
663  * while(true);
664  * }
665  * @endcode
666  *
667  * <hr>
668  */
669 
670 #ifndef ti_drivers_spi_SPICC26X4DMA__include
671 #define ti_drivers_spi_SPICC26X4DMA__include
672 
673 #include <stdint.h>
674 #include <ti/drivers/SPI.h>
677 #include <ti/drivers/Power.h>
679 
680 #include <ti/drivers/dpl/HwiP.h>
681 #include <ti/drivers/dpl/SemaphoreP.h>
682 #include <ti/drivers/dpl/SwiP.h>
683 
684 #ifdef __cplusplus
685 extern "C" {
686 #endif
687 
698 /* Add SPICC26X4DMA_STATUS_* macros here */
699 
720 #define SPICC26X4DMA_CMD_RETURN_PARTIAL_ENABLE (SPI_CMD_RESERVED + 0)
721 
729 #define SPICC26X4DMA_CMD_RETURN_PARTIAL_DISABLE (SPI_CMD_RESERVED + 1)
730 
737 #define SPICC26X4DMA_CMD_SET_CSN_PIN (SPI_CMD_RESERVED + 2)
738 
744 #define SPICC26X4DMA_CMD_CLEAR_CSN_PIN (SPI_CMD_RESERVED + 3)
745 
759 #define SPICC26X4DMA_CMD_SET_MANUAL (SPI_CMD_RESERVED + 4)
760 
770 #define SPICC26X4DMA_CMD_CLR_MANUAL (SPI_CMD_RESERVED + 5)
771 
782 #define SPICC26X4DMA_CMD_MANUAL_START (SPI_CMD_RESERVED + 6)
783 
803 #define SPICC26X4DMA_CMD_SET_SAMPLE_DELAY (SPI_CMD_RESERVED + 7)
804 
807 /* BACKWARDS COMPATIBILITY */
808 #define SPICC26X4DMA_RETURN_PARTIAL_ENABLE SPICC26X4DMA_CMD_RETURN_PARTIAL_ENABLE
809 #define SPICC26X4DMA_RETURN_PARTIAL_DISABLE SPICC26X4DMA_CMD_RETURN_PARTIAL_DISABLE
810 #define SPICC26X4DMA_SET_CSN_PIN SPICC26X4DMA_CMD_SET_CSN_PIN
811 /* END BACKWARDS COMPATIBILITY */
812 
819 
829 typedef enum {
833 
841 typedef enum {
846 
901 typedef struct {
903  uint32_t baseAddr;
905  uint8_t intNum;
920  uint8_t intPriority;
927  uint32_t swiPriority;
929  PowerCC26XX_Resource powerMngrId;
937  volatile tDMAControlTable *dmaTxTableEntryPri;
939  volatile tDMAControlTable *dmaRxTableEntryPri;
941  volatile tDMAControlTable *dmaTxTableEntryAlt;
943  volatile tDMAControlTable *dmaRxTableEntryAlt;
945  int32_t txPinMux;
947  int32_t rxPinMux;
949  int32_t clkPinMux;
951  int32_t csnPinMux;
960 
964 
970 typedef struct {
971  HwiP_Struct hwi;
975  SwiP_Struct swi;
976  SemaphoreP_Struct transferComplete;
977 
983 
984  size_t framesQueued;
988 
989  uint32_t activeChannel;
990  uint32_t bitRate;
991  uint32_t dataSize;
992  uint32_t transferTimeout;
993  uint32_t busyBit;
994  uint32_t dsample;
995 
996  uint16_t rxScratchBuf;
997  uint16_t txScratchBuf;
998 
1001  uint8_t format;
1004  bool isOpen;
1007 
1008 #ifdef __cplusplus
1009 }
1010 #endif
1011 
1012 #endif /* ti_drivers_spi_SPICC26X4DMA__include */
volatile tDMAControlTable * dmaTxTableEntryPri
Definition: SPICC26X4DMA.h:937
uint8_t PIN_Id
Pin identifier data type.
Definition: PIN.h:584
Definition: SPICC26X4DMA.h:830
uint32_t baseAddr
SPI Peripheral&#39;s base address.
Definition: SPICC26X4DMA.h:903
PIN_Id csnPin
Definition: SPICC26X4DMA.h:1002
PIN_State pinState
Definition: SPICC26X4DMA.h:973
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:584
SPICC26X4DMA Object.
Definition: SPICC26X4DMA.h:970
uint8_t intNum
Definition: SPICC26X4DMA.h:905
SPICC26X4DMA_ReturnPartial returnPartial
Definition: SPICC26X4DMA.h:1003
PowerCC26XX_Resource powerMngrId
Definition: SPICC26X4DMA.h:929
SPI_TransferMode
SPI transfer mode determines the whether the SPI controller operates synchronously or asynchronously...
Definition: SPI.h:620
volatile tDMAControlTable * dmaRxTableEntryAlt
Definition: SPICC26X4DMA.h:943
Definition: SPICC26X4DMA.h:843
Power Manager.
Definition: SPICC26X4DMA.h:831
int32_t txPinMux
Definition: SPICC26X4DMA.h:945
UDMACC26XX Global configuration.
Definition: UDMACC26XX.h:235
Power manager interface for CC26XX/CC13XX.
uint8_t intPriority
SPI CC26X4DMA Peripheral&#39;s interrupt priority.
Definition: SPICC26X4DMA.h:920
int32_t clkPinMux
Definition: SPICC26X4DMA.h:949
uint32_t bitRate
Definition: SPICC26X4DMA.h:990
UDMACC26XX_Handle udmaHandle
Definition: SPICC26X4DMA.h:982
uint32_t transferTimeout
Definition: SPICC26X4DMA.h:992
The definition of a SPI function table that contains the required set of functions to control a speci...
Definition: SPI.h:709
int32_t csnPinMux
Definition: SPICC26X4DMA.h:951
SPICC26X4DMA Hardware attributes.
Definition: SPICC26X4DMA.h:901
SPICC26X4DMA_ReturnPartial
Definition: SPICC26X4DMA.h:841
volatile tDMAControlTable * dmaTxTableEntryAlt
Definition: SPICC26X4DMA.h:941
PIN_Id misoPin
Definition: SPICC26X4DMA.h:955
uint8_t format
Definition: SPICC26X4DMA.h:1001
Device-specific pin & GPIO driver for CC26xx family [def].
SPI_Transaction * completedTransfers
Definition: SPICC26X4DMA.h:981
size_t altTransferSize
Definition: SPICC26X4DMA.h:987
int32_t rxPinMux
Definition: SPICC26X4DMA.h:947
SwiP_Struct swi
Definition: SPICC26X4DMA.h:975
UDMACC26XX driver implementation.
A SPI_Transaction data structure is used with SPI_transfer(). It indicates how many SPI_FrameFormat f...
Definition: SPI.h:563
Power notify object structure.
Definition: Power.h:443
uint32_t txChannelBitMask
Definition: SPICC26X4DMA.h:935
Definition: SPICC26X4DMA.h:844
SPI_Mode
Definitions for various SPI modes of operation.
Definition: SPI.h:590
PIN_Id csnPin
Definition: SPICC26X4DMA.h:959
uint32_t activeChannel
Definition: SPICC26X4DMA.h:989
PIN_Handle pinHandle
Definition: SPICC26X4DMA.h:972
SPI_TransferMode transferMode
Definition: SPICC26X4DMA.h:999
uint32_t minDmaTransferSize
Definition: SPICC26X4DMA.h:962
underlying data structure for type PIN_State
Definition: PIN.h:714
SPI_Mode mode
Definition: SPICC26X4DMA.h:1000
uint32_t dataSize
Definition: SPICC26X4DMA.h:991
size_t framesQueued
Definition: SPICC26X4DMA.h:984
SPI_CallbackFxn transferCallbackFxn
Definition: SPICC26X4DMA.h:978
SPI_Transaction * headPtr
Definition: SPICC26X4DMA.h:979
uint16_t defaultTxBufValue
Definition: SPICC26X4DMA.h:931
uint32_t busyBit
Definition: SPICC26X4DMA.h:993
const SPI_FxnTable SPICC26X4DMA_fxnTable
PIN_Id clkPin
Definition: SPICC26X4DMA.h:957
uint32_t rxChannelBitMask
Definition: SPICC26X4DMA.h:933
PIN_Id mosiPin
Definition: SPICC26X4DMA.h:953
size_t priTransferSize
Definition: SPICC26X4DMA.h:986
size_t framesTransferred
Definition: SPICC26X4DMA.h:985
HwiP_Struct hwi
Definition: SPICC26X4DMA.h:971
uint16_t rxScratchBuf
Definition: SPICC26X4DMA.h:996
uint32_t swiPriority
SPI SWI priority. The higher the number, the higher the priority. The minimum is 0 and the maximum is...
Definition: SPICC26X4DMA.h:927
bool manualStart
Definition: SPICC26X4DMA.h:1005
Definition: SPICC26X4DMA.h:842
volatile tDMAControlTable * dmaRxTableEntryPri
Definition: SPICC26X4DMA.h:939
uint16_t txScratchBuf
Definition: SPICC26X4DMA.h:997
uint32_t dsample
Definition: SPICC26X4DMA.h:994
SPI_Transaction * tailPtr
Definition: SPICC26X4DMA.h:980
SemaphoreP_Struct transferComplete
Definition: SPICC26X4DMA.h:976
SPICC26X4DMA_FrameSize
Definition: SPICC26X4DMA.h:829
Power_NotifyObj spiPostObj
Definition: SPICC26X4DMA.h:974
bool isOpen
Definition: SPICC26X4DMA.h:1004
© Copyright 1995-2022, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale