Skip to main content
Explorer II
October 13, 2022
Solved

UART to interface with TMC2209-Eval Board problems

  • October 13, 2022
  • 10 replies
  • 16675 views

Hi

I have to connect an STM34 Nucleo board to a TMC2209. I have to setup a single wire UART. Only TX is connected with the TMC board.

I transmitted a datagram and when I try to receive the response I get back the initial data I have e sent.

Does anybody know what could be happening?

does anyone has experience controlling a stepper motor with TRINAMIC TMC2209?

Please, I need help. I am in a bit of a hurry.

Best regards, Raúl

    This topic has been closed for replies.
    Best answer by Piranha

    This post is just wrong in almost everything and should not be selected as an answer!

    > "highest byte transmitted first" is WRONG ! Ignore !

    > data bytes 3, 2, 1, 0 (high to low byte) is BS too. I have no idea why this was put in there.

    > The 32 bit data is just sent LSByte first and not as they incorrectly suggest 'MSbyte first'.

    No, the byte order is indeed big-endian (highest byte first) like written in datasheet. Ironically you even disprove yourself. The default value for CHOPCONF register is 0x10000053, which you are setting in your example with a sequence:

    0x05, 0x00, 0xEC, 0x10,0x00,0x00,0x53, 0x81

    Where the data obviously is in a big-endian order. And your CRC is also wrong. The correct CRC for this sequence is 0x9C.

    > You can use their example C source code to calulate it for each 7 byte datagram but they fail to advise that you also need a dummy 0x00 byte on the end to make it 8 bytes total.

    This is the only thing that is almost correct in that post. The datasheet code example indeed takes N bytes, calculates the CRC for the first N-1 bytes and inserts the CRC in the last byte. But before the call that last byte can be of any value because it is initialized to 0 in that example code anyway.

    10 replies

    Graduate II
    October 14, 2022

    >>Please, I need help. I am in a bit of a hurry

    It's the internet, nobody cares.

    Lead with details, code and wiring. Links to datasheets.

    Assuming STM32G4xx something from prior posts.

    Any code examples for any other MCU you've found in two weeks?

    The TMC2209 is wired to the STM32G4 how, using what pins, which UART?

    Single wire apt to see what you send, need to config the pins suitably, and wait for response.

    Can use a two pin mode with a resistor. That way the idle TX just pulls the RX high, but doesn't block response.

    Should wait for UART TC, and then await response.

    IC probably going to ignore messages with bad CRC.

    https://www.trinamic.com/fileadmin/assets/Products/ICs_Documents/TMC2209_datasheet_rev1.08.pdf

    RPGAuthor
    Explorer II
    October 14, 2022

    Hi Tesla

    You are right, we have STM32G4xx on our project but I am using a NUCLEO-L496ZG to try to make the first integration.

        UM2179 STM32 Nucleo-144 boards (MB1312)  

    I have to connect with UART with the TMC2209-EVAL driver board.

     TMC2209 Datasheet 

    This is a simplified diagram since the evaluation board is already adding that resistor.

    0693W00000Uo44RQAR.png 

    This is how I have connected the boards:

    0693W00000Uo4D4QAJ.png 

    Regarding the CRC I have used the CRC functions they use in the full evaluation kit that you can find here: https://github.com/trinamic/TMC-EvalSystem/releases/tag/3.08.24, the CRC they use in the TMC2209 datasheet of the driver (see above link) and event the CRC from the nucleo board but still nothing.

    There source code is attached to the post.

    I have been through lots of code. I haven't seen any for this eval board and STM32. I have seen a lot of code for Arduino. The code from the evaluation kit helped me to understand how the datagrams should be sent together with the TMC driver datasheet. But I have found some discrepancies between the documentation and the Arduino and the evaluation board code... I have tried all sort of configurations for days.

    The current source code I have uploaded is not receiving anything anymore.

    Thanks in advance for taking your time. And please, let me know that else I could provide in case you need it.

    Best regards.

    Graduate II
    October 14, 2022

    The UART_TX pin on the header needs to go to the STM32 USARTx_TX pin, RX to RX

    Currently I think you're driving a High push-pull signal directly into their output.

    MS1/MS2 not connected, have internal pull-down, will be SLAVEADDR = 0

    I would probably use a polled method initially where the loop processes input and output together at a register level. Watching for framing or other errors on the receiver,and resyncing the input buffer pointer once the last transmitted byte signals TC, and discard the echo back.

    RPGAuthor
    Explorer II
    October 14, 2022

    I forgot to set back correctly the length of the transmission on this line:

    >  HAL_UART_Transmit_IT(&huart3, (uint8_t*)tx_buffer,4);

    It should be:

      HAL_UART_Transmit_IT(&huart3, (uint8_t*)tx_buffer,sizeof(tx_buffer));

    Sorry I have been coding late at night and forgot to replace that line after a test.

    RPGAuthor
    Explorer II
    October 14, 2022

    I have used protocol tool with my AD2 and the data seems to be transmitted but nothing is back from TMC.

    0693W00000Uo50uQAB.png

    RPGAuthor
    Explorer II
    October 14, 2022

    I have also tried including or excluding the last byte of the datagram, since in some examples I have seem they sometimes include it sometimes not. But nothing...

      tx_buffer[7] = tmc_CRC8((uint8_t*)tx_buffer, sizeof(tx_buffer)-1, 1);

    or

      tx_buffer[7] = tmc_CRC8((uint8_t*)tx_buffer, sizeof(tx_buffer), 1);

    Visitor II
    October 28, 2022

    The problems you're having with the TMC2209 are because there are errors in the data sheet for starters. Anyone trying to write to the TMC2209 via Uart (without an Arduino type 'hold your hand' library), usually gives up in disgust because of these errors. I spent 2 whole days trying to figure out the damn datasheet and finally figured it out.

    The biggest error is the ambiguity in this section: Section 4.1 UART WRITE ACCESS DATAGRAM STRUCTURE

    . . . . . each byte is LSB…MSB, "highest byte transmitted first" is WRONG ! Ignore !

    . . . data bytes 3, 2, 1, 0 (high to low byte) is BS too. I have no idea why this was put in there.

    The 2 items above have confused many to date and caused them to give up.

    I'm retired and love a good mystery so could afford the time required to solve this.

    The 7 bytes plus CRC byte are just sent in the following order:

    sync + reserved, 8 bit slave address, RW + 7 bit register addr, 32 bit data, CRC

    The 32 bit data is just sent LSByte first and not as they incorrectly suggest 'MSbyte first'.

    The other issue is the CRC bytes calculation. You can use their example C source code to calulate it for each 7 byte datagram but they fail to advise that you also need a dummy 0x00 byte on the end to make it 8 bytes total.

    So here's an example datagram from my Assembly language routine for this chip:

    This will give you somethig to work with when testing out their CRC code.

    CHOPCONF: ; Reg Address = 0x6C

    ; Sync SlAd W&RgAd D1 D2  D3  D4 CRC

    .db 0x05, 0x00, 0xEC, 0x10,0x00,0x00,0x53, 0x81

    So the data required for their CRC calculation code is:

    0x05, 0x00, 0xEC, 0x10, 0x00, 0x00, 0x53, 0x00 which will return 0x81 CRC value.

    RPGAuthor
    Explorer II
    November 1, 2022

    Sorry, it took me a while to reply but I have been very busy implementing this. One day before you wrote me I received a TMC2209-BOB and it worked perfectly as intended.

    You are right. The TMC2209-eval board is not working even well with the whole evaluation kit… it is incredible that one gets charged for such expensive board when the documentation is not aligned and the hardware is not working at all as intended… I ordered also a TMC5160 evaluation kit which uses SPI and that was working fine from scratch. But the TMC2209-eval kit is totally messed up.

    I recommend using the BOB to those who wants to start with TMC2209.

    @Community member​ Thank you very much. Your code and tips help me out also to code the UART with the BOB much easily. Without your help would have been much difficult to understand what was happening.

    Graduate II
    November 1, 2022

    http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

    The correct CRC can be checked in this website by setting the default CRC-8 to "Custom" and enabling "Input reflected".

    Here is my improved generic implementation for this CRC:

    uint8_t CRC_8(const void *pData, uint_fast8_t nbData)
    {
    	uint8_t xCRC = 0;
    	const uint8_t *pbData = pData;
     
    	for (; nbData; --nbData) {
    		uint8_t bData = *pbData++;
     
    		for (uint_fast8_t i = 8; i; --i) {
    			bool fXOR = ((xCRC >> 7) ^ bData) & 1;
     
    			bData >>= 1;
    			xCRC <<= 1;
    			if (fXOR) {
    				xCRC ^= 0x07;
    			}
    		}
    	}
    	return xCRC;
    }

    And here is an optimized implementation for Cortex-M3 and higher (with RBIT instruction) cores:

    uint8_t CRC_8(const void *pData, uint_fast8_t nbData)
    {
    	uint8_t xCRC = 0;
    	const uint8_t *pbData = pData;
     
    	for (; nbData; --nbData) {
    		uint8_t bData = *pbData++;
     
    		for (uint_fast8_t i = 8; i; --i) {
    			bool fXOR = (xCRC ^ bData) & 1;
     
    			bData >>= 1;
    			xCRC >>= 1;
    			if (fXOR) {
    				xCRC ^= 0xE0; // 0x07 reversed
    			}
    		}
    	}
    	return (uint8_t)__RBIT(xCRC << 24ul);
    }

    By the way, the byte order can be swapped by REV instruction on any Cortex-M core.

    Also read my post about the hardware configuration in this topic:

    https://community.st.com/s/question/0D53W00001TgA9WSAV/for-stm32f407-what-uart-mode-to-set-for-tmc2209-pdnuart-pin

    RPGAuthor
    Explorer II
    November 1, 2022

    Have noticed myself after a few hours that the last byte must be taken in count also with 0x00 value. It was not very obvious from the documentation but by playing with their example I could figure out.

    Graduate II
    November 1, 2022

    No, the last (CRC) byte is not included in the CRC calculation. The datasheet code example also shows that.

    Visitor II
    November 3, 2022

    @Piranha

    You Wrote:

    "And your CRC is also wrong. The correct CRC for this sequence is 0x9C."

    I stand corrected here. You are correct on this point and I apologize for my error.

    A most important issue is the absolute neccessity to check the IFCNT register at address 0x02

    which holds the the number of successfull WRITE transmissions.

    This is the only real way to confirm if your writes were successfull.

    Visitor II
    November 3, 2022

    @Piranha

    0x05, 0x00, 0xEC, 0x10,0x00,0x00,0x53, 0x9C is the order that the TCM2209 expects to receive the data, was my point. First byte out of the UART is 0x05 sync byte etc. through to 0x9C CRC byte.

    How you arrange these in memory is up to you.

    Graduate II
    November 4, 2022

    > neccessity to check the IFCNT register

    Absolutely agreed on this one!

    > How you arrange these in memory is up to you.

    The driver's datasheet doesn't talk or care about a representation in MCU's memory. It talks about the driver's registers, which are 32-bit. The default value for CHOPCONF register 0x10000053 shows that the byte 0x10 corresponds to register bits [31:24] - the highest byte. As it must be transferred first, the datasheet is correct that the byte order is big-endian - highest byte first.

    Visitor II
    August 25, 2025

    I've encountered a similar issue while working with the STM32F103ZET6. 
    When configuring USART1 for Half-Duplex mode via STM32CUBEMX, UART communication didn't work, no received data was captured. However, when I used UART4 with the exact same configuration, and explicitly called HAL_HalfDuplex_EnableReceiver and HAL_HalfDuplex_EnableTransmitter before each HAL_UART_Transmitand and HAL_UART_Receive call, it worked perfectly.

    Hope this helps you facing the same issue — double-check the HAL control calls for half-duplex mode.