/** * \internal * \brief AC window mode test function * * This test checks the window functionality of the AC module. * Inputs are given in each region of the window (below, inside & above) * and corresponding window output states are verified. * * \param test Current test case. */ static void run_ac_window_mode_test(const struct test_case *test) { volatile uint32_t state = AC_WIN_STATUS_UNKNOWN; /* Skip test if initialization failed */ test_assert_true(test, ac_init_success, "Skipping test due to failed AC initialization"); /* Test for region-below detection */ dac_chan_write(&dac_inst, DAC_CHANNEL_0, DAC_VAL_ZERO_VOLT); delay_ms(1); ac_chan_trigger_single_shot(&ac_inst, AC_CHAN_CHANNEL_0); while (!ac_win_is_ready(&ac_inst, AC_WIN_CHANNEL_0)) { } state = ac_win_get_status(&ac_inst, AC_WIN_CHANNEL_0); state = state & AC_WIN_STATUS_BELOW; test_assert_true(test, state == AC_WIN_STATUS_BELOW, "AC window mode: Less than lower limit not detected"); ac_win_clear_status(&ac_inst, AC_WIN_CHANNEL_0); ac_chan_clear_status(&ac_inst, AC_CHAN_CHANNEL_0); ac_chan_clear_status(&ac_inst, AC_CHAN_CHANNEL_1); /* Test for region-inside detection */ state = AC_WIN_STATUS_UNKNOWN; dac_chan_write(&dac_inst, DAC_CHANNEL_0, DAC_VAL_HALF_VOLT); delay_ms(1); ac_chan_trigger_single_shot(&ac_inst, AC_CHAN_CHANNEL_0); while (!ac_win_is_ready(&ac_inst, AC_WIN_CHANNEL_0)) { } state = ac_win_get_status(&ac_inst, AC_WIN_CHANNEL_0); state = state & AC_WIN_STATUS_INSIDE; test_assert_true(test, state == AC_WIN_STATUS_INSIDE, "AC window mode: Within limit not detected"); ac_win_clear_status(&ac_inst, AC_WIN_CHANNEL_0); ac_chan_clear_status(&ac_inst, AC_CHAN_CHANNEL_0); ac_chan_clear_status(&ac_inst, AC_CHAN_CHANNEL_1); /* Test for region-above detection */ state = AC_WIN_STATUS_UNKNOWN; dac_chan_write(&dac_inst, DAC_CHANNEL_0, DAC_VAL_ONE_VOLT); delay_ms(1); ac_chan_trigger_single_shot(&ac_inst, AC_CHAN_CHANNEL_0); while (!ac_win_is_ready(&ac_inst, AC_WIN_CHANNEL_0)) { } state = ac_win_get_status(&ac_inst, AC_WIN_CHANNEL_0); state = state & AC_WIN_STATUS_ABOVE; test_assert_true(test, state == AC_WIN_STATUS_ABOVE, "AC window mode: More than upper limit not detected"); ac_win_clear_status(&ac_inst, AC_WIN_CHANNEL_0); ac_chan_clear_status(&ac_inst, AC_CHAN_CHANNEL_0); ac_chan_clear_status(&ac_inst, AC_CHAN_CHANNEL_1); }
/** \brief Determines the state of a specified Window Comparator. * * Retrieves the current window detection state, indicating what the input * signal is currently comparing to relative to the window boundaries. * * \param[in] module_inst Software instance for the Analog Comparator peripheral * \param[in] win_channel Comparator Window channel to test * * \return Bit mask of Analog Comparator window channel status flags. */ uint8_t ac_win_get_status( struct ac_module *const module_inst, const enum ac_win_channel win_channel) { /* Sanity check arguments */ Assert(module_inst); Assert(module_inst->hw); Ac *const ac_module = module_inst->hw; uint32_t win_status = 0; /* Check if interrupt flag is set */ if (ac_module->INTFLAG.reg & (AC_INTFLAG_WIN0 << win_channel)) { win_status |= AC_WIN_STATUS_INTERRUPT_SET; } /* If one or both window comparators not ready, return unknown result */ if (ac_win_is_ready(module_inst, win_channel) == false) { win_status |= AC_WIN_STATUS_UNKNOWN; return win_status; } uint8_t statusa_tmp = ac_module->STATUSA.reg; /* Map hardware comparison states to logical window states */ if (statusa_tmp & (AC_STATUSA_WSTATE0_BELOW << win_channel)) { return win_status | AC_WIN_STATUS_BELOW; } else if (statusa_tmp & (AC_STATUSA_WSTATE0_INSIDE << win_channel)) { return win_status | AC_WIN_STATUS_INSIDE; } else { return win_status | AC_WIN_STATUS_ABOVE; } }