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

Does I2S Stereo in Slave mode have no channel synchronization? #81

Closed
pvvx opened this issue Jan 29, 2023 · 4 comments
Closed

Does I2S Stereo in Slave mode have no channel synchronization? #81

pvvx opened this issue Jan 29, 2023 · 4 comments

Comments

@pvvx
Copy link

pvvx commented Jan 29, 2023

When I2S is initialized in the DMA receive buffer, there is no certainty as to whether the receive data address is even or odd for the L or R channel. Depends on the I2S turn-on time. How to synchronize channels?
This is a hardware defect of all Bouffalo Lab chips?

@pvvx
Copy link
Author

pvvx commented Jan 29, 2023

Without a reset, the i2s will not re-sync.

static void reset_i2s0(void) {
	uint32_t tmpVal;
	tmpVal = getreg32(GLB_BASE+GLB_SWRST_CFG1_OFFSET);
	tmpVal |= GLB_SWRST_S1AA_MSK; // software reset I2S
	putreg32(tmpVal, GLB_BASE + GLB_SWRST_CFG1_OFFSET);
	tmpVal &= ~GLB_SWRST_S1AA_MSK; // software reset I2S
	putreg32(tmpVal, GLB_BASE + GLB_SWRST_CFG1_OFFSET);
}

After reset and initialization, you cannot stop DMA or clear the I2S FIFO, or turn RX off and on - сhannel synchronization will be broken.

The described problem is reliably solved by turning off the external I2S source, resetting the I2S controller, initializing I2S, starting the external source. Channel synchronization will work in such a session.
When changing the I2S parameters, all actions must be repeated.

@minlewang
Copy link

If your pcm data is 8 bits or 16 bits, you can use the channel merge feature to solve this problem

@minlewang
Copy link

    /* enable channel merge */
    bflb_i2s_feature_control(i2s0, I2S_CMD_CHANNEL_LR_MERGE, true);
    /* enable i2s tx and rx */
    bflb_i2s_feature_control(i2s0, I2S_CMD_DATA_ENABLE, I2S_CMD_DATA_ENABLE_TX | I2S_CMD_DATA_ENABLE_RX);

You also need to change the bit width of the DMA's transmitted data.
This method can only work with 8/16bits of pcm data.

@pvvx
Copy link
Author

pvvx commented Jan 31, 2023

24 bits are used.
Solved by workarounds with reset I2S.
There are also situations in y I2C when reset is indispensable.
It is desirable to have macros or functions to reset controllers in the SDK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants