GeeXboX

GPIO remote receive on Cubox-i

April 6th, 2016

Home › Forums › GeeXboX on ARM SoCs › GPIO remote receive on Cubox-i

This topic contains 7 replies, has 2 voices, and was last updated by Warped Rudi 1 day, 7 hours ago.

Viewing 8 posts – 1 through 8 (of 8 total)
  • Author
    Posts
  • #10423

    michal
    Member

    I have a cubox-i used as a media center and PVR. Currently I have one annoying problem – when tvheadend is recording OTA TV (using an HVR-950Q ATSC tuner, au0828 module), the GPIO remote receiver doesn’t work. My remote uses the RC6 protocol. I enabled debugging in the RC6 decoder module. Comparing the debug outputs when the tuner isn’t recording to when it is, it looks like the timing is (nearly) identical for the first few dozen pulses, but then it appears that some transitions are lost. The two segments pasted in below start at the same point in the same button code. The long (erroneous) 1355us space in the second trace makes me think that the GPIO interrupt isn’t getting serviced quickly enough.

    Apr 05 22:33:39 geexbox kernel: ir_rc6_decode: RC6 decode started at state 6 (424us space)
    Apr 05 22:33:39 geexbox kernel: ir_rc6_decode: RC6 decode started at state 7 (456us pulse)
    Apr 05 22:33:39 geexbox kernel: ir_rc6_decode: RC6 decode started at state 6 (12us pulse)
    Apr 05 22:33:39 geexbox kernel: ir_rc6_decode: RC6 decode started at state 6 (398us space)
    Apr 05 22:33:39 geexbox kernel: ir_rc6_decode: RC6 decode started at state 7 (476us pulse)
    Apr 05 22:33:39 geexbox kernel: ir_rc6_decode: RC6 decode started at state 6 (32us pulse)
    Apr 05 22:33:39 geexbox kernel: ir_rc6_decode: RC6 decode started at state 6 (437us space)

    —————————-

    Apr 05 22:32:45 geexbox kernel: ir_rc6_decode: RC6 decode started at state 6 (428us space)
    Apr 05 22:32:45 geexbox kernel: ir_rc6_decode: RC6 decode started at state 7 (449us pulse)
    Apr 05 22:32:45 geexbox kernel: ir_rc6_decode: RC6 decode started at state 6 (5us pulse)
    Apr 05 22:32:45 geexbox kernel: ir_rc6_decode: RC6 decode started at state 6 (1355us space)
    Apr 05 22:32:45 geexbox kernel: ir_rc6_decode: RC6 decode failed at state 6 (1355us space)

    Is it possible that using the tuner in causing GPIO interrupts to be missed?

    This problem is a regression. In kernels a half a year or so ago I didn’t see this issue. I believe this coincided with the switch from the 3.14.14_linaro-stable kernels to the mx6-sr versions.

    Is there some simple way to fiddle with the interrupt priorities (devmem?)

    #10424

    Warped Rudi
    Moderator

    Unfortunately I don’t have a good idea for you. It is definitively possible that other activity in the system can block/defer interrupt processing. And (mis-)using a GPIO for IR decoding is a sensitive thing…

    But I’m not so sure that this was so much better with the older kernels. I think there were interrupt latentcy problems with these as well (network traffic affecting audio, especially when running at 1000Mbps while transmitting DTS-HD or 192/24 multichannel). Does your tvheadend record to a network drive?

    Edit: I just remembered that we have this ‘irqbalance’ tool installed on the Cubox. It is supposed to help to evenly spread interrupt load on all cores. Maybe it’s possible to play with this. But that’s just a shot in the dark…

    #10425

    michal
    Member

    tvheadend here is recording to a SATA disk on the E-SATA connector, so there should be no network traffic. Playback of recorded video from the same disk is no problem – it just seems to be the usb tv-tuner that causes problems.

    I will look in to irqbalance – thanks for the pointer. I realized I have packages from the linaro kernels lying around where I don’t think I saw this problem. Is it “safe” to force install an old kernel. say from Aug 2015, or are there other changes, eg in systemd, that will cause problems on those kernels?

    Thanks,

    #10426

    michal
    Member

    Wow. Thank you is in order here! irqbalance if anything is part of the problem. Looking at /proc/interrupts it becomes obvious that almost all interrupts for almost everything were all being handled on cpu0. The GPIO interrupt seems unable to be tied to a specific cpu (write error when writing to /proc/irq/*/smp_affinity), but I can set the usb controller interrupts and the “galcore interrupt service” to leave cpu 0 alone, and that appears to solve my problem. So what I did was:
    systemctl stop irqbalanace
    systemctl disable irqbalance
    then,
    echo e > /proc/irq/72/smp_affinity
    echo e > /proc/irq/75/smp_affinity
    echo e > /proc/irq/41/smp_affinity

    and it seems all is well.

    I have rather a lot to say about the RC6 decoder being totally screwed up for some subset of RC6 (RC6A) remote controls (of which I have one) so that it produces spurious key repeats, but that’s an upstream problem, and I’ve patched it so it works nicely for me (but won’t work in a general way)…

    Thanks for the pointer to irqbalance, it led me right to a solution!

    #10427

    Warped Rudi
    Moderator

    Nice finding! To be honest: I never really looked at the details of irqbalance. Some kernel guru said we should use it and so we did. Maybe we do not set it up in the right way. Looks like this needs some investigation…

    About RC6: I test this from time to time with an original Microsoft MCE remote. An unmodified upstream kernel, usually produces the problem that when two different keys are pressed quickly after each other, the first key is doubled while the second is ignored. We use this patch as workaround, but it does not fully fix the behaviour and is – as you said for your patch – not a general solution. I got a second remote here (Zotac), which claims to be RC6 as well and which seems to expose a problem related to the toggle bit. I have not tried to debug this because I normally use CEC…

    #10428

    michal
    Member

    It doesn’t look to me as though there is much to configure in irqbalance. I didn’t go through it carefully, but it looks to me as though you just start it and it wakes up every so often and looks at how many interrupts have occurred on each irq and then it plays with assigning them to the various cpus. It looks though like the ir controller produces so few interrupts most of the time that it just gets lost in the noise.

    I did go through the RC6 decoder very carefully a year or so ago because I had a similar problem to what you describe – my fix though reverts your patch, and actually lets key repeat work quickly. It does hardcode the number of bits expected – different RC6A remotes produce 20, 24, or 32 bit codes apparently.

    My patch is in three pieces:

    
    --- drivers/media/rc/rc-main.c~	2015-08-30 21:06:49.297777262 -0700
    +++ drivers/media/rc/rc-main.c	2015-08-30 21:12:59.494142971 -0700
    @@ -31,7 +31,7 @@
     #define IR_TAB_MAX_SIZE	8192
     /* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
    -#define IR_KEYPRESS_TIMEOUT 550
    +#define IR_KEYPRESS_TIMEOUT 150
     /* Used to keep track of known keymaps */
     static LIST_HEAD(rc_map_list);
    --- drivers/media/rc/ir-raw.c~	2014-12-17 06:56:17.000000000 -0800
    +++ drivers/media/rc/ir-raw.c	2015-08-30 21:13:40.533739458 -0700
    @@ -116,7 +116,7 @@
     	now = ktime_get();
     	delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
    -	delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]);
    +	delay = MS_TO_NS(20);
     	/* Check for a long duration since last event or if we're
     	 * being called for the first time, note that delta can't
    
    --- drivers/media/rc/ir-rc6-decoder.c~	2014-12-17 06:56:17.000000000 -0800
    +++ drivers/media/rc/ir-rc6-decoder.c	2015-08-30 21:15:32.222640707 -0700
    @@ -188,7 +188,7 @@
     			data->wanted_bits = RC6_0_NBITS;
     			break;
     		case RC6_MODE_6A:
    -			data->wanted_bits = RC6_6A_NBITS;
    +			data->wanted_bits = 24;
     			break;
     		default:
     			IR_dprintk(1, "RC6 unknown moden");
    @@ -204,6 +204,11 @@
     				if (ev.pulse)
     					data->body |= 1;
     			}
    +			if (data->count == data->wanted_bits){
    +			  ev.pulse = 0;
    +			  data->state = STATE_FINISHED;
    +			  goto again;
    +			}
     			data->state = STATE_BODY_BIT_END;
     			return 0;
     		} else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse &&
    

    The MCE I believe uses 32 bits, and looks to be handled somewhat separately. Its possible that just changing the wanted_bits to 32 in my patch would make the MCE work well…

    #10430

    Warped Rudi
    Moderator

    That’s interresting. I guess I’ll have a look at this when I find some time (and the other RC6 remote that is currently ‘missing in action’).

    #10433

    Warped Rudi
    Moderator

    I never really looked at the details of irqbalance.

    It appears that our irqbalance package is rater antique. Maybe a more recent one will do a better job…

Viewing 8 posts – 1 through 8 (of 8 total)

You must be logged in to reply to this topic.

Comments are closed.