blob: 9a2bef4ff926c689853c727d0b8942611c93ff80 [file] [log] [blame]
/*
* Copyright (c) 2015-2016, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*!*****************************************************************************
* @file SPI.h
*
* @brief SPI driver interface
*
* The SPI driver interface provides device independent APIs, data types,
* and macros. The SPI header file should be included in an application as
* follows:
* @code
* #include <ti/drivers/SPI.h>
* @endcode
*
* # Overview #
* The Serial Peripheral Interface (SPI) driver is a generic, full-duplex
* driver that transmits and receives data on a SPI bus. SPI is sometimes
* called SSI (Synchronous Serial Interface).
* The SPI protocol defines the format of a data transfer over the SPI bus,
* but it leaves flow control, data formatting, and handshaking mechanisms
* to higher-level software layers.
*
* The APIs in this driver serve as an interface to a typical RTOS
* application. Its purpose is to redirect the SPI APIs to specific
* driver implementations which are specified using a pointer to a
* #SPI_FxnTable. The specific SPI implementations are responsible for
* creating all the RTOS specific primitives to allow for thread-safe
* operation.
*
* The SPI driver operates on some key definitions and assumptions:
* - The driver operates transparently from the chip select. Some SPI
* controllers feature a hardware chip select to assert SPI slave
* peripherals. See the specific peripheral implementations on chip
* select requirements.
*
* - The SPI protocol does not account for a built-in handshaking mechanism
* and neither does this SPI driver. Therefore, when operating in
* ::SPI_SLAVE mode, the application must provide such a mechanism to
* ensure that the SPI slave is ready for the SPI master. The SPI slave
* must call SPI_transfer() *before* the SPI master starts transmitting.
* Some example application mechanisms could include:
* - Timed delays on the SPI master to guarantee the SPI slave is ready
* for a SPI transaction.
* - A form of GPIO flow control from the slave to the SPI master to notify
* the master when ready.
*
* # Usage #
*
* To use the SPI driver to send data over the SPI bus, the application
* calls the following APIs:
* - SPI_init(): Initialize the SPI driver.
* - SPI_Params_init(): Initialize a #SPI_Params structure with default
* vaules. Then change the parameters from non-default values as
* needed.
* - SPI_open(): Open an instance of the SPI driver, passing the
* initialized parameters, or NULL, and an index (described later).
* - SPI_transfer(): Transmit/receive data. This function takes a
* #SPI_Transaction argument that specifies buffers for data to be
* transmitted/received.
* - SPI_close(): De-initialize the SPI instance.
*
* The following code example opens a SPI instance as a master SPI,
* and issues a transaction.
*
* @code
* SPI_Handle spi;
* SPI_Params spiParams;
* SPI_Transaction spiTransaction;
* uint8_t transmitBuffer[MSGSIZE];
* uint8_t receiveBuffer[MSGSIZE];
* bool transferOK;
*
* SPI_init(); // Initialize the SPI driver
*
* SPI_Params_init(&spiParams); // Initialize SPI parameters
* spiParams.dataSize = 8; // 8-bit data size
*
* spi = SPI_open(Board_SPI0, &spiParams);
* if (spi == NULL) {
* while (1); // SPI_open() failed
* }
*
* // Fill in transmitBuffer
*
* spiTransaction.count = MSGSIZE;
* spiTransaction.txBuf = transmitBuffer;
* spiTransaction.rxBuf = receiveBuffer;
*
* transferOK = SPI_transfer(spi, &spiTransaction);
* if (!transferOK) {
* // Error in SPI or transfer already in progress.
* }
* @endcode
*
* More details on usage are provided in the following subsections.
*
* ### SPI Driver Configuration #
*
* In order to use the SPI APIs, the application is required
* to provide device-specific SPI configuration in the Board.c file.
* The SPI driver interface defines a configuration data structure:
*
* @code
* typedef struct SPI_Config_ {
* SPI_FxnTable const *fxnTablePtr;
* void *object;
* void const *hwAttrs;
* } SPI_Config;
* @endcode
*
* The application must declare an array of SPI_Config elements, named
* SPI_config[]. Each element of SPI_config[] must be populated with
* pointers to a device specific SPI driver implementation's function
* table, driver object, and hardware attributes. The hardware attributes
* define properties such as the SPI peripheral's base address, and
* the MOSI and MISO pins. Each element in SPI_config[] corresponds to
* a SPI instance, and none of the elements should have NULL pointers.
* There is no correlation between the index and the
* peripheral designation (such as SPI0 or SPI1). For example, it is
* possible to use SPI_config[0] for SPI1.
*
* Because the SPI configuration is very device dependent, you will need to
* check the doxygen for the device specific SPI implementation. There you
* will find a description of the SPI hardware attributes. Please also
* refer to the Board.c file of any of your examples to see the SPI
* configuration.
*
* ### Initializing the SPI Driver #
*
* SPI_init() must be called before any other SPI APIs. This function
* iterates through the elements of the SPI_config[] array, calling
* the element's device implementation SPI initialization function.
*
* ### SPI Parameters
*
* The #SPI_Params structure is passed to the SPI_open() call. If NULL
* is passed for the parameters, SPI_open() uses default parameters.
* A #SPI_Params structure is initialized with default values by passing
* it to SPI_Params_init().
* Some of the SPI parameters are described below. To see brief descriptions
* of all the parameters, see #SPI_Params.
*
* #### SPI Mode
* The SPI driver operates in both SPI master and SPI slave modes.
* Logically, the implementation is identical, however the difference
* between these two modes is driven by hardware. The default mode is
* ::SPI_MASTER, but can be set to slave mode by setting ::SPI_Params.mode
* to ::SPI_SLAVE in the parameters passed to SPI_open(). See
* <a href="#Master_Slave_Modes"> Master/Slave Modes</a> for further
* details.
*
* #### SPI Transfer Mode
* The SPI driver supports two transfer modes of operation: blocking and
* callback. The transfer mode is determined by the transferMode parameter
* in the SPI_Params data structure. The SPI driver
* defaults to blocking mode, if the application does not set it.
* Once a SPI driver is opened, the only way to change the operation mode
* is to close and re-open the SPI instance with the new transfer mode.
*
* In blocking mode, a task's code execution is blocked until a SPI
* transaction has completed. This ensures that only one SPI transaction
* operates at a given time. Other tasks requesting SPI transactions while
* a transaction is currently taking place are also placed into a blocked
* state. SPI transactions are executed in the order in which they were
* received. In blocking mode, you cannot perform SPI transactions
* in the context of a software or hardware ISR.
*
* In callback mode, a SPI transaction functions asynchronously, which
* means that it does not block code execution. After a SPI transaction
* has been completed, the SPI driver calls a user-provided hook function.
* Callback mode is supported in the execution context of tasks and
* hardware interrupt routines. However, if a SPI transaction is
* requested while a transaction is taking place, SPI_transfer() returns
* FALSE.
*
*
* #### SPI Frame Formats and Data Size
* The SPI driver can configure the device's SPI peripheral with various
* SPI format options: SPI (with various polarity and phase settings),
* TI, and Micro-wire. The frame format is set with SPI_Params.frameFormat.
* The smallest single unit of data transmitted onto the SPI bus is called
* a SPI frame and is of size SPI_Params.dataSize. A series of SPI frames
* transmitted/received on a SPI bus is known as a SPI transaction.
*
* ### Opening the SPI Driver #
* After initializing the SPI driver by calling SPI_init(), the application
* can open a SPI instance by calling SPI_open(). This function
* takes an index into the SPI_config[] array, and a SPI parameters data
* structure. The SPI instance is specified by the index of the SPI in
* SPI_config[]. Only one SPI index can be used at a time;
* calling SPI_open() a second time with the same index previosly
* passed to SPI_open() will result in an error. You can,
* though, re-use the index if the instance is closed via SPI_close().
*
* If no SPI_Params structure is passed to SPI_open(), default values are
* used. If the open call is successful, it returns a non-NULL value.
*
* Example opening a SPI driver instance in blocking mode:
* @code
* SPI_Handle spi;
* SPI_Params spiParams;
*
* SPI_Params_init(&spiParams);
* spiParams.transferMode = SPI_MODE_BLOCKING;
* spi = SPI_open(Board_SPI0, &spiParams);
*
* if (spi == NULL) {
* // Error opening SPI
* }
* @endcode
*
* Example opening a SPI driver instance in callback mode:
* @code
* SPI_Handle spi;
* SPI_Params spiParams;
*
* SPI_Params_init(&spiParams);
* spiParams.transferMode = SPI_MODE_CALLBACK;
* spiParams.transferCallbackFxn = UserCallbackFxn;
*
* spi = SPI_open(Board_SPI0, &spiParams);
* if (spi == NULL) {
* // Error opening SPI
* }
* @endcode
*
*
* ### SPI Transactions #
*
* A SPI transaction consists of a series of SPI frames
* transmitted/received on a SPI bus. A SPI transaction is performed
* using SPI_transfer(). SPI_transfer() accepts a pointer to a
* #SPI_Transaction structure that dictates the quantity of data to be
* sent and received.
* The SPI_Transaction.txBuf and SPI_Transaction.rxBuf are both pointers
* to data buffers. If txBuf is NULL, the driver sends SPI frames with all
* data bits set to 0. If rxBuf is NULL, the driver discards all SPI frames
* received.
* A SPI_transfer() of a SPI transaction is performed atomically.
*
* When the SPI is opened, the dataSize value determines the element types
* of txBuf and rxBuf. If the dataSize is from 4 to 8 bits, the driver
* assumes the data buffers are of type uint8_t (unsigned char). If the
* dataSize is larger than 8 bits, the driver assumes the data buffers are
* of type uint16_t (unsigned short).
* The optional SPI_Transaction.arg variable can only be used when the
* SPI driver has been opened in callback mode. This variable is used to
* pass a user-defined value into the user-defined callback function.
*
* SPI_transfer() always performs full-duplex SPI transactions. This means
* the SPI simultaneously receives data as it transmits data. The application
* is responsible for formatting the data to be transmitted as well as
* determining whether the data received is meaningful.
* Specifics about SPI frame formatting and data sizes are provided in
* device-specific data sheets and technical reference manuals.
*
* The following code snippets perform SPI transactions.
*
* Example transferring 6-bit SPI frames. The transmit and receive
* buffers are of type uint8_t.
* @code
* SPI_Transaction spiTransaction;
* uint8_t transmitBuffer[BUFSIZE];
* uint8_t receiveBuffer[BUFSIZE];
* bool transferOK;
*
* SPI_Params_init(&spiParams);
* spiParams.dataSize = 6;
* spi = SPI_open(Board_SPI0, &spiParams);
* ...
* spiTransaction.count = someIntegerValue;
* spiTransaction.txBuf = transmitBuffer;
* spiTransaction.rxBuf = receiveBuffer;
*
* ret = SPI_transfer(spi, &spiTransaction);
* if (!transferOK) {
* // Unsuccessful SPI transfer
* }
* @endcode
*
* Example transferring 12-bit SPI frames. The transmit and receive
* buffers are of type uint16_t.
* @code
* SPI_Transaction spiTransaction;
* uint16_t transmitBuffer[BUFSIZE];
* uint16_t receiveBuffer[BUFSIZE];
* bool transferOK;
*
* SPI_Params_init(&spiParams);
* spiParams.dataSize = 12;
* spi = SPI_open(Board_SPI0, &spiParams);
* ...
* spiTransaction.count = someIntegerValue;
* spiTransaction.txBuf = transmitBuffer;
* spiTransaction.rxBuf = receiveBuffer;
*
* ret = SPI_transfer(spi, &spiTransaction);
* if (!transferOK) {
* // Unsuccessful SPI transfer
* }
* @endcode
*
* ### Canceling a transaction #
* SPI_transferCancel() is used to cancel a SPI transaction when the driver is
* used in ::SPI_MODE_CALLBACK mode.
*
* Calling this API while no transfer is in progress has no effect. If a
* transfer is in progress, it is canceled and the callback functions is
* called.
* The ::SPI_Status status field in the ::SPI_Transaction structure
* can be examined within the callback to determine if the transaction
* succeeded.
*
* Example:
* @code
* SPI_transferCancel(spi);
* @endcode
*
*
* <h2><a NAME="Master_Slave_Modes">Master/Slave Modes</a></h2>
* This SPI driver functions in both SPI master and SPI slave modes.
* Logically, the implementation is identical, however the difference between
* these two modes is driven by hardware. As a SPI master, the peripheral is
* in control of the clock signal and therefore will commence communications
* to the SPI slave immediately. As a SPI slave, the SPI driver prepares
* the peripheral to transmit and receive data in a way such that the
* peripheral is ready to transfer data when the SPI master initiates a
* transaction.
*
* ### Asserting on Chip Select
* The SPI protocol requires that the SPI master asserts a SPI slave's chip
* select pin prior to starting a SPI transaction. While this protocol is
* generally followed, various types of SPI peripherals have different
* timing requirements as to when and for how long the chip select pin must
* remain asserted for a SPI transaction.
*
* Commonly, the SPI master uses a hardware chip select to assert and
* de-assert the SPI slave for every data frame. In other cases, a SPI slave
* imposes the requirement of asserting the chip select over several SPI
* data frames. This is generally accomplished by using a regular,
* general-purpose output pin. Due to the complexity of such SPI peripheral
* implementations, this SPI driver has been designed to operate
* transparently to the SPI chip select. When the hardware chip
* select is used, the peripheral automatically selects/enables the
* peripheral. When using a software chip select, the application needs to
* handle the proper chip select and pin configuration.
*
* - _Hardware chip select_ No additional action by the application is
* required.
* - _Software chip select_ The application needs to handle the chip select
* assertion and de-assertion for the proper SPI peripheral.
*
* # Implementation #
*
* This module serves as the main interface for RTOS applications. Its
* purpose is to redirect the module's APIs to specific peripheral
* implementations which are specified using a pointer to a #SPI_FxnTable.
*
* The SPI driver interface module is joined (at link time) to an
* array of SPI_Config data structures named *SPI_config*.
* The SPI_config array is implemented in the application with each entry
* being an instance of a SPI peripheral. Each entry in *SPI_config* contains
* the following:
* - (SPI_FxnTable *) A pointer to a set of functions that implement a
* SPI peripheral.
* - (void *) A data object that is associated with the SPI_FxnTable.
* - (void *) The hardware attributes that are associated with the
* SPI_FxnTable.
*
*******************************************************************************
*/
#ifndef ti_drivers_SPI__include
#define ti_drivers_SPI__include
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/**
* @defgroup SPI_CONTROL SPI_control command and status codes
* These SPI macros are reservations for SPI.h
* @{
*/
/*!
* Common SPI_control command code reservation offset.
* SPI driver implementations should offset command codes with SPI_CMD_RESERVED
* growing positively
*
* Example implementation specific command codes:
* @code
* #define SPIXYZ_CMD_COMMAND0 SPI_CMD_RESERVED + 0
* #define SPIXYZ_CMD_COMMAND1 SPI_CMD_RESERVED + 1
* @endcode
*/
#define SPI_CMD_RESERVED (32)
/*!
* Common SPI_control status code reservation offset.
* SPI driver implementations should offset status codes with
* SPI_STATUS_RESERVED growing negatively.
*
* Example implementation specific status codes:
* @code
* #define SPIXYZ_STATUS_ERROR0 SPI_STATUS_RESERVED - 0
* #define SPIXYZ_STATUS_ERROR1 SPI_STATUS_RESERVED - 1
* #define SPIXYZ_STATUS_ERROR2 SPI_STATUS_RESERVED - 2
* @endcode
*/
#define SPI_STATUS_RESERVED (-32)
/**
* @defgroup SPI_STATUS Status Codes
* SPI_STATUS_* macros are general status codes returned by SPI_control()
* @{
* @ingroup SPI_CONTROL
*/
/*!
* @brief Successful status code returned by SPI_control().
*
* SPI_control() returns SPI_STATUS_SUCCESS if the control code was executed
* successfully.
*/
#define SPI_STATUS_SUCCESS (0)
/*!
* @brief Generic error status code returned by SPI_control().
*
* SPI_control() returns SPI_STATUS_ERROR if the control code was not executed
* successfully.
*/
#define SPI_STATUS_ERROR (-1)
/*!
* @brief An error status code returned by SPI_control() for undefined
* command codes.
*
* SPI_control() returns SPI_STATUS_UNDEFINEDCMD if the control code is not
* recognized by the driver implementation.
*/
#define SPI_STATUS_UNDEFINEDCMD (-2)
/** @}*/
/**
* @defgroup SPI_CMD Command Codes
* SPI_CMD_* macros are general command codes for SPI_control(). Not all SPI
* driver implementations support these command codes.
* @{
* @ingroup SPI_CONTROL
*/
/* Add SPI_CMD_<commands> here */
/** @}*/
/** @}*/
/*!
* @brief Wait forever define
*/
#define SPI_WAIT_FOREVER (~(0U))
/*!
* @brief A handle that is returned from a SPI_open() call.
*/
typedef struct SPI_Config_ *SPI_Handle;
/*!
* @brief Status codes that are set by the SPI driver.
*/
typedef enum SPI_Status_ {
SPI_TRANSFER_COMPLETED = 0,
SPI_TRANSFER_STARTED,
SPI_TRANSFER_CANCELED,
SPI_TRANSFER_FAILED,
SPI_TRANSFER_CSN_DEASSERT
} SPI_Status;
/*!
* @brief
* A ::SPI_Transaction data structure is used with SPI_transfer(). It indicates
* how many ::SPI_FrameFormat frames are sent and received from the buffers
* pointed to txBuf and rxBuf.
* The arg variable is an user-definable argument which gets passed to the
* ::SPI_CallbackFxn when the SPI driver is in ::SPI_MODE_CALLBACK.
*/
typedef struct SPI_Transaction_ {
/* User input (write-only) fields */
size_t count; /*!< Number of frames for this transaction */
void *txBuf; /*!< void * to a buffer with data to be transmitted */
void *rxBuf; /*!< void * to a buffer to receive data */
void *arg; /*!< Argument to be passed to the callback function */
/* User output (read-only) fields */
SPI_Status status; /*!< Status code set by SPI_transfer */
} SPI_Transaction;
/*!
* @brief The definition of a callback function used by the SPI driver
* when used in ::SPI_MODE_CALLBACK
*
* @param SPI_Handle SPI_Handle
* @param SPI_Transaction* SPI_Transaction*
*/
typedef void (*SPI_CallbackFxn) (SPI_Handle handle,
SPI_Transaction *transaction);
/*!
* @brief
* Definitions for various SPI modes of operation.
*/
typedef enum SPI_Mode_ {
SPI_MASTER = 0, /*!< SPI in master mode */
SPI_SLAVE = 1 /*!< SPI in slave mode */
} SPI_Mode;
/*!
* @brief
* Definitions for various SPI data frame formats.
*/
typedef enum SPI_FrameFormat_ {
SPI_POL0_PHA0 = 0, /*!< SPI mode Polarity 0 Phase 0 */
SPI_POL0_PHA1 = 1, /*!< SPI mode Polarity 0 Phase 1 */
SPI_POL1_PHA0 = 2, /*!< SPI mode Polarity 1 Phase 0 */
SPI_POL1_PHA1 = 3, /*!< SPI mode Polarity 1 Phase 1 */
SPI_TI = 4, /*!< TI mode */
SPI_MW = 5 /*!< Micro-wire mode */
} SPI_FrameFormat;
/*!
* @brief
*
* SPI transfer mode determines the whether the SPI controller operates
* synchronously or asynchronously. In ::SPI_MODE_BLOCKING mode SPI_transfer()
* blocks code execution until the SPI transaction has completed. In
* ::SPI_MODE_CALLBACK SPI_transfer() does not block code execution and instead
* calls a ::SPI_CallbackFxn callback function when the transaction has
* completed.
*/
typedef enum SPI_TransferMode_ {
/*!
* SPI_transfer() blocks execution. This mode can only be used when called
* within a Task context
*/
SPI_MODE_BLOCKING,
/*!
* SPI_transfer() does not block code execution and will call a
* ::SPI_CallbackFxn. This mode can be used in a Task, Swi, or Hwi context.
*/
SPI_MODE_CALLBACK
} SPI_TransferMode;
/*!
* @brief SPI Parameters
*
* SPI Parameters are used to with the SPI_open() call. Default values for
* these parameters are set using SPI_Params_init().
*
* @sa SPI_Params_init()
*/
typedef struct SPI_Params_ {
SPI_TransferMode transferMode; /*!< Blocking or Callback mode */
uint32_t transferTimeout; /*!< Transfer timeout in system
ticks (Not supported with all
implementations */
SPI_CallbackFxn transferCallbackFxn;/*!< Callback function pointer */
SPI_Mode mode; /*!< Master or Slave mode */
uint32_t bitRate; /*!< SPI bit rate in Hz */
uint32_t dataSize; /*!< SPI data frame size in bits */
SPI_FrameFormat frameFormat; /*!< SPI frame format */
void *custom; /*!< Custom argument used by driver
implementation */
} SPI_Params;
/*!
* @brief A function pointer to a driver specific implementation of
* SPI_close().
*/
typedef void (*SPI_CloseFxn) (SPI_Handle handle);
/*!
* @brief A function pointer to a driver specific implementation of
* SPI_control().
*/
typedef int_fast16_t (*SPI_ControlFxn) (SPI_Handle handle, uint_fast16_t cmd,
void *arg);
/*!
* @brief A function pointer to a driver specific implementation of
* SPI_init().
*/
typedef void (*SPI_InitFxn) (SPI_Handle handle);
/*!
* @brief A function pointer to a driver specific implementation of
* SPI_open().
*/
typedef SPI_Handle (*SPI_OpenFxn) (SPI_Handle handle, SPI_Params *params);
/*!
* @brief A function pointer to a driver specific implementation of
* SPI_transfer().
*/
typedef bool (*SPI_TransferFxn) (SPI_Handle handle,
SPI_Transaction *transaction);
/*!
* @brief A function pointer to a driver specific implementation of
* SPI_transferCancel().
*/
typedef void (*SPI_TransferCancelFxn) (SPI_Handle handle);
/*!
* @brief The definition of a SPI function table that contains the
* required set of functions to control a specific SPI driver
* implementation.
*/
typedef struct SPI_FxnTable_ {
/*! Function to close the specified peripheral */
SPI_CloseFxn closeFxn;
/*! Function to implementation specific control function */
SPI_ControlFxn controlFxn;
/*! Function to initialize the given data object */
SPI_InitFxn initFxn;
/*! Function to open the specified peripheral */
SPI_OpenFxn openFxn;
/*! Function to initiate a SPI data transfer */
SPI_TransferFxn transferFxn;
/*! Function to cancel SPI data transfer */
SPI_TransferCancelFxn transferCancelFxn;
} SPI_FxnTable;
/*!
* @brief SPI Global configuration
*
* The SPI_Config structure contains a set of pointers used to characterize
* the SPI driver implementation.
*
* This structure needs to be defined before calling SPI_init() and it must
* not be changed thereafter.
*
* @sa SPI_init()
*/
typedef struct SPI_Config_ {
/*! Pointer to a table of driver-specific implementations of SPI APIs */
SPI_FxnTable const *fxnTablePtr;
/*! Pointer to a driver specific data object */
void *object;
/*! Pointer to a driver specific hardware attributes structure */
void const *hwAttrs;
} SPI_Config;
/*!
* @brief Function to close a SPI peripheral specified by the SPI handle
*
* @pre SPI_open() has to be called first.
*
* @param handle A SPI handle returned from SPI_open()
*
* @sa SPI_open()
*/
extern void SPI_close(SPI_Handle handle);
/*!
* @brief Function performs implementation specific features on a given
* SPI_Handle.
*
* Commands for SPI_control can originate from SPI.h or from implementation
* specific SPI*.h (_SPICC26XX.h_, _SPIMSP432.h_, etc.. ) files.
* While commands from SPI.h are API portable across driver implementations,
* not all implementations may support all these commands.
* Conversely, commands from driver implementation specific SPI*.h files add
* unique driver capabilities but are not API portable across all SPI driver
* implementations.
*
* Commands supported by SPI.h follow a SPI_CMD_\<cmd\> naming
* convention.<br>
* Commands supported by SPI*.h follow a SPI*_CMD_\<cmd\> naming
* convention.<br>
* Each control command defines @b arg differently. The types of @b arg are
* documented with each command.
*
* See @ref SPI_CMD "SPI_control command codes" for command codes.
*
* See @ref SPI_STATUS "SPI_control return status codes" for status codes.
*
* @pre SPI_open() has to be called first.
*
* @param handle A SPI handle returned from SPI_open()
*
* @param cmd SPI.h or SPI*.h commands.
*
* @param controlArg An optional R/W (read/write) command argument
* accompanied with cmd
*
* @return Implementation specific return codes. Negative values indicate
* unsuccessful operations.
*
* @sa SPI_open()
*/
extern int_fast16_t SPI_control(SPI_Handle handle, uint_fast16_t cmd,
void *controlArg);
/*!
* @brief This function initializes the SPI module.
*
* @pre The SPI_config structure must exist and be persistent before this
* function can be called. This function must also be called before
* any other SPI driver APIs. This function call does not modify any
* peripheral registers.
*/
extern void SPI_init(void);
/*!
* @brief This function opens a given SPI peripheral.
*
* @pre SPI controller has been initialized using SPI_init()
*
* @param index Logical peripheral number for the SPI indexed into
* the SPI_config table
*
* @param params Pointer to an parameter block, if NULL it will use
* default values. All the fields in this structure are
* RO (read-only).
*
* @return A SPI_Handle on success or a NULL on an error or if it has been
* opened already.
*
* @sa SPI_init()
* @sa SPI_close()
*/
extern SPI_Handle SPI_open(uint_least8_t index, SPI_Params *params);
/*!
* @brief Function to initialize the SPI_Params struct to its defaults
*
* @param params An pointer to SPI_Params structure for
* initialization
*
* Defaults values are:
* transferMode = SPI_MODE_BLOCKING
* transferTimeout = SPI_WAIT_FOREVER
* transferCallbackFxn = NULL
* mode = SPI_MASTER
* bitRate = 1000000 (Hz)
* dataSize = 8 (bits)
* frameFormat = SPI_POL0_PHA0
*/
extern void SPI_Params_init(SPI_Params *params);
/*!
* @brief Function to perform SPI transactions
*
* If the SPI is in ::SPI_MASTER mode, it will immediately start the
* transaction. If the SPI is in ::SPI_SLAVE mode, it prepares itself for a
* transaction with a SPI master.
*
* In ::SPI_MODE_BLOCKING, SPI_transfer will block task execution until the
* transaction has completed.
*
* In ::SPI_MODE_CALLBACK, SPI_transfer() does not block task execution and
* calls a ::SPI_CallbackFxn. This makes the SPI_tranfer() safe to be used
* within a Task, Swi, or Hwi context. The ::SPI_Transaction structure must
* stay persistent until the SPI_transfer function has completed!
*
* @param handle A SPI_Handle
*
* @param transaction A pointer to a SPI_Transaction. All of the fields within
* transaction except SPI_Transaction.count and
* SPI_Transaction.status are WO (write-only) unless
* otherwise noted in the driver implementations. If a
* transaction timeout has occurred, SPI_Transaction.count
* will contain the number of frames that were transferred.
*
* @return true if started successfully; else false
*
* @sa SPI_open
* @sa SPI_transferCancel
*/
extern bool SPI_transfer(SPI_Handle handle, SPI_Transaction *transaction);
/*!
* @brief Function to cancel SPI transactions
*
* In ::SPI_MODE_BLOCKING, SPI_transferCancel has no effect.
*
* In ::SPI_MODE_CALLBACK, SPI_transferCancel() will stop an SPI transfer if
* if one is in progress.
* If a transaction was in progress, its callback function will be called
* in context from which this API is called from. The ::SPI_CallbackFxn
* function can determine if the transaction was successful or not by reading
* the ::SPI_Status status value in the ::SPI_Transaction structure.
*
* @param handle A SPI_Handle
*
* @sa SPI_open
* @sa SPI_transfer
*/
extern void SPI_transferCancel(SPI_Handle handle);
#ifdef __cplusplus
}
#endif
#endif /* ti_drivers_SPI__include */