brownout detection not operating as expected

Zingemneire
Posts: 68
Joined: Tue Apr 17, 2018 7:35 am

brownout detection not operating as expected

Postby Zingemneire » Thu Oct 18, 2018 9:00 am

Hi,

As reported yesterday in this topic: viewtopic.php?f=2&t=7690#p32365
I used the technique described in this answer from ESP_igrr: viewtopic.php?t=6855#p29440.

I implemented it as follows:

Code: Select all

//CONFIG_BROWNOUT_DET_LVL_SEL_3
#ifdef CONFIG_BROWNOUT_DET_LVL
#define BROWNOUT_DET_LVL CONFIG_BROWNOUT_DET_LVL
#else
#define BROWNOUT_DET_LVL 4
#endif //CONFIG_BROWNOUT_DET_LVL

#define TAG "Brownout.c"

static void BOD_BrownoutIsrHandler()
{
   /* Normally RTC ISR clears the interrupt flag after the application-supplied
    * handler returns. Since restart is called here, the flag needs to be
    * cleared manually.
    */
   REG_WRITE ( RTC_CNTL_INT_CLR_REG, RTC_CNTL_BROWN_OUT_INT_CLR );
   /* Stall the other CPU to make sure the code running there doesn't use UART
    * at the same time as the following ets_printf.
    */
   esp_cpu_stall ( !xPortGetCoreID () );
   EvLog_WriteEntry( TAG, "Brownout detector was triggered!" );
   // Wait for 2 seconds to allow any NVS storage to finish
   vTaskDelay ( 2000/portTICK_PERIOD_MS );
   ets_printf("\r\nBrownout detector was triggered\r\n\r\n");
   LCD_ShowText ( "BAT");
   Sleep_StartDeepSleep ( ON );
}

void BOD_BrownoutInit( void )
{
   esp_err_t espError;

   REG_WRITE
   (
      RTC_CNTL_BROWN_OUT_REG,
      RTC_CNTL_BROWN_OUT_ENA                 /* Enable BOD */
      | RTC_CNTL_BROWN_OUT_PD_RF_ENA         /* Automatically power down RF */
      | (2 << RTC_CNTL_BROWN_OUT_RST_WAIT_S) /* Reset timeout must be set to >1 even if BOR feature is not used */
      | ( BROWNOUT_DET_LVL << RTC_CNTL_DBROWN_OUT_THRES_S )
   );

   espError = rtc_isr_register ( BOD_BrownoutIsrHandler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M ) ;
   if ( espError == ESP_OK )
   {
      REG_SET_BIT ( RTC_CNTL_INT_ENA_REG, RTC_CNTL_BROWN_OUT_INT_ENA_M );
      ESP_LOGI ( TAG, "Registered brownout ISR");
   }
   else
   {
      EvLog_WriteEntry( TAG, "Could not register BOD_BrownoutIsrHandler !!" );
   }
}
In my UART output log files I am sure the BOD_BrownoutInit function is called and succeeds as I get the "Registered brownoutISR" message.
However: When I use my regulated power supply to lower the voltage the registered ISR is not executing as I do not get the "Brownout detector was triggered" message. Instead I get this:

(08:57:33.720) abort() was called at PC 0x40082ddd on core 0<CR>
(08:57:53.050) <CR>
(08:57:53.050) Backtrace: 0x4008ff5c:0x3ffb0000 0x40090133:0x3ffb0020 0x40082ddd:0x3ffb0040 0x40082efd:0x3ffb0070 0x400da4ba:0x3ffb0090 0x400dd715:0x3ffb03a0 0x40082d0d:0x3ffb03d0 0x400e431a:0x3ffb0420 0x400e31c7:0x3ffb05d0 0x400ea22e:0x3ffb05f0 0x400826a9:0x3ffb0610 0x4014baf3:0x00000000<CR>
(08:57:53.081) <CR>
(08:57:53.081) Rebooting...<CR>
(08:57:53.097) ets Jun 8 2016 00:22:57<CR>
(08:57:53.097) <CR>
(08:57:53.097) rst:0xc (SW_CPU_RESET),boot:0x37 (SPI_FAST_FLASH_BOOT)<CR>
...
..
.


The reboot keeps repeating until I increase the supply voltage again. Also: I have tried with various values for BROWNOUT_DET_LVL and it does not make the slightest difference. The abort() call always occurs at the same voltage.

Obviously I must be doing something wrong but for now I have no idea what.

Edit: Analysis of the map file shows that the call to abort() at PC 0x40082ddd is somewhere within file "locks.c"

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: brownout detection not operating as expected

Postby WiFive » Thu Oct 18, 2018 9:33 am

You keep linking that other thread where it says don't try to use nvs or anything complicated that can't run from isr context...

Zingemneire
Posts: 68
Joined: Tue Apr 17, 2018 7:35 am

Re: brownout detection not operating as expected

Postby Zingemneire » Thu Oct 18, 2018 9:55 am

Hi WiFive,

In the mean time I had a sneaky suspicion that something like that may be the cause.

using xtensa-esp32-elf-gdb I have located where exactly it is happening in locks.c:

Code: Select all

    if (xPortInIsrContext()) {
        /* In ISR Context */
        if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) {
            abort(); /* recursive mutexes make no sense in ISR context */
        }
        BaseType_t higher_task_woken = false;
        success = xSemaphoreTakeFromISR(h, &higher_task_woken);
        if (!success && delay > 0) {
I am trying to do complicated stuff in the ISR so I will rewrite the code to try and eliminate the problem.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: brownout detection not operating as expected

Postby WiFive » Thu Oct 18, 2018 10:28 am

Using brownout to detect a low but stable-enough-to-do-complicated-things battery voltage is not really the intended use.

Zingemneire
Posts: 68
Joined: Tue Apr 17, 2018 7:35 am

Re: brownout detection not operating as expected

Postby Zingemneire » Fri Oct 26, 2018 1:11 pm

Hi,

I have figured it out in the mean time: I do detect the brownout as desired and manage to do all of the required complicated stuff as well.

The method to do it is as follows:
  • First of all: when I detect brownout there is still enough life in the battery to do the complicated stuff as there is very little of it to do.
    When brownout actually occurs I write some flags and the timestamp value to reserved areas in RTC slow memory.
    Then I put the unit to sleep for 60 seconds.
    After that it wakes up, notices the brownout detected flag, does not register the brownout ISR function and logs when the detected brownout was detected.
    Subsequently it goes into deep sleep again for 24 hours after it has put "bAt" on the 7 segment LCD display.
Bottom line is that after a brownout is detected the system reverts to deep sleep and potentially wakes up again once every 24 hours. If the battery is really low it soon goes back to deep sleep and displaying "bat" on the LCD, thereby consuming next to nothing in terms of energy.

Who is online

Users browsing this forum: No registered users and 104 guests