cancel
Showing results for 
Search instead for 
Did you mean: 

UART to interface with TMC2209-Eval Board problems

RPG
Senior

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

1 ACCEPTED SOLUTION

Accepted Solutions

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.

View solution in original post

30 REPLIES 30

>>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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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.

RPG
Senior

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.

RPG
Senior

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

0693W00000Uo50uQAB.png

RPG
Senior

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);

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I have applied the changes but still same result.

TX and RX on the STm32 are push-pull with no pull-up/no pull-down. I have tried also with open drain but nothing changes.

0693W00000Uo5tLQAR.pngI am sending and receiving this way now and nothing:

  while (1)

 {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

 HAL_UART_Transmit(&huart3, (uint8_t*)tx_buffer,sizeof(tx_buffer), 10);

 HAL_Delay(100);

 HAL_UART_Receive(&huart3, (uint8_t*)rx_buffer, sizeof(rx_buffer), 10);

 HAL_Delay(5000);

 }

The device should respond within one character time, so delaying 100ms is not likely to work.

Both pins should be PP_AF, the USART decides if it's an input/output

0693W00000Uo5x8QAB.jpgOnly send what's actually needed, perhaps find a simple, small packet example?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Something along these lines, I'm not using a G4 currently

Push out transmit data, and look to recover response notionally starting within a byte time, or so, of the last byte of valid command data. Find some examples of small packets

#define USART_TMC2209 USART3
 
uint8_t rx_buffer[16]; // Enough to hold full responses
 
void TMC2209_SendReceive(uint8_t *txbuf, uint32_t txsize, uint8_t *rxbuf, uint32_t rxsize)
{
	uint32_t timeout = 500;
	uint32_t i;
	uint32_t start;
 
	i = 0;
	
	start = HAL_GetTick();
 
	while(((HAL_GetTick() - start) < timeout) && (i < txsize))
	{
		if ((USART_TMC2209->ISR & USART_ISR_TXE) != 0)
			USART_TMC2209->TDR = txbuf[i++];
 
		// Check/Clear reception
		
		if (USART_TMC2209->ISR & USART_ISR_ORE) // Overrun Error
			USART_TMC2209->ICR = USART_ICR_ORECF;
		
		if (USART_TMC2209->ISR & USART_ISR_NE) // Noise Error
			USART_TMC2209->ICR = USART_ICR_NECF;
		
		if (USART_TMC2209->ISR & USART_ISR_FE) // Framing Error
			USART_TMC2209->ICR = USART_ICR_FECF;
 
		if ((USART_TMC2209->ISR & USART_ISR_RXNE) != 0) // Clear Pending Data (Echo)
			rxbuf[0] = USART_TMC2209->RDR;
	}
 
  if ((HAL_GetTick() - start) >= timeout)	return; // unlikely to timeout, but covering bases
	
	// Perhaps wait for TC here, otherwise first byte likely to be last byte sent, looping back
	
	i = 0;
	
	start = HAL_GetTick();
	
	while(((HAL_GetTick() - start) < timeout) && (i < rxsize))
	{
		if (USART_TMC2209->ISR & USART_ISR_ORE) // Overrun Error
			USART_TMC2209->ICR = USART_ICR_ORECF;
		
		if (USART_TMC2209->ISR & USART_ISR_NE) // Noise Error
			USART_TMC2209->ICR = USART_ICR_NECF;
		
		if (USART_TMC2209->ISR & USART_ISR_FE) // Framing Error
			USART_TMC2209->ICR = USART_ICR_FECF;
 
		if ((USART_TMC2209->ISR & USART_ISR_RXNE) != 0) // Response
			rxbuf[i++] = USART_TMC2209->RDR;
	}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..