/***************************************************************************//** * \file cy_scb_spi.h * \version 3.10 * * Provides SPI API declarations of the SCB driver. * ******************************************************************************** * \copyright * Copyright 2016-2021 Cypress Semiconductor Corporation * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ /** * \addtogroup group_scb_spi * \{ * Driver API for SPI Peripheral. * * The functions and other declarations used in this part of the driver are in * cy_scb_spi.h. You can also include cy_pdl.h to get access * to all functions and declarations in the PDL. * * The SPI protocol is a synchronous serial interface protocol. Devices operate * in either master or slave mode. The master initiates the data transfer. * The SCB supports single-master-multiple-slaves topology for SPI. Multiple * slaves are supported with individual slave select lines. * * Features: * * Supports master and slave functionalitySupports three types of SPI protocols: * * Motorola SPI - modes 0, 1, 2, and 3 * * Texas Instruments SPI, with coinciding and preceding data frame indicator - mode 1 only * * National Semiconductor (MicroWire) SPI - mode 0 only * * Master supports up to four slave select lines * * Each slave select has configurable active polarity (high or low) * * Slave select can be programmed to stay active for a whole transfer, or * just for each byte * * Master supports late sampling for better timing margin * * Master supports continuous SPI clock * * Data frame size programmable from 4 bits to 32 bits * * Programmable oversampling * * MSb or LSb first * * Median filter available for inputs * ******************************************************************************** * \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 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 populated * \ref cy_stc_scb_spi_config_t structure and the allocated * \ref cy_stc_scb_spi_context_t structure. * * \snippet scb/spi_snippet/main.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 dedicated SCB SPI pins to the * SCB block. Also, the SPI output pins must be configured in Strong Drive Input * Off mode and SPI input pins in Digital High-Z. * * \snippet scb/spi_snippet/main.c SPI_CFG_PINS * ******************************************************************************** * \subsection group_scb_spi_clock Assign Clock Divider ******************************************************************************** * A clock source must be connected to the SCB block to oversample input and * output signals, in this document this clock will be referred as clk_scb. * You must use one of the 8-bit or 16-bit dividers. Use the \ref group_sysclk * driver API to do this. * * \snippet scb/spi_snippet/main.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 clk_scb must be * fast enough to provide sufficient oversampling. Use the \ref group_sysclk driver * API to do that. * * \snippet scb/spi_snippet/main.c SPI_CFG_DATA_RATE_SLAVE * * To get the SPI master to operate with the desired data rate, multiply the * oversample factor by the desired data rate to determine the required * frequency for clk_scb. Use the \ref group_sysclk driver API to configure * clk_scb frequency. Set the oversample parameter in configuration * structure 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/spi_snippet/main.c SPI_CFG_DATA_RATE_MASTER * * \note * In CAT1D devices, to avoid potential metastable conditions at 50 MHz, set * clock to 200 MHz, oversample to 4 and median filter to 1. * * 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. * The interrupt must be configured when \ref group_scb_spi_hl will be used. * * \snippet scb/spi_snippet/main.c SPI_INTR_A * \snippet scb/spi_snippet/main.c SPI_INTR_B * \snippet scb/spi_snippet/main.c SPI_INTR_C * ******************************************************************************** * \subsection group_scb_spi_enable Enable SPI ******************************************************************************** * Finally, enable the SPI operation by calling \ref Cy_SCB_SPI_Enable. * For the slave, this means that SPI device starts responding to the transfers. * For the master, it is ready to execute transfers. * * \snippet scb/spi_snippet/main.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 * Do not mix High-Level and Low-Level API because a Low-Level * API can adversely affect the operation of a High-Level API. * ******************************************************************************** * \subsection group_scb_spi_ll Low-Level API ******************************************************************************** * The \ref group_scb_spi_low_level_functions functions allow * interacting directly with the hardware and do not use \ref Cy_SCB_SPI_Interrupt. * These functions do not require context for operation. Thus, NULL can be * passed for context parameter 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 nature of SPI, 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. Again due to the nature * of SPI these functions do not start a transfer on the bus, they only read * data out of the RX FIFO that has already been received. * * * The statuses can be polled using: \ref Cy_SCB_SPI_GetRxFifoStatus, * \ref Cy_SCB_SPI_GetTxFifoStatus and \ref Cy_SCB_SPI_GetSlaveMasterStatus. * The statuses are W1C (Write 1 to Clear) and after a status * is set, it must be cleared. 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). * Also, the 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/spi_snippet/main.c SPI_TRANFER_DATA_LL * ******************************************************************************** * \subsection group_scb_spi_hl High-Level API ******************************************************************************** * The \ref group_scb_spi_high_level_functions API use \ref Cy_SCB_SPI_Interrupt * to execute the transfer. Call \ref Cy_SCB_SPI_Transfer to start communication: for master * mode calling this function starts a transaction with the slave. For slave mode * the read and write buffers are prepared for the communication with the master. * After a transfer is started, the \ref Cy_SCB_SPI_Interrupt handles the * transfer until its completion. Therefore, the \ref Cy_SCB_SPI_Interrupt function * 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/spi_snippet/main.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 is active while 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 * For example, the RX FIFO has 8 data elements and the RX FIFO level is 0. * The RX trigger signal is active until DMA reads all data from * the RX FIFO. * * * The TX trigger signal is active while 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 * For example, the TX FIFO has 0 data elements (empty) and the TX FIFO level * is 7. The TX trigger signal is active until DMA loads TX FIFO * with 8 data elements (note that after the first TX load operation, the data * element goes to the shift register and TX FIFO is empty). * * 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 callback functions to handle power mode transitions. * The callback \ref Cy_SCB_SPI_DeepSleepCallback must be called * during execution of \ref Cy_SysPm_CpuEnterDeepSleep; \ref Cy_SCB_SPI_HibernateCallback * must be called during execution of \ref Cy_SysPm_SystemEnterHibernate. 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 keep the inactive level (the same state * when SPI master is enabled and does not transfer data) before entering Deep * Sleep or Hibernate mode. To do that, write the GPIO data register of each pin * to the inactive level for each output pin. Then configure High-Speed Input * Output Multiplexer (HSIOM) of each pin to be controlled by the GPIO (use * \ref group_gpio driver API). After after exiting Deep Sleep mode the SPI * master must be enabled and the pins configuration restored to return the * SPI master control of the pins (after exiting Hibernate mode, the * system initialization code does the same). 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 rev-08 of the CY8CKIT-062-BLE. * 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. * * \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_device.h" #if (defined (CY_IP_MXSCB) || defined (CY_IP_MXS22SCB)) #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), /** * SPI is busy processing a transfer. */ 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_CPHA1_CPOL0 = 1U, /**< Clock is active low, data is changed on second edge */ CY_SCB_SPI_CPHA0_CPOL1 = 2U, /**< Clock is active high, data is changed on first 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; /** SPI Parity */ #if(((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB)) || defined (CY_DOXYGEN)) /** * \note * This enum is available for CAT1B and CAT1C devices. **/ typedef enum { CY_SCB_SPI_PARITY_NONE = 0U, /**< SPI has no parity check */ CY_SCB_SPI_PARITY_EVEN = 2U, /**< SPI has even parity check */ CY_SCB_SPI_PARITY_ODD = 3U, /**< SPI has odd parity check */ } cy_en_scb_spi_parity_t; #endif /* CY_IP_MXSCB_VERSION */ /** \} 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; #if(((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB)) || defined (CY_DOXYGEN)) /** Configures the SPI parity */ /** * \note * This parameter is available for CAT1B and CAT1C devices. **/ cy_en_scb_spi_parity_t parity; /** * Enables the hardware to drop data in the RX FIFO when a parity error is * detected */ /** * \note * This parameter is available for CAT1B and CAT1C devices. **/ bool dropOnParityError; #endif /* CY_IP_MXSCB_VERSION */ /** * Oversample factor for SPI. * * For the master mode, the data rate is the SCB clock / oversample * (the valid range is 4 to 16, when MISO is used; if MISO is not used * then the valid range is 2 to 16). * * For the slave mode, the oversample value is ignored. The data rate is * determined by the SCB clock frequency. */ uint32_t oversample; /** * The width of RX data (valid range 4-32). It must be the same as * \ref txDataWidth except in National sub-mode. */ uint32_t rxDataWidth; /** * The width of TX data (valid range 4-32). 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; #if(((defined (CY_IP_MXSCB_VERSION) && (CY_IP_MXSCB_VERSION>=2)) || defined (CY_IP_MXS22SCB)) || defined (CY_DOXYGEN)) /** * Indicates the SPI SELECT setup delay (between SELECT activation and SPI clock). * '0': With this setting the same timing is generated as in SCB v1 block. * 0.75 SPI clock cycles * '1': With this setting an additional delay of 1 SPI clock cycle is generated. * 1.75 SPI clock cycles * Only applies in SPI MOTOROLA submode, when SCLK_CONTINUOUS=0 and oversampling factor>2. */ /** * \note * This parameter is available for CAT1B and CAT1C devices. **/ bool ssSetupDelay; /** * Indicates the SPI SELECT hold delay (between SPI clock and SELECT deactivation). * '0': With this setting the same timing is generated as in CAT1A devices. * 0.75 SPI clock cycles * '1': With this setting an additional delay of 1 SPI clock cycle is generated. * 1.75 SPI clock cycles * Only applies in SPI MOTOROLA submode, when SCLK_CONTINUOUS=0 and oversampling factor>2. */ /** * \note * This parameter is available for CAT1B and CAT1C devices. **/ bool ssHoldDelay; /** * Indicates the SPI SELECT inter-dataframe delay (between SELECT deactivation and SELECT activation). * '0': With this setting the same timing is generated as in CAT1A devices. * 1.5 SPI clock cycles * '1': With this setting an additional delay of 1 SPI clock cycle is generated. * 2.5 SPI clock cycles * Only applies in SPI MOTOROLA submode, when SCLK_CONTINUOUS=0 and oversampling factor>2. */ /** * \note * This parameter is available for CAT1B and CAT1C devices. **/ bool ssInterFrameDelay; #endif /* CY_IP_MXSCB_VERSION */ /** * 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 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 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_callback_mode_t mode); cy_en_syspm_status_t Cy_SCB_SPI_HibernateCallback(cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode); /** \} 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 * Macros to check SPI TX FIFO status returned by \ref Cy_SCB_SPI_GetTxFifoStatus * function or assign mask for \ref Cy_SCB_SPI_ClearTxFifoStatus function. * 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 * \{ * Macros to check SPI RX FIFO status returned by \ref Cy_SCB_SPI_GetRxFifoStatus * function or assign mask for \ref Cy_SCB_SPI_ClearRxFifoStatus function. * 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 * \{ * Macros to check SPI Mater and Slave status returned by \ref Cy_SCB_SPI_GetSlaveMasterStatus * function or assign mask for \ref Cy_SCB_SPI_ClearSlaveMasterStatus function. */ /** 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 * \{ * Macros to check current SPI transfer status returned by * \ref Cy_SCB_SPI_GetTransferStatus function. * 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 * \{ * Macros to check SPI events passed by \ref cy_cb_scb_spi_handle_events_t callback. * Note that only single event is notified by the callback when it is called. */ /** * 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) <= 32UL) ) #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) { SCB_CTRL(base) |= 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 the moment of the initial * pulse on the slave select line and lasts until the transfer is complete * (all bytes from the TX FIFO area shifted-out on the bus). * * \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 transmit each data element separated by * a de-assertion of the slave select line, 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, SCB_SPI_STATUS(base)); } /******************************************************************************* * 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 must 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)); CY_REG32_CLR_SET(SCB_SPI_CTRL(base), 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 must 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) { uint32_t mask = _VAL2FLD(CY_SCB_SPI_CTRL_SSEL_POLARITY, (0x01UL << ((uint32_t)slaveSelect))); CY_ASSERT_L3(CY_SCB_SPI_IS_SLAVE_SEL_VALID(slaveSelect)); CY_ASSERT_L3(CY_SCB_SPI_IS_POLARITY_VALID (polarity)); if (CY_SCB_SPI_ACTIVE_HIGH == polarity) { SCB_SPI_CTRL(base) |= (uint32_t) mask; } else { SCB_SPI_CTRL(base) &= (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. * * \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. * * \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; * 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. * * \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, SCB_SPI_CTRL(base))) { 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, SCB_SPI_CTRL(base))) { 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, this function writes data into the TX FIFO and * waits until the transfer is completed before reading 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 element 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, this function writes data into the TX FIFO and * waits until the transfer is completed before reading 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 element 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 element 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 element 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. * * To get the event notification, the corresponding interrupt mask needs to be * set in the interrupt mask register so that interrupt request register can * trigger an interrupt event in \ref Cy_SCB_SPI_Interrupt. * *******************************************************************************/ __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) { uint32_t retVal; switch (subMode) { case CY_SCB_SPI_TI_PRECEDES: case CY_SCB_SPI_TI_COINCIDES: retVal = (uint32_t) CY_SCB_SPI_CPHA1_CPOL0; break; case CY_SCB_SPI_NATIONAL: retVal = (uint32_t) CY_SCB_SPI_CPHA0_CPOL0; break; case CY_SCB_SPI_MOTOROLA: retVal = (uint32_t) sclkMode; break; default: retVal = (uint32_t) sclkMode; break; } return retVal; } /** \endcond */ /** \} group_scb_spi_interrupt_functions */ #if defined(__cplusplus) } #endif /** \} group_scb_spi */ #endif /* (defined (CY_IP_MXSCB) || defined (CY_IP_MXS22SCB)) */ #endif /* (CY_SCB_SPI_H) */ /* [] END OF FILE */