コード例 #1
0
ファイル: qs_tcc_faultx.c プロジェクト: meamail/asf
//! [callback_eic]
static void eic_callback_to_clear_halt(void)
{
	if (port_pin_get_input_level(CONF_FAULT_EIC_PIN)) {
		tcc_clear_status(&tcc_instance,
				TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(0) |
				TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(0));
	}
}
コード例 #2
0
/**
 * \brief Retrieves the current module status.
 *
 * Retrieves the status of the module, giving overall state information.
 *
 * \param[in] module_inst  Pointer to the TCC software instance struct
 *
 * \return Bitmask of \c TCC_STATUS_* flags.
 *
 * \retval TCC_STATUS_CHANNEL_MATCH_CAPTURE(n)         Channel n match/capture has occured
 * \retval TCC_STATUS_CHANNEL_OUTPUT(n)                Channel n match/capture output state
 * \retval TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(x)   Non-recoverable fault x has occured
 * \retval TCC_STATUS_RECOVERABLE_FAULT_OCCUR(n)       Recoverable fault n has occured
 * \retval TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(x) Non-recoverable fault x input present
 * \retval TCC_STATUS_RECOVERABLE_FAULT_PRESENT(n)     Recoverable fault n input present
 * \retval TCC_STATUS_SYNC_READY          None of register is syncing
 * \retval TCC_STATUS_CAPTURE_OVERFLOW    Timer capture data has overflowed
 * \retval TCC_STATUS_COUNTER_EVENT       Timer counter event has occurred
 * \retval TCC_STATUS_COUNT_OVERFLOW      Timer count value has overflowed
 * \retval TCC_STATUS_COUNTER_RETRIGGERED Timer counter has been retriggered
 * \retval TCC_STATUS_STOP                Timer counter has been stopped
 * \retval TCC_STATUS_RAMP_CYCLE_INDEX    Wave ramp index for cycle
 */
uint32_t tcc_get_status(
		struct tcc_module *const module_inst)
{
	/* Sanity check arguments */
	Assert(module_inst);
	Assert(module_inst->hw);

	uint32_t int_flags = module_inst->hw->INTFLAG.reg;
	uint32_t status_flags = module_inst->hw->STATUS.reg;
	uint32_t status = 0;
	int i;

	/* SYNC */
	if (module_inst->hw->SYNCBUSY.reg == 0) {
		status |= TCC_STATUS_SYNC_READY;
	}

	/* Channels */
	for (i = 0; i < TCC_NUM_CHANNELS; i++) {
		if (int_flags & TCC_INTFLAG_MC(i)) {
			status |= TCC_STATUS_CHANNEL_MATCH_CAPTURE(i);
		}
		if (status_flags & TCC_STATUS_CMP(i)) {
			status |= TCC_STATUS_CHANNEL_OUTPUT(i);
		}
	}
	/* Non-recoverable fault state */
	if ((int_flags & TCC_INTFLAG_FAULT1) ||
		(status_flags & TCC_STATUS_FAULT1)) {
		status |= TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(1);
	}
	if ((int_flags & TCC_INTFLAG_FAULT0) ||
		(status_flags & TCC_STATUS_FAULT0)) {
		status |= TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(0);
	}
	/* Non-recoverable fault inputs */
	if (status_flags & TCC_STATUS_FAULT0IN) {
		status |= TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(0);
	}
	if (status_flags & TCC_STATUS_FAULT1IN) {
		status |= TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(1);
	}
	/* Recoverable fault state */
	if ((int_flags & TCC_INTFLAG_FAULTB) ||
		(status_flags & TCC_STATUS_FAULTB)) {
		status |= TCC_STATUS_RECOVERABLE_FAULT_OCCUR(1);
	}
	if ((int_flags & TCC_INTFLAG_FAULTA) ||
		(status_flags & TCC_STATUS_FAULTA)) {
		status |= TCC_STATUS_RECOVERABLE_FAULT_OCCUR(0);
	}
	/* Recoverable fault inputs */
	if (status_flags & TCC_STATUS_FAULTAIN) {
		status |= TCC_STATUS_RECOVERABLE_FAULT_PRESENT(0);
	}
	if (status_flags & TCC_STATUS_FAULTBIN) {
		status |= TCC_STATUS_RECOVERABLE_FAULT_PRESENT(1);
	}

	/* Check for TCC capture overflow */
	if (int_flags & TCC_INTFLAG_ERR) {
		status |= TCC_STATUS_CAPTURE_OVERFLOW;
	}
	/* Check for TCC count counter */
	if (int_flags & TCC_INTFLAG_CNT) {
		status |= TCC_STATUS_COUNTER_EVENT;
	}
	/* Check for TCC count retrigger */
	if (int_flags & TCC_INTFLAG_TRG) {
		status |= TCC_STATUS_COUNTER_RETRIGGERED;
	}
	/* Check for TCC count overflow */
	if (int_flags & TCC_INTFLAG_OVF) {
		status |= TCC_STATUS_COUNT_OVERFLOW;
	}
	/* Check for TCC count stop */
	if (status_flags & TCC_STATUS_STOP) {
		status |= TCC_STATUS_STOPPED;
	}
	return status;
}
コード例 #3
0
ファイル: unit_test.c プロジェクト: AndreyMostovov/asf
/**
 * \internal
 * \brief Test Non-Recoverable Fault (FAULTx)
 *
 * This test uses TCC0 as a PWM generator (compare function).
 * EXTINT will be used to route fault input to TCC0.
 *
 * \param test Current test case.
 */
static void run_faultx_test(const struct test_case *test)
{
	test_assert_true(test,
	tcc_init_success == true,
	"TCC initialization failed, skipping test");

	/* Configure TCC module for PWM generation with fault */
	tcc_reset(&tcc_test0_module);
	tcc_get_config_defaults(&tcc_test0_config, CONF_TEST_TCC0);
	tcc_test0_config.counter.period = 0x03FF;
	tcc_test0_config.compare.wave_generation  =
	TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	tcc_test0_config.compare.match[TCC_MATCH_CAPTURE_CHANNEL_0]  = 0x01FF;
	tcc_test0_config.wave_ext.non_recoverable_fault[TCC_WAVE_OUTPUT_0].output = TCC_FAULT_STATE_OUTPUT_1;
	tcc_init(&tcc_test0_module, CONF_TEST_TCC0, &tcc_test0_config);
	/* Configure TCC events for non-recoverable fault input */
	struct tcc_events tcc_test_events;
	memset(&tcc_test_events, 0, sizeof(struct tcc_events));
	tcc_test_events.on_input_event_perform_action[0] = true;
	tcc_test_events.input_config[0].modify_action = true;
	tcc_test_events.input_config[0].action = TCC_EVENT_ACTION_NON_RECOVERABLE_FAULT;
	tcc_enable_events(&tcc_test0_module, &tcc_test_events);
	tcc_enable(&tcc_test0_module);

	/* Configure IO pin to generate fault */
	struct port_config config_pin;
	port_get_config_defaults(&config_pin);
	config_pin.direction = PORT_PIN_DIR_OUTPUT;
	port_pin_set_config(CONF_TEST_PIN_OUT, &config_pin);
	port_pin_set_output_level(CONF_TEST_PIN_OUT, true);

	/* Configure EIC to capture fault input */
	struct extint_chan_conf config;
	extint_chan_get_config_defaults(&config);
	config.filter_input_signal = true;
	config.detection_criteria  = EXTINT_DETECT_BOTH;
	config.gpio_pin     = CONF_EIC_PIN;
	config.gpio_pin_mux = CONF_EIC_MUX;
	extint_chan_set_config(CONF_EIC_CHAN, &config);

	struct extint_events extint_test_events;
	memset(&extint_test_events, 0, sizeof(struct extint_events));
	extint_test_events.generate_event_on_detect[CONF_EIC_CHAN] = true;
	extint_enable_events(&extint_test_events);

	/* Configure EVENTs to route fault input */
	struct events_resource event_resource;
	struct events_config event_config;
	events_get_config_defaults(&event_config);
	event_config.generator = CONF_EVENT_GENERATOR_ID;
	event_config.path      = EVENTS_PATH_ASYNCHRONOUS;
	events_allocate(&event_resource, &event_config);
	events_attach_user(&event_resource, CONF_EVENT_USER_ID_FAULTx);

	/* Clear halt status */
	tcc_clear_status(&tcc_test0_module,
			TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(0) |
			TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(0));

	uint32_t test_val1 = tcc_get_count_value(&tcc_test0_module);
	uint32_t test_val2 = tcc_get_count_value(&tcc_test0_module);

	/* Check TCC is running */
	test_assert_true(test,
			test_val1 != test_val2,
			"The counter failed to stop on non-recoverable fault");

	/* Set fault */
	port_pin_set_output_level(CONF_TEST_PIN_OUT, false);

	/* Check fault state */
	test_assert_true(test,
				TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(0) &
						tcc_get_status(&tcc_test0_module),
				"The counter failed to detect non-recoverable fault");

	/* Check TCC is running */
	test_val1 = tcc_get_count_value(&tcc_test0_module);
	test_val2 = tcc_get_count_value(&tcc_test0_module);
	test_assert_true(test,
			test_val1 == test_val2,
			"The counter failed to stop on non-recoverable fault");
}