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       SPI.h
34  *
35  *  @brief      Serial Peripheral Interface (SPI) Driver Interface
36  *
37  * @anchor ti_drivers_SPI_Overview
38  *  # Overview
39  *  The Serial Peripheral Interface (SPI) driver is a generic, full-duplex
40  *  driver that transmits and receives data on a SPI bus.  SPI is sometimes
41  *  called SSI (Synchronous Serial Interface).
42  *  The SPI protocol defines the format of a data transfer over the SPI bus,
43  *  but it leaves flow control, data formatting, and handshaking mechanisms
44  *  to higher-level software layers.
45  *
46  *  The SPI driver operates on some key definitions and assumptions:
47  *  - The driver operates transparently from the chip select. Some SPI
48  *    controllers feature a hardware chip select to assert SPI slave
49  *    peripherals. See the specific device implementations on chip
50  *    select requirements.
51  *
52  *  - The SPI protocol does not account for a built-in handshaking mechanism
53  *    and neither does this SPI driver. Therefore, when operating in
54  *    #SPI_SLAVE mode, the application must provide such a mechanism to
55  *    ensure that the SPI slave is ready for the SPI master. The SPI slave
56  *    must call #SPI_transfer() *before* the SPI master starts transmitting.
57  *    Some example application mechanisms could include:
58  *    - Timed delays on the SPI master to guarantee the SPI slave is ready
59  *      for a SPI transaction.
60  *    - A form of GPIO flow control from the slave to the SPI master to notify
61  *      the master when ready.
62  *
63  *  <hr>
64  *  @anchor ti_drivers_SPI_Usage
65  *  # Usage
66  *
67  *  To use the SPI driver to send data over the SPI bus, the application
68  *  calls the following APIs:
69  *    - SPI_init(): Initialize the SPI driver.
70  *    - SPI_Params_init():  Initialize a #SPI_Params structure with default
71  *      values.  Then change the parameters from non-default values as
72  *      needed.
73  *    - SPI_open():  Open an instance of the SPI driver, passing the
74  *      initialized parameters, or NULL, and an index to the configuration to
75  *      open (detailed later).
76  *    - SPI_transfer():  Transmit/receive data.  This function takes a
77  *      #SPI_Transaction argument that describes the transfer that is requested.
78  *    - SPI_close():  De-initialize the SPI instance.
79  *
80  *  @anchor ti_drivers_SPI_Synopsis
81  *  ## Synopsis
82  *  The following code example opens a SPI instance as a master SPI,
83  *  and issues a transaction.
84  *
85  *  @code
86  *  SPI_Handle      spi;
87  *  SPI_Params      spiParams;
88  *  SPI_Transaction spiTransaction;
89  *  uint8_t         transmitBuffer[MSGSIZE];
90  *  uint8_t         receiveBuffer[MSGSIZE];
91  *  bool            transferOK;
92  *
93  *  SPI_init();  // Initialize the SPI driver
94  *
95  *  SPI_Params_init(&spiParams);  // Initialize SPI parameters
96  *  spiParams.dataSize = 8;       // 8-bit data size
97  *
98  *  spi = SPI_open(CONFIG_SPI0, &spiParams);
99  *  if (spi == NULL) {
100  *      while (1);  // SPI_open() failed
101  *  }
102  *
103  *  // Fill in transmitBuffer
104  *  spiTransaction.count = MSGSIZE;
105  *  spiTransaction.txBuf = (void *)transmitBuffer;
106  *  spiTransaction.rxBuf = (void *)receiveBuffer;
107  *
108  *  transferOK = SPI_transfer(spi, &spiTransaction);
109  *  if (!transferOK) {
110  *      // Error in SPI or transfer already in progress.
111  *      while (1);
112  *  }
113  *  @endcode
114  *
115  *  More details on usage are provided in the following subsections.
116  *
117  *  @anchor ti_drivers_SPI_Examples
118  *  ## Examples #
119  *  * @ref ti_drivers_SPI_Synopsis "Usage Synopsis"
120  *  * @ref ti_drivers_SPI_Example_openblocking "Open in blocking mode"
121  *  * @ref ti_drivers_SPI_Example_opencallback "Open in callback mode"
122  *  * @ref ti_drivers_SPI_Example_6bitframes "Sending 6 bit frames"
123  *  * @ref ti_drivers_SPI_Example_12bitframes "Sending 12 bit frames"
124  *  * @ref ti_drivers_SPI_Example_callbackarg "Callback function using arg"
125  *
126  *  ## Initializing the SPI Driver
127  *
128  *  SPI_init() must be called before any other SPI APIs.  This function
129  *  iterates through the elements of the @p SPI_config[] array, calling
130  *  the element's device implementation SPI initialization function.
131  *
132  *  ## Opening the SPI Driver
133  *  After initializing the SPI driver by calling SPI_init(), the application
134  *  can open a SPI instance by calling SPI_open().  This function
135  *  takes an index into the @p SPI_config[] array, and a SPI parameters data
136  *  structure. The SPI instance is specified by the index of the SPI in
137  *  @p SPI_config[]. Calling SPI_open() a second time with the same index
138  *  previously passed to SPI_open() will result in an error.  You can,
139  *  though, re-use the index if the instance is closed via SPI_close().
140  *
141  *  If no #SPI_Params structure is passed to SPI_open(), default values are
142  *  used. If the open call is successful, it returns a non-NULL value.
143  *
144  *  @anchor ti_drivers_SPI_Example_openblocking
145  *  Example opening a SPI driver instance in blocking mode:
146  *  @code
147  *  SPI_Handle  spi;
148  *  SPI_Params  spiParams;
149  *
150  *  SPI_Params_init(&spiParams);
151  *  spiParams.transferMode = SPI_MODE_BLOCKING;
152  *  spi = SPI_open(CONFIG_SPI0, &spiParams);
153  *
154  *  if (spi == NULL) {
155  *      // Error opening SPI
156  *      while(1);
157  *  }
158  *  @endcode
159  *
160  *  @anchor ti_drivers_SPI_Example_opencallback
161  *  Example opening a SPI driver instance in callback mode:
162  *  @code
163  *  SPI_Handle spi;
164  *  SPI_Params spiParams;
165  *
166  *  SPI_Params_init(&spiParams);
167  *  spiParams.transferMode = SPI_MODE_CALLBACK;
168  *  spiParams.transferCallbackFxn = UserCallbackFxn;
169  *
170  *  spi = SPI_open(CONFIG_SPI0, &spiParams);
171  *  if (spi == NULL) {
172  *      // Error opening SPI
173  *      while (1);
174  *  }
175  *  @endcode
176  *
177  *  ## SPI Parameters
178  *
179  *  The #SPI_Params structure is passed to the SPI_open() call.  If NULL
180  *  is passed for the parameters, SPI_open() uses default parameters.
181  *  A #SPI_Params structure is initialized with default values by passing
182  *  it to SPI_Params_init().
183  *  Some of the SPI parameters are described below.  To see brief descriptions
184  *  of all the parameters, see #SPI_Params.
185  *
186  *  ### SPI Mode
187  *  The SPI driver operates in both SPI master and SPI slave modes.
188  *  Logically, the implementation is identical, however the difference
189  *  between these two modes is driven by hardware.  The default mode is
190  *  #SPI_MASTER, but can be set to slave mode by setting #SPI_Params.mode
191  *  to #SPI_SLAVE in the parameters passed to SPI_open().  See
192  *  @ref ti_drivers_SPI_MasterSlaveModes "Master/Slave Modes" for further
193  *  details.
194  *
195  *  ### SPI Transfer Mode
196  *  The SPI driver supports two transfer modes of operation: blocking and
197  *  callback. The transfer mode is determined by the transferMode parameter
198  *  in the #SPI_Params data structure. The SPI driver
199  *  defaults to blocking mode, if the application does not set it.
200  *  Once a SPI driver is opened, the only way to change the operation mode
201  *  is to close and re-open the SPI instance with the new transfer mode.
202  *
203  *  In blocking mode, a task's code execution is blocked until a SPI
204  *  transaction has completed or a timeout has occurred. This ensures
205  *  that only one SPI transfer operates at a given time. Other tasks requesting
206  *  SPI transfers while a transfer is currently taking place will receive
207  *  a FALSE return value.  If a timeout occurs the transfer is canceled, the
208  *  task is unblocked & will receive a FALSE return value. The transaction
209  *  count field will have the amount of frames which were transferred
210  *  successfully before the timeout.  In blocking mode, transfers cannot be
211  *  performed in software or hardware ISR context.
212  *
213  *  In callback mode, a SPI transaction functions asynchronously, which
214  *  means that it does not block code execution. After a SPI transaction
215  *  has been completed, the SPI driver calls a user-provided hook function.
216  *  Callback mode is supported in the execution context of tasks and
217  *  hardware interrupt routines.
218  *
219  *  ### SPI Frame Formats and Data Size
220  *  The SPI driver can configure the device's SPI peripheral to transfer
221  *  data in several SPI format options: SPI (with various polarity and phase
222  *  settings), TI, and Micro-wire. The frame format is set with
223  *  #SPI_Params.frameFormat. Some SPI implementations may not support all frame
224  *  formats & the SPI driver will fail to opened.  Refer to the device specific
225  *  implementation documentation for details on which frame formats are
226  *  supported.
227  *
228  *  The smallest single unit of data transmitted onto the SPI bus is called
229  *  a SPI frame and is of size #SPI_Params.dataSize.  A series of SPI frames
230  *  transmitted/received on a SPI bus is referred to as a SPI transaction.
231  *
232  *  ## SPI Transactions
233  *
234  *  A SPI transaction consists of a series of SPI frames
235  *  transmitted/received on a SPI bus.  A SPI transaction is performed
236  *  using SPI_transfer(). SPI_transfer() accepts a pointer to a
237  *  #SPI_Transaction structure that dictates the quantity of data to be
238  *  sent and received.
239  *  The #SPI_Transaction.txBuf and #SPI_Transaction.rxBuf are both pointers
240  *  to data buffers.  If txBuf is NULL, the driver sends SPI frames with all
241  *  data set to the default value specified in the hardware attributes. If
242  *  rxBuf is NULL, the driver discards all SPI frames received. SPI_transfer()
243  *  of a SPI transaction is performed atomically.
244  *
245  *  @warning The use of NULL as a sentinel txBuf or rxBuf value to determine
246  *  whether the SPI transaction includes a tx or rx component implies
247  *  that it is not possible to perform a transmit or receive transfer
248  *  directly from/to a buffer with a base address of 0x00000000. To support
249  *  this rare use-case, the application will have to manually copy the
250  *  contents of location 0x00000000 to/from a temporary buffer before/after
251  *  the tx/rx SPI transaction.
252  *
253  *  When the SPI is opened, the dataSize value determines the element types
254  *  of txBuf and rxBuf. If the dataSize is from 4 to 8 bits, the driver
255  *  assumes the data buffers are of type uint8_t (unsigned char). If the
256  *  dataSize is from 8 to 16 bits, the driver assumes the data buffers are
257  *  of type uint16_t (unsigned short).  If the dataSize is greater than
258  *  16 bits, the driver assumes the data buffers are uint32_t (unsigned long).
259  *  Some SPI driver implementations may not support all data sizes; refer
260  *  to device specific SPI implementation documentation for details on
261  *  what data sizes are supported.
262  *
263  *  The optional #SPI_Transaction.arg variable can only be used when the
264  *  SPI driver has been opened in callback mode. This variable is used to
265  *  pass a user-defined value into the user-defined callback function.
266  *
267  *  SPI_transfer() always performs full-duplex SPI transactions. This means
268  *  the SPI simultaneously receives data as it transmits data. The application
269  *  is responsible for formatting the data to be transmitted as well as
270  *  determining whether the data received is meaningful.
271  *  Specifics about SPI frame formatting and data sizes are provided in
272  *  device-specific data sheets and technical reference manuals.
273  *
274  *  The following code snippets perform SPI transactions.
275  *
276  *  @anchor ti_drivers_SPI_Example_6bitframes
277  *  Example transferring 6-bit SPI frames.  The transmit and receive
278  *  buffers are of type uint8_t.
279  *  @code
280  *  SPI_Transaction spiTransaction;
281  *  uint8_t         transmitBuffer[BUFSIZE];
282  *  uint8_t         receiveBuffer[BUFSIZE];
283  *  bool            transferOK;
284  *
285  *  SPI_Params_init(&spiParams);
286  *  spiParams.dataSize = 6;
287  *  spi = SPI_open(CONFIG_SPI0, &spiParams);
288  *  ...
289  *  spiTransaction.count = someIntegerValue;
290  *  spiTransaction.txBuf = transmitBuffer;
291  *  spiTransaction.rxBuf = receiveBuffer;
292  *
293  *  transferOK = SPI_transfer(spi, &spiTransaction);
294  *  if (!transferOK) {
295  *      // Error in SPI or transfer already in progress.
296  *  }
297  *  @endcode
298  *
299  *  @anchor ti_drivers_SPI_Example_12bitframes
300  *  Example transferring 12-bit SPI frames.  The transmit and receive
301  *  buffers are of type uint16_t.
302  *  @code
303  *  SPI_Transaction spiTransaction;
304  *  uint16_t        transmitBuffer[BUFSIZE];
305  *  uint16_t        receiveBuffer[BUFSIZE];
306  *  bool            transferOK;
307  *
308  *  SPI_Params_init(&spiParams);
309  *  spiParams.dataSize = 12;
310  *  spi = SPI_open(CONFIG_SPI0, &spiParams);
311  *  ...
312  *  spiTransaction.count = someIntegerValue;
313  *  spiTransaction.txBuf = transmitBuffer;
314  *  spiTransaction.rxBuf = receiveBuffer;
315  *
316  *  transferOK = SPI_transfer(spi, &spiTransaction);
317  *  if (!transferOK) {
318  *      // Error in SPI or transfer already in progress.
319  *  }
320  *  @endcode
321  *
322  * The following example shows an example of a callback function that
323  * utilizes the arg parameter.
324  *  @anchor ti_drivers_SPI_Example_callbackarg
325  *  @code
326  *  // SPI is opened with callback function as seen in other examples
327  *  // Our goal is to post a semaphore when transfer with sufficient size
328  *  // completes.
329  *  ...
330  *  // Pass pointer to an initialized semaphore to callback via arg
331  *  spiTransaction.count = someIntegerValue;
332  *  spiTransaction.txBuf = transmitBuffer;
333  *  spiTransaction.rxBuf = receiveBuffer;
334  *  spiTransaction.arg   = &mySemaphore;
335  *
336  *  ...
337  *
338  *  // Our callback function is defined here
339  *  void spiCallbackFxn(SPI_Handle spi, SPI_Transaction *tran)
340  *  {
341  *      sem_t *semPtr = (sem_t *)(tran->arg);
342  *
343  *      // Post the semaphore if our transaction was more than LIMIT
344  *      if (tran->status == SPI_STATUS_SUCCESS &&
345  *          tran->count > LIMIT) {
346  *          sem_post(semPtr);
347  *      }
348  *  }
349  *  @endcode
350  *
351  *  ## Canceling a transaction
352  *  SPI_transferCancel() is used to cancel a SPI transaction when the driver is
353  *  used in #SPI_MODE_CALLBACK mode.
354  *
355  *  Calling this API while no transfer is in progress has no effect. If a
356  *  transfer is in progress, it is canceled and the callback functions is
357  *  called.
358  *  The #SPI_Status status field in the #SPI_Transaction structure
359  *  can be examined within the callback to determine if the transaction
360  *  succeeded.
361  *
362  *  Example:
363  *  @code
364  *  SPI_transferCancel(spi);
365  *  @endcode
366  *
367  *  @anchor ti_drivers_SPI_MasterSlaveModes
368  *  ## Master/Slave Modes
369  *  This SPI driver functions in both SPI master and SPI slave modes.
370  *  Logically, the implementation is identical, however the difference between
371  *  these two modes is driven by hardware. As a SPI master, the peripheral is
372  *  in control of the clock signal and therefore will commence communications
373  *  to the SPI slave immediately. As a SPI slave, the SPI driver prepares
374  *  the peripheral to transmit and receive data in a way such that the
375  *  peripheral is ready to transfer data when the SPI master initiates a
376  *  transaction.
377  *
378  *  ## Asserting on Chip Select
379  *  The SPI protocol requires that the SPI master asserts a SPI slave's chip
380  *  select pin prior to starting a SPI transaction. While this protocol is
381  *  generally followed, various types of SPI peripherals have different
382  *  timing requirements as to when and for how long the chip select pin must
383  *  remain asserted for a SPI transaction.
384  *
385  *  Commonly, the SPI master uses a hardware chip select to assert and
386  *  de-assert the SPI slave for every data frame. In other cases, a SPI slave
387  *  imposes the requirement of asserting the chip select over several SPI
388  *  data frames. This is generally accomplished by using a regular,
389  *  general-purpose output pin. Due to the complexity of such SPI peripheral
390  *  implementations, this SPI driver has been designed to operate
391  *  transparently to the SPI chip select. When the hardware chip
392  *  select is used, the peripheral automatically selects/enables the
393  *  peripheral. When using a software chip select, the application needs to
394  *  handle the proper chip select and pin configuration.  Chip select support
395  *  will vary per SPI peripheral, refer to the device specific implementation
396  *  documentation for details on chip select support.
397  *
398  *  - _Hardware chip select_  No additional action by the application is
399  *    required.
400  *  - _Software chip select_  The application needs to handle the chip select
401  *    assertion and de-assertion for the proper SPI peripheral.
402  *
403  *  <hr>
404  *  @anchor ti_drivers_SPI_Configuration
405  *  # Configuration
406  *
407  *  In order to use the SPI APIs, the application is required to provide
408  *  device-specific SPI configuration in the ti_drivers_config.c file.
409  *  The SPI driver interface defines a configuration data structure:
410  *
411  *  @code
412  *  typedef struct  {
413  *      SPI_FxnTable  const    *fxnTablePtr;
414  *      void                   *object;
415  *      void          const    *hwAttrs;
416  *  } SPI_Config;
417  *  @endcode
418  *
419  *  The application must declare an array of #SPI_Config elements, named
420  *  @p SPI_config[].  Each element of @p SPI_config[] must be populated with
421  *  pointers to a device specific SPI driver implementation's function
422  *  table, driver object, and hardware attributes.  The hardware attributes
423  *  define properties such as the SPI peripheral's base address, and
424  *  the MOSI and MISO pins.  Each element in @p SPI_config[] corresponds to
425  *  a SPI instance, and none of the elements should have NULL pointers.
426  *  There is no correlation between the index and the
427  *  peripheral designation (such as SPI0 or SPI1).  For example, it is
428  *  possible to use SPI_config[0] for SPI1.
429  *
430  *  Because the SPI configuration is very device dependent, you will need to
431  *  check the doxygen for the device specific SPI implementation.  There you
432  *  will find a description of the SPI hardware attributes.  Please also
433  *  refer to the ti_drivers_config.c file of any of your examples to see the
434  *  SPI configuration.
435  *
436  *******************************************************************************
437  */
438 
439 #ifndef ti_drivers_SPI__include
440 #define ti_drivers_SPI__include
441 
442 #include <stdbool.h>
443 #include <stddef.h>
444 #include <stdint.h>
445 
446 #ifdef __cplusplus
447 extern "C" {
448 #endif
449 
450 /**
451  *  @defgroup SPI_CONTROL SPI_control command and status codes
452  *  These SPI macros are reservations for SPI.h
453  *  @{
454  */
455 
456 /*!
457  * Common SPI_control() command code reservation offset.
458  * SPI driver implementations should offset command codes with #SPI_CMD_RESERVED
459  * growing positively
460  *
461  * Example implementation specific command codes:
462  * @code
463  * #define SPIXYZ_CMD_COMMAND0     SPI_CMD_RESERVED + 0
464  * #define SPIXYZ_CMD_COMMAND1     SPI_CMD_RESERVED + 1
465  * @endcode
466  */
467 #define SPI_CMD_RESERVED           (32)
468 
469 /*!
470  * Common SPI_control status code reservation offset.
471  * SPI driver implementations should offset status codes with
472  * #SPI_STATUS_RESERVED growing negatively.
473  *
474  * Example implementation specific status codes:
475  * @code
476  * #define SPIXYZ_STATUS_ERROR0    SPI_STATUS_RESERVED - 0
477  * #define SPIXYZ_STATUS_ERROR1    SPI_STATUS_RESERVED - 1
478  * #define SPIXYZ_STATUS_ERROR2    SPI_STATUS_RESERVED - 2
479  * @endcode
480  */
481 #define SPI_STATUS_RESERVED        (-32)
482 
483 /**
484  *  @defgroup SPI_STATUS Status Codes
485  *  SPI_STATUS_* macros are general status codes returned by SPI_control()
486  *  @{
487  *  @ingroup SPI_CONTROL
488  */
489 
490 /*!
491  * @brief   Successful status code returned by SPI_control().
492  *
493  * This value is returned from SPI_control() if the control code was executed
494  * successfully.
495  */
496 #define SPI_STATUS_SUCCESS         (0)
497 
498 /*!
499  * @brief   Generic error status code returned by SPI_control().
500  *
501  * This value is returned from SPI_control() if the control code was not
502  * executed successfully.
503  */
504 #define SPI_STATUS_ERROR           (-1)
505 
506 /*!
507  * @brief   An error status code returned by SPI_control() for undefined
508  * command codes.
509  *
510  * This value is returned from SPI_control() if the control code is not
511  * recognized by the driver implementation.
512  */
513 #define SPI_STATUS_UNDEFINEDCMD    (-2)
514 /** @}*/
515 
516 /**
517  *  @defgroup SPI_CMD Command Codes
518  *  SPI_CMD_* macros are general command codes for SPI_control(). Not all SPI
519  *  driver implementations support these command codes.
520  *  @{
521  *  @ingroup SPI_CONTROL
522  */
523 
524 /* Add SPI_CMD_<commands> here */
525 
526 /** @}*/
527 
528 /** @}*/
529 
530 /*!
531  *  @brief    Wait forever define used to specify timeouts.
532  */
533 #define SPI_WAIT_FOREVER           (~(0U))
534 
535 /*!
536  *  @brief      A handle that is returned from a SPI_open() call.
537  */
538 typedef struct SPI_Config_    *SPI_Handle;
539 
540 /*!
541  *  @brief      Status codes that are set by the SPI driver.
542  */
543 typedef enum {
544     SPI_TRANSFER_COMPLETED = 0,      /*!< SPI transfer completed */
545     SPI_TRANSFER_STARTED,            /*!< SPI transfer started and in progress */
546     SPI_TRANSFER_CANCELED,           /*!< SPI transfer was canceled */
547     SPI_TRANSFER_FAILED,             /*!< SPI transfer failed */
548     SPI_TRANSFER_CSN_DEASSERT,       /*!< SPI chip select was de-asserted (only
549                                           applicable in return partial mode) */
550     SPI_TRANSFER_PEND_CSN_ASSERT,    /*!< SPI transfer is pending until the chip
551                                           select is asserted */
552     SPI_TRANSFER_QUEUED              /*!< SPI transfer added to transaction queue */
553 } SPI_Status;
554 
555 /*!
556  *  @brief
557  *  A #SPI_Transaction data structure is used with SPI_transfer(). It indicates
558  *  how many #SPI_FrameFormat frames are sent and received from the buffers
559  *  pointed to txBuf and rxBuf.
560  *  The arg variable is an user-definable argument which gets passed to the
561  *  #SPI_CallbackFxn when the SPI driver is in #SPI_MODE_CALLBACK.
562  */
563 typedef struct  {
564     /* User input (write-only) fields */
565     size_t     count;       /*!< Number of frames for this transaction */
566     void      *txBuf;       /*!< void * to a buffer with data to be transmitted */
567     void      *rxBuf;       /*!< void * to a buffer to receive data */
568     void      *arg;         /*!< Argument to be passed to the callback function */
569 
570     /* User output (read-only) fields */
571     SPI_Status status;      /*!< #SPI_Status code set by SPI_transfer */
572 
573     void *nextPtr;          /*!< Field used internally by the driver and must
574                                  never be accessed by the application. */
575 } SPI_Transaction;
576 
577 /*!
578  *  @brief      The definition of a callback function used by the SPI driver
579  *              when used in #SPI_MODE_CALLBACK
580  *
581  *  @param      SPI_Handle          A #SPI_Handle
582  *  @param      SPI_Transaction*    Pointer to a #SPI_Transaction
583  */
584 typedef void (*SPI_CallbackFxn) (SPI_Handle handle,
585     SPI_Transaction *transaction);
586 /*!
587  *  @brief
588  *  Definitions for various SPI modes of operation.
589  */
590 typedef enum {
591     SPI_MASTER = 0,    /*!< SPI in master mode */
592     SPI_SLAVE  = 1     /*!< SPI in slave mode */
593 } SPI_Mode;
594 
595 /*!
596  *  @brief
597  *  Definitions for various SPI data frame formats.
598  */
599 typedef enum {
600     SPI_POL0_PHA0 = 0,    /*!< SPI mode Polarity 0 Phase 0 */
601     SPI_POL0_PHA1 = 1,    /*!< SPI mode Polarity 0 Phase 1 */
602     SPI_POL1_PHA0 = 2,    /*!< SPI mode Polarity 1 Phase 0 */
603     SPI_POL1_PHA1 = 3,    /*!< SPI mode Polarity 1 Phase 1 */
604     SPI_TI        = 4,    /*!< TI mode (not supported on all
605                                implementations) */
606     SPI_MW        = 5     /*!< Micro-wire mode (not supported on all
607                                implementations) */
608 } SPI_FrameFormat;
609 
610 /*!
611  *  @brief
612  *
613  *  SPI transfer mode determines the whether the SPI controller operates
614  *  synchronously or asynchronously. In #SPI_MODE_BLOCKING mode SPI_transfer()
615  *  blocks code execution until the SPI transaction has completed. In
616  *  #SPI_MODE_CALLBACK SPI_transfer() does not block code execution and instead
617  *  calls a #SPI_CallbackFxn callback function when the transaction has
618  *  completed (successfully or not).
619  */
620 typedef enum {
621     /*!
622      * SPI_transfer() blocks execution. This mode can only be used when called
623      * within a Task context
624      */
625     SPI_MODE_BLOCKING,
626     /*!
627      * SPI_transfer() does not block code execution and will call a
628      * #SPI_CallbackFxn. This mode can be used in a Task, software or hardware
629      * interrupt context.
630      */
631     SPI_MODE_CALLBACK
632 } SPI_TransferMode;
633 
634 /*!
635  *  @brief SPI Parameters
636  *
637  *  SPI Parameters are used to with the SPI_open() call. Default values for
638  *  these parameters are set using SPI_Params_init().
639  *
640  *  @sa         SPI_Params_init()
641  */
642 typedef struct {
643     SPI_TransferMode transferMode;       /*!< Blocking or Callback mode */
644     uint32_t         transferTimeout;    /*!< Transfer timeout in system
645                                               ticks */
646     SPI_CallbackFxn  transferCallbackFxn;/*!< Callback function pointer */
647     SPI_Mode         mode;               /*!< Master or Slave mode */
648     /*! @brief SPI bit rate in Hz
649      *
650      *  Maximum bit rates supported by hardware:
651      *  Device Family | Slave Max (MHz)    | Master Max (MHz) |
652      *  ------------- | ------------------ | ---------------- |
653      *  MSP432P4      | 16 MHz             | 24 MHz           |
654      *  MSP432E4      | 10 MHz             | 60 MHz           |
655      *  CC13XX/CC26XX | 4  MHz             | 12 MHz           |
656      *  CC32XX        | 20 MHz             | 20 MHz           |
657      *
658      *  Please note that depending on the specific use case, the driver may not
659      *  support the hardware's maximum bit rate.
660      */
661     uint32_t         bitRate;
662     uint32_t         dataSize;           /*!< SPI data frame size in bits */
663     SPI_FrameFormat  frameFormat;        /*!< SPI frame format */
664     void            *custom;             /*!< Custom argument used by driver
665                                               implementation */
666 } SPI_Params;
667 
668 /*!
669  *  @brief      A function pointer to a driver specific implementation of
670  *              SPI_close().
671  */
672 typedef void (*SPI_CloseFxn) (SPI_Handle handle);
673 
674 /*!
675  *  @brief      A function pointer to a driver specific implementation of
676  *              SPI_control().
677  */
678 typedef int_fast16_t (*SPI_ControlFxn) (SPI_Handle handle, uint_fast16_t cmd,
679     void *arg);
680 
681 /*!
682  *  @brief      A function pointer to a driver specific implementation of
683  *              SPI_init().
684  */
685 typedef void (*SPI_InitFxn) (SPI_Handle handle);
686 
687 /*!
688  *  @brief      A function pointer to a driver specific implementation of
689  *              SPI_open().
690  */
691 typedef SPI_Handle (*SPI_OpenFxn) (SPI_Handle handle, SPI_Params *params);
692 
693 /*!
694  *  @brief      A function pointer to a driver specific implementation of
695  *              SPI_transfer().
696  */
697 typedef bool (*SPI_TransferFxn) (SPI_Handle handle,
698     SPI_Transaction *transaction);
699 
700 /*!
701  *  @brief      A function pointer to a driver specific implementation of
702  *              SPI_transferCancel().
703  */
704 typedef void (*SPI_TransferCancelFxn) (SPI_Handle handle);
705 
706 /*!
707  *  @brief      The definition of a SPI function table that contains the
708  *              required set of functions to control a specific SPI driver
709  *              implementation.
710  */
711 typedef struct {
712     /*! Function to close the specified peripheral */
713     SPI_CloseFxn          closeFxn;
714 
715     /*! Function to implementation specific control function */
716     SPI_ControlFxn        controlFxn;
717 
718     /*! Function to initialize the given data object */
719     SPI_InitFxn           initFxn;
720 
721     /*! Function to open the specified peripheral */
722     SPI_OpenFxn           openFxn;
723 
724     /*! Function to initiate a SPI data transfer */
725     SPI_TransferFxn       transferFxn;
726 
727     /*! Function to cancel SPI data transfer */
728     SPI_TransferCancelFxn transferCancelFxn;
729 } SPI_FxnTable;
730 
731 /*!
732  *  @brief SPI Global configuration
733  *
734  *  The #SPI_Config structure contains a set of pointers used to characterize
735  *  the SPI driver implementation.
736  *
737  *  This structure needs to be defined before calling SPI_init() and it must
738  *  not be changed thereafter.
739  *
740  *  @sa     SPI_init()
741  */
742 typedef struct SPI_Config_ {
743     /*! Pointer to a table of driver-specific implementations of SPI APIs */
744     SPI_FxnTable const *fxnTablePtr;
745 
746     /*! Pointer to a driver specific data object */
747     void               *object;
748 
749     /*! Pointer to a driver specific hardware attributes structure */
750     void         const *hwAttrs;
751 } SPI_Config;
752 
753 /*!
754  *  @brief  Function to close a SPI peripheral specified by the SPI handle
755  *
756  *  @pre    SPI_open() has to be called first.
757  *
758  *  @param  handle A #SPI_Handle returned from SPI_open()
759  *
760  *  @sa     SPI_open()
761  */
762 extern void SPI_close(SPI_Handle handle);
763 
764 /*!
765  *  @brief  Function performs implementation specific features on a given
766  *          #SPI_Handle.
767  *
768  *  Commands for SPI_control can originate from SPI.h or from implementation
769  *  specific SPI*.h (SPICC26XXDMA.h, SPIMSP432DMA.h, etc.. ) files.
770  *  While commands from SPI.h are API portable across driver implementations,
771  *  not all implementations may support all these commands.
772  *  Conversely, commands from driver implementation specific SPI*.h files add
773  *  unique driver capabilities but are not API portable across all SPI driver
774  *  implementations.
775  *
776  *  Commands supported by SPI.h follow a SPI_CMD_\<cmd\> naming
777  *  convention.<br>
778  *  Commands supported by SPI*.h follow a SPI*_CMD_\<cmd\> naming
779  *  convention.<br>
780  *  Each control command defines @b arg differently. The types of @b arg are
781  *  documented with each command.
782  *
783  *  See @ref SPI_CMD "SPI_control command codes" for command codes.
784  *
785  *  See @ref SPI_STATUS "SPI_control return status codes" for status codes.
786  *
787  *  @pre    SPI_open() has to be called first.
788  *
789  *  @param  handle      A #SPI_Handle returned from SPI_open()
790  *
791  *  @param  cmd         SPI.h or SPI*.h commands.
792  *
793  *  @param  controlArg  An optional R/W (read/write) command argument
794  *                      accompanied with cmd
795  *
796  *  @return Implementation specific return codes. Negative values indicate
797  *          unsuccessful operations.
798  *
799  *  @sa     SPI_open()
800  */
801 extern int_fast16_t SPI_control(SPI_Handle handle, uint_fast16_t cmd,
802     void *controlArg);
803 
804 /*!
805  *  @brief  This function initializes the SPI module.
806  *
807  *  @pre    The SPI_config[] array must exist and be persistent before this
808  *          function can be called. This function must also be called before
809  *          any other SPI driver APIs. This function call does not modify any
810  *          peripheral registers.
811  */
812 extern void SPI_init(void);
813 
814 /*!
815  *  @brief  This function opens a given SPI peripheral.
816  *
817  *  @pre    SPI controller has been initialized using SPI_init()
818  *
819  *  @param  index         Index of config to use in the *SPI_config* array
820  *
821  *  @param  params        Pointer to an parameter block, if NULL it will use
822  *                        default values. All the fields in this structure are
823  *                        RO (read-only).
824  *
825  *  @return A #SPI_Handle on success or a NULL on an error or if it has been
826  *          opened already.
827  *
828  *  @sa     SPI_init()
829  *  @sa     SPI_close()
830  */
831 extern SPI_Handle SPI_open(uint_least8_t index, SPI_Params *params);
832 
833 /*!
834  *  @brief  Function to initialize the #SPI_Params struct to its defaults
835  *
836  *  @param  params      An pointer to #SPI_Params structure for
837  *                      initialization
838  *
839  *  Defaults values are:
840  *  * SPI_Params.transferMode        = #SPI_MODE_BLOCKING
841  *  * SPI_Params.transferTimeout     = #SPI_WAIT_FOREVER
842  *  * SPI_Params.transferCallbackFxn = NULL
843  *  * SPI_Params.mode                = #SPI_MASTER
844  *  * SPI_Params.bitRate             = 1000000 (Hz)
845  *  * SPI_Params.dataSize            = 8 (bits)
846  *  * SPI_Params.frameFormat         = #SPI_POL0_PHA0
847  */
848 extern void SPI_Params_init(SPI_Params *params);
849 
850 /*!
851  *  @brief  Function to perform SPI transactions
852  *
853  *  If the SPI is in #SPI_MASTER mode, it will immediately start the
854  *  transaction. If the SPI is in #SPI_SLAVE mode, it prepares the driver for
855  *  a transaction with a SPI master device. The device will then wait until
856  *  the master begins the transfer.
857  *
858  *  In #SPI_MODE_BLOCKING, #SPI_transfer() will block task execution until the
859  *  transaction has completed or a timeout has occurred.
860  *
861  *  In #SPI_MODE_CALLBACK, %SPI_transfer() does not block task execution, but
862  *  calls a #SPI_CallbackFxn once the transfer has finished. This makes
863  *  %SPI_tranfer() safe to be used within a Task, software or hardware
864  *  interrupt context. If queued transactions are supported SPI_Transfer may
865  *  be called multiple times to queue multiple transactions. If the driver does
866  *  not support this functionality additional calls will return false. Refer to
867  *  device specific SPI driver documentation for support information.
868  *
869  *  From calling #SPI_transfer() until transfer completion, the #SPI_Transaction
870  *  structure must stay persistent and must not be altered by application code.
871  *  It is also forbidden to modify the content of the #SPI_Transaction.txBuf
872  *  during a transaction, even though the physical transfer might not have
873  *  started yet. Doing this can result in data corruption. This is especially
874  *  important for slave operations where SPI_transfer() might be called a long
875  *  time before the actual data transfer begins.
876  *
877  *  @param  handle      A #SPI_Handle
878  *
879  *  @param  transaction A pointer to a #SPI_Transaction. All of the fields within
880  *                      transaction except #SPI_Transaction.count and
881  *                      #SPI_Transaction.status are WO (write-only) unless
882  *                      otherwise noted in the driver implementations. If a
883  *                      transaction timeout has occurred, #SPI_Transaction.count
884  *                      will contain the number of frames that were transferred.
885  *                      Neither is it allowed to modify the transaction object nor
886  *                      the content of #SPI_Transaction.txBuf until the transfer
887  *                      has completed.
888  *
889  *  @return @p true if started successfully; else @p false
890  *
891  *  @sa     #SPI_open
892  *  @sa     #SPI_transferCancel
893  */
894 extern bool SPI_transfer(SPI_Handle handle, SPI_Transaction *transaction);
895 
896 /*!
897  *  @brief  Function to cancel SPI transactions
898  *
899  *  In #SPI_MODE_BLOCKING, SPI_transferCancel has no effect.
900  *
901  *  In #SPI_MODE_CALLBACK, SPI_transferCancel() will stop an SPI transfer if
902  *  if one is in progress.
903  *  If a transaction was in progress, its callback function will be called
904  *  in context from which this API is called from. The #SPI_CallbackFxn
905  *  function can determine if the transaction was successful or not by reading
906  *  the #SPI_Status status value in the #SPI_Transaction structure.
907  *
908  *  @pre    SPI_init(), SPI_open(), SPI_transfer() are called
909  *
910  *  @param  handle      A #SPI_Handle
911  *
912  *  @sa     #SPI_open
913  *  @sa     #SPI_transfer
914  */
915 extern void SPI_transferCancel(SPI_Handle handle);
916 
917 #ifdef __cplusplus
918 }
919 #endif
920 
921 #endif /* ti_drivers_SPI__include */
922