I2S Feasability on Portenta H7

I’m attempting to port over CubeIDE generated initialization code for I2S to PIO for the Portenta H7, since as far as I can tell nobody is using I2S on the Portenta, and Arduino’s libraries do not support I2S on the Portenta.

When I bring in the generated header files from Cube and include them, I get a few compiler errors, but they appear to be within the ArduinoMbed-Core, and it isn’t (yet) complaining about the initialization functions.

In file included from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/targets/TARGET_STM/device.h:38:0,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/platform/include/platform/platform.h:28,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/platform/include/platform/FileHandle.h:25,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/macros.h:41,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/variants/PORTENTA_H7_M7/pins_arduino.h:2,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/Arduino.h:76,
                 from src/main.cpp:1:
/Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h:55:5: error: 'RNG_HandleTypeDef' does not name a type; did you mean 'I2S_HandleTypeDef'?
     RNG_HandleTypeDef handle;
     ^~~~~~~~~~~~~~~~~
     I2S_HandleTypeDef
/Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h:73:5: error: 'SPI_HandleTypeDef' does not name a type; did you mean 'I2S_HandleTypeDef'?
     SPI_HandleTypeDef handle;
     ^~~~~~~~~~~~~~~~~
     I2S_HandleTypeDef
/Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h:141:5: error: 'ADC_HandleTypeDef' does not name a type; did you mean 'I2C_HandleTypeDef'?
     ADC_HandleTypeDef handle;
     ^~~~~~~~~~~~~~~~~
     I2C_HandleTypeDef
/Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h:150:5: error: 'QSPI_HandleTypeDef' does not name a type; did you mean 'EXTI_HandleTypeDef'?
     QSPI_HandleTypeDef handle;
     ^~~~~~~~~~~~~~~~~~
     EXTI_HandleTypeDef
In file included from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/targets/TARGET_STM/device.h:38:0,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/platform/include/platform/platform.h:28,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/platform/include/platform/FileHandle.h:25,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/macros.h:41,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/variants/PORTENTA_H7_M7/pins_arduino.h:2,
                 from /Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/Arduino.h:76,
                 from src/main.cpp:1:
/Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h:193:5: error: 'DAC_HandleTypeDef' does not name a type; did you mean 'I2C_HandleTypeDef'?
     DAC_HandleTypeDef handle;
     ^~~~~~~~~~~~~~~~~
     I2C_HandleTypeDef
/Users/trylaarsdam/.platformio/packages/framework-arduino-mbed/cores/arduino/mbed/targets/TARGET_STM/TARGET_STM32H7/objects.h:204:5: error: 'FDCAN_HandleTypeDef' does not name a type; did you mean 'MDMA_HandleTypeDef'?
     FDCAN_HandleTypeDef CanHandle;
     ^~~~~~~~~~~~~~~~~~~
     MDMA_HandleTypeDef
*** [.pio/build/portenta_h7_m7/src/main.cpp.o] Error 1

I’m somewhat stuck with how to get I2S working on the Portentas. I can’t use pure CubeIDE without the massive pain of adding in the Arduino bootloader functionality and losing drivers for WiFi/BLE.

Any guidance on methods for getting I2S ported and working would be helpful. Thanks!

Just selectively copy the init functions and take care of possible interrupts and callbacks being declared as extern "C" when written in .cpp files (or directly put them in .c files), otherwise they won’t be found by the in-C written STM32HAL.

I’ve went ahead and used CubeMX to generate a project that inits I2S1 with

it generated code in main.c, msp_init.c and the header files. Picking and placing the init functions in a C file an exposing said functions gives a compilable firmware. Throw some minimal code to generate a sine wave at 100Hz frequency in the mix and you got yourself a minimal firmware that compiles nicely.

Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [=         ]  13.2% (used 69320 bytes from 523624 bytes)
Flash: [==        ]  18.2% (used 143064 bytes from 786432 bytes)
Building .pio\build\portenta_h7_m7\firmware.bin
======================= [SUCCESS] Took 6.37 seconds =======================

See

Also note that ArduinoCore-mbed has some built in libraries, e.g., to read the microphone on a Portenta H7 vision shield, it has the PDM library and example code.

Worked perfectly, all I had to do was change the pins and clock inits to I2S2 and it worked with the Portenta Breakout.

Would you mind if I used this example to create a PIO library for I2S on the Portenta in the future?

No problem, use the code as you see fit.

1 Like