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

I2S LL Driver fails to compile under C++ (IDFGH-10367) #11625

Closed
3 tasks done
NaivelyWritten opened this issue Jun 8, 2023 · 0 comments
Closed
3 tasks done

I2S LL Driver fails to compile under C++ (IDFGH-10367) #11625

NaivelyWritten opened this issue Jun 8, 2023 · 0 comments
Assignees
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF

Comments

@NaivelyWritten
Copy link

Answers checklist.

  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

5.1-rc1

Operating System used.

macOS

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

What is the expected behavior?

#include <hal/i2s_ll.h> works in a C++ file

What is the actual behavior?

Compile fails

Steps to reproduce.

  1. Step
  2. Step
  3. Step
    ...

Build or installation Logs.

No response

More Information.

#5604

I can use the following patch to make it work:

/**
 * @brief Set the bimap of the active TX chan, only the active chan can launch audio data.
 *
 * @param hw Peripheral I2S hardware instance address.
 * @param chan_mask mask of tx active chan
 */
static inline void i2s_ll_tx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_mask)
{
#if __cplusplus
    decltype(hw->tx_tdm_ctrl.val) tdm_ctrl_reg = hw->tx_tdm_ctrl.val;
    tdm_ctrl_reg &= ~I2S_LL_TDM_CH_MASK;
    tdm_ctrl_reg |= chan_mask & I2S_LL_TDM_CH_MASK;
    hw->tx_tdm_ctrl.val = tdm_ctrl_reg;
#else
    typeof(hw->tx_tdm_ctrl) tdm_ctrl_reg = hw->tx_tdm_ctrl;
    tdm_ctrl_reg.val &= ~I2S_LL_TDM_CH_MASK;
    tdm_ctrl_reg.val |= chan_mask & I2S_LL_TDM_CH_MASK;
    hw->tx_tdm_ctrl.val = tdm_ctrl_reg.val;
#endif
}

/**
 * @brief Set the bimap of the active RX chan, only the active chan can receive audio data.
 *
 * @param hw Peripheral I2S hardware instance address.
 * @param chan_mask mask of rx active chan
 */
static inline void i2s_ll_rx_set_active_chan_mask(i2s_dev_t *hw, uint32_t chan_mask)
{
#if __cplusplus
    decltype(hw->rx_tdm_ctrl.val) tdm_ctrl_reg = hw->rx_tdm_ctrl.val;
    tdm_ctrl_reg &= ~I2S_LL_TDM_CH_MASK;
    tdm_ctrl_reg |= chan_mask & I2S_LL_TDM_CH_MASK;
    hw->rx_tdm_ctrl.val = tdm_ctrl_reg;
#else
    typeof(hw->rx_tdm_ctrl) tdm_ctrl_reg = hw->rx_tdm_ctrl;
    tdm_ctrl_reg.val &= ~I2S_LL_TDM_CH_MASK;
    tdm_ctrl_reg.val |= chan_mask & I2S_LL_TDM_CH_MASK;
    hw->rx_tdm_ctrl.val = tdm_ctrl_reg.val;
#endif
}

Also for the MCLK set function:

/**
 * @brief Configure I2S TX module clock divider
 *
 * @param hw Peripheral I2S hardware instance address.
 * @param sclk system clock
 * @param mclk module clock
 * @param mclk_div integer part of the division from sclk to mclk
 */
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, uint32_t sclk, uint32_t mclk, uint32_t mclk_div)
{
    int ma = 0;
    int mb = 0;
    int denominator = 1;
    int numerator = 0;
    uint32_t min = ~0;

    uint32_t freq_diff = abs((int)sclk - (int)(mclk * mclk_div));
    float decimal = freq_diff / (float)mclk;
    if (!freq_diff) {
        goto finish;
    }
    // Carry bit if the decimal is greater than 1.0 - 1.0 / (63.0 * 2) = 125.0 / 126.0
    if (decimal > 125.0 / 126.0) {
        mclk_div++;
        goto finish;
    }
    for (int a = 2; a <= I2S_LL_MCLK_DIVIDER_MAX; a++) {
        int b = (int)(a * (freq_diff / (double)mclk) + 0.5);
        ma = freq_diff * a;
        mb = mclk * b;
        if (ma == mb) {
            denominator = a;
            numerator = b;
            goto finish;
        }
        if (abs((mb - ma)) < min) {
            denominator = a;
            numerator = b;
            min = abs(mb - ma);
        }
    }
finish:
    HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_clkm_conf, tx_clkm_div_num, mclk_div);
    if (denominator == 0 || numerator == 0) {
        hw->tx_clkm_div_conf.tx_clkm_div_x = 0;
        hw->tx_clkm_div_conf.tx_clkm_div_y = 0;
        hw->tx_clkm_div_conf.tx_clkm_div_z = 0;
    } else {
        if (numerator > denominator / 2) {
            hw->tx_clkm_div_conf.tx_clkm_div_x = denominator / (denominator - numerator) - 1;
            hw->tx_clkm_div_conf.tx_clkm_div_y = denominator % (denominator - numerator);
            hw->tx_clkm_div_conf.tx_clkm_div_z = denominator - numerator;
            hw->tx_clkm_div_conf.tx_clkm_div_yn1 = 1;
        } else {
            hw->tx_clkm_div_conf.tx_clkm_div_x = denominator / numerator - 1;
            hw->tx_clkm_div_conf.tx_clkm_div_y = denominator % numerator;
            hw->tx_clkm_div_conf.tx_clkm_div_z = numerator;
            hw->tx_clkm_div_conf.tx_clkm_div_yn1 = 0;
        }
    }
}

repeat for the TX MCLK set function as well.

@NaivelyWritten NaivelyWritten added the Type: Bug bugs in IDF label Jun 8, 2023
@github-actions github-actions bot changed the title I2S LL Driver fails to compile under C++ I2S LL Driver fails to compile under C++ (IDFGH-10367) Jun 8, 2023
@espressif-bot espressif-bot added the Status: Opened Issue is new label Jun 8, 2023
@espressif-bot espressif-bot added Status: Selected for Development Issue is selected for development Status: In Progress Work is in progress and removed Status: Opened Issue is new Status: Selected for Development Issue is selected for development labels Jun 12, 2023
@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: In Progress Work is in progress labels Jun 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

3 participants