Fire_RT1052_WHD/include/whd_port/hal/cyhal_spi.h

250 lines
9.8 KiB
C

/***************************************************************************//**
* \file cyhal_spi.h
*
* \brief
* Provides a high level interface for interacting with the Cypress SPI.
* This interface abstracts out the chip specific details. If any chip specific
* functionality is necessary, or performance is critical the low level functions
* can be used directly.
*
********************************************************************************
* \copyright
* Copyright 2018-2019 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_hal_spi SPI (Serial Peripheral Interface)
* \ingroup group_hal
* \{
* High level interface for interacting with the Cypress SPI.
*
* \defgroup group_hal_spi_macros Macros
* \defgroup group_hal_spi_functions Functions
* \defgroup group_hal_spi_data_structures Data Structures
* \defgroup group_hal_spi_enums Enumerated Types
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "cy_result.h"
#include "cyhal_hw_types.h"
#include "cyhal_modules.h"
#if defined(__cplusplus)
extern "C" {
#endif
/**
* \addtogroup group_hal_spi_macros
* \{
*/
/** Bad argument */
#define CYHAL_SPI_RSLT_BAD_ARGUMENT (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 0) )
/** Failed to initialize SPI clock */
#define CYHAL_SPI_RSLT_CLOCK_ERROR (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 1) )
/** Failed to Transfer SPI data */
#define CYHAL_SPI_RSLT_TRANSFER_ERROR (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 2) )
/** Provided clock is not supported by SPI */
#define CYHAL_SPI_RSLT_CLOCK_NOT_SUPPORTED (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 3) )
/** Provided PIN configuration is not supported by SPI */
#define CYHAL_SPI_RSLT_PIN_CONFIG_NOT_SUPPORTED (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 5) )
/** Provided PIN configuration is not supported by SPI */
#define CYHAL_SPI_RSLT_INVALID_PIN_API_NOT_SUPPORTED (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 6) )
/** The requested resource type is invalid */
#define CYHAL_SPI_RSLT_ERR_INVALID_PIN (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SPI, 7) )
/** \} group_hal_spi_macros */
/** SPI interrupt triggers */
typedef enum
{
CYHAL_SPI_IRQ_NONE = 0, //!< Disable all interrupt call backs
/** All transfer data has been moved into data FIFO */
CYHAL_SPI_IRQ_DATA_IN_FIFO = 1 << 1,
/** Transfer complete. */
CYHAL_SPI_IRQ_DONE = 1 << 2,
/** An error occurred while transferring data */
CYHAL_SPI_IRQ_ERROR = 1 << 3,
} cyhal_spi_irq_event_t;
/** Handler for SPI interrupts */
typedef void (*cyhal_spi_irq_handler_t)(void *handler_arg, cyhal_spi_irq_event_t event);
/** SPI operating modes */
typedef enum
{
/** Standard motorola SPI CPOL=0, CPHA=0 with MSB first operation */
CYHAL_SPI_MODE_00_MSB,
/** Standard motorola SPI CPOL=0, CPHA=0 with LSB first operation */
CYHAL_SPI_MODE_00_LSB,
/** Standard motorola SPI CPOL=0, CPHA=1 with MSB first operation */
CYHAL_SPI_MODE_01_MSB,
/** Standard motorola SPI CPOL=0, CPHA=1 with LSB first operation */
CYHAL_SPI_MODE_01_LSB,
/** Standard motorola SPI CPOL=1, CPHA=0 with MSB first operation */
CYHAL_SPI_MODE_10_MSB,
/** Standard motorola SPI CPOL=1, CPHA=0 with LSB first operation */
CYHAL_SPI_MODE_10_LSB,
/** Standard motorola SPI CPOL=1, CPHA=1 with MSB first operation */
CYHAL_SPI_MODE_11_MSB,
/** Standard motorola SPI CPOL=1, CPHA=1 with LSB first operation */
CYHAL_SPI_MODE_11_LSB,
} cyhal_spi_mode_t;
/** Initial SPI configuration. */
typedef struct
{
cyhal_spi_mode_t mode; //!< The operating mode
uint8_t data_bits; //!< The number of bits per transfer
bool is_slave; //!< Whether the peripheral is operating as slave or master
} cyhal_spi_cfg_t;
/** Initialize the SPI peripheral
*
* Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral
* @param[out] obj The SPI object to initialize
* @param[in] mosi The pin to use for MOSI
* @note At least MOSI or MISO pin should be non-NC
* @param[in] miso The pin to use for MISO
* @note At least MOSI or MISO pin should be non-NC
* @param[in] sclk The pin to use for SCLK
* @note This pin cannot be NC
* @param[in] ssel The pin to use for SSEL
* @note This pin can be NC
* @param[in] clk The clock to use can be shared, if not provided a new clock will be allocated
* @param[in] bits The number of bits per frame
* @note bits should be 8 or 16
* @param[in] mode The SPI mode (clock polarity, phase, and shift direction)
* @param[in] is_slave false for master mode or true for slave mode operation
* @return The status of the init request
*/
cy_rslt_t cyhal_spi_init(cyhal_spi_t *obj, cyhal_gpio_t mosi, cyhal_gpio_t miso, cyhal_gpio_t sclk, cyhal_gpio_t ssel,
const cyhal_clock_divider_t *clk,
uint8_t bits, cyhal_spi_mode_t mode, bool is_slave);
/** Release a SPI object
*
* Return the peripheral, pins and clock owned by the SPI object to their reset state
* @param[in,out] obj The SPI object to deinitialize
*/
void cyhal_spi_free(cyhal_spi_t *obj);
/** Set the SPI baud rate
*
* Actual frequency may differ from the desired frequency due to available dividers and bus clock
* Configures the SPI peripheral's baud rate
* @param[in,out] obj The SPI object to configure
* @param[in] hz The baud rate in Hz
* @return The status of the frequency request
*/
cy_rslt_t cyhal_spi_frequency(cyhal_spi_t *obj, uint32_t hz);
/** Get a received value out of the SPI receive buffer
*
* Blocks until a value is available
* @param[in] obj The SPI peripheral to read
* @param[in] value The value received
* @return The status of the read request
* @note
* - In Master mode, MISO pin required to be non-NC for this API to operate
* - In Slave mode, MOSI pin required to be non-NC for this API to operate
*/
cy_rslt_t cyhal_spi_read(cyhal_spi_t *obj, uint32_t *value);
/** Write a byte out
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] value The value to send
* @return The status of the write request
* @note
* - In Master mode, MOSI pin required to be non-NC for this API to operate
* - In Slave mode, MISO pin required to be non-NC for this API to operate
*/
cy_rslt_t cyhal_spi_write(cyhal_spi_t *obj, uint32_t value);
/** Write a block out and receive a value
*
* The total number of bytes sent and received will be the maximum of
* tx_length and rx_length. The bytes written will be padded with the
* value 0xff.
*
* @param[in] obj The SPI peripheral to use for sending
* @param[in] tx Pointer to the byte-array of data to write to the device
* @param[in,out] tx_length Number of bytes to write, updated with the number actually written
* @param[out] rx Pointer to the byte-array of data to read from the device
* @param[in,out] rx_length Number of bytes to read, udpated with the number actually read
* @param[in] write_fill Default data transmitted while performing a read
* @return The status of the transfer request
* @note Both MOSI and MISO pins required to be non-NC for this API to operate
*/
cy_rslt_t cyhal_spi_transfer(cyhal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length,
uint8_t write_fill);
/** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff
*
* @param[in] obj The SPI object that holds the transfer information
* @param[in] tx The transmit buffer
* @param[in,out] tx_length The number of bytes to transmit
* @param[out] rx The receive buffer
* @param[in,out] rx_length The number of bytes to receive
* @return The status of the transfer_async request
* @note Both MOSI and MISO pins required to be non-NC for this API to operate
*/
cy_rslt_t cyhal_spi_transfer_async(cyhal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx,
size_t rx_length);
/** Checks if the specified SPI peripheral is in use
*
* @param[in] obj The SPI peripheral to check
* @return Indication of whether the SPI is still transmitting
*/
bool cyhal_spi_is_busy(cyhal_spi_t *obj);
/** Abort an SPI transfer
*
* @param[in] obj The SPI peripheral to stop
* @return The status of the abort_async request
*/
cy_rslt_t cyhal_spi_abort_async(cyhal_spi_t *obj);
/** The SPI interrupt handler registration
*
* @param[in] obj The SPI object
* @param[in] handler The callback handler which will be invoked when the interrupt fires
* @param[in] handler_arg Generic argument that will be provided to the handler when called
*/
void cyhal_spi_register_irq(cyhal_spi_t *obj, cyhal_spi_irq_handler_t handler, void *handler_arg);
/** Configure SPI interrupt. This function is used for word-approach
*
* @param[in] obj The SPI object
* @param[in] event The SPI IRQ type
* @param[in] enable True to turn on interrupts, False to turn off
*/
void cyhal_spi_irq_enable(cyhal_spi_t *obj, cyhal_spi_irq_event_t event, bool enable);
/** \} group_hal_spi_functions */
#if defined(__cplusplus)
}
#endif