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

nRF52840 I2S digital MEMS Mic

Hello All.

I Need help ... first time use "nRF52840"

Goal of this project is "record voice with digital mems mic and play that voice using speaker with i2s"

First i use SDK52 Ver 16.04  and Find some example to play sound first

     -> Success to use PCM data to play music 

and next use "SPH0645LM4H-B" mic to record and play

     -> Working not well.. help please

     -> if i use this code to check it i can hear only "bzzzzzzzzzzzzz" noise sound

     -> MCLK : 2.907MHz / LRCK 60KHz / RATIO X64 Use for mic and change CLK, LRCK when i use spk

     -> i can not sure that mic can not record the sound or my save way is wrong...

     

//////////////////////////////////////////////////////////Code////////////////////////////////////////////////////////////////

..... //include .h files

uint32_t pcm_samples[] = {0,};

...

static void i2s_Init(void)
{
          // Enable transmission
          NRF_I2S->CONFIG.TXEN = (I2S_CONFIG_TXEN_TXEN_DISABLE << I2S_CONFIG_TXEN_TXEN_Pos);
          NRF_I2S->CONFIG.RXEN = (I2S_CONFIG_RXEN_RXEN_DISABLE << I2S_CONFIG_RXEN_RXEN_Pos);
          // Enable MCK generator
          NRF_I2S->CONFIG.MCKEN = (I2S_CONFIG_MCKEN_MCKEN_ENABLE << I2S_CONFIG_MCKEN_MCKEN_Pos);

          // MCKFREQ = 4 MHz
          NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;//31

          // Ratio = 64
          NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_64X << I2S_CONFIG_RATIO_RATIO_Pos;//128

          // Master mode, 16Bit, left aligned
          NRF_I2S->CONFIG.MODE = I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos;
          NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
          NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_LEFT << I2S_CONFIG_ALIGN_ALIGN_Pos;

          // Format = I2S
          NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S << I2S_CONFIG_FORMAT_FORMAT_Pos;

          // Use stereo
          NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_LEFT << I2S_CONFIG_CHANNELS_CHANNELS_Pos;

          // Configure pins
          NRF_I2S->PSEL.MCK = (PIN_MCK << I2S_PSEL_MCK_PIN_Pos);
          NRF_I2S->PSEL.SCK = (PIN_SCK << I2S_PSEL_SCK_PIN_Pos);
          NRF_I2S->PSEL.LRCK = (PIN_LRCK << I2S_PSEL_LRCK_PIN_Pos);
          NRF_I2S->PSEL.SDOUT = (PIN_SDOUT << I2S_PSEL_SDOUT_PIN_Pos);
          NRF_I2S->PSEL.SDIN = (PIN_SDIN << I2S_PSEL_SDIN_PIN_Pos);


          nrf_gpio_cfg_output(17); //SPK out enable
          nrf_gpio_cfg_output(32); //I2S_SDOUT
          nrf_gpio_cfg_output(22); //LRCK
          nrf_gpio_cfg_output(20); //SCK
          nrf_gpio_cfg_input(24,NRF_GPIO_PIN_PULLDOWN); //I2S_SDIN
          nrf_gpio_pin_set(17);

          nrf_gpio_cfg_input(14,NRF_GPIO_PIN_PULLDOWN); //OLED SCL -> SW -> Low -> SPK High -> Mic


          NRF_I2S->ENABLE = 1;

}

....

int main (void)

{

...

          i2s_Init();
          NRF_I2S->RXTXD.MAXCNT = 1;
          // Start transmitting I2S data
          NRF_I2S->EVENTS_TXPTRUPD = 0;
          NRF_I2S->TASKS_START = 1;

          if(nrf_gpio_pin_read(14) == 1)//Mic On Mode
          {
                    if(oneOn == 0)
                    {
                              oneOn = 1; oneOf = 0; Count = 0;
                              nrf_gpio_pin_clear(17);
                              NRF_I2S->TASKS_STOP = 1; // shortly stop to change FRQ
                              NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
                              NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_64X << I2S_CONFIG_RATIO_RATIO_Pos;
                              NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_24BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;

                              NRF_I2S->CONFIG.TXEN = (I2S_CONFIG_TXEN_TXEN_DISABLE << I2S_CONFIG_TXEN_TXEN_Pos);
                              NRF_I2S->CONFIG.RXEN = (I2S_CONFIG_RXEN_RXEN_ENABLE << I2S_CONFIG_RXEN_RXEN_Pos);
                              // Configure data pointer
                              NRF_I2S->RXD.PTR = (uint32_t)&pcm_samples[0];

                              NRF_I2S->ENABLE = 1;
                              NRF_I2S->TASKS_START = 1;
                              nrf_delay_ms(5);
                    }
                    else{}
          }
          else//Spk On Mode
          {
                    if(oneOf == 0)
                    {
                              oneOf = 1; oneOn = 0; Count = 0;
                              nrf_gpio_pin_set(17);
                              NRF_I2S->TASKS_STOP = 1; // shortly stop to change FRQ
                              NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
                              NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_64X << I2S_CONFIG_RATIO_RATIO_Pos;
                              NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_24BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;

                              NRF_I2S->CONFIG.TXEN = (I2S_CONFIG_TXEN_TXEN_ENABLE << I2S_CONFIG_TXEN_TXEN_Pos);
                              NRF_I2S->CONFIG.RXEN = (I2S_CONFIG_RXEN_RXEN_DISABLE << I2S_CONFIG_RXEN_RXEN_Pos);
                              // Configure data pointer
                              NRF_I2S->TXD.PTR = (uint32_t)&pcm_samples[0];

                              NRF_I2S->ENABLE = 1;
                              NRF_I2S->TASKS_START = 1;
                              nrf_delay_ms(5);
                    }
                    else{}
          }

          if(NRF_I2S->EVENTS_TXPTRUPD != 0)
          {
                    NRF_I2S->TXD.PTR = (uint32_t)&pcm_samples[Count];
                    if(++Count > 100000){Count = 0;}
                    NRF_I2S->EVENTS_TXPTRUPD = 0;
                    NRF_LOG_INFO("TXD_PTR_Work");
          }
          if(NRF_I2S->EVENTS_RXPTRUPD != 0)
          {
                    if(++Count > 100000){Count = 0;}
                    NRF_I2S->RXD.PTR = (uint32_t)&pcm_samples[Count];
                    NRF_I2S->EVENTS_RXPTRUPD = 0;
                    NRF_LOG_INFO("RXD_PTR_Work");
          }

}

...

Parents Reply Children
No Data
Related