Random zero data when i2s acts as a slave

Hi,
When I tried to use Rock960 i2s as a slave role, I found out that there would be some random zero data in it (Master works fine). Does anyone ever see this problem before?
Attached pictures are the result from LA, and all the data I sent is 0xffff (16bit 48k).
screenshot_2021-02-25-103408

I take it that your pictures are the output of a logic probe?

A bit of clarification is needed on your setup;

  1. Which side is sending data? The rock960? Or whatever you have connected to it?
  2. Is the data pin actually connected between two devices when running this test? If it is, then EITHER side could be responsible for the 0-bits, which leads to the next point;
  3. Are you sure that the data output and input pins are connected correctly? 96boards Data OUT --> peripheral Data IN. Peripheral Data OUT --> 96boards Data IN.
  4. The device you are connecting to… is it operating at a compatible voltage level? It should have a logic level of 1.8 volt for 96boards compatibility.

Can you add an analog channel to the Data line on your probe? It may be helpful to see what the voltages look like to make sure that they are within spec.

Yes, pics are from logic probe.

The codec acts as an I2S master and data is sending from rock960. The codec is simple without any I2C configuration and it is a proprietary chip but has been verified on the other platform.

The data pins are connected to each other with dupont line and regarding for the pin correctness, I have checked by switching the rock960’s role to master and it works fine.
As you mentioned that both side could be responsible the 0-bits, I connected the I2S dout from rock960 directly to the logic probe and still saw the problem, although I do not know if this is a proper way or not.

I will try to find the analog probe to see the detail level, but I am sure that the both sides are running at 1.8v level.
Any thoughts would be welcomed, thanks.

BTW, I am running Armbian 20.11.6 Focal with Linux 5.9.14-rockchip64 and attached my modified overlay dts file.

/dts-v1/;
/plugin/;

/ {
    compatible = "rockchip,rk3399";

    fragment@0 {
        target-path = "/";
        __overlay__ {
            codec-sound {
                compatible = "simple-audio-card";
                simple-audio-card,name = "codec-sound";
                simple-audio-card,mclk-fs = <128>;

                status="okay";

                capture_link: simple-audio-card,dai-link@0 {
                    format = "left_j";
                    fsync-width = <31>;
                    bitclock-master = <&r_codec_dai>;
                    frame-master = <&r_codec_dai>;

                    r_cpu_dai: cpu {
                       sound-dai = <&i2s0>;
                    };

                    r_codec_dai: codec {
                         sound-dai = <&codec_in>;
                    };
                };

                playback_link: simple-audio-card,dai-link@1 {
                    format = "left_j";
                    fsync-width = <31>;
                    bitclock-master = <&p_codec_dai>;
                    frame-master = <&p_codec_dai>;

                    p_cpu_dai: cpu {
                        sound-dai = <&i2s0>;
                    };

                    p_codec_dai: codec {
                        sound-dai = <&codec_out>;
                    };
               };
            };
        };
    };

    fragment@1 {
        target-path = "/";
        __overlay__ {
            codec_out: spdif-transmitter {
                #address-cells = <0>;
                #size-cells = <0>;
                #sound-dai-cells = <0>;
                compatible = "linux,spdif-dit";
                status = "okay";
            };
            codec_in: spdif-receiver {
                #address-cells = <0>;
                #size-cells = <0>;
                #sound-dai-cells = <0>;
                compatible = "linux,spdif-dir";
                status = "okay";
            };
        };
    };

    fragment@2 {
        target = <&i2s0>;
        __overlay__ {
            status = "okay";
        };
    };
};

Yes, that should be fine. You can also try a loopback configuration by just jumping the DO and DI together on the LS header and try a simultaneous playback+capture (which I would also perform withOUT the probe connected). In theory, the captured data should match the transmitted data, which would be an easy way to confirm that the probe output is actually good.

I presume that the probe is actually compatible with 1.8v logic and that you have a good ground connection between the probe and the SBC? The reason I ask is that many inexpensive probes are NOT compatible with 1.8v logic, and for that matter, also some probes that CLAIM not to be compatible actually work quite well. Saleae logic 4 is an example of a 3.3v/5.0v probe that, in my experience, works well at 1.8v, HOWEVER, I wouldn’t stake my life on it being exactly correct since that is technically out of spec.

I wonder if you have also verified that the PROBE ITSELF isn’t responsible for the data oddities? The reason I suggested the loopback test above is that it would validate the probe’s output.

I can’t really comment on the programming, since my experience with rock960/rk3399 is limited to using them as tv boxes as a stopgap measure waiting for google to offer something decent to replace Nexus Player that could handle HEVC, but even with those, I haven’t powered one on since I replaced them with Google CCGTV’s. Hardware wise, my familiarity is greatest with Dragonboard 820c. All my rock960’s have been relegated to my “junk box”.

Its not ONLY about verifying the 1.8v level. Its also about watching the patterns where the unexpected data is observed to see the slopes and if there is anything unusual happening, for example, maybe the “high” level is hovering somewhere just below Vh? If so, you might be able to correct it by increasing the drive strength on the pin.