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.
74 lines
2.0 KiB
74 lines
2.0 KiB
/* |
|
* 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; |
|
}
|
|
|