Skip to content

Instantly share code, notes, and snippets.

@sommersoft
Created May 25, 2018 17:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sommersoft/5ad6cd326409dbca29de72ddd9fd32ab to your computer and use it in GitHub Desktop.
Save sommersoft/5ad6cd326409dbca29de72ddd9fd32ab to your computer and use it in GitHub Desktop.
FrequencyIn_NVIC_Fail_Graceful
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