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");
}
}
...