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

Glitch in analog audio output when using I2S module

Hello.

I'm using the NRF52832 with I2S module connected to TLV320DAC from TI. I've configured the DAC and I2S module successfully. I'm getting audio output (simple sine wave read from a table) but there is an impulse glitch in the audio signal. The glitch appears to occur at the end of every I2S buffer send. When I set the I2S TX buffer size to 250 samples, I see a glitch in the audio at the corresponding time interval. For example, 250 buffer size at 41666 sample rate, causes a glitch in the audio every 0.006 seconds. When I increase the I2S buffer size, the glitch period increases correspondingly.

I've checked my sine table interpolation algorithm. It looks good. I believe the problem is with the NRF52832 and not the DAC. The I2S buffer size is the only variable which seems to affect the audio glitch. Oh, I also tried using I2S slave mode where I program the DAC to send the I2S clocks to the NRF chip. That did not change the glitch though.

I recorded the audio output in Audacity. Take a look at the waveform and frequency spectrum...

\

Parents
  • Okay, looks like I was have been deceived. The scratch buffer seems to have only masked the issue. After some seemingly unrelated code changes the original symptoms returned. This time I managed to suppress them simply by adding an extra word to the start of the buffer, and then passing a pointer to index 1 instead! It's as if the DMA is sucking data from *before* the buffer pointer passed to it.

  • Not sure if I have any idea here, you could try to read the I2S chapter in the product specification for any suggestion also:
    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/i2s.html#concept_z2v_24y_vr

    You may also look into placing the i2s buffers into a specific RAM section not used by other peripherals:
    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/memory.html#memory

    Kenneth

  • Okay thank you. It's a little off-topic, but I have been looking for some guidance for performing a debug build but have not been able to locate any. I cannot find any documentation on DEBUG_NRF. There is no reference to a "Debug" build in the NRF Connect SDK docs, including those associated with running the debugger in SES.

    The closest I've come to instructions on performing a debug build is the notes of a few users, such as Jimmy Wong, who list "CONFIG_LOG", "CONFIG_LOG_DEFAULT_LEVEL" and "CONFIG_DEBUG_OPTIMIZATIONS" as the relevant options.

    Are you aware of any documentation on doing a debug build when working with a project based on the NRF Connect SDK?

  • Oh dear. Not only was it a mission to effectively define DEBUG_NRF with the nRF Connect SDK, after spending far too long trying to figure out why it wasn't working, I finally discover that DEBUG_NRF isn't even part of the SDK! It does not appear anywhere, and is only found in projects with a nRF5x library. This being a nRF9x project does not use it at all!

    So I finally discover that the way to do it now is to use CONFIG_ASSERT - only to find that my bare bones application will no longer run thanks to a mysterious assertion fail in a part of the SDK I've never looked at:

    ASSERTION FAIL [((arch_is_in_isr() == 0) || ((timeout).ticks == (((k_timeout_t) {})).ticks))] @ WEST_TOPDIR/zephyr/kernel/sem.c:140

    The fail is deep within disk_access_init --> sdhc_spi_detect --> spi_nrfx_transceive, but I can't afford to spend any more time unpicking the incomplete nRF SDK. Will have to make do and move on.

  • Aaargh! These issues are three layers deep!

    So while the word-alignment issue I've raised is still valid, it turns out cory123's suggestion from a month ago about having to double buffer the data is also true.

    After re-reading the docs, I see that the driver only double buffers the pointer! So yes, the user also has to double buffer the data, because the driver requests more data before it has finished reading from that previously provided.

  • Typically you can choose between Release and Debug in SES by:

    The difference between the two is found by opening the project file in text editor, e.g.:

      <configuration Name="Release"
        c_preprocessor_definitions="NDEBUG"
        link_time_optimization="No"    gcc_optimization_level="Optimize For Size" />
      <configuration Name="Debug"
        c_preprocessor_definitions="DEBUG; DEBUG_NRF"
        gcc_optimization_level="None"/>

  • Ah! Good to know thank you. I can confirm that those configurations certainly don't appear if you follow the nRF Connect SDK installation instructions, at least as of a month ago.

    I feel I'm probably not missing out on anything anyway, since "DEBUG_NRF" does not appear in the SDK anywhere:

    github.com/search

    As far as I can tell, that define is obsolete. I think the current way to do it is CONFIG_DEBUG and friends but I'm working blind so I'm not sure.

Reply
  • Ah! Good to know thank you. I can confirm that those configurations certainly don't appear if you follow the nRF Connect SDK installation instructions, at least as of a month ago.

    I feel I'm probably not missing out on anything anyway, since "DEBUG_NRF" does not appear in the SDK anywhere:

    github.com/search

    As far as I can tell, that define is obsolete. I think the current way to do it is CONFIG_DEBUG and friends but I'm working blind so I'm not sure.

Children
  • Sorry, I forgot you were using NCS, my screenshot were for nRF5 SDK. In your case I guess you can add the following to prj.conf:

    # Debugging configuration
    CONFIG_THREAD_NAME=y
    CONFIG_THREAD_ANALYZER=y
    CONFIG_THREAD_ANALYZER_AUTO=y
    CONFIG_THREAD_ANALYZER_RUN_UNLOCKED=y
    CONFIG_THREAD_ANALYZER_USE_PRINTK=y
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y
    CONFIG_SERIAL=y
    CONFIG_PRINTK=y
    CONFIG_USE_SEGGER_RTT=n
    
    # add asserts
    CONFIG_ASSERT=y
    CONFIG_ASSERT_VERBOSE=y
    CONFIG_ASSERT_NO_COND_INFO=n
    CONFIG_ASSERT_NO_MSG_INFO=n
    CONFIG_RESET_ON_FATAL_ERROR=n
    CONFIG_THREAD_NAME=y
    CONFIG_ARM_MPU=y

  • Thanks for that Kenneth. Yes, I sort of barged my way into this thread not realising how isolated the nRF5 world was from the NCS world, so I'm sorry for the confusion.

    I appreciate that list of CONFIGs. Haven't been burnt so bad stepping into the unknown so many times in this project so far, I'm going to tread very carefully. Every CONFIG seems to have unintended consequences that soak up precious hours. So to be honest, unless a compelling reason comes up, or some really good documentation, I'm going to leave sleeping dogs lie! Great to have them to refer back to though.

Related