Skip to content

Commit 2fb7364

Browse files
committed
STM32 I2S
1 parent 325aa40 commit 2fb7364

File tree

2 files changed

+61
-90
lines changed

2 files changed

+61
-90
lines changed

src/AudioI2S/I2SConfig.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ class I2SConfig : public AudioBaseInfo {
7777
int pin_data_rx; // rx pin for RXTX_MODE
7878
I2SFormat i2s_format = I2S_STD_FORMAT;
7979

80-
#ifdef ESP32
80+
#if defined(STM32)
81+
int buffer_count = I2S_BUFFER_COUNT;
82+
int buffer_size = I2S_BUFFER_SIZE;
83+
#elif defined(ESP32)
8184
int buffer_count = I2S_BUFFER_COUNT;
8285
int buffer_size = I2S_BUFFER_SIZE;
8386

src/AudioI2S/I2SSTM32.h

Lines changed: 57 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
#include "AudioI2S/I2SConfig.h"
55

66
namespace audio_tools {
7+
#include "stm32-i2s.h"
78

89
/**
910
* @brief Basic I2S API - for the STM32
11+
* Depends on https://github.com/pschatzmann/STM32F411-i2s-prototype
12+
* We just add a write and read buffer!
1013
* @author Phil Schatzmann
1114
* @copyright GPLv3
1215
*/
16+
1317
class I2SBase {
1418
friend class I2SStream;
1519

@@ -28,33 +32,47 @@ class I2SBase {
2832

2933
/// starts the DAC
3034
bool begin(I2SConfig cfg) {
31-
bool result = true;
32-
this->cfg = cfg;
33-
i2s.Instance = SPI2;
34-
if (cfg.channels=!2){
35-
LOGE("Unsupported channels %d - must be 2", cfg.channels);
35+
deleteBuffers();
36+
37+
if (cfg.bits_per_sample!=16){
38+
LOGE("Bits per second not supported: %d", cfg.bits_per_sample);
39+
return false;
40+
}
41+
if (cfg.sample_rate!=44100){
42+
LOGE("Sample rate not supported: %d", cfg.sample_rate);
43+
return false;
3644
}
45+
if (cfg.channels!=2){
46+
LOGE("Channels not supported: %d", cfg.channels);
47+
return false;
48+
}
49+
50+
switch(cfg.rx_tx_mode){
51+
case RX_MODE:
52+
p_rx_buffer = new NBuffer<uint8_t>(cfg.buffer_size, cfg.buffer_count);
53+
startI2SReceive(&hi2s3, writeFromReceive, cfg.buffer_size);
54+
break;
55+
case TX_MODE:
56+
p_tx_buffer = new NBuffer<uint8_t>(cfg.buffer_size, cfg.buffer_count);
57+
startI2STransmit(&hi2s3, readToTransmit, cfg.buffer_size);
58+
break;
59+
case RXTX_MODE:
60+
p_tx_buffer = new NBuffer<uint8_t>(cfg.buffer_size, cfg.buffer_count);
61+
startI2STransmitReceive(&hi2s3, readToTransmit, writeFromReceive, cfg.buffer_size);
62+
break;
63+
default:
64+
LOGE("Unsupported mode");
65+
return false;
3766

38-
i2s.Init.Mode = getMode(cfg);
39-
i2s.Init.Standard = getStandard(cfg);
40-
i2s.Init.DataFormat = getDataFormat(cfg);
41-
i2s.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
42-
i2s.Init.AudioFreq = cfg.sample_rate;
43-
i2s.Init.CPOL = I2S_CPOL_LOW;
44-
i2s.Init.ClockSource = I2S_CLOCK_PLL;
45-
i2s.Init.FullDuplexMode = cfg.rx_tx_mode==RXTX_MODE? I2S_FULLDUPLEXMODE_ENABLE: I2S_FULLDUPLEXMODE_DISABLE;
46-
if (HAL_I2S_Init(&i2s) != HAL_OK){
47-
LOGE("HAL_I2S_Init failed");
48-
result = false;
4967
}
50-
return result;
68+
69+
return true;
5170
}
5271

5372
/// stops the I2C and unistalls the driver
5473
void end(){
55-
if (HAL_I2S_DeInit(&i2s) != HAL_OK){
56-
LOGE("HAL_I2S_DeInit failed");
57-
}
74+
stopI2S();
75+
deleteBuffers();
5876
}
5977

6078
/// we assume the data is already available in the buffer
@@ -74,87 +92,37 @@ class I2SBase {
7492

7593
/// writes the data to the I2S interface
7694
size_t writeBytes(const void *src, size_t size_bytes){
77-
size_t result = 0;
78-
HAL_StatusTypeDef res = HAL_I2S_Transmit(&i2s, (uint16_t*)src, size_bytes/2, HAL_MAX_DELAY);
79-
if(res == HAL_OK) {
80-
result = size_bytes;
81-
} else {
82-
LOGE("HAL_I2S_Transmit failed");
83-
}
84-
85-
return result;
95+
return p_tx_buffer->writeArray((uint8_t*)src, size_bytes);
8696
}
8797

8898
size_t readBytes(void *dest, size_t size_bytes){
89-
size_t result = 0;
90-
HAL_StatusTypeDef res = HAL_I2S_Receive(&i2s, (uint16_t*)dest, size_bytes, HAL_MAX_DELAY);
91-
if(res == HAL_OK) {
92-
result = size_bytes;
93-
} else {
94-
LOGE("HAL_I2S_Receive failed");
95-
}
99+
return p_rx_buffer->readArray((uint8_t*)dest, size_bytes);
100+
}
101+
102+
static void writeFromReceive(uint8_t *buffer, uint16_t byteCount){
103+
p_rx_buffer->writeArray(buffer, byteCount);
104+
}
96105

97-
return result;
106+
static void readToTransmit(uint8_t *buffer, uint16_t byteCount) {
107+
memset(buffer,0,byteCount);
108+
p_tx_buffer->readArray(buffer, byteCount);
98109
}
99110

100111
protected:
101112
I2SConfig cfg;
102-
I2S_HandleTypeDef i2s;
103-
104-
uint32_t getMode(I2SConfig &cfg){
105-
if (cfg.is_master) {
106-
switch(cfg.rx_tx_mode){
107-
case RX_MODE:
108-
return I2S_MODE_MASTER_RX;
109-
case TX_MODE:
110-
return I2S_MODE_MASTER_TX;
111-
default:
112-
LOGE("RXTX_MODE not supported");
113-
return I2S_MODE_MASTER_TX;
114-
}
115-
} else {
116-
switch(cfg.rx_tx_mode){
117-
case RX_MODE:
118-
return I2S_MODE_SLAVE_RX;
119-
case TX_MODE:
120-
return I2S_MODE_SLAVE_TX;
121-
default:
122-
LOGE("RXTX_MODE not supported");
123-
return I2S_MODE_SLAVE_TX;
124-
}
125-
}
126-
}
113+
inline static NBuffer<uint8_t> *p_tx_buffer=nullptr;
114+
inline static NBuffer<uint8_t> *p_rx_buffer=nullptr;
127115

128-
129-
uint32_t getStandard(I2SConfig &cfg){
130-
uint32_t result;
131-
switch(cfg.i2s_format) {
132-
case I2S_PHILIPS_FORMAT:
133-
return I2S_STANDARD_PHILIPS;
134-
case I2S_STD_FORMAT:
135-
case I2S_LSB_FORMAT:
136-
case I2S_RIGHT_JUSTIFIED_FORMAT:
137-
return I2S_STANDARD_MSB;
138-
case I2S_MSB_FORMAT:
139-
case I2S_LEFT_JUSTIFIED_FORMAT:
140-
return I2S_STANDARD_LSB;
116+
void deleteBuffers() {
117+
if (p_rx_buffer!=nullptr) {
118+
delete p_rx_buffer;
119+
p_rx_buffer = nullptr;
141120
}
142-
return I2S_STANDARD_PHILIPS;
143-
}
144-
145-
uint32_t getDataFormat(I2SConfig &cfg) {
146-
switch(cfg.bits_per_sample){
147-
case 16:
148-
return I2S_DATAFORMAT_16B;
149-
case 24:
150-
return I2S_DATAFORMAT_24B;
151-
case 32:
152-
return I2S_DATAFORMAT_32B;
121+
if (p_tx_buffer!=nullptr) {
122+
delete p_tx_buffer;
123+
p_tx_buffer = nullptr;
153124
}
154-
return I2S_DATAFORMAT_16B;
155-
156125
}
157-
158126
};
159127

160128
}

0 commit comments

Comments
 (0)