@@ -33,7 +33,7 @@ class I2SBasePIO {
33
33
}
34
34
35
35
// / starts the DAC with the default config in TX Mode
36
- bool begin (RxTxMode mode = TX_MODE) {
36
+ bool begin (RxTxMode mode = TX_MODE) {
37
37
LOGD (LOG_METHOD);
38
38
return begin (defaultConfig (mode));
39
39
}
@@ -58,19 +58,26 @@ class I2SBasePIO {
58
58
LOGE (" Unsupported bits_per_sample: %d" , cfg.bits_per_sample );
59
59
return false ;
60
60
}
61
- if (cfg.channels != 2 ){
61
+
62
+ if (cfg.channels < 1 || cfg.channels > 2 ){
62
63
LOGE (" Unsupported channels: '%d' - only 2 is supported" , cfg.channels );
63
64
return false ;
64
65
}
65
- if (!I2S.begin (cfg.sample_rate )){
66
+
67
+ int rate = cfg.sample_rate ;
68
+ if (cfg.channels ==1 ){
69
+ rate = rate /2 ;
70
+ }
71
+
72
+ if (!I2S.begin (rate)){
66
73
LOGE (" Could not start I2S" );
67
74
return false ;
68
75
}
69
76
return true ;
70
77
}
71
78
72
79
// / stops the I2C and unistalls the driver
73
- void end (){
80
+ void end () {
74
81
I2S.end ();
75
82
}
76
83
@@ -80,37 +87,80 @@ class I2SBasePIO {
80
87
}
81
88
82
89
// / writes the data to the I2S interface
83
- size_t writeBytes (const void *src, size_t size_bytes){
90
+ size_t writeBytes (const void *src, size_t size_bytes) {
84
91
LOGD (LOG_METHOD);
85
- // size_t result = I2S.write(src, frames);
86
92
size_t result = 0 ;
87
- uint32_t *p32 = (uint32_t *)src;
88
- for (int j=0 ;j<size_bytes/4 ;j++){
89
- while (!I2S.write ((void *)p32[j], 4 )){
90
- delay (5 );
91
- }
92
- result = j*4 ;
93
- }
94
- LOGD (" %s: %d -> %d " , LOG_METHOD, size_bytes, result);
93
+ int16_t *p16 = (int16_t *)src;
94
+
95
+ if (cfg.channels ==1 ){
96
+ int samples = size_bytes/2 ;
97
+ // multiply 1 channel into 2
98
+ int16_t buffer[samples*2 ]; // from 1 byte to 2 bytes
99
+ for (int j=0 ;j<samples;j++){
100
+ buffer[j*2 ]= p16[j];
101
+ buffer[j*2 +1 ]= p16[j];
102
+ }
103
+ result = I2S.write ((const uint8_t *)buffer, size_bytes*2 )*2 ;
104
+ } else if (cfg.channels ==2 ){
105
+ result = I2S.write ((const uint8_t *)src, size_bytes)*4 ;
106
+ }
95
107
return result;
96
108
}
97
109
98
- size_t readBytes (void *dest, size_t size_bytes){
99
- LOGD (LOG_METHOD);
110
+ size_t readBytes (void *dest, size_t size_bytes) {
111
+ LOGE (LOG_METHOD);
100
112
size_t result = 0 ;
101
113
return result;
102
114
}
103
115
104
- virtual int availableForWrite () {
105
- return I2S.availableForWrite ();
116
+ int availableForWrite () {
117
+ int result = 0 ;
118
+ if (cfg.channels == 1 ){
119
+ // it should be a multiple of 2
120
+ result = I2S.availableForWrite ()/2 *2 ;
121
+ // return half of it because we double when writing
122
+ result = result / 2 ;
123
+ } else {
124
+ // it should be a multiple of 4
125
+ result = I2S.availableForWrite ()/4 *4 ;
126
+ }
127
+ if (result<4 ){
128
+ result = 0 ;
129
+ }
130
+ return result;
131
+ }
132
+
133
+ int available () {
134
+ return 0 ;
106
135
}
107
136
108
- int available () {
109
- return I2S.available ();
137
+ void flush () {
138
+ return I2S.flush ();
110
139
}
111
140
112
141
protected:
113
142
I2SConfig cfg;
143
+
144
+ // blocking write
145
+ void writeSample (int16_t sample){
146
+ int written = I2S.write (sample);
147
+ while (!written) {
148
+ delay (5 );
149
+ LOGW (" written: %d " , written);
150
+ written = I2S.write (sample);
151
+ }
152
+ }
153
+
154
+ int writeSamples (int samples, int16_t * values){
155
+ int result=0 ;
156
+ for (int j=0 ;j<samples;j++){
157
+ int16_t sample = values[j];
158
+ writeSample (sample);
159
+ writeSample (sample);
160
+ result++;
161
+ }
162
+ return result;
163
+ }
114
164
115
165
};
116
166
0 commit comments