BlackPill F411CEU6 I2S

Post here first, or if you can't find a relevant section!
Post Reply
Miguel
Posts: 4
Joined: Mon Dec 02, 2024 9:39 pm

BlackPill F411CEU6 I2S

Post by Miguel »

Hello,

I’m developing an autonomous audio recorder that captures signals from a custom amplifier, uses the PMOD I2S2 ADC, and saves them to an SD card at 16-bit, 44.1 kHz (this requires MCLK).

It’s working on an ESP32, but I want to compare different MCUs, primarily to optimize power consumption. The SD data logger is functioning correctly, but I’m struggling to configure the I2S peripheral on an STM32 device since the ESP32 has its own driver.
At the moment, I'm trying to make the I2S work (without the SD connected to other SPI bus).

Before attempting to write the code directly in STM32CubeIDE, I’d like to know if anyone has implemented something similar.

I’m using a BlackPill F411CEU6 (alternatively F401 or F103). Additionally, I believe it’s possible to export code generated in STM32CubeIDE to the Arduino IDE, but I haven’t found a clear, step-by-step guide for this. If such a guide exists, I’d greatly appreciate it, as I need to test different sampling rates. Also, since I need the SPI bus for both the SD card and the ADC (with MCLK), pin management becomes challenging.

My experience with STM32CubeIDE and HAL functions is limited. The same goes for creating Arduino libraries. Any help would be appreciated.

PD: If someone thinks this task would be much easier accomplished on CubeIDE please let me know, so I won't waste mine and others time. :D

Thanks!
Last edited by Miguel on Tue Dec 03, 2024 8:04 am, edited 1 time in total.
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Re: BlackPill F411CEU6 I2S

Post by STM32ardui »

I never made something with I2s on STM32.
Do you know this: https://github.com/pschatzmann/stm32-i2s ?
Do you connect SD-card on ESP32 as SPI or SD-MMC?
Miguel
Posts: 4
Joined: Mon Dec 02, 2024 9:39 pm

Re: BlackPill F411CEU6 I2S

Post by Miguel »

STM32ardui wrote: Tue Dec 03, 2024 7:21 am I never made something with I2s on STM32.
Do you know this: https://github.com/pschatzmann/stm32-i2s ?
Do you connect SD-card on ESP32 as SPI or SD-MMC?
Sorry I wasn't clear enough. I'm trying to make work just the I2S, without the SD card connected to other SPI peripheral, for testing purposes. As far as I understand, its the same hardware/peripheral working with different configuration.

On the ESP32 there are avaiable 4 SPI peripherals (2 for internal flash memory + 2 avaiable). Since all pins are connected through matrix, they are avaiable to any pin. Don't know if the same SPI hardware drives both devices at the same time, in slower ESP32 modules {such as C3 Super Mini} both devices won't work properly at the same time. This might be due its single core. Also, the ESP32 driver for the I2S is provided by Espressif, so there is no need to use Arduino i2s library, and its compatible with all ESP32 devices.

On the Black Pill, 5 SPI drivers are avaiable. 2 (3 and 4) are required for the I2S with Master Clock.

The stm32-i2s provided by Pschatzmann doesnt even compile on my ArduinoIDE.

Example code:

Code: Select all

#include "AudioTools.h"
#include "stm32-i2s.h"

using namespace stm32_i2s;

SineWaveGenerator<int16_t> sineWave(32000);   // subclass of SoundGenerator with max amplitude of 32000
I2SSettingsSTM32 i2s_settings;
Stm32I2sClass I2S;
int sample_rate = 8000;
int channels = 1;

void readToTransmit(uint8_t *buffer, uint16_t byteCount, void*) {
	uint16_t samples = byteCount / 2;
	int16_t *buffer_16 = (int16_t*) buffer;
	for (uint j = 0; j < samples; j+=2) {
		int16_t sample = sineWave.readSample();
		buffer_16[j] = sample;
		buffer_16[j+1] = sample;
	}
}

void setup() {
	Serial.begin(115200);
	sineWave.begin(channels, sample_rate, N_B4);
	i2s_settings.sample_rate = I2S_AUDIOFREQ_8K;
	if (!I2S.beginWriteDMA(i2s_settings, readToTransmit)){
		Serial.println("I2S Error");
	}
}

void loop() {}

Error:
C:\Users\Miguel\AppData\Local\Temp\.arduinoIDE-unsaved2024112-13628-19nnl1.rljl3\i2s-in\i2s-in.ino:4:17: error: 'stm32_i2s' is not a namespace-name
4 | using namespace stm32_i2s;
| ^~~~~~~~~
C:\Users\Miguel\AppData\Local\Temp\.arduinoIDE-unsaved2024112-13628-19nnl1.rljl3\i2s-in\i2s-in.ino:7:1: error: 'I2SSettingsSTM32' does not name a type
7 | I2SSettingsSTM32 i2s_settings;
| ^~~~~~~~~~~~~~~~
C:\Users\Miguel\AppData\Local\Temp\.arduinoIDE-unsaved2024112-13628-19nnl1.rljl3\i2s-in\i2s-in.ino:8:1: error: 'Stm32I2sClass' does not name a type
8 | Stm32I2sClass I2S;
| ^~~~~~~~~~~~~
C:\Users\Miguel\AppData\Local\Temp\.arduinoIDE-unsaved2024112-13628-19nnl1.rljl3\i2s-in\i2s-in.ino: In function 'void setup()':
C:\Users\Miguel\AppData\Local\Temp\.arduinoIDE-unsaved2024112-13628-19nnl1.rljl3\i2s-in\i2s-in.ino:25:9: error: 'i2s_settings' was not declared in this scope
25 | i2s_settings.sample_rate = I2S_AUDIOFREQ_8K;
| ^~~~~~~~~~~~
C:\Users\Miguel\AppData\Local\Temp\.arduinoIDE-unsaved2024112-13628-19nnl1.rljl3\i2s-in\i2s-in.ino:26:14: error: 'I2S' was not declared in this scope
26 | if (!I2S.beginWriteDMA(i2s_settings, readToTransmit)){
| ^~~
Multiple libraries were found for "AudioConfig.h"
Used: C:\Users\Miguel\Documents\Arduino\libraries\arduino-audio-tools
Not used: C:\Users\Miguel\Documents\Arduino\libraries\audio-tools
exit status 1

Compilation error: 'stm32_i2s' is not a namespace-name
I have no idea what ''stm32_i2s' is not a namespace-name' does mean, since is defined at the begining of the 'stm32-i2s.cpp'.

PS: OK, now the code compiles, if I make this code work I will mark it as 'solved'.
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Re: BlackPill F411CEU6 I2S

Post by STM32ardui »

Miguel wrote: Tue Dec 03, 2024 8:19 am I have no idea what ''stm32_i2s' is not a namespace-name' does mean, since is defined at the begining of the 'stm32-i2s.cpp'.

PS: OK, now the code compiles, if I make this code work I will mark it as 'solved'.
Does error disappaer after restarting ArduinoIDE?
fpiSTM
Posts: 1944
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: BlackPill F411CEU6 I2S

Post by fpiSTM »

I know this library uses I2S:
https://github.com/stm32duino/X-NUCLEO- ... f401re.cpp

And here an example how to convert a Cube project to Arduino:
viewtopic.php?t=110
Miguel
Posts: 4
Joined: Mon Dec 02, 2024 9:39 pm

Re: BlackPill F411CEU6 I2S

Post by Miguel »

STM32ardui wrote: Tue Dec 03, 2024 9:37 am
Miguel wrote: Tue Dec 03, 2024 8:19 am I have no idea what ''stm32_i2s' is not a namespace-name' does mean, since is defined at the begining of the 'stm32-i2s.cpp'.

PS: OK, now the code compiles, if I make this code work I will mark it as 'solved'.
Does error disappaer after restarting ArduinoIDE?
Not sure, maybe the problem was the Arduino IDE and some library definition/library folder.

The output example works (it generates a sine signal).

Code: Select all

#include "AudioTools.h"
#include "stm32-i2s.h"
#define LED_BUILTIN PC13
using namespace stm32_i2s;
Stm32I2sClass I2S;
SineWaveGenerator<int16_t> sineWave(2000);   // subclass of SoundGenerator with max amplitude of 2000
I2SSettingsSTM32 i2s_settings;
int sample_rate = 44000;
int channels = 1;

void readToTransmit(uint8_t *buffer, uint16_t byteCount, void*) {
	uint16_t samples = byteCount / 2;
	int16_t *buffer_16 = (int16_t*) buffer;
	for (uint j = 0; j < samples; j+=2) {
		int16_t sample = sineWave.readSample();
		buffer_16[j] = sample;
		buffer_16[j+1] = sample;
	}
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
	Serial.begin(115200);
	sineWave.begin(channels, sample_rate, N_B4);
	i2s_settings.sample_rate = I2S_AUDIOFREQ_44K;
	if (!I2S.beginWriteDMA(i2s_settings, readToTransmit)){
		Serial.println("I2S Error");
		return;
	}
}

void loop() {
}
But the input-output example does not work, I think the interrupt function is not triggered at any time.

This board turns on the user led with LOW. This sketch never turns off the user led. The loopback does not work, and I can't make it work with the STM32CubeIDE (I'm trying to modify this code but it does not work https://github.com/YetAnotherElectronic ... 32_DSP_IIR).

Code: Select all

#include "AudioTools.h"
#include "stm32-i2s.h"
#define LED_BUILTIN PC13
#define I2S_BUFFER_SIZE 512
using namespace stm32_i2s;
Stm32I2sClass I2S;
I2SSettingsSTM32 i2s_settings;
uint8_t buffer[I2S_BUFFER_SIZE];

void readToTransmit(uint8_t *data, uint16_t byteCount, void *) {
  digitalWrite(LED_BUILTIN, HIGH);
  assert(byteCount == I2S_BUFFER_SIZE);
  memmove(data, buffer, byteCount);
}

void writeToReceive(uint8_t *data, uint16_t byteCount, void *) {
  digitalWrite(LED_BUILTIN, HIGH);
  assert(byteCount == I2S_BUFFER_SIZE);
  memmove(buffer, data, byteCount);
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  if (!I2S.beginReadWriteDMA(i2s_settings, readToTransmit, writeToReceive)) {
    digitalWrite(LED_BUILTIN, HIGH);
    return;
  }
}

void loop() {
}
The line ' digitalWrite(LED_BUILTIN, HIGH);' is never called.
I will contact Phil Schatzmann.
fpiSTM
Posts: 1944
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: BlackPill F411CEU6 I2S

Post by fpiSTM »

Try to add extern "C" to the irq callback.

Ex:

Code: Select all

extern "C" void readToTransmit(uint8_t *buffer, uint16_t byteCount, void*) {
Same for the second one
Post Reply

Return to “General discussion”