This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Need I2S help

Hi there,

I'm just trying to start to code my project. I want to stream 48k 16 bit audio from one nrf52840 dongle to the other one. I only need one way transfer.

I have looked at every example I could find but still dont seem to get how to send the packets to the radio and over the wireless connection.

Is there anyone that can help get me started with some simple no frills code.

I'm using Segger and sdk v17.

I would be most grateful if someone could assist me here.  Once I get the streaming part working successfully I think I can work out how to do the other things I need but this I2S is very tricky it seems to know what to do. It needs to be a steady stream.

Kind regards,

Dam076

  • Thanks for your help so far. If I was to use the radio library directly and use ->PACKETPTR  will this pointer accept a pointer to an array or only a single 32bit variable? If it will accept an array, how do I code it correctly and how do I tell the radio how many 32bit words to send via RF?

  • Also, is it possible to use EASYDMA to have the IS2 buffer auto copy to the Radio buffer using interupts when the I2S buffer fills up, and if so are you able to help with a simple example, keeping in mind that this I2S buffer will be constantly filling and needing to be copied and freed to allow the next I2S words to collect in the buffer. Would double buffering work in this case, and again if so, are you able to provide a very simple example? Thanks again. The learning curve here is enormous. All I want to do is send I2S over the radio link lol. cheers

  • Hi

    damo76 said:
    If I was to use the radio library directly and use ->PACKETPTR  will this pointer accept a pointer to an array or only a single 32bit variable? If it will accept an array, how do I code it correctly and how do I tell the radio how many 32bit words to send via RF?

    The PACKETPTR register assumes it is pointed to a byte array, and the length of the packet is set by a combination of the LENGTH field in the packet and the STATLEN field in the PCNF1 register

    The LENGTH field allows for dynamic packet length, where the packet length is sent along with the payload content so that the receiver knows how long each packet is. The critical thing when using the LENGTH field is that one of the first bytes in the buffer pointed to by PACKETPTR will be used to store the length, as described in this chapter of the RADIO documentation. 

    It shouldn't be a problem pointing PACKETPTR to an array of 32-bit values instead, you just have to multiply the length by 4 (and ensure the total packet length in bytes doesn't exceed 258 bytes, as mentioned in the chapter I linked to above). 

    damo76 said:
    Also, is it possible to use EASYDMA to have the IS2 buffer auto copy to the Radio buffer using interupts when the I2S buffer fills up, and if so are you able to help with a simple example, keeping in mind that this I2S buffer will be constantly filling and needing to be copied and freed to allow the next I2S words to collect in the buffer.

    You can't have the EasyDMA copy from one buffer to another, no, but you don't really need to. The trick is to assign the EasyDMA of both the radio and the I2S interface to the same buffer, then no copying is needed. 

    As I mentioned earlier you can implement a FIFO/ringbuffer in RAM (an array of buffers essentially), and start filling it up using the I2S interface. Once the first buffer is filled you point the EasyDMA of the I2S to the second buffer in the FIFO, and ask the RADIO to send the data stored in the first. 

    Then the I2S will be busy filling the second buffer, while the RADIO is busy transmitting the first buffer over the air. Once the radio operation is complete you can mark the first buffer as free for more I2S data. 

    damo76 said:
    Would double buffering work in this case, and again if so, are you able to provide a very simple example?

    If you don't plan to do any data acknowledge and retransmissions then a double buffer should be sufficient, but in this case you will be more susceptible to packet loss over the air. 

    Regarding the example, what specifically do you need demonstrated?

    As I mentioned earlier I would suggest starting on the I2S integration, and try to get data out of your I2S device. Until this is working there is no point trying to set up the rest. 

    Best regards
    Torbjørn

  • Now that was really helpful thankyou. One issue I have found when trying to copy and paste some code i found is that the function nrf_drv_i2s_start is different from nrfx_i2s_start even though the nrf_drv_i2s.h file links the 2 functions with a #define macro. Are you able to help me with specific code to 1) activate I2S in RX mode only, and 2) in TX mode only. It seems the new nrfx function requires both buffers to be passed as a structure in the first argument, yet the old driver allowed for them to be split. Is it possible I can pass the structure but give the value NULL in the rx (or tx) pointer where required or do I have to provide both buffers?  This would help me out because I only need I2S as a one way device and only want to deal with 1 set of buffers on each RF module, if possible.  and thanks again. 

  • "

    The trick is to assign the EasyDMA of both the radio and the I2S interface to the same buffer, then no copying is needed. 

    As I mentioned earlier you can implement a FIFO/ringbuffer in RAM (an array of buffers essentially), and start filling it up using the I2S interface. Once the first buffer is filled you point the EasyDMA of the I2S to the second buffer in the FIFO, and ask the RADIO to send the data stored in the first. 

    Then the I2S will be busy filling the second buffer, while the RADIO is busy transmitting the first buffer over the air. Once the radio operation is complete you can mark the first buffer as free for more I2S data. "

    This is exactly what i needed help to code. Is there any example of this or are you able to help me with a basic code structure for this? I am still getting my head around how I2S utilises the easyDMA.. tbh I am struggling to understand how it implements the alternating buffers in the data_handler

Related