zephyr 3.5.0 I2S on nrf52840

Hi. I have a new project using zephyr 3.5.0 and ZMK, so I don't think NCS SDK is an option. 
I am using pca10056/nrf52840dk

I am trying to configure I2S, and the examples I'm seeing for the above toolchain are inconsistent. 
For starters I just want to see MCK, SCK, LRCK and SDOUT on the logic analyzer before managing buffering. 
I am obviously not a zephyr pro, I've used it twice before for brief projects. 

1) the overlay file uses pinctrl, not 'mck-pin' or 'sck-pin' inside &i2s0 definition.

2) Certain pins on pca10056 are not functioning as intended. 

eg - I try the following, but I only see LRCK and SDOUT on the logic analyzer.
I had MCK working at one point but have lost that configuration with trial and error. 

i2s0_default: i2s0_default {
 group1 {
 psels = <NRF_PSEL(I2S_MCK, 0, 28)>,
  <NRF_PSEL(I2S_SCK_M, 0, 30)>,
  <NRF_PSEL(I2S_LRCK_M, 0, 29)>,
  <NRF_PSEL(I2S_SDOUT, 0, 31)>;
 };
};


In Vscode XPERIPHERALS, I check the register for pin mapping, 
Then I check MCKEN is set
This is my main.c. I'm currently not connected to the TAS2110, and just trying to validate the i2s signals. 
Is there something simple I can do to achieve this? 
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2s.h>
#include <zephyr/devicetree.h>
#include <zephyr/logging/log.h>
#include <math.h>

LOG_MODULE_REGISTER(i2s_sine, LOG_LEVEL_INF);

#define M_PI 3.14159265358979323846

#define I2S_NODE DT_NODELABEL(i2s0)

#define SAMPLE_RATE 48000
#define CHANNELS 1
#define BITS_PER_SAMPLE 16

#define FREQUENCY_HZ 60

#define SINE_WAVE_BUFFER_SIZE (SAMPLE_RATE / FREQUENCY_HZ)
#define BLOCK_SIZE (SINE_WAVE_BUFFER_SIZE * CHANNELS * (BITS_PER_SAMPLE / 8))

// Pre-computed sine wave data buffer
int16_t sine_wave_buffer[SINE_WAVE_BUFFER_SIZE];

// Memory slab for I2S DMA buffers
K_MEM_SLAB_DEFINE(mem_slab_tx, BLOCK_SIZE, 4, 1);

static const struct device *i2s_dev = DEVICE_DT_GET(I2S_NODE);

static void generate_sine_wave(void) {
    double freq = FREQUENCY_HZ;
    double amplitude = 32767.0; // Full-scale for 16-bit signed audio

    for (int i = 0; i < SINE_WAVE_BUFFER_SIZE; i++) {
        double t = (double)i / SAMPLE_RATE;
        double value = amplitude * sin(2.0 * M_PI * freq * t);
        sine_wave_buffer[i] = (int16_t)value;
    }
}

int main(void) {
    int ret;
    struct i2s_config i2s_cfg;
    void *mem_block_tx;

    if (!device_is_ready(i2s_dev)) {
        LOG_ERR("I2S device is not ready.");
        return 0;
    }

    // Generate the 60 Hz sine wave data
    generate_sine_wave();

    // I2S configuration structure
    i2s_cfg.word_size = BITS_PER_SAMPLE;
    i2s_cfg.channels = CHANNELS;
    i2s_cfg.format = I2S_FMT_DATA_FORMAT_I2S; // Standard I2S format
    i2s_cfg.options = I2S_OPT_FRAME_CLK_MASTER;
    i2s_cfg.frame_clk_freq = SAMPLE_RATE;
    i2s_cfg.mem_slab = &mem_slab_tx;
    i2s_cfg.block_size = BLOCK_SIZE;
    i2s_cfg.timeout = 100;

    ret = i2s_configure(i2s_dev, I2S_DIR_TX, &i2s_cfg);
    if (ret < 0) {
        LOG_ERR("I2S config failed: %d", ret);
        return 0;
    }

    // Trigger start of transmission
    ret = i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_START);
    if (ret < 0) {
        LOG_ERR("I2S trigger start failed: %d", ret);
        return 0;
    }

    while (1) {
        // Allocate a memory block from the slab
        ret = k_mem_slab_alloc(&mem_slab_tx, &mem_block_tx, K_FOREVER);
        if (ret < 0) {
            LOG_ERR("Failed to allocate memory block: %d", ret);
            continue;
        }

        // Copy the sine wave data to the allocated buffer
        memcpy(mem_block_tx, sine_wave_buffer, BLOCK_SIZE);

        // Write the filled buffer to the I2S TX queue
        ret = i2s_write(i2s_dev, mem_block_tx, BLOCK_SIZE);
        if (ret < 0) {
            LOG_ERR("I2S write failed: %d", ret);
            k_mem_slab_free(&mem_slab_tx, mem_block_tx);
        }
    }

    return 0;
}
Related