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

30 REPLIES 30

Hi Tesla.

Sorry for the delay. I haven't seen your messages. For any reason GMAIL got stuck and wasn't updating messages, so I didn't get any messages since Friday. But fixed it and I am just reading all what you sent me.

Nice you have a link with working CRCs. That's something I can use.

I will try and will come up with feedback.

Thank you very much for your help.

Best regards

Now I am sure I am calculating the right the CRC is the one from the TMC2209 datasheet, Something that is not explained correctly in the data sheet is that when sending a read of the register one has to send 4 bytes (the data part which must be included in the writing datagram must be omitted 32 bits). I am now sending a basic read with 4 bytes only as it should. And get no reply from the TMC. I think datagram {0x05, 0x00, 0x00, 0x48} is a valid one. But in my protocol analyser tool I can only see the command I sent but no reply.

0693W00000UoAS5QAN.png 

I will continue trying other links you sent me.

I have also tried with your TMC2209_SendReceive function. No error showing up.

It sounds like the TMC2209-eval board is not receiving the TX datagram. Because at this point there might be a response showing up at least on the protocol analyser for UART that I have attached to the TX and RX pins. Am I right?

JMybu.1
Associate II

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.

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.

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.

> Something that is not explained correctly in the data sheet is that when sending a read of the register one has to send 4 bytes (the data part which must be included in the writing datagram must be omitted 32 bits).

The read access request diagram in "4.1.2 Read Access" clearly shows 32 bits of total length without a data field.

> I think datagram {0x05, 0x00, 0x00, 0x48} is a valid one.

Yes, that is correct, including the CRC.

Piranha
Chief II

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

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.