I2S in NRF9161

Hi. I am working on upgrading an old project made for NRF9160 to NRF9161. a Requirement that seems to require upgrading Zephyr/NRF SDK and this 10000 lines of application code too. Now I got stuck with I2S. It looks like a lots of stuff have changed since I originally got this working  https://devzone.nordicsemi.com/f/nordic-q-a/60256/i2s-on-nrf9160

What I would like to know that is there now any samples available that would show how I2S should be properly used? Could not find any. Apparently nowadays you could use it with zephyr APIs also, but doing that solely based on documentation does not sound very appealing. For the minimun code changes I would probably prefer to use NRFX APIs directly as before. For now, after modifying the API calls to compile with new API all I get is a crash when calling nrfx_i2s_init. So probably some magical definitions from somewhere in the SDK are missing again.

  • I finally got a debugger working at least somehow. It shows that it crashes to bus fault as soon as the NRF driver touches MODE at 0x40028504. To me this seems like exactly the correct address to set the mode. Any ideas what might cause this?

    Screenshot just before the last function call shows that config and pointer to peripheral should be ok:

    Screeshot just before the crash shows that everything should still be ok:

    Not sure how trustworthy the data here is as it looks like almost all the flags are on. But a bus fault anyway:

  • Is it from the sample, or from your own code?

    Also, why is called nrfy_i2s_config_t?

    Best regards,

    Michal

  • So, I finally had some time to invest to this one. These errors are from my own code. It is not very easy to port samples to the custom HW I am using. No idea why the nrfy. This is straight from the SDK.

    I am pretty sure that the crash happens because I2S peripheral is secure by default. There used to be a way to make it unsecure by modifying spm.c. But this is apparently no more possible.

    If I understood correctly, now you would need to add `CONFIG_I2S_NRFX=y` and that would set the peripheral to unsecure. But to add that you will also need to modify the device tree for it to compile. which I tried to do like this:

    &pinctrl {
    
    	i2s0_default: i2s0_default {
    		group1 {
    			psels = <NRF_PSEL(I2S_SCK_M, 0, 24)>,
    				<NRF_PSEL(I2S_LRCK_M, 0, 23)>,
    				<NRF_PSEL(I2S_SDIN, 0, 25)>;
    		};
    	};
    
    	i2s0_sleep: i2s0_sleep {
    		group1 {
    			psels = <NRF_PSEL(I2S_SCK_M, 0, 24)>,
    				<NRF_PSEL(I2S_LRCK_M, 0, 23)>,
    				<NRF_PSEL(I2S_SDIN, 0, 25)>;
    			low-power-enable;
    		};
    	};
    };
    
    
    &i2s0 {
    	compatible = "nordic,nrf-i2s";
    	status = "okay";
    	pinctrl-0 = <&i2s0_default>;
    	pinctrl-1 = <&i2s0_sleep>;
    	pinctrl-names = "default", "sleep";
    };

    But only effect is that device crashes even earlier to a bus fault in 4002 8564. That is SCK signal so obviously I am doing something wrong. My HW only has WS, SD and SCK connected.

    What I would of course prefer would be to not use device tree at all since that is how the legacy code was originally made. But anyways. All the hints are welcome. It is also possible that I am completely in the wrong track with my investigation here.

  • Hello,

    The nrfy part is from a rework of the nrfx driver which I was not aware of at the time.

    Did you add CONFIG_I2S=y to prj.conf?

    Though with a pure nrfx solution I think that using devicetree should not be required.

    Best regards,

    Michal

Related