You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
394 lines
16 KiB
394 lines
16 KiB
/*
|
|
* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its
|
|
* contributors may be used to endorse or promote products derived from this
|
|
* software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef NRFX_TWIS_H__
|
|
#define NRFX_TWIS_H__
|
|
|
|
#include <nrfx.h>
|
|
#include <hal/nrf_twis.h>
|
|
#include <hal/nrf_gpio.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @defgroup nrfx_twis TWIS driver
|
|
* @{
|
|
* @ingroup nrf_twis
|
|
* @brief Two Wire Interface Slave with EasyDMA (TWIS) peripheral driver.
|
|
*/
|
|
|
|
/** @brief TWIS driver instance data structure. */
|
|
typedef struct
|
|
{
|
|
NRF_TWIS_Type * p_reg; ///< Pointer to a structure with TWIS registers.
|
|
uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
|
|
} nrfx_twis_t;
|
|
|
|
#ifndef __NRFX_DOXYGEN__
|
|
enum {
|
|
#if NRFX_CHECK(NRFX_TWIS0_ENABLED)
|
|
NRFX_TWIS0_INST_IDX,
|
|
#endif
|
|
#if NRFX_CHECK(NRFX_TWIS1_ENABLED)
|
|
NRFX_TWIS1_INST_IDX,
|
|
#endif
|
|
#if NRFX_CHECK(NRFX_TWIS2_ENABLED)
|
|
NRFX_TWIS2_INST_IDX,
|
|
#endif
|
|
#if NRFX_CHECK(NRFX_TWIS3_ENABLED)
|
|
NRFX_TWIS3_INST_IDX,
|
|
#endif
|
|
NRFX_TWIS_ENABLED_COUNT
|
|
};
|
|
#endif
|
|
|
|
/** @brief Macro for creating a TWIS driver instance. */
|
|
#define NRFX_TWIS_INSTANCE(id) \
|
|
{ \
|
|
.p_reg = NRFX_CONCAT_2(NRF_TWIS, id), \
|
|
.drv_inst_idx = NRFX_CONCAT_3(NRFX_TWIS, id, _INST_IDX), \
|
|
}
|
|
|
|
/** @brief Event callback function event definitions. */
|
|
typedef enum
|
|
{
|
|
NRFX_TWIS_EVT_READ_REQ, ///< Read request detected.
|
|
/**< If there is no buffer prepared, buf_req flag in the even will be set.
|
|
Call then @ref nrfx_twis_tx_prepare to give parameters for buffer.
|
|
*/
|
|
NRFX_TWIS_EVT_READ_DONE, ///< Read request finished - free any data.
|
|
NRFX_TWIS_EVT_READ_ERROR, ///< Read request finished with error.
|
|
NRFX_TWIS_EVT_WRITE_REQ, ///< Write request detected.
|
|
/**< If there is no buffer prepared, buf_req flag in the even will be set.
|
|
Call then @ref nrfx_twis_rx_prepare to give parameters for buffer.
|
|
*/
|
|
NRFX_TWIS_EVT_WRITE_DONE, ///< Write request finished - process data.
|
|
NRFX_TWIS_EVT_WRITE_ERROR, ///< Write request finished with error.
|
|
NRFX_TWIS_EVT_GENERAL_ERROR ///< Error that happens not inside WRITE or READ transaction.
|
|
} nrfx_twis_evt_type_t;
|
|
|
|
/**
|
|
* @brief Possible error sources.
|
|
*
|
|
* This is flag enum - values from this enum can be connected using logical or operator.
|
|
* @note
|
|
* You can use directly @ref nrf_twis_error_t. Error type enum is redefined here because
|
|
* of possible future extension (eg. supporting timeouts and synchronous mode).
|
|
*/
|
|
typedef enum
|
|
{
|
|
NRFX_TWIS_ERROR_OVERFLOW = NRF_TWIS_ERROR_OVERFLOW, /**< RX buffer overflow detected, and prevented. */
|
|
NRFX_TWIS_ERROR_DATA_NACK = NRF_TWIS_ERROR_DATA_NACK, /**< NACK sent after receiving a data byte. */
|
|
NRFX_TWIS_ERROR_OVERREAD = NRF_TWIS_ERROR_OVERREAD, /**< TX buffer over-read detected, and prevented. */
|
|
NRFX_TWIS_ERROR_UNEXPECTED_EVENT = 1 << 8 /**< Unexpected event detected by state machine. */
|
|
} nrfx_twis_error_t;
|
|
|
|
/** @brief TWIS driver event structure. */
|
|
typedef struct
|
|
{
|
|
nrfx_twis_evt_type_t type; ///< Event type.
|
|
union
|
|
{
|
|
bool buf_req; ///< Flag for @ref NRFX_TWIS_EVT_READ_REQ and @ref NRFX_TWIS_EVT_WRITE_REQ.
|
|
/**< Information if transmission buffer requires to be prepared. */
|
|
uint32_t tx_amount; ///< Data for @ref NRFX_TWIS_EVT_READ_DONE.
|
|
uint32_t rx_amount; ///< Data for @ref NRFX_TWIS_EVT_WRITE_DONE.
|
|
uint32_t error; ///< Data for @ref NRFX_TWIS_EVT_GENERAL_ERROR.
|
|
} data; ///< Union to store event data.
|
|
} nrfx_twis_evt_t;
|
|
|
|
/**
|
|
* @brief TWI slave event callback function type.
|
|
*
|
|
* @param[in] p_event Event information structure.
|
|
*/
|
|
typedef void (*nrfx_twis_event_handler_t)(nrfx_twis_evt_t const * p_event);
|
|
|
|
/** @brief Structure for TWIS configuration. */
|
|
typedef struct
|
|
{
|
|
uint32_t addr[2]; //!< Set addresses that this slave should respond. Set 0 to disable.
|
|
uint32_t scl; //!< SCL pin number.
|
|
uint32_t sda; //!< SDA pin number.
|
|
nrf_gpio_pin_pull_t scl_pull; //!< SCL pin pull.
|
|
nrf_gpio_pin_pull_t sda_pull; //!< SDA pin pull.
|
|
uint8_t interrupt_priority; //!< The priority of interrupt for the module to be set.
|
|
} nrfx_twis_config_t;
|
|
|
|
/** @brief Generate the default configuration for the TWIS driver instance. */
|
|
#define NRFX_TWIS_DEFAULT_CONFIG \
|
|
{ \
|
|
.addr = { NRFX_TWIS_DEFAULT_CONFIG_ADDR0, \
|
|
NRFX_TWIS_DEFAULT_CONFIG_ADDR1 }, \
|
|
.scl = 31, \
|
|
.sda = 31, \
|
|
.scl_pull = (nrf_gpio_pin_pull_t)NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL, \
|
|
.sda_pull = (nrf_gpio_pin_pull_t)NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL, \
|
|
.interrupt_priority = NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY \
|
|
}
|
|
|
|
/**
|
|
* @brief Function for initializing the TWIS driver instance.
|
|
*
|
|
* Function initializes and enables the TWIS driver.
|
|
* @attention After driver initialization enable it with @ref nrfx_twis_enable.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
* @attention @em p_instance has to be global object.
|
|
* It will be used by interrupts so make it sure that object
|
|
* is not destroyed when function is leaving.
|
|
* @param[in] p_config Pointer to the structure with the initial configuration.
|
|
* @param[in] event_handler Event handler provided by the user.
|
|
*
|
|
* @retval NRFX_SUCCESS Initialization is successful.
|
|
* @retval NRFX_ERROR_INVALID_STATE The driver is already initialized.
|
|
* @retval NRFX_ERROR_BUSY Some other peripheral with the same
|
|
* instance ID is already in use. This is
|
|
* possible only if NRFX_PRS_ENABLED
|
|
* is set to a value other than zero.
|
|
*/
|
|
nrfx_err_t nrfx_twis_init(nrfx_twis_t const * p_instance,
|
|
nrfx_twis_config_t const * p_config,
|
|
nrfx_twis_event_handler_t event_handler);
|
|
|
|
/**
|
|
* @brief Function for uninitializing the TWIS driver instance.
|
|
*
|
|
* Function uninitializes the peripheral and resets all registers to default values.
|
|
*
|
|
* @note
|
|
* It is safe to call nrfx_twis_uninit even before initialization.
|
|
* Actually, @ref nrfx_twis_init function calls this function to
|
|
* make sure that TWIS state is known.
|
|
* @note
|
|
* If TWIS driver was in uninitialized state before calling this function,
|
|
* the selected pins would not be reset to default configuration.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*/
|
|
void nrfx_twis_uninit(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for enabling the TWIS instance.
|
|
*
|
|
* This function enables the TWIS instance.
|
|
* Function defined if there is need for dynamically enabling and disabling the peripheral.
|
|
* Use @ref nrfx_twis_enable and @ref nrfx_twis_disable functions.
|
|
* They do not change any configuration registers.
|
|
*
|
|
* @param p_instance Pointer to the driver instance structure.
|
|
*/
|
|
void nrfx_twis_enable(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for disabling the TWIS instance.
|
|
*
|
|
* This function disables the TWIS instance, which gives possibility to turn off the TWIS while
|
|
* holding configuration done by @ref nrfx_twis_init.
|
|
*
|
|
* @param p_instance Pointer to the driver instance structure.
|
|
*/
|
|
void nrfx_twis_disable(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for getting and clearing the last error flags.
|
|
*
|
|
* This function gets the information about errors.
|
|
* This is also the only possibility to exit from the error substate of the internal state machine.
|
|
* @attention
|
|
* This function clears error state and flags.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*
|
|
* @return Error flags defined in @ref nrfx_twis_error_t.
|
|
*/
|
|
uint32_t nrfx_twis_error_get_and_clear(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for preparing the data for sending.
|
|
*
|
|
* This function is to be used in response to the @ref NRFX_TWIS_EVT_READ_REQ event.
|
|
*
|
|
* @note Peripherals using EasyDMA (including TWIS) require the transfer buffers
|
|
* to be placed in the Data RAM region. If this condition is not met,
|
|
* this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
|
|
* @attention Transmission buffer must be placed in RAM.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
* @param[in] p_buf Transmission buffer.
|
|
* @param[in] size Maximum number of bytes that master may read from buffer given.
|
|
*
|
|
* @retval NRFX_SUCCESS The preparation finished properly.
|
|
* @retval NRFX_ERROR_INVALID_ADDR The given @em p_buf is not placed inside the RAM.
|
|
* @retval NRFX_ERROR_INVALID_LENGTH There is a wrong value in the @em size parameter.
|
|
* @retval NRFX_ERROR_INVALID_STATE The module is not initialized or not enabled.
|
|
*/
|
|
nrfx_err_t nrfx_twis_tx_prepare(nrfx_twis_t const * p_instance,
|
|
void const * p_buf,
|
|
size_t size);
|
|
|
|
/**
|
|
* @brief Function for getting the number of transmitted bytes.
|
|
*
|
|
* This function returns the number of bytes sent.
|
|
* This function can be called after @ref NRFX_TWIS_EVT_READ_DONE or @ref NRFX_TWIS_EVT_READ_ERROR events.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*
|
|
* @return Number of bytes sent.
|
|
*/
|
|
__STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for preparing the data for receiving.
|
|
*
|
|
* This function must be used in response to the @ref NRFX_TWIS_EVT_WRITE_REQ event.
|
|
*
|
|
* @note Peripherals using EasyDMA (including TWIS) require the transfer buffers
|
|
* to be placed in the Data RAM region. If this condition is not met,
|
|
* this function fails with the error code NRFX_ERROR_INVALID_ADDR.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
* @param[in] p_buf Buffer that is to be filled with received data.
|
|
* @param[in] size Size of the buffer (maximum amount of data to receive).
|
|
*
|
|
* @retval NRFX_SUCCESS The preparation finished properly.
|
|
* @retval NRFX_ERROR_INVALID_ADDR The given @em p_buf is not placed inside the RAM.
|
|
* @retval NRFX_ERROR_INVALID_LENGTH There is a wrong value in the @em size parameter.
|
|
* @retval NRFX_ERROR_INVALID_STATE The module is not initialized or not enabled.
|
|
*/
|
|
nrfx_err_t nrfx_twis_rx_prepare(nrfx_twis_t const * p_instance,
|
|
void * p_buf,
|
|
size_t size);
|
|
|
|
/**
|
|
* @brief Function for getting the number of received bytes.
|
|
*
|
|
* This function returns number of bytes received.
|
|
* It can be called after @ref NRFX_TWIS_EVT_WRITE_DONE or @ref NRFX_TWIS_EVT_WRITE_ERROR events.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*
|
|
* @return Number of bytes received.
|
|
*/
|
|
__STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for checking if the driver is busy right now.
|
|
*
|
|
* This function tests the actual driver substate.
|
|
* If the driver is in any other state than IDLE or ERROR, this function returns true.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*
|
|
* @retval true The driver is in state other than ERROR or IDLE.
|
|
* @retval false There is no transmission pending.
|
|
*/
|
|
bool nrfx_twis_is_busy(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for checking if the driver is waiting for a TX buffer.
|
|
*
|
|
* If this function returns true, the driver is stalled expecting
|
|
* of the @ref nrfx_twis_tx_prepare function call.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*
|
|
* @retval true The driver is waiting for @ref nrfx_twis_tx_prepare.
|
|
* @retval false The driver is not in the state where it is waiting for preparing a TX buffer.
|
|
*/
|
|
bool nrfx_twis_is_waiting_tx_buff(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for checking if the driver is waiting for an RX buffer.
|
|
*
|
|
* If this function returns true, the driver is stalled expecting
|
|
* of the @ref nrfx_twis_rx_prepare function call.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*
|
|
* @retval true The driver is waiting for @ref nrfx_twis_rx_prepare.
|
|
* @retval false The driver is not in the state where it is waiting for preparing an RX buffer.
|
|
*/
|
|
bool nrfx_twis_is_waiting_rx_buff(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for checking if the driver is sending data.
|
|
*
|
|
* If this function returns true, there is an ongoing output transmission.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*
|
|
* @retval true There is an ongoing output transmission.
|
|
* @retval false The driver is in other state.
|
|
*/
|
|
bool nrfx_twis_is_pending_tx(nrfx_twis_t const * p_instance);
|
|
|
|
/**
|
|
* @brief Function for checking if the driver is receiving data.
|
|
*
|
|
* If this function returns true, there is an ongoing input transmission.
|
|
*
|
|
* @param[in] p_instance Pointer to the driver instance structure.
|
|
*
|
|
* @retval true There is an ongoing input transmission.
|
|
* @retval false The driver is in other state.
|
|
*/
|
|
bool nrfx_twis_is_pending_rx(nrfx_twis_t const * p_instance);
|
|
|
|
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
|
__STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance)
|
|
{
|
|
return nrf_twis_tx_amount_get(p_instance->p_reg);
|
|
}
|
|
|
|
__STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance)
|
|
{
|
|
return nrf_twis_rx_amount_get(p_instance->p_reg);
|
|
}
|
|
#endif // SUPPRESS_INLINE_IMPLEMENTATION
|
|
|
|
/** @} */
|
|
|
|
|
|
void nrfx_twis_0_irq_handler(void);
|
|
void nrfx_twis_1_irq_handler(void);
|
|
void nrfx_twis_2_irq_handler(void);
|
|
void nrfx_twis_3_irq_handler(void);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // NRFX_TWIS_H__
|
|
|