cancel
Showing results for 
Search instead for 
Did you mean: 

For STM32F407, what UART Mode to set for TMC2209 PDN_UART pin?

MSing.8
Associate III

I am trying to figure out what UART mode do i set in CubeMX configuration for my STM32F407VE in order to connect stepper motor driver TMC2209? Should it be Half-Duplex?

This question may fall on TMC2209 manufacturer. I searched the forums but I only see arduino based TMC libraries and know less about STM32 based libraries for TMC2209.

page 15 - https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2209_Datasheet_V103.pdf

9 REPLIES 9
Petr DAVID
ST Employee

Hello MSing.8,

yes the Single Wire (Half-duplex) mode seems as the best option, because you will not need to connect the RX and TX pins externally. After selecting this mode: 

  • the TX and RX lines are internally connected
  • the RX pin is no longer used
  • the TX pin is always released when no data is transmitted.  

Thus TX pin acts as a standard I/O in idle or in reception. It means that the I/O must be configured so that TX is configured as floating input (or output high open-drain) when not driven by the USART. Apart from this, the communications are similar to what is done in normal USART mode. The conflicts on the line must be managed by the software. Also you must take into account, that all transmitted data are also received by the RX input.

Edit:

Than you @Piranha​ ​ for clarifying, that the TMC2209 uses push pull configuration when transmitting. The single wire configuration as I described it would be good for communication between two devices with the same transmitting configuration as open-drain and in that case the series resistor would not be necessary. In this case I would go with configuration as you suggest it. With push-pull configuration, pull-up resistor and series resistor.

MSing.8
Associate III

Hello Petr,

Thank you for the clarification.

Few questions:

  1. "Tx is configured as floating input", so essentially should the GPIO_Init for Tx pin look like this below?

**************************************************

 /**USART1 GPIO Configuration

  PA9   ------> USART1_TX

  */

  GPIO_InitStruct.Pin = GPIO_PIN_9;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

  GPIO_InitStruct.Pull = GPIO_NOPULL;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

  GPIO_InitStruct.Alternate = GPIO_AF7_USART1;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

**************************************************

2.

I am trying to use this TMC2209 library for STM32F4. This library is arduino based but my toolset is STM32CubeIDE.

https://downloads.arduino.cc/libraries/github.com/janelia-arduino/TMC2209-8.0.5.zip

So in the TMC2209.cpp there are these functions. From where do I get HardwareSerial & SerialAddress (in terms of STM32CubeIDE perspective)?

*************************************************************

TMC2209::TMC2209()

{

 blocking_ = true;

 serial_ptr_ = nullptr;

 serial_baud_rate_ = 500000;

 serial_address_ = SERIAL_ADDRESS_0;

 cool_step_enabled_ = false;

}

void TMC2209::setup(HardwareSerial & serial,

 long serial_baud_rate,

 SerialAddress serial_address)

{

 blocking_ = false;

 serial_baud_rate_ = serial_baud_rate;

 setOperationModeToSerial(serial,serial_baud_rate,serial_address);

 setRegistersToDefaults();

 readAndStoreRegisters();

 minimizeMotorCurrent();

 disable();

 disableAutomaticCurrentScaling();

 disableAutomaticGradientAdaptation();

 if (not isSetupAndCommunicating())

 {

  blocking_ = true;

 }

}

*************************************************************

I believe the autogenerated code by STM32CubeIDE for UART should have some relation with the HardwareSerial & SerialAddress but I am unable to connect dots due to lack of experience.

If you can shed some light in this direction will be helpful in enabling me.

Regards.

PS: I understand that HardwareSerial is some library include in Arduino. Is there any equivalent of HardwareSerial in STM32CubeIDE from UART perspective.

Petr DAVID
ST Employee

Hello MSnig.8,

The configuration of the pin seems alright. I am not personally familiar with C++ or Arduino, but STM32 UART peripheral do not have any address defined, maybe it was meant the address of the TMC2209. I am not sayin it is impossible to make the library work with some changes, but i am not able to help. I would personally go with the approach to create the datagram structures to be sent and interpret by myself and use HAL or LL drivers for the work with the UART peripheral for sending and receiving messages. But it really is only a personal preference.

Good luck on your project and do not hesitate to ask further questions possibly as new topic.

LMilt.1
Associate

Hi,

I have same problem with communication by UART between STM32 and TMC2209. Did you find a fix of this problem? I am sending a datagram "39 08 00 00 00 80 00 05" to set GCONF pdn_disable register, and next i am sending " 48 00 00 05" to read register 0x00, but TMC2209 isn't responding.

MSing.8
Associate III

I was not successful either with UART. It was taking long time to debug so I just enabled STEP/DIR mode.

The main issue for me in UART was, I was unable to configure it in the code.

So if you can share how you configure UART in STMCudeIDE that would be great.

One thing I recall is, when you send(Tx) datagram, you have to configure the same pin for read right after that (essentially TMC2209 responds with a reply datagram). Please check the TMC2209 datasheet.

Hi

I am also looking for a library to use the TMC2209.

Have you found a solution? Or a example project for controlling the stepper motor by uart?

Best regards,

Raúl

Piranha
Chief II

@Petr DAVID​ , unfortunately the accepted answer (the first post) is not only incomplete, but also wrong and potentially (electrically) damaging.

The single wire UART interface on Trinamic drivers switches between input and output modes. When it is an output, it is a push-pull pin! They made it push-pull to be able to work at high baud rates. As it is not an open-drain, configuring an open-drain on the MCU side cannot save from a short connection. Therefore the 1k series resistor must always be present, even with a single driver! And, as the UART line is made safe with that resistor, there is no point in configuring the MCU pin as open-drain and degrading the line performance. In addition, for the line to not be floating during the Tx/Rx transition moments, it must be pulled high to the Rx idle state. A pull-up together with a series resistor will create a voltage divider for a motor driver low level output, but, compared to the pull-up resistance, the 1k resistor value is low enough to not cause problems with signal level.

Therefore the 1k series resistor is mandatory and the correct pin configuration is: alternate function, push-pull, low speed, pull-up. And this configuration doesn't need to be changed at runtime.

Take a note that setting USART_CR3_HDSEL sets the mode to half-duplex communication on Tx pin with Rx pin released, but combining it with USART_CR2_SWAP makes a complete swap - Rx pin becomes a half-duplex communication pin and Tx pin is released.

A related topic:

https://community.st.com/s/question/0D53W00001rsnW3SAI/uart-to-interface-with-tmc2209eval-board-problems

The evaluation board has a 1k resistor already and the BOB from TRINAMIC also.

veysiadn
Associate II

I was also struggling with the UART communication with TMC2209, in my case transmit was always working fine but receive wasn't. I solved my issue by enabling halfduplex transmitter (HAL_HalfDuplex_EnableTransmitter) before sending and enabling halfduplex receiver (HAL_HalfDuplex_EnableReceiver) before receiving. An example driver code is available on my github page (https://github.com/veysiadn/tmc_2209), the other parts of the code is modified from TMC2209 arduino library (https://github.com/janelia-arduino/TMC2209).

Good luck,

Veysi