diff --git a/input_i2s2.cpp b/input_i2s2.cpp index 5edf5f97..3b538cfc 100644 --- a/input_i2s2.cpp +++ b/input_i2s2.cpp @@ -48,7 +48,7 @@ void AudioInputI2S2::begin(void) //block_left_1st = NULL; //block_right_1st = NULL; - // TODO: should we set & clear the I2S_RCSR_SR bit here? + I2S2_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic AudioOutputI2S2::config_i2s(); CORE_PIN5_CONFIG = 2; //EMC_08, 2=SAI2_RX_DATA, page 434 @@ -154,10 +154,17 @@ void AudioInputI2S2::update(void) block_offset = 0; __enable_irq(); // then transmit the DMA's former blocks - transmit(out_left, 0); - release(out_left); - transmit(out_right, 1); - release(out_right); + if (NULL != out_left) + { + transmit(out_left, 0); + release(out_left); + } + + if (NULL != out_right) + { + transmit(out_right, 1); + release(out_right); + } //Serial.print("."); } else if (new_left != NULL) { // the DMA didn't fill blocks, but we allocated blocks diff --git a/input_i2s2.h b/input_i2s2.h index 5830f4ac..34cbdbd0 100644 --- a/input_i2s2.h +++ b/input_i2s2.h @@ -32,6 +32,11 @@ #include "AudioStream.h" #include "DMAChannel.h" +#if !defined(I2S_RCSR_SR) // not always in the master header +#define I2S_RCSR_SR ((uint32_t)0x01000000) // Software Reset +#endif // !defined(I2S_RCSR_SR) + + class AudioInputI2S2 : public AudioStream { public: diff --git a/input_i2s_hex.cpp b/input_i2s_hex.cpp index 07e73551..d508a08e 100644 --- a/input_i2s_hex.cpp +++ b/input_i2s_hex.cpp @@ -50,6 +50,7 @@ void AudioInputI2SHex::begin(void) const int pinoffset = 0; // TODO: make this configurable... AudioOutputI2S::config_i2s(); + I2S1_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic I2S1_RCR3 = I2S_RCR3_RCE_3CH << pinoffset; switch (pinoffset) { case 0: @@ -195,8 +196,8 @@ void AudioInputI2SHex::update(void) } __disable_irq(); if (block_offset >= AUDIO_BLOCK_SAMPLES) { - // the DMA filled 4 blocks, so grab them and get the - // 4 new blocks to the DMA, as quickly as possible + // the DMA filled 6 blocks, so grab them and get the + // 6 new blocks to the DMA, as quickly as possible out1 = block_ch1; block_ch1 = new1; out2 = block_ch2; @@ -212,18 +213,40 @@ void AudioInputI2SHex::update(void) block_offset = 0; __enable_irq(); // then transmit the DMA's former blocks - transmit(out1, 0); - release(out1); - transmit(out2, 1); - release(out2); - transmit(out3, 2); - release(out3); - transmit(out4, 3); - release(out4); - transmit(out5, 4); - release(out5); - transmit(out6, 5); - release(out6); + if (NULL != out1) + { + transmit(out1, 0); + release(out1); + } + + if (NULL != out2) + { + transmit(out2, 1); + release(out2); + } + + if (NULL != out3) + { + transmit(out3, 2); + release(out3); + } + if (NULL != out4) + { + transmit(out4, 3); + release(out4); + } + + if (NULL != out5) + { + transmit(out5, 4); + release(out5); + } + + if (NULL != out6) + { + transmit(out6, 5); + release(out6); + } } else if (new1 != NULL) { // the DMA didn't fill blocks, but we allocated blocks if (block_ch1 == NULL) { diff --git a/input_i2s_hex.h b/input_i2s_hex.h index f3387b0b..49991354 100644 --- a/input_i2s_hex.h +++ b/input_i2s_hex.h @@ -31,6 +31,10 @@ #include "AudioStream.h" #include "DMAChannel.h" +#if !defined(I2S_RCSR_SR) // not always in the master header +#define I2S_RCSR_SR ((uint32_t)0x01000000) // Software Reset +#endif // !defined(I2S_RCSR_SR) + class AudioInputI2SHex : public AudioStream { public: diff --git a/input_i2s_oct.cpp b/input_i2s_oct.cpp index 5708cb7e..c79ce6a3 100644 --- a/input_i2s_oct.cpp +++ b/input_i2s_oct.cpp @@ -51,7 +51,9 @@ void AudioInputI2SOct::begin(void) dma.begin(true); // Allocate the DMA channel first AudioOutputI2S::config_i2s(); + I2S1_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic I2S1_RCR3 = I2S_RCR3_RCE_4CH; + CORE_PIN8_CONFIG = 3; CORE_PIN6_CONFIG = 3; CORE_PIN9_CONFIG = 3; @@ -203,7 +205,7 @@ void AudioInputI2SOct::update(void) } __disable_irq(); if (block_offset >= AUDIO_BLOCK_SAMPLES) { - // the DMA filled 4 blocks, so grab them and get the + // the DMA filled 8 blocks, so grab them and get the // 8 new blocks to the DMA, as quickly as possible out1 = block_ch1; block_ch1 = new1; @@ -224,22 +226,53 @@ void AudioInputI2SOct::update(void) block_offset = 0; __enable_irq(); // then transmit the DMA's former blocks - transmit(out1, 0); - release(out1); - transmit(out2, 1); - release(out2); - transmit(out3, 2); - release(out3); - transmit(out4, 3); - release(out4); - transmit(out5, 4); - release(out5); - transmit(out6, 5); - release(out6); - transmit(out7, 6); - release(out7); - transmit(out8, 7); - release(out8); + if (NULL != out1) + { + transmit(out1, 0); + release(out1); + } + + if (NULL != out2) + { + transmit(out2, 1); + release(out2); + } + + if (NULL != out3) + { + transmit(out3, 2); + release(out3); + } + if (NULL != out4) + { + transmit(out4, 3); + release(out4); + } + + if (NULL != out5) + { + transmit(out5, 4); + release(out5); + } + + if (NULL != out6) + { + transmit(out6, 5); + release(out6); + } + + if (NULL != out7) + { + transmit(out7, 6); + release(out7); + } + + if (NULL != out8) + { + transmit(out8, 7); + release(out8); + } + } else if (new1 != NULL) { // the DMA didn't fill blocks, but we allocated blocks if (block_ch1 == NULL) { diff --git a/input_i2s_oct.h b/input_i2s_oct.h index f07457c9..34860ac3 100644 --- a/input_i2s_oct.h +++ b/input_i2s_oct.h @@ -31,6 +31,10 @@ #include "AudioStream.h" #include "DMAChannel.h" +#if !defined(I2S_RCSR_SR) // not always in the master header +#define I2S_RCSR_SR ((uint32_t)0x01000000) // Software Reset +#endif // !defined(I2S_RCSR_SR) + class AudioInputI2SOct : public AudioStream { public: diff --git a/input_i2s_quad.cpp b/input_i2s_quad.cpp index 3539ed2c..7da50bee 100644 --- a/input_i2s_quad.cpp +++ b/input_i2s_quad.cpp @@ -48,7 +48,8 @@ void AudioInputI2SQuad::begin(void) dma.begin(true); // Allocate the DMA channel first #if defined(KINETISK) - // TODO: should we set & clear the I2S_RCSR_SR bit here? + I2S0_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic + AudioOutputI2SQuad::config_i2s(); CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 @@ -79,6 +80,8 @@ void AudioInputI2SQuad::begin(void) #elif defined(__IMXRT1062__) const int pinoffset = 0; // TODO: make this configurable... + I2S1_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic + AudioOutputI2S::config_i2s(); I2S1_RCR3 = I2S_RCR3_RCE_2CH << pinoffset; switch (pinoffset) { @@ -227,14 +230,29 @@ void AudioInputI2SQuad::update(void) block_offset = 0; __enable_irq(); // then transmit the DMA's former blocks - transmit(out1, 0); - release(out1); - transmit(out2, 1); - release(out2); - transmit(out3, 2); - release(out3); - transmit(out4, 3); - release(out4); + if (NULL != out1) + { + transmit(out1, 0); + release(out1); + } + + if (NULL != out2) + { + transmit(out2, 1); + release(out2); + } + + if (NULL != out3) + { + transmit(out3, 2); + release(out3); + } + if (NULL != out4) + { + transmit(out4, 3); + release(out4); + } + } else if (new1 != NULL) { // the DMA didn't fill blocks, but we allocated blocks if (block_ch1 == NULL) { diff --git a/input_i2s_quad.h b/input_i2s_quad.h index 3b2556bf..08a87aa7 100644 --- a/input_i2s_quad.h +++ b/input_i2s_quad.h @@ -31,6 +31,10 @@ #include "AudioStream.h" #include "DMAChannel.h" +#if !defined(I2S_RCSR_SR) // not always in the master header +#define I2S_RCSR_SR ((uint32_t)0x01000000) // Software Reset +#endif // !defined(I2S_RCSR_SR) + class AudioInputI2SQuad : public AudioStream { public: diff --git a/input_pdm.cpp b/input_pdm.cpp index e8a4381b..1b949f9f 100644 --- a/input_pdm.cpp +++ b/input_pdm.cpp @@ -128,6 +128,8 @@ void AudioInputPDM::begin() */ I2S1_RMR = 0; //I2S1_RCSR = (1<<25); //Reset + I2S1_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic + I2S1_RCR1 = I2S_RCR1_RFW(2); // 2 not 1 I2S1_RCR2 = I2S_RCR2_SYNC(rsync) | I2S_RCR2_BCP | (I2S_RCR2_BCD | I2S_RCR2_DIV((1)) | I2S_RCR2_MSEL(1)); // sync=0; rx is async; I2S1_RCR3 = I2S_RCR3_RCE; diff --git a/input_pdm.h b/input_pdm.h index 7e2c97ec..8a53bc5f 100644 --- a/input_pdm.h +++ b/input_pdm.h @@ -31,6 +31,11 @@ #include "AudioStream.h" #include "DMAChannel.h" +#if !defined(I2S_RCSR_SR) // not always in the master header +#define I2S_RCSR_SR ((uint32_t)0x01000000) // Software Reset +#endif // !defined(I2S_RCSR_SR) + + class AudioInputPDM : public AudioStream { public: diff --git a/input_pdm_i2s2.cpp b/input_pdm_i2s2.cpp index e23e15e9..bc038e5b 100644 --- a/input_pdm_i2s2.cpp +++ b/input_pdm_i2s2.cpp @@ -112,6 +112,8 @@ void AudioInputPDM2::begin(void) I2S2_TMR = 0; //I2S2_TCSR = (1<<25); //Reset + I2S2_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic + I2S2_TCR1 = I2S_TCR1_RFW(1); I2S2_TCR2 = I2S_TCR2_SYNC(tsync) | I2S_TCR2_BCP | (I2S_TCR2_BCD | I2S_TCR2_DIV((1)) | I2S_TCR2_MSEL(1)); // sync=0; tx is async; I2S2_TCR3 = I2S_TCR3_TCE; diff --git a/input_pdm_i2s2.h b/input_pdm_i2s2.h index bf3ab3d5..fd195bd3 100644 --- a/input_pdm_i2s2.h +++ b/input_pdm_i2s2.h @@ -31,6 +31,11 @@ #include "AudioStream.h" #include "DMAChannel.h" +#if !defined(I2S_RCSR_SR) // not always in the master header +#define I2S_RCSR_SR ((uint32_t)0x01000000) // Software Reset +#endif // !defined(I2S_RCSR_SR) + + class AudioInputPDM2 : public AudioStream { public: diff --git a/input_tdm.cpp b/input_tdm.cpp index dbbf98b8..22edd9d8 100644 --- a/input_tdm.cpp +++ b/input_tdm.cpp @@ -47,6 +47,8 @@ void AudioInputTDM::begin(void) // TODO: should we set & clear the I2S_RCSR_SR bit here? AudioOutputTDM::config_tdm(); #if defined(KINETISK) + I2S0_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic + CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 dma.TCD->SADDR = &I2S0_RDR0; dma.TCD->SOFF = 0; @@ -65,6 +67,8 @@ void AudioInputTDM::begin(void) I2S0_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE | I2S_RCSR_FRDE | I2S_RCSR_FR; I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE; // TX clock enable, because sync'd to TX #elif defined(__IMXRT1062__) + I2S1_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic + CORE_PIN8_CONFIG = 3; //RX_DATA0 IOMUXC_SAI1_RX_DATA0_SELECT_INPUT = 2; dma.TCD->SADDR = &I2S1_RDR0; diff --git a/input_tdm.h b/input_tdm.h index 9ce8f0c9..4c276021 100644 --- a/input_tdm.h +++ b/input_tdm.h @@ -33,6 +33,11 @@ #define AUDIO_TDM_BLOCKS 16 +#if !defined(I2S_RCSR_SR) // not always in the master header +#define I2S_RCSR_SR ((uint32_t)0x01000000) // Software Reset +#endif // !defined(I2S_RCSR_SR) + + class AudioInputTDM : public AudioStream { public: diff --git a/input_tdm2.cpp b/input_tdm2.cpp index e77b4a93..70291ed5 100644 --- a/input_tdm2.cpp +++ b/input_tdm2.cpp @@ -44,8 +44,8 @@ void AudioInputTDM2::begin(void) { dma.begin(true); // Allocate the DMA channel first - // TODO: should we set & clear the I2S_RCSR_SR bit here? AudioOutputTDM2::config_tdm(); + I2S2_RCSR |= I2S_RCSR_SR; // soft-reset the I2S receiver logic CORE_PIN5_CONFIG = 2; //2:RX_DATA0 IOMUXC_SAI2_RX_DATA0_SELECT_INPUT = 0; diff --git a/input_tdm2.h b/input_tdm2.h index 28f67790..770cae4e 100644 --- a/input_tdm2.h +++ b/input_tdm2.h @@ -34,6 +34,11 @@ #define AUDIO_TDM_BLOCKS 16 +#if !defined(I2S_RCSR_SR) // not always in the master header +#define I2S_RCSR_SR ((uint32_t)0x01000000) // Software Reset +#endif // !defined(I2S_RCSR_SR) + + class AudioInputTDM2 : public AudioStream { public: