75 lines
2.0 KiB
C
75 lines
2.0 KiB
C
/*
|
|
* Copyright (c) 2023, Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include "spi_nrfx_common.h"
|
|
#include <zephyr/kernel.h>
|
|
|
|
int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin)
|
|
{
|
|
nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLDOWN;
|
|
uint8_t ch;
|
|
nrfx_gpiote_trigger_config_t trigger_config = {
|
|
.trigger = NRFX_GPIOTE_TRIGGER_HITOLO,
|
|
.p_in_channel = &ch,
|
|
};
|
|
nrfx_gpiote_input_pin_config_t input_config = {
|
|
.p_pull_config = &pull_config,
|
|
.p_trigger_config = &trigger_config,
|
|
.p_handler_config = NULL,
|
|
};
|
|
nrfx_err_t res;
|
|
|
|
res = nrfx_gpiote_channel_alloc(gpiote, &ch);
|
|
if (res != NRFX_SUCCESS) {
|
|
return -ENODEV;
|
|
}
|
|
|
|
res = nrfx_gpiote_input_configure(gpiote, wake_pin, &input_config);
|
|
if (res != NRFX_SUCCESS) {
|
|
nrfx_gpiote_channel_free(gpiote, ch);
|
|
return -EIO;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin)
|
|
{
|
|
nrf_gpiote_event_t trigger_event = nrfx_gpiote_in_event_get(gpiote, wake_pin);
|
|
uint32_t start_cycles;
|
|
uint32_t max_wait_cycles =
|
|
DIV_ROUND_UP(CONFIG_SPI_NRFX_WAKE_TIMEOUT_US *
|
|
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC,
|
|
1000000);
|
|
int err = 0;
|
|
|
|
/* Enable the trigger (a high-to-low transition) without its interrupt.
|
|
* The expected time to wait is quite short so it is not worth paying
|
|
* the overhead of context switching to handle the interrupt.
|
|
*/
|
|
nrfx_gpiote_trigger_enable(gpiote, wake_pin, false);
|
|
/* Enable pull-up on the WAKE line. After the slave device sees the
|
|
* WAKE line going high, it will force the line to go low. This will
|
|
* be caught by the enabled trigger and the loop below waits for that.
|
|
*/
|
|
nrf_gpio_cfg_input(wake_pin, NRF_GPIO_PIN_PULLUP);
|
|
|
|
start_cycles = k_cycle_get_32();
|
|
while (!nrf_gpiote_event_check(gpiote->p_reg, trigger_event)) {
|
|
uint32_t elapsed_cycles = k_cycle_get_32() - start_cycles;
|
|
|
|
if (elapsed_cycles >= max_wait_cycles) {
|
|
err = -ETIMEDOUT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
nrfx_gpiote_trigger_disable(gpiote, wake_pin);
|
|
nrf_gpio_cfg_input(wake_pin, NRF_GPIO_PIN_PULLDOWN);
|
|
|
|
return err;
|
|
}
|