4
4
#include " AudioI2S/I2SConfig.h"
5
5
6
6
namespace audio_tools {
7
+ #include " stm32-i2s.h"
7
8
8
9
/* *
9
10
* @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!
10
13
* @author Phil Schatzmann
11
14
* @copyright GPLv3
12
15
*/
16
+
13
17
class I2SBase {
14
18
friend class I2SStream ;
15
19
@@ -28,33 +32,47 @@ class I2SBase {
28
32
29
33
// / starts the DAC
30
34
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 ;
36
44
}
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 ;
37
66
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 ;
49
67
}
50
- return result;
68
+
69
+ return true ;
51
70
}
52
71
53
72
// / stops the I2C and unistalls the driver
54
73
void end (){
55
- if (HAL_I2S_DeInit (&i2s) != HAL_OK){
56
- LOGE (" HAL_I2S_DeInit failed" );
57
- }
74
+ stopI2S ();
75
+ deleteBuffers ();
58
76
}
59
77
60
78
// / we assume the data is already available in the buffer
@@ -74,87 +92,37 @@ class I2SBase {
74
92
75
93
// / writes the data to the I2S interface
76
94
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);
86
96
}
87
97
88
98
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
+ }
96
105
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);
98
109
}
99
110
100
111
protected:
101
112
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 ;
127
115
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 ;
141
120
}
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 ;
153
124
}
154
- return I2S_DATAFORMAT_16B;
155
-
156
125
}
157
-
158
126
};
159
127
160
128
}
0 commit comments