Software timer and/or INT causing to lock in vAssertCalled()

Hi,
(I am using a PIC32MZ with MPLAB and Harmony MHC.)

I have the code below that somehow 1) locks the system and 2) it seems that sometimes it locks in the vAssertCalled() function. But unfortunately the pcFile and ulLine values are not readable from the IDE/debugger… when halted they show:

pcFile        OPTIMIZED -> (DW_OP_GNU_entry_value 1 DW_OP_reg4)
ulLine        OPTIMIZED -> (DW_OP_GNU_entry_value 1 DW_OP_reg5)

The project is practically empty/new and this is the code that seems to create the issue. There are two functions to debounce a switch. The entire cycle is started by detecting a change notification (button pressed) which then starts a timer to debounce the press. Then again a similar one to detect the released and debounce the release.

This is the Change notification INT callback

void CBK_CHANGE_NOTIF_PurgeButton(GPIO_PIN pin, uintptr_t context)
{
    switch(task_sensorsData.xBtn_PurgeButtonState)
    {
        case PUSHBTN_STATE_AT_REST:
        {
            //button was pressed
            if (PURGE_BTN_Get() == PIN_STATE_PURGE_BUTTON_PRESSED)
            {
                //configure timer for debouncing 
                xTimerChangePeriod(task_sensorsData.xTimer_Handle_PurgeButton, 
                                        pdMS_TO_TICKS(TMR_RELOAD_PURGE_BUTTON_PRESS_DEBOUNCE_MS),
                                        0);
                xTimerReset(task_sensorsData.xTimer_Handle_PurgeButton, 0);
                //disable autoreload 
                vTimerSetReloadMode(task_sensorsData.xTimer_Handle_PurgeButton, pdFALSE);
                xTimerStart(task_sensorsData.xTimer_Handle_PurgeButton, 0);
                //disable CHANGE NOTIF interrupt for Purge Button
                PURGE_BTN_InterruptDisable();
                //change state to BTN_STATE_DEBOUNCING
                task_sensorsData.xBtn_PurgeButtonState = PUSHBTN_STATE_PRESS_DEBOUNCING;
                SYS_DEBUG_MESSAGE(SYS_ERROR_DEBUG, "Changing to PUSHBTN_STATE_PRESS_DEBOUNCING from PUSHBTN_STATE_AT_REST\r\n");
            }
            break;
        }
        case PUSHBTN_STATE_PRESSED:
        {
            //check CN was because button was pressed
            if (PURGE_BTN_Get() == PIN_STATE_PURGE_BUTTON_RELEASED)
            {
                //configure timer for debouncing 
                xTimerChangePeriod(task_sensorsData.xTimer_Handle_PurgeButton, 
                                        pdMS_TO_TICKS(TMR_RELOAD_PURGE_BUTTON_RELEASE_DEBOUNCE_MS),
                                        0);
                xTimerReset(task_sensorsData.xTimer_Handle_PurgeButton, 0);
                //disable autoreload 
                vTimerSetReloadMode(task_sensorsData.xTimer_Handle_PurgeButton, pdFALSE);
                xTimerStart(task_sensorsData.xTimer_Handle_PurgeButton, 0);
                //disable CHANGE NOTIF interrupt for Purge Button
                PURGE_BTN_InterruptDisable();
                //change state to BTN_STATE_DEBOUNCING
                task_sensorsData.xBtn_PurgeButtonState = PUSHBTN_STATE_RELEASE_DEBOUNCING;
                SYS_DEBUG_MESSAGE(SYS_ERROR_DEBUG, "Changing to PUSHBTN_STATE_RELEASE_DEBOUNCING from PUSHBTN_STATE_PRESSED\r\n");
            }
            break;
        }
        case PUSHBTN_STATE_PRESS_DEBOUNCING:
        case PUSHBTN_STATE_RELEASE_DEBOUNCING:
        default:
        {
            SYS_DEBUG_MESSAGE(SYS_ERROR_ERROR, "DEBUG ERROR - Entered Unused state in Purge Button CHANGE NOTIF Callback \r\n");
            DEBUG_RUNTIME_ERROR_LOG("DEBUG ERROR - Entered Unused state in Purge Button CHANGE NOTIF Callback \r\n");             
        }
    }        
}

This is the software timer callbak:

void CBK_SOFT_TMR_PurgeButtonProcess(TimerHandle_t pxExpiredTimer)
{
    switch (task_sensorsData.xBtn_PurgeButtonState)
    {
        case PUSHBTN_STATE_PRESS_DEBOUNCING:
        {
            //Here at end of debounce time 
            if (PURGE_BTN_Get() == PIN_STATE_PURGE_BUTTON_PRESSED)
            {
                //if still pressed
                //send a PRESS message 
                SYS_DEBUG_MESSAGE(SYS_ERROR_WARNING, "PRESS\r\n");
                //change state to pressed
                task_sensorsData.xBtn_PurgeButtonState = PUSHBTN_STATE_PRESSED;
                SYS_DEBUG_MESSAGE(SYS_ERROR_DEBUG, "Changing to PUSHBTN_STATE_PRESSED from PUSHBTN_STATE_PRESS_DEBOUNCING\r\n");
            }
            else
            {
                //if released then change state back to rest
                task_sensorsData.xBtn_PurgeButtonState = PUSHBTN_STATE_AT_REST;
                SYS_DEBUG_MESSAGE(SYS_ERROR_DEBUG, "Changing to PUSHBTN_STATE_AT_REST from PUSHBTN_STATE_PRESS_DEBOUNCING\r\n");
            }
            //in both cases re-enable interrupt for Purge Button so can sense release state from now on
            PURGE_BTN_InterruptEnable();
            break;
        }

        case PUSHBTN_STATE_RELEASE_DEBOUNCING:
        {
            //Here at end of debounce time 
            if (PURGE_BTN_Get() == PIN_STATE_PURGE_BUTTON_RELEASED)
            {
                //if still pressed
                //send a RELEASED message 
                SYS_DEBUG_MESSAGE(SYS_ERROR_WARNING, "RELEASED\r\n");
                //if released then change state back to rest
                task_sensorsData.xBtn_PurgeButtonState = PUSHBTN_STATE_AT_REST;
                SYS_DEBUG_MESSAGE(SYS_ERROR_DEBUG, "Changing to PUSHBTN_STATE_AT_REST from PUSHBTN_STATE_RELEASE_DEBOUNCING\r\n");
                
            }
            else
            {
                //if released then change state back to rest
                task_sensorsData.xBtn_PurgeButtonState = PUSHBTN_STATE_PRESSED;
                SYS_DEBUG_MESSAGE(SYS_ERROR_DEBUG, "Changing to PUSHBTN_STATE_PRESSED from PUSHBTN_STATE_RELEASE_DEBOUNCING\r\n");
            }
            //in both cases re-enable interrupt for Purge Button so can sense release state from now on
            PURGE_BTN_InterruptEnable();
            break;
        }
        
        default:
        {
            SYS_DEBUG_MESSAGE(SYS_ERROR_ERROR, "DEBUG ERROR - xBtn_PurgeButton reached default Switch case\r\n");
            break;
        }        
    }
}

What could be causing it?

Thank you as always! :slight_smile:

Is the interrupt callback called from an interrupt? If so, then you can’t use API functions that don’t end in “FromISR”.

If you want to see the line number and file name in the assert then update the code so they are not optimised away or print them out from within the assert.

Thank you Richard!

I can’t believe I made that mistake!

There isn’t a “fromISR” version for the SetReloadMode. I can work around that, but purely out of curiosity is there a reason for it?

Thank you