Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 34

Thread: Using TDA1543A with Teensy 4.0

  1. #1
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9

    Using TDA1543A with Teensy 4.0

    Hello!
    I am trying to port Pazi's original TDA1543A code (https://forum.pjrc.com/threads/29284...314#post141314) to work with my Teensy 4.0. So far, I have the CLK and FS signals working, but I haven't been so lucky with getting the DATA line to give me any output. I'm pretty new to low level coding like this, and this is what I came up with by looking at the datasheet (the excessive comments are me trying to understand the code). Am I missing anything? Are there obvious mistakes?

    output_tda.h:
    Code:
    /* Audio Library for Teensy 3.X
     * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
     */
    
    #ifndef output_tda_h_
    #define output_tda_h_
    
    #include "Arduino.h"
    #include "AudioStream.h"
    #include "DMAChannel.h"
    
    class AudioOutputTDA : public AudioStream
    {
    public:
        AudioOutputTDA(void) : AudioStream(2, inputQueueArray) { begin(); }
        virtual void update(void);
        void begin(void);
    protected:
        static void configureI2S(void);
        static audio_block_t *block_left_1st;
        static audio_block_t *block_right_1st;
        static bool update_responsibility;
        static DMAChannel dma;
        static void isr(void);
    private:
        static audio_block_t *block_left_2nd;
        static audio_block_t *block_right_2nd;
        static uint16_t block_left_offset;
        static uint16_t block_right_offset;
        audio_block_t *inputQueueArray[2];
    
        static void configureDMA();
        static void receiveAudioBlock(audio_block_t*& index,
                                      uint16_t& blockOffset,
                                      audio_block_t*& block_1st,
                                      audio_block_t*& block_2nd);
        static uint32_t scaleInputTo32Bit(uint16_t input);
        static void copyAndScaleInputToOutput(uint32_t*& dest,
                                              uint16_t& blockOffset,
                                              audio_block_t*& block_1st,
                                              audio_block_t*& block_2nd);
        static uint32_t* getDestination();
    };
    
    #endif
    output_tda.cpp:
    Code:
    /* Audio Library for Teensy 3.X
     *
     * TDA1543A DAC interface
     *
     * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
     * Original Teensy 3.X version by user Pazi
     *    (https://forum.pjrc.com/threads/29284-Dual-channel-16bit-dac-PT8211/page5?p=141314#post141314)
     *
     * Adapted for Teensy 4.0 by DaniŽl Kamp, with help from Wouter Ensink
     *
     */
    
    #include "output_tda.h"
    #include "utility/imxrt_hw.h"
    
    audio_block_t * AudioOutputTDA::block_left_1st = NULL;
    audio_block_t * AudioOutputTDA::block_right_1st = NULL;
    audio_block_t * AudioOutputTDA::block_left_2nd = NULL;
    audio_block_t * AudioOutputTDA::block_right_2nd = NULL;
    
    uint16_t  AudioOutputTDA::block_left_offset = 0;
    uint16_t  AudioOutputTDA::block_right_offset = 0;
    
    bool AudioOutputTDA::update_responsibility = false;
    
    DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES * 2];
    
    DMAChannel AudioOutputTDA::dma(false);
    
    // ==============================================
    //  Do setup things
    // ==============================================
    void AudioOutputTDA::begin(void)
    {
      // Allocate memory and init DMAChannel
      memset(i2s_tx_buffer, 0, sizeof(i2s_tx_buffer));
      dma.begin(true);
    
      block_left_1st = NULL;
      block_right_1st = NULL;
    
      // Do protocol configuration
      configureI2S_2();
    
      // Config pin 7 for use with SAI
      CORE_PIN7_CONFIG  = 3;  //1:TX_DATA0
    
      // Flush cache
      arm_dcache_flush_delete(i2s_tx_buffer, sizeof(i2s_tx_buffer));
      configureDMA();
    
      // Set enable bits for I2S transmitter and receiver
      I2S1_RCSR |= I2S_RCSR_RE;
      I2S1_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE;
    
      update_responsibility = update_setup();
    
      // Attach isr() function to DMA interrupt
      dma.attachInterrupt(isr);
    }
    
    void AudioOutputTDA::configureDMA() {
      // Set DMA source address
      dma.TCD->SADDR = i2s_tx_buffer;
      // Set DMA source offset
      dma.TCD->SOFF = 4;
      // Set DMA attribute bits
      dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(2) | DMA_TCD_ATTR_DSIZE(2);
      // Set DMA's number of bytes to transfer per request
      dma.TCD->NBYTES_MLNO = 4;
      // Set DMA source last address
      dma.TCD->SLAST = -sizeof(i2s_tx_buffer);
      // Set DMA destination offset
      dma.TCD->DOFF = 0;
      // Set DMA current major iterator count [6.6.5.28.4, page 166]
      dma.TCD->CITER_ELINKNO = sizeof(i2s_tx_buffer) / 4;
      // Set address for error handling? AFAIK not applicable right now, might look into this later
      dma.TCD->DLASTSGA = 0;
      // Set DMA beginning major iterator count [6.6.5.32, page 171]
      dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 4;
      // Set DMA CSR config bits
      dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
      // Set DMA destination address
      dma.TCD->DADDR = (void *)((uint32_t)&I2S1_TDR0);
      // Link DMA to SAI1 hardware event
      dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI1_TX);
      // Enable the DMA
      dma.enable();
    }
    void AudioOutputTDA::configureI2S(void) {
      CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON);
    
      // TODO: understand what this does
      //PLL:
      int fs = AUDIO_SAMPLE_RATE_EXACT;
      // PLL between 27*24 = 648MHz und 54*24=1296MHz
      int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
      int n2 = 1 + (24000000 * 27) / (fs * 256 * n1);
    
      double C = ((double)fs * 256 * n1 * n2) / 24000000;
      int c0 = C;
      int c2 = 10000;
      int c1 = C * c2 - (c0 * c2);
      set_audioClock(c0, c1, c2);
    
      // Clear SAI1_CLK register locations
      CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK))
                   | CCM_CSCMR1_SAI1_CLK_SEL(2); // (0,1,2): PLL3PFD0, PLL5, PLL4
      CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
                   | CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
                   | CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
    
      // Select MCLK
      IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 & ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK))
                        | (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0));
      // TODO: end of confusion
    
      // Don't continue setup sequence if I2S1_TCSR_TE (Transmit Enable) is already set
      if (I2S1_TCSR & I2S_TCSR_TE) return;
    
      // Configure BCK and CS pins
      CORE_PIN21_CONFIG = 3;  //1:RX_BCLK
      CORE_PIN20_CONFIG = 3;  //1:RX_SYNC
    
      // ==========================================================
      // Configure the I2S register
      // Datasheet: page 1987 onwards
      // ==========================================================
    
      // Setup transmitter
      constexpr int bitwidth = 31;
      I2S1_TMR = 0;
      I2S1_TCR1 = I2S_TCR1_RFW(0);
      I2S1_TCR2 = I2S_TCR2_SYNC(0) | I2S_TCR2_BCP | I2S_TCR2_MSEL(1) | I2S_TCR2_BCD | I2S_TCR2_DIV(0);
      I2S1_TCR3 = I2S_TCR3_TCE;
      I2S1_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(bitwidth) | I2S_TCR4_MF | I2S_TCR4_FSE | I2S_TCR4_FSP | I2S_TCR4_FSD;
      I2S1_TCR5 = I2S_TCR5_WNW(bitwidth) | I2S_TCR5_W0W(bitwidth) | I2S_TCR5_FBT(bitwidth);
    
      // Setup receiver (unnecessary afaik, but the example did it too)
      I2S1_RMR = 0;
      I2S1_RCR1 = I2S_RCR1_RFW(0);
      I2S1_RCR2 = I2S_RCR2_SYNC(1) | I2S_RCR2_BCP | I2S_RCR2_MSEL(1) | I2S_TCR2_BCD | I2S_TCR2_DIV(0);
      I2S1_RCR3 = I2S_RCR3_RCE;
      I2S1_RCR4 = I2S_RCR4_FRSZ(1) | I2S_RCR4_SYWD(bitwidth) | I2S_RCR4_MF | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD;
      I2S1_RCR5 = I2S_RCR5_WNW(bitwidth) | I2S_RCR5_W0W(bitwidth) | I2S_RCR5_FBT(bitwidth);
    }
    
    // ==============================================
    //  Handle incoming audio blocks
    // ==============================================
    void AudioOutputTDA::update(void) {
      // Receive left channel
      auto* block_left = receiveReadOnly(0);
      receiveAudioBlock(block_left, block_left_offset, block_left_1st, block_left_2nd);
    
      // Receive right channel
      auto* block_right = receiveReadOnly(1);
      receiveAudioBlock(block_right, block_right_offset, block_right_1st, block_right_2nd);
    }
    
    void AudioOutputTDA::receiveAudioBlock(audio_block_t*& block, uint16_t& blockOffset, audio_block_t*& block_1st, audio_block_t*& block_2nd) {
      if (block) {
        // Deny interrupt requests while buffer is being moved
        __disable_irq();
        // Move the block into whichever buffer is empty...
        if (block_1st == NULL) {
          block_1st = block;
          blockOffset = 0;
          __enable_irq();
        } else if (block_2nd == NULL) {
          block_2nd = block;
          __enable_irq();
        }
        // ...or shift the buffers and fill the last one
        else {
          audio_block_t *tmp = block_1st;
          block_1st = block_2nd;
          block_2nd = block;
          blockOffset = 0;
          __enable_irq();
          release(tmp);
        }
      }
    }
    
    // ==============================================
    //  Handle outgoing audio blocks
    // ==============================================
    void AudioOutputTDA::isr(void) {
      dma.clearInterrupt();
      auto* dest = getDestination();
    
      // Copy and scale left channel
      copyAndScaleInputToOutput(dest, block_left_offset, block_left_1st, block_left_2nd);
      // Move back to beginning(+1) of buffer
      dest -= AUDIO_BLOCK_SAMPLES - 1;
      // Copy and scale right channel
      copyAndScaleInputToOutput(dest, block_right_offset, block_right_1st, block_right_2nd);
    //  Serial.println(*dest);
    }
    
    uint32_t* AudioOutputTDA::getDestination()
    {
      const auto saddr = (uint32_t)(dma.TCD->SADDR);
    
      // Fill the part of the buffer that the DMA isn't currently transmitting
      if (saddr < (uint32_t)i2s_tx_buffer + sizeof(i2s_tx_buffer) / 2) {
        auto* temp = (uint32_t *)&i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
    
        // TODO: figure out what this does (something IRQ?)
        if (AudioOutputTDA::update_responsibility)
          AudioStream::update_all();
        return temp;
      } else {
        return (uint32_t *)i2s_tx_buffer;
      }
    }
    uint32_t AudioOutputTDA::scaleInputTo32Bit(uint16_t input)
    {
      // 0x8000 == 0b1000'0000'0000'0000
      // AND-ing with 0x8000 gives us the unsigned 16-bit version of the input
    
      // 0xff000000 == 1111'1111'0000'0000'0000'0000'0000'0000
      // 32-bit input == 0000'0000'bbbb'bbbb'bbbb'bbbb'0000'0000
      // OR-ing these together gives us the correct format for the TDA1543A chip
    
      return ((uint32_t)input << 9) | ((input & 0x8000) != 0 ? 0xff000000 : 0);
    }
    void AudioOutputTDA::copyAndScaleInputToOutput(uint32_t*& dest,
                                                   uint16_t& blockOffset,
                                                   audio_block_t*& block_1st,
                                                   audio_block_t*& block_2nd)
    {
      if (block_1st) {
        auto offset = blockOffset;
        auto* src = &block_1st->data[offset];
    
        for (int i = 0; i < AUDIO_BLOCK_SAMPLES/2; ++i) {
          *dest = scaleInputTo32Bit(*src++);
          dest += 2;
        }
    
        offset += AUDIO_BLOCK_SAMPLES/2;
        if (offset < AUDIO_BLOCK_SAMPLES) {
          blockOffset = offset;
        } else {
          blockOffset = 0;
          AudioStream::release(block_1st);
          block_1st = block_2nd;
          block_2nd = NULL;
        }
      } else {
        for (int i = 0; i < AUDIO_BLOCK_SAMPLES/2; ++i) {
          *dest = 0;
          dest += 2;
        }
      }
    }
    Any help would be very much appreciated!
    Last edited by layetri; 05-04-2021 at 04:04 PM. Reason: Added link to original thread

  2. #2
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9
    By means of extensive serial printing, I've figured out that the most likely problem is with the I2S setup. Could someone take a look at the configuration and tell me whether there are any mistakes? I've tried to do this myself, but I don't think I'm advanced enough to fully understand the IMXRT datasheet.

  3. #3
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    625
    Is there a reason that you don't use the supplied Teensy Audio Library? The TDA1543A is supported according to this page [top row].

    Regards,
    Paul

  4. #4
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9
    From what I've been able to find, the AudioOutputPT8211 class that is supplied delivers 16 bits per CS cycle, while the A flavor of the TDA1543 expects 24/32 bits (if I understand correctly). Using the original gives me this:
    Click image for larger version. 

Name:	tda1543_at_its_finest.png 
Views:	24 
Size:	43.8 KB 
ID:	24918
    (applying the modifications that are commented out in the original gives me the same output).
    I figured it would have something to do with the fact that this Japanese format expects a higher bit count, and since the OP of the original thread got it to work, I thought it'd be worthwhile to try and port their code to run on my T4.

  5. #5
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    625
    I'm not sure the A flavor of THD1543 requires/expects 24/32 bits. It's a 16bit DAC after all. The attached datasheet doesn't mention it as far as I can tell.
    Perhaps you should give this code a quick try:
    Code:
    // TDA1543A     Teensy 4.x
    // VDD          Vin
    // GND          GND
    // WS           20            LRCK 176.4 KHz
    // DATA          7
    // BCK          21            5.6469 MHz = 32.LRCK
    
    #include <Audio.h>
    
    AudioSynthWaveformSine   sine1;
    AudioOutputPT8211        pt8211_1;
    AudioConnection          patchCord1(sine1, 0, pt8211_1, 0);
    AudioConnection          patchCord2(sine1, 0, pt8211_1, 1);
    
    void setup(){
      AudioMemory(1);
      sine1.frequency(1000);
      sine1.amplitude(0.50);  // -6dB
    }
    
    void loop(){
    }
    Regards,
    Paul

    Philips TDA1543A.pdf

  6. #6
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9
    Am I mistaken if I read page 9 of the datasheet as the chip expecting 8 bits of MSB before the actual data starts? And thus requiring at least 24 CLK cycles to receive a full 16 bit message? This was also the issue in the original thread, and OP solved it by modifying the existing header to work with 32-bit signals instead, where both the MSB and LSB filled 8 additional bits.
    The attached scope screenshot from my last post was the result of code similar to what you posted. This is (as far as my understanding goes) a result of the chip only interpreting the last 8 of the 16 bits, due to it expecting the first 8 to only be MSB.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,834
    Quote Originally Posted by layetri View Post
    Am I mistaken if I read page 9 of the datasheet as the chip expecting 8 bits of MSB before the actual data starts? And thus requiring at least 24 CLK cycles to receive a full 16 bit message?
    It does look that way in figure 5, where "MSB" is shown as constant for several clock cycles. But figure 4 seems to show each clock gets a new data bit. Probably some experimentation needed to know how this DAC chip really works.

  8. #8
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9
    After some tinkering, I've noticed that when setting a very small amplitude (0.001 or lower), the output signal is correct. This leads me to assume that the chip indeed only considers the last 8 bits in the current setup (the current setup being the one that PaulS proposed earlier).
    Last edited by layetri; 05-27-2021 at 12:42 PM.

  9. #9
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,058
    I remember we had used and tested this chip when filldling withh code for the pt8211.
    Unfortunateley it is so long ago, and I don't remember any details. I searched the chip in my drawers but could not find it anymore..
    Sorry, I'm getting older ( But I bought an electric guitar some weeks ago and try to practice every day *g*, so sorry, that I'm not that often here anymore - I whish I had begun some decades earlier..)
    Well, I openend the PT821 source, and found this:

    Code:
    //    I2S0_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(15) | I2S_TCR4_MF | I2S_TCR4_FSE | I2S_TCR4_FSP | I2S_TCR4_FSD; //TDA1543
        I2S0_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(15) | I2S_TCR4_MF /*| I2S_TCR4_FSE*/ | I2S_TCR4_FSP | I2S_TCR4_FSD; //PT8211
    Not sure if it was for the A Version or not.. but maybe it can help a little bit. Just open the PT8211 code and take a look.. - as first step, ignore the oversampling stuff.

  10. #10
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9
    I tried this fix already and got exactly the same outcome as with the original PT8211 code.

    As to my own attempt at porting the original thread's driver: when looking at the I2S and DMA configuration in the code, are there any obvious problems with my code that could cause this behavior? (BCK and WS working, DATA line empty)
    Click image for larger version. 

Name:	003.png 
Views:	47 
Size:	48.1 KB 
ID:	24929

  11. #11
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9
    I'm most worried about this part of the code. Am I doing something wrong here? (I think the most obvious culprit would be a mistake in the transmitter setup)
    Code:
      CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON);
    
      // TODO: understand what this does
      //PLL:
      int fs = AUDIO_SAMPLE_RATE_EXACT;
      // PLL between 27*24 = 648MHz und 54*24=1296MHz
      int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
      int n2 = 1 + (24000000 * 27) / (fs * 256 * n1);
    
      double C = ((double)fs * 256 * n1 * n2) / 24000000;
      int c0 = C;
      int c2 = 10000;
      int c1 = C * c2 - (c0 * c2);
      set_audioClock(c0, c1, c2);
    
      // Clear SAI1_CLK register locations
      CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK))
                   | CCM_CSCMR1_SAI1_CLK_SEL(2); // (0,1,2): PLL3PFD0, PLL5, PLL4
      CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
                   | CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
                   | CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f
    
      // Select MCLK
      IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 & ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK))
                        | (IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0));
      // TODO: end of confusion
    
      // Don't continue setup sequence if I2S1_TCSR_TE (Transmit Enable) is already set
      if (I2S1_TCSR & I2S_TCSR_TE) return;
    
      // Configure BCK and CS pins
      CORE_PIN21_CONFIG = 3;  //1:RX_BCLK
      CORE_PIN20_CONFIG = 3;  //1:RX_SYNC
    
      // ==========================================================
      // Configure the I2S register
      // Datasheet: page 1987 onwards
      // ==========================================================
    
      // Setup transmitter
      constexpr int bitwidth = 31;
      I2S1_TMR = 0;
      I2S1_TCR1 = I2S_TCR1_RFW(0);
      I2S1_TCR2 = I2S_TCR2_SYNC(0) | I2S_TCR2_BCP | I2S_TCR2_MSEL(1) | I2S_TCR2_BCD | I2S_TCR2_DIV(0);
      I2S1_TCR3 = I2S_TCR3_TCE;
      I2S1_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(bitwidth) | I2S_TCR4_MF | I2S_TCR4_FSE | I2S_TCR4_FSP | I2S_TCR4_FSD;
      I2S1_TCR5 = I2S_TCR5_WNW(bitwidth) | I2S_TCR5_W0W(bitwidth) | I2S_TCR5_FBT(bitwidth);
    
      // Setup receiver (unnecessary afaik, but the example did it too)
      I2S1_RMR = 0;
      I2S1_RCR1 = I2S_RCR1_RFW(0);
      I2S1_RCR2 = I2S_RCR2_SYNC(1) | I2S_RCR2_BCP | I2S_RCR2_MSEL(1) | I2S_TCR2_BCD | I2S_TCR2_DIV(0);
      I2S1_RCR3 = I2S_RCR3_RCE;
      I2S1_RCR4 = I2S_RCR4_FRSZ(1) | I2S_RCR4_SYWD(bitwidth) | I2S_RCR4_MF | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD;
      I2S1_RCR5 = I2S_RCR5_WNW(bitwidth) | I2S_RCR5_W0W(bitwidth) | I2S_RCR5_FBT(bitwidth);

  12. #12
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    625
    Like Frank B, I vaguely remember that I have been playing with the TDA1543A as well.
    But I also could not find the chips in my drawers anymore...
    Since I have a working setup with the TDA1543 non-A version as pictured below [on a T3.2], I just ordered 2pcs TDA1543A here.

    Click image for larger version. 

Name:	TDA1543 setup.jpg 
Views:	26 
Size:	116.3 KB 
ID:	25024

    With a bit of luck, they will arrive within a week and I can start testing on a Teensy 3.2 & 4.0.

    Regards,
    Paul

  13. #13
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    625
    Well, finally received the TDA1543A's today.
    Replaced the TDA1543 from the setup pictured above with a fresh TDA1543A and uploaded a simple sketch that works with a PT8211 [I verified it]:
    Code:
    // TDA1543A       Teensy 3.2
    // 8 Vdd          5V          10uF + 100nF to GND
    // 4 GND          GND
    // 2 WS           23          LRCK 176.4 KHz
    // 3 DATA         22
    // 1 BCK          9           5.6469 MHz = 32.LRCK
    //
    // 7 Vref                     reference voltage, 1K to GND
    // 6 AOL                      left current output, 1K to GND
    // 8 AOR                      right current output, 1K to GND
    
    #include <Audio.h>
    
    AudioSynthWaveformSine   sine1;
    AudioOutputPT8211        pt8211_1;
    AudioConnection          patchCord1(sine1, 0, pt8211_1, 0);
    AudioConnection          patchCord2(sine1, 0, pt8211_1, 1);
    
    void setup(){
      AudioMemory(1);
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, HIGH);
    
      sine1.frequency(1000);
      sine1.amplitude(1.0);
    }
    
    void loop(){
    }
    Unfortunately no sine output from the TDA1543A but the same garbage as in Layetri's message #4 above.
    So the japanese format that works for the PT8211 does not work for the TDA1543A. The TDA1543A should be able to handle the 176.4 KHz samplerate.
    I also tried Frank's suggestion as in his message #9 but without success.

    @Frank: since I received 2pcs TDA1543A, I could send one piece to you for investigation [if you want to besides your guitar endeavours].

    Regards,
    Paul

  14. #14
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,058
    Sure, with pleasure.
    It's very unlikely that I'll be anywhere near as good as your compatriot Van Halen. Besides, my fingers hurt a little when I practice too much. So I will find time for the chip





    Oh my.. It will be 30 years before I even come close.
    But then I'll look at the grass from below.

  15. #15
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    625
    Eddie Van Halen's Eruption is quite a target
    Thanks, I will send you an email for your postal address.

    Gruesse,
    Paul

  16. #16
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,058
    Quote Originally Posted by PaulS View Post
    Eddie Van Halen's Eruption is quite a target
    Indeed, but hey I can play "Happy "Birthday".
    No.. no chance.. 30 yrs are not enough

    Eddie, rest in peace.

  17. #17
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9
    @PaulS have you tried the solution that the other thread had? I canít test this myself as I donít own a T3x. If that code works, the problem must be somewhere with my low-level coding.

  18. #18
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    625
    You mean Pazi's code? No, I did not try it. I believe Pazi's when he says that it works.
    I would not be surprised that the DMA engine and specific registers are different between a Teensy 3.x and a Teensy 4.x since the processors are quite different.

    Paul

  19. #19
    Junior Member
    Join Date
    May 2021
    Location
    Netherlands
    Posts
    9
    This is what Iíve been trying to address with my code from my first post, and itís exactly where I suspect the problem to be. Itíd be great if someone who knows more about this specific hardware could take a look at the setup of the DMA and registers to find possible mistakes.

  20. #20
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,058
    Quote Originally Posted by PaulS View Post
    @Frank: since I received 2pcs TDA1543A, I could send one piece to you for investigation [if you want to besides your guitar endeavours].
    Got your chip today. Thank you, Paul!
    Will give it a try tonight. After dinner.
    To do this I need to set up my scope again, find a breadbord and find cables.... The chip -output is also a current source like the TDA1543, right? I'm not connecting an op-amp to it. Which resistor should I use? (I think you have already done this, and I can save myself thinking about it

  21. #21
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,190
    The resistor needs to be small enough to prevent the output straying from the compliance range, which is typically less than a diode drop.

  22. #22
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    625
    Quote Originally Posted by Frank B View Post
    Which resistor should I use?
    Code:
    // TDA1543A       Teensy 3.2
    // 8 Vdd          5V          10uF + 100nF to GND
    // 4 GND          GND
    // 2 WS           23          LRCK 176.4 KHz
    // 3 DATA         22
    // 1 BCK          9           5.6469 MHz = 32.LRCK
    //
    // 7 Vref                     reference voltage, 1K to GND
    // 6 AOL                      left current output, 1K to GND
    // 8 AOR                      right current output, 1K to GND
    1K will do to give a decent signal on your scope.

    No hurries...

    Paul

  23. #23
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,058
    Quote Originally Posted by PaulS View Post
    [CODE]

    No hurries...
    Nope
    I have no beer anymore. Ich gehe gleich mal zur Tankstelle..

    I'm outputing a 1 Hz sine. The Scope shows a left or right justified sawtooth swapping every 1/2 second. Not too bad...
    Will try more when I'm back.

  24. #24
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,058
    Quote Originally Posted by Frank B View Post
    The Scope shows a left or right justified sawtooth swapping every 1/2 second. Not too bad...
    Sometimes i wish i'd bought a 4 channel scope..
    As far I can tell, the format is OK and looks like the one from the datasheet. This leads to the "sawtooth" however.
    Tried playing with the i2s format-bts with no effort so far.
    Perhaps we indeed have to switch to 24 or 32 bit transfers.. At the weekend, perhaps..

  25. #25
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    9,058
    Just modfied the code by PAZI for a T4.
    Code is attached.

    On my Scope, it looks like a sine (just 1k between vref and out).

    Note, i see no difference between
    Code:
    *dest = ((uint32_t)*src << 9) /*| ((*src & 0x8000) != 0 ? 0xff000000 : 0)*/;
    and
    Code:
    *dest = ((uint32_t)*src << 9) | ((*src & 0x8000) != 0 ? 0xff000000 : 0);
    Perhaps you want to investigate this.
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •