Hi,
I am discovering the nrf52 software with the Segger Embedded Studio environment.
I have developed an application derived of the ble_app_uart example.
I have many events that run well, but I wanted to add some tests in my main loop (detect a button change for example) or trigger an action once the new BLE data has been received (I am more used to the Arduino environment where I write non-blocking functions in my main loop).
My issue is that the code doesn't seem to loop inside the main loop. After some investigation, I discovered that the nrf_pwr_mgmt_run() was the cause of my problems even if I don't really understand why.
So my questions are :
- Why does the nrf_pwr_mgmt_run() blocks the main loop ?
- What am I doing wrong ?
Thanks a lot to anyone who can help me !
PS : I have added the code that I want to run inside my main loop. To give a broad idea of what it does, I have a RV3028 RTC connected through I2C to my nrf52832. I set an alarm through the bluetooth and the device is supposed to go to sleep and wake up at the given date and time.
int main(void)
{
bool erase_bonds;
uint32_t button_reset_previous = 0;
uint32_t reed_previous = 0;
// Initialize.
log_init();
NRF_LOG_INFO("Main function started");
timers_init();
buttons_leds_init(&erase_bonds);
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
TWI_Init();
pwm_init();
RV3028_configuration_init();
// Start execution.
NRF_LOG_INFO("Main function started");
advertising_start();
bool alarmSet = false;
bool wakeFromAlarm = false;
uint8_t Status = 0;
RV3028_GetFlags(&RTC, &Status);
if(Status & RV3028_FLAG_ALARM)
{
RV3028_ClearFlags(&RTC, RV3028_FLAG_ALARM);
wakeFromAlarm = true;
}
// Enter main loop.
for (;;)
{
idle_state_handle();
if(resetRTC)
{
RV3028_configuration_init(false);
RV3028_ClearFlags(&RTC, RV3028_FLAG_ALARM);
resetRTC = false;
}
if(wakeFromAlarm)
{
NRF_LOG_INFO("Waking Up from alarm");
nrf_gpio_pin_set(PIN_DRV_SLEEP); // put driver out of sleep mode
nrf_gpio_pin_set(PIN_DRV_DIR); // backward mode
nrf_delay_ms(10);
app_pwm_enable(&PWM1);
while (app_pwm_channel_duty_set(&PWM1, 0, 50) == NRF_ERROR_BUSY);
nrf_delay_ms(3000);
while (app_pwm_channel_duty_set(&PWM1, 0, 0) == NRF_ERROR_BUSY);
nrf_delay_ms(500);
nrf_gpio_pin_clear(PIN_DRV_SLEEP); // put driver in sleep mode
nrf_gpio_pin_clear(PIN_DRV_DIR);
app_pwm_disable(&PWM1);
wakeFromAlarm = false;
}
if(writeEeprom)
{
uint8_t data = 3;
ErrorCode = RV3028_SetEEPROM(&RTC, 2, data);
if(ErrorCode != RV3028_NO_ERROR)
{
NRF_LOG_INFO("Error writing Eeprom. Error: %u", ErrorCode);
}
else
{
NRF_LOG_INFO("Eeprom write done");
}
writeEeprom = false;
}
if(readEeprom)
{
uint8_t data = 0;
ErrorCode = RV3028_GetEEPROM(&RTC, 2, &data);
if(ErrorCode != RV3028_NO_ERROR)
{
NRF_LOG_INFO("Error reading Eeprom. Error: %u", ErrorCode);
}
else
{
NRF_LOG_INFO("Eeprom data: %u", data);
}
readEeprom = false;
}
if(alarmSet)
{
NRF_LOG_INFO("Going into sleep mode");
NRF_LOG_PROCESS();
sleep_mode_enter();
}
if(CurrentTime.tm_mon != 0)
{
ErrorCode = RV3028_SetTime(&RTC, &CurrentTime);
if(ErrorCode != RV3028_NO_ERROR)
{
NRF_LOG_INFO("Error writing current time. Error: %u", ErrorCode);
}
CurrentTime.tm_mon = 0;
}
if (printRTCTime)
{
printRTCTime = false;
struct tm tmpTime;
RV3028_GetTime(&RTC, &tmpTime);
NRF_LOG_INFO("RTC time: %u-%u-20%u %u:%u:%u", tmpTime.tm_mday, tmpTime.tm_mon, tmpTime.tm_year, tmpTime.tm_hour, tmpTime.tm_min, tmpTime.tm_sec);
}
if(RTC_Alarm.Day != 0)
{
NRF_LOG_INFO("setting Alarm %u %u %u", RTC_Alarm.Day, RTC_Alarm.Hours, RTC_Alarm.Minutes);
ErrorCode = RV3028_EnableAlarm(&RTC, &RTC_Alarm);
if(ErrorCode != RV3028_NO_ERROR)
{
NRF_LOG_INFO("Error writing Alarm. Error: %u", ErrorCode);
}
else
{
nrf_gpio_pin_set(PIN_DRV_SLEEP); // put driver out of sleep mode
nrf_gpio_pin_clear(PIN_DRV_DIR); // forward mode
nrf_delay_ms(10);
app_pwm_enable(&PWM1);
while (app_pwm_channel_duty_set(&PWM1, 0, 50) == NRF_ERROR_BUSY);
nrf_delay_ms(3000);
while (app_pwm_channel_duty_set(&PWM1, 0, 0) == NRF_ERROR_BUSY);
nrf_delay_ms(500);
app_pwm_disable(&PWM1);
nrf_gpio_pin_clear(PIN_DRV_SLEEP); // put driver in sleep mode
nrf_delay_ms(500);
NRF_LOG_FLUSH();
alarmSet = true;
}
RTC_Alarm.Day = 0;
}
if(getRtcFlag)
{
ErrorCode = RV3028_GetFlags(&RTC, &Status);
if(ErrorCode != RV3028_NO_ERROR)
{
NRF_LOG_INFO("Error writing Alarm. Error: %u", ErrorCode);
}
if(Status & RV3028_FLAG_ALARM)
{
NRF_LOG_INFO(" Alarm ");
RV3028_ClearFlags(&RTC, RV3028_FLAG_ALARM);
}
getRtcFlag = false;
}
if(button_reset_previous != nrf_gpio_pin_read(PIN_BTN_RST))
{
nrf_delay_ms(50);
button_reset_previous = nrf_gpio_pin_read(PIN_BTN_RST);
NRF_LOG_INFO("BTN_RST Toggle");
}
if(reed_previous != nrf_gpio_pin_read(PIN_REED_VAL))
{
nrf_delay_ms(50);
reed_previous = nrf_gpio_pin_read(PIN_REED_VAL);
NRF_LOG_INFO("REED Toggle");
nrf_gpio_pin_toggle(BLE_STATUS_LED);
}
}
}