I need to use one IO port of the nrf52832. This IO can not only detect the ECG signal but also achieve system off wake-up. The ECG signal is a PWM signal with a duty cycle of 20%. By detecting the PWM period, the RR value can be detected. I would like to ask how to configure the code? The PWM detection code has been written. How can this IO be used for wake-up at the same time?
The following code is the configuration code for the PWM detection pin:
static uint32_t timer_ticks_to_us(uint32_t ticks)
{
return ticks;
}
static uint32_t calculate_time_diff(uint32_t current, uint32_t previous)
{
if (current >= previous)
{
return current - previous;
}
else
{
return (0xFFFFFFFF - previous) + current + 1;
}
}
void timer_event_handler(nrf_timer_event_t event_type, void *p_context)
{
switch (event_type)
{
case NRF_TIMER_EVENT_COMPARE0:
break;
case NRF_TIMER_EVENT_COMPARE1:
break;
default:
break;
}
}
void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
// if (!m_measurement_active) return;
uint32_t rr_interval;
uint32_t current_time = nrf_drv_timer_capture(&m_timer, NRF_TIMER_CC_CHANNEL0);
switch (action)
{
case NRF_GPIOTE_POLARITY_LOTOHI:
if (m_last_heartbeat_time != 0)
{
uint32_t period_ticks = calculate_time_diff(current_time, m_rise_time);
m_period_us = timer_ticks_to_us(period_ticks);
m_measurement_valid = true;
NRF_LOG_DEBUG("Rising edge - Period: %u us", m_period_us)
rr_interval= m_period_us/1000;
NRF_LOG_DEBUG("rr interval %u ", rr_interval)
uint16_t rr_interval_ble = (uint16_t)( rr_interval * 1024 /1000);
if (rr_interval >= 500 && rr_interval <= 2000)
{
if (m_rr_count < BLE_HRS_MAX_RR_INTERVALS)
{
m_rr_interval[m_rr_count++] = rr_interval_ble;
NRF_LOG_DEBUG("m-rr-interval %u ", rr_interval_ble);
}
}
}
m_rise_time = current_time;
m_last_heartbeat_time = current_time;
break;
default:
break;
}
}
ret_code_t pwm_detector_init(uint32_t pwm_input_pin)
{
ret_code_t err_code;
NRF_LOG_INFO("Initializing RR detector on pin %d", pwm_input_pin);
if (!nrf_drv_gpiote_is_init())
{
err_code = nrf_drv_gpiote_init();
if (err_code != NRF_SUCCESS)
{
NRF_LOG_ERROR("GPIOTE init failed: 0x%X", err_code);
return err_code;
}
}
nrf_drv_gpiote_in_config_t in_config =
{
.sense =NRF_GPIOTE_POLARITY_HITOLO,
.pull = NRF_GPIO_PIN_PULLUP,
.is_watcher = false,
.hi_accuracy = true,
.skip_gpio_setup = false
};
err_code = nrf_drv_gpiote_in_init(pwm_input_pin, &in_config, gpiote_event_handler);
if (err_code != NRF_SUCCESS)
{
NRF_LOG_ERROR("GPIOTE in init failed: 0x%X", err_code);
return err_code;
}
nrf_drv_timer_config_t timer_cfg =
{
.frequency = TIMER_FREQUENCY,
.mode = NRF_TIMER_MODE_TIMER,
.bit_width = NRF_TIMER_BIT_WIDTH_32,
.interrupt_priority = APP_IRQ_PRIORITY_LOW,
.p_context = NULL
};
err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_event_handler);
if (err_code != NRF_SUCCESS)
{
NRF_LOG_ERROR("Timer init failed: 0x%X", err_code);
return err_code;
}
nrf_drv_timer_enable(&m_timer);
nrf_drv_gpiote_in_event_enable(pwm_input_pin, true);
m_measurement_active = true;
NRF_LOG_INFO("RR detector initialized successfully");
return NRF_SUCCESS;
}
uint32_t pwm_get_period_us(void)
{
return m_last_heartbeat_time;
}