This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

PDM not working on certain pins

Hello,

We used our old rev board to prototype some new features including a new PDM digital microphone.  It worked great using the nrfx_pdm module.  When we spun a new rev of our board to use this, we used different pins, and have had trouble getting PDM to work at all on the new board.

We had the prototype working, connecting PDM CLK to P0.28 and DATA on P0.31.  On the new board, we have CLK on P1.12 and DATA on P1.03.  I've confirmed that with the same code, CLK is not clocking, but is fixed at GND while the PDM driver is active.  I've tried a couple configurations to troubleshoot.  If I remove the mic from the board, I can switch the CLK and DATA and still don't get any output on the CLK line (i.e. no clock signal on P1.12 or P1.03).  If I set the CLK pin to 0.31, the clock signal is clearly discernible.  

Is there any limitation on what pins can be used for PDM?  I haven't found any such notes in the documentation or errata.  I did discover a fact we missed during our board design, that both the pins used on this rev of the board and in prototyping are noted as "low frequency only".  So we may have to change this for production, but since the P0 pins worked in the prototype we are stumped as to why the P1 pins won't work for us on this board, and this is holding up our development efforts.

Please let me know if you can shed any light on this question

Parents Reply Children
  • Hello,

    I did discover a fact we missed during our board design, that both the pins used on this rev of the board and in prototyping are noted as "low frequency only".  So we may have to change this for production

    Yes, the designated low frequency pins ( < 10 kHz signals only ) are designated as such because of their proximity to the radio. Routing high frequency signals through these pins should be fine for the peripheral, but it may degrade radio performance considerably, so I would recommend that you change this before production or ensure that the pins are not in use concurrently with the RADIO peripheral.

    Allen Jameson said:
    OK, finally figured out the answer digging into the drivers a bit more.  The PDM driver truncates the pin number, losing the Port number.  When I preserve the port number, it works.

    I am glad to hear that you figured out the cause of this issue!
    Reading your ticket I was about to ask if you could show me how you are designating your pins?
    I would recommend using the NRF_GPIO_PIN_MAP macro in order to make sure that you're targeting the right pin on the right port.

    Best regards,
    Karl

  • Karl,

    Thanks for your comment.  We do assign the pins properly e.g. 


    #define PDM_MIC_CLK_PIN NRF_GPIO_PIN_MAP(1, 3)
    #define PDM_MIC_DATA_PIN NRF_GPIO_PIN_MAP(1, 12)

    In nrf_pdm.h the function nrf_pdm_psel_connect truncated the Port from the specified pins.  I added the port back in with the "| (([pin]) & PDM_PSEL_CLK_PORT_Msk)" lines:

    __STATIC_INLINE void nrf_pdm_psel_connect(uint32_t psel_clk, uint32_t psel_din)
    {
        NRF_PDM->PSEL.CLK = ((psel_clk << PDM_PSEL_CLK_PIN_Pos) & PDM_PSEL_CLK_PIN_Msk)
                | ((psel_clk) & PDM_PSEL_CLK_PORT_Msk)
                | ((PDM_PSEL_CLK_CONNECT_Connected << PDM_PSEL_CLK_CONNECT_Pos) & PDM_PSEL_CLK_CONNECT_Msk);
        NRF_PDM->PSEL.DIN = ((psel_din << PDM_PSEL_DIN_PIN_Pos) & PDM_PSEL_DIN_PIN_Msk)
                | ((psel_din) & PDM_PSEL_CLK_PORT_Msk)
                | ((PDM_PSEL_DIN_CONNECT_Connected << PDM_PSEL_CLK_CONNECT_Pos) & PDM_PSEL_DIN_CONNECT_Msk);
    }

  • It appears this is resolved in the latest version of the SDK.  Not clear when the change was made, as I didn't see anything in the update notes or bug lists - but perhaps I missed something.  The implementation is much cleaner - the SDK 15.0 implementation uses lots of constants, bit shifting, and bit masks unnecessarily.  In SDK 17 it is: 

    __STATIC_INLINE void nrf_pdm_psel_connect(uint32_t psel_clk, uint32_t psel_din)
    {
        NRF_PDM->PSEL.CLK = psel_clk;
        NRF_PDM->PSEL.DIN = psel_din;
    }

  • Allen Jameson said:
    We do assign the pins properly e.g.

    Great - I thought I should mention it just in case.

    Allen Jameson said:
    In nrf_pdm.h the function nrf_pdm_psel_connect truncated the Port from the specified pins.  I added the port back in with the "| (([pin]) & PDM_PSEL_CLK_PORT_Msk)" lines:

    That's strange.. I do not see the same in my mint nRF5 SDK v15.0.0, I have the same implementation of nrf_pdm_psel_connect that you mention in your latest comment.
    I.e:

    __STATIC_INLINE void nrf_pdm_psel_connect(uint32_t psel_clk, uint32_t psel_din)
    {
        NRF_PDM->PSEL.CLK = psel_clk;
        NRF_PDM->PSEL.DIN = psel_din;
    }


    Is there any way you could revision check this part of your SDK to see if there has been made any changes to it in the past? Given that the SDK is an older version, has this been handed over to you by somebody else that have worked on it previously, or have you been in the loop the entire time of the development?

    Best regards,
    Karl

  • Karl,

    Thanks for looking into that.  I can confirm that one of our devs accidentally made this change when adding higher frequency options to the PDM module according to the source code provided by the OP in https://devzone.nordicsemi.com/f/nordic-q-a/15150/single-pdm-microphone-at-higher-pcm-sampling-rate.  Sorry for the confusion.

    --Allen

Related