The driver uses pinctrl to configure pins instead of nrfx I2S API.
Check whether MCK pin was actually connected by pinctrl instead of
comparing nrfx_cfg.mck_pin that is always NRF_I2S_PIN_NOT_CONNECTED.
This makes it possible for nRF I2S to provide master clock even when
operating in I2S Slave mode.
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Calling I2S write with less bytes than I2S TX memory block size makes it
possible to synchronize the time when next block is used against some
other, possibly externally sourced, signal. Example use case includes
USB Audio where audio sink and/or source has to be synchronized against
USB SOF. In Asynchronous synchronization type the rate matching is
achieved by varying the number of samples sent/received by 1 sample
(e.g. for 48 kHz audio, 47 or 49 samples are transmitted during frame
instead of 48).
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
There is inherent race condition between i2s_nrfx_write() and I2S
interrupt handler because I2S operates independently from the rest
of the system. If software takes too long to supply next TX pointer
then nRF I2S peripheral will simply resupply the previous buffer.
The race window is rather short. The failed race executes as follows:
1. i2s_nrfx_write() checks state and loads next_tx_buffer_needed
2. I2S interrupt handler executes and calls data_handler() which
notices empty TX queue and therefore sets next_tx_buffer_needed
3. i2s_nrfx_write() continues with the queue TX path (because the
next_tx_buffer_needed was false when it was accessed)
If next i2s_nrfx_write() executes before next I2S interrupt:
4a. i2s_nrfx_write() notices next_tx_buffer_needed is true and
supplies the buffer directly to I2S peripheral. Previously queued
buffer will remain in the queue until the just supplied buffer
starts transmitting. Effectively swapping whole I2S block leads to
clearly audible artifacts under normal circumstances.
If next I2S interrupt executes before next i2s_nrfx_write():
4b. data_handler() notices that buffer was reused and stops despite
having a buffer available in TX queue
Modify i2s_nrfx_write() to always queue the TX pointer first and only
supply the buffer to nrfx if the queue was empty when interrupt handler
executed. This prevents both the out-of-order TX and premature stop.
Fixes: #63730
Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
Modify the signature of the k_mem_slab_free() function with a new one,
replacing the old void **mem with void *mem as a parameter.
The following function:
void k_mem_slab_free(struct k_mem_slab *slab, void **mem);
has the wrong signature. mem is only used as a regular pointer, so there
is no need to use a double-pointer. The correct signature should be:
void k_mem_slab_free(struct k_mem_slab *slab, void *mem);
The issue with the current signature, although functional, is that it is
extremely confusing. I myself, a veteran Zephyr developer, was confused
by this parameter when looking at it recently.
All in-tree uses of the function have been adapted.
Fixes#61888.
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
New nrfx release extended nrfx_i2s API and requires to specify
pointer to driver instance structure. This commit aligns SHIM
to reworked nrfx driver.
Signed-off-by: Adam Wojasinski <adam.wojasinski@nordicsemi.no>
Since PINCTRL and pinctrl-0 is now required, there's no point in doing
extra validation at driver level. Modify the macro to just check that
sleep state is present when needed, since it was the only remaining
assertion that was not covered. Renamed the macro to make it more clear
what it does: NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Change automated searching for files using "IRQ_CONNECT()" API not
including <zephyr/irq.h>.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In order to bring consistency in-tree, migrate all drivers to the new
prefix <zephyr/...>. Note that the conversion has been scripted, refer
to #45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Extend the macro with checks for DT properties related to pin
assignments that are defined but would be ignored, depending on
whether PINCTRL is enabled or not, what presumably indicates
a resulting configuration different from what the user expects.
Add also a possibility to indicate that the pinctrl-1 property
should not be checked because the caller does not support the
sleep state.
Rename the macro so that its name better reflects its function.
Update accordingly all drivers that use it.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Add support for the new pinctrl API to the nRF I2S driver. Update code
of the driver and the related devicetree binding.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Shims for nrfx drivers should only connect the related IRQ handlers,
they should not enable the IRQs, as this could lead to a situation
where the interrupt handler is called before the driver had a chance
to properly initialize the peripheral and install the provided event
handler. nrfx drivers will enable the interrupts appropriately on
their own by calling the NRFX_IRQ_ENABLE macro which is implemented
in nrfx_glue.h as a call to irq_enable().
This commit fixes the above issue spotted in the following shims:
- dmic_nrfx_pdm
- clock_control_nrf
- i2s_nrfx
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
- 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 <andrzej.glabek@nordicsemi.no>
Remove unnecessary condition that effectively limits the usability
of the I2S format to two channels mode only.
Although the description of the `i2s_config` structure contains
a remark that for the I2S format the specified number of channels
is ignored and always two are used, in fact only one other in-tree
driver (i2s_sam_ssc) applies such limitation.
The nRF I2S hardware has no problem with handling the I2S format
with audio data for only one channel, so there is no need for having
this limitation in the driver, and without such mode of operation of
the driver it is impossible to feed it with PCM data directly from
the PDM peripheral working in one channel mode.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
I2S direction was not checked correctly in the i2s_nrfx_configure
function.
This patch also fixes coverity issue 238365.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Add a shim that allows using the nrfx I2S driver via the Zephyr API.
Add also missing devicetree nodes representing the I2S peripherals
in the nRF52 Series SoCs.
Extend the "nordic,nrf-i2s" binding with a new property that allows
specifying the clock source to be used by the I2S peripheral (so that
it is possible to use HFXO for better accurracy of the peripheral clock
or, in the nRF53 Series SoCs, to use the dedicated audio oscillator).
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>