SPICC26X2DMA.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2019, 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 SPICC26X2DMA.h
34  *
35  * @brief SPI driver implementation for a CC26XX 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/SPICC26X2DMA.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 SPICC26X2DMA_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_X2).
57  *
58  * # General Behavior #
59  * Before using SPI on CC26XX:
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  * to 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 "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 #SPICC26X2DMA_CMD_SET_MANUAL command. In this mode, the driver will
71  * not start any queued transfers until SPI_control() is called with the
72  * #SPICC26X2DMA_CMD_MANUAL_START command. This mode is off by default and
73  * can be disabled by using command #SPICC26X2DMA_CMD_CLR_MANUAL. See the
74  * @ref USE_CASE_MANUAL_START "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 occur 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 goes full in order to
84  * avoid overflow. If the TX buffer is underflowed, 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_X2) use case below.
87  * - The SPI driver supports partial return, that can be used if the
88  * transfer size is unknown. If #SPICC26X2DMA_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_X2) 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 "Manual Start mode."
97  *
98  * @warning The SPI modules on the CC13x0, CC26x0, and CC26x0R2 devices have a
99  * bug which may result in TX data being lost when operating in SPI slave
100  * mode. Please refer to the device errata sheet for full details. The SPI
101  * protocol should therefore include a data integrity check, such as
102  * appending a CRC to the payload to ensure all the data was transmitted
103  * correctly by the SPI slave.
104  *
105  * The following apply for master operation:
106  * - SPI and UDMA modules are enabled by calling SPI_transfer().
107  * - If the SPI_transfer() succeeds, SPI module is enabled and UDMA module is disabled.
108  * - If SPI_transferCancel() is called, SPI and UDMA modules are disabled and
109  * TX and RX FIFOs are flushed.
110  * .
111  * After SPI operation has ended:
112  * - Release system dependencies for SPI by calling SPI_close().
113  * .
114  * The callback function is always called in a SWI context.
115  *
116  * @warning The application should avoid transmitting data stored in flash via SPI if the application
117  * might switch to the XOSC_HF, the high frequency external oscillator, during this transfer.
118  *
119  * # Error handling #
120  * If an RX overrun occurs during slave operation:
121  * - If a transfer is ongoing, all bytes received up until the error occurs will be returned, with the
122  * error signaled in the #SPI_Transaction.status field. RX overrun IRQ, SPI and UDMA modules are then disabled,
123  * TX and RX FIFOs are flushed and all bytes will be ignored until a new transfer is issued.
124  * - If a transfer is not ongoing, RX overrun IRQ, SPI and UDMA modules are disabled,
125  * TX and RX FIFOs are flushed and all bytes will be ignored until a new transfer is issued.
126  *
127  * # Timeout #
128  * Timeout can occur in #SPI_MODE_BLOCKING, there's no timeout in #SPI_MODE_CALLBACK.
129  * When in #SPI_MODE_CALLBACK, the transfer must be cancelled by calling SPI_transferCancel().@n
130  * If a timeout happens in either #SPI_SLAVE or #SPI_MASTER mode,
131  * the receive buffer will contain the bytes received up until the timeout occurred.
132  * The SPI transaction status will be set to #SPI_TRANSFER_FAILED.
133  * The SPI transaction count will be set to the number of bytes sent/received before timeout.
134  * The remaining bytes will be flushed from the TX FIFO so that the subsequent transfer
135  * can be executed correctly. Note that specifying a timeout prevents the
136  * driver from performing a polling transfer when in slave mode.
137  *
138  * # Power Management #
139  * The TI-RTOS power management framework will try to put the device into the most
140  * power efficient mode whenever possible. Please see the technical reference
141  * manual for further details on each power mode.
142  *
143  * The SPICC26X2DMA.h driver is setting a power constraint during transfers to keep
144  * the device out of standby. When the transfer has finished, the power
145  * constraint is released.
146  * The following statements are valid:
147  * - After SPI_open(): the device is still allowed to enter standby.
148  * - In slave mode:
149  * - During SPI_transfer(): the device cannot enter standby, only idle.
150  * - After an RX overflow: device is allowed to enter standby.
151  * - After a successful SPI_transfer(): the device is allowed
152  * to enter standby, but SPI module remains enabled.
153  * - _Note_: In slave mode, the device might enter standby while a byte is being
154  * transferred if SPI_transfer() is not called again after a successful
155  * transfer. This could result in corrupt data being transferred.
156  * - Application thread should typically either issue another transfer after
157  * SPI_transfer() completes successfully, or call
158  * SPI_transferCancel() to disable the SPI module and thus assuring that no data
159  * is received while entering standby.
160  * .
161  * - In master mode:
162  * - During SPI_transfer(): the device cannot enter standby, only idle.
163  * - After SPI_transfer() succeeds: the device can enter standby.
164  * - If SPI_transferCancel() is called: the device can enter standby.
165  *
166  * @note The external hardware connected to the SPI might have some pull configured on the
167  * SPI lines. When the SPI is inactive, this might cause leakage on the IO and the
168  * current consumption to increase. The application must configure a pull configuration
169  * that aligns with the external hardware.
170  * See [Ensure low power during inactive periods] (@ref USE_CASE_LPWR_X2) for code example.
171  *
172  * # SPI details #
173  * ## Chip Select #
174  * This SPI controller supports a hardware chip select pin. Refer to the
175  * user manual on how this hardware chip select pin behaves in regards
176  * to the SPI frame format.
177  *
178  * <table>
179  * <tr>
180  * <th>Chip select type</th>
181  * <th>SPI_MASTER mode</th>
182  * <th>SPI_SLAVE mode</th>
183  * </tr>
184  * <tr>
185  * <td>Hardware chip select</td>
186  * <td>No action is needed by the application to select the peripheral.</td>
187  * <td>See the device documentation on it's chip select requirements.</td>
188  * </tr>
189  * <tr>
190  * <td>Software chip select</td>
191  * <td>The application is responsible to ensure that correct SPI slave is
192  * selected before performing a SPI_transfer().</td>
193  * <td>See the device documentation on it's chip select requirements.</td>
194  * </tr>
195  * </table>
196  *
197  * ### Multiple slaves when operating in master mode #
198  * In a scenario where the SPI module is operating in master mode with multiple
199  * SPI slaves, the chip select pin can be reallocated at runtime to select the
200  * appropriate slave device. See [Master Mode With Multiple Slaves](@ref USE_CASE_MMMS_X2) use case below.
201  * This is only relevant when chip select is a hardware chip select. Otherwise the application
202  * can control the chip select pins directly using the PIN driver.
203  *
204  * ## Data Frames #
205  *
206  * SPI data frames can be any size from 4-bits to 16-bits. If the dataSize in
207  * #SPI_Params is greater that 8-bits, then the SPICC26X2DMA driver
208  * implementation will assume that the #SPI_Transaction txBuf and rxBuf
209  * point to an array of 16-bit uint16_t elements.
210  *
211  * dataSize | buffer element size |
212  * -------- | ------------------- |
213  * 4-8 bits | uint8_t |
214  * 9-16 bits | uint16_t |
215  *
216  * ## Bit Rate ##
217  * When the SPI is configured as SPI slave, the maximum bit rate is 4MHz.
218  *
219  * When the SPI is configured as SPI master, the maximum bit rate is 12MHz.
220  *
221  *
222  * ## UDMA #
223  * ### Interrupts #
224  * The UDMA module generates IRQs on the SPI interrupt vector. This driver automatically
225  * installs a UDMA aware Hwi (interrupt) to service the assigned UDMA channels.
226  *
227  * ### Transfer Size Limit #
228  *
229  * The UDMA controller only supports data transfers of up to 1024 data frames.
230  * A transfer with more than 1024 frames will be transmitted/received in
231  * multiple 1024 sized portions until all data has been transmitted/received.
232  * A data frame can be 4 to 16 bits in length.
233  *
234  * ### Scratch Buffers #
235  * A uint16_t scratch buffer is used to allow SPI_transfers where txBuf or rxBuf
236  * are NULL. Rather than requiring txBuf or rxBuf to have a dummy buffer of size
237  * of the transfer count, a single-word UDMA accessible uint16_t scratch buffer is used.
238  * When rxBuf is NULL, the UDMA will transfer all the received SPI data into the
239  * scratch buffer as a "bit-bucket".
240  * When txBuf is NULL, the scratch buffer is initialized to defaultTxBufValue
241  * so the uDMA will send some known value.
242  * Each SPI driver instance uses its own scratch buffer.
243  *
244  * ### TX and RX buffers #
245  * Before SPI_transfer, txBuf should be filled with the outgoing SPI data. These
246  * data are sent out during the transfer, while the incoming data are received
247  * into rxBuf. To save memory space, txBuf and rxBuf can be assigned to the same
248  * buffer location. At the beginning of the transfer, this buffer holds outgoing
249  * data. At the end of the transfer, the outgoing data are overwritten and
250  * the buffer holds the received SPI data.
251  *
252  * ## Polling SPI transfers #
253  * When used in blocking mode small SPI transfers are can be done by polling
254  * the peripheral & sending data frame-by-frame. A master device can perform
255  * the transfer immediately and return, but a slave will block until it
256  * receives the number of frames specified in the SPI_Transfer() call.
257  * The minDmaTransferSize field in the hardware attributes is
258  * the threshold; if the transaction count is below the threshold a polling
259  * transfer is performed; otherwise a DMA transfer is done. This is intended
260  * to reduce the overhead of setting up a DMA transfer to only send a few
261  * data frames.
262  *
263  * Notes:
264  * - Specifying a timeout prevents slave devices from using polling transfers.
265  * - Keep in mind that during polling transfers the current task
266  * is still being executed; there is no context switch to another task.
267  *
268  * # Supported Functions #
269  * | Generic API function | API function | Description |
270  * |-----------------------|------------------------------- |-------------------------------------------------------------|
271  * | SPI_init() | SPICC26X2DMA_init() | Initialize SPI driver |
272  * | SPI_open() | SPICC26X2DMA_open() | Initialize SPI HW and set system dependencies |
273  * | SPI_close() | SPICC26X2DMA_close() | Disable SPI and UDMA HW and release system dependencies |
274  * | SPI_control() | SPICC26X2DMA_control() | Configure an already opened SPI handle |
275  * | SPI_transfer() | SPICC26X2DMA_transfer() | Start transfer from SPI |
276  * | SPI_transferCancel() | SPICC26X2DMA_transferCancel() | Cancel ongoing transfer from SPI |
277  *
278  * @note All calls should go through the generic API
279  *
280  * ## Use Cases @anchor USE_CASES_SPI_X2 ##
281  * ### Basic Slave Mode #
282  * Receive 100 bytes over SPI in #SPI_MODE_BLOCKING.
283  * @code
284  * SPI_Handle handle;
285  * SPI_Params params;
286  * SPI_Transaction transaction;
287  * uint8_t rxBuf[100]; // Receive buffer
288  *
289  * // Init SPI and specify non-default parameters
290  * SPI_Params_init(&params);
291  * params.bitRate = 1000000;
292  * params.frameFormat = SPI_POL1_PHA1;
293  * params.mode = SPI_SLAVE;
294  *
295  * // Configure the transaction
296  * transaction.count = 100;
297  * transaction.txBuf = NULL;
298  * transaction.rxBuf = rxBuf;
299  *
300  * // Open the SPI and perform the transfer
301  * handle = SPI_open(Board_SPI, &params);
302  * SPI_transfer(handle, &transaction);
303  * @endcode
304  *
305  * ### Slave Mode With Return Partial @anchor USE_CASE_RP_X2 #
306  * This use case will perform a transfer in #SPI_MODE_BLOCKING until the wanted amount of bytes is
307  * transferred or until chip select is deasserted by the SPI master.
308  * This SPI_transfer() call can be used when unknown amount of bytes shall
309  * be transferred. Note: The partial return is also possible in #SPI_MODE_CALLBACK mode.
310  * @code
311  * SPI_Handle handle;
312  * SPI_Params params;
313  * SPI_Transaction transaction;
314  * uint8_t rxBuf[100]; // Receive buffer
315  *
316  * // Init SPI and specify non-default parameters
317  * SPI_Params_init(&params);
318  * params.bitRate = 1000000;
319  * params.frameFormat = SPI_POL1_PHA1;
320  * params.mode = SPI_SLAVE;
321  *
322  * // Configure the transaction
323  * transaction.count = 100;
324  * transaction.txBuf = NULL;
325  * transaction.rxBuf = rxBuf;
326  *
327  * // Open the SPI and initiate the partial read
328  * handle = SPI_open(Board_SPI, &params);
329  *
330  * // Enable RETURN_PARTIAL
331  * SPI_control(handle, SPICC26X2DMA_RETURN_PARTIAL_ENABLE, NULL);
332  *
333  * // Begin transfer
334  * SPI_transfer(handle, &transaction);
335  * @endcode
336  *
337  * ### Continuous Slave Transfer In #SPI_MODE_CALLBACK @anchor USE_CASE_CST_X2 #
338  * This use case will configure the SPI driver to transfer continuously in
339  * #SPI_MODE_CALLBACK, 16 bytes at the time and echoing received data after every
340  * 16 bytes.
341  * @code
342  * // Callback function
343  * static void transferCallback(SPI_Handle handle, SPI_Transaction *transaction)
344  * {
345  * // Start another transfer
346  * SPI_transfer(handle, transaction);
347  * }
348  *
349  * static void taskFxn(uintptr_t a0, uintptr_t a1)
350  * {
351  * SPI_Handle handle;
352  * SPI_Params params;
353  * SPI_Transaction transaction;
354  * uint8_t buf[16]; // Receive and transmit buffer
355  *
356  * // Init SPI and specify non-default parameters
357  * SPI_Params_init(&params);
358  * params.bitRate = 1000000;
359  * params.frameFormat = SPI_POL1_PHA1;
360  * params.mode = SPI_SLAVE;
361  * params.transferMode = SPI_MODE_CALLBACK;
362  * params.transferCallbackFxn = transferCallback;
363  *
364  * // Configure the transaction
365  * transaction.count = 16;
366  * transaction.txBuf = buf;
367  * transaction.rxBuf = buf;
368  *
369  * // Open the SPI and initiate the first transfer
370  * handle = SPI_open(Board_SPI, &params);
371  * SPI_transfer(handle, &transaction);
372  *
373  * // Wait forever
374  * while(true);
375  * }
376  * @endcode
377  *
378  * ### Basic Master Mode #
379  * This use case will configure a SPI master to send the data in txBuf while receiving data to rxBuf in
380  * BLOCKING_MODE.
381  * @code
382  * SPI_Handle handle;
383  * SPI_Params params;
384  * SPI_Transaction transaction;
385  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
386  * uint8_t rxBuf[11]; // Receive buffer
387  *
388  * // Init SPI and specify non-default parameters
389  * SPI_Params_init(&params);
390  * params.bitRate = 1000000;
391  * params.frameFormat = SPI_POL1_PHA1;
392  * params.mode = SPI_MASTER;
393  *
394  * // Configure the transaction
395  * transaction.count = sizeof(txBuf);
396  * transaction.txBuf = txBuf;
397  * transaction.rxBuf = rxBuf;
398  *
399  * // Open the SPI and perform the transfer
400  * handle = SPI_open(Board_SPI, &params);
401  * SPI_transfer(handle, &transaction);
402  * @endcode
403  *
404  * ### Master Mode With Multiple Slaves @anchor USE_CASE_MMMS_X2 #
405  * This use case will configure a SPI master to send data to one slave and then to another in
406  * BLOCKING_MODE. It is assumed that the board file is configured so that the two chip select
407  * pins have a default setting of a high output and that the #SPICC26X2DMA_HWAttrs used points
408  * to one of them since the SPI driver will revert to this default setting when switching the
409  * chip select pin.
410  *
411  * @code
412  * // From board.c
413  * PIN_Config BoardGpioInitTable[] = {
414  * Board_CSN_0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL, // Ensure SPI slave 0 is not selected
415  * Board_CSN_1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL // Ensure SPI slave 1 is not selected
416  * }
417  *
418  * const SPICC26X2DMA_HWAttrs SPICC26X2DMAHWAttrs[CC2650_SPICOUNT] = {
419  * { // Use SPI0 module with default chip select on Board_CSN_0
420  * .baseAddr = SSI0_BASE,
421  * .intNum = INT_SSI0,
422  * .intPriority = ~0,
423  * .swiPriority = 0,
424  * .defaultTxBufValue = 0,
425  * .powerMngrId = PERIPH_SSI0,
426  * .rxChannelIndex = UDMA_CHAN_SSI0_RX,
427  * .txChannelIndex = UDMA_CHAN_SSI0_TX,
428  * .mosiPin = Board_SPI0_MOSI,
429  * .misoPin = Board_SPI0_MISO,
430  * .clkPin = Board_SPI0_CLK,
431  * .csnPin = Board_CSN_0
432  * }
433  *
434  * // From your_application.c
435  * static void taskFxn(uintptr_t a0, uintptr_t a1)
436  * {
437  * SPI_Handle handle;
438  * SPI_Params params;
439  * SPI_Transaction transaction;
440  * PIN_Id csnPin1 = PIN_ID(Board_CSN_1);
441  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
442  *
443  * // Init SPI and specify non-default parameters
444  * SPI_Params_init(&params);
445  * params.bitRate = 1000000;
446  * params.frameFormat = SPI_POL1_PHA1;
447  * params.mode = SPI_MASTER;
448  *
449  * // Configure the transaction
450  * transaction.count = sizeof(txBuf);
451  * transaction.txBuf = txBuf;
452  * transaction.rxBuf = NULL;
453  *
454  * // Open the SPI and perform transfer to the first slave
455  * handle = SPI_open(Board_SPI, &params);
456  * SPI_transfer(handle, &transaction);
457  *
458  * // Then switch chip select pin and perform transfer to the second slave
459  * SPI_control(handle, SPICC26X2DMA_SET_CSN_PIN, &csnPin1);
460  * SPI_transfer(handle, &transaction);
461  * }
462  * @endcode
463  *
464  * ### Queueing Transactions in Callback Mode #
465  * @anchor USE_CASE_QUEUE
466  * Below is an example of queueing three transactions
467  * @code
468  * // SPI already opened in callback mode
469  * SPI_Transaction t0, t1, t2;
470  *
471  * t0.txBuf = txBuff0;
472  * t0.rxBuf = rxBuff0;
473  * t0.count = 2000;
474  *
475  * t1.txBuf = txBuff1;
476  * t1.rxBuf = rxBuff1;
477  * t1.count = 1000;
478  *
479  * t2.txBuf = txBuff2;
480  * t2.rxBuf = NULL;
481  * t2.count = 1000;
482  *
483  * bool transferOk = false;
484  *
485  * if (SPI_transfer(spiHandle, &t0)) {
486  * if (SPI_transfer(spiHandle, &t1)) {
487  * transferOk = SPI_transfer(spiHandle, &t2);
488  * }
489  * }
490  * }
491  * @endcode
492  *
493  * ### Queueing in Manual Start Mode#
494  * This example shows a slave device queueing two transactions that will
495  * complete one after the other. From the master's perspective there will be
496  * one long transfer.
497  * @note Manual mode also works while the device is in #SPI_MASTER mode. The
498  * control call to MANUAL_START will start the transfers.
499  *
500  * @warning Manual start mode should not be enabled or disabled while a
501  * transaction is in progress.
502  *
503  * @anchor USE_CASE_MANUAL_START
504  * @code
505  * SPI_Handle spi;
506  * SPI_Params params;
507  * SPI_Transaction t0, t1;
508  * uint8_t status = SPI_STATUS_SUCCESS;
509  *
510  * SPI_Params_init(&params);
511  * params.mode = SPI_SLAVE;
512  * spi = SPI_open(Board_SPI, &params);
513  *
514  * if (spi == NULL) {
515  * exit(0);
516  * }
517  *
518  * // Enable manual start mode
519  * SPI_control(spi, SPICC26X2DMA_CMD_SET_MANUAL, NULL);
520  *
521  * // Queue transactions
522  * t0.txBuf = txBuff0;
523  * t0.rxBuf = rxBuff0;
524  * t0.count = 2000;
525  * if (!SPI_transfer(spi, &t0)) {
526  * status = SPI_STATUS_FAIL;
527  * }
528  *
529  * t1.txBuf = txBuff1;
530  * t1.rxBuf = rxBuff1;
531  * t1.count = 1000;
532  * if (!SPI_transfer(spi, &t1)) {
533  * status = SPI_STATUS_FAIL;
534  * }
535  *
536  * // Enable the transfers
537  * if (status == SPI_STATUS_SUCCESS) {
538  * SPI_control(spi, SPICC26X2DMA_CMD_MANUAL_START, NULL);
539  * }
540  * else {
541  * status = SPI_STATUS_FAILURE;
542  * }
543  *
544  * // At this point the slave is ready for the master to start the transfer
545  * // Assume the callback implementation (not shown) posts a semaphore when
546  * // the last transaction completes
547  * sem_wait(&spiSemaphore);
548  *
549  * // Disable manual start mode
550  * SPI_control(spi, SPICC26X2DMA_CMD_CLR_MANUAL, NULL);
551  *
552  * @endcode
553  *
554  * ### Ensure low power during inactive periods @anchor USE_CASE_LPWR_X2 #
555  * External hardware connected on the SPI, i.e. SPI host/slave, might have configured
556  * a pull on one or more of the SPI lines. Dependent on the hardware, it might conflict
557  * with the pull used for the CC26XX SPI. To avoid increased leakage and ensure the lowest
558  * possible power consumption when the SPI is inactive, the application must configure a
559  * matching pull on the SPI IOs. An example of how this can be done is shown below.
560  *
561  * @code
562  * PIN_Handle pinHandle;
563  * SPI_Handle handle;
564  * SPI_Params params;
565  * SPI_Transaction transaction;
566  * uint8_t txBuf[] = "Heartbeat"; // Transmit buffer
567  * uint8_t rxBuf[9]; // Receive buffer
568  * PIN_Id misoPinId;
569  * uint32_t standbyDurationMs = 100;
570  *
571  * // Init SPI and specify non-default parameters
572  * SPI_Params_init(&params);
573  * params.bitRate = 1000000;
574  * params.frameFormat = SPI_POL1_PHA1;
575  * params.mode = SPI_MASTER;
576  *
577  * // Configure the transaction
578  * transaction.count = sizeof(txBuf);
579  * transaction.txBuf = txBuf;
580  * transaction.rxBuf = rxBuf;
581  *
582  * // Open the SPI and perform the transfer
583  * handle = SPI_open(Board_SPI, &params);
584  * // Get pinHandle
585  * pinHandle = ((SPICC26X2DMA_Object *)spiHandle->object)->pinHandle;
586  * // Get miso pin id
587  * misoPinId = ((SPICC26X2DMA_HWAttrs *)spiHandle->hwAttrs)->misoPin;
588  *
589  * // Apply low power sleep pull config for MISO
590  * PIN_setConfig(pinHandle, PIN_BM_PULLING, PIN_PULLUP | misoPinId);
591  *
592  * // Do forever
593  * while(1) {
594  * // Transfer data
595  * SPI_transfer(handle, &transaction);
596  * // Sleep
597  * Task_sleep(standbyDurationMs*100);
598  * }
599  * @endcode
600  *
601  * ### Wake Up On Chip Select Deassertion In Slave Mode Using #SPI_MODE_CALLBACK #
602  * To wake the SPI slave device up on deassertion of the chip select, the chip select
603  * pin must be controled outside of the SPI driver in between SPI transfers.
604  * The example below show how this can be implemented by registering the chip select pin
605  * with the PIN driver and configuring a callback on a falling edge.
606  * In the PIN callback, the chip select pin is released from the PIN driver,
607  * the SPI driver is opened, and a transaction started. During the SPI callback, the SPI
608  * driver is closed again and the chip select pin is reconfigured to trigger a callback on
609  * a falling edge again.
610  *
611  * *Note: The SPI master must allow enough time between deasserting the chip select and the
612  * start of the transaction for the SPI slave to wake up and open up the SPI driver.
613  *
614  * @code
615  * // Global variables
616  * SPI_Handle spiHandle
617  * SPI_Params spiParams;
618  * SPI_Transaction spiTransaction;
619  * const uint8_t transferSize = 8;
620  * uint8_t txBuf[8];
621  * PIN_Handle pinHandle;
622  * PIN_Config pinConfig[] = {
623  * PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE | CS_PIN_ID,
624  * PIN_TERMINATE // Terminate list
625  * };
626  *
627  * // Chip select callback
628  * static void chipSelectCallback(PIN_Handle handle, PIN_Id pinId)
629  * {
630  * // Release the chip select pin
631  * PIN_remove(handle, pinId);
632  *
633  * // Open SPI driver
634  * spiHandle = SPI_open(Board_SPI, &spiParams);
635  *
636  * // Issue echo transfer
637  * SPI_transfer(spiHandle, &spiTransaction);
638  * }
639  *
640  * // SPI transfer callback
641  * static void transferCallback(SPI_Handle handle, SPI_Transaction *transaction)
642  * {
643  * // Close the SPI driver
644  * SPI_close(handle);
645  *
646  * // Add chip select back to the PIN driver
647  * PIN_add(pinHandle, pinConfig[0]);
648  *
649  * // Register chip select callback
650  * PIN_registerIntCb(pinHandle, chipSelectCallback);
651  * }
652  *
653  * // From your_application.c
654  * static void taskFxn(uintptr_t a0, uintptr_t a1)
655  * {
656  * uint8_t i;
657  * PIN_State pinState;
658  *
659  * // Setup SPI params
660  * SPI_Params_init(&spiParams);
661  * spiParams.bitRate = 1000000;
662  * spiParams.frameFormat = SPI_POL1_PHA1;
663  * spiParams.mode = SPI_SLAVE;
664  * spiParams.dataSize = transferSize;
665  * spiParams.transferMode = SPI_MODE_CALLBACK;
666  * spiParams.transferCallbackFxn = transferCallback;
667  *
668  * // Setup SPI transaction
669  * spiTransaction.arg = NULL;
670  * spiTransaction.count = transferSize;
671  * spiTransaction.txBuf = txBuf;
672  * spiTransaction.rxBuf = txBuf;
673  *
674  * // First echo message
675  * for (i = 0; i < transferSize; i++) {
676  * txBuf[i] = i;
677  * }
678  *
679  * // Open PIN driver and configure chip select pin callback
680  * pinHandle = PIN_open(&pinState, pinConfig);
681  * PIN_registerIntCb(pinHandle, chipSelectCallback);
682  *
683  * // Wait forever
684  * while(true);
685  * }
686  * @endcode
687  *
688  * <hr>
689  */
690 
691 #ifndef ti_drivers_spi_SPICC26X2DMA__include
692 #define ti_drivers_spi_SPICC26X2DMA__include
693 
694 #ifdef __cplusplus
695 extern "C" {
696 #endif
697 
698 #include <stdint.h>
699 #include <ti/drivers/SPI.h>
702 #include <ti/drivers/Power.h>
704 
705 #include <ti/drivers/dpl/HwiP.h>
706 #include <ti/drivers/dpl/SemaphoreP.h>
707 #include <ti/drivers/dpl/SwiP.h>
708 
719 /* Add SPICC26X2DMA_STATUS_* macros here */
720 
740 #define SPICC26X2DMA_CMD_RETURN_PARTIAL_ENABLE (SPI_CMD_RESERVED + 0)
741 
749 #define SPICC26X2DMA_CMD_RETURN_PARTIAL_DISABLE (SPI_CMD_RESERVED + 1)
750 
758 #define SPICC26X2DMA_CMD_SET_CSN_PIN (SPI_CMD_RESERVED + 2)
759 
773 #define SPICC26X2DMA_CMD_SET_MANUAL (SPI_CMD_RESERVED + 3)
774 
784 #define SPICC26X2DMA_CMD_CLR_MANUAL (SPI_CMD_RESERVED + 4)
785 
796 #define SPICC26X2DMA_CMD_MANUAL_START (SPI_CMD_RESERVED + 5)
797 
800 /* BACKWARDS COMPATIBILITY */
801 #define SPICC26X2DMA_RETURN_PARTIAL_ENABLE SPICC26X2DMA_CMD_RETURN_PARTIAL_ENABLE
802 #define SPICC26X2DMA_RETURN_PARTIAL_DISABLE SPICC26X2DMA_CMD_RETURN_PARTIAL_DISABLE
803 #define SPICC26X2DMA_SET_CSN_PIN SPICC26X2DMA_CMD_SET_CSN_PIN
804 /* END BACKWARDS COMPATIBILITY */
805 
812 
826 
839 
894 typedef struct SPICC26X2DMA_HWAttrs {
896  uint32_t baseAddr;
898  uint8_t intNum;
913  uint8_t intPriority;
920  uint32_t swiPriority;
922  PowerCC26XX_Resource powerMngrId;
937 
941 
947 typedef struct SPICC26X2DMA_Object {
948  HwiP_Struct hwi;
952  SwiP_Struct swi;
953  SemaphoreP_Struct transferComplete;
954 
960 
961  size_t framesQueued;
965 
966  uint32_t activeChannel;
967  uint32_t bitRate;
968  uint32_t dataSize;
969  uint32_t transferTimeout;
970  uint32_t busyBit;
971 
972  uint16_t rxScratchBuf;
973  uint16_t txScratchBuf;
974 
977  uint8_t format;
980  bool isOpen;
983 
984 #ifdef __cplusplus
985 }
986 #endif
987 
988 #endif /* ti_drivers_spi_SPICC26X2DMA__include */
uint8_t PIN_Id
Pin identifier data type.
Definition: PIN.h:577
Definition: SPICC26X2DMA.h:837
uint16_t defaultTxBufValue
Definition: SPICC26X2DMA.h:924
uint32_t minDmaTransferSize
Definition: SPICC26X2DMA.h:939
PIN_Id csnPin
Definition: SPICC26X2DMA.h:978
PIN_State pinState
Definition: SPICC26X2DMA.h:950
SPI_Transaction * headPtr
Definition: SPICC26X2DMA.h:956
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
uint32_t txChannelBitMask
Definition: SPICC26X2DMA.h:928
SPI_Transaction * completedTransfers
Definition: SPICC26X2DMA.h:958
uint32_t bitRate
Definition: SPICC26X2DMA.h:967
uint32_t rxChannelBitMask
Definition: SPICC26X2DMA.h:926
SPI_TransferMode
SPI transfer mode determines the whether the SPI controller operates synchronously or asynchronously...
Definition: SPI.h:620
SPI_Transaction * tailPtr
Definition: SPICC26X2DMA.h:957
Power Manager.
UDMACC26XX Global configuration.
Definition: UDMACC26XX.h:231
Power manager interface for CC26XX/CC13XX.
Power_NotifyObj spiPostObj
Definition: SPICC26X2DMA.h:951
uint16_t rxScratchBuf
Definition: SPICC26X2DMA.h:972
uint32_t transferTimeout
Definition: SPICC26X2DMA.h:969
PIN_Id clkPin
Definition: SPICC26X2DMA.h:934
uint32_t activeChannel
Definition: SPICC26X2DMA.h:966
size_t altTransferSize
Definition: SPICC26X2DMA.h:964
SPI_Mode mode
Definition: SPICC26X2DMA.h:976
uint8_t intNum
Definition: SPICC26X2DMA.h:898
SPI_TransferMode transferMode
Definition: SPICC26X2DMA.h:975
const SPI_FxnTable SPICC26X2DMA_fxnTable
Definition: SPICC26X2DMA.h:823
The definition of a SPI function table that contains the required set of functions to control a speci...
Definition: SPI.h:711
uint32_t swiPriority
SPI SWI priority. The higher the number, the higher the priority. The minimum is 0 and the maximum is...
Definition: SPICC26X2DMA.h:920
SPICC26X2DMA_ReturnPartial returnPartial
Definition: SPICC26X2DMA.h:979
Device-specific pin & GPIO driver for CC26xx family [def].
size_t framesQueued
Definition: SPICC26X2DMA.h:961
PIN_Handle pinHandle
Definition: SPICC26X2DMA.h:949
SPICC26X2DMA Hardware attributes.
Definition: SPICC26X2DMA.h:894
uint8_t format
Definition: SPICC26X2DMA.h:977
SwiP_Struct swi
Definition: SPICC26X2DMA.h:952
struct SPICC26X2DMA_HWAttrs SPICC26X2DMA_HWAttrs
SPICC26X2DMA Hardware attributes.
UDMACC26XX driver implementation.
uint32_t busyBit
Definition: SPICC26X2DMA.h:970
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
Definition: SPICC26X2DMA.h:835
SPI_Mode
Definitions for various SPI modes of operation.
Definition: SPI.h:590
UDMACC26XX_Handle udmaHandle
Definition: SPICC26X2DMA.h:959
SemaphoreP_Struct transferComplete
Definition: SPICC26X2DMA.h:953
SPICC26X2DMA_ReturnPartial
Definition: SPICC26X2DMA.h:834
PIN_Id misoPin
Definition: SPICC26X2DMA.h:932
PIN_Id mosiPin
Definition: SPICC26X2DMA.h:930
underlying data structure for type PIN_State
Definition: PIN.h:707
Definition: SPICC26X2DMA.h:824
size_t framesTransferred
Definition: SPICC26X2DMA.h:962
uint16_t txScratchBuf
Definition: SPICC26X2DMA.h:973
SPICC26X2DMA_FrameSize
Definition: SPICC26X2DMA.h:822
size_t priTransferSize
Definition: SPICC26X2DMA.h:963
bool manualStart
Definition: SPICC26X2DMA.h:981
SPI_CallbackFxn transferCallbackFxn
Definition: SPICC26X2DMA.h:955
bool isOpen
Definition: SPICC26X2DMA.h:980
struct SPICC26X2DMA_Object SPICC26X2DMA_Object
SPICC26X2DMA Object.
PowerCC26XX_Resource powerMngrId
Definition: SPICC26X2DMA.h:922
SPICC26X2DMA Object.
Definition: SPICC26X2DMA.h:947
Definition: SPICC26X2DMA.h:836
HwiP_Struct hwi
Definition: SPICC26X2DMA.h:948
uint32_t dataSize
Definition: SPICC26X2DMA.h:968
PIN_Id csnPin
Definition: SPICC26X2DMA.h:936
uint8_t intPriority
SPI CC26XXDMA Peripheral&#39;s interrupt priority.
Definition: SPICC26X2DMA.h:913
uint32_t baseAddr
SPI Peripheral&#39;s base address.
Definition: SPICC26X2DMA.h:896
© Copyright 1995-2019, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale