From 5473b22275c1fa78d2fa68bc9320ebb60452b16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Thu, 23 Sep 2021 12:35:53 +0200 Subject: [PATCH] drivers: i2s_nrfx: Fix a few minor fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - correct the names of buffers used by message queues so that it is possible to have multiple instances of the driver (in case such need appears in the future) - make `stop` and `discard_rx` normal structure members, not bit fields, as they are modified in the interrupt handler and that could lead to overwriting of other bit fields located in the same memory unit - add a log message providing the actual frame clock (WS) frequency (i.e. PCM rate) that the driver was able to configure (due to hardware limitations, it is not always possible to achieve the exact requested frequency and the driver selects the closest one available, so make it more visible to users Signed-off-by: Andrzej Głąbek --- drivers/i2s/i2s_nrfx.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/i2s/i2s_nrfx.c b/drivers/i2s/i2s_nrfx.c index 8f87413adcd..1073c6c94bf 100644 --- a/drivers/i2s/i2s_nrfx.c +++ b/drivers/i2s/i2s_nrfx.c @@ -27,12 +27,12 @@ struct i2s_nrfx_drv_data { const uint32_t *last_tx_buffer; enum i2s_state state; enum i2s_dir active_dir; + bool stop; /* stop after the current (TX or RX) block */ + bool discard_rx; /* discard further RX blocks */ + volatile bool next_tx_buffer_needed; bool tx_configured : 1; bool rx_configured : 1; - bool stop : 1; /* stop after the current (TX or RX) block */ - bool discard_rx : 1; /* discard further RX blocks */ bool request_clock : 1; - volatile bool next_tx_buffer_needed; }; struct i2s_nrfx_drv_cfg { @@ -81,6 +81,7 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg, uint32_t best_diff = UINT32_MAX; uint8_t r, best_r = 0; nrf_i2s_mck_t best_mck_cfg = 0; + uint32_t best_mck = 0; for (r = 0; r < ARRAY_SIZE(ratios); ++r) { /* Only multiples of the frame width can be used as ratios. */ @@ -110,6 +111,7 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg, if (diff < best_diff) { best_mck_cfg = mck_factor * 4096; + best_mck = actual_mck; best_r = r; /* Stop if an exact match is found. */ if (diff == 0) { @@ -150,6 +152,7 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg, if (diff < best_diff) { best_mck_cfg = dividers[d].divider_enum; + best_mck = mck_freq; best_r = r; /* Stop if an exact match is found. */ if (diff == 0) { @@ -173,6 +176,8 @@ static void find_suitable_clock(const struct i2s_nrfx_drv_cfg *drv_cfg, config->mck_setup = best_mck_cfg; config->ratio = ratios[best_r].ratio_enum; + LOG_INF("I2S MCK frequency: %u, actual PCM rate: %u", + best_mck, best_mck / ratios[best_r].ratio_val); } static bool get_next_tx_buffer(struct i2s_nrfx_drv_data *drv_data, @@ -876,8 +881,8 @@ static const struct i2s_driver_api i2s_nrf_drv_api = { #define I2S_CLK_SRC(idx) DT_STRING_TOKEN(I2S(idx), clock_source) #define I2S_NRFX_DEVICE(idx) \ - static void *tx_msgs[CONFIG_I2S_NRFX_TX_BLOCK_COUNT]; \ - static void *rx_msgs[CONFIG_I2S_NRFX_RX_BLOCK_COUNT]; \ + static void *tx_msgs##idx[CONFIG_I2S_NRFX_TX_BLOCK_COUNT]; \ + static void *rx_msgs##idx[CONFIG_I2S_NRFX_RX_BLOCK_COUNT]; \ static struct i2s_nrfx_drv_data i2s_nrfx_data##idx = { \ .state = I2S_STATE_READY, \ }; \ @@ -887,11 +892,11 @@ static const struct i2s_driver_api i2s_nrf_drv_api = { nrfx_isr, nrfx_i2s_irq_handler, 0); \ irq_enable(DT_IRQN(I2S(idx))); \ k_msgq_init(&i2s_nrfx_data##idx.tx_queue, \ - (char *)tx_msgs, sizeof(void *), \ - CONFIG_I2S_NRFX_TX_BLOCK_COUNT); \ + (char *)tx_msgs##idx, sizeof(void *), \ + ARRAY_SIZE(tx_msgs##idx)); \ k_msgq_init(&i2s_nrfx_data##idx.rx_queue, \ - (char *)rx_msgs, sizeof(void *), \ - CONFIG_I2S_NRFX_RX_BLOCK_COUNT); \ + (char *)rx_msgs##idx, sizeof(void *), \ + ARRAY_SIZE(rx_msgs##idx)); \ init_clock_manager(dev); \ return 0; \ } \