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.

Parents
  • 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:

  • 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

  • Yes I did CONFIG_I2S=y

    You don't have any idea how to make sure that I2S really is insecure? I need to try to find some documentation for this once I again get more urgent matters away from my desk.

    • First just try it
    • Then debug it
    • If nothing else helps, read the manual

    Slight smile

  • I will have to research more into the secure/insecure peripherals and ask around my colleagues, as I am not an expert on TF-M.

    I will get back to you.

    Best regards,

    Michal

  • Hello,

    Did you get any progress on that in the meantime by chance?

    Best regards,

    Michal

Reply Children
  • Noup. This is in my low priority list. But it has to be done at some point anway. I'll post here once I get back to this and figure out how to get it working.

  • Ok. Finally back in debugging this puppy. I tried to confirm my theory about secure/non-secure problem by looking at how SPU is configured. This is a memory dump from what I believe is the SPU peripheral configuration memory area

    SPU peripheral permissions @50003800
    50003800 12 00 00 80 00 00 00 00 11 00 00 80 11 00 00 80
    50003810 02 00 00 80 02 00 00 80 11 00 00 80 12 00 00 80
    50003820 0A 00 00 80 0A 00 00 80 0A 00 00 80 0A 00 00 80
    50003830 00 00 00 00 11 00 00 80 0A 00 00 80 02 00 00 80
    50003840 02 00 00 80 02 00 00 80 00 00 00 00 00 00 00 00
    50003850 02 00 00 80 02 00 00 80 00 00 00 00 03 00 00 80
    50003860 02 00 00 80 00 00 00 00 00 00 00 00 02 00 00 80
    50003870 02 00 00 80 02 00 00 80 02 00 00 80 02 00 00 80
    50003880 02 00 00 80 0A 00 00 80 0A 00 00 80 0A 00 00 80
    50003890 0A 00 00 80 00 00 00 00 3A 00 00 80 00 00 00 00
    500038A0 3A 00 00 80 00 00 00 00 02 00 00 80 00 00 00 00
    500038B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

    I2S ID == 40 == 0x28
    So I suppose it is found from this line

    50003820 0A 00 00 80 0A 00 00 80 0A 00 00 80 0A 00 00 80 00 00

    And if I try to decode that

    0A 00 00 80
    00001010 00000000 00000000 10000000
    Swap
    10000000 00000000 00000000 00001010
    F == 1 == Peripheral present
    A == 10 == 2 == User selectable
    B == 10 == 2 == DMA has a separate attribute
    C == 0 == Non secure
    D == 0 == DMA transfer is non-secure
    E == 0 == Unlocked

    So I2S is configured as non-secure just as it should be. I suppose there goes that theory then. Now I again have no idea why do I get that bus fault. But I just need to keep digging

  • Hello,

    Please check if your platform/ext/target/nordic_nrf/common/core/target_cfg.c file includes this commit: https://github.com/nrfconnect/sdk-trusted-firmware-m/commit/f2a462080edc42818003d052c57d777954220145. There was an issue in previous versions of the SDK that the I2S peripheral did not get configured as non-secure due to inconsistent naming between nRFx chip variants. 

    With TF-M, peripherals will generally default to non-secure unless specified otherwise through the CONFIG_NRF_<peripheral_name>_SECURE symbols. Note: in SDK v2.6.0, the CONFIG_NRF_UARTE1_SECURE is enabled by default for debug logging. This means that the following peripherals will not be accessible to the NS application:

    fastfox said:
    And if I try to decode that

    I recommend using the peripheral viewer in the VS code or Segger Ozone debugger to view the register configurations so you don't have to decode the memory dump by hand.

    Best regards,

    Vidar

  • Aww yeah, it works. I was using 2.5.0 and now updated to 2.6.1 and no problems with I2S anymore. Unfortunately one I2C device now crashes the whole thing that had no problem in 2.5.0, but that is another story.

    Thanks for your help!

    ps. I didn't know that ozone can decode NRF register configurations. I need to try that.

  • Unfortunately one I2C device now crashes the whole thing that had no problem in 2.5.0, but that is another story.

    Are you using TWIM1 by any chance? In that case, disabling UARTE1 in TF-M should fix the problem.

    You can disable UARTE1 and logging in TF-M by adding the following lines to your prj.conf file:

    CONFIG_TFM_SECURE_UART=n
    CONFIG_TFM_LOG_LEVEL_SILENCE=y
Related