MSPM0G1X0X_G3X0X TI-Driver Library  1.20.01.06
SPIMSPM0.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022-2023 Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*!*****************************************************************************
33  * @file SPIMSPM0.h
34  *
35  * @brief SPI driver implementation for MSPM0 SPI
36  * controller using the DMA controller.
37  * @defgroup SPIMSPM0 SPI driver APIs
38  *
39  * # Driver include #
40  * The SPI header file should be included in an application as follows:
41  * @code
42  * #include <ti/drivers/SPI.h> #include <ti/drivers/spi/SPIMSPM0.h> #include
43  * <ti/drivers/dma/DMAMSPM0.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 DMAMSPM0.h driver since the SPI
49  * uses DMA in order to improve throughput.
50  *
51  * # Overview #
52  * The general SPI API should be used in application code, i.e. SPI_open()
53  * should be used instead of SPIMSPM0_open(). The configuration file will define the
54  * device specific config, and casting in the general API will ensure that the
55  * correct device specific functions are called. This is also reflected in the
56  * example code.
57  *
58  * # General Behavior #
59  * Before using SPI on MSPM0 devices:
60  * - The SPI driver is initialized by calling SPI_init().
61  * - The SPI HW is configured and flags system dependencies (e.g. IOs, power,
62  * etc.) by calling SPI_open().
63  * - The SPI driver makes use of DMA in order to optimize throughput. This is
64  * handled directly by the SPI driver, so the application should never make
65  * any calls directly to the DMAMSPM0.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
70  * using the #SPIMSPM0_CMD_SET_MANUAL command. In this mode, the driver
71  * will not start any queued transfers until SPI_control() is called with
72  * the #SPIMSPM0_CMD_MANUAL_START command. This mode is off by default and
73  * can be disabled by using command #SPIMSPM0_CMD_CLR_MANUAL. See the
74  * @ref USE_CASE_MANUAL_START "Manual Start Example".
75  *
76  * The following is true for peripheral operation:
77  * - RX overrun IRQ, SPI and DMA modules are enabled by calling
78  SPI_transfer().
79  * - All received bytes are ignored after SPI_open() is called, until the
80  * first SPI_transfer().
81  * - If an RX overrun occurs or if SPI_transferCancel() is called, RX overrun
82  IRQ, SPI and DMA modules are disabled, TX and RX FIFOs are flushed and
83  all bytes are ignored.
84  * - After a successful transfer, RX overrun IRQ and SPI module remains
85  enabled and DMA module is disabled. SPI_transfer() must be called again
86  before RX FIFO fills up in order to avoid overflow. If the TX buffer
87  overflows, zeros will be output. It is safe to call another
88  SPI_transfer() from the transfer callback, see [Continuous Peripheral
89  Transfer] (@ref USE_CASE_CST) use case below.
90  * - The SPI driver supports partial return, that can be used if the transfer
91  * size is unknown. If #SPIMSPM0_CMD_RETURN_PARTIAL_ENABLE is passed to
92  * SPI_control(), the transfer will end when chip select is deasserted. The
93  * #SPI_Transaction.status and the #SPI_Transaction.count will be updated to
94  * indicate whether the transfer ended due to a chip select deassertion and
95  * how many bytes were transferred. See [Peripheral Mode With Return
96  * Partial] (@ref USE_CASE_RP) use case below.
97  * - When queueing several transactions if the first is a 'short' transaction
98  * (8 or fewer frames), it is required to use
99  * @ref USE_CASE_MANUAL_START "Manual Start mode."
100  *
101  * The following apply for controller operation:
102  * - SPI and DMA modules are enabled by calling SPI_transfer().
103  * - If the SPI_transfer() succeeds, SPI module is enabled and DMA module is
104  disabled.
105  * - If SPI_transferCancel() is called, SPI and DMA modules are disabled and
106  * TX and RX FIFOs are flushed.
107  *
108  * After SPI operation has ended:
109  * - Release system dependencies for SPI by calling SPI_close().
110  *
111  * The callback function is always called in a SWI context.
112  *
113  * # Error handling #
114  * If an RX overrun occurs during peripheral operation:
115  * - If a transfer is ongoing, all bytes received up until the error occurs
116  will be returned, with the error signaled in the #SPI_Transaction.status
117  field. RX overrun IRQ, SPI and DMA modules are then disabled, TX and RX
118  FIFOs are flushed and all bytes will be ignored until a new transfer is
119  issued.
120  * - If a transfer is not ongoing, RX overrun IRQ, SPI and DMA modules are
121  disabled, TX and RX FIFOs are flushed and all bytes will be ignored until
122  a new transfer is issued.
123  *
124  * # Timeout #
125  * Timeout can occur in #SPI_MODE_BLOCKING, there's no timeout in
126  #SPI_MODE_CALLBACK. When in #SPI_MODE_CALLBACK, the transfer must be
127  cancelled by calling SPI_transferCancel().@n If a timeout happens in either
128  #SPI_PERIPHERAL or #SPI_CONTROLLER mode, the receive buffer will contain the
129  bytes received up until the timeout occurred. The SPI transaction status will
130  be set to #SPI_TRANSFER_FAILED. The SPI transaction count will be set to the
131  number of bytes sent/received before timeout. The remaining bytes will be
132  flushed from the TX FIFO so that the subsequent transfer can be executed
133  correctly. Note that specifying a timeout prevents the driver from performing
134  a polling transfer when in peripheral mode.
135  *
136  * # Power Management #
137  * The power management framework will try to put the device into the
138  most power efficient mode whenever possible. Please see the technical
139  reference manual for further details on each power mode.
140  *
141  * The SPIMSPM0.h driver is setting a power constraint during transfers to
142  keep the device out of standby. When the transfer has finished, the power
143  constraint is released. The following statements are valid:
144  * - After SPI_open(): the device is still allowed to enter standby.
145  * - In peripheral mode:
146  * - During SPI_transfer(): the device cannot enter standby, only idle.
147  * - After an RX overflow: device is allowed to enter standby.
148  * - After a successful SPI_transfer(): the device is allowed to enter
149  * standby, but SPI module remains enabled.
150  * - _Note_: In peripheral mode, the device might enter standby while a
151  byte is being transferred if SPI_transfer() is not called again after
152  a successful transfer. This could result in corrupt data being
153  transferred.
154  * - Application thread should typically either issue another transfer after
155  * SPI_transfer() completes successfully, or call SPI_transferCancel() to
156  * disable the SPI module and thus assuring that no data is received while
157  * entering standby.
158  * - In controller mode:
159  * - During SPI_transfer(): the device cannot enter standby, only idle.
160  * - After SPI_transfer() succeeds: the device can enter standby.
161  * - If SPI_transferCancel() is called: the device can enter standby.
162  *
163  * @note The external hardware connected to the SPI might have some pull
164  configured on the SPI lines. When the SPI is inactive, this might cause
165  leakage on the IO and the current consumption to increase. The application
166  must configure a pull configuration that aligns with the external hardware.
167  See [Ensure low power during inactive periods] (@ref USE_CASE_LPWR) for
168  code example.
169  *
170  * # SPI details #
171  * ## Chip Select #
172  * This SPI controller supports a hardware chip select pin. Refer to the user
173  * manual on how this hardware chip select pin behaves in regards to the SPI
174  * frame format.
175  *
176  * <table>
177  * <tr>
178  * <th>Chip select type</th>
179  * <th>SPI_CONTROLLER mode</th>
180  * <th>SPI_PERIPHERAL mode</th>
181  * </tr>
182  * <tr>
183  * <td>Hardware chip select</td>
184  * <td>No action is needed by the application to select the peripheral.</td>
185  * <td>See the device documentation on it's chip select requirements.</td>
186  * </tr>
187  * <tr>
188  * <td>Software chip select</td>
189  * <td>The application is responsible to ensure that correct SPI peripheral is
190  * selected before performing a SPI_transfer().</td>
191  * <td>See the device documentation on it's chip select requirements.</td>
192  * </tr>
193  * </table>
194  *
195  * ### Multiple peripherals when operating in controller mode #
196  * In a scenario where the SPI module is operating in controller mode with
197  multiple SPI peripherals, the chip select pin can be reallocated at runtime
198  to select the appropriate peripheral device. See [Controller Mode With
199  Multiple Peripherals](@ref USE_CASE_MMMS) use case below. This is only
200  relevant when chip select is a hardware chip select. Otherwise the
201  application can control the chip select pins directly using the GPIO driver.
202  *
203  * ## Data Frames #
204  *
205  * SPI data frames can be any size from 4-bits to 16-bits. If the dataSize in
206  * #SPI_Params is greater that 8-bits, then the SPIMSPM0 driver
207  * implementation will assume that the #SPI_Transaction txBuf and rxBuf point
208  * to an array of 16-bit uint16_t elements.
209  *
210  * dataSize | buffer element size |
211  * -------- | ------------------- |
212  * 4-8 bits | uint8_t |
213  * 9-16 bits | uint16_t |
214  *
215  * ## DMA #
216  * ### Interrupts #
217  * The DMA module generates IRQs on the SPI interrupt vector. This driver
218  automatically installs a DMA aware Hwi (interrupt) to service the assigned
219  DMA channels.
220  *
221  * ### Transfer Size Limit #
222  *
223  * The DMA controller only supports data transfers of up to 1024 data frames.
224  * A transfer with more than 1024 frames will be transmitted/received in
225  * multiple 1024 sized portions until all data has been transmitted/received. A
226  * data frame can be 4 to 16 bits in length.
227  *
228  * ### Scratch Buffers #
229  * A uint16_t scratch buffer is used to allow SPI_transfers where txBuf or
230  rxBuf are NULL. Rather than requiring txBuf or rxBuf to have a dummy buffer
231  of size of the transfer count, a single-word DMA accessible uint16_t
232  scratch buffer is used. When rxBuf is NULL, the DMA will transfer all the
233  received SPI data into the scratch buffer as a "bit-bucket". When txBuf is
234  NULL, the scratch buffer is initialized to defaultTxBufValue so the DMA
235  will send some known value. Each SPI driver instance uses its own scratch
236  buffer.
237  *
238  * ### TX and RX buffers #
239  * Before SPI_transfer, txBuf should be filled with the outgoing SPI data.
240  These data are sent out during the transfer, while the incoming data are
241  received into rxBuf. To save memory space, txBuf and rxBuf can be assigned
242  to the same buffer location. At the beginning of the transfer, this buffer
243  holds outgoing data. At the end of the transfer, the outgoing data are
244  overwritten and the buffer holds the received SPI data.
245  *
246  * ## Polling SPI transfers #
247  * When used in blocking mode small SPI transfers are can be done by polling
248  * the peripheral & sending data frame-by-frame. A controller device can
249  * perform the transfer immediately and return, but a peripheral will block
250  * until it receives the number of frames specified in the SPI_Transfer() call.
251  * The minDmaTransferSize field in the hardware attributes is the threshold; if
252  * the transaction count is below the threshold a polling transfer is
253  * performed; otherwise a DMA transfer is done. This is intended to reduce the
254  * overhead of setting up a DMA transfer to only send a few data frames.
255  *
256  * Notes:
257  * - Specifying a timeout prevents peripheral devices from using polling
258  transfers.
259  * - Keep in mind that during polling transfers the current task is still being
260  * executed; there is no context switch to another task.
261  *
262  * # Supported Functions #
263  * Generic API function | API function | Description
264  * ----------------------|------------------------------- |------------------------------------------------------------
265  * SPI_init() | SPIMSPM0_init() | Initialize SPI driver
266  * SPI_open() | SPIMSPM0_open() | Initialize SPI HW and set system dependencies
267  * SPI_close() | SPIMSPM0_close() | Disable SPI and DMA HW and release system dependencies
268  * SPI_control() | SPIMSPM0_control() | Configure an already opened SPI handle
269  * SPI_transfer() | SPIMSPM0_transfer() | Start transfer from SPI
270  * SPI_transferCancel() | SPIMSPM0_transferCancel() | Cancel ongoing transfer from SPI
271  *
272  * @note All calls should go through the generic API
273  *
274  * ## Use Cases @anchor USE_CASES_SPI ##
275  * ### Basic Peripheral Mode #
276  * Receive 100 bytes over SPI in #SPI_MODE_BLOCKING.
277  * @code
278  * SPI_Handle handle; SPI_Params params; SPI_Transaction transaction; uint8_t
279  * rxBuf[100]; // Receive buffer
280  *
281  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
282  * params.bitRate = 500000; params.frameFormat = SPI_POL1_PHA1;
283  * params.mode = SPI_PERIPHERAL;
284  *
285  * // Configure the transaction transaction.count = 100; transaction.txBuf =
286  * NULL; transaction.rxBuf = rxBuf;
287  *
288  * // Open the SPI and perform the transfer handle = SPI_open(CONFIG_SPI,
289  * &params); SPI_transfer(handle, &transaction);
290  * @endcode
291  *
292  * ### Peripheral Mode With Return Partial @anchor USE_CASE_RP #
293  * This use case will perform a transfer in #SPI_MODE_BLOCKING until the wanted
294  amount of bytes is transferred or until chip select is deasserted by the SPI
295  controller. This SPI_transfer() call can be used when unknown amount of
296  bytes shall be transferred. Note: The partial return is also possible in
297  #SPI_MODE_CALLBACK mode. Note: Polling transfers are not available when
298  using return partial mode.
299  * @code
300  * SPI_Handle handle; SPI_Params params; SPI_Transaction transaction; uint8_t
301  * rxBuf[100]; // Receive buffer
302  *
303  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
304  * params.bitRate = 500000; params.frameFormat = SPI_POL1_PHA1;
305  * params.mode = SPI_PERIPHERAL;
306  *
307  * // Configure the transaction transaction.count = 100; transaction.txBuf =
308  * NULL; transaction.rxBuf = rxBuf;
309  *
310  * // Open the SPI and initiate the partial read handle = SPI_open(CONFIG_SPI,
311  * &params);
312  *
313  * // Enable RETURN_PARTIAL SPI_control(handle,
314  * SPIMSPM0_CMD_RETURN_PARTIAL_ENABLE, NULL);
315  *
316  * // Begin transfer SPI_transfer(handle, &transaction);
317  * @endcode
318  *
319  * ### Continuous Peripheral Transfer In #SPI_MODE_CALLBACK @anchor USE_CASE_CST #
320  * This use case will configure the SPI driver to transfer continuously in
321  * #SPI_MODE_CALLBACK, 16 bytes at the time and echoing received data after
322  * every 16 bytes.
323  * @code
324  * // Callback function static void transferCallback(SPI_Handle handle,
325  * SPI_Transaction *transaction)
326  * {
327  * // Start another transfer
328  * SPI_transfer(handle, transaction);
329  * }
330  *
331  * static void taskFxn(uintptr_t a0, uintptr_t a1)
332  * {
333  * SPI_Handle handle;
334  * SPI_Params params;
335  * SPI_Transaction transaction;
336  * uint8_t buf[16]; // Receive and transmit buffer
337  *
338  * // Init SPI and specify non-default parameters
339  * SPI_Params_init(&params);
340  * params.bitRate = 500000;
341  * params.frameFormat = SPI_POL1_PHA1;
342  * params.mode = SPI_PERIPHERAL;
343  * params.transferMode = SPI_MODE_CALLBACK;
344  * params.transferCallbackFxn = transferCallback;
345  *
346  * // Configure the transaction
347  * transaction.count = 16;
348  * transaction.txBuf = buf;
349  * transaction.rxBuf = buf;
350  *
351  * // Open the SPI and initiate the first transfer
352  * handle = SPI_open(CONFIG_SPI, &params);
353  * SPI_transfer(handle, &transaction);
354  *
355  * // Wait forever
356  * while(true);
357  * }
358  * @endcode
359  *
360  * ### Basic Controller Mode #
361  * This use case will configure a SPI controller to send the data in txBuf
362  while receiving data to rxBuf in BLOCKING_MODE.
363  * @code
364  * SPI_Handle handle; SPI_Params params; SPI_Transaction transaction; uint8_t
365  * txBuf[] = "Hello World"; // Transmit buffer uint8_t rxBuf[11];
366  * // Receive buffer
367  *
368  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
369  * params.bitRate = 500000; params.frameFormat = SPI_POL1_PHA1;
370  * params.mode = SPI_CONTROLLER;
371  *
372  * // Configure the transaction transaction.count = sizeof(txBuf);
373  * transaction.txBuf = txBuf; transaction.rxBuf = rxBuf;
374  *
375  * // Open the SPI and perform the transfer handle = SPI_open(CONFIG_SPI,
376  * &params); SPI_transfer(handle, &transaction);
377  * @endcode
378  *
379  * ### Controller Mode With Multiple Peripherals @anchor USE_CASE_MMMS #
380  * This use case will configure a SPI controller to send data to one peripheral
381  and then to another in BLOCKING_MODE. It is assumed that SysConfig is
382  configured so that the two chip select pins have a default setting of a high
383  output and that the #SPIMSPM0_HWAttrs used points to one of them since the
384  SPI driver will revert to this default setting when switching the chip
385  select pin.
386  *
387  * @code
388  * // From ti_drivers_config.c // Use the sysconfig settings to make sure both
389  * pins are set to HIGH when not in use GPIO_PinConfig gpioPinConfigs[31] = {
390  * ...
391  * GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH, // CONFIG_CSN_0
392  * ...
393  * GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH, // CONFIG_CSN_1
394  * }
395  ********************************************************************************************
396  * const SPIMSPM0_HWAttrs SPIMSPM0HWAttrs[CONFIG_SPI_COUNT] =
397  * {
398  * {
399  * .spi = SPI_1_INST,
400  * .intNum = SPI_1_INST_INT_IRQN,
401  * .intPriority = (~0),
402  * .clockSource = DL_SPI_CLOCK_BUSCLK,
403  * .clockDivider = DL_SPI_CLOCK_DIVIDE_RATIO_1,
404  * .defaultTxBufValue = 0xFF,
405  *
406  * .pociPin = GPIO_SPI_1_POCI_PIN,
407  * .pociPincm = GPIO_SPI_1_IOMUX_POCI,
408  * .pociPinMux = GPIO_SPI_1_IOMUX_POCI_FUNC,
409  *
410  * .picoPin = GPIO_SPI_1_PICO_PIN,
411  * .picoPincm = GPIO_SPI_1_IOMUX_PICO,
412  * .picoPinMux = GPIO_SPI_1_IOMUX_PICO_FUNC,
413  *
414  * .sclkPin = GPIO_SPI_1_SCLK_PIN,
415  * .sclkPincm = GPIO_SPI_1_IOMUX_SCLK,
416  * .sclkPinMux = GPIO_SPI_1_IOMUX_SCLK_FUNC,
417 
418  * .csnPin = GPIO_SPI_1_CS0_PIN,
419  * .csnPincm = GPIO_SPI_1_IOMUX_CS0,
420  * .csnPinMux = GPIO_SPI_1_IOMUX_CS0_FUNC,
421 
422  * .txFifoThreshold = DL_SPI_TX_FIFO_LEVEL_ONE_FRAME,
423  * .rxFifoThreshold = DL_SPI_RX_FIFO_LEVEL_ONE_FRAME,
424  * .cssel = 0,
425  * .noOfDMAChannels = 2,
426  * },
427  * };
428  *
429  * // From your_application.c static void taskFxn(uintptr_t a0, uintptr_t a1)
430  * {
431  * SPI_Handle handle;
432  * SPI_Params params;
433  * SPI_Transaction transaction;
434  * uint_least8_t csnPin1 = CONFIG_CSN_1;
435  * uint8_t txBuf[] = "Hello World"; // Transmit buffer
436  *
437  * // Init SPI and specify non-default parameters
438  * SPI_Params_init(&params);
439  * params.bitRate = 500000;
440  * params.frameFormat = SPI_POL1_PHA1;
441  * params.mode = SPI_CONTROLLER;
442  *
443  * // Configure the transaction
444  * transaction.count = sizeof(txBuf);
445  * transaction.txBuf = txBuf;
446  * transaction.rxBuf = NULL;
447  *
448  * // Open the SPI and perform transfer to the first peripheral
449  * handle = SPI_open(CONFIG_SPI, &params);
450  * SPI_transfer(handle, &transaction);
451  *
452  * // Then switch chip select pin and perform transfer to the second
453  peripheral
454  SPI_control(handle, SPIMSPM0_CMD_SET_CSN_PIN, &csnPin1);
455  SPI_transfer(handle, &transaction);
456  * }
457  * @endcode
458  *
459  * ### Queueing Transactions in Callback Mode #
460  * @anchor USE_CASE_QUEUE Below is an example of queueing three
461  * transactions
462  * @code
463  * // SPI already opened in callback mode SPI_Transaction t0, t1, t2;
464  *
465  * t0.txBuf = txBuff0; t0.rxBuf = rxBuff0; t0.count = 2000;
466  *
467  * t1.txBuf = txBuff1; t1.rxBuf = rxBuff1; t1.count = 1000;
468  *
469  * t2.txBuf = txBuff2; t2.rxBuf = NULL; t2.count = 1000;
470  *
471  * bool transferOk = false;
472  *
473  * if (SPI_transfer(spiHandle, &t0)) { if (SPI_transfer(spiHandle, &t1)) {
474  * transferOk = SPI_transfer(spiHandle, &t2);
475  * }
476  * }
477  * }
478  * @endcode
479  *
480  * ### Queueing in Manual Start Mode#
481  * This example shows a peripheral device queueing two transactions that will
482  * complete one after the other. From the controller's perspective there will
483  * be one long transfer.
484  * @note Manual mode also works while the device is in #SPI_CONTROLLER mode.
485  The control call to MANUAL_START will start the transfers.
486  *
487  * @warning Manual start mode should not be enabled or disabled while a
488  * transaction is in progress.
489  *
490  * @anchor USE_CASE_MANUAL_START
491  * @code
492  * SPI_Handle spi; SPI_Params params; SPI_Transaction t0, t1; uint8_t status =
493  * SPI_STATUS_SUCCESS;
494  *
495  * SPI_Params_init(&params); params.mode = SPI_PERIPHERAL; spi =
496  * SPI_open(CONFIG_SPI, &params);
497  *
498  * if (spi == NULL) { exit(0);
499  * }
500  *
501  * // Enable manual start mode SPI_control(spi, SPIMSPM0_CMD_SET_MANUAL,
502  * NULL);
503  *
504  * // Queue transactions t0.txBuf = txBuff0; t0.rxBuf = rxBuff0; t0.count =
505  * 2000; if (!SPI_transfer(spi, &t0)) { status = SPI_STATUS_FAIL;
506  * }
507  *
508  * t1.txBuf = txBuff1; t1.rxBuf = rxBuff1; t1.count = 1000; if
509  * (!SPI_transfer(spi, &t1)) { status = SPI_STATUS_FAIL;
510  * }
511  *
512  * // Enable the transfers if (status == SPI_STATUS_SUCCESS) { SPI_control(spi,
513  * SPIMSPM0_CMD_MANUAL_START, NULL);
514  * }
515  * else { status = SPI_STATUS_FAILURE;
516  * }
517  *
518  * // At this point the peripheral is ready for the controller to start the
519  transfer // Assume the callback implementation (not shown) posts a semaphore
520  when // the last transaction completes sem_wait(&spiSemaphore);
521  *
522  * // Disable manual start mode SPI_control(spi, SPIMSPM0_CMD_CLR_MANUAL,
523  * NULL);
524  *
525  * @endcode
526  *
527  * ### Ensure low power during inactive periods @anchor USE_CASE_LPWR #
528  * External hardware connected on the SPI, i.e. SPI controller/peripheral,
529  might have configured a pull on one or more of the SPI lines. Dependent on
530  the hardware, it might conflict with the pull used for the device SPI.
531  To avoid increased leakage and ensure the lowest possible power
532  consumption when the SPI is inactive, the application must configure a
533  matching pull on the SPI IOs. An example of how this can be done is shown
534  below.
535  *
536  * @code
537  * SPI_Params params; SPI_Transaction transaction; uint8_t txBuf[] =
538  * "Heartbeat"; // Transmit buffer uint8_t rxBuf[9]; //
539  * Receive buffer uint32_t standbyDurationMs = 100;
540  *
541  * // Init SPI and specify non-default parameters SPI_Params_init(&params);
542  * params.bitRate = 500000; params.frameFormat = SPI_POL1_PHA1;
543  * params.mode = SPI_CONTROLLER;
544  *
545  * // Configure the transaction transaction.count = sizeof(txBuf);
546  * transaction.txBuf = txBuf; transaction.rxBuf = rxBuf;
547  *
548  * // Open the SPI and perform the transfer handle = SPI_open(CONFIG_SPI_0,
549  * &params);
550  *
551  * // Apply low power sleep pull config for POCI
552  * GPIO_setConfig(CONFIG_GPIO_SPI_0_POCI, GPIO_CFG_IN_PU);
553  *
554  * // Do forever while(1) { // Transfer data SPI_transfer(handle,
555  * &transaction); // Sleep Task_sleep(standbyDurationMs*100);
556  * }
557  * @endcode
558  *
559  * ### Wake Up On Chip Select Deassertion In Peripheral Mode Using #SPI_MODE_CALLBACK #
560  * This example demonstrates using a GPIO callback on Chip Select to wake up
561  the device to allow low power modes while waiting for a chip select edge.
562  *
563  * In sysconfig or the board file, the CSN GPIO should be configured as
564  * input/pull up with an interrupt on falling edge. Otherwise, SPI_close() will
565  * reset the pin to the wrong settings and you may see line glitches.
566  *
567  * *Note: The SPI controller must allow enough time between deasserting the
568  chip select and the start of the transaction for the SPI peripheral to wake
569  up and open up the SPI driver.
570  *
571  * @code
572  * // Global variables SPI_Handle spiHandle SPI_Params spiParams;
573  * SPI_Transaction spiTransaction; const uint8_t transferSize = 8; uint8_t
574  * txBuf[8];
575  *
576  * // Chip select callback static void chipSelectCallback(uint_least8_t)
577  * {
578  * // Open SPI driver, which will override any previous GPIO configuration
579  * spiHandle = SPI_open(CONFIG_SPI, &spiParams);
580  * // Issue the transfer
581  * SPI_transfer(spiHandle, &spiTransaction);
582  * }
583  *
584  * // SPI transfer callback static void transferCallback(SPI_Handle handle,
585  * SPI_Transaction *transaction)
586  * {
587  * // Close the SPI driver
588  * SPI_close(handle);
589  *
590  * // Note: SPI_close() will reset the pin configuration, so it is
591  important to
592  // set the default values correctly in sysconfig. We just need to set
593  the
594  // callback and enable the falling edge interrupt
595  *
596  * GPIO_setCallback(CS_PIN_INDEX, chipSelectCallback);
597  * GPIO_enableInt(CS_PIN_INDEX);
598  * }
599  *
600  * // From your_application.c static void taskFxn(uintptr_t a0, uintptr_t a1)
601  * {
602  * uint8_t i;
603  *
604  * // Setup SPI params
605  * SPI_Params_init(&spiParams);
606  * spiParams.bitRate = 1000000;
607  * spiParams.frameFormat = SPI_POL1_PHA1;
608  * spiParams.mode = SPI_PERIPHERAL;
609  * spiParams.dataSize = transferSize;
610  * spiParams.transferMode = SPI_MODE_CALLBACK;
611  * spiParams.transferCallbackFxn = transferCallback;
612  *
613  * // Setup SPI transaction
614  * spiTransaction.arg = NULL;
615  * spiTransaction.count = transferSize;
616  * spiTransaction.txBuf = txBuf;
617  * spiTransaction.rxBuf = txBuf;
618  *
619  * // First echo message
620  * for (i = 0; i < transferSize; i++) {
621  * txBuf[i] = i;
622  * }
623  *
624  * // Configure chip select callback
625  * GPIO_setCallback(CS_PIN_INDEX, chipSelectCallback);
626  * GPIO_enableInt(CS_PIN_INDEX);
627  *
628  * // Wait forever
629  * while(true);
630  * }
631  * @endcode
632  *
633  * <hr>
634  */
639 /* clang-format off */
640 #ifndef ti_drivers_spi_SPIMSPM0__include
641 #define ti_drivers_spi_SPIMSPM0__include
642 
643 #include <stdint.h>
644 #include <ti/drivers/SPI.h>
645 #include <ti/drivers/dma/DMAMSPM0.h>
647 #ifdef POWER_MANAGEMENT_MSPM0
648 #include <ti/drivers/Power.h>
649 #endif
650 #include <ti/driverlib/dl_spi.h>
651 #include <ti/drivers/dpl/HwiP.h>
652 #include <ti/drivers/dpl/SemaphoreP.h>
653 #ifdef __cplusplus
654 extern "C" {
655 #endif
656 
667 /* Add SPIMSPM0_STATUS_* macros here */
668 
689 #define SPIMSPM0_CMD_RETURN_PARTIAL_ENABLE (SPI_CMD_RESERVED + 0)
690 
698 #define SPIMSPM0_CMD_RETURN_PARTIAL_DISABLE (SPI_CMD_RESERVED + 1)
699 
706 #define SPIMSPM0_CMD_SET_CSN_PIN (SPI_CMD_RESERVED + 2)
707 
713 #define SPIMSPM0_CMD_CLEAR_CSN_PIN (SPI_CMD_RESERVED + 3)
714 
728 #define SPIMSPM0_CMD_SET_MANUAL (SPI_CMD_RESERVED + 4)
729 
739 #define SPIMSPM0_CMD_CLR_MANUAL (SPI_CMD_RESERVED + 5)
740 
751 #define SPIMSPM0_CMD_MANUAL_START (SPI_CMD_RESERVED + 6)
752 
772 #define SPIMSPM0_CMD_SET_SAMPLE_DELAY (SPI_CMD_RESERVED + 7)
773 
779 extern const SPI_FxnTable SPIMSPM0_fxnTable;
780 
787 typedef enum
788 {
794 
800 typedef enum
801 {
809 
866 typedef struct
867 {
869  SPI_Regs *spi;
871  uint8_t intNum;
884  uint8_t intPriority;
885 #ifdef POWER_MANAGEMENT_MSPM0
886 
887  uint8_t powerID;
888 #endif
889 
892 
894  DL_SPI_CLOCK clockSource;
896  DL_SPI_CLOCK_DIVIDE_RATIO clockDivider;
897 
899  uint32_t pociPinMux;
901  uint32_t picoPinMux;
903  uint32_t sclkPinMux;
905  uint32_t csnPinMux;
906 
908  uint_least8_t pociPincm;
910  uint_least8_t pociPin;
911 
913  uint_least8_t picoPincm;
915  uint_least8_t picoPin;
916 
918  uint_least8_t sclkPincm;
920  uint_least8_t sclkPin;
921 
923  uint_least8_t csnPincm;
925  uint_least8_t csnPin;
926 
928  DL_SPI_TX_FIFO_LEVEL txFifoThreshold;
930  DL_SPI_RX_FIFO_LEVEL rxFifoThreshold;
936 
942 typedef struct
943 {
945  HwiP_Struct hwi;
946 #ifdef POWER_MANAGEMENT_MSPM0
947  Power_NotifyObj spiPostObj;
948 #endif
949 
950  SemaphoreP_Struct transferComplete;
960  size_t framesQueued;
964  size_t transferSize;
966  uint32_t txDMAChannel;
968  uint32_t rxDMAChannel;
970  uint32_t bitRate;
972  uint32_t dataSize;
974  uint32_t transferTimeout;
976  uint32_t busyBit;
978  uint32_t dsample;
980  uint16_t rxScratchBuf;
982  uint16_t txScratchBuf;
988  uint8_t format;
992  uint_least8_t csnPin;
998  bool isOpen;
1001 } SPIMSPM0_Object;
1002 
1003 #ifdef __cplusplus
1004 }
1005 #endif
1006 
1007 #endif /* ti_drivers_spi_SPIMSPM0__include */
1008 /* clang-format on */
uint32_t sclkPinMux
Definition: SPIMSPM0.h:903
Definition: SPIMSPM0.h:790
SPI_Parity parity
Definition: SPIMSPM0.h:996
uint_least8_t sclkPin
Definition: SPIMSPM0.h:920
uint32_t dataSize
Definition: SPIMSPM0.h:972
SPI Driver Interface.
size_t transferSize
Definition: SPIMSPM0.h:964
SPIMSPM0 Object.
Definition: SPIMSPM0.h:942
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:611
uint16_t defaultTxBufValue
Definition: SPIMSPM0.h:891
SPIMSPM0_FrameSize
SPIMSPM0 data frame size is used to determine how to configure the DMA data transfers. This field is to be only used internally.
Definition: SPIMSPM0.h:787
uint_least8_t csnPin
Definition: SPIMSPM0.h:925
uint32_t pociPinMux
Definition: SPIMSPM0.h:899
uint32_t transferTimeout
Definition: SPIMSPM0.h:974
SPIMSPM0 Hardware attributes.
Definition: SPIMSPM0.h:866
DL_SPI_TX_FIFO_LEVEL txFifoThreshold
Definition: SPIMSPM0.h:928
SPI_TransferMode
SPI transfer mode determines the whether the SPI controller operates synchronously or asynchronously...
Definition: SPI.h:704
SPIMSPM0_ReturnPartial
SPIMSPM0 return partial field indicates the status of the return partial mode and the associated pin ...
Definition: SPIMSPM0.h:800
SPI_Chip_Select cssel
Definition: SPIMSPM0.h:932
uint8_t format
Definition: SPIMSPM0.h:988
uint32_t txDMAChannel
Definition: SPIMSPM0.h:966
size_t framesTransferred
Definition: SPIMSPM0.h:962
uint32_t rxDMAChannel
Definition: SPIMSPM0.h:968
uint_least8_t csnPincm
Definition: SPIMSPM0.h:923
HwiP_Struct hwi
Definition: SPIMSPM0.h:945
DMAMSPM0 Global configuration.
Definition: DMAMSPM0.h:181
bool isOpen
Definition: SPIMSPM0.h:998
The definition of a SPI function table that contains the required set of functions to control a speci...
Definition: SPI.h:792
const SPI_FxnTable SPIMSPM0_fxnTable
SPI function table pointer.
uint32_t dsample
Definition: SPIMSPM0.h:978
SPI_Mode
Definitions for various SPI modes of operation.
Definition: SPI.h:616
uint_least8_t sclkPincm
Definition: SPIMSPM0.h:918
SPI_Parity
Definitions for parity.
Definition: SPI.h:628
SPI_Chip_Select
Definitions for chip select.
Definition: SPI.h:652
uint_least8_t csnPin
Definition: SPIMSPM0.h:992
uint8_t intNum
Definition: SPIMSPM0.h:871
Definition: SPIMSPM0.h:807
DL_SPI_CLOCK_DIVIDE_RATIO clockDivider
Definition: SPIMSPM0.h:896
uint_least8_t picoPin
Definition: SPIMSPM0.h:915
A SPI_Transaction data structure is used with SPI_transfer(). It indicates how many SPI_FrameFormat f...
Definition: SPI.h:584
uint8_t noOfDMAChannels
Definition: SPIMSPM0.h:934
GPIO driver implementation for MSPM0 devices.
uint_least8_t picoPincm
Definition: SPIMSPM0.h:913
uint_least8_t pociPincm
Definition: SPIMSPM0.h:908
uint16_t txScratchBuf
Definition: SPIMSPM0.h:982
Definition: SPIMSPM0.h:805
SPI_Transaction * tailPtr
Definition: SPIMSPM0.h:958
uint32_t csnPinMux
Definition: SPIMSPM0.h:905
SPI_TransferMode transferMode
Definition: SPIMSPM0.h:984
uint32_t busyBit
Definition: SPIMSPM0.h:976
SPI_Mode mode
Definition: SPIMSPM0.h:986
SPI_Transaction * headPtr
Definition: SPIMSPM0.h:956
bool manualStart
Definition: SPIMSPM0.h:1000
DL_SPI_CLOCK clockSource
Definition: SPIMSPM0.h:894
uint_least8_t pociPin
Definition: SPIMSPM0.h:910
uint32_t bitRate
Definition: SPIMSPM0.h:970
uint32_t picoPinMux
Definition: SPIMSPM0.h:901
DL_SPI_RX_FIFO_LEVEL rxFifoThreshold
Definition: SPIMSPM0.h:930
SPI_BitOrder
Definitions for bit order.
Definition: SPI.h:641
SPI_BitOrder bitOrder
Definition: SPIMSPM0.h:990
size_t framesQueued
Definition: SPIMSPM0.h:960
DMAMSPM0_Handle DMA_Handle
Definition: SPIMSPM0.h:952
SPI_CallbackFxn transferCallbackFxn
Definition: SPIMSPM0.h:954
SPIMSPM0_ReturnPartial returnPartial
Definition: SPIMSPM0.h:994
SemaphoreP_Struct transferComplete
Definition: SPIMSPM0.h:950
uint16_t rxScratchBuf
Definition: SPIMSPM0.h:980
Definition: SPIMSPM0.h:792
SPI_Regs * spi
Definition: SPIMSPM0.h:869
DMA driver implementation for MSPM0.
Definition: SPIMSPM0.h:803
uint8_t intPriority
SPIMSPM0 Peripheral&#39;s interrupt priority.
Definition: SPIMSPM0.h:884
© Copyright 1995-2023, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale