Esempio n. 1
0
/**
 * \brief Enables callback.
 *
 * Enables the callback specified by the callback_type.
 *
 * \param[in,out]  module  Pointer to the software instance struct
 * \param[in]     callback_type Callback type to enable
 */
void rtc_count_enable_callback(
		struct rtc_module *const module,
		enum rtc_count_callback callback_type)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	Rtc *const rtc_module = module->hw;

	if (callback_type == RTC_COUNT_CALLBACK_OVERFLOW) {
		rtc_module->MODE0.INTENSET.reg = RTC_MODE0_INTFLAG_OVF;
	} else if (callback_type >= RTC_COUNT_CALLBACK_PERIODIC_INTERVAL_0
			&& callback_type <= RTC_COUNT_CALLBACK_PERIODIC_INTERVAL_7) {
		rtc_module->MODE0.INTENSET.reg = RTC_MODE1_INTFLAG_PER(1 << callback_type);
	}else {
		rtc_module->MODE0.INTENSET.reg = RTC_MODE1_INTFLAG_CMP(1 << (callback_type - RTC_PER_NUM));
	}
	/* Mark callback as enabled. */
	module->enabled_callback |= (1 << callback_type);
}
Esempio n. 2
0
/**
 * \brief Clears RTC compare match flag.
 *
 * Clears the compare flag. The compare flag is set when there is a compare
 * match between the counter and the compare.
 *
 * \note Compare 4 and 5 are only available in 16-bit mode.
 *
 * \param[in,out] module  Pointer to the software instance struct
 * \param[in] comp_index  Index of compare to check current flag
 *
 * \return Status indicating if flag was successfully cleared.
 * \retval STATUS_OK               If flag was successfully cleared
 * \retval STATUS_ERR_INVALID_ARG  If invalid argument(s) were provided
 * \retval STATUS_ERR_BAD_FORMAT   If the module was not initialized in a mode
 */
enum status_code rtc_count_clear_compare_match(
		struct rtc_module *const module,
		const enum rtc_count_compare comp_index)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	Rtc *const rtc_module = module->hw;

	/* Check sanity. */
	switch (module->mode){
		case RTC_COUNT_MODE_32BIT:
			/* Check sanity for 32-bit mode. */
			if (comp_index > RTC_NUM_OF_COMP32) {
				return STATUS_ERR_INVALID_ARG;
			}

			break;

		case RTC_COUNT_MODE_16BIT:
			/* Check sanity for 16-bit mode. */
			if (comp_index > RTC_NUM_OF_COMP16) {
				return STATUS_ERR_INVALID_ARG;
			}

			break;

		default:
			Assert(false);
			return STATUS_ERR_BAD_FORMAT;
	}

	/* Clear INTFLAG. */
	rtc_module->MODE0.INTFLAG.reg = RTC_MODE1_INTFLAG_CMP(1 << comp_index);

	return STATUS_OK;
}
Esempio n. 3
0
/**
 * \brief Check if RTC compare match has occurred.
 *
 * Checks the compare flag to see if a match has occurred. The compare flag is
 * set when there is a compare match between counter and the compare.
 *
 * \note Compare 4 and 5 are only available in 16-bit mode.
 *
 * \param[in,out] module  Pointer to the software instance struct
 * \param[in] comp_index  Index of compare to check current flag
 */
bool rtc_count_is_compare_match(
		struct rtc_module *const module,
		const enum rtc_count_compare comp_index)
{
	/* Sanity check arguments */
	Assert(module);
	Assert(module->hw);

	Rtc *const rtc_module = module->hw;

	/* Check sanity. */
	switch (module->mode) {
		case RTC_COUNT_MODE_32BIT:
			/* Check sanity for 32-bit mode. */
			if (comp_index > RTC_COMP32_NUM) {
				return false;
			}

			break;

		case RTC_COUNT_MODE_16BIT:
			/* Check sanity for 16-bit mode. */
			if (comp_index > RTC_NUM_OF_COMP16) {
				return false;
			}

			break;

		default:
			Assert(false);
			return false;
	}

	/* Set status of INTFLAG as return argument. */
	return (rtc_module->MODE0.INTFLAG.reg & RTC_MODE1_INTFLAG_CMP(1 << comp_index)) ? true : false;
}
Esempio n. 4
0
/**
 * \internal Interrupt handler for RTC
 *
 * \param [in] instance_index  Default value 0
 */
static void _rtc_interrupt_handler(const uint32_t instance_index)
{
	struct rtc_module *module = _rtc_instance[instance_index];

	Rtc *const rtc_module = module->hw;

	/* Combine callback registered and enabled masks */
	uint16_t callback_mask = module->enabled_callback;
	callback_mask &= module->registered_callback;

	/* Read and mask interrupt flag register */
	uint16_t interrupt_status = rtc_module->MODE0.INTFLAG.reg;
	interrupt_status &= rtc_module->MODE0.INTENSET.reg;

	if (interrupt_status & RTC_MODE0_INTFLAG_OVF) {
		/* Overflow interrupt */
		if (callback_mask & (1 << RTC_COUNT_CALLBACK_OVERFLOW)) {
			module->callbacks[RTC_COUNT_CALLBACK_OVERFLOW]();
		}

		/* Clear interrupt flag */
		rtc_module->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_OVF;

	} else if (interrupt_status & RTC_MODE1_INTFLAG_PER(0xff)) {
		uint8_t i  = 0;
		for ( i = 0;i < RTC_PER_NUM;i++) {
			if ((interrupt_status & RTC_MODE1_INTFLAG_PER(1 << i))
			  && (callback_mask & (1 << i))) {
				module->callbacks[i]();
			}

			/* Clear interrupt flag */
			rtc_module->MODE0.INTFLAG.reg = RTC_MODE1_INTFLAG_PER(1<<i);
		}
	}else if (interrupt_status & RTC_MODE1_INTFLAG_CMP(1 << 0)) {
		/* Compare 0 interrupt */
		if (callback_mask & (1 << RTC_COUNT_CALLBACK_COMPARE_0)) {
			module->callbacks[RTC_COUNT_CALLBACK_COMPARE_0]();
		}
		/* Clear interrupt flag */
		rtc_module->MODE0.INTFLAG.reg = RTC_MODE1_INTFLAG_CMP(1 << 0);

	} else if (interrupt_status & RTC_MODE1_INTFLAG_CMP(1 << 1)) {
		#if (RTC_NUM_OF_COMP16 > 1) || defined(__DOXYGEN__)
		/* Compare 1 interrupt */
		if (callback_mask & (1 << RTC_COUNT_CALLBACK_COMPARE_1)) {
			module->callbacks[RTC_COUNT_CALLBACK_COMPARE_1]();
		}
		/* Clear interrupt flag */
		rtc_module->MODE0.INTFLAG.reg = RTC_MODE1_INTFLAG_CMP(1 << 1);
		#endif

	} else if (interrupt_status & RTC_MODE1_INTFLAG_CMP(1 << 2)) {
		#if (RTC_NUM_OF_COMP16 > 2)	|| defined(__DOXYGEN__)
		/* Compare 2 interrupt */
		if (callback_mask & (1 << RTC_COUNT_CALLBACK_COMPARE_2)) {
			module->callbacks[RTC_COUNT_CALLBACK_COMPARE_2]();
		}
		/* Clear interrupt flag */
		rtc_module->MODE0.INTFLAG.reg = RTC_MODE1_INTFLAG_CMP(1 << 2);
		#endif

	} else if (interrupt_status & RTC_MODE1_INTFLAG_CMP(1 << 3)) {
		#if (RTC_NUM_OF_COMP16 > 3)	|| defined(__DOXYGEN__)
		/* Compare 3 interrupt */
		if (callback_mask & (1 << RTC_COUNT_CALLBACK_COMPARE_3)) {
			module->callbacks[RTC_COUNT_CALLBACK_COMPARE_3]();
		}
		/* Clear interrupt flag */
		rtc_module->MODE0.INTFLAG.reg = RTC_MODE1_INTFLAG_CMP(1 << 3);
		#endif

	} else if (interrupt_status & RTC_MODE1_INTFLAG_CMP(1 << 4)) {
		#if (RTC_NUM_OF_COMP16 > 4) || defined(__DOXYGEN__)
		/* Compare 4 interrupt */
		if (callback_mask & (1 << RTC_COUNT_CALLBACK_COMPARE_4)) {
			module->callbacks[RTC_COUNT_CALLBACK_COMPARE_4]();
		}
		/* Clear interrupt flag */
		rtc_module->MODE0.INTFLAG.reg = RTC_MODE1_INTFLAG_CMP(1 << 4);
		#endif

	} else if (interrupt_status & RTC_MODE1_INTFLAG_CMP(1 << 5)) {
		#if (RTC_NUM_OF_COMP16 > 5) || defined(__DOXYGEN__)
		/* Compare 5 interrupt */
		if (callback_mask & (1 << RTC_COUNT_CALLBACK_COMPARE_5)) {
			module->callbacks[RTC_COUNT_CALLBACK_COMPARE_5]();
		}
		/* Clear interrupt flag */
		rtc_module->MODE0.INTFLAG.reg = RTC_MODE1_INTFLAG_CMP(1 << 5);
		#endif
	}
}