Skip to content

Feather Express M0 - pulseio.PulseIN - freezes at high frequency #516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Apotessar opened this issue Jan 9, 2018 · 6 comments
Closed

Feather Express M0 - pulseio.PulseIN - freezes at high frequency #516

Apotessar opened this issue Jan 9, 2018 · 6 comments
Assignees
Milestone

Comments

@Apotessar
Copy link

Apotessar commented Jan 9, 2018

Test Case:
Messure Light trough a light-to-frequency-coverter.

Test Setup:
Feather Express M0 - Circuit Python 2.2.0
TSL235R-LF
https://www.sparkfun.com/datasheets/Sensors/Imaging/TSL235R-LF.pdf
connected 3V to VDD, GND to GND and Output to D12

> #Feather Express M0 connected 3V to VDD, GND to GND and Output to D12
 import board
 from board import*
 import digitalio
 import busio
 import adafruit_ssd1306
 import time
 import analogio
 import pulseio

 i2c = busio.I2C(SCL, SDA)
 display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
 pulses = pulseio.PulseIn(board.D12, maxlen=20)

 while True:
     time.sleep(1)
     pulse = 500000/float(pulses[0])
     display.fill(0)
     display.text(str(pulse),0,0)
     print(pulse)
     display.show()

Error:
Board do not response, crash or disconnect while the input frequency is above 25 kHz.
The specific freqency could not be determinated.
While covering the Converter it is sometimes possible to recover the board. Outwise a reset is nessessary.

Source:
https://forums.adafruit.com/viewtopic.php?f=60&t=129061

@tannewt tannewt added this to the 3.0 milestone Jan 9, 2018
@sommersoft
Copy link

Now that PulseIn is in 3.0 (with updated tick_delay to boot), I decided to give this a run. I don't have a sensor available that will pulse >25kHz, so I used a Feather M0 Express with PWMOut.

Feather M0 Express was running this PWMOut script. 50% duty cycle, starting at 8kHz with incremental increases.

ItsyBitsy M0 Express (w/JLink) was running this PulseIn script. This version has a max_len=20, but also tested with default of 2 with the same results.

I got up to 64kHz before the REPL froze. After a few runs, I noticed that it always froze when the result was <20. But, after scrolling back through the terminal, 19's & 18's appeared with no effect.

I'm still narrowing down where to look specifically, but something interesting is showing up. I've had the Feather PWMOut script halted, and the jumper removed, for over 20 minutes. When I pause the ItsyBitsy and step-over in Atmel Studio, the callstack shows that it's cycling through instances of EIC_Handler. The REPL is also still unresponsive.

@sommersoft
Copy link

I'm still narrowing down where to look specifically, but something interesting is showing up. I've had the Feather PWMOut script halted, and the jumper removed, for over 20 minutes. When I pause the ItsyBitsy and step-over in Atmel Studio, the callstack shows that it's cycling through instances of EIC_Handler. The REPL is also still unresponsive.

CORRECTION: I thought I had the jumper removed. After actually removing it, the calls to EIC_Handler subsided. REPL became responsive....

@tannewt
Copy link
Member

tannewt commented Apr 30, 2018

It sounds like we're hitting the limit for how fast we can execute the interrupt handler. Are the pulse lengths close enough that we can determine the input frequency?

We could add another C class specifically designed to measure an input frequency. It wouldn't need interrupts, we could have a counter measure input edges or something.

@sommersoft
Copy link

sommersoft commented Apr 30, 2018

That's pretty much the conclusion I've come to today. I removed the pulsein.clear() from the script, thinking that the interrupt disabling was a culprit. That got me up to 128kHz before locking up.

Setting a breakpoint in Atmel Studio on pulsein_interrupt_handler proved interesting. With continuous output of total_diff, last_ms, and last_us, it shut down the serial comms to the terminal, but kept chugging right along past 128kHz. The only problem: total_diff never gets below 18 and tick_ms outputs a steady number (never increases). Using the same breakpoint output for SysTick_Handler->ticks_ms on a subsequent run resulted in a lockup at 128kHz.

So, yeah, I think we're getting stuck in an endless EIC interrupt loop.

Could we use the TC peripheral? During some searches I saw that it could be used for PWM In...but I didn't dig deep into it. Might also run into similar limitations with the EVSYS...

EDIT: TC peripheral...not TCC

@sommersoft
Copy link

I've got a FrequencyIn core module working!

Using the same PWMOut script as above, I'm now getting up to 512kHz before the REPL locks up. Using this script to capture the frequency in:

import board, pulseio
tc = pulseio.FrequencyIn(board.D7)
while True:
    if (tc.value > 0):
        freq = 48000000 / tc.value  // currently only working on SAMD21
        print(freq)

I have the TC prescaler set to 1 right now, and I think it may be hitting max COUNTER. Will continue to debug it. Will also look into a way to catch the upper bound and raise an exception (most likely the interrupt error flag).

Progress at least.

@ladyada
Copy link
Member

ladyada commented May 20, 2018

awesome!

@tannewt tannewt self-assigned this May 24, 2018
dhalbert pushed a commit that referenced this issue Jun 8, 2018
We now track the last time the background task ran and bail on the
PulseIn if it starves the background work. In practice, this
happens after the numbers from pulsein are no longer accurate.

This also adjusts interrupt priorities so most are the lowest level
except for the tick and USB interrupts.

Fixes #516 and #876
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants