Recently i have been experimenting with interrupts on orange pi zero plus2-H3 trying to capture data-ready pulses from an external adc on gpio PA19. The aim is to synchronize spi-read-data transactions with the incoming adc data-ready signal. First I tried to get it to work on legacy kernel 3.4 by adding the following section in to /boot/script.fex and compile the .fex file to .bin file using fex2bin:
Unfortunately i could only get it to work if i replace IRQF_TRIGGER_RISING with IRQF_TRIGGER_LOW. This was tested by issuing dmesg to obtain the irq number and then cat /proc/interrupts to monitor interrupt events on the allocated irq. At first, this gave me the impression that interrupts in the kernel are polling the pin instead of actual hardware triggering. Based on the data sheets of the sunxi H3 chipset (http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf, page 74) PA19 is interrupt capable by the setting the pinmux to PA_EINT19, function code 0x6. So i decided to do low level configuration of the pinmux by adding the following section to the module and test accordingly:
I could see in the dmesg printouts that the PA19-pin was configured properly but still i could only get interrupts to work if i use IRQF_TRIGGER_LOW.
After some reading on the Internet and instability issues with WiFi i decided to go with the latest mainline development kernel which uses device trees. Executing the kernel module with low-level register programming on the mainline kernel resulted in Kernel-oops and segmentation faults.
I modified /boot/dtb/sun8i-h3-orangepi-zeroplus.dts based on an example i found at http://geek-mag.com/posts/265668/ as follows and tested using the pulse-counter module presented at the same site:
Still the same issues, I could only get interrupts if i set IRQF_TRIGGER_LOW. After three weeks of reading, digging and diving on the Internet i had decided to test gpio-PA19 using a switch connected with a pull-up resistor to 3.3v. pressing the switch will result in grounding PA19 and hence a rising edge pulse will be generated when the switch is released. To my surprise i got rising edge interrupts to work. Now y thaughts are shifting towards hardware issues so i grabbed a scope and function generator to monitor the activities on the gpio-pin PA19.
Here are some of my findings:
Picture 1: adc_drdy_pulse_width.jpeg, pulse width 1us, frequency 2KHz - 128Khz depending on sampling frequency setup, no-interrupts detected
Picture 2: adc-pulse-frequency.jpeg
Picture 3: function-generator-pulse-50percent-duty.jpeg, frequency 50Hz, interrupts visible if i increase generator voltage to 4.3 volts. It seems that the gpio input load reduces the function-generator voltage from 3.3V to 2.7V and hence logic level voltages are not detected correctly.
Conclusions:
interrupt activity detection is lowered as the frequency increases
@10KHz no more interrupts visible
@1% pulse duty cycle of 400Hz no more interrupts visible
Questions:
1) How do i activate hardware irq sampling on PA19 in mainline kernel?
2) How do i set irq-pin sampling debounce to 24MHz on mainline kernel?
3) Can the kernel handle high speed irq's
4) Why does are irqs not triggering when i increase the pulse frequency or lower pwm duty.
5) How can i do low level register programming in mainline kernel?
Question
Ohms
Recently i have been experimenting with interrupts on orange pi zero plus2-H3 trying to capture data-ready pulses from an external adc on gpio PA19. The aim is to synchronize spi-read-data transactions with the incoming adc data-ready signal. First I tried to get it to work on legacy kernel 3.4 by adding the following section in to /boot/script.fex and compile the .fex file to .bin file using fex2bin:
This configured the pin properly as i had tested on other pins with some leds and it works. The driver code for capturing the interrupt was based on an example i found at https://github.com/tomxue/Kernel_GPIO_interrupt/blob/master/m_test.c and is as follows:
Unfortunately i could only get it to work if i replace IRQF_TRIGGER_RISING with IRQF_TRIGGER_LOW. This was tested by issuing dmesg to obtain the irq number and then cat /proc/interrupts to monitor interrupt events on the allocated irq. At first, this gave me the impression that interrupts in the kernel are polling the pin instead of actual hardware triggering. Based on the data sheets of the sunxi H3 chipset (http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf, page 74) PA19 is interrupt capable by the setting the pinmux to PA_EINT19, function code 0x6. So i decided to do low level configuration of the pinmux by adding the following section to the module and test accordingly:
I could see in the dmesg printouts that the PA19-pin was configured properly but still i could only get interrupts to work if i use IRQF_TRIGGER_LOW.
After some reading on the Internet and instability issues with WiFi i decided to go with the latest mainline development kernel which uses device trees. Executing the kernel module with low-level register programming on the mainline kernel resulted in Kernel-oops and segmentation faults.
I modified /boot/dtb/sun8i-h3-orangepi-zeroplus.dts based on an example i found at http://geek-mag.com/posts/265668/ as follows and tested using the pulse-counter module presented at the same site:
/dts-v1/; / { interrupt-parent = <0x1>; #address-cells = <0x1>; #size-cells = <0x1>; model = "Xunlong Orange Pi Zero Plus"; compatible = "xunlong,orangepi-zeroplus", "allwinner,sun8i-h3"; sst: pulse_counter { compatible = "gpio-pulse-counter"; pi_irq_counter@0 { label = "sst_PA19_pulse_counter"; pinctrl-names = "default"; pinctrl-0 = <&ext_counter_PA19>; /* bank: 0, pin 19, function 6 */ gpios = <&pio 0 19 6>; /* interrupt properties may be omitted if used gpios property */ interrupt-parent = <&pio>; interrupt-names = "counter-edge-rising"; interrupts = <19 0>; /* PA19 / EINT19 / rising edge*/ }; }; .... pio: pinctrl@01c20800 { reg = <0x1c20800 0x400>; interrupts = <0x0 0xb 0x4 0x0 0x11 0x4>; clocks = <0x2 0x36 0x3 0x5>; clock-names = "apb", "hosc", "losc"; gpio-controller; #gpio-cells = <0x3>; interrupt-controller; #interrupt-cells = <0x3>; compatible = "allwinner,sun8i-h3-pinctrl"; linux,phandle = <0xd>; phandle = <0xd>; .... ext_counter_PA19: sst_pins@0 { allwinner,pins = "PA19"; allwinner,function = "gpio_in"; drive = <0>; pull = <1>; }; }; };
Still the same issues, I could only get interrupts if i set IRQF_TRIGGER_LOW. After three weeks of reading, digging and diving on the Internet i had decided to test gpio-PA19 using a switch connected with a pull-up resistor to 3.3v. pressing the switch will result in grounding PA19 and hence a rising edge pulse will be generated when the switch is released. To my surprise i got rising edge interrupts to work. Now y thaughts are shifting towards hardware issues so i grabbed a scope and function generator to monitor the activities on the gpio-pin PA19.
Here are some of my findings:
Conclusions:
interrupt activity detection is lowered as the frequency increases
@10KHz no more interrupts visible
@1% pulse duty cycle of 400Hz no more interrupts visible
Questions:
1) How do i activate hardware irq sampling on PA19 in mainline kernel?
2) How do i set irq-pin sampling debounce to 24MHz on mainline kernel?
3) Can the kernel handle high speed irq's
4) Why does are irqs not triggering when i increase the pulse frequency or lower pwm duty.
5) How can i do low level register programming in mainline kernel?
Any help would be appreciated
Link to comment
Share on other sites
19 answers to this question
Recommended Posts