There are so many examples of audio playback using the on board CS43L22 audio DAC for the STM32F4Discovery available online. The official demo uses the USB Host functionality to read a raw audio file from a USB Flash Drive. Then there are examples that use SD cards in the SPI mode. The STM32F407 microcontroller on the STM32F4Discovery does pack in an SDIO bus for native interface with SD cards, however it turns out that the CS43L22 connects to the STM32F407 using two signal pins PC10 and PC12 that are required by the SDIO bus [SDIO_D2 and SDIO_CK], further, those signals are non-remappable. Therefore it seems it is not possible to get both the DAC and the SDIO interface working together.
I wondered if it was possible to physically remap the I2S3 pins that connects to the CS43L22, instead of the SDIO pins. A check at the datasheet confirmed that I2S3 signals I2S3_CK (initially at PC10, also SDIO_DAT2) and I2S3_SD (initially at PC12, also SDIO_CK) may be remapped through software to appear instead at pins PB3 and PB5 respectively.
I also had the following alternatives in mind:
- Using the on-board DAC on the STM32(pins PA4 and PA5) with a headphone amplifier.
- Now that the signals have been remapped, using an external audio DAC / codec to play back the audio. I felt this somehow defeated the purpose of having a complete audio DAC setup onboard.
- Building a full custom design. This is a good long-term solution, and is in progress.
Since I also had a LCD connected via FSMC to my set-up, the LCD RD pin was mapped to FSMC_NOE (PD4), which also goes to the RESET pin on the CS43L22. This issue had been taken care of by making the LCD write-only [the pin was configured as general push-pull, not AF mode].
I however decided to solve the problem in situ by modding my STM32F4Discovery and rewiring the I2S3 signals onto PB3 and PB5. Armed with the CS43L22 and STM32F4Discovery datasheets and following the traces on the bottom layer of the PCB, I was able to cut the traces and then reroute them onto the PB3 and PB5. It was so simple, I wonder why it hadn’t been like that in the first place.
The F4 Discovery board undergoes the knife
However getting the modified board play back audio via the microSD card took longer than expected. This was due to my inability to perform simultaneous I2S and SDIO data transactions to enable streaming audio playback after the traces were cut and rerouted. I was able to play wave files though by sending the stream to the CS43L22 Audio DAC and waiting for the transfer to complete before requesting another chunk of audio data from the SD Card. This naturally led to significant stuttering in playback.
Debugging led me to the SDIO low level driver, which used to fail after the first frame was read and sent, with the error flag SDIO_STA_DCRCFAIL, meaning data corruption (CRC on received data failed). But how? The traces had been cut properly, there was no sign of electrical continuity.
My instinct was to try out SDIO in 1-bit bus mode. Circular audio playback worked perfectly this time. Therefore it could have something to do with the cut traces (PC10 and PC12). The traces were quite close and one of the cut ends now carried a 48 MHz clock signal.
Next was tried addition of series resistors (100 ohm) on the SDIO lines going from the card to the board. I targeted PC10 and PC12 specifically, and the issue seemed to be resolved even with 4-bit mode now. I was now successfully able to play back streaming audio from the SD Card.
Post-Script
Through further trials, I found out that:
- Keeping 100 ohm resistors between the SD Card both PC10 (SDIO_CK) and PC12 (SDIO_D3), circular audio playback works
- Keeping 100 ohm between SD Card and PC10 (SDIO_CK) but not on PC12 (SDIO_D3), it still works
- Keeping 100 ohm between SD Card and PC12 (SDIO_D3) but connecting PC10 (SDIO_CK) directly to the SD card worked but locked up after a few seconds or so.
The SDIO_CK line needs suitable termination, especially with mine being a wire-wrap breakout board that puts everything together.
The sources will be made available soon.
The sources are now available at https://github.com/abhishek-kakkar/STM32F4SDIOAudio . The code is provided “as-is” as a reference that might be useful, compilation may break with the latest versions of ChibiOS and uGFX.