Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers: audio: dmic_nrfx: Add support for nRF54H20 #81588

Merged
merged 2 commits into from
Dec 16, 2024

Conversation

mstasiaknordic
Copy link
Contributor

PDM driver can now be used on nRF54H20. It required an addition of DMM mechanism and minor changes to clock management,
nRF54H20 does not require clock control in case of PDM driver.

Currently, product specification for nRF54H20 PDM does not provide fully correct formula to calculate PDM clock frequency, thus master clock source frequency has to be passed as 8 MHz to ensure proper driver behavior. To be corrected and removed once correct formula is found.

nika-nordic
nika-nordic previously approved these changes Nov 29, 2024
Copy link
Collaborator

@nika-nordic nika-nordic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am approving but dmm calls needs to be fixed, could be done later

@@ -59,6 +62,14 @@ static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
LOG_ERR("Failed to allocate buffer: %d", ret);
stop = true;
} else {
ret = dmm_buffer_in_prepare(drv_cfg->mem_reg, &buffer,
drv_data->block_size,
(void *)drv_data->mem_slab->buffer);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is wrong and won't work if non-DMAble buffer is provided - API of dma_buffer_in_prepare looks like this:

int dmm_buffer_in_prepare(void *region, void *user_buffer, size_t user_length, void **buffer_in);

So you should have additional pointer void *dma_buffer , use it in dma_buffer_in_prepare and then in nrfx_pdm_buffer_set :

struct dmic_nrfx_pdm_drv_data {
	const nrfx_pdm_t *pdm;
	struct onoff_manager *clk_mgr;
        void *memslab_buffer;
};

void event_handler() {
void *dma_buffer;

k_mem_slab_alloc(drv_data->mem_slab, &dev->data->memslab_buffer, K_NO_WAIT);
dmm_buffer_in_prepare(drv_cfg->mem_reg, dev->data->memslab_buffer,
	              drv_data->block_size,
                      &dma_buffer);
nrfx_pdm_buffer_set(drv_data->pdm, dma_buffer, drv_data->block_size / 2);
}

Then, when PDM is stopped or buffer is filled with data, and the DMA buffer is to be freed:

else if (evt->buffer_released) {
	       ret = dmm_buffer_in_release(drv_cfg->mem_reg, dev->data->memslab_buffer,
						  drv_data->block_size,
						  evt->buffer_released);
		ret = k_msgq_put(&drv_data->rx_queue,
				 dev->data->memslab_buffer,
				 K_NO_WAIT);
               /* User calls k_mem_slab_free on original `dev->data->memslab_buffer`  */

Similar code needs to be applied to if (drv_data->stopping) { conditional

It works right now because dmm calls does nothing if memslab is completely preallocated in correct region, and this seem to be the case for existing tests

Added pdm0 node to nrf54h20 devicetree with proper bindings.

Signed-off-by: Michał Stasiak <[email protected]>
Added support for DMM in PDM drivers in order to use it
with nRF54H20.

Signed-off-by: Michał Stasiak <[email protected]>
@kartben kartben merged commit ff405ea into zephyrproject-rtos:main Dec 16, 2024
26 checks passed
@mstasiaknordic mstasiaknordic deleted the nrf54h20_pdm branch January 2, 2025 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants