Hello everybody,
I recently bought the MCXN947 evaluation board for my company's project as it seemed a very suitable soc for our needs, and for its native support for Zephyr, our rtos of choice.
Im having troubles setting up I2S communications over SAI module to retrieve data from a mems microphone, this code already worked for another soc albeit of another semiconductor company.
From my understanding, the board out of the box has all R0s set correctly for having SAI1 signals mapped on the available pins, they only clash with the LPSPI6 pins, and as the .dtsi file suggests (frdm_mcxn947_mcxn947_cpu0.dtsi) i disabled the flexcomm6 node. The i left the .pinctrl invaried, and connected Word Select (FS) to PT3_19 and Bit clock (BCLK) to PT3_18 and finally Data line (D0) to PT3_21. With an oscilloscope, i can confirm that no signal is seen on the FS and BTCLK line after an issued I2S_TRIGGER_START with the i2s_trigger function
here follows the main.c:
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include "math.h"
#include <zephyr/device.h>
#include <zephyr/drivers/i2s.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(Main);
/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS 1000
/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)
/*
* A build error on this line means your board is unsupported.
* See the sample documentation for information on how to fix this.
*/
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static const struct device* i2s_dev = DEVICE_DT_GET(DT_ALIAS(i2srx));
#define SAMPLE_RATE_HZ 48000
#define WORD_BITS 32
#define WORD_BYTES 4
#define CHANNELS 1
#define FRAME_BYTES (CHANNELS * WORD_BYTES)
#define I2S_RX_DURATION_MS 10
#define MEM_BLOCK_SIZE (SAMPLE_RATE_HZ * (CHANNELS * 0.001 * I2S_RX_DURATION_MS))
#define MEM_BLOCK_BYTESIZE (MEM_BLOCK_SIZE * WORD_BYTES)
K_MEM_SLAB_DEFINE(slab, (size_t)MEM_BLOCK_BYTESIZE, 3, 4);
int main(void)
{
int ret;
bool led_state = true;
if (!gpio_is_ready_dt(&led)) {
return 0;
}
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
if (ret < 0) {
return 0;
}
struct i2s_config cfg = {
.word_size = WORD_BITS,
.channels = CHANNELS,
.format = I2S_FMT_DATA_FORMAT_I2S,
.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER,
.frame_clk_freq = SAMPLE_RATE_HZ,
.mem_slab = &slab,
.block_size = MEM_BLOCK_BYTESIZE,
.timeout = 1000,
};
ret = i2s_configure(i2s_dev, I2S_DIR_RX, &cfg);
if (ret < 0) {
LOG_ERR("FAILED");
return -EIO;
}
ret = i2s_trigger(i2s_dev, I2S_DIR_RX, I2S_TRIGGER_START);
if (ret < 0) {
LOG_ERR("I2S Trigger start failed");
return -EIO;
}
while (1) {
void* blk;
size_t blk_sz;
int ret = i2s_read(i2s_dev, &blk, &blk_sz);
if (ret != 0) {
/* Why is there no data? */
LOG_ERR("No data. %i", ret);
return -EIO;
}
ret = gpio_pin_toggle_dt(&led);
if (ret < 0) {
return 0;
}
led_state = !led_state;
printf("LED state: %s\n", led_state ? "ON" : "OFF");
k_msleep(SLEEP_TIME_MS);
}
return 0;
}
the following is my overlay:
/ {
aliases {
i2srx = &sai1;
};
};
// See comment in frdm_mcxn947_mcxn947_cpu0.dtsi
&flexcomm6_lpspi6 {
status = "disabled";
};
The following is my prj.conf
CONFIG_GPIO=y
CONFIG_I2S=y
CONFIG_DMA=y
CONFIG_DEBUG=y
CONFIG_LOG=y
CONFIG_I2S_LOG_LEVEL_DBG=y
CONFIG_DMA_LOG_LEVEL_DBG=y
To get a clearer picture im also attaching a .zip of the project, which is a simple blinky with added the baseline functions needed to retrieve data from the microphones, can someone please help out or direct me to something that could help understand the issue?