2023-03-07 11:25 AM
Hi, I am trying to use a 4 I2s microphone. And I am using cubemx.
I made work both of them with a sinple DMA transfer.
I used I2s half duplex reciever 16of32bits sample rate 48Khz and DMA for 48*2 samples with uint16_t format. For that I used DMA1 stream 0, pheriferal to memory, half word... circular.
Then I used HAL_I2S_RxCpltCallback to make things in mi code.
All works well.
The problem is when I include another I2S module (i2s3),
I sused cubemx to obtain same configuration but in this case I used DMA1 stream 2.
then
MX_GPIO_Init();
MX_DMA_Init();
MX_I2S2_Init();
MX_I2S3_Init();
HAL_I2S_Receive_DMA(&hi2s2,(uint16_t *)data_i2s2,I2S_BUFFERSIZE);
// HAL_I2S_Receive_DMA(&hi2s3,(uint16_t *)data_i2s3,I2S_BUFFERSIZE);
It is possible make different dma streams in parallel.
I am afraid becouse i have just to realice that stmf401re has only one DMA module.
Can you help me with this?
Solved! Go to Solution.
2023-03-08 01:54 AM
Solved
Thanks @Community member
---------------------------------------------------------------------------------------------------
void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
uint16_t fakemodetest=0;
uint32_t index;
uint16_t ini_loop=0;
uint16_t end_loop=(I2S_BUFFERSIZE/(2*2))-1;
if (hi2s == &hi2s2) {
for(index=ini_loop; index<=end_loop; index++)
{
if (fakemodetest==1)
{
Bufffake8[(4*index)] = data_i2s2[(2*index)];
Bufffake8[(4*index)+1] = data_i2s2[(2*index)+1];
}
else
{
dmaBuffer[(4*index)] = data_i2s2[(2*index)];
dmaBuffer[(4*index)+1] = data_i2s2[(2*index)+1];
}
}
}
else if (hi2s == &hi2s3) {
for(index=ini_loop; index<=end_loop; index++)
{
dmaBuffer[(4*index)+2] = data_i2s3[(2*index)];
dmaBuffer[(4*index)+3] = data_i2s3[(2*index)+1];
}
}
}
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
{
uint16_t fakemodetest=0;
uint32_t index;
uint16_t ini_loop=(I2S_BUFFERSIZE/(2*2))-1;
uint16_t end_loop=(I2S_BUFFERSIZE/2)-1;
if (hi2s == &hi2s2) {
for(index=ini_loop; index<=end_loop; index++)
{
if (fakemodetest==1)
{
Bufffake8[(4*index)]=data_i2s2[(2*index)];
Bufffake8[(4*index)+1]=data_i2s2[(2*index)+1];
}
else
{
dmaBuffer[(4*index)] = data_i2s2[(2*index)];
dmaBuffer[(4*index)+1] = data_i2s2[(2*index)+1];
}
}
flag_Cplti2s2=1;
}
else if (hi2s == &hi2s3) {
for(index=ini_loop; index<=end_loop; index++)
{
dmaBuffer[(4*index)+2]=data_i2s3[(2*index)];
dmaBuffer[(4*index)+3]=data_i2s3[(2*index)+1];
}
flag_Cplti2s3=1;
}
if ((flag_Cplti2s2==1)&(flag_Cplti2s3==1)&(fakemodetest==0)){
flag_Cplti2s2=0; flag_Cplti2s3=0;
HAL_GPIO_WritePin(USBTransfer_GPIO_Port,USBTransfer_Pin,GPIO_PIN_SET);
Send_Audio_to_USB((int16_t *)dmaBuffer, CH_BUFFERSIZE);
HAL_GPIO_WritePin(USBTransfer_GPIO_Port,USBTransfer_Pin,GPIO_PIN_RESET);
}
if ((flag_Cplti2s2==1)&(fakemodetest==1)){
Send_Audio_to_USB((int16_t *)Bufffake8, CH_BUFFERSIZE);
flag_Cplti2s2=0;
}
}
2023-03-07 11:30 AM
It seems that i2s module are only linked with DMA1, and other modules like TIM, ADC, are linked with DMA2. is it possible to associate one I2S to DMA1 and I2s to DMA2? It is possible paralelize streams for sameDMA controller? kind regards,T
2023-03-07 11:50 AM
> It is possible make different dma streams in parallel.
Yes.
I don't understand, how did you configure DMA for I2S2_Rx - there's no connectivity to I2S2_Rx (=SPI2_RX) in DMA1 Stream 0.
SPI2_Rx can be used only with DMA1 Stream 3.
> Is it possible to associate one I2S to DMA1 and I2s to DMA2?
No.
JW
2023-03-07 11:56 AM
Hi, thanks for your fast response.
Yes it is muy fault.
-I2s2 DMA1 stream 3
-I2s3 DMA1 stream 0,2
I could work well with I2s2
HAL_I2S_Receive_DMA(&hi2s2,(uint16_t *)data_i2s2,I2S_BUFFERSIZE);
But when i include I2s3 DMA all star to work bad.
HAL_I2S_Receive_DMA(&hi2s2,(uint16_t *)data_i2s2,I2S_BUFFERSIZE);
// HAL_I2S_Receive_DMA(&hi2s3,(uint16_t *)data_i2s3,I2S_BUFFERSIZE)
Futhermore I do not how works with
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
{
UNUSED(hi2s);
I2S_AUDIO_Process();
}
How I can control that both dma are finished by HAL_I2S_RxCpltCallback
It seems that i have to remove that UNUSED and try to make some flags for each transaction.
is it relevant put different priopry for both DMA?
Thanks for you help, @Community member
Kind regads, TCG
*****
void I2S_AUDIO_Process(void)
{
uint32_t index;
uint16_t modetest=1;
HAL_GPIO_WritePin(USBTransfer_GPIO_Port,USBTransfer_Pin,GPIO_PIN_SET);
for(index=0; index<=I2S_BUFFERSIZE/2; index++)
{
dmaBuffer[(4*index)]=data_i2s2[(2*index)];
dmaBuffer[(4*index)+1]=data_i2s2[(2*index)+1];
dmaBuffer[(4*index)+2]=data_i2s3[(2*index)];
dmaBuffer[(4*index)+3]=data_i2s3[(2*index)+1];
}
Send_Audio_to_USB((int16_t *)dmaBuffer, CH_BUFFERSIZE);
HAL_GPIO_WritePin(USBTransfer_GPIO_Port,USBTransfer_Pin,GPIO_PIN_RESET);
}
2023-03-07 12:47 PM
> But when i include I2s3 DMA all star to work bad.
What is "bad"?
I don't use Cube/HAL, but in HAL_I2S_RxCpltCallback() you are supposed to test, from which I2S came the callback, and process only data of that I2S. Something like (again, I don't use Cube/HAL so I don't know the exact "wording"):
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) {
if (hi2s->Instance == I2S2) {
// copy data for i2s2
} else {
// copy data for i2s3
// and maybe send to usb here, if you are okay with this order
}
}
JW
2023-03-08 12:42 AM
Hi @Community member ,
That is the behaviour with 2 i2s channels and 2 sine in ram .
Then when i include the other i2s 4 channel are working but a bad use of HAL_I2S_RxCallback is producing some 0's in channel 1 (due to 0.5). Those produce a noise in the audio channel. Futhermore CH3 and Ch4 looks well but a iron effect is produced in the channel.
I think that including your feedback it could ork well.
The problem is that hi2s2 is not defined and i do not know how compare this instance.
that is the struct of hi2s
I think that reparing this and including a halfconversion callback it will work
thank a lot;tcg
2023-03-08 01:54 AM
Solved
Thanks @Community member
---------------------------------------------------------------------------------------------------
void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
uint16_t fakemodetest=0;
uint32_t index;
uint16_t ini_loop=0;
uint16_t end_loop=(I2S_BUFFERSIZE/(2*2))-1;
if (hi2s == &hi2s2) {
for(index=ini_loop; index<=end_loop; index++)
{
if (fakemodetest==1)
{
Bufffake8[(4*index)] = data_i2s2[(2*index)];
Bufffake8[(4*index)+1] = data_i2s2[(2*index)+1];
}
else
{
dmaBuffer[(4*index)] = data_i2s2[(2*index)];
dmaBuffer[(4*index)+1] = data_i2s2[(2*index)+1];
}
}
}
else if (hi2s == &hi2s3) {
for(index=ini_loop; index<=end_loop; index++)
{
dmaBuffer[(4*index)+2] = data_i2s3[(2*index)];
dmaBuffer[(4*index)+3] = data_i2s3[(2*index)+1];
}
}
}
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
{
uint16_t fakemodetest=0;
uint32_t index;
uint16_t ini_loop=(I2S_BUFFERSIZE/(2*2))-1;
uint16_t end_loop=(I2S_BUFFERSIZE/2)-1;
if (hi2s == &hi2s2) {
for(index=ini_loop; index<=end_loop; index++)
{
if (fakemodetest==1)
{
Bufffake8[(4*index)]=data_i2s2[(2*index)];
Bufffake8[(4*index)+1]=data_i2s2[(2*index)+1];
}
else
{
dmaBuffer[(4*index)] = data_i2s2[(2*index)];
dmaBuffer[(4*index)+1] = data_i2s2[(2*index)+1];
}
}
flag_Cplti2s2=1;
}
else if (hi2s == &hi2s3) {
for(index=ini_loop; index<=end_loop; index++)
{
dmaBuffer[(4*index)+2]=data_i2s3[(2*index)];
dmaBuffer[(4*index)+3]=data_i2s3[(2*index)+1];
}
flag_Cplti2s3=1;
}
if ((flag_Cplti2s2==1)&(flag_Cplti2s3==1)&(fakemodetest==0)){
flag_Cplti2s2=0; flag_Cplti2s3=0;
HAL_GPIO_WritePin(USBTransfer_GPIO_Port,USBTransfer_Pin,GPIO_PIN_SET);
Send_Audio_to_USB((int16_t *)dmaBuffer, CH_BUFFERSIZE);
HAL_GPIO_WritePin(USBTransfer_GPIO_Port,USBTransfer_Pin,GPIO_PIN_RESET);
}
if ((flag_Cplti2s2==1)&(fakemodetest==1)){
Send_Audio_to_USB((int16_t *)Bufffake8, CH_BUFFERSIZE);
flag_Cplti2s2=0;
}
}