Example #1
0
/**
 * \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);
}
Example #2
0
File: ac.c Project: Gussy/sam0
/** \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;
    }

}