Requesting interrupts in kernel space on Beaglebone

For anyone in the group who does kernel development, I’ve been working on a driver for the enhanced quadrature encoder pulse (eQEP) subsystem on the Beaglebone’s CPU. (Turns out its also the hardware as a number of their chips…). At this point I have position measurement working with up to a 1 MHz encoder pulse (its a little AVR generating the pulse train). I’d like to get some of the other features, like frequency measurement of the pulses and unit time measurement (after a specific unit of time it latches the position register to a buffer and fires an interrupt). But in order to do this I have to register a handler for the aforementioned interrupt. I know the interrupt’s vector, (79 for eQEP0, 88 for eQEP1, and 89 for eQEP2) but I don’t know how to translate this into a interrupt routine. Would I just use request_irq() with the vector number? I know you pass the IRQ number on the PC, but is it the same on ARM?

Also, in the documentation for the AM3359, SYS_CLKOUT with a prescaler is used as the source of the timer in eQEP, and for the Beaglebone, we see up to a 720 MHz clock and for the Beaglebone Black, we see up to a 1 GHz clock. Is this the frequency this signal runs at? does it vary with the current operating frequency as defined by the cpufreq module? or is this some constant manipulation of clock before multiplication for the CPU core frequency?

  • Nathaniel Lewis

Hi Nathaniel,

I’m interested in using the eQEP devices could you share some information?. I would like to capture analog signals synchonized with the encoder signal, and also be able to read the encoder position from another encoder.

Do you think is possible?

Thanks in advance,

Paco

So there are three eQEP units in the beaglebone, one per timer subsystem. Unfortunately only two of them have all their pins broken out on the original beaglebone (eQEP1 and eQEP2. eQEP0 only has channel B and the index pin broken out. renders the unit useless). The Beaglebone Black has all three broken out. The only mux options for the eQEP pins have them on the lcd_data lines so you can’t use an LCD or HDMI on either of the beaglebones. The eQEP0 pins on the black share lines with the audio controller. Just a heads up.

I’m actually putting together a kernel module (platform driver) that fits in nicely with the device tree. Its still mostly a big hack right now, but it will support the three measurement modes of the eQEP unit → absolute position, frequency measurement (counts per unit time), and pulse width - where it measures the width of the encoder pulses. But yes, what you want to do is entirely possible. I’m using the input subsystem of linux. So you’ll just listen to an /dev/input/ device like so:

/dev/input/by-path/platform-48302180.eqep-event (eQEP 1)

And when you get an event, you’d read the ADC. The issue is that the hardware wasn’t designed to alert the device a lot. For instance there is not “position changed” event from the hardware. The only way to implement that is to set the max position to 1 and listen for overflow or underflow events. At that point you loose the advantage of having the hardware because of the sheer amount of interrupts flooding the CPU, as eQEP is designed to handle up to 1 MHz input. I’ll have the sources up on my Github in a few days when I can assure people the driver doesn’t break stuff. On the kernel side of things, I’m coming up with an abstraction, a lot like the linux/pwm abstraction, because the kernel doesn’t have an abstraction for position sensors. And there are a lot of things I’d like to do with the unit, like high frequency PID control of a motor, but on the kernel side so its very responsive. I’m just trying to decouple the hardware driver from the input driver.

  • Nathaniel Lewis

Hi Nathaniel,

I have Ubuntu 13.04 in the flash and Debian Wheezy in the SD. From none of them I could access the /dev/input/by-path/platform-48302180.eqep-event, in fact I only have the I2C under by-path. I have tried to add the encoder funcionallity in the kernel 3.8.13-bone22, compiled and installed the kernel in both Linux distributions… no clue about the eqep system. Do I need to unload and load a new cape?

I would like to use some of your (wonderful) work. I’m a BBB newbie!

Kind regards,

Paco

Oh sorry about that, thats the format the driver I’m working on presents to the user. And I don’t know what encoder functionality you were looking at? The GPIO rotary encoder driver doesn’t really work on the Beaglebone. eQEP is the hardware quadrature encoder controller on the chip. As I said, I need a few days before its really ready, but I’ll send you an email with what I have currently.

Here you say that the eQEP can handle 1 MHz input but on the github page you say the clock speed is 100 MHz. Is one of these a mistake or are these not the same thing? I’m looking for the max read frequency for quadrature encoders.
-Thank You