5#if defined(RP2040_HOWER)
8#define IS_I2S_IMPLEMENTED
19class I2SDriverRP2040 :
public I2SDriverBase {
20 friend class I2SStream;
24 I2SConfigStd defaultConfig(RxTxMode mode) {
29 bool setAudioInfo(AudioInfo info) {
30 if (info.sample_rate != cfg.sample_rate && !i2s.setFrequency(info.sample_rate)) {
31 LOGI(
"i2s.setFrequency %d failed", info.sample_rate);
34 if (info.bits_per_sample != cfg.bits_per_sample && !i2s.setBitsPerSample(info.bits_per_sample)) {
35 LOGI(
"i2s.setBitsPerSample %d failed", info.bits_per_sample);
38 cfg.sample_rate = info.sample_rate;
39 cfg.bits_per_sample = info.bits_per_sample;
40 cfg.channels = info.channels;
45 bool begin(RxTxMode mode = TX_MODE) {
47 return begin(defaultConfig(mode));
51 bool begin(I2SConfigStd cfg) {
56 has_input[0] = has_input[1] =
false;
60 if (!setupMode())
return false;
61 if (!setupSlaveMode())
return false;
62 if (!setupClockPins())
return false;
63 if (!setupDataPins())
return false;
64 if (!setupMCK())
return false;
65 if (!setupAudioParameters())
return false;
67 if (!i2s.begin(cfg.sample_rate)) {
68 LOGE(
"Could not start I2S");
83 I2SConfigStd config() {
return cfg; }
86 size_t writeBytes(
const void *src,
size_t size_bytes) {
87 LOGD(
"writeBytes(%d)", size_bytes);
90 if (cfg.channels == 1) {
91 result = writeExpandChannel(src, size_bytes);
92 }
else if (cfg.channels == 2) {
93 const uint8_t *p = (
const uint8_t *)src;
94 while (size_bytes >=
sizeof(int32_t)) {
95 bool justWritten = i2s.write(
99 size_bytes -=
sizeof(int32_t);
100 p +=
sizeof(int32_t);
101 result +=
sizeof(int32_t);
109 size_t readBytes(
void *dest,
size_t size_bytes) {
111 switch (cfg.channels) {
113 return read1Channel(dest, size_bytes);
115 return read2Channels(dest, size_bytes);
120 int availableForWrite() {
121 if (cfg.channels == 1) {
122 return cfg.buffer_size;
124 return i2s.availableForWrite();
128 int available() {
return min(i2s.available(), cfg.buffer_size); }
130 void flush() { i2s.flush(); }
132 bool getOverUnderflow() {
133 return i2s.getOverUnderflow() ;
140 bool is_active =
false;
144 switch (cfg.rx_tx_mode) {
155 LOGE(
"Unsupported mode");
162 bool setupSlaveMode() {
163#if (ARDUINO_PICO_MAJOR >= 5 && ARDUINO_PICO_MINOR >= 3)
164 if (!cfg.is_master) {
165 if (!i2s.setSlave()) {
166 LOGE(
"Could not set slave mode");
175 bool setupClockPins() {
176 if (cfg.pin_ws == cfg.pin_bck + 1) {
177 if (!i2s.setBCLK(cfg.pin_bck)) {
178 LOGE(
"Could not set bck pin: %d", cfg.pin_bck);
181 }
else if (cfg.pin_ws == cfg.pin_bck - 1) {
182 if (!i2s.swapClocks() ||
185 LOGE(
"Could not set bck pin: %d", cfg.pin_bck);
189 LOGE(
"pins bck: '%d' and ws: '%d' must be next to each other",
190 cfg.pin_bck, cfg.pin_ws);
197 bool setupDataPins() {
198 if (cfg.rx_tx_mode == RXTX_MODE) {
199 if (!i2s.setDOUT(cfg.pin_data)) {
200 LOGE(
"Could not set pin_data: %d with setDOUT()", cfg.pin_data);
203 if (!i2s.setDIN(cfg.pin_data_rx)) {
204 LOGE(
"Could not set pin_data_rx: %d with setDIN()", cfg.pin_data);
208 int pin = cfg.pin_data;
210 if (cfg.rx_tx_mode == RX_MODE && cfg.pin_data_rx != -1) {
211 pin = cfg.pin_data_rx;
214 if (cfg.rx_tx_mode == TX_MODE && cfg.pin_data != -1) {
218 if (pin == -1) pin = cfg.pin_data;
220 if (!i2s.setDATA(pin)) {
221 LOGE(
"Could not set pin_data: %d with pin_data()", pin);
230 if (cfg.pin_mck != -1) {
231 LOGI(
"Using MCK pin: %d with multiplier %d", cfg.pin_mck,
233 i2s.setMCLKmult(cfg.mck_multiplier);
234 if (!i2s.setMCLK(cfg.pin_mck)) {
235 LOGE(
"Could not set data pin: %d", cfg.pin_mck);
243 bool setupAudioParameters() {
244 if (cfg.bits_per_sample == 8 ||
245 !i2s.setBitsPerSample(cfg.bits_per_sample)) {
246 LOGE(
"Could not set bits per sample: %d", cfg.bits_per_sample);
250 if (!i2s.setBuffers(cfg.buffer_count, cfg.buffer_size)) {
251 LOGE(
"Could not set buffers: Count: '%d', size: '%d'", cfg.buffer_count,
257 if (cfg.i2s_format == I2S_STD_FORMAT ||
258 cfg.i2s_format == I2S_PHILIPS_FORMAT) {
260 }
else if (cfg.i2s_format == I2S_LEFT_JUSTIFIED_FORMAT ||
261 cfg.i2s_format == I2S_LSB_FORMAT) {
262 if (!i2s.setLSBJFormat()) {
263 LOGE(
"Could not set LSB Format")
267 LOGE(
"Unsupported I2S format");
271 if (cfg.signal_type != TDM && (cfg.channels < 1 || cfg.channels > 2)) {
272 LOGE(
"Unsupported channels: '%d'", cfg.channels);
276 if (cfg.signal_type == TDM) {
278 i2s.setTDMChannels(cfg.channels);
285 size_t writeExpandChannel(
const void *src,
size_t size_bytes) {
286 switch (cfg.bits_per_sample) {
297 int16_t *pt16 = (int16_t *)src;
298 for (
int j = 0; j < size_bytes /
sizeof(int16_t); j++) {
299 i2s.write16(pt16[j], pt16[j]);
303 int32_t *pt24 = (int32_t *)src;
304 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j++) {
305 i2s.write24(pt24[j], pt24[j]);
309 int32_t *pt32 = (int32_t *)src;
310 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j++) {
311 i2s.write32(pt32[j], pt32[j]);
319 size_t read2Channels(
void *dest,
size_t size_bytes) {
322 switch (cfg.bits_per_sample) {
335 int16_t *data = (int16_t *)dest;
336 for (
int j = 0; j < size_bytes /
sizeof(int16_t); j += 2) {
337 if (i2s.read16(data + j, data + j + 1)) {
346 int32_t *data = (int32_t *)dest;
347 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j += 2) {
348 if (i2s.read24(data + j, data + j + 1)) {
357 int32_t *data = (int32_t *)dest;
358 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j += 2) {
359 if (i2s.read32(data + j, data + j + 1)) {
372 size_t read1Channel(
void *dest,
size_t size_bytes) {
375 switch (cfg.bits_per_sample) {
391 int16_t *data = (int16_t *)dest;
392 for (
int j = 0; j < size_bytes /
sizeof(int16_t); j++) {
393 if (i2s.read16(tmp, tmp + 1)) {
394 data[j] = mix(tmp[0], tmp[1]);
404 int32_t *data = (int32_t *)dest;
405 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j++) {
406 if (i2s.read24(tmp, tmp + 1)) {
407 data[j] = mix(tmp[0], tmp[1]);
417 int32_t *data = (int32_t *)dest;
418 for (
int j = 0; j < size_bytes /
sizeof(int32_t); j++) {
419 if (i2s.read32(tmp, tmp + 1)) {
420 data[j] = mix(tmp[0], tmp[1]);
433 T mix(T left, T right) {
434 if (left != 0) has_input[0] =
true;
435 if (right != 0) has_input[1] =
true;
438 if (has_input[0] && !has_input[1]) {
443 if (!has_input[0] && has_input[1]) {
447 return (left / 2) + (right / 2);
#define INPUT
Definition Arduino.h:34
#define OUTPUT
Definition Arduino.h:38
#define INPUT_PULLUP
Definition Arduino.h:42
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26
constexpr const _Ep * end(initializer_list< _Ep > __il) noexcept
Definition InitializerList.h:63
constexpr const _Ep * begin(initializer_list< _Ep > __il) noexcept
Definition InitializerList.h:55