How to use i2s in full-duplex mode

biterror
Posts: 30
Joined: Thu Apr 30, 2020 11:00 am

Re: How to use i2s in full-duplex mode

Postby biterror » Mon Jun 07, 2021 8:30 pm

I have now configured I2S0 as a master receiver (which works) and try to configure I2S1 as a slave transmitter (which does not work). I'm trying to configure the gpio matrix so that I2S1 clock and word select use the same pins as I2S0, but I2S1 is not running. Even the first i2s_write() times out although the DMA buffers should be more than enough to hold the data.

Is it possible to do this? It's so annoying trying all things and not even knowing if I'm trying something that's impossible. I _think_ it should be possible to get the clock and ws to I2S1 from the same pins used by I2S0, but why isn't it working?

I have set the FUN_IE bit in IO_MUX_x_REG for the clock and ws pins. I have also configured GPIO_FUNCn_OUT_SEL_CFG_REG registers for the outputs used by I2S0 (configuring both interfaces to the same pins messes up the config, so I have to fix it manually).

Sigh.

ns1668
Posts: 50
Joined: Tue Mar 16, 2021 2:00 pm

Re: How to use i2s in full-duplex mode

Postby ns1668 » Tue Jun 08, 2021 9:39 am

I'm going to make some assumptions as I haven't tested full-duplex.

You should only need to configure a single I2S port, so I2S0 or I2S1. You should configure it to be master or slave based on what you are going to connect to the clock inputs. If you don't have an external clock then you need to be set the device as master.

I assume that when you use i2s_write you are just adding data to a transmit queue, which is then clocked out based on the sample rate.
So, if you are reading from the rx buffers the slave device will be clocked by the esp32 i2s master. I am unsure how the clock is controlled in a "Master Receive" mode but I assume that you can enable/disable the output clocks as required.

Are you using a custom driver for the i2s, or using the esp-idf HAL/library?

biterror
Posts: 30
Joined: Thu Apr 30, 2020 11:00 am

Re: How to use i2s in full-duplex mode

Postby biterror » Wed Jun 09, 2021 6:12 am

I'm using the driver in idf v4.2 and first I tried using only one I2S interface. TX worked, but RX never returned any data. Then I found (googled) a note that full-duplex mode is not supported by the driver, so I tried using two interfaces instead. Either way, I can make TX _or_ RX work, but not both.

Are there better drivers? Ones that work in full-duplex mode?

I guess using two interfaces should just work if it's possible for the slave interface to get the clocks from the same pins driven by the master. Or is it that the slave doesn't work? I have seen comments about having problems with the slave I2S which disappeared when switching to master mode.

I have simple shift registers connected to I2S to get 40 extra I/O pins. The pins must be "polled" at regular intervals and I2S is great for that - I can generate and process the data in a non-critical task while still keeping the exact timing. IF I can ever make I2S work.

ns1668
Posts: 50
Joined: Tue Mar 16, 2021 2:00 pm

Re: How to use i2s in full-duplex mode

Postby ns1668 » Wed Jun 09, 2021 8:13 am

I guess using two interfaces should just work if it's possible for the slave interface to get the clocks from the same pins driven by the master. Or is it that the slave doesn't work? I have seen comments about having problems with the slave I2S which disappeared when switching to master mode.
Slave mode works - I have tested this with an external codec.

In regards to full duplex, take a look at the i2s driver (i2s.c), there seems to be some code related to running in full duplex, such as:

Code: Select all

#define I2S_FULL_DUPLEX_SLAVE_MODE_MASK   (I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_SLAVE)
#define I2S_FULL_DUPLEX_MASTER_MODE_MASK  (I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_MASTER)
If any espressif staff could confirm that full-duplex functionality does or does not work, it would save you/me more time wondering.

Good luck

biterror
Posts: 30
Joined: Thu Apr 30, 2020 11:00 am

Re: How to use i2s in full-duplex mode

Postby biterror » Wed Jun 09, 2021 9:33 am

Yeah, I was originally using I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX and TX worked just fine, but RX never returned any data.

I agree that it would be great to get some feedback from espressif so I knew whether to keep trying or if it just won't work.

I already read the idf changelog in hopes that the i2s driver has been fixed to work, but didn't find any indication of that.

biterror
Posts: 30
Joined: Thu Apr 30, 2020 11:00 am

Re: How to use i2s in full-duplex mode

Postby biterror » Sun Jun 20, 2021 10:26 am

Okay, I realized that when I built my app using an old idf version, full-duplex was working and yes, that's still the case. Some #defines have changed between idf versions and I finally found out that full-duplex doesn't work with I2S_COMM_FORMAT_STAND_MSB, but it works with I2S_COMM_FORMAT_STAND_I2S, so I changed my code a bit and both directions work now. (Luckily, my hardware "supports" both formats (or, it's too stupid to really care).)

So, I2S full-duplex mode does work with idf v4.2 if you use I2S_COMM_FORMAT_STAND_I2S data format.

ns1668
Posts: 50
Joined: Tue Mar 16, 2021 2:00 pm

Re: How to use i2s in full-duplex mode

Postby ns1668 » Mon Jun 21, 2021 7:41 am

Thanks for the update.
That's very interesting, I will need to test this as I assumed the hardware was only capable of half-duplex (which is what the official documentation states). I wonder if Espressif managed to get it running in full duplex but did not update the documentation.

I have been working on HFP for BT voice comms so will investigate why the I2S format allows full-duplex in the i2s.c driver from esp-idf.
Running in full-duplex from a single I2S port would be very advantageous for my application.

biterror
Posts: 30
Joined: Thu Apr 30, 2020 11:00 am

Re: How to use i2s in full-duplex mode

Postby biterror » Mon Jun 21, 2021 6:44 pm

Please let us know if you get it working. Good luck!

biterror
Posts: 30
Joined: Thu Apr 30, 2020 11:00 am

Re: How to use i2s in full-duplex mode

Postby biterror » Thu Jul 01, 2021 7:27 am

I just noticed that if I use the I2S driver to configure I2S in full-duplex master mode with data format set to I2S_COMM_FORMAT_STAND_I2S and then clear the I2S_RX_MSB_SHIFT and I2S_TX_MSB_SHIFT bits in I2S_CONF_REG, I get the mode I wanted. So it's definately the driver that is broken, the hardware works just fine.

EDIT: It wasn't that simple. I think there's something timing critical or random here. Sometimes the method above works, sometimes the RX side doesn't work after a reboot. I then added a delay before clearing the MSB_SHIFT bits and RX seemed to work every time, but the incoming word rate was only half of what it should have been. Now I'm testing clearing only I2S_TX_MSB_SHIFT and leaving RX in Philips mode.. so far, so good. Needs more testing.

JonS99
Posts: 1
Joined: Wed May 04, 2022 4:33 pm

Re: How to use i2s in full-duplex mode

Postby JonS99 » Wed Feb 22, 2023 3:44 am

Hi. Just wondering if there's any update on this issue...? Were you able to get full duplex mode working without needing the delay?

Thanks.

Who is online

Users browsing this forum: No registered users and 106 guests