Hi @jingpan
As mentioned above in the post, I implemented the same in software and tried to test but it doesn't work.
The following is the program (I used acmp_interrupt program and modified it little but to suit my requirements)
#include "fsl_acmp.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define DEMO_ACMP_BASEADDR CMP0
#define DEMO_ACMP_USER_CHANNEL 0U
#define DEMO_ACMP_IRQ_ID CMP0_IRQn
#define DEMO_ACMP_IRQ_HANDLER_FUNC CMP0_IRQHandler
#define LED_INIT() LED_GREEN1_INIT(LOGIC_LED_OFF)
#define LED_ON() LED_GREEN1_ON()
#define LED_OFF() LED_GREEN1_OFF()
#define RISING_THRESHOLD 103u // 2V
#define FALLING_THRESHOLD 51u // 1V
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile uint32_t g_acmpOutputRising = 0U;
volatile uint32_t g_acmpOutputFalling = 0U;
volatile uint8_t g_edge = 0u;
volatile uint32_t rising_error = 0u;
volatile uint32_t falling_error = 0u;
acmp_config_t acmpConfigStruct;
acmp_channel_config_t channelConfigStruct;
acmp_dac_config_t dacConfigStruct;
/*******************************************************************************
* Code
******************************************************************************/
static void Custom_ACMP_Init( void );
static void Custom_ACMP_ReInit( uint8_t edge_type );
void DEMO_ACMP_IRQ_HANDLER_FUNC(void)
{
uint32_t statusFlags = 0u;
statusFlags = ACMP_GetStatusFlags(DEMO_ACMP_BASEADDR);
ACMP_ClearStatusFlags(DEMO_ACMP_BASEADDR, statusFlags);
if( g_edge == 0u )
{
if ((kACMP_OutputAssertEventFlag == (statusFlags & kACMP_OutputAssertEventFlag)) &&
(kACMP_OutputRisingEventFlag == (statusFlags & kACMP_OutputRisingEventFlag)))
{
g_acmpOutputRising = 1U;
}
else
{
rising_error++;
}
// Reconfigure
Custom_ACMP_ReInit(1);
g_edge = 1u;
}
else if( g_edge == 1u )
{
if ((kACMP_OutputAssertEventFlag != (statusFlags & kACMP_OutputAssertEventFlag)) &&
(kACMP_OutputFallingEventFlag == (statusFlags & kACMP_OutputFallingEventFlag)))
{
g_acmpOutputFalling = 1U;
}
else
{
falling_error++;
}
Custom_ACMP_ReInit(0);
g_edge = 0u;
}
SDK_ISR_EXIT_BARRIER;
}
/*!
* @brief Main function
*/
int main(void)
{
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
LED_INIT();
LED_OFF();
Custom_ACMP_Init();
PRINTF("The example compares analog input to the reference DAC output(CMP negative port).\r\n");
PRINTF("The LED will be turned ON/OFF when the analog input is HIGHER/LOWER than the DAC output.\r\n");
PRINTF("Change the analog input voltage to see the LED status.\r\n");
while (true)
{
/* Check the comparison result and toggle the LED according to the result. */
if (g_acmpOutputRising)
{
g_acmpOutputRising = 0U;
LED_ON();
PRINTF("The analog input is HIGHER than DAC output\r\n");
}
else if (g_acmpOutputFalling)
{
g_acmpOutputFalling = 0U;
LED_OFF();
PRINTF("The analog input is LOWER than DAC output\r\n");
}
else
{
/* Unknown status. */
}
}
}
static void Custom_ACMP_Init( void )
{
ACMP_GetDefaultConfig(&acmpConfigStruct);
acmpConfigStruct.hysteresisMode = kACMP_HysteresisLevel3;
ACMP_Init(DEMO_ACMP_BASEADDR, &acmpConfigStruct);
channelConfigStruct.positivePortInput = kACMP_PortInputFromMux;
channelConfigStruct.negativePortInput = kACMP_PortInputFromDAC;
channelConfigStruct.minusMuxInput = 0U; /* Dummy channel. */
channelConfigStruct.plusMuxInput = DEMO_ACMP_USER_CHANNEL;
ACMP_SetChannelConfig(DEMO_ACMP_BASEADDR, &channelConfigStruct);
/* Configure DAC. */
dacConfigStruct.referenceVoltageSource = kACMP_VrefSourceVin1;
dacConfigStruct.DACValue = RISING_THRESHOLD; //0x7FU; /* Half of referene voltage. */
#if defined(FSL_FEATURE_ACMP_HAS_C1_DACOE_BIT) && (FSL_FEATURE_ACMP_HAS_C1_DACOE_BIT == 1U)
dacConfigStruct.enableOutput = true;
#endif /* FSL_FEATURE_ACMP_HAS_C1_DACOE_BIT */
#if defined(FSL_FEATURE_ACMP_HAS_C1_DMODE_BIT) && (FSL_FEATURE_ACMP_HAS_C1_DMODE_BIT == 1U)
dacConfigStruct.workMode = kACMP_DACWorkLowSpeedMode;
#endif /* FSL_FEATURE_ACMP_HAS_C1_DMODE_BIT */
ACMP_SetDACConfig(DEMO_ACMP_BASEADDR, &dacConfigStruct);
/* Enable the interrupts. */
// ACMP_EnableInterrupts(DEMO_ACMP_BASEADDR, kACMP_OutputRisingInterruptEnable | kACMP_OutputFallingInterruptEnable);
ACMP_EnableInterrupts(DEMO_ACMP_BASEADDR, kACMP_OutputRisingInterruptEnable );
EnableIRQ(DEMO_ACMP_IRQ_ID);
ACMP_Enable(DEMO_ACMP_BASEADDR, true);
}
static void Custom_ACMP_ReInit( uint8_t edge_type )
{
ACMP_Enable(DEMO_ACMP_BASEADDR, false);
/* Configure DAC. */
if( edge_type == 0u )
{
dacConfigStruct.DACValue = RISING_THRESHOLD;
}
else
{
dacConfigStruct.DACValue = FALLING_THRESHOLD;
}
ACMP_SetDACConfig(DEMO_ACMP_BASEADDR, &dacConfigStruct);
/* Enable the interrupts. */
if( edge_type == 0u )
{
ACMP_DisableInterrupts(DEMO_ACMP_BASEADDR, kACMP_OutputFallingInterruptEnable);
ACMP_EnableInterrupts(DEMO_ACMP_BASEADDR, kACMP_OutputRisingInterruptEnable);
}
else
{
ACMP_DisableInterrupts(DEMO_ACMP_BASEADDR, kACMP_OutputRisingInterruptEnable);
ACMP_EnableInterrupts(DEMO_ACMP_BASEADDR, kACMP_OutputFallingInterruptEnable);
}
EnableIRQ(DEMO_ACMP_IRQ_ID);
ACMP_Enable(DEMO_ACMP_BASEADDR, true);
}
The flow is as below.
- At Power-Up, configure the CMP for Rising Edge
- When Rising Edge is received, Disable the CMP
- Update the DAC value for Falling Edge
- Enable the Falling Interrupt and Disable the Rising Interrupt
- Repeat the same steps for Rising Edge
But when I do so, the first rising edge is okay, but as soon as I tried to change the DAC value, and reconfigure the module, the next interrupt occurs immediately.
After debugging I found the following scenarios.
I disabled the Comparator Module, before updating the DAC value, and here CFF bit is set (my understanding is, since we disabled the module, Comparator Output changes from High -> Low, hence this happens)

After updating the DAC value for falling edge, I enabled the Comparator, and due to the my setup position, COUT is now 1 again, and hence CFR bit is also set.

And this messed up by simple state-machine.

But if I run my code by commenting the line ACMP_Enable(DEMO_ACMP_BASEADDR, false);, everything works fine, for obvious reason.
Can you please suggest, should I proceed without disabling the module?
The reason I disabled the module is because I am changing the DAC values and enabling only one type of interrupt at a time.