@@ -33,7 +33,7 @@ class I2SBasePIO {
3333 }
3434
3535 // / starts the DAC with the default config in TX Mode
36- bool begin (RxTxMode mode = TX_MODE) {
36+ bool begin (RxTxMode mode = TX_MODE) {
3737 LOGD (LOG_METHOD);
3838 return begin (defaultConfig (mode));
3939 }
@@ -58,19 +58,26 @@ class I2SBasePIO {
5858 LOGE (" Unsupported bits_per_sample: %d" , cfg.bits_per_sample );
5959 return false ;
6060 }
61- if (cfg.channels != 2 ){
61+
62+ if (cfg.channels < 1 || cfg.channels > 2 ){
6263 LOGE (" Unsupported channels: '%d' - only 2 is supported" , cfg.channels );
6364 return false ;
6465 }
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)){
6673 LOGE (" Could not start I2S" );
6774 return false ;
6875 }
6976 return true ;
7077 }
7178
7279 // / stops the I2C and unistalls the driver
73- void end (){
80+ void end () {
7481 I2S.end ();
7582 }
7683
@@ -80,37 +87,80 @@ class I2SBasePIO {
8087 }
8188
8289 // / 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) {
8491 LOGD (LOG_METHOD);
85- // size_t result = I2S.write(src, frames);
8692 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+ }
95107 return result;
96108 }
97109
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);
100112 size_t result = 0 ;
101113 return result;
102114 }
103115
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 ;
106135 }
107136
108- int available () {
109- return I2S.available ();
137+ void flush () {
138+ return I2S.flush ();
110139 }
111140
112141 protected:
113142 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+ }
114164
115165};
116166
0 commit comments