2022-11-21 10:02 AM
I have 2 I2S ports. I have a masterclock from an external source.
My clock config is set for external 24.576Mhz I2S clock.
I have set up I2S1 in half duplex slave mode for an ADC. It is receiving data in DMA.
I have setup I2S2 in half duplex master mode for a DAC. It does absolutely nothing, except set the registers up exactly as per the reference manual.
I2S is enabled in master. DMA has transfered the first byte to the output DR. Everythng is waiting on TXE to fire and I2S to send the byte, but... it doesn't.
Further, it produces no BCK and hold LRCLK HIGH. Why HIGH? It's setup in standard I2S which expects the left (LOW) channel first. Why is it holding that line high? It should be low.
I have run the logic analyser on it and the ONLY signal I see is the master clock, which is not from the STM32. NONE of the I2S pins move. The only way I can get any of them to even trigger on an edge to hit NRST.
I have had it working in master before, when it was generating the MCK output.
My suspicion is that the configuration of GPIO PA2 as MCLK input is broken and can only be applied to ONE AFR5. Either SPI1 or SPI2. Trying to use it for both fails. I just can't confirm it or fix it. I can only see it Init'ing pin PA2 once. For GPIO_AF5_SPI1. I have tried swapping that to GPIO_AF5_SPI2 but this had no effect.
The I2S interface is, for some reason, not being driven by the external clock.
Note. If I connect another set of jumpers between an ADC and the same I2S pins for the DAC... music comes out. So both ADC and DAC are configured correctly. I2S2 is innert completely non-functional. All the lights on, but nobody is home. Has to be the MCLK.
Solved! Go to Solution.
2022-11-21 11:45 AM
__HAL_RCC_I2S_CONFIG(RCC_I2SCLKSOURCE_EXT);
Fixes it. The code that sets all this up in the HAL libraries is a mess of ifdef this ifdef that and multiple layers of macro expansion. I'm not surprised it has bugs.
2022-11-21 11:05 AM
I have a lead.
Stepping through the code, reading the reference manual, rinse repeat.
I found this function:
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
Which calls:
/* Get the current I2S source */
srcclk = __HAL_RCC_GET_I2S_SOURCE();
Which is my case currently returns: RCC_I2SCLKSOURCE_PLLI2S
So ... I2S is configured (both 1 and 2) to use the PLLI2S input. However RCC is setup to use the external clock on I2S_CKIN (PA2).
"That's your problem right there."
So, now I got a figure out a fix. Obviously this is a bug in HAL code. I'll track down if and where that register is being set and if it's not I'll add it in a usercode section.
It also makes sense why the slave was working, it doesn't need to generate any clocks so it wouldn't have mattered to it.... much.
I get the feeling these HAL libraries are a bit of a lucky bag. Sometimes you get lucky, some times you get bugs. Either way you'll end up understanding what they do better than they do and wondering why you bothered. They certainly don't make the platform accessible. I can bet this turns away 1000s of hobbyists and professionals.
2022-11-21 11:45 AM
__HAL_RCC_I2S_CONFIG(RCC_I2SCLKSOURCE_EXT);
Fixes it. The code that sets all this up in the HAL libraries is a mess of ifdef this ifdef that and multiple layers of macro expansion. I'm not surprised it has bugs.