Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    Sammy C21 support for 2 TMC2209 drivers with UART com

    Scheduled Pinned Locked Moved
    Hardware dev
    2
    44
    4.5k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Gixxerfastundefined
      Gixxerfast @Gixxerfast
      last edited by Gixxerfast

      @DC42 Might be of interest.
      I have now temporarily replaced the Sammy C21 with a Seeduino XIAO extending Klipper.

      It has no problem communicating via UART with the TMC2209 without any pullup resistor (and with the 20k pulldown intact).

      I'm going to look at the UART signal later. The Duet UART transmission without the pullup is shifted somehow. I can see that it's transmitted but it's sort of shifted so that the startbits comes last in the start byte instead of first. I'll add some pictures from the logic analyzer tomorrow.

      056c6503-33f5-45ca-b2ff-43e7bb9200f4-image.png

      22:00:07
      SG_RESULT: 00000000
      22:00:07
      PWM_AUTO: 000e0024 pwm_ofs_auto=36 pwm_grad_auto=14
      22:00:07
      PWM_SCALE: 0000001d pwm_scale_sum=29
      22:00:07
      PWMCONF: c80d0e24 pwm_ofs=36 pwm_grad=14 pwm_freq=1 pwm_autoscale=1 pwm_autograd=1 pwm_reg=8 pwm_lim=12
      22:00:07
      DRV_STATUS: c0190000 cs_actual=25 stealth=1 stst=1
      22:00:07
      CHOPCONF: 34030053 toff=3 hstrt=5 tbl=2 vsense=1 mres=4(16usteps) intpol=1 dedge=1
      22:00:07
      MSCURACT: 00f7000c cur_a=12 cur_b=247
      22:00:07
      MSCNT: 00000008 mscnt=8
      22:00:07
      TSTEP: 000fffff tstep=1048575
      22:00:07
      FACTORY_CONF: 0000000c fclktrim=12
      22:00:07
      IOIN: 21000041 enn=1 pdn_uart=1 version=0x21
      22:00:07
      OTP_READ: 0000000c otp_fclktrim=12
      22:00:07
      IFCNT: 00000008 ifcnt=8
      22:00:07
      GSTAT: 00000001 reset=1(Reset)
      22:00:07
      GCONF: 000001c0 pdn_disable=1 mstep_reg_select=1 multistep_filt=1
      22:00:07
      ========== Queried registers ==========
      22:00:07
      SGTHRS: 00000000
      22:00:07
      TPOWERDOWN: 00000014 tpowerdown=20
      22:00:07
      TPWMTHRS: 00000003 tpwmthrs=3
      22:00:07
      IHOLD_IRUN: 00081919 ihold=25 irun=25 iholddelay=8
      22:00:07
      SLAVECONF: 00000200 senddelay=2
      22:00:07
      ========== Write-only registers ==========
      22:00:07
      DUMP_TMC STEPPER=gear_stepper
      

      With Duet and Sammy C21 and no pullup on UART-line:
      Screenshot from 2022-02-16 17-50-41.png

      With Klipper and Seeeduino XIAO and no pullup:
      Screenshot from 2022-02-16 23-16-17.png

      Voron V2.4 (#1317) with Duet 3 Mini5+ Wifi and 1LC v1.1 Toolboard
      Voron V0.1 (#637) with Duet 3 Mini 5+ Wifi and 1LC v1.2 Toolboard
      Ender 3 Pro with BTT SKR-2 + RRF

      1 Reply Last reply Reply Quote 0
      • dc42undefined
        dc42 administrators
        last edited by dc42

        @gixxerfast I think the reason is that in the TMC22xx driver on the SAMC21 we disable the transmitter for a short while in function TmcDriverState::StartTransfer. My guess is that this sets the output to high impedance. You could probably rewrite it to just reset the receiver, if you also defer enabling the transmit DMA until the very end.

        Duet WiFi hardware designer and firmware engineer
        Please do not ask me for Duet support via PM or email, use the forum
        http://www.escher3d.com, https://miscsolutions.wordpress.com

        Gixxerfastundefined 2 Replies Last reply Reply Quote 0
        • Gixxerfastundefined
          Gixxerfast @dc42
          last edited by

          @dc42 Thanks (very appreciated as always), yes I've been looking at this for a while as I suspect it could "drop the line" for a short moment:

          #if TMC22xx_USES_SERCOM
          		sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);	// disable transmitter and receiver, reset receiver
          		while (sercom->USART.SYNCBUSY.bit.CTRLB) { }
          #else
          

          Not sure if it's exactly there but I was thinking of trying to alter it a bit. Not that I know what I'm doing but it's per usual 🙂

          Voron V2.4 (#1317) with Duet 3 Mini5+ Wifi and 1LC v1.1 Toolboard
          Voron V0.1 (#637) with Duet 3 Mini 5+ Wifi and 1LC v1.2 Toolboard
          Ender 3 Pro with BTT SKR-2 + RRF

          1 Reply Last reply Reply Quote 0
          • Gixxerfastundefined
            Gixxerfast @dc42
            last edited by Gixxerfast

            OK, so far so good! It's been stable for a while now so maybe I can trust it I don't totally trust it. I had to change in a few more places.

            @dc42 Well, that look promising 🙂

            So now (I really hope it lasts):

            Driver 0: pos 80000, 80.0 steps/mm,standstill, SG min 16, read errors 0, write errors 0, ifcnt 70, reads 13761, writes 1, timeouts 0, DMA errors 0, CC errors 0, steps req 0 done 0
            Driver 1: pos 574280, 574.3 steps/mm,standstill, SG min 16, read errors 0, write errors 0, ifcnt 68, reads 13762, writes 1, timeouts 0, DMA errors 0, CC errors 0, steps req 0 done 0
            
            $ git diff src/Movement/StepperDrivers/TMC22xx.cpp
            diff --git a/src/Movement/StepperDrivers/TMC22xx.cpp b/src/Movement/StepperDrivers/TMC22xx.cpp
            index 4b8a1acb..b301af8e 100644
            --- a/src/Movement/StepperDrivers/TMC22xx.cpp
            +++ b/src/Movement/StepperDrivers/TMC22xx.cpp
            @@ -1441,7 +1441,7 @@ void TmcDriverState::AbortTransfer() noexcept
             #if TMC22xx_USES_SERCOM
                    DmacManager::DisableChannel(DmacChanTmcTx);
                    DmacManager::DisableChannel(DmacChanTmcRx);
            -       sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);
            +       sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_RXEN/* | SERCOM_USART_CTRLB_TXEN*/);    //UER
                    while (sercom->USART.SYNCBUSY.bit.CTRLB) { }
             #else
                    uart->UART_IDR = UART_IDR_ENDRX;                                // disable end-of-receive interrupt
            @@ -1497,17 +1497,18 @@ inline void TmcDriverState::StartTransfer() noexcept
            
                            regnumBeingUpdated = regNum;
             #if TMC22xx_USES_SERCOM
            -               sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);        // disable transmitter and receiver, reset receiver
            +               sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_RXEN /*| SERCOM_USART_CTRLB_TXEN*/);    // disable /*transmitter <--- UER*/ and receiver, reset receiver
                            while (sercom->USART.SYNCBUSY.bit.CTRLB) { }
             #else
                            uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX;  // reset transmitter and receiver
             #endif
                            const uint8_t regNumber = (regNum < WriteSpecial) ? WriteRegNumbers[regNum] : specialWriteRegisterNumber;
            -               SetupDMASend(regNumber, writeRegisters[regNum]);                                                                        // set up the DMAC
            +               //SetupDMASend(regNumber, writeRegisters[regNum]);                                                                      // set up the DMAC <---UER
             #if TMC22xx_USES_SERCOM
                            dmaFinishedReason = DmaCallbackReason::none;
                            DmacManager::EnableCompletedInterrupt(DmacChanTmcRx);
            -               sercom->USART.CTRLB.reg |= (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);         // enable transmitter and receiver
            +               sercom->USART.CTRLB.reg |= (SERCOM_USART_CTRLB_RXEN /*| SERCOM_USART_CTRLB_TXEN*/);             // enable transmitter and receiver <--- UER
            +               SetupDMASend(regNumber, writeRegisters[regNum]);
             #else
                            uart->UART_IER = UART_IER_ENDRX;                                // enable end-of-transfer interrupt
                            uart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;    // enable transmitter and receiver
            @@ -1520,19 +1521,20 @@ inline void TmcDriverState::StartTransfer() noexcept
                            AtomicCriticalSectionLocker lock;
            
             #if TMC22xx_USES_SERCOM
            -               sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);        // disable transmitter and receiver, reset receiver
            +               sercom->USART.CTRLB.reg &= ~(SERCOM_USART_CTRLB_RXEN/* | SERCOM_USART_CTRLB_TXEN*/);    // disable transmitter and receiver, reset receiver
                            while (sercom->USART.SYNCBUSY.bit.CTRLB) { }
             #else
                            uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX;  // reset transmitter and receiver
             #endif
            
                            const uint8_t readRegNumber = (registerToRead < NumReadRegisters) ? ReadRegNumbers[registerToRead] : specialReadRegisterNumber;
            -               SetupDMARead(readRegNumber);                                                                                                            // set up the DMAC
            +               //SetupDMARead(readRegNumber);                                                                                                          // set up the DMAC
            
             #if TMC22xx_USES_SERCOM
                            dmaFinishedReason = DmaCallbackReason::none;
                            DmacManager::EnableCompletedInterrupt(DmacChanTmcRx);
            -               sercom->USART.CTRLB.reg |= (SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN);         // enable transmitter and receiver
            +               sercom->USART.CTRLB.reg |= (SERCOM_USART_CTRLB_RXEN/* | SERCOM_USART_CTRLB_TXEN*/);             // enable transmitter and receiver
            +               SetupDMARead(readRegNumber);
             #else
                            uart->UART_IER = UART_IER_ENDRX;                                // enable end-of-receive interrupt
                            uart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;    // enable transmitter and rec
            

            Voron V2.4 (#1317) with Duet 3 Mini5+ Wifi and 1LC v1.1 Toolboard
            Voron V0.1 (#637) with Duet 3 Mini 5+ Wifi and 1LC v1.2 Toolboard
            Ender 3 Pro with BTT SKR-2 + RRF

            1 Reply Last reply Reply Quote 0
            • Gixxerfastundefined Gixxerfast referenced this topic
            • Gixxerfastundefined Gixxerfast referenced this topic
            • Gixxerfastundefined Gixxerfast referenced this topic
            • First post
              Last post
            Unless otherwise noted, all forum content is licensed under CC-BY-SA