| /***************************************************************************//** |
| * \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 */ |
| |