Skip to content

Commit 9c36c45

Browse files
committed
Separate the configuration of rx and tx slots for I2S in tdm mode
1 parent d290357 commit 9c36c45

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

src/i2s/tdm.rs

+42-10
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,17 @@ pub(super) mod config {
2626
clk_cfg: TdmClkConfig,
2727

2828
/// TDM mode channel slot configuration.
29+
#[cfg(esp_idf_version_major = "4")]
2930
slot_cfg: TdmSlotConfig,
3031

32+
/// TDM mode channel rx slot configuration.
33+
#[cfg(not(esp_idf_version_major = "4"))]
34+
pub(super) slot_rx_cfg: Option<TdmSlotConfig>,
35+
36+
/// TDM mode channel tx slot configuration.
37+
#[cfg(not(esp_idf_version_major = "4"))]
38+
pub(super) slot_tx_cfg: Option<TdmSlotConfig>,
39+
3140
/// TDM mode channel data configuration.
3241
#[cfg(not(esp_idf_version_major = "4"))]
3342
gpio_cfg: TdmGpioConfig,
@@ -40,14 +49,21 @@ pub(super) mod config {
4049
pub fn new(
4150
channel_cfg: Config,
4251
clk_cfg: TdmClkConfig,
43-
slot_cfg: TdmSlotConfig,
52+
#[cfg(esp_idf_version_major = "4")] slot_cfg: TdmSlotConfig,
53+
#[cfg(not(esp_idf_version_major = "4"))] slot_rx_cfg: Option<TdmSlotConfig>,
54+
#[cfg(not(esp_idf_version_major = "4"))] slot_tx_cfg: Option<TdmSlotConfig>,
4455
#[cfg(not(esp_idf_version_major = "4"))] gpio_cfg: TdmGpioConfig,
4556
) -> Self {
4657
Self {
4758
channel_cfg,
4859
clk_cfg,
60+
#[cfg(esp_idf_version_major = "4")]
4961
slot_cfg,
5062
#[cfg(not(esp_idf_version_major = "4"))]
63+
slot_rx_cfg,
64+
#[cfg(not(esp_idf_version_major = "4"))]
65+
slot_tx_cfg,
66+
#[cfg(not(esp_idf_version_major = "4"))]
5167
gpio_cfg,
5268
}
5369
}
@@ -62,12 +78,23 @@ pub(super) mod config {
6278
dout: Option<PeripheralRef<'d, impl OutputPin>>,
6379
mclk: Option<PeripheralRef<'d, impl InputPin + OutputPin>>,
6480
ws: PeripheralRef<'d, impl InputPin + OutputPin>,
65-
) -> i2s_tdm_config_t {
66-
i2s_tdm_config_t {
67-
clk_cfg: self.clk_cfg.as_sdk(),
68-
slot_cfg: self.slot_cfg.as_sdk(),
69-
gpio_cfg: self.gpio_cfg.as_sdk(bclk, din, dout, mclk, ws),
70-
}
81+
) -> (Option<i2s_tdm_config_t>, Option<i2s_tdm_config_t>) {
82+
let clk_cfg = self.clk_cfg.as_sdk();
83+
let gpio_cfg = self.gpio_cfg.as_sdk(bclk, din, dout, mclk, ws);
84+
85+
let rx = self.slot_rx_cfg.map(|slot_cfg| i2s_tdm_config_t {
86+
clk_cfg,
87+
slot_cfg: slot_cfg.as_sdk(),
88+
gpio_cfg,
89+
});
90+
91+
let tx = self.slot_tx_cfg.map(|slot_cfg| i2s_tdm_config_t {
92+
clk_cfg,
93+
slot_cfg: slot_cfg.as_sdk(),
94+
gpio_cfg,
95+
});
96+
97+
(rx, tx)
7198
}
7299

73100
/// Convert to the ESP-IDF SDK `i2s_driver_config_t` representation.
@@ -984,27 +1011,32 @@ impl<'d, Dir> I2sDriver<'d, Dir> {
9841011
mclk: Option<impl Peripheral<P = impl InputPin + OutputPin> + 'd>,
9851012
ws: impl Peripheral<P = impl InputPin + OutputPin> + 'd,
9861013
) -> Result<Self, EspError> {
1014+
// Check that the configuration is correct for the selected mode
1015+
if rx && config.slot_rx_cfg.is_none() || tx && config.slot_tx_cfg.is_none() {
1016+
return Err(EspError::from_infallible::<ESP_ERR_INVALID_ARG>());
1017+
}
1018+
9871019
let chan_cfg = config.channel_cfg.as_sdk(I2S::port());
9881020

9891021
let this = Self::internal_new::<I2S>(&chan_cfg, rx, tx)?;
9901022

9911023
// Create the channel configuration.
992-
let tdm_config = config.as_sdk(
1024+
let (tdm_rx_config, tdm_tx_config) = config.as_sdk(
9931025
bclk.into_ref(),
9941026
din.map(|d_in| d_in.into_ref()),
9951027
dout.map(|d_out| d_out.into_ref()),
9961028
mclk.map(|m_clk| m_clk.into_ref()),
9971029
ws.into_ref(),
9981030
);
9991031

1000-
if rx {
1032+
if let Some(tdm_config) = tdm_rx_config {
10011033
unsafe {
10021034
// Open the RX channel.
10031035
esp!(i2s_channel_init_tdm_mode(this.rx_handle, &tdm_config))?;
10041036
}
10051037
}
10061038

1007-
if tx {
1039+
if let Some(tdm_config) = tdm_tx_config {
10081040
unsafe {
10091041
// Open the TX channel.
10101042
esp!(i2s_channel_init_tdm_mode(this.tx_handle, &tdm_config))?;

0 commit comments

Comments
 (0)