/** * \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); }
/** * \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; }
/** * \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; }
/** * \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 } }