mirror of
https://github.com/jam422470459/EPD-nRF52-hema213.git
synced 2025-12-19 06:43:20 +08:00
move components to SDK dir
This commit is contained in:
@@ -0,0 +1,444 @@
|
||||
/**
|
||||
* Copyright (c) 2013 - 2017, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sdk_common.h"
|
||||
#if NRF_MODULE_ENABLED(SPIS)
|
||||
#define ENABLED_SPIS_COUNT (SPIS0_ENABLED+SPIS1_ENABLED+SPIS2_ENABLED)
|
||||
#if ENABLED_SPIS_COUNT
|
||||
#include "nrf_drv_spis.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "app_error.h"
|
||||
#include "app_util_platform.h"
|
||||
#include "nrf_drv_common.h"
|
||||
#include "nrf_assert.h"
|
||||
|
||||
#define NRF_LOG_MODULE_NAME "SPIS"
|
||||
|
||||
#if SPIS_CONFIG_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL SPIS_CONFIG_LOG_LEVEL
|
||||
#define NRF_LOG_INFO_COLOR SPIS_CONFIG_INFO_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR SPIS_CONFIG_DEBUG_COLOR
|
||||
#define EVT_TO_STR(event) (event == NRF_SPIS_EVENT_ACQUIRED ? "NRF_SPIS_EVENT_ACQUIRED" : \
|
||||
(event == NRF_SPIS_EVENT_END ? "NRF_SPIS_EVENT_END" : "UNKNOWN ERROR"))
|
||||
|
||||
#else //SPIS_CONFIG_LOG_ENABLED
|
||||
#define EVT_TO_STR(event) ""
|
||||
#define NRF_LOG_LEVEL 0
|
||||
#endif //SPIS_CONFIG_LOG_ENABLED
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
|
||||
|
||||
/**@brief States of the SPI transaction state machine. */
|
||||
typedef enum
|
||||
{
|
||||
SPIS_STATE_INIT, /**< Initialization state. In this state the module waits for a call to @ref spi_slave_buffers_set. */
|
||||
SPIS_BUFFER_RESOURCE_REQUESTED, /**< State where the configuration of the memory buffers, which are to be used in SPI transaction, has started. */
|
||||
SPIS_BUFFER_RESOURCE_CONFIGURED, /**< State where the configuration of the memory buffers, which are to be used in SPI transaction, has completed. */
|
||||
SPIS_XFER_COMPLETED /**< State where SPI transaction has been completed. */
|
||||
} nrf_drv_spis_state_t;
|
||||
|
||||
|
||||
#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
|
||||
#define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n
|
||||
#define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void)
|
||||
|
||||
#if NRF_MODULE_ENABLED(SPIS0)
|
||||
IRQ_HANDLER(0);
|
||||
#endif
|
||||
#if NRF_MODULE_ENABLED(SPIS1)
|
||||
IRQ_HANDLER(1);
|
||||
#endif
|
||||
#if NRF_MODULE_ENABLED(SPIS2)
|
||||
IRQ_HANDLER(2);
|
||||
#endif
|
||||
static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_SPIS_COUNT] = {
|
||||
#if NRF_MODULE_ENABLED(SPIS0)
|
||||
IRQ_HANDLER_NAME(0),
|
||||
#endif
|
||||
#if NRF_MODULE_ENABLED(SPIS1)
|
||||
IRQ_HANDLER_NAME(1),
|
||||
#endif
|
||||
#if NRF_MODULE_ENABLED(SPIS2)
|
||||
IRQ_HANDLER_NAME(2),
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
#define IRQ_HANDLER(n) void SPIS##n##_IRQ_HANDLER(void)
|
||||
#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
|
||||
#define SPIS_IRQHANDLER_TEMPLATE(NUM) \
|
||||
IRQ_HANDLER(NUM) \
|
||||
{ \
|
||||
spis_irq_handler(NRF_SPIS##NUM, &m_cb[SPIS##NUM##_INSTANCE_INDEX]); \
|
||||
}
|
||||
|
||||
|
||||
/**@brief SPIS control block - driver instance local data. */
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t tx_buffer_size; //!< SPI slave TX buffer size in bytes.
|
||||
volatile uint32_t rx_buffer_size; //!< SPI slave RX buffer size in bytes.
|
||||
nrf_drv_spis_event_handler_t handler; //!< SPI event handler.
|
||||
volatile const uint8_t * tx_buffer; //!< SPI slave TX buffer.
|
||||
volatile uint8_t * rx_buffer; //!< SPI slave RX buffer.
|
||||
nrf_drv_state_t state; //!< driver initialization state.
|
||||
volatile nrf_drv_spis_state_t spi_state; //!< SPI slave state.
|
||||
} spis_cb_t;
|
||||
|
||||
static spis_cb_t m_cb[ENABLED_SPIS_COUNT];
|
||||
|
||||
ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance,
|
||||
nrf_drv_spis_config_t const * p_config,
|
||||
nrf_drv_spis_event_handler_t event_handler)
|
||||
{
|
||||
ASSERT(p_config);
|
||||
spis_cb_t * p_cb = &m_cb[p_instance->instance_id];
|
||||
ret_code_t err_code;
|
||||
|
||||
NRF_SPIS_Type * p_spis = p_instance->p_reg;
|
||||
|
||||
if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
|
||||
return err_code;
|
||||
}
|
||||
|
||||
if ((uint32_t)p_config->mode > (uint32_t)NRF_DRV_SPIS_MODE_3)
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_PARAM;
|
||||
NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
|
||||
return err_code;
|
||||
}
|
||||
if (!event_handler)
|
||||
{
|
||||
err_code = NRF_ERROR_NULL;
|
||||
NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
|
||||
return err_code;
|
||||
}
|
||||
#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
|
||||
if (nrf_drv_common_per_res_acquire(p_spis,
|
||||
m_irq_handlers[p_instance->instance_id]) != NRF_SUCCESS)
|
||||
{
|
||||
err_code = NRF_ERROR_BUSY;
|
||||
NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
|
||||
return err_code;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Configure the SPI pins for input.
|
||||
uint32_t mosi_pin;
|
||||
uint32_t miso_pin;
|
||||
|
||||
if (p_config->miso_pin != NRF_DRV_SPIS_PIN_NOT_USED)
|
||||
{
|
||||
nrf_gpio_cfg(p_config->miso_pin,
|
||||
NRF_GPIO_PIN_DIR_INPUT,
|
||||
NRF_GPIO_PIN_INPUT_CONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
p_config->miso_drive,
|
||||
NRF_GPIO_PIN_NOSENSE);
|
||||
miso_pin = p_config->miso_pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
miso_pin = NRF_SPIS_PIN_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
if (p_config->mosi_pin != NRF_DRV_SPIS_PIN_NOT_USED)
|
||||
{
|
||||
nrf_gpio_cfg(p_config->mosi_pin,
|
||||
NRF_GPIO_PIN_DIR_INPUT,
|
||||
NRF_GPIO_PIN_INPUT_CONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
NRF_GPIO_PIN_S0S1,
|
||||
NRF_GPIO_PIN_NOSENSE);
|
||||
mosi_pin = p_config->mosi_pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
mosi_pin = NRF_SPIS_PIN_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
nrf_gpio_cfg(p_config->csn_pin,
|
||||
NRF_GPIO_PIN_DIR_INPUT,
|
||||
NRF_GPIO_PIN_INPUT_CONNECT,
|
||||
p_config->csn_pullup,
|
||||
NRF_GPIO_PIN_S0S1,
|
||||
NRF_GPIO_PIN_NOSENSE);
|
||||
|
||||
nrf_gpio_cfg(p_config->sck_pin,
|
||||
NRF_GPIO_PIN_DIR_INPUT,
|
||||
NRF_GPIO_PIN_INPUT_CONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
NRF_GPIO_PIN_S0S1,
|
||||
NRF_GPIO_PIN_NOSENSE);
|
||||
|
||||
nrf_spis_pins_set(p_spis, p_config->sck_pin, mosi_pin, miso_pin, p_config->csn_pin);
|
||||
|
||||
nrf_spis_rx_buffer_set(p_spis, NULL, 0);
|
||||
nrf_spis_tx_buffer_set(p_spis, NULL, 0);
|
||||
|
||||
// Configure SPI mode.
|
||||
nrf_spis_configure(p_spis, (nrf_spis_mode_t) p_config->mode,
|
||||
(nrf_spis_bit_order_t) p_config->bit_order);
|
||||
|
||||
// Configure DEF and ORC characters.
|
||||
nrf_spis_def_set(p_spis, p_config->def);
|
||||
nrf_spis_orc_set(p_spis, p_config->orc);
|
||||
|
||||
// Clear possible pending events.
|
||||
nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END);
|
||||
nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED);
|
||||
|
||||
// Enable END_ACQUIRE shortcut.
|
||||
nrf_spis_shorts_enable(p_spis, NRF_SPIS_SHORT_END_ACQUIRE);
|
||||
|
||||
m_cb[p_instance->instance_id].spi_state = SPIS_STATE_INIT;
|
||||
m_cb[p_instance->instance_id].handler = event_handler;
|
||||
|
||||
|
||||
// Enable IRQ.
|
||||
nrf_spis_int_enable(p_spis, NRF_SPIS_INT_ACQUIRED_MASK | NRF_SPIS_INT_END_MASK);
|
||||
nrf_drv_common_irq_enable(p_instance->irq, p_config->irq_priority);
|
||||
|
||||
p_cb->state = NRF_DRV_STATE_INITIALIZED;
|
||||
|
||||
// Enable SPI slave device.
|
||||
nrf_spis_enable(p_spis);
|
||||
|
||||
err_code = NRF_SUCCESS;
|
||||
NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
void nrf_drv_spis_uninit(nrf_drv_spis_t const * const p_instance)
|
||||
{
|
||||
spis_cb_t * p_cb = &m_cb[p_instance->instance_id];
|
||||
ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED);
|
||||
|
||||
NRF_SPIS_Type * p_spis = p_instance->p_reg;
|
||||
|
||||
#define DISABLE_ALL 0xFFFFFFFF
|
||||
nrf_spis_disable(p_spis);
|
||||
nrf_drv_common_irq_disable(p_instance->irq);
|
||||
nrf_spis_int_disable(p_spis, DISABLE_ALL);
|
||||
#undef DISABLE_ALL
|
||||
|
||||
#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING)
|
||||
nrf_drv_common_per_res_release(p_spis);
|
||||
#endif
|
||||
|
||||
p_cb->state = NRF_DRV_STATE_UNINITIALIZED;
|
||||
NRF_LOG_INFO("Initialized.\r\n");
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function for executing the state entry action. */
|
||||
static void spis_state_entry_action_execute(NRF_SPIS_Type * p_spis,
|
||||
spis_cb_t * p_cb)
|
||||
{
|
||||
nrf_drv_spis_event_t event;
|
||||
|
||||
switch (p_cb->spi_state)
|
||||
{
|
||||
case SPIS_BUFFER_RESOURCE_REQUESTED:
|
||||
nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_ACQUIRE);
|
||||
break;
|
||||
|
||||
case SPIS_BUFFER_RESOURCE_CONFIGURED:
|
||||
event.evt_type = NRF_DRV_SPIS_BUFFERS_SET_DONE;
|
||||
event.rx_amount = 0;
|
||||
event.tx_amount = 0;
|
||||
|
||||
APP_ERROR_CHECK_BOOL(p_cb->handler != NULL);
|
||||
p_cb->handler(event);
|
||||
break;
|
||||
|
||||
case SPIS_XFER_COMPLETED:
|
||||
event.evt_type = NRF_DRV_SPIS_XFER_DONE;
|
||||
event.rx_amount = nrf_spis_rx_amount_get(p_spis);
|
||||
event.tx_amount = nrf_spis_tx_amount_get(p_spis);
|
||||
NRF_LOG_INFO("Transfer rx_len:%d.\r\n", event.rx_amount);
|
||||
NRF_LOG_DEBUG("Rx data:\r\n");
|
||||
NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->rx_buffer, event.rx_amount * sizeof(p_cb->rx_buffer));
|
||||
APP_ERROR_CHECK_BOOL(p_cb->handler != NULL);
|
||||
p_cb->handler(event);
|
||||
break;
|
||||
|
||||
default:
|
||||
// No implementation required.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**@brief Function for changing the state of the SPI state machine.
|
||||
*
|
||||
* @param[in] p_spis SPIS instance register.
|
||||
* @param[in] p_cb SPIS instance control block.
|
||||
* @param[in] new_state State where the state machine transits to.
|
||||
*/
|
||||
static void spis_state_change(NRF_SPIS_Type * p_spis,
|
||||
spis_cb_t * p_cb,
|
||||
nrf_drv_spis_state_t new_state)
|
||||
{
|
||||
p_cb->spi_state = new_state;
|
||||
spis_state_entry_action_execute(p_spis, p_cb);
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf_drv_spis_buffers_set(nrf_drv_spis_t const * const p_instance,
|
||||
const uint8_t * p_tx_buffer,
|
||||
uint8_t tx_buffer_length,
|
||||
uint8_t * p_rx_buffer,
|
||||
uint8_t rx_buffer_length)
|
||||
{
|
||||
spis_cb_t * p_cb = &m_cb[p_instance->instance_id];
|
||||
uint32_t err_code;
|
||||
|
||||
VERIFY_PARAM_NOT_NULL(p_rx_buffer);
|
||||
VERIFY_PARAM_NOT_NULL(p_tx_buffer);
|
||||
|
||||
// EasyDMA requires that transfer buffers are placed in Data RAM region;
|
||||
// signal error if they are not.
|
||||
if ((p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_tx_buffer)) ||
|
||||
(p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_rx_buffer)))
|
||||
{
|
||||
err_code = NRF_ERROR_INVALID_ADDR;
|
||||
NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
|
||||
return err_code;
|
||||
}
|
||||
|
||||
switch (p_cb->spi_state)
|
||||
{
|
||||
case SPIS_STATE_INIT:
|
||||
case SPIS_XFER_COMPLETED:
|
||||
case SPIS_BUFFER_RESOURCE_CONFIGURED:
|
||||
p_cb->tx_buffer = p_tx_buffer;
|
||||
p_cb->rx_buffer = p_rx_buffer;
|
||||
p_cb->tx_buffer_size = tx_buffer_length;
|
||||
p_cb->rx_buffer_size = rx_buffer_length;
|
||||
err_code = NRF_SUCCESS;
|
||||
|
||||
spis_state_change(p_instance->p_reg, p_cb, SPIS_BUFFER_RESOURCE_REQUESTED);
|
||||
break;
|
||||
|
||||
case SPIS_BUFFER_RESOURCE_REQUESTED:
|
||||
err_code = NRF_ERROR_INVALID_STATE;
|
||||
break;
|
||||
|
||||
default:
|
||||
// @note: execution of this code path would imply internal error in the design.
|
||||
err_code = NRF_ERROR_INTERNAL;
|
||||
break;
|
||||
}
|
||||
|
||||
NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code));
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static void spis_irq_handler(NRF_SPIS_Type * p_spis, spis_cb_t * p_cb)
|
||||
{
|
||||
// @note: as multiple events can be pending for processing, the correct event processing order
|
||||
// is as follows:
|
||||
// - SPI semaphore acquired event.
|
||||
// - SPI transaction complete event.
|
||||
|
||||
// Check for SPI semaphore acquired event.
|
||||
if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_ACQUIRED))
|
||||
{
|
||||
nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED);
|
||||
NRF_LOG_DEBUG("SPIS: Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SPIS_EVENT_ACQUIRED));
|
||||
|
||||
switch (p_cb->spi_state)
|
||||
{
|
||||
case SPIS_BUFFER_RESOURCE_REQUESTED:
|
||||
nrf_spis_tx_buffer_set(p_spis, (uint8_t *)p_cb->tx_buffer, p_cb->tx_buffer_size);
|
||||
nrf_spis_rx_buffer_set(p_spis, (uint8_t *)p_cb->rx_buffer, p_cb->rx_buffer_size);
|
||||
|
||||
nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_RELEASE);
|
||||
|
||||
spis_state_change(p_spis, p_cb, SPIS_BUFFER_RESOURCE_CONFIGURED);
|
||||
break;
|
||||
|
||||
default:
|
||||
// No implementation required.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for SPI transaction complete event.
|
||||
if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_END))
|
||||
{
|
||||
nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END);
|
||||
NRF_LOG_DEBUG("SPIS: Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SPIS_EVENT_END));
|
||||
|
||||
switch (p_cb->spi_state)
|
||||
{
|
||||
case SPIS_BUFFER_RESOURCE_CONFIGURED:
|
||||
spis_state_change(p_spis, p_cb, SPIS_XFER_COMPLETED);
|
||||
break;
|
||||
|
||||
default:
|
||||
// No implementation required.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if NRF_MODULE_ENABLED(SPIS0)
|
||||
SPIS_IRQHANDLER_TEMPLATE(0)
|
||||
#endif
|
||||
|
||||
#if NRF_MODULE_ENABLED(SPIS1)
|
||||
SPIS_IRQHANDLER_TEMPLATE(1)
|
||||
#endif
|
||||
|
||||
#if NRF_MODULE_ENABLED(SPIS2)
|
||||
SPIS_IRQHANDLER_TEMPLATE(2)
|
||||
#endif
|
||||
|
||||
#endif // SPI_COUNT > 0
|
||||
#endif // NRF_MODULE_ENABLED(SPIS)
|
||||
@@ -0,0 +1,258 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2017, 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, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, 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 Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**@file
|
||||
* @addtogroup nrf_spis SPIS HAL and driver
|
||||
* @ingroup nrf_drivers
|
||||
* @brief SPIS APIs.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SPI_SLAVE_H__
|
||||
#define SPI_SLAVE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf_error.h"
|
||||
#include "sdk_config.h"
|
||||
#include "nrf_spis.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "sdk_common.h"
|
||||
#include "app_util_platform.h"
|
||||
#include "nrf_peripherals.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define SPIS0_IRQ SPI0_TWI0_IRQn
|
||||
#define SPIS0_IRQ_HANDLER SPI0_TWI0_IRQHandler
|
||||
#define SPIS1_IRQ SPI1_TWI1_IRQn
|
||||
#define SPIS1_IRQ_HANDLER SPI1_TWI1_IRQHandler
|
||||
|
||||
#if SPIS_COUNT > 2
|
||||
#define SPIS2_IRQ SPIM2_SPIS2_SPI2_IRQn
|
||||
#define SPIS2_IRQ_HANDLER SPIM2_SPIS2_SPI2_IRQHandler
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup nrf_drv_spis SPI slave driver
|
||||
* @{
|
||||
* @ingroup nrf_spis
|
||||
* @brief Multi-instance SPI slave driver.
|
||||
*/
|
||||
|
||||
#define NRF_DRV_SPIS_DEFAULT_CSN_PULLUP NRF_GPIO_PIN_NOPULL /**< Default pull-up configuration of the SPI CS. */
|
||||
#define NRF_DRV_SPIS_DEFAULT_MISO_DRIVE NRF_GPIO_PIN_S0S1 /**< Default drive configuration of the SPI MISO. */
|
||||
|
||||
/**
|
||||
* @brief This value can be provided instead of a pin number for the signals MOSI
|
||||
* and MISO to specify that the given signal is not used and therefore
|
||||
* does not need to be connected to a pin.
|
||||
*/
|
||||
#define NRF_DRV_SPIS_PIN_NOT_USED 0xFF
|
||||
|
||||
/** @brief SPIS transaction bit order definitions. */
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST = NRF_SPIS_BIT_ORDER_LSB_FIRST, /**< Least significant bit shifted out first. */
|
||||
NRF_DRV_SPIS_BIT_ORDER_MSB_FIRST = NRF_SPIS_BIT_ORDER_MSB_FIRST /**< Most significant bit shifted out first. */
|
||||
} nrf_drv_spis_endian_t;
|
||||
|
||||
/** @brief SPIS mode definitions for clock polarity and phase. */
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_SPIS_MODE_0 = NRF_SPIS_MODE_0, /**< (CPOL = 0, CPHA = 0). */
|
||||
NRF_DRV_SPIS_MODE_1 = NRF_SPIS_MODE_1, /**< (CPOL = 0, CPHA = 1). */
|
||||
NRF_DRV_SPIS_MODE_2 = NRF_SPIS_MODE_2, /**< (CPOL = 1, CPHA = 0). */
|
||||
NRF_DRV_SPIS_MODE_3 = NRF_SPIS_MODE_3 /**< (CPOL = 1, CPHA = 1). */
|
||||
} nrf_drv_spis_mode_t;
|
||||
|
||||
/** @brief Event callback function event definitions. */
|
||||
typedef enum
|
||||
{
|
||||
NRF_DRV_SPIS_BUFFERS_SET_DONE, /**< Memory buffer set event. Memory buffers have been set successfully to the SPI slave device, and SPI transactions can be done. */
|
||||
NRF_DRV_SPIS_XFER_DONE, /**< SPI transaction event. SPI transaction has been completed. */
|
||||
NRF_DRV_SPIS_EVT_TYPE_MAX /**< Enumeration upper bound. */
|
||||
} nrf_drv_spis_event_type_t;
|
||||
|
||||
/** @brief Structure containing the event context from the SPI slave driver. */
|
||||
typedef struct
|
||||
{
|
||||
nrf_drv_spis_event_type_t evt_type; //!< Type of event.
|
||||
uint32_t rx_amount; //!< Number of bytes received in last transaction. This parameter is only valid for @ref NRF_DRV_SPIS_XFER_DONE events.
|
||||
uint32_t tx_amount; //!< Number of bytes transmitted in last transaction. This parameter is only valid for @ref NRF_DRV_SPIS_XFER_DONE events.
|
||||
} nrf_drv_spis_event_t;
|
||||
|
||||
/** @brief SPI slave driver instance data structure. */
|
||||
typedef struct
|
||||
{
|
||||
NRF_SPIS_Type * p_reg; //!< SPIS instance register.
|
||||
uint8_t instance_id; //!< SPIS instance ID.
|
||||
IRQn_Type irq; //!< IRQ of the specific instance.
|
||||
} nrf_drv_spis_t;
|
||||
|
||||
#define SPIS0_INSTANCE_INDEX 0
|
||||
#define SPIS1_INSTANCE_INDEX SPIS0_INSTANCE_INDEX+SPIS0_ENABLED
|
||||
#define SPIS2_INSTANCE_INDEX SPIS1_INSTANCE_INDEX+SPIS1_ENABLED
|
||||
|
||||
/** @brief Macro for creating an SPI slave driver instance. */
|
||||
#define NRF_DRV_SPIS_INSTANCE(id) \
|
||||
{ \
|
||||
.p_reg = CONCAT_2(NRF_SPIS, id), \
|
||||
.irq = CONCAT_3(SPIS, id, _IRQ), \
|
||||
.instance_id = CONCAT_3(SPIS, id, _INSTANCE_INDEX), \
|
||||
}
|
||||
|
||||
/** @brief SPI slave instance default configuration. */
|
||||
#define NRF_DRV_SPIS_DEFAULT_CONFIG \
|
||||
{ \
|
||||
.sck_pin = NRF_DRV_SPIS_PIN_NOT_USED, \
|
||||
.mosi_pin = NRF_DRV_SPIS_PIN_NOT_USED, \
|
||||
.miso_pin = NRF_DRV_SPIS_PIN_NOT_USED, \
|
||||
.csn_pin = NRF_DRV_SPIS_PIN_NOT_USED, \
|
||||
.miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE, \
|
||||
.csn_pullup = NRF_DRV_SPIS_DEFAULT_CSN_PULLUP, \
|
||||
.orc = SPIS_DEFAULT_ORC, \
|
||||
.def = SPIS_DEFAULT_DEF, \
|
||||
.mode = (nrf_drv_spis_mode_t)SPIS_DEFAULT_MODE, \
|
||||
.bit_order = (nrf_drv_spis_endian_t)SPIS_DEFAULT_BIT_ORDER, \
|
||||
.irq_priority = SPIS_DEFAULT_CONFIG_IRQ_PRIORITY, \
|
||||
}
|
||||
|
||||
/** @brief SPI peripheral device configuration data. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t miso_pin; //!< SPI MISO pin (optional).
|
||||
/**< Set @ref NRF_DRV_SPIS_PIN_NOT_USED
|
||||
* if this signal is not needed. */
|
||||
uint32_t mosi_pin; //!< SPI MOSI pin (optional).
|
||||
/**< Set @ref NRF_DRV_SPIS_PIN_NOT_USED
|
||||
* if this signal is not needed. */
|
||||
uint32_t sck_pin; //!< SPI SCK pin.
|
||||
uint32_t csn_pin; //!< SPI CSN pin.
|
||||
nrf_drv_spis_mode_t mode; //!< SPI mode.
|
||||
nrf_drv_spis_endian_t bit_order; //!< SPI transaction bit order.
|
||||
nrf_gpio_pin_pull_t csn_pullup; //!< CSN pin pull-up configuration.
|
||||
nrf_gpio_pin_drive_t miso_drive; //!< MISO pin drive configuration.
|
||||
uint8_t def; //!< Character clocked out in case of an ignored transaction.
|
||||
uint8_t orc; //!< Character clocked out after an over-read of the transmit buffer.
|
||||
uint8_t irq_priority; //!< Interrupt priority.
|
||||
} nrf_drv_spis_config_t;
|
||||
|
||||
|
||||
/** @brief SPI slave event callback function type.
|
||||
*
|
||||
* @param[in] event SPI slave driver event.
|
||||
*/
|
||||
typedef void (*nrf_drv_spis_event_handler_t)(nrf_drv_spis_event_t event);
|
||||
|
||||
/** @brief Function for initializing the SPI slave driver instance.
|
||||
*
|
||||
* @param[in] p_instance Pointer to the driver instance structure.
|
||||
* @param[in] p_config Pointer to the structure with the initial configuration.
|
||||
* If NULL, the default configuration will be used.
|
||||
* @param[in] event_handler Function to be called by the SPI slave driver upon event.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the initialization was successful.
|
||||
* @retval NRF_ERROR_INVALID_PARAM If an invalid parameter is supplied.
|
||||
* @retval NRF_ERROR_BUSY If some other peripheral with the same
|
||||
* instance ID is already in use. This is
|
||||
* possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
* is set to a value other than zero.
|
||||
*/
|
||||
ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance,
|
||||
nrf_drv_spis_config_t const * p_config,
|
||||
nrf_drv_spis_event_handler_t event_handler);
|
||||
|
||||
/**
|
||||
* @brief Function for uninitializing the SPI slave driver instance.
|
||||
*
|
||||
* @param[in] p_instance Pointer to the driver instance structure.
|
||||
*/
|
||||
void nrf_drv_spis_uninit(nrf_drv_spis_t const * const p_instance);
|
||||
|
||||
/** @brief Function for preparing the SPI slave instance for a single SPI transaction.
|
||||
*
|
||||
* This function prepares the SPI slave device to be ready for a single SPI transaction. It configures
|
||||
* the SPI slave device to use the memory supplied with the function call in SPI transactions.
|
||||
*
|
||||
* When either the memory buffer configuration or the SPI transaction has been
|
||||
* completed, the event callback function will be called with the appropriate event
|
||||
* @ref nrf_drv_spis_event_type_t. Note that the callback function can be called before returning from
|
||||
* this function, because it is called from the SPI slave interrupt context.
|
||||
*
|
||||
* @note This function can be called from the callback function context.
|
||||
*
|
||||
* @note Client applications must call this function after every @ref NRF_DRV_SPIS_XFER_DONE event if
|
||||
* the SPI slave driver should be prepared for a possible new SPI transaction.
|
||||
*
|
||||
* @note Peripherals that are using EasyDMA (for example, SPIS) require the transfer buffers
|
||||
* to be placed in the Data RAM region. Otherwise, this function will fail
|
||||
* with the error code NRF_ERROR_INVALID_ADDR.
|
||||
*
|
||||
* @param[in] p_instance Pointer to the driver instance structure.
|
||||
* @param[in] p_tx_buffer Pointer to the TX buffer.
|
||||
* @param[in] p_rx_buffer Pointer to the RX buffer.
|
||||
* @param[in] tx_buffer_length Length of the TX buffer in bytes.
|
||||
* @param[in] rx_buffer_length Length of the RX buffer in bytes.
|
||||
*
|
||||
* @retval NRF_SUCCESS If the operation was successful.
|
||||
* @retval NRF_ERROR_NULL If the operation failed because a NULL pointer was supplied.
|
||||
* @retval NRF_ERROR_INVALID_STATE If the operation failed because the SPI slave device is in an incorrect state.
|
||||
* @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data
|
||||
* RAM region.
|
||||
* @retval NRF_ERROR_INTERNAL If the operation failed because of an internal error.
|
||||
*/
|
||||
ret_code_t nrf_drv_spis_buffers_set(nrf_drv_spis_t const * const p_instance,
|
||||
const uint8_t * p_tx_buffer,
|
||||
uint8_t tx_buffer_length,
|
||||
uint8_t * p_rx_buffer,
|
||||
uint8_t rx_buffer_length);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SPI_SLAVE_H__
|
||||
|
||||
/** @} */
|
||||
Reference in New Issue
Block a user