3#include "AudioTools/CoreAudio/AudioI2S/I2SConfig.h"
4#if defined(RP2040_HOWER)
7#define IS_I2S_IMPLEMENTED
18class I2SDriverRP2040 {
19 friend class I2SStream;
23 I2SConfigStd defaultConfig(
RxTxMode mode) {
28 bool setAudioInfo(AudioInfo info) {
29 if (info.sample_rate != cfg.sample_rate && !i2s.setFrequency(info.sample_rate)) {
30 LOGI(
"i2s.setFrequency %d failed", info.sample_rate);
33 if (info.bits_per_sample != cfg.bits_per_sample && !i2s.setBitsPerSample(info.bits_per_sample)) {
34 LOGI(
"i2s.setBitsPerSample %d failed", info.bits_per_sample);
37 cfg.sample_rate = info.sample_rate;
38 cfg.bits_per_sample = info.bits_per_sample;
39 cfg.channels = info.channels;
44 bool begin(
RxTxMode mode = TX_MODE) {
46 return begin(defaultConfig(mode));
50 bool begin(I2SConfigStd cfg) {
56 switch (cfg.rx_tx_mode) {
62 has_input[0] = has_input[1] =
false;
65 LOGE(
"Unsupported mode: only TX_MODE is supported");
71#if (ARDUINO_PICO_MAJOR >= 5 && ARDUINO_PICO_MINOR >= 3)
73 if (!i2s.setSlave()) {
74 LOGE(
"Could not set slave mode");
80 if (cfg.pin_ws == cfg.pin_bck + 1) {
81 if (!i2s.setBCLK(cfg.pin_bck)) {
82 LOGE(
"Could not set bck pin: %d", cfg.pin_bck);
85 }
else if (cfg.pin_ws == cfg.pin_bck - 1) {
86 if (!i2s.swapClocks() ||
89 LOGE(
"Could not set bck pin: %d", cfg.pin_bck);
93 LOGE(
"pins bck: '%d' and ws: '%d' must be next to each other",
94 cfg.pin_bck, cfg.pin_ws);
97 if (!i2s.setDATA(cfg.pin_data)) {
98 LOGE(
"Could not set data pin: %d", cfg.pin_data);
101 if (cfg.pin_mck != -1) {
102 LOGI(
"Using MCK pin: %d with multiplier %d", cfg.pin_mck,
104 i2s.setMCLKmult(cfg.mck_multiplier);
105 if (!i2s.setMCLK(cfg.pin_mck)) {
106 LOGE(
"Could not set data pin: %d", cfg.pin_mck);
111 if (cfg.bits_per_sample == 8 ||
112 !i2s.setBitsPerSample(cfg.bits_per_sample)) {
113 LOGE(
"Could not set bits per sample: %d", cfg.bits_per_sample);
117 if (!i2s.setBuffers(cfg.buffer_count, cfg.buffer_size)) {
118 LOGE(
"Could not set buffers: Count: '%d', size: '%d'", cfg.buffer_count,
124 if (cfg.i2s_format == I2S_STD_FORMAT ||
125 cfg.i2s_format == I2S_PHILIPS_FORMAT) {
127 }
else if (cfg.i2s_format == I2S_LEFT_JUSTIFIED_FORMAT ||
128 cfg.i2s_format == I2S_LSB_FORMAT) {
129 if (!i2s.setLSBJFormat()) {
130 LOGE(
"Could not set LSB Format")
134 LOGE(
"Unsupported I2S format");
138 if (cfg.signal_type != TDM && (cfg.channels < 1 || cfg.channels > 2)) {
139 LOGE(
"Unsupported channels: '%d'", cfg.channels);
143 if (cfg.signal_type == TDM) {
145 i2s.setTDMChannels(cfg.channels);
148 if (!i2s.begin(cfg.sample_rate)) {
149 LOGE(
"Could not start I2S");
164 I2SConfigStd config() {
return cfg; }
167 size_t writeBytes(
const void *src,
size_t size_bytes) {
168 LOGD(
"writeBytes(%d)", size_bytes);
171 if (cfg.channels == 1) {
172 result = writeExpandChannel(src, size_bytes);
173 }
else if (cfg.channels == 2) {
174 const uint8_t *p = (
const uint8_t *)src;
175 while (size_bytes >=
sizeof(int32_t)) {
176 bool justWritten = i2s.write(
180 size_bytes -=
sizeof(int32_t);
181 p +=
sizeof(int32_t);
182 result +=
sizeof(int32_t);
190 size_t readBytes(
void *dest,
size_t size_bytes) {
192 switch (cfg.channels) {
194 return read1Channel(dest, size_bytes);
196 return read2Channels(dest, size_bytes);
201 int availableForWrite() {
202 if (cfg.channels == 1) {
203 return cfg.buffer_size;
205 return i2s.availableForWrite();
209 int available() {
return min(i2s.available(), cfg.buffer_size); }
211 void flush() { i2s.flush(); }
213 bool getOverUnderflow() {
214 return i2s.getOverUnderflow() ;
221 bool is_active =
false;
225 size_t writeExpandChannel(
const void *src,
size_t size_bytes) {
226 switch (cfg.bits_per_sample) {
237 int16_t *pt16 = (int16_t *)src;
238 for (
int j = 0; j < size_bytes /
sizeof(int16_t); j++) {
239 i2s.write16(pt16[j], pt16[j]);
243 int32_t *pt24 = (int32_t *)src;
244 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j++) {
245 i2s.write24(pt24[j], pt24[j]);
249 int32_t *pt32 = (int32_t *)src;
250 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j++) {
251 i2s.write32(pt32[j], pt32[j]);
259 size_t read2Channels(
void *dest,
size_t size_bytes) {
262 switch (cfg.bits_per_sample) {
275 int16_t *data = (int16_t *)dest;
276 for (
int j = 0; j < size_bytes /
sizeof(int16_t); j += 2) {
277 if (i2s.read16(data + j, data + j + 1)) {
286 int32_t *data = (int32_t *)dest;
287 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j += 2) {
288 if (i2s.read24(data + j, data + j + 1)) {
297 int32_t *data = (int32_t *)dest;
298 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j += 2) {
299 if (i2s.read32(data + j, data + j + 1)) {
312 size_t read1Channel(
void *dest,
size_t size_bytes) {
315 switch (cfg.bits_per_sample) {
331 int16_t *data = (int16_t *)dest;
332 for (
int j = 0; j < size_bytes /
sizeof(int16_t); j++) {
333 if (i2s.read16(tmp, tmp + 1)) {
334 data[j] = mix(tmp[0], tmp[1]);
344 int32_t *data = (int32_t *)dest;
345 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j++) {
346 if (i2s.read24(tmp, tmp + 1)) {
347 data[j] = mix(tmp[0], tmp[1]);
357 int32_t *data = (int32_t *)dest;
358 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j++) {
359 if (i2s.read32(tmp, tmp + 1)) {
360 data[j] = mix(tmp[0], tmp[1]);
373 T mix(T left, T right) {
374 if (left != 0) has_input[0] =
true;
375 if (right != 0) has_input[1] =
true;
378 if (has_input[0] && !has_input[1]) {
383 if (!has_input[0] && has_input[1]) {
387 return (left / 2) + (right / 2);
391using I2SDriver = I2SDriverRP2040;
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:30