Created
May 25, 2018 17:52
-
-
Save sommersoft/5ad6cd326409dbca29de72ddd9fd32ab to your computer and use it in GitHub Desktop.
FrequencyIn_NVIC_Fail_Graceful
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static uint8_t MAX_FREQUENCY = CONF_CPU_FREQUENCY / 512000; | |
void frequencyin_interrupt_handler(uint8_t index) { | |
Tc* tc = tc_insts[index]; | |
if (!tc->COUNT16.INTFLAG.bit.MC0) return; // false trigger | |
pulseio_frequencyin_obj_t* self = active_frequencyins[index]; | |
// since we use EVACT.PPW, the Period is put into the CC[0] register | |
// and that's all we need. CC[1] will contain the Pulse Width. | |
uint16_t freq = tc->COUNT16.CC[0].bit.CC; | |
self->frequency = freq; | |
// we'll read CC[1] to make sure all of the INTFLAG registers are | |
// also cleared. CC[1] will contain the Pulse Width measurement, which | |
// we won't use. of course, we could use it in the future (replace PulseIn?). | |
self->pulse_width = tc->COUNT16.CC[1].bit.CC; | |
if (freq < MAX_FREQUENCY && freq > 0){ | |
self->max_frequency_captured = true; | |
} else { | |
self->max_frequency_captured = false; | |
} | |
if (tc->COUNT16.INTFLAG.bit.ERR) { | |
err_count++; | |
tc->COUNT16.INTFLAG.reg |= TC_INTFLAG_ERR; | |
} | |
if (tc->COUNT16.INTFLAG.bit.OVF) { | |
ovf_count++; | |
tc->COUNT16.INTFLAG.reg |= TC_INTFLAG_OVF; | |
} | |
//err_count += tc->COUNT16.INTFLAG.bit.ERR; | |
//ovf_count += tc->COUNT16.INTFLAG.bit.OVF; | |
} | |
uint16_t common_hal_pulseio_frequencyin_get_item(pulseio_frequencyin_obj_t* self) { | |
//common_hal_mcu_disable_interrupts(); | |
#ifdef SAMD21 | |
NVIC_DisableIRQ(self->TC_IRQ); | |
NVIC_DisableIRQ(EIC_IRQn); | |
#endif | |
if (self->max_frequency_captured) { // we've experienced a capture above what we can detect | |
//common_hal_mcu_disable_interrupts(); | |
common_hal_pulseio_frequencyin_pause(self); // pause any further captures | |
//common_hal_mcu_enable_interrupts(); | |
#ifdef SAMD21 | |
NVIC_ClearPendingIRQ(self->TC_IRQ); | |
NVIC_EnableIRQ(self->TC_IRQ); | |
NVIC_ClearPendingIRQ(EIC_IRQn); | |
NVIC_EnableIRQ(EIC_IRQn); | |
#endif | |
mp_raise_RuntimeError("Frequency captured is above capability. Capture Paused."); | |
} | |
//common_hal_mcu_enable_interrupts(); | |
#ifdef SAMD21 | |
NVIC_EnableIRQ(self->TC_IRQ); | |
NVIC_EnableIRQ(EIC_IRQn); | |
#endif | |
//uint16_t value = CONF_CPU_FREQUENCY / self->frequency; | |
//return value; | |
return self->frequency; | |
} | |
void common_hal_pulseio_frequencyin_pause(pulseio_frequencyin_obj_t* self) { | |
Tc *tc = tc_insts[self->tc_index]; | |
if (!tc->COUNT16.EVCTRL.bit.TCEI) { | |
return; | |
} | |
tc->COUNT16.EVCTRL.bit.TCEI = 0; | |
#ifdef SAMD21 // pause the EIC | |
uint32_t masked_value = EIC->EVCTRL.vec.EXTINTEO; | |
EIC->EVCTRL.vec.EXTINTEO = masked_value | (0 << self->channel); | |
#endif | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment