Problem with interrupt driven pins



Recommended Posts

Hello everyone.


From some time ago I´m working in an application that comunicates with some external devices, using GPIOs.  With this aim, I´ve programmed my own driver with its methods, whose are automatic loaded at startup.


My hardware is a BananaPi m2u, and kernel version is 5.4.35-sunxi.


Now, I´ve to read an external HW that has 2 data lines, whose idle state is "high" and once per minute sends  a packet of 26 bits of data. One of these lines is a Data0 signal, and the other is Data1 signal. Every pulse is around 100us, and there is an idle interval of about 2ms between one bit and the next. There is no way for data line 0 and data line 1to be active simultaneously.


I`ve writed a new driver using Falling edge interrupts, data lines are connected to BMC224 (Pin 31 of header) & BCM225 (Pin 33 of header).


Now I´m having troubles when pulses of external hardware arrives, I´m always loosing some of this 26 pulses. (I receive from 10 to 16 pulses, and lose the rest).


I'm helping myself by using


tail -f /cat/log/syslog


to watch kernel messages (I used some temporally printk inside interrupt handler, just to debug). Here is a screenshot where you can see there is 6 correct received pulses before my problem arises (between time 829.536885 and 829.547099)


root@bananapim2ultra:/home/pi/TK401# tail -f /var/log/syslog
May 21 19:45:01 localhost CRON[1923]: (root) CMD (/usr/lib/armbian/armbian-truncate-logs)
May 21 19:45:01 localhost wpa_supplicant[1138]: wlan0: Failed to initiate sched scan
May 21 19:45:16 localhost kernel: [  817.446427] usb 4-1: USB disconnect, device number 14
May 21 19:45:18 localhost kernel: [  819.128519] usb 4-1: new low-speed USB device number 15 using ohci-platform
May 21 19:45:18 localhost kernel: [  819.355553] usb 4-1: New USB device found, idVendor=0458, idProduct=003a, bcdDevice= 1.00
May 21 19:45:18 localhost kernel: [  819.355563] usb 4-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
May 21 19:45:18 localhost kernel: [  819.355569] usb 4-1: Product: USB Optical Mouse
May 21 19:45:18 localhost kernel: [  819.355575] usb 4-1: Manufacturer: Genius
May 21 19:45:18 localhost kernel: [  819.362882] input: Genius USB Optical Mouse as /devices/platform/soc/1c1c400.usb/usb4/4-1/4-1:1.0/0003:0458:003A.0010/input/input18
May 21 19:45:18 localhost kernel: [  819.363214] hid-generic 0003:0458:003A.0010: input,hidraw2: USB HID v1.11 Mouse [Genius USB Optical Mouse] on usb-1c1c400.usb-1/input0
May 21 19:45:29 localhost kernel: [  829.536885] 0
May 21 19:45:29 localhost kernel: [  829.538920] 0
May 21 19:45:29 localhost kernel: [  829.540969] 1
May 21 19:45:29 localhost kernel: [  829.543009] 1
May 21 19:45:29 localhost kernel: [  829.545057] 1
May 21 19:45:29 localhost kernel: [  829.547099] 1
May 21 19:45:29 localhost kernel: [  829.557355] 0
May 21 19:45:29 localhost kernel: [  829.559398] 1
May 21 19:45:29 localhost kernel: [  829.561445] 1
May 21 19:45:29 localhost kernel: [  829.563487] 0


But suddenly, after sixth bit, there is no more handled pulses for a time period of 10ms, IMHO that looks like some higher hierarchy proccess is blocking my interrupts, and so, there is a lot of pulses lost. Also if I look at




I can see there was 4 received interrupts from D0 (CPU0) and 6 from D1 (CPU0), so there is a match between info provided in both files.


My testing code from user space is just a big sleep, so I think there is nothing there that can cause problems.


Trying to understand where is this problem originated, I installed WiringPi (a library that provides access to GPIO, and includes interrupt driven inputs), I had to modify some pieces of code, cause they don´t like to work with "weird fruits Pi". With this apporoach I obtained a similar result (I loose about the same number of data bits), however if I use it in a Raspberry with Raspbian, I can read hundreeds od data packets with no looses at all.


Could any of you please indicate where I can start looking for my error?


Many thanks in advance!



Link to post
Share on other sites

Armbian is a community driven open source project. Do you like to contribute your code?

I think I found a solution to this problem, based on a post I read in some forum and confirmed in this thread (Really thanks to all who helped there).



Base clock for GPIO interrupts was configured to work in low speed (LOSC 32KHz), and then 10us pulses can frequently be unnoticed. 


I installed devmem2, and wrote a new value of 1 in bit 0 (PIO_INT_CLK_SELECT) of PIO_INT_DEB (see details below)


PIO Base Address = 0x01C20800
PIO_INT_DEB = 0x0218


So, final address:


0x01C20800 + 0x0218 = 0x01C20A18


And now I can read 26 bits of lossless data.


So, now I just have to decide if I work with this approach, or if, like martinayotte said, I use a dedicated subsystem to deal with it (this second approach will give me more flexibility, cause we frequently have to work with other standards that aren't Wiegand at all).


Just in case I keep the first option, based in your experience. What is the best way to have EINT clock modified to HOSC? Should I work with my already modified .dts file? ( I had to change the original .dts file to add ALSA record support and enable UART2 & UART5).


And one more question, do you think that modified EINT clock will cause some undesirable secondary effect? I know no one is a clairvoyant, but I'm just wondering if there are any obvious consequences that I'm missing.


Thanks for your recomendation.




Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.