Skip to content
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

Random channel assignment and intermittent detection #1

Open
Dloranger opened this issue Mar 27, 2018 · 14 comments
Open

Random channel assignment and intermittent detection #1

Dloranger opened this issue Mar 27, 2018 · 14 comments

Comments

@Dloranger
Copy link

I am seeing intermittent detection of the octo card between boots, and random channel assignment within each iteration of speaker-test utility.

Note during these tests the hardware is sitting in isolation on my backplane board with the scope attached. Nothing is disturbing the hardware in any way except reboots which are done via command line and power cycles are done via killing the DC supply. I have checked the signals and everything is nice clean digital pulses coming from the pi3.

I am testing using the latest distro via apt-get update & apt-get upgrade (effective Mar 1, 2018).

I am using a customized version of the driver as discussed via email, where the clocks are never disabled. I don't expect this to be relevant, but just in case

The command I am running to test is

speaker-test -c 8 -t sine -f 500

I am measuring what I consider channel 0 with an oscilloscope in the below tests

power cycle #1, card detected & loaded, signal detected during channel 2
reboot cycle #1, card detected, but not loaded into kernel

[ 9.551263] audioinjector-octo soc:sound: ASoC: CODEC DAI cs42448 not registered - will retry
[ 9.551278] audioinjector-octo soc:sound: snd_soc_register_card failed (-517)
reboot cycle #2, card detected, but not loaded into kernel
[ 7.941254] audioinjector-octo soc:sound: ASoC: CODEC DAI cs42448 not registered - will retry
[ 7.941270] audioinjector-octo soc:sound: snd_soc_register_card failed (-517)

reboot cycle #3, card detected & loaded,
signal detected during channel 6 on speaker test session #1
signal detected during channel 0 on speaker test session #2
signal detected during channel 2 on speaker test session #3
signal detected during channel 2 on speaker test session #4
signal detected during channel 0 on speaker test session #5
signal detected during channel 0 on speaker test session #6 // test killed while channel 5 was playing
signal detected during channel 4 on speaker test session #7 // test killed while channel 4 was playing
signal detected during channel 2 on speaker test session #8 // test killed while channel 2 was playing
signal detected during channel 6 on speaker test session #6 // test killed while channel 5 was playing

Below find the DTS and config.txt that I am using, I can't upload as files for some reason, invalid file format error

Here is the DTS that I am using which includes loading up 3x MCP23017 gpio expanders, these are all working perfectly.

/dts-v1/;
/plugin/;

/ {
compatible = "brcm,bcm2708";

fragment@0 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};

fragment@1 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

cs42448: cs42448@48 {
#sound-dai-cells = <0>;
compatible = "cirrus,cs42448";
reg = <0x48>;
clocks = <&cs42448_mclk>;
clock-names = "mclk";
VA-supply = <&vdd_5v0_reg>;
VD-supply = <&vdd_3v3_reg>;
VLS-supply = <&vdd_3v3_reg>;
VLC-supply = <&vdd_3v3_reg>;
status = "okay";
};

cs42448_mclk: codec-mclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <49152000>;
};
};
};

fragment@2 {
target = <&sound>;
__overlay__ {
compatible = "ai,audioinjector-octo-soundcard";
mult-gpios = <&gpio 27 0>, <&gpio 22 0>, <&gpio 23 0>,
<&gpio 24 0>;
reset-gpios = <&gpio 5 0>;
i2s-controller = <&i2s>;
codec = <&cs42448>;
status = "okay";
};
};

// Definitions for MCP23017 Gpio Extenders from Microchip Semiconductor

fragment@3 {
target = <&gpio>;
__overlay__ {
mcp23017_pins: mcp23017_pins {
brcm,pins = <24>;
brcm,function = <0>;
};
};
};

fragment@4 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;

mcp20:mcp23017@20 {
compatible = "microchip,mcp23017";
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;

interrupt-parent = <&gpio>;
interrupts = <12 2>;
interrupt-controller;
#interrupt-cells=<2>;
microchip,irq-mirror;
status = "okay";
};
};
};

fragment@5 {
target = <&i2c1>;
__overlay__ { 
#address-cells = <1>; 
#size-cells = <0>;

mcp21:mcp23017@21 {
compatible = "microchip,mcp23017";
reg = <0x21>;
gpio-controller;
#gpio-cells = <2>;

interrupt-parent = <&gpio>;
interrupts = <16 2>;
interrupt-controller;
#interrupt-cells=<2>;
microchip,irq-mirror;
status = "okay";
};
};
};

fragment@6 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;

mcp22:mcp23017@22 {
compatible = "microchip,mcp23017";
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;

interrupt-parent = <&gpio>;
interrupts = <6 2>;
interrupt-controller;
#interrupt-cells=<2>;
microchip,irq-mirror;
status = "okay";
};
};
};
fragment@7 {
target = <&gpio>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <&my_pins>;

my_pins: my_pins {
brcm,pins = <6 12 16>; /* gpio no. */
brcm,function = <0 0 0>; /* 0:in, 1:out */
brcm,pull = <2 2 2>; /* 2:up 1:down 0:none */
};
};
};
};

Here is the config.txt file I am using

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
dtparam=i2s=on
dtparam=spi=on

# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi

# Additional overlays and parameters are documented /boot/overlays/README

# Enable audio (loads snd_bcm2835)
#dtparam=audio=on

#usb max current
usb_max_current=1

#use the gpio implementation of the I2C bus to handle clock stretching
#dtoverlay=i2c-gpio
dtparam=i2c1_baudrate=200000


#Enable FE-Pi Overlay
#dtoverlay=fe-pi-audio
dtoverlay=i2s-mmap

#Enable mcp3008 adc overlay
#dtoverlay=mcp3008:spi0-0-present,spi0-0-speed=3600000

#use the UART for GPS
enable_uart=1

#dtoverlay=audioinjector-addons
dtoverlay=pi-repeater-6x-mcp23017

some additional information. I turned on device tree debugging (dtdebug=1) and read the logs

On a bad boot (not loaded, but registers on i2c) I get the exact same messages (excluding time stamps). My I2C GPIO expanders which are loaded after the octo in the same device tree blob, are just fine however.

Bad boot

pi@PI-REPEATER-2X:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: UU UU UU -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

good boot

pi@PI-REPEATER-2X:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: UU UU UU -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

relevant part of the logs...

001964.547: Loaded overlay 'pi-repeater-6x-mcp23017'
001964.610: dtdebug: Found fragment 0 (offset 36)
001968.076: dtdebug: merge_fragment(/soc/i2s@7e203000,/fragment@0/__overlay__)
001968.101: dtdebug: +prop(status)
001969.958: dtdebug: merge_fragment() end
001970.016: dtdebug: Found fragment 1 (offset 112)
001976.737: dtdebug: merge_fragment(/soc/i2c@7e804000,/fragment@1/__overlay__)
001976.765: dtdebug: +prop(#address-cells)
001978.261: dtdebug: +prop(#size-cells)
001979.764: dtdebug: +prop(status)
001985.133: dtdebug: merge_fragment(/soc/i2c@7e804000/cs42448@48,/fragment@1/__overlay__/cs42448@48)
001985.158: dtdebug: +prop(#sound-dai-cells)
001986.720: dtdebug: +prop(compatible)
001988.189: dtdebug: +prop(reg)
001989.686: dtdebug: +prop(clocks)
001991.226: dtdebug: +prop(clock-names)
001992.803: dtdebug: +prop(VA-supply)
001994.737: dtdebug: +prop(VD-supply)
001996.689: dtdebug: +prop(VLS-supply)
001998.656: dtdebug: +prop(VLC-supply)
002000.639: dtdebug: +prop(status)
002002.302: dtdebug: +prop(linux,phandle)
002004.332: dtdebug: +prop(phandle)
002005.966: dtdebug: merge_fragment() end
002010.056: dtdebug: merge_fragment(/soc/i2c@7e804000/codec-mclk,/fragment@1/__overlay__/codec-mclk)
002010.084: dtdebug: +prop(compatible)
002011.565: dtdebug: +prop(#clock-cells)
002013.110: dtdebug: +prop(clock-frequency)
002014.735: dtdebug: +prop(linux,phandle)
002016.702: dtdebug: +prop(phandle)
002018.268: dtdebug: merge_fragment() end
002018.298: dtdebug: merge_fragment() end
002018.412: dtdebug: Found fragment 2 (offset 560)
002030.501: dtdebug: merge_fragment(/soc/sound,/fragment@2/__overlay__)
002030.528: dtdebug: +prop(compatible)
002031.562: dtdebug: +prop(mult-gpios)
002033.058: dtdebug: +prop(reset-gpios)
002034.580: dtdebug: +prop(i2s-controller)
002036.126: dtdebug: +prop(codec)
002037.693: dtdebug: +prop(status)
002038.770: dtdebug: merge_fragment() end
002038.836: dtdebug: Found fragment 3 (offset 796)
002040.769: dtdebug: merge_fragment(/soc/gpio@7e200000,/fragment@3/__overlay__)
002044.444: dtdebug: merge_fragment(/soc/gpio@7e200000/mcp23017_pins,/fragment@3/__overlay__/mcp23017_pins)
002044.473: dtdebug: +prop(brcm,pins)
002046.572: dtdebug: +prop(brcm,function)
002048.698: dtdebug: +prop(linux,phandle)
002051.202: dtdebug: +prop(phandle)
002053.315: dtdebug: merge_fragment() end
002053.345: dtdebug: merge_fragment() end
002053.423: dtdebug: Found fragment 4 (offset 940)
002060.500: dtdebug: merge_fragment(/soc/i2c@7e804000,/fragment@4/__overlay__)
002060.525: dtdebug: +prop(#address-cells)
002062.087: dtdebug: +prop(#size-cells)
002068.090: dtdebug: merge_fragment(/soc/i2c@7e804000/mcp23017@20,/fragment@4/__overlay__/mcp23017@20)
002068.117: dtdebug: +prop(compatible)
002069.639: dtdebug: +prop(reg)
002071.203: dtdebug: +prop(gpio-controller)
002072.807: dtdebug: +prop(#gpio-cells)
002074.428: dtdebug: +prop(interrupt-parent)
002075.999: dtdebug: +prop(interrupts)
002077.607: dtdebug: +prop(interrupt-controller)
002079.254: dtdebug: +prop(#interrupt-cells)
002080.906: dtdebug: +prop(microchip,irq-mirror)
002082.981: dtdebug: +prop(status)
002084.710: dtdebug: +prop(linux,phandle)
002086.815: dtdebug: +prop(phandle)
002088.529: dtdebug: merge_fragment() end
002088.571: dtdebug: merge_fragment() end
002088.665: dtdebug: Found fragment 5 (offset 1252)
002095.868: dtdebug: merge_fragment(/soc/i2c@7e804000,/fragment@5/__overlay__)
002095.896: dtdebug: +prop(#address-cells)
002097.488: dtdebug: +prop(#size-cells)
002103.764: dtdebug: merge_fragment(/soc/i2c@7e804000/mcp23017@21,/fragment@5/__overlay__/mcp23017@21)
002103.789: dtdebug: +prop(compatible)
002105.334: dtdebug: +prop(reg)
002106.917: dtdebug: +prop(gpio-controller)
002108.560: dtdebug: +prop(#gpio-cells)
002110.207: dtdebug: +prop(interrupt-parent)
002111.808: dtdebug: +prop(interrupts)
002113.443: dtdebug: +prop(interrupt-controller)
002115.110: dtdebug: +prop(#interrupt-cells)
002116.791: dtdebug: +prop(microchip,irq-mirror)
002118.904: dtdebug: +prop(status)
002120.670: dtdebug: +prop(linux,phandle)
002122.790: dtdebug: +prop(phandle)
002124.517: dtdebug: merge_fragment() end
002124.560: dtdebug: merge_fragment() end
002124.651: dtdebug: Found fragment 6 (offset 1564)
002132.634: dtdebug: merge_fragment(/soc/i2c@7e804000,/fragment@6/__overlay__)
002132.660: dtdebug: +prop(#address-cells)
002134.275: dtdebug: +prop(#size-cells)
002140.797: dtdebug: merge_fragment(/soc/i2c@7e804000/mcp23017@22,/fragment@6/__overlay__/mcp23017@22)
002140.825: dtdebug: +prop(compatible)
002142.396: dtdebug: +prop(reg)
002144.005: dtdebug: +prop(gpio-controller)
002145.662: dtdebug: +prop(#gpio-cells)
002147.337: dtdebug: +prop(interrupt-parent)
002148.972: dtdebug: +prop(interrupts)
002150.632: dtdebug: +prop(interrupt-controller)
002152.327: dtdebug: +prop(#interrupt-cells)
002154.042: dtdebug: +prop(microchip,irq-mirror)
002156.174: dtdebug: +prop(status)
002157.958: dtdebug: +prop(linux,phandle)
002160.102: dtdebug: +prop(phandle)
002161.856: dtdebug: merge_fragment() end
002161.898: dtdebug: merge_fragment() end
002161.991: dtdebug: Found fragment 7 (offset 1876)
002164.254: dtdebug: merge_fragment(/soc/gpio@7e200000,/fragment@7/__overlay__)
002164.282: dtdebug: +prop(pinctrl-names)
002166.607: dtdebug: +prop(pinctrl-0)
002173.129: dtdebug: merge_fragment(/soc/gpio@7e200000/my_pins,/fragment@7/__overlay__/my_pins)
002173.152: dtdebug: +prop(brcm,pins)
002175.332: dtdebug: +prop(brcm,function)
002177.528: dtdebug: +prop(brcm,pull)
002179.753: dtdebug: +prop(linux,phandle)
002182.351: dtdebug: +prop(phandle)
002184.546: dtdebug: merge_fragment() end
002184.575: dtdebug: merge_fragment() end
@flatmax
Copy link
Contributor

flatmax commented Mar 27, 2018 via email

@Dloranger
Copy link
Author

Okay, I can script the modprobe for now to get reliable detection, that will solve 1 problem.

Can you help to explain the mechanism that is causing the channels to be reassigned because the clocks are running? I think this is fundamentally where the issue lies.

On all other sound cards I have used, the left channel in hardware is always the left channel, and the right is always the right channel; they are never randomized. This is somewhat out of my area of expertise, but feels like there is some configuration missing that would prevent the random channels.

I can safely say the electrical interface in the chip is not changing, so it must be a software setting that is not doing the right things. I don't know if this is in the audio codec chip drivers, alsa, or elsewhere though.

In the end, I need the clocks to be left running and channel X to always be channel X, regardless of reboots, power outages, application start and stop, etc. I am more than happy to test whatever ideas you have if you can help me find a working configuration. This is the last issue I am fighting with before being able to start launching our new design.

Appreciate the help so far, just stuck trying to get over this last hurdle

@flatmax
Copy link
Contributor

flatmax commented Mar 27, 2018 via email

@Dloranger
Copy link
Author

Dloranger commented Mar 27, 2018 via email

@Dloranger
Copy link
Author

Dloranger commented Apr 8, 2018

I think I understand the issue with the sound synchronization now, but still not sure how to address the issue.

SVXLINK application is consuming the audio for the purposes of clocking. I am not sure how this is happening, I can't follow the code enough to understand it, see above post for the link.

My understanding from the behavior is the svxlink software takes control of the sound card somehow (as its blocked to other devices), but somehow that is not triggering your application to turn the clocking on except when svxlink software is doing playout functions.

I suspect the svxlink software is not doing a proper record, but rather monitoring/polling the channels. The svxlink application is used to control communication repeaters that are expected to be left running for months to years without intervention (Some may be VERY remote from civilization) so a traditional record function wouldnt make sense.. Perhaps this is where the disconnect in the two usages does not overlap. Just speculating here, but seems like a possibility.

If I am understanding the svxlink code starting at line 92 in the above link, it looks like it is doing some form of polling and watching for events rather than doing a recording.

@flatmax
Copy link
Contributor

flatmax commented Apr 8, 2018 via email

@Dloranger
Copy link
Author

Dloranger commented Apr 8, 2018 via email

@Dloranger
Copy link
Author

Dloranger commented Apr 9, 2018 via email

@flatmax
Copy link
Contributor

flatmax commented Apr 9, 2018 via email

@Dloranger
Copy link
Author

Dloranger commented Apr 9, 2018 via email

@Dloranger
Copy link
Author

I had an instance of where the sound card did not load, and I tried running the commands you provided above, and while the hardware is now claimed by the processor, alsa can't use it

pi@PI-REPEATER-2X:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: UU UU UU -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@PI-REPEATER-2X:~ $
pi@PI-REPEATER-2X:~ $
pi@PI-REPEATER-2X:~ $ sudo modprobe -r snd_soc_audioinjector_octo_soundcard
pi@PI-REPEATER-2X:~ $ sudo modprobe -r snd_soc_cs42xx8_i2c
pi@PI-REPEATER-2X:~ $ sudo modprobe -r snd_soc_cs42xx8
pi@PI-REPEATER-2X:~ $ sudo modprobe snd_soc_cs42xx8
pi@PI-REPEATER-2X:~ $ sudo modprobe snd_soc_cs42xx8_i2c
pi@PI-REPEATER-2X:~ $ sudo modprobe snd_soc_audioinjector_octo_soundcard
pi@PI-REPEATER-2X:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: UU UU UU -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@PI-REPEATER-2X:~ $ aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
equal
anyChannelCount
default
pi@PI-REPEATER-2X:~ $ aplay -l
aplay: device_list:270: no soundcards found...
pi@PI-REPEATER-2X:~ $ alsamixer
cannot open mixer: No such file or directory
pi@PI-REPEATER-2X:~ $

This is what I did just before it disappeared from the system last time in case it matters

@nettings
Copy link

@Dloranger, sorry to bump this old thread, but have you considered using JACK for your application? That way, the device can keep running all the time (with clocks) and retain its channel order reliably. It's what I'm doing here with a number of different I²S soundcards, and it works very well.

@Dloranger
Copy link
Author

@nettings,

I havent used Jack as I dont have a gui. The application runs headless, but if you could advise a settings set to get started with?

Perhaps I could set up a station with a gui to get the config file and then deploy it to the headless setups?

This is well outside my expertise so any guidance is much appreciated.

@nettings
Copy link

JACK does not require a GUI. I'm using it headless here, configured so that the system comes up with all audio stuff running without user interaction.

my_user@mn_29f4ff:~ $ cat /etc/systemd/system/jackd.service 
[Unit]
Description=JACK Audio Connection Kit
After=sound.target
After=ntp.service
After=time-sync.target
Before=jackd.target
Requires=jackd.target

[Service]
EnvironmentFile=-/etc/my_jack_config
LimitRTPRIO=85
LimitMEMLOCK=700000000
User=my_user
Environment="DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket"
ExecStartPre=/bin/sleep 10
ExecStart=/usr/bin/jackd $JACKD_OPTIONS
RestartSec=5
Restart=on-failure

In this case, $JACKD_OPTIONS is parsed from an external config file my_config. If your system hardware is fixed, you might as well hardcode it.
For the Octo, I'm using "-R -P70 -dalsa -dhw:audioinjectoroc -r48000 -p256 -n3 -zs".
Note the DBUS variable which is necessary if you want to run as a non-root user without a login session. For testing, don't use this right away, try cmdline first. When it runs, jack_lsp will show you the available ports, jack_connect connects them. Note that if you're currently pushing audio to the interface, you will have to re-design your application to implement a callback, because jack will tell you when to send audio.

As for the systemd integration, check http://jack-audio.10948.n7.nabble.com/Jack-Devel-Some-observations-re-Jack-and-systemd-td20340.html.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants