SPICC26XXDMA.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 SPICC26XXDMA.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/SPICC26XXDMA.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 SPICC26XXDMA_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).
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  *
67  * The following is true for slave operation:
68  * - RX overrun IRQ, SPI and UDMA modules are enabled by calling SPI_transfer().
69  * - All received bytes are ignored after SPI_open() is called, until
70  * the first SPI_transfer().
71  * - If an RX overrun occur or if SPI_transferCancel() is called, RX overrun IRQ, SPI and UDMA
72  * modules are disabled, TX and RX FIFOs are flushed and all bytes are ignored.
73  * - After a successful transfer, RX overrun IRQ and SPI module remains enabled and UDMA module is disabled.
74  * SPI_transfer() must be called again before RX FIFO goes full in order to
75  * avoid overflow. If the TX buffer is underflowed, zeros will be output.
76  * It is safe to call another SPI_transfer() from the transfer callback,
77  * see [Continuous Slave Transfer] (@ref USE_CASE_CST) use case below.
78  * - The SPI driver supports partial return, that can be used if the
79  * passed to SPI_control(), the transfer will end when chip select is
80  * deasserted. The #SPI_Transaction.status and the #SPI_Transaction.count
81  * will be updated to indicate whether the transfer ended due to a chip
82  * select deassertion and how many bytes were transferred. See
83  * [Slave Mode With Return Partial] (@ref USE_CASE_RP_X2) use case below.
84  *
85  * @warning The SPI modules on the CC13x0, CC26x0, and CC26x0R2 devices have a
86  * bug which may result in TX data being lost when operating in SPI slave
87  * mode. Please refer to the device errata sheet for full details. The SPI
88  * protocol should therefore include a data integrity check, such as
89  * appending a CRC to the payload to ensure all the data was transmitted
90  * correctly by the SPI slave.
91  *
92  * @warning This driver does not support queueing multiple SPI transactions.
93  *
94  * The following apply for master operation:
95  * - SPI and UDMA modules are enabled by calling SPI_transfer().
96  * - If the SPI_transfer() succeeds, SPI module is enabled and UDMA module is disabled.
97  * - If SPI_transferCancel() is called, SPI and UDMA modules are disabled and
98  * TX and RX FIFOs are flushed.
99  * .
100  * After SPI operation has ended:
101  * - Release system dependencies for SPI by calling SPI_close().
102  * .
103  * The callback function is called in the following context:
104  * - When an error occurs, the callback function is called in a HWI context.
105  * - When no error occurs, the callback function is called in a SWI context.
106  *
107  * @warning The application should avoid transmitting data stored in flash via SPI if the application
108  * might switch to the XOSC_HF, the high frequency external oscillator, during this transfer.
109  *
110  * # Error handling #
111  * If an RX overrun occurs during slave operation:
112  * - If a transfer is ongoing, all bytes received up until the error occurs will be returned, with the
113  * error signaled in the #SPI_Transaction.status field. RX overrun IRQ, SPI and UDMA modules are then disabled,
114  * TX and RX FIFOs are flushed and all bytes will be ignored until a new transfer is issued.
115  * - If a transfer is not ongoing, RX overrun IRQ, SPI and UDMA modules are disabled,
116  * TX and RX FIFOs are flushed and all bytes will be ignored until a new transfer is issued.
117  *
118  * # Timeout #
119  * Timeout can occur in #SPI_MODE_BLOCKING, there's no timeout in #SPI_MODE_CALLBACK.
120  * When in #SPI_MODE_CALLBACK, the transfer must be cancelled by calling SPI_transferCancel().\n
121  * If a timeout happens in either #SPI_SLAVE or #SPI_MASTER mode,
122  * the receive buffer will contain the bytes received up until the timeout occurred.
123  * The SPI transaction status will be set to #SPI_TRANSFER_FAILED.
124  * The SPI transaction count will be set to the number of bytes sent/received before timeout.
125  * The remaining bytes will be flushed from the TX FIFO so that the subsequent transfer
126  * can be executed correctly. Note that specifying a timeout prevents the
127  * driver from performing a polling transfer when in slave mode.
128  *
129  * # Power Management #
130  * The TI-RTOS power management framework will try to put the device into the most
131  * power efficient mode whenever possible. Please see the technical reference
132  * manual for further details on each power mode.
133  *
134  * The SPICC26XXDMA.h driver is setting a power constraint during transfers to keep
135  * the device out of standby. When the transfer has finished, the power
136  * constraint is released.
137  * The following statements are valid:
138  * - After SPI_open(): the device is still allowed to enter standby.
139  * - In slave mode:
140  * - During SPI_transfer(): the device cannot enter standby, only idle.
141  * - After an RX overflow: device is allowed to enter standby.
142  * - After a successful SPI_transfer(): the device is allowed
143  * to enter standby, but SPI module remains enabled.
144  * - _Note_: In slave mode, the device might enter standby while a byte is being
145  * transferred if SPI_transfer() is not called again after a successful
146  * transfer. This could result in corrupt data being transferred.
147  * - Application thread should typically either issue another transfer after
148  * SPI_transfer() completes successfully, or call
149  * SPI_transferCancel() to disable the SPI module and thus assuring that no data
150  * is received while entering standby.
151  * .
152  * - In master mode:
153  * - During SPI_transfer(): the device cannot enter standby, only idle.
154  * - After SPI_transfer() succeeds: the device can enter standby.
155  * - If SPI_transferCancel() is called: the device can enter standby.
156  *
157  * @note The external hardware connected to the SPI might have some pull configured on the
158  * SPI lines. When the SPI is inactive, this might cause leakage on the IO and the
159  * current consumption to increase. The application must configure a pull configuration
160  * that aligns with the external hardware.
161  * See [Ensure low power during inactive periods] (@ref USE_CASE_LPWR) for code example.
162  *
163  * # SPI details #
164  * ## Chip Select #
165  * This SPI controller supports a hardware chip select pin. Refer to the
166  * user manual on how this hardware chip select pin behaves in regards
167  * to the SPI frame format.
168  *
169  * <table>
170  * <tr>
171  * <th>Chip select type</th>
172  * <th>SPI_MASTER mode</th>
173  * <th>SPI_SLAVE mode</th>
174  * </tr>
175  * <tr>
176  * <td>Hardware chip select</td>
177  * <td>No action is needed by the application to select the peripheral.</td>
178  * <td>See the device documentation on it's chip select requirements.</td>
179  * </tr>
180  * <tr>
181  * <td>Software chip select</td>
182  * <td>The application is responsible to ensure that correct SPI slave is
183  * selected before performing a SPI_transfer().</td>
184  * <td>See the device documentation on it's chip select requirements.</td>
185  * </tr>
186  * </table>
187  *
188  * ### Multiple slaves when operating in master mode #
189  * In a scenario where the SPI module is operating in master mode with multiple
190  * SPI slaves, the chip select pin can be reallocated at runtime to select the
191  * appropriate slave device. See [Master Mode With Multiple Slaves](@ref USE_CASE_MMMS) use case below.
192  * This is only relevant when chip select is a hardware chip select. Otherwise the application
193  * can control the chip select pins directly using the PIN driver.
194  *
195  * ## Data Frames #
196  *
197  * SPI data frames can be any size from 4-bits to 16-bits. If the dataSize in
198  * #SPI_Params is greater that 8-bits, then the SPICC26XXDMA driver
199  * implementation will assume that the #SPI_Transaction txBuf and rxBuf
200  * point to an array of 16-bit uint16_t elements.
201  *
202  * dataSize | buffer element size |
203  * -------- | ------------------- |
204  * 4-8 bits | uint8_t |
205  * 9-16 bits | uint16_t |
206  *
207  * ## Bit Rate ##
208  * When the SPI is configured as SPI slave, the maximum bit rate is 4MHz.
209  *
210  * When the SPI is configured as SPI master, the maximum bit rate is 12MHz.
211  *
212  *
213  * ## UDMA #
214  * ### Interrupts #
215  * The UDMA module generates IRQs on the SPI interrupt vector. This driver automatically
216  * installs a UDMA aware Hwi (interrupt) to service the assigned UDMA channels.
217  *
218  * ### Transfer Size Limit #
219  *
220  * The UDMA controller only supports data transfers of up to 1024 data frames.
221  * A transfer with more than 1024 frames will be transmitted/received in
222  * multiple 1024 sized portions until all data has been transmitted/received.
223  * A data frame can be 4 to 16 bits in length.
224  *
225  * ### Scratch Buffers #
226  * A uint16_t scratch buffer is used to allow SPI_transfers where txBuf or rxBuf
227  * are NULL. Rather than requiring txBuf or rxBuf to have a dummy buffer of size
228  * of the transfer count, a single-word UDMA accessible uint16_t scratch buffer is used.
229  * When rxBuf is NULL, the UDMA will transfer all the received SPI data into the
230  * scratch buffer as a "bit-bucket".
231  * When txBuf is NULL, the scratch buffer is initialized to defaultTxBufValue
232  * so the uDMA will send some known value.
233  * Each SPI driver instance uses its own scratch buffer.
234  *
235  * ### TX and RX buffers #
236  * Before SPI_transfer, txBuf should be filled with the outgoing SPI data. These
237  * data are sent out during the transfer, while the incoming data are received
238  * into rxBuf. To save memory space, txBuf and rxBuf can be assigned to the same
239  * buffer location. At the beginning of the transfer, this buffer holds outgoing
240  * data. At the end of the transfer, the outgoing data are overwritten and
241  * the buffer holds the received SPI data.
242  *
243  * ## Polling SPI transfers #
244  * When used in blocking mode small SPI transfers are can be done by polling
245  * the peripheral & sending data frame-by-frame. A master device can perform
246  * the transfer immediately and return, but a slave will block until it
247  * receives the number of frames specified in the SPI_Transfer() call.
248  * The minDmaTransferSize field in the hardware attributes is
249  * the threshold; if the transaction count is below the threshold a polling
250  * transfer is performed; otherwise a DMA transfer is done. This is intended
251  * to reduce the overhead of setting up a DMA transfer to only send a few
252  * data frames.
253  *
254  * Notes:
255  * - Specifying a timeout prevents slave devices from using polling transfers.
256  * - Keep in mind that during polling transfers the current task
257  * is still being executed; there is no context switch to another task.
258 
259  *
260  * # Supported Functions #
261  * | Generic API function | API function | Description |
262  * |-----------------------|------------------------------- |-------------------------------------------------------------|
263  * | SPI_init() | SPICC26XXDMA_init() | Initialize SPI driver |
264  * | SPI_open() | SPICC26XXDMA_open() | Initialize SPI HW and set system dependencies |
265  * | SPI_close() | SPICC26XXDMA_close() | Disable SPI and UDMA HW and release system dependencies |
266  * | SPI_control() | SPICC26XXDMA_control() | Configure an already opened SPI handle |
267  * | SPI_transfer() | SPICC26XXDMA_transfer() | Start transfer from SPI |
268  * | SPI_transferCancel() | SPICC26XXDMA_transferCancel() | Cancel ongoing transfer from SPI |
269  *
270  * @note All calls should go through the generic API
271  *
272  * ## Unsupported Functionality #
273  * The CC26XX SPI driver does not support:
274  * - SPICC26XXDMA_serviceISR()
275  *
276  * ## Use Cases @anchor USE_CASES_SPI ##
277  * ### Basic Slave Mode #
278  * Receive 100 bytes over SPI in #SPI_MODE_BLOCKING.
279  * @code
280  * SPI_Handle handle;
281  * SPI_Params params;
282  * SPI_Transaction transaction;
283  * uint8_t rxBuf[100]; // Receive buffer
284  *
285  * // Init SPI and specify non-default parameters
286  * SPI_Params_init(&params);
287  * params.bitRate = 1000000;
288  * params.frameFormat = SPI_POL1_PHA1;
289  * params.mode = SPI_SLAVE;
290  *
291  * // Configure the transaction
292  * transaction.count = 100;
293  * transaction.txBuf = NULL;
294  * transaction.rxBuf = rxBuf;
295  *
296  * // Open the SPI and perform the transfer
297  * handle = SPI_open(Board_SPI, &params);
298  * SPI_transfer(handle, &transaction);
299  * @endcode
300  *
301  * ### Slave Mode With Return Partial @anchor USE_CASE_RP #
302  * This use case will perform a transfer in #SPI_MODE_BLOCKING until the wanted amount of bytes is
303  * transferred or until chip select is deasserted by the SPI master.
304  * This SPI_transfer() call can be used when unknown amount of bytes shall
305  * be transferred. Note: The partial return is also possible in #SPI_MODE_CALLBACK mode.
306  * @code
307  * SPI_Handle handle;
308  * SPI_Params params;
309  * SPI_Transaction transaction;
310  * uint8_t rxBuf[100]; // Receive buffer
311  *
312  * // Init SPI and specify non-default parameters
313  * SPI_Params_init(&params);
314  * params.bitRate = 1000000;
315  * params.frameFormat = SPI_POL1_PHA1;
316  * params.mode = SPI_SLAVE;
317  *
318  * // Configure the transaction
319  * transaction.count = 100;
320  * transaction.txBuf = NULL;
321  * transaction.rxBuf = rxBuf;
322  *
323  * // Open the SPI and initiate the partial read
324  * handle = SPI_open(Board_SPI, &params);
325  *
326  * // Enable RETURN_PARTIAL
327  * SPI_control(handle, SPICC26XXDMA_RETURN_PARTIAL_ENABLE, NULL);
328  *
329  * // Begin transfer
330  * SPI_transfer(handle, &transaction);
331  * @endcode
332  *
333  * ### Continuous Slave Transfer In #SPI_MODE_CALLBACK @anchor USE_CASE_CST #
334  * This use case will configure the SPI driver to transfer continuously in
335  * #SPI_MODE_CALLBACK, 16 bytes at the time and echoing received data after every
336  * 16 bytes.
337  * @code
338  * // Callback function
339  * static void transferCallback(SPI_Handle handle, SPI_Transaction *transaction)
340  * {
341  * // Start another transfer
342  * SPI_transfer(handle, transaction);
343  * }
344  *
345  * static void taskFxn(uintptr_t a0, uintptr_t a1)
346  * {
347  * SPI_Handle handle;
348  * SPI_Params params;
349  * SPI_Transaction transaction;
350  * uint8_t buf[16]; // Receive and transmit buffer
351  *
352  * // Init SPI and specify non-default parameters
353  * SPI_Params_init(&params);
354  * params.bitRate = 1000000;
355  * params.frameFormat = SPI_POL1_PHA1;
356  * params.mode = SPI_SLAVE;
357  * params.transferMode = SPI_MODE_CALLBACK;
358  * params.transferCallbackFxn = transferCallback;
359  *
360  * // Configure the transaction
361  * transaction.count = 16;
362  * transaction.txBuf = buf;
363  * transaction.rxBuf = buf;
364  *
365  * // Open the SPI and initiate the first transfer
366  * handle = SPI_open(Board_SPI, &params);
367  * SPI_transfer(handle, &transaction);
368  *
369  * // Wait forever
370  * while(true);
371  * }
372  * @endcode
373  *
374  * ### Basic Master Mode #
375  * This use case will configure a SPI master to send the data in txBuf while receiving data to rxBuf in
376  * BLOCKING_MODE.
377  * @code
378  * SPI_Handle handle;
379  * SPI_Params params;
380  * SPI_Transaction transaction;
381  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
382  * uint8_t rxBuf[11]; // Receive buffer
383  *
384  * // Init SPI and specify non-default parameters
385  * SPI_Params_init(&params);
386  * params.bitRate = 1000000;
387  * params.frameFormat = SPI_POL1_PHA1;
388  * params.mode = SPI_MASTER;
389  *
390  * // Configure the transaction
391  * transaction.count = sizeof(txBuf);
392  * transaction.txBuf = txBuf;
393  * transaction.rxBuf = rxBuf;
394  *
395  * // Open the SPI and perform the transfer
396  * handle = SPI_open(Board_SPI, &params);
397  * SPI_transfer(handle, &transaction);
398  * @endcode
399  *
400  * ### Master Mode With Multiple Slaves @anchor USE_CASE_MMMS #
401  * This use case will configure a SPI master to send data to one slave and then to another in
402  * BLOCKING_MODE. It is assumed that the board file is configured so that the two chip select
403  * pins have a default setting of a high output and that the #SPICC26XXDMA_HWAttrsV1 used points
404  * to one of them since the SPI driver will revert to this default setting when switching the
405  * chip select pin.
406  *
407  * @code
408  * // From board.c
409  * PIN_Config BoardGpioInitTable[] = {
410  * Board_CSN_0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL, // Ensure SPI slave 0 is not selected
411  * Board_CSN_1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL // Ensure SPI slave 1 is not selected
412  * }
413  *
414  * const SPICC26XXDMA_HWAttrsV1 spiCC26XXDMAHWAttrs[CC2650_SPICOUNT] = {
415  * { // Use SPI0 module with default chip select on Board_CSN_0
416  * .baseAddr = SSI0_BASE,
417  * .intNum = INT_SSI0,
418  * .intPriority = ~0,
419  * .swiPriority = 0,
420  * .defaultTxBufValue = 0,
421  * .powerMngrId = PERIPH_SSI0,
422  * .rxChannelIndex = UDMA_CHAN_SSI0_RX,
423  * .txChannelIndex = UDMA_CHAN_SSI0_TX,
424  * .mosiPin = Board_SPI0_MOSI,
425  * .misoPin = Board_SPI0_MISO,
426  * .clkPin = Board_SPI0_CLK,
427  * .csnPin = Board_CSN_0
428  * }
429  *
430  * // From your_application.c
431  * static void taskFxn(uintptr_t a0, uintptr_t a1)
432  * {
433  * SPI_Handle handle;
434  * SPI_Params params;
435  * SPI_Transaction transaction;
436  * PIN_Id csnPin1 = PIN_ID(Board_CSN_1);
437  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
438  *
439  * // Init SPI and specify non-default parameters
440  * SPI_Params_init(&params);
441  * params.bitRate = 1000000;
442  * params.frameFormat = SPI_POL1_PHA1;
443  * params.mode = SPI_MASTER;
444  *
445  * // Configure the transaction
446  * transaction.count = sizeof(txBuf);
447  * transaction.txBuf = txBuf;
448  * transaction.rxBuf = NULL;
449  *
450  * // Open the SPI and perform transfer to the first slave
451  * handle = SPI_open(Board_SPI, &params);
452  * SPI_transfer(handle, &transaction);
453  *
454  * // Then switch chip select pin and perform transfer to the second slave
455  * SPI_control(handle, SPICC26XXDMA_SET_CSN_PIN, &csnPin1);
456  * SPI_transfer(handle, &transaction);
457  * }
458  * @endcode
459  *
460  * ### Ensure low power during inactive periods @anchor USE_CASE_LPWR #
461  * External hardware connected on the SPI, i.e. SPI host/slave, might have configured
462  * a pull on one or more of the SPI lines. Dependent on the hardware, it might conflict
463  * with the pull used for the CC26XX SPI. To avoid increased leakage and ensure the lowest
464  * possible power consumption when the SPI is inactive, the application must configure a
465  * matching pull on the SPI IOs. An example of how this can be done is shown below.
466  *
467  * @code
468  * PIN_Handle pinHandle;
469  * SPI_Handle handle;
470  * SPI_Params params;
471  * SPI_Transaction transaction;
472  * uint8_t txBuf[] = "Heartbeat"; // Transmit buffer
473  * uint8_t rxBuf[9]; // Receive buffer
474  * PIN_Id misoPinId;
475  * uint32_t standbyDurationMs = 100;
476  *
477  * // Init SPI and specify non-default parameters
478  * SPI_Params_init(&params);
479  * params.bitRate = 1000000;
480  * params.frameFormat = SPI_POL1_PHA1;
481  * params.mode = SPI_MASTER;
482  *
483  * // Configure the transaction
484  * transaction.count = sizeof(txBuf);
485  * transaction.txBuf = txBuf;
486  * transaction.rxBuf = rxBuf;
487  *
488  * // Open the SPI and perform the transfer
489  * handle = SPI_open(Board_SPI, &params);
490  * // Get pinHandle
491  * pinHandle = ((SPICC26XXDMA_Object *)spiHandle->object)->pinHandle;
492  * // Get miso pin id
493  * misoPinId = ((SPICC26XXDMA_HWAttrsV1 *)spiHandle->hwAttrs)->misoPin;
494  *
495  * // Apply low power sleep pull config for MISO
496  * PIN_setConfig(pinHandle, PIN_BM_PULLING, PIN_PULLUP | misoPinId);
497  *
498  * // Do forever
499  * while(1) {
500  * // Transfer data
501  * SPI_transfer(handle, &transaction);
502  * // Sleep
503  * Task_sleep(standbyDurationMs*100);
504  * }
505  * @endcode
506  *
507  * ### Wake Up On Chip Select Deassertion In Slave Mode Using #SPI_MODE_CALLBACK #
508  * To wake the SPI slave device up on deassertion of the chip select, the chip select
509  * pin must be controled outside of the SPI driver in between SPI transfers.
510  * The example below show how this can be implemented by registering the chip select pin
511  * with the PIN driver and configuring a callback on a falling edge.
512  * In the PIN callback, the chip select pin is released from the PIN driver,
513  * the SPI driver is opened, and a transaction started. During the SPI callback, the SPI
514  * driver is closed again and the chip select pin is reconfigured to trigger a callback on
515  * a falling edge again.
516  *
517  * *Note: The SPI master must allow enough time between deasserting the chip select and the
518  * start of the transaction for the SPI slave to wake up and open up the SPI driver.
519  *
520  * @code
521  * // Global variables
522  * SPI_Handle spiHandle
523  * SPI_Params spiParams;
524  * SPI_Transaction spiTransaction;
525  * const uint8_t transferSize = 8;
526  * uint8_t txBuf[8];
527  * PIN_Handle pinHandle;
528  * PIN_Config pinConfig[] = {
529  * PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE | CS_PIN_ID,
530  * PIN_TERMINATE // Terminate list
531  * };
532  *
533  * // Chip select callback
534  * static void chipSelectCallback(PIN_Handle handle, PIN_Id pinId)
535  * {
536  * // Release the chip select pin
537  * PIN_remove(handle, pinId);
538  *
539  * // Open SPI driver
540  * spiHandle = SPI_open(Board_SPI, &spiParams);
541  *
542  * // Issue echo transfer
543  * SPI_transfer(spiHandle, &spiTransaction);
544  * }
545  *
546  * // SPI transfer callback
547  * static void transferCallback(SPI_Handle handle, SPI_Transaction *transaction)
548  * {
549  * // Close the SPI driver
550  * SPI_close(handle);
551  *
552  * // Add chip select back to the PIN driver
553  * PIN_add(pinHandle, pinConfig[0]);
554  *
555  * // Register chip select callback
556  * PIN_registerIntCb(pinHandle, chipSelectCallback);
557  * }
558  *
559  * // From your_application.c
560  * static void taskFxn(uintptr_t a0, uintptr_t a1)
561  * {
562  * uint8_t i;
563  * PIN_State pinState;
564  *
565  * // Setup SPI params
566  * SPI_Params_init(&spiParams);
567  * spiParams.bitRate = 1000000;
568  * spiParams.frameFormat = SPI_POL1_PHA1;
569  * spiParams.mode = SPI_SLAVE;
570  * spiParams.dataSize = transferSize;
571  * spiParams.transferMode = SPI_MODE_CALLBACK;
572  * spiParams.transferCallbackFxn = transferCallback;
573  *
574  * // Setup SPI transaction
575  * spiTransaction.arg = NULL;
576  * spiTransaction.count = transferSize;
577  * spiTransaction.txBuf = txBuf;
578  * spiTransaction.rxBuf = txBuf;
579  *
580  * // First echo message
581  * for (i = 0; i < transferSize; i++) {
582  * txBuf[i] = i;
583  * }
584  *
585  * // Open PIN driver and configure chip select pin callback
586  * pinHandle = PIN_open(&pinState, pinConfig);
587  * PIN_registerIntCb(pinHandle, chipSelectCallback);
588  *
589  * // Wait forever
590  * while(true);
591  * }
592  * @endcode
593  *
594  * # Instrumentation #
595  * The SPI driver interface produces log statements if instrumentation is
596  * enabled.
597  *
598  * Diagnostics Mask | Log details |
599  * ---------------- | ----------- |
600  * Diags_USER1 | basic SPI operations performed |
601  * Diags_USER2 | detailed SPI operations performed |
602  *
603  * ============================================================================
604  */
605 
606 #ifndef ti_drivers_spi_SPICC26XXDMA__include
607 #define ti_drivers_spi_SPICC26XXDMA__include
608 
609 #ifdef __cplusplus
610 extern "C" {
611 #endif
612 
613 #include <stdint.h>
614 #include <ti/drivers/SPI.h>
617 #include <ti/drivers/Power.h>
619 
620 #include <ti/drivers/dpl/HwiP.h>
621 #include <ti/drivers/dpl/SemaphoreP.h>
622 #include <ti/drivers/dpl/SwiP.h>
623 
634 /* Add SPICC26XXDMA_STATUS_* macros here */
635 
655 #define SPICC26XXDMA_CMD_RETURN_PARTIAL_ENABLE (SPI_CMD_RESERVED + 0)
656 
664 #define SPICC26XXDMA_CMD_RETURN_PARTIAL_DISABLE (SPI_CMD_RESERVED + 1)
665 
672 #define SPICC26XXDMA_CMD_SET_CSN_PIN (SPI_CMD_RESERVED + 2)
673 
675 /* BACKWARDS COMPATIBILITY */
676 #define SPICC26XXDMA_RETURN_PARTIAL_ENABLE SPICC26XXDMA_CMD_RETURN_PARTIAL_ENABLE
677 #define SPICC26XXDMA_RETURN_PARTIAL_DISABLE SPICC26XXDMA_CMD_RETURN_PARTIAL_DISABLE
678 #define SPICC26XXDMA_SET_CSN_PIN SPICC26XXDMA_CMD_SET_CSN_PIN
679 /* END BACKWARDS COMPATIBILITY */
680 
687 
701 
756 typedef struct SPICC26XXDMA_HWAttrsV1 {
758  uint32_t baseAddr;
760  uint8_t intNum;
774  uint8_t intPriority;
780  uint32_t swiPriority;
782  PowerCC26XX_Resource powerMngrId;
797 
801 
807 typedef struct SPICC26XXDMA_Object {
808  /* SPI control variables */
810  unsigned int transferTimeout;
819  unsigned int bitRate;
820  unsigned int dataSize;
823  /* SPI SYS/BIOS objects */
824  HwiP_Struct hwi;
825  SwiP_Struct swi;
826  SemaphoreP_Struct transferComplete;
828  /* SPI current transaction */
830  size_t amtDataXferred;
831  size_t currentXferAmt;
834  /* Support for dynamic CSN pin allocation */
837  /* PIN driver state object and handle */
840 
841  /* UDMA driver handle */
843 
844  /* Optional slave mode features */
847  /* Scratch buffer of size uint32_t */
848  uint16_t scratchBuf;
849 
850  /* SPI pre- and post notification functions */
851  void *spiPreFxn;
852  void *spiPostFxn;
856  volatile bool spiPowerConstraint;
858  bool isOpen;
860 
861 
862 
863 
864 #ifdef __cplusplus
865 }
866 #endif
867 
868 #endif /* ti_drivers_spi_SPICC26XXDMA__include */
Definition: SPICC26XXDMA.h:698
uint8_t PIN_Id
Pin identifier data type.
Definition: PIN.h:577
PIN_Id csnPin
Definition: SPICC26XXDMA.h:835
const SPI_FxnTable SPICC26XXDMA_fxnTable
uint16_t defaultTxBufValue
Definition: SPICC26XXDMA.h:784
Serial Peripheral Interface (SPI) Driver Interface.
uint32_t baseAddr
Definition: SPICC26XXDMA.h:758
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
Power_NotifyObj spiPostObj
Definition: SPICC26XXDMA.h:854
unsigned int bitRate
SPI bit rate in Hz.
Definition: SPICC26XXDMA.h:819
SPI_CallbackFxn transferCallbackFxn
Definition: SPICC26XXDMA.h:811
struct SPICC26XXDMA_Object * SPICC26XXDMA_Handle
uint32_t minDmaTransferSize
Definition: SPICC26XXDMA.h:799
SPI_TransferMode
SPI transfer mode determines the whether the SPI controller operates synchronously or asynchronously...
Definition: SPI.h:620
uint8_t intPriority
SPI CC26XXDMA Peripheral&#39;s interrupt priority.
Definition: SPICC26XXDMA.h:774
Power Manager.
uint32_t rxChannelBitMask
Definition: SPICC26XXDMA.h:786
void * spiPreFxn
Definition: SPICC26XXDMA.h:851
UDMACC26XX Global configuration.
Definition: UDMACC26XX.h:231
uint32_t txChannelBitMask
Definition: SPICC26XXDMA.h:788
uint16_t scratchBuf
Definition: SPICC26XXDMA.h:848
Power manager interface for CC26XX/CC13XX.
PIN_Id clkPin
Definition: SPICC26XXDMA.h:794
SPICC26XXDMA Hardware attributes.
Definition: SPICC26XXDMA.h:756
volatile bool spiPowerConstraint
Definition: SPICC26XXDMA.h:856
PIN_Id misoPin
Definition: SPICC26XXDMA.h:792
SPI_TransferMode transferMode
Definition: SPICC26XXDMA.h:809
The definition of a SPI function table that contains the required set of functions to control a speci...
Definition: SPI.h:711
SPICC26XXDMA Object.
Definition: SPICC26XXDMA.h:807
Device-specific pin & GPIO driver for CC26xx family [def].
void * spiPostFxn
Definition: SPICC26XXDMA.h:852
PIN_State pinState
Definition: SPICC26XXDMA.h:838
SPI_Mode mode
Definition: SPICC26XXDMA.h:812
SPICC26XXDMA_FrameSize
Definition: SPICC26XXDMA.h:697
SPICC26XXDMA_FrameSize frameSize
Definition: SPICC26XXDMA.h:832
UDMACC26XX driver implementation.
A SPI_Transaction data structure is used with SPI_transfer(). It indicates how many SPI_FrameFormat f...
Definition: SPI.h:563
bool returnPartial
Definition: SPICC26XXDMA.h:845
Power notify object structure.
Definition: Power.h:443
struct SPICC26XXDMA_Object SPICC26XXDMA_Object
SPICC26XXDMA Object.
SPI_Mode
Definitions for various SPI modes of operation.
Definition: SPI.h:590
struct SPICC26XXDMA_HWAttrsV1 SPICC26XXDMA_HWAttrsV1
SPICC26XXDMA Hardware attributes.
PIN_Id csnPin
Definition: SPICC26XXDMA.h:796
UDMACC26XX_Handle udmaHandle
Definition: SPICC26XXDMA.h:842
uint8_t intNum
Definition: SPICC26XXDMA.h:760
PIN_Id mosiPin
Definition: SPICC26XXDMA.h:790
unsigned int transferTimeout
Definition: SPICC26XXDMA.h:810
underlying data structure for type PIN_State
Definition: PIN.h:707
HwiP_Struct hwi
Definition: SPICC26XXDMA.h:824
SPI_FrameFormat frameFormat
Definition: SPICC26XXDMA.h:821
Power_NotifyObj spiPreObj
Definition: SPICC26XXDMA.h:853
SemaphoreP_Struct transferComplete
Definition: SPICC26XXDMA.h:826
SwiP_Struct swi
Definition: SPICC26XXDMA.h:825
size_t amtDataXferred
Definition: SPICC26XXDMA.h:830
bool isOpen
Definition: SPICC26XXDMA.h:858
uint32_t swiPriority
SPI SWI priority. The higher the number, the higher the priority. The minimum is 0 and the maximum is...
Definition: SPICC26XXDMA.h:780
Definition: SPICC26XXDMA.h:699
PowerCC26XX_Resource powerMngrId
Definition: SPICC26XXDMA.h:782
size_t currentXferAmt
Definition: SPICC26XXDMA.h:831
PIN_Handle pinHandle
Definition: SPICC26XXDMA.h:839
unsigned int dataSize
Definition: SPICC26XXDMA.h:820
SPI_FrameFormat
Definitions for various SPI data frame formats.
Definition: SPI.h:599
SPI_Transaction * currentTransaction
Definition: SPICC26XXDMA.h:829
© Copyright 1995-2019, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale