blob: cdceb1c1af5d179cdd430062665f3e1d99e4e85c [file] [log] [blame]
/***************************************************************************//**
* \file cy_scb_spi.h
* \version 2.20
*
* Provides SPI API declarations of the SCB driver.
*
********************************************************************************
* \copyright
* Copyright 2016-2018, Cypress Semiconductor Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
/**
* \addtogroup group_scb_spi
* \{
* Driver API for SPI Bus Peripheral.
*
* Three different SPI protocols or modes are supported:
* * The original SPI protocol as defined by Motorola.
* * TI: Uses a short pulse on "spi_select" to indicate a start of transaction.
* * National Semiconductor (Microwire): Transmissions and Receptions occur
* separately.
* In addition to the standard 8-bit word length, the component supports a
* configurable 4- to 16-bit data width for communicating at non-standard SPI
* data widths.
*
* \section group_scb_spi_configuration Configuration Considerations
* The SPI driver configuration can be divided to number of sequential
* steps listed below:
* * \ref group_scb_spi_config
* * \ref group_scb_spi_pins
* * \ref group_scb_spi_clock
* * \ref group_scb_spi_data_rate
* * \ref group_scb_spi_intr
* * \ref group_scb_spi_enable
*
* \note
* The SPI driver is built on top of the SCB hardware block. The SCB1 instance is
* used as an example for all code snippets. Modify the code to match your
* design.
*
* \subsection group_scb_spi_config Configure SPI
* To set up the SPI slave driver, provide the configuration parameters in the
* \ref cy_stc_scb_spi_config_t structure. For example: provide spiMode,
* subMode, sclkMode, oversample, rxDataWidth, and txDataWidth. The other
* parameters are optional for operation. To initialize the driver, call
* \ref Cy_SCB_SPI_Init function providing a pointer to the filled
* \ref cy_stc_scb_spi_config_t structure and allocated \ref cy_stc_scb_spi_context_t.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_CFG
*
* \subsection group_scb_spi_pins Assign and Configure Pins
* Only dedicated SCB pins can be used for SPI operation. The HSIOM
* register must be configured to connect block to the pins. Also the SPI output
* pins must be configured in Strong Drive mode and SPI input pins in
* Digital High-Z:
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_CFG_PINS
*
* \note
* The SCB stops driving pins when it is disabled or enters low power mode (except
* Alternate Active or Sleep). To keep the pins' states, they should be reconfigured or
* be frozen.
*
* \subsection group_scb_spi_clock Assign Clock Divider
* The clock source must be connected to the SCB block to oversample input and
* output signals. You must use one of the 8-bit or 16-bit dividers <em><b>(the
* source clock of this divider must be Clk_Peri)</b></em>. Use the
* \ref group_sysclk driver API to do that.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_CFG_ASSIGN_CLOCK
*
* \subsection group_scb_spi_data_rate Configure Data Rate
* To get the SPI slave to operate with the desired data rate, the source clock must be
* fast enough to provide sufficient oversampling. Therefore, the clock divider
* must be configured to provide desired clock frequency. Use the
* \ref group_sysclk driver API to do that.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_CFG_DATA_RATE_SLAVE
*
* To get the SPI master to operate with the desired data rate, the source clock frequency
* and the SCLK (SPI clock) period must be configured. Use the
* \ref group_sysclk driver API to configure source clock frequency. Set the
* <em><b>oversample parameter in configuration structure</b></em> to define number of SCB
* clocks in one SCLK period. When this value is even, the first and second phases
* of the SCLK period are the same. Otherwise, the first phase is one SCB clock
* cycle longer than the second phase. The level of the first phase of the clock
* period depends on CPOL settings: 0 - low level and 1 - high level.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_CFG_DATA_RATE_MASTER
*
* Refer to the technical reference manual (TRM) section SPI sub-section
* Oversampling and Bit Rate to get information about how to configure SPI to run with
* desired data rate.
*
* \subsection group_scb_spi_intr Configure Interrupt
* The interrupt is optional for the SPI operation. To configure the interrupt,
* the \ref Cy_SCB_SPI_Interrupt function must be called in the interrupt
* handler for the selected SCB instance. Also, this interrupt must be enabled
* in the NVIC.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_INTR_A
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_INTR_B
*
* \subsection group_scb_spi_enable Enable SPI
* Finally, enable the SPI operation calling \ref Cy_SCB_SPI_Enable.
* For the slave, this means that SPI device starts respond to the transfers.
* For the master, it is ready to execute transfers.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_ENABLE
*
* \section group_scb_spi_use_cases Common Use Cases
* The SPI API is the same for the master and slave mode operation and
* is divided into two categories: \ref group_scb_spi_low_level_functions
* and \ref group_scb_spi_high_level_functions. \n
* <em>Do not mix <b>High-Level</b> and <b>Low-Level</b> API because a Low-Level
* API can adversely affect the operation of a High-Level API.</em>
*
* \subsection group_scb_spi_ll Low-Level API
* The \ref group_scb_spi_low_level_functions API allows
* interacting directly with the hardware and do not use interrupt.
* These functions do not require context for operation. Thus, NULL can be
* passed in \ref Cy_SCB_SPI_Init and \ref Cy_SCB_SPI_Disable instead of
* a pointer to the context structure.
*
* * To write data into the TX FIFO, use one of the provided functions:
* \ref Cy_SCB_SPI_Write, \ref Cy_SCB_SPI_WriteArray or
* \ref Cy_SCB_SPI_WriteArrayBlocking.
* Note that in the master mode, putting data into the TX FIFO starts a
* transfer. Due to the SPI nature, the received data is put into the RX FIFO.
*
* * To read data from the RX FIFO, use one of the provided functions:
* \ref Cy_SCB_SPI_Read or \ref Cy_SCB_SPI_ReadArray.
*
* * The statuses can be polled using: \ref Cy_SCB_SPI_GetRxFifoStatus,
* \ref Cy_SCB_SPI_GetTxFifoStatus and \ref Cy_SCB_SPI_GetSlaveMasterStatus.
* <em>The statuses are <b>W1C (Write 1 to Clear)</b> and after a status
* is set, it must be cleared.</em> Note that there are statuses evaluated as level.
* These statuses remain set until an event is true. Therefore, after the clear
* operation, the status is cleared but then it is restored (if the event is still
* true).
* For example: the TX FIFO empty interrupt source can be cleared when the
* TX FIFO is not empty. Put at least two data elements (one goes to the
* shifter and next to FIFO) before clearing this status. \n
* Also, following functions can be used for polling as well
* \ref Cy_SCB_SPI_IsBusBusy, \ref Cy_SCB_SPI_IsTxComplete,
* \ref Cy_SCB_SPI_GetNumInRxFifo and \ref Cy_SCB_SPI_GetNumInTxFifo.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_TRANFER_DATA_LL
*
* \subsection group_scb_spi_hl High-Level API
* The \ref group_scb_spi_high_level_functions API uses an interrupt to execute
* a transfer. Call \ref Cy_SCB_SPI_Transfer to start communication: for the
* master mode, a transfer to the slave starts but for the slave mode,
* the Read and Write buffers are prepared for the following communication
* with the master.
* After a transfer is started, the \ref Cy_SCB_SPI_Interrupt handles the
* transfer until its completion. Therefore, it must be called inside the
* user interrupt handler to make the High-Level API work. To monitor the status
* of the transfer operation, use \ref Cy_SCB_SPI_GetTransferStatus.
* Alternatively, use \ref Cy_SCB_SPI_RegisterCallback to register a callback
* function to be notified about \ref group_scb_spi_macros_callback_events.
*
* \snippet SCB_CompDatasheet_sut_01_revA.cydsn\spi_snippets.c SPI_TRANFER_DATA
*
* \section group_scb_spi_dma_trig DMA Trigger
* The SCB provides TX and RX output trigger signals that can be routed to the
* DMA controller inputs. These signals are assigned based on the data availability
* in the TX and RX FIFOs appropriately.
*
* * The RX trigger signal remains active until the number of data
* elements in the RX FIFO is greater than the value of RX FIFO level. Use
* function \ref Cy_SCB_SetRxFifoLevel or set configuration structure
* rxFifoTriggerLevel parameter to configure RX FIFO level value. \n
* <em>For example, the RX FIFO has 8 data elements and the RX FIFO level is 0.
* The RX trigger signal remains active until DMA does not read all data from
* the RX FIFO.</em>
*
* * The TX trigger signal remains active until the number of data elements
* in the TX FIFO is less than the value of TX FIFO level. Use function
* \ref Cy_SCB_SetTxFifoLevel or set configuration structure txFifoTriggerLevel
* parameter to configure TX FIFO level value. \n
* <em>For example, the TX FIFO has 0 data elements (empty) and the TX FIFO level
* is 7. The TX trigger signal remains active until DMA does not load TX FIFO
* with 7 data elements (note that after the first TX load operation, the data
* element goes to the shift register and TX FIFO remains empty).</em>
*
* To route SCB TX or RX trigger signals to the DMA controller, use \ref group_trigmux
* driver API.
*
* \note
* To properly handle DMA level request signal activation and de-activation from the SCB
* peripheral block the DMA Descriptor typically must be configured to re-trigger
* after 16 Clk_Slow cycles.
*
* \section group_scb_spi_lp Low Power Support
* The SPI driver provides the callback functions to handle power mode transition.
* The callback \ref Cy_SCB_SPI_DeepSleepCallback must be called
* during execution of \ref Cy_SysPm_DeepSleep; \ref Cy_SCB_SPI_HibernateCallback
* must be called during execution of \ref Cy_SysPm_Hibernate. To trigger the
* callback execution, the callback must be registered before calling the
* power mode transition function. Refer to \ref group_syspm driver for more
* information about power mode transitions and callback registration.
*
* The SPI master is disabled during Deep Sleep and Hibernate and stops driving
* the output pins. The state of the SPI master output pins SCLK, SS, and MOSI is
* High-Z, which can cause unexpected behavior of the SPI Slave due to possible
* glitches on these lines. These pins must be set to the inactive state before
* entering Deep Sleep or Hibernate mode. To do that, configure the SPI master
* pins output to drive the inactive state and High-Speed Input Output
* Multiplexer (HSIOM) to control output by GPIO (use \ref group_gpio
* driver API). The pins configuration must be restored after exiting Deep Sleep
* mode to return the SPI master control of the pins (after exiting Hibernate
* mode, the system init code does the same).
* Note that the SPI master must be enabled to drive the pins during
* configuration change not to cause glitches on the lines. Copy either or
* both \ref Cy_SCB_SPI_DeepSleepCallback and \ref Cy_SCB_SPI_HibernateCallback
* as appropriate, and make the changes described above inside the function.
* Alternately, external pull-up or pull-down resistors can be connected
* to the appropriate SPI lines to keep them inactive during Deep-Sleep or
* Hibernate.
*
* \note
* Only applicable for <b>rev-08 of the CY8CKIT-062-BLE</b>.
* For proper operation, when the SPI slave is configured to be a wakeup
* source from Deep Sleep mode, the \ref Cy_SCB_SPI_DeepSleepCallback must be
* copied and modified. Refer to the function description to get the details.
*
* \section group_scb_spi_more_information More Information
* For more information on the SCB peripheral, refer to the technical reference
* manual (TRM).
*
* \section group_scb_spi_MISRA MISRA-C Compliance
* <table class="doxtable">
* <tr>
* <th>MISRA Rule</th>
* <th>Rule Class (Required/Advisory)</th>
* <th>Rule Description</th>
* <th>Description of Deviation(s)</th>
* </tr>
* <tr>
* <td>11.4</td>
* <td>A</td>
* <td>A cast should not be performed between a pointer to object type and
* a different pointer to object type.</td>
* <td>
* * The pointer to the buffer memory is void to allow handling
* different data types: uint8_t (4-8 bits) or uint16_t (9-16 bits).
* The cast operation is safe because the configuration is verified
* before operation is performed.
* * The functions \ref Cy_SCB_SPI_DeepSleepCallback and
* \ref Cy_SCB_SPI_HibernateCallback are callback of
* \ref cy_en_syspm_status_t type. The cast operation safety in these
* functions becomes the user's responsibility because pointers are
* initialized when callback is registered in SysPm driver.</td>
* </tr>
* <tr>
* <td>13.7</td>
* <td>R</td>
* <td>Boolean operations whose results are invariant shall not be
* permitted.</td>
* <td>The SCB block parameters can be a constant false or true depends on
* the selected device and cause this violation.</td>
* </tr>
* <tr>
* <td>14.1</td>
* <td>R</td>
* <td>There shall be no unreachable code.</td>
* <td>The SCB block parameters can be a constant false or true depends on
* the selected device and cause code to be unreachable.</td>
* </tr>
* <tr>
* <td>14.2</td>
* <td>R</td>
* <td>All non-null statements shall either: a) have at least one side-effect
* however executed, or b) cause control flow to change.</td>
* <td>The unused function parameters are cast to void. This statement
* has no side-effect and is used to suppress a compiler warning.</td>
* </tr>
* <tr>
* <td>14.7</td>
* <td>R</td>
* <td>A function shall have a single point of exit at the end of the
* function.</td>
* <td>The functions can return from several points. This is done to improve
* code clarity when returning error status code if input parameters
* validation is failed.</td>
* </tr>
* </table>
*
* \section group_scb_spi_changelog Changelog
* <table class="doxtable">
* <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
* <tr>
* <td>2.10</td>
* <td>None.</td>
* <td>SCB I2C driver updated.</td>
* </tr>
* <tr>
* <td rowspan="4"> 2.0</td>
* <td>Fixed SPI callback notification when error event occurred.</td>
* <td>The SPI callback passed incorrect event value if error event occurred.</td>
* </tr>
* <tr>
* <td>Added parameters validation for public API.</td>
* <td></td>
* </tr>
* <tr>
* <td>Replaced variables that have limited range of values with enumerated
* types.</td>
* <td></td>
* </tr>
* <tr>
* <td>Added missing "cy_cb_" to the callback function type names.</td>
* <td></td>
* </tr>
* <tr>
* <td>1.0</td>
* <td>Initial version.</td>
* <td></td>
* </tr>
* </table>
*
* \defgroup group_scb_spi_macros Macros
* \defgroup group_scb_spi_functions Functions
* \{
* \defgroup group_scb_spi_general_functions General
* \defgroup group_scb_spi_high_level_functions High-Level
* \defgroup group_scb_spi_low_level_functions Low-Level
* \defgroup group_scb_spi_interrupt_functions Interrupt
* \defgroup group_scb_spi_low_power_functions Low Power Callbacks
* \}
* \defgroup group_scb_spi_data_structures Data Structures
* \defgroup group_scb_spi_enums Enumerated Types
*/
#if !defined(CY_SCB_SPI_H)
#define CY_SCB_SPI_H
#include "cy_scb_common.h"
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************
* Enumerated Types
***************************************/
/**
* \addtogroup group_scb_spi_enums
* \{
*/
/** SPI status codes */
typedef enum
{
/** Operation completed successfully */
CY_SCB_SPI_SUCCESS = 0U,
/** One or more of input parameters are invalid */
CY_SCB_SPI_BAD_PARAM = (CY_SCB_ID | CY_PDL_STATUS_ERROR | CY_SCB_SPI_ID | 1U),
/**
* The SPI is busy processing a transfer. Call \ref Cy_SCB_SPI_Transfer
* function again once that transfer is completed or aborted.
*/
CY_SCB_SPI_TRANSFER_BUSY = (CY_SCB_ID | CY_PDL_STATUS_ERROR | CY_SCB_SPI_ID | 2U)
} cy_en_scb_spi_status_t;
/** SPI Modes */
typedef enum
{
CY_SCB_SPI_SLAVE, /**< Configures SCB for SPI Slave operation */
CY_SCB_SPI_MASTER, /**< Configures SCB for SPI Master operation */
} cy_en_scb_spi_mode_t;
/** SPI Submodes */
typedef enum
{
/** Configures an SPI for a standard Motorola SPI operation */
CY_SCB_SPI_MOTOROLA = 0x0U,
/**
* Configures the SPI for the TI SPI operation. In the TI mode, the slave
* select is a pulse. In this case, the pulse coincides with the first bit.
*/
CY_SCB_SPI_TI_COINCIDES = 0x01U,
/**
* Configures an SPI for the National SPI operation. This is a half-duplex
* mode of operation.
*/
CY_SCB_SPI_NATIONAL = 0x02U,
/**
* Configures an SPI for the TI SPI operation, in the TI mode. The slave
* select is a pulse. In this case the pulse precedes the first bit.
*/
CY_SCB_SPI_TI_PRECEDES = 0x05U,
} cy_en_scb_spi_sub_mode_t;
/** SPI SCLK Modes */
typedef enum
{
CY_SCB_SPI_CPHA0_CPOL0 = 0U, /**< Clock is active low, data is changed on first edge */
CY_SCB_SPI_CPHA0_CPOL1 = 1U, /**< Clock is active high, data is changed on first edge */
CY_SCB_SPI_CPHA1_CPOL0 = 2U, /**< Clock is active low, data is changed on second edge */
CY_SCB_SPI_CPHA1_CPOL1 = 3U, /**< Clock is active high, data is changed on second edge */
} cy_en_scb_spi_sclk_mode_t;
/** SPI Slave Selects */
typedef enum
{
CY_SCB_SPI_SLAVE_SELECT0 = 0U, /**< Master will use Slave Select 0 */
CY_SCB_SPI_SLAVE_SELECT1 = 1U, /**< Master will use Slave Select 1 */
CY_SCB_SPI_SLAVE_SELECT2 = 2U, /**< Master will use Slave Select 2 */
CY_SCB_SPI_SLAVE_SELECT3 = 3U, /**< Master will use Slave Select 3 */
} cy_en_scb_spi_slave_select_t;
/** SPI Polarity */
typedef enum
{
CY_SCB_SPI_ACTIVE_LOW = 0U, /**< Signal in question is active low */
CY_SCB_SPI_ACTIVE_HIGH = 1U, /**< Signal in question is active high */
} cy_en_scb_spi_polarity_t;
/** \} group_scb_spi_enums */
/***************************************
* Type Definitions
***************************************/
/**
* \addtogroup group_scb_spi_data_structures
* \{
*/
/**
* Provides the typedef for the callback function called in the
* \ref Cy_SCB_SPI_Interrupt to notify the user about occurrences of
* \ref group_scb_spi_macros_callback_events.
*/
typedef void (* cy_cb_scb_spi_handle_events_t)(uint32_t event);
/** SPI configuration structure */
typedef struct cy_stc_scb_spi_config
{
/** Specifies the mode of operation */
cy_en_scb_spi_mode_t spiMode;
/** Specifies the submode of SPI operation */
cy_en_scb_spi_sub_mode_t subMode;
/**
* Configures the SCLK operation for Motorola sub-mode, ignored for all
* other submodes
*/
cy_en_scb_spi_sclk_mode_t sclkMode;
/**
* Oversample factor for SPI.
* * For the master mode, the data rate is the SCB clock / oversample
* (valid range is 4-16).
* * For the slave mode, the oversample value is ignored. The data rate is
* determined by the SCB clock frequency. See the device datasheet for
* more details.
*/
uint32_t oversample;
/**
* The width of RX data (valid range 4-16). It must be the same as
* \ref txDataWidth except in National sub-mode.
*/
uint32_t rxDataWidth;
/**
* The width of TX data (valid range 4-16). It must be the same as
* \ref rxDataWidth except in National sub-mode.
*/
uint32_t txDataWidth;
/**
* Enables the hardware to shift out the data element MSB first, otherwise,
* LSB first
*/
bool enableMsbFirst;
/**
* Enables the master to generate a continuous SCLK regardless of whether
* there is data to send
*/
bool enableFreeRunSclk;
/**
* Enables a digital 3-tap median filter to be applied to the input
* of the RX FIFO to filter glitches on the line.
*/
bool enableInputFilter;
/**
* Enables the master to sample MISO line one half clock later to allow
* better timings.
*/
bool enableMisoLateSample;
/**
* Enables the master to transmit each data element separated by a
* de-assertion of the slave select line (only applicable for the master
* mode)
*/
bool enableTransferSeperation;
/**
* Sets active polarity of each SS line.
* This is a bit mask: bit 0 corresponds to SS0 and so on to SS3.
* 1 means active high, a 0 means active low.
*/
uint32_t ssPolarity;
/**
* When set, the slave will wake the device when the slave select line
* becomes active.
* Note that not all SCBs support this mode. Consult the device
* datasheet to determine which SCBs support wake from Deep Sleep.
*/
bool enableWakeFromSleep;
/**
* When there are more entries in the RX FIFO, then at this level
* the RX trigger output goes high. This output can be connected
* to a DMA channel through a trigger mux.
* Also, it controls the \ref CY_SCB_SPI_RX_TRIGGER interrupt source.
*/
uint32_t rxFifoTriggerLevel;
/**
* Bits set in this mask will allow events to cause an interrupt
* (See \ref group_scb_spi_macros_rx_fifo_status for the set of constant)
*/
uint32_t rxFifoIntEnableMask;
/**
* When there are fewer entries in the TX FIFO, then at this level
* the TX trigger output goes high. This output can be connected
* to a DMA channel through a trigger mux.
* Also, it controls the \ref CY_SCB_SPI_TX_TRIGGER interrupt source.
*/
uint32_t txFifoTriggerLevel;
/**
* Bits set in this mask allow events to cause an interrupt
* (See \ref group_scb_spi_macros_tx_fifo_status for the set of constants)
*/
uint32_t txFifoIntEnableMask;
/**
* Bits set in this mask allow events to cause an interrupt
* (See \ref group_scb_spi_macros_master_slave_status for the set of
* constants)
*/
uint32_t masterSlaveIntEnableMask;
}cy_stc_scb_spi_config_t;
/** SPI context structure.
* All fields for the context structure are internal. Firmware never reads or
* writes these values. Firmware allocates the structure and provides the
* address of the structure to the driver in function calls. Firmware must
* ensure that the defined instance of this structure remains in scope
* while the drive is in use.
*/
typedef struct cy_stc_scb_spi_context
{
/** \cond INTERNAL */
uint32_t volatile status; /**< The receive status */
void *rxBuf; /**< The pointer to the receive buffer */
uint32_t rxBufSize; /**< The receive buffer size */
uint32_t volatile rxBufIdx; /**< The current location in the receive buffer */
void *txBuf; /**< The pointer to the transmit buffer */
uint32_t txBufSize; /**< The transmit buffer size */
uint32_t volatile txBufIdx; /**< The current location in the transmit buffer */
/**
* The pointer to an event callback that is called when any of
* \ref group_scb_spi_macros_callback_events occurs
*/
cy_cb_scb_spi_handle_events_t cbEvents;
#if !defined(NDEBUG)
uint32_t initKey; /**< Tracks the context initialization */
#endif /* !(NDEBUG) */
/** \endcond */
} cy_stc_scb_spi_context_t;
/** \} group_scb_spi_data_structures */
/***************************************
* Function Prototypes
***************************************/
/**
* \addtogroup group_scb_spi_general_functions
* \{
*/
cy_en_scb_spi_status_t Cy_SCB_SPI_Init(CySCB_Type *base, cy_stc_scb_spi_config_t const *config,
cy_stc_scb_spi_context_t *context);
void Cy_SCB_SPI_DeInit (CySCB_Type *base);
__STATIC_INLINE void Cy_SCB_SPI_Enable(CySCB_Type *base);
void Cy_SCB_SPI_Disable(CySCB_Type *base, cy_stc_scb_spi_context_t *context);
__STATIC_INLINE void Cy_SCB_SPI_SetActiveSlaveSelect(CySCB_Type *base,
cy_en_scb_spi_slave_select_t slaveSelect);
__STATIC_INLINE void Cy_SCB_SPI_SetActiveSlaveSelectPolarity(CySCB_Type *base,
cy_en_scb_spi_slave_select_t slaveSelect,
cy_en_scb_spi_polarity_t polarity);
__STATIC_INLINE bool Cy_SCB_SPI_IsBusBusy(CySCB_Type const *base);
/** \} group_scb_spi_general_functions */
/**
* \addtogroup group_scb_spi_high_level_functions
* \{
*/
cy_en_scb_spi_status_t Cy_SCB_SPI_Transfer(CySCB_Type *base, void *txBuffer, void *rxBuffer, uint32_t size,
cy_stc_scb_spi_context_t *context);
void Cy_SCB_SPI_AbortTransfer (CySCB_Type *base, cy_stc_scb_spi_context_t *context);
uint32_t Cy_SCB_SPI_GetTransferStatus(CySCB_Type const *base, cy_stc_scb_spi_context_t const *context);
uint32_t Cy_SCB_SPI_GetNumTransfered (CySCB_Type const *base, cy_stc_scb_spi_context_t const *context);
/** \} group_scb_spi_high_level_functions */
/**
* \addtogroup group_scb_spi_low_level_functions
* \{
*/
__STATIC_INLINE uint32_t Cy_SCB_SPI_Read (CySCB_Type const *base);
__STATIC_INLINE uint32_t Cy_SCB_SPI_ReadArray(CySCB_Type const *base, void *buffer, uint32_t size);
__STATIC_INLINE uint32_t Cy_SCB_SPI_Write (CySCB_Type *base, uint32_t data);
__STATIC_INLINE uint32_t Cy_SCB_SPI_WriteArray(CySCB_Type *base, void *buffer, uint32_t size);
__STATIC_INLINE void Cy_SCB_SPI_WriteArrayBlocking(CySCB_Type *base, void *buffer, uint32_t size);
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetTxFifoStatus (CySCB_Type const *base);
__STATIC_INLINE void Cy_SCB_SPI_ClearTxFifoStatus(CySCB_Type *base, uint32_t clearMask);
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetRxFifoStatus (CySCB_Type const *base);
__STATIC_INLINE void Cy_SCB_SPI_ClearRxFifoStatus(CySCB_Type *base, uint32_t clearMask);
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetSlaveMasterStatus (CySCB_Type const *base);
__STATIC_INLINE void Cy_SCB_SPI_ClearSlaveMasterStatus(CySCB_Type *base, uint32_t clearMask);
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetNumInTxFifo(CySCB_Type const *base);
__STATIC_INLINE bool Cy_SCB_SPI_IsTxComplete (CySCB_Type const *base);
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetNumInRxFifo(CySCB_Type const *base);
__STATIC_INLINE void Cy_SCB_SPI_ClearRxFifo(CySCB_Type *base);
__STATIC_INLINE void Cy_SCB_SPI_ClearTxFifo(CySCB_Type *base);
/** \} group_scb_spi_low_level_functions */
/**
* \addtogroup group_scb_spi_interrupt_functions
* \{
*/
void Cy_SCB_SPI_Interrupt(CySCB_Type *base, cy_stc_scb_spi_context_t *context);
__STATIC_INLINE void Cy_SCB_SPI_RegisterCallback(CySCB_Type const *base, cy_cb_scb_spi_handle_events_t callback,
cy_stc_scb_spi_context_t *context);
/** \} group_scb_spi_interrupt_functions */
/**
* \addtogroup group_scb_spi_low_power_functions
* \{
*/
cy_en_syspm_status_t Cy_SCB_SPI_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams);
cy_en_syspm_status_t Cy_SCB_SPI_HibernateCallback(cy_stc_syspm_callback_params_t *callbackParams);
/** \} group_scb_spi_low_power_functions */
/***************************************
* API Constants
***************************************/
/**
* \addtogroup group_scb_spi_macros
* \{
*/
/**
* \defgroup group_scb_spi_macros_tx_fifo_status SPI TX FIFO Statuses
* Each SPI TX FIFO status is encoded in a separate bit. Therefore multiple bits
* may be set to indicate the current status.
* \{
*/
/** The number of entries in the TX FIFO is less than the TX FIFO trigger level
* value
*/
#define CY_SCB_SPI_TX_TRIGGER (SCB_INTR_TX_TRIGGER_Msk)
/** The TX FIFO is not full, there is a space for more data */
#define CY_SCB_SPI_TX_NOT_FULL (SCB_INTR_TX_NOT_FULL_Msk)
/**
* The TX FIFO is empty, note that there may still be data in the shift register.
*/
#define CY_SCB_SPI_TX_EMPTY (SCB_INTR_TX_EMPTY_Msk)
/** An attempt to write to the full TX FIFO */
#define CY_SCB_SPI_TX_OVERFLOW (SCB_INTR_TX_OVERFLOW_Msk)
/**
* Applicable only for the slave mode. The master tried to read more
* data elements than available.
*/
#define CY_SCB_SPI_TX_UNDERFLOW (SCB_INTR_TX_UNDERFLOW_Msk)
/** \} group_scb_spi_macros_tx_fifo_status */
/**
* \defgroup group_scb_spi_macros_rx_fifo_status SPI RX FIFO Statuses
* \{
* Each SPI RX FIFO status is encoded in a separate bit. Therefore, multiple
* bits may be set to indicate the current status.
*/
/** The number of entries in the RX FIFO is more than the RX FIFO trigger
* level value.
*/
#define CY_SCB_SPI_RX_TRIGGER (SCB_INTR_RX_TRIGGER_Msk)
/** The RX FIFO is not empty, there is data to read */
#define CY_SCB_SPI_RX_NOT_EMPTY (SCB_INTR_RX_NOT_EMPTY_Msk)
/**
* The RX FIFO is full. There is no more space for additional data.
* Any additional data will be dropped.
*/
#define CY_SCB_SPI_RX_FULL (SCB_INTR_RX_FULL_Msk)
/**
* The RX FIFO was full and there was an attempt to write to it.
* This additional data was dropped.
*/
#define CY_SCB_SPI_RX_OVERFLOW (SCB_INTR_RX_OVERFLOW_Msk)
/** An attempt to read from an empty RX FIFO */
#define CY_SCB_SPI_RX_UNDERFLOW (SCB_INTR_RX_UNDERFLOW_Msk)
/** \} group_scb_spi_macros_rx_fifo_status */
/**
* \defgroup group_scb_spi_macros_master_slave_status SPI Master and Slave Statuses
* \{
*/
/** The slave was deselected at the wrong time */
#define CY_SCB_SPI_SLAVE_ERR (SCB_INTR_S_SPI_BUS_ERROR_Msk)
/** The master has transmitted all data elements from FIFO and shifter */
#define CY_SCB_SPI_MASTER_DONE (SCB_INTR_M_SPI_DONE_Msk)
/** \} group_scb_spi_macros_master_slave_status */
/**
* \defgroup group_scb_spi_macros_xfer_status SPI Transfer Status
* \{
* Each SPI transfer status is encoded in a separate bit, therefore multiple bits
* may be set to indicate the current status.
*/
/**
* Transfer operation started by \ref Cy_SCB_SPI_Transfer is in progress
*/
#define CY_SCB_SPI_TRANSFER_ACTIVE (0x01UL)
/**
* All data elements specified by \ref Cy_SCB_SPI_Transfer for transmission
* have been loaded into the TX FIFO
*/
#define CY_SCB_SPI_TRANSFER_IN_FIFO (0x02UL)
/** The slave was deselected at the wrong time. */
#define CY_SCB_SPI_SLAVE_TRANSFER_ERR (SCB_INTR_S_SPI_BUS_ERROR_Msk)
/**
* RX FIFO was full and there was an attempt to write to it.
* This additional data was dropped.
*/
#define CY_SCB_SPI_TRANSFER_OVERFLOW (SCB_INTR_RX_OVERFLOW_Msk)
/**
* Applicable only for the slave mode. The master tried to read more
* data elements than available in the TX FIFO.
*/
#define CY_SCB_SPI_TRANSFER_UNDERFLOW (SCB_INTR_TX_UNDERFLOW_Msk)
/** \} group_scb_spi_macros_xfer_status */
/**
* \defgroup group_scb_spi_macros_callback_events SPI Callback Events
* \{
* Only single event is notified by the callback.
*/
/**
* All data elements specified by \ref Cy_SCB_SPI_Transfer for transmission
* have been loaded into the TX FIFO
*/
#define CY_SCB_SPI_TRANSFER_IN_FIFO_EVENT (0x01U)
/** The transfer operation started by \ref Cy_SCB_SPI_Transfer is complete */
#define CY_SCB_SPI_TRANSFER_CMPLT_EVENT (0x02U)
/**
* An error occurred during the transfer. This includes overflow, underflow
* and a transfer error. Check \ref Cy_SCB_SPI_GetTransferStatus.
*/
#define CY_SCB_SPI_TRANSFER_ERR_EVENT (0x04U)
/** \} group_scb_spi_macros_callback_events */
/** Default TX value when no TX buffer is defined */
#define CY_SCB_SPI_DEFAULT_TX (0x0000FFFFUL)
/** Data returned by the hardware when an empty RX FIFO is read */
#define CY_SCB_SPI_RX_NO_DATA (0xFFFFFFFFUL)
/***************************************
* Internal Constants
***************************************/
/** \cond INTERNAL */
#define CY_SCB_SPI_RX_INTR_MASK (CY_SCB_SPI_RX_TRIGGER | CY_SCB_SPI_RX_NOT_EMPTY | CY_SCB_SPI_RX_FULL | \
CY_SCB_SPI_RX_OVERFLOW | CY_SCB_SPI_RX_UNDERFLOW)
#define CY_SCB_SPI_TX_INTR_MASK (CY_SCB_SPI_TX_TRIGGER | CY_SCB_SPI_TX_NOT_FULL | CY_SCB_SPI_TX_EMPTY | \
CY_SCB_SPI_TX_OVERFLOW | CY_SCB_SPI_TX_UNDERFLOW)
#define CY_SCB_SPI_MASTER_SLAVE_INTR_MASK (CY_SCB_SPI_MASTER_DONE | CY_SCB_SPI_SLAVE_ERR)
#define CY_SCB_SPI_TRANSFER_ERR (CY_SCB_SPI_SLAVE_TRANSFER_ERR | CY_SCB_SPI_TRANSFER_OVERFLOW | \
CY_SCB_SPI_TRANSFER_UNDERFLOW)
#define CY_SCB_SPI_INIT_KEY (0x00ABCDEFUL)
#define CY_SCB_SPI_IS_MODE_VALID(mode) ( (CY_SCB_SPI_SLAVE == (mode)) || \
(CY_SCB_SPI_MASTER == (mode)) )
#define CY_SCB_SPI_IS_SUB_MODE_VALID(subMode) ( (CY_SCB_SPI_MOTOROLA == (subMode)) || \
(CY_SCB_SPI_TI_COINCIDES == (subMode)) || \
(CY_SCB_SPI_TI_PRECEDES == (subMode)) || \
(CY_SCB_SPI_NATIONAL == (subMode)) )
#define CY_SCB_SPI_IS_SCLK_MODE_VALID(clkMode) ( (CY_SCB_SPI_CPHA0_CPOL0 == (clkMode)) || \
(CY_SCB_SPI_CPHA0_CPOL1 == (clkMode)) || \
(CY_SCB_SPI_CPHA1_CPOL0 == (clkMode)) || \
(CY_SCB_SPI_CPHA1_CPOL1 == (clkMode)) )
#define CY_SCB_SPI_IS_POLARITY_VALID(polarity) ( (CY_SCB_SPI_ACTIVE_LOW == (polarity)) || \
(CY_SCB_SPI_ACTIVE_HIGH == (polarity)) )
#define CY_SCB_SPI_IS_SLAVE_SEL_VALID(ss) ( (CY_SCB_SPI_SLAVE_SELECT0 == (ss)) || \
(CY_SCB_SPI_SLAVE_SELECT1 == (ss)) || \
(CY_SCB_SPI_SLAVE_SELECT2 == (ss)) || \
(CY_SCB_SPI_SLAVE_SELECT3 == (ss)) )
#define CY_SCB_SPI_IS_OVERSAMPLE_VALID(ovs, mode) ( (CY_SCB_SPI_MASTER == (mode)) ? (((ovs) >= 2UL) && ((ovs) <= 16UL)) : true )
#define CY_SCB_SPI_IS_DATA_WIDTH_VALID(width) ( ((width) >= 4UL) && ((width) <= 16UL) )
#define CY_SCB_SPI_IS_SS_POLARITY_VALID(polarity) ( (0UL == ((polarity) & (~0x0FUL))) )
#define CY_SCB_SPI_IS_BUFFER_VALID(txBuffer, rxBuffer, size) ( ((size) > 0UL) && \
(false == ((NULL == (txBuffer)) && (NULL == (rxBuffer)))) )
#define CY_SCB_SPI_IS_BOTH_DATA_WIDTH_VALID(subMode, rxWidth, txWidth) ( (CY_SCB_SPI_NATIONAL != (subMode)) ? \
((rxWidth) == (txWidth)) : true )
/** \endcond */
/** \} group_scb_spi_macros */
/***************************************
* In-line Function Implementation
***************************************/
/**
* \addtogroup group_scb_spi_general_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_SCB_SPI_Enable
****************************************************************************//**
*
* Enables the SCB block for the SPI operation.
*
* \param base
* The pointer to the SPI SCB instance.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_Enable(CySCB_Type *base)
{
base->CTRL |= SCB_CTRL_ENABLED_Msk;
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_IsBusBusy
****************************************************************************//**
*
* Returns whether the SPI bus is busy or not. The bus busy is determined using
* the slave select signal.
* * Motorola and National Semiconductor sub-modes: the bus is busy after the
* slave select line is activated and lasts until the slave select line is
* deactivated.
* * Texas Instrument sub-modes: The bus is busy at the moment of the initial
* pulse on the slave select line and lasts until the transfer is complete.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \return
* True - the bus is busy; false - the bus is idle.
*
* \note
* * The SPI master does not assign the slave select line immediately after
* the first data element is written into the TX FIFO. It takes up to two SCLK
* clocks to assign the slave select line. Before this happens, the bus
* is considered idle.
* * If the SPI master is configured to separate a data elements transfer,
* the bus is busy during each element transfer and is free between them.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SCB_SPI_IsBusBusy(CySCB_Type const *base)
{
return _FLD2BOOL(SCB_SPI_STATUS_BUS_BUSY, base->SPI_STATUS);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_SetActiveSlaveSelect
****************************************************************************//**
*
* Selects an active slave select line from one of four available.
* This function is applicable for the master and slave.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param slaveSelect
* The slave select line number.
* See \ref cy_en_scb_spi_slave_select_t for the set of constants.
*
* \note
* The SCB be idle or disabled before calling this function.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_SetActiveSlaveSelect(CySCB_Type *base, cy_en_scb_spi_slave_select_t slaveSelect)
{
CY_ASSERT_L3(CY_SCB_SPI_IS_SLAVE_SEL_VALID(slaveSelect));
base->SPI_CTRL = _CLR_SET_FLD32U(base->SPI_CTRL, SCB_SPI_CTRL_SSEL, (uint32_t) slaveSelect);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_SetActiveSlaveSelectPolarity
****************************************************************************//**
*
* Sets the active polarity for the slave select line.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param slaveSelect
* The slave select line number.
* See \ref cy_en_scb_spi_slave_select_t for the set of constants.
*
* \param polarity
* The polarity of the slave select line.
* See \ref cy_en_scb_spi_polarity_t for the set of constants.
*
* \note
* The SCB be idle or disabled before calling this function.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_SetActiveSlaveSelectPolarity(CySCB_Type *base,
cy_en_scb_spi_slave_select_t slaveSelect,
cy_en_scb_spi_polarity_t polarity)
{
CY_ASSERT_L3(CY_SCB_SPI_IS_SLAVE_SEL_VALID(slaveSelect));
CY_ASSERT_L3(CY_SCB_SPI_IS_POLARITY_VALID (polarity));
uint32_t mask = _VAL2FLD(CY_SCB_SPI_CTRL_SSEL_POLARITY, (0x01UL << slaveSelect));
if (CY_SCB_SPI_ACTIVE_HIGH != polarity)
{
base->SPI_CTRL |= (uint32_t) mask;
}
else
{
base->SPI_CTRL &= (uint32_t) ~mask;
}
}
/** \} group_scb_spi_general_functions */
/**
* \addtogroup group_scb_spi_low_level_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_SCB_SPI_GetRxFifoStatus
****************************************************************************//**
*
* Returns the current status of the RX FIFO.
* Clear the active statuses to let the SCB hardware update them.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \return
* \ref group_scb_spi_macros_rx_fifo_status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetRxFifoStatus(CySCB_Type const *base)
{
return (Cy_SCB_GetRxInterruptStatus(base) & CY_SCB_SPI_RX_INTR_MASK);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_ClearRxFifoStatus
****************************************************************************//**
*
* Clears the selected statuses of the RX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param clearMask
* The mask of which statuses to clear.
* See \ref group_scb_spi_macros_rx_fifo_status for the set of constants.
*
* \note
* * This status is also used for interrupt generation, so clearing it also
* clears the interrupt sources.
* * Level sensitive statuses such as \ref CY_SCB_SPI_RX_TRIGGER,
* \ref CY_SCB_SPI_RX_NOT_EMPTY and \ref CY_SCB_SPI_RX_FULL set high again after
* being cleared if the condition remains true.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_ClearRxFifoStatus(CySCB_Type *base, uint32_t clearMask)
{
CY_ASSERT_L2(CY_SCB_IS_INTR_VALID(clearMask, CY_SCB_SPI_RX_INTR_MASK));
Cy_SCB_ClearRxInterrupt(base, clearMask);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_GetNumInRxFifo
****************************************************************************//**
*
* Returns the number of data elements in the SPI RX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \return
* The number of data elements in the RX FIFO.
* The size of a data element defined by the configured RX data width.
*
* \note
* This number does not include any data currently in the RX shifter.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetNumInRxFifo(CySCB_Type const *base)
{
return Cy_SCB_GetNumInRxFifo(base);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_ClearRxFifo
****************************************************************************//**
*
* Clears all data out of the SPI RX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \sideeffect
* Any data currently in the shifter is cleared and lost.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_ClearRxFifo(CySCB_Type *base)
{
Cy_SCB_ClearRxFifo(base);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_GetTxFifoStatus
****************************************************************************//**
*
* Returns the current status of the TX FIFO.
* Clear the active statuses to let the SCB hardware update them.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \return
* \ref group_scb_spi_macros_tx_fifo_status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetTxFifoStatus(CySCB_Type const *base)
{
return (Cy_SCB_GetTxInterruptStatus(base) & CY_SCB_SPI_TX_INTR_MASK);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_ClearTxFifoStatus
****************************************************************************//**
*
* Clears the selected statuses of the TX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param clearMask
* The mask of which statuses to clear.
* See \ref group_scb_spi_macros_tx_fifo_status for the set of constants.
*
* \note
* * The status is also used for interrupt generation, so clearing it also
* clears the interrupt sources.
* * Level sensitive statuses such as \ref CY_SCB_SPI_TX_TRIGGER,
* \ref CY_SCB_SPI_TX_EMPTY and \ref CY_SCB_SPI_TX_NOT_FULL set high again after
* being cleared if the condition remains true.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_ClearTxFifoStatus(CySCB_Type *base, uint32_t clearMask)
{
CY_ASSERT_L2(CY_SCB_IS_INTR_VALID(clearMask, CY_SCB_SPI_TX_INTR_MASK));
Cy_SCB_ClearTxInterrupt(base, clearMask);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_GetNumInTxFifo
****************************************************************************//**
*
* Returns the number of data elements in the SPI TX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \return
* The number of data elements in the TX FIFO.
* The size of a data element defined by the configured TX data width.
*
* \note
* This number does not include any data currently in the TX shifter.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetNumInTxFifo(CySCB_Type const *base)
{
return Cy_SCB_GetNumInTxFifo(base);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_IsTxComplete
****************************************************************************//**
*
* Checks whether the TX FIFO and Shifter are empty and there is no more data to send
*
* \param base
* Pointer to the SPI SCB instance.
*
* \return
* If true, transmission complete. If false, transmission is not complete.
*
*******************************************************************************/
__STATIC_INLINE bool Cy_SCB_SPI_IsTxComplete(CySCB_Type const *base)
{
return Cy_SCB_IsTxComplete(base);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_ClearTxFifo
****************************************************************************//**
*
* Clears all data out of the SPI TX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \sideeffect
* The TX FIFO clear operation also clears the shift register, so that
* the shifter can be cleared in the middle of a data element transfer,
* corrupting it. The data element corruption means that all bits that have
* not been transmitted are transmitted as 1s on the bus.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_ClearTxFifo(CySCB_Type *base)
{
Cy_SCB_ClearTxFifo(base);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_GetSlaveMasterStatus
****************************************************************************//**
*
* Returns the current status of either the slave or the master, depending
* on the configured SPI mode.
* Clear the active statuses to let the SCB hardware update them.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \return
* \ref group_scb_spi_macros_master_slave_status
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_GetSlaveMasterStatus(CySCB_Type const *base)
{
uint32_t retStatus;
if (_FLD2BOOL(SCB_SPI_CTRL_MASTER_MODE, base->SPI_CTRL))
{
retStatus = (Cy_SCB_GetMasterInterruptStatus(base) & CY_SCB_MASTER_INTR_SPI_DONE);
}
else
{
retStatus = (Cy_SCB_GetSlaveInterruptStatus(base) & CY_SCB_SLAVE_INTR_SPI_BUS_ERROR);
}
return (retStatus);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_ClearSlaveMasterStatus
****************************************************************************//**
*
* Clears the selected statuses of either the slave or the master.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param clearMask
* The mask of which statuses to clear.
* See \ref group_scb_spi_macros_master_slave_status for the set of constants.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_ClearSlaveMasterStatus(CySCB_Type *base, uint32_t clearMask)
{
if (_FLD2BOOL(SCB_SPI_CTRL_MASTER_MODE, base->SPI_CTRL))
{
CY_ASSERT_L2(CY_SCB_IS_INTR_VALID(clearMask, CY_SCB_MASTER_INTR_SPI_DONE));
Cy_SCB_ClearMasterInterrupt(base, clearMask);
}
else
{
CY_ASSERT_L2(CY_SCB_IS_INTR_VALID(clearMask, CY_SCB_SLAVE_INTR_SPI_BUS_ERROR));
Cy_SCB_ClearSlaveInterrupt(base, clearMask);
}
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_Read
****************************************************************************//**
*
* Reads a single data element from the SPI RX FIFO.
* This function does not check whether the RX FIFO has data before reading it.
* If the RX FIFO is empty, the function returns \ref CY_SCB_SPI_RX_NO_DATA.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \return
* Data from the RX FIFO.
* The data element size is defined by the configured RX data width.
*
* \note
* * This function only reads data available in the RX FIFO. It does not
* initiate an SPI transfer.
* * When in the master mode, writes data into the TX FIFO and waits until
* the transfer is completed before getting data from the RX FIFO.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_Read(CySCB_Type const *base)
{
return Cy_SCB_ReadRxFifo(base);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_ReadArray
****************************************************************************//**
*
* Reads an array of data out of the SPI RX FIFO.
* This function does not block. It returns how many data elements were read
* from the RX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param buffer
* The pointer to the location to place data read from the RX FIFO.
* The item size is defined by the data type, which depends on the configured
* RX data width.
*
* \param size
* The number of data elements to read from the RX FIFO.
*
* \return
* The number of data elements read from the RX FIFO.
*
* \note
* * This function only reads data available in the RX FIFO. It does not
* initiate an SPI transfer.
* * When in the master mode, writes data into the TX FIFO and waits until
* the transfer is completed before getting data from the RX FIFO.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_ReadArray(CySCB_Type const *base, void *buffer, uint32_t size)
{
CY_ASSERT_L1(CY_SCB_IS_BUFFER_VALID(buffer, size));
return Cy_SCB_ReadArray(base, buffer, size);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_Write
****************************************************************************//**
*
* Places a single data element in the SPI TX FIFO.
* This function does not block. It returns how many data elements were placed
* in the TX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param data
* Data to put in the TX FIFO.
* The item size is defined by the data type, which depends on the configured
* TX data width.
*
* \return
* The number of data elements placed in the TX FIFO: 0 or 1.
*
* \note
* * When in the master mode, writing data into the TX FIFO starts an SPI
* transfer.
* * When in the slave mode, writing data into the TX FIFO does not start
* an SPI transfer. The data is loaded in the TX FIFO and will be sent
* to the master on its request.
* * The SPI interface is full-duplex, therefore reads and writes occur
* at the same time. Thus for every data element transferred out of the
* TX FIFO, one is transferred into the RX FIFO.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_Write(CySCB_Type *base, uint32_t data)
{
return Cy_SCB_Write(base, data);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_WriteArray
****************************************************************************//**
*
* Places an array of data in the SPI TX FIFO. This function does not
* block. It returns how many data elements were placed in the TX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param buffer
* The pointer to the data to place in the TX FIFO.
* The item size is defined by the data type, which depends on the configured
* TX data width.
*
* \param size
* The number of data elements to transmit.
*
* \return
* The number of data elements placed in the TX FIFO.
*
* \note
* * When in the master mode, writing data into the TX FIFO starts an SPI
* transfer.
* * When in the slave mode, writing data into the TX FIFO does not start
* an SPI transfer. The data is loaded in the TX FIFO and will be sent to
* the master on its request.
* * The SPI interface is full-duplex, therefore reads and writes occur
* at the same time. Thus for every data element transferred out of the
* TX FIFO, one is transferred into the RX FIFO.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_SCB_SPI_WriteArray(CySCB_Type *base, void *buffer, uint32_t size)
{
CY_ASSERT_L1(CY_SCB_IS_BUFFER_VALID(buffer, size));
return Cy_SCB_WriteArray(base, buffer, size);
}
/*******************************************************************************
* Function Name: Cy_SCB_SPI_WriteArrayBlocking
****************************************************************************//**
*
* Places an array of data in the SPI TX FIFO. This function blocks
* until the number of data elements specified by size is placed in the SPI
* TX FIFO.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param buffer
* The pointer to data to place in the TX FIFO.
* The item size is defined by the data type, which depends on the configured
* TX data width.
*
* \param size
* The number of data elements to write into the TX FIFO.
*
* \note
* * When in the master mode, writing data into the TX FIFO starts an SPI
* transfer.
* * When in the slave mode, writing data into the TX FIFO does not start
* an SPI transfer. The data is loaded in the TX FIFO and will be sent to
* the master on its request.
* * The SPI interface is full-duplex, therefore reads and writes occur
* at the same time. Thus for every data element transferred out of the
* TX FIFO, one is transferred into the RX FIFO.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_WriteArrayBlocking(CySCB_Type *base, void *buffer, uint32_t size)
{
CY_ASSERT_L1(CY_SCB_IS_BUFFER_VALID(buffer, size));
Cy_SCB_WriteArrayBlocking(base, buffer, size);
}
/** \} group_scb_spi_low_level_functions */
/**
* \addtogroup group_scb_spi_interrupt_functions
* \{
*/
/*******************************************************************************
* Function Name: Cy_SCB_SPI_RegisterCallback
****************************************************************************//**
*
* Registers a callback function, which notifies that
* \ref group_scb_spi_macros_callback_events occurred in the
* \ref Cy_SCB_SPI_Interrupt.
*
* \param base
* The pointer to the SPI SCB instance.
*
* \param callback
* The pointer to the callback function.
* See \ref cy_cb_scb_spi_handle_events_t for the function prototype.
*
* \param context
* The pointer to the context structure \ref cy_stc_scb_spi_context_t allocated
* by the user. The structure is used during the SPI operation for internal
* configuration and data retention. The user should not modify anything
* in this structure.
*
* \note
* To remove the callback, pass NULL as the pointer to the callback function.
*
*******************************************************************************/
__STATIC_INLINE void Cy_SCB_SPI_RegisterCallback(CySCB_Type const *base,
cy_cb_scb_spi_handle_events_t callback, cy_stc_scb_spi_context_t *context)
{
/* Suppress a compiler warning about unused variables */
(void) base;
context->cbEvents = callback;
}
/** \cond INTERNAL */
/*******************************************************************************
* Function Name: CY_SCB_SPI_GetSclkMode
****************************************************************************//**
*
* Return correct SCLK mode depends on selected sub mode.
*
* \param subMode
* \ref cy_en_scb_spi_sub_mode_t
*
* \param sclkMode
* \ref cy_en_scb_spi_sclk_mode_t
*
* \return
* \ref cy_en_scb_spi_sclk_mode_t
*
*******************************************************************************/
__STATIC_INLINE uint32_t CY_SCB_SPI_GetSclkMode(cy_en_scb_spi_sub_mode_t subMode , cy_en_scb_spi_sclk_mode_t sclkMode)
{
switch (subMode)
{
case CY_SCB_SPI_TI_PRECEDES:
case CY_SCB_SPI_TI_COINCIDES:
return (uint32_t) CY_SCB_SPI_CPHA1_CPOL0;
case CY_SCB_SPI_NATIONAL:
return (uint32_t) CY_SCB_SPI_CPHA0_CPOL0;
case CY_SCB_SPI_MOTOROLA:
return (uint32_t) sclkMode;
default:
return (uint32_t) sclkMode;
}
}
/** \endcond */
/** \} group_scb_spi_interrupt_functions */
#if defined(__cplusplus)
}
#endif
/** \} group_scb_spi */
#endif /* (CY_SCB_SPI_H) */
/* [] END OF FILE */