Skip to main content
Visitor II
February 23, 2023
Question

STM32F103 and TMC2209 Stepper driver UART connection, no reply.

  • February 23, 2023
  • 6 replies
  • 6891 views

I have been trying to get a TMC2209 and STM32F103 working over UART for a while now.

I have followed 2 posts ( I am pretty sure correctly ) on this but I can't add them here as I am a new member, they are already on this community.

I have found online that I need to bridge a connection at the back of the driver board I am using, I have done that.

I have also found that for the start UART comms I need to set "GCONF.pdn_disable = 1"

I think that is done correctly in the code below but feel free to correct me.

I have connected a 1K resistor between the Tx and Rx lines as in the datasheet and in one of the posts above.

My problems start with the UART connection I believe.

I have included nothing else in this code so I can just look at getting this working.

I get a 0x05 on Recv[0] each time I run the code but I do not get any other values, I expect to see 0xFF in Recv[1] but I get 0x00.

I get the sync nibble but then nothing else, when I disconnect the Rx and Tx line from the TMC2209 I still get the 0x05 so that makes me thing something is wrong there.

I have tried to use the Receive to idel but I get the same results as the above.

I have played with delays before Receving but then I don't even get the 0x05.

I worried that I might be sending the data in the wrong order ?

All I am trying to do is read back the register I just wrote to.

:

Any pointers would be great on where to go to from here.

Thanks all.

    This topic has been closed for replies.

    6 replies

    TDuck.1Author
    Visitor II
    February 23, 2023

    For some reason my code did not get added, here it is :

    /* USER CODE BEGIN Header */
    /**
     ******************************************************************************
     * @file : main.c
     * @brief : Main program body
     ******************************************************************************
     * @attention
     *
     * Copyright (c) 2023 STMicroelectronics.
     * All rights reserved.
     *
     * This software is licensed under terms that can be found in the LICENSE file
     * in the root directory of this software component.
     * If no LICENSE file comes with this software, it is provided AS-IS.
     *
     ******************************************************************************
     */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
     
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
     
    /* USER CODE END Includes */
     
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
     
    /* USER CODE END PTD */
     
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    /* USER CODE END PD */
     
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
     
    /* USER CODE END PM */
     
    /* Private variables ---------------------------------------------------------*/
    TIM_HandleTypeDef htim5;
     
    UART_HandleTypeDef huart3;
     
    /* USER CODE BEGIN PV */
     
    /* USER CODE END PV */
     
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_USART3_UART_Init(void);
    static void MX_TIM5_Init(void);
    /* USER CODE BEGIN PFP */
     
    /* USER CODE END PFP */
     
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
     
    /* USER CODE END 0 */
     
    /**
     * @brief The application entry point.
     * @retval int
     */
    int main(void)
    {
     /* USER CODE BEGIN 1 */
     
     /* USER CODE END 1 */
     
     /* MCU Configuration--------------------------------------------------------*/
     
     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
     HAL_Init();
     
     /* USER CODE BEGIN Init */
     
     /* USER CODE END Init */
     
     /* Configure the system clock */
     SystemClock_Config();
     
     /* USER CODE BEGIN SysInit */
     
     /* USER CODE END SysInit */
     
     /* Initialize all configured peripherals */
     MX_GPIO_Init();
     MX_USART3_UART_Init();
     MX_TIM5_Init();
     /* USER CODE BEGIN 2 */
     
     /* USER CODE END 2 */
     
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     
     // basic testing for the TMC2209 driver, sending data on the UART line.
     
     uint8_t send [8]; // total to send
     send[0] = 0x05; // Sysnc part to start Tx
     send[1] = 0x00; // Slave Addr ( to address the different drivers
     send[2] = 0x80; // Addr of the register +
     send[3] = 0x00;
     send[4] = 0x00;
     send[5] = 0x03;
     send[6] = 0x2E;
     send[7] = 0xEF;
     
     HAL_UART_Transmit(&huart3, send, sizeof(send),10);
     
     // ask for a read now from 0x02 ( IFCNT )
     
     
     
     uint8_t Recv[8] = {0};
     uint8_t send2 [4]; // total to send
     send2[0] = 0x05; // Sysnc part to start Tx
     send2[1] = 0x00; // Slave Addr ( to address the different drivers
     send2[2] = 0x00; // Addr of the register +
     send2[3] = 0x48;
     
     HAL_UART_Transmit(&huart3, send2, sizeof(send),10);
     HAL_UART_Receive(&huart3, Recv, 8, 100);
     
     
     
     
     while (1)
     {
     /* USER CODE END WHILE */
     
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }
     
    /**
     * @brief System Clock Configuration
     * @retval None
     */
    void SystemClock_Config(void)
    {
     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
     
     /** Initializes the RCC Oscillators according to the specified parameters
     * in the RCC_OscInitTypeDef structure.
     */
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
     RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
     Error_Handler();
     }
     
     /** Initializes the CPU, AHB and APB buses clocks
     */
     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
     |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
     
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
     {
     Error_Handler();
     }
    }
     
    /**
     * @brief TIM5 Initialization Function
     * @param None
     * @retval None
     */
    static void MX_TIM5_Init(void)
    {
     
     /* USER CODE BEGIN TIM5_Init 0 */
     
     /* USER CODE END TIM5_Init 0 */
     
     TIM_ClockConfigTypeDef sClockSourceConfig = {0};
     TIM_MasterConfigTypeDef sMasterConfig = {0};
     
     /* USER CODE BEGIN TIM5_Init 1 */
     
     /* USER CODE END TIM5_Init 1 */
     htim5.Instance = TIM5;
     htim5.Init.Prescaler = 50;
     htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
     htim5.Init.Period = 100;
     htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
     htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
     if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
     {
     Error_Handler();
     }
     sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
     if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)
     {
     Error_Handler();
     }
     sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
     sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
     if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN TIM5_Init 2 */
     
     /* USER CODE END TIM5_Init 2 */
     
    }
     
    /**
     * @brief USART3 Initialization Function
     * @param None
     * @retval None
     */
    static void MX_USART3_UART_Init(void)
    {
     
     /* USER CODE BEGIN USART3_Init 0 */
     
     /* USER CODE END USART3_Init 0 */
     
     /* USER CODE BEGIN USART3_Init 1 */
     
     /* USER CODE END USART3_Init 1 */
     huart3.Instance = USART3;
     huart3.Init.BaudRate = 115200;
     huart3.Init.WordLength = UART_WORDLENGTH_8B;
     huart3.Init.StopBits = UART_STOPBITS_1;
     huart3.Init.Parity = UART_PARITY_NONE;
     huart3.Init.Mode = UART_MODE_TX_RX;
     huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
     huart3.Init.OverSampling = UART_OVERSAMPLING_16;
     if (HAL_UART_Init(&huart3) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN USART3_Init 2 */
     
     /* USER CODE END USART3_Init 2 */
     
    }
     
    /**
     * @brief GPIO Initialization Function
     * @param None
     * @retval None
     */
    static void MX_GPIO_Init(void)
    {
     
     /* GPIO Ports Clock Enable */
     __HAL_RCC_GPIOA_CLK_ENABLE();
     __HAL_RCC_GPIOC_CLK_ENABLE();
     
    }
     
    /* USER CODE BEGIN 4 */
     
    /* USER CODE END 4 */
     
    /**
     * @brief This function is executed in case of error occurrence.
     * @retval None
     */
    void Error_Handler(void)
    {
     /* USER CODE BEGIN Error_Handler_Debug */
     /* User can add his own implementation to report the HAL error return state */
     __disable_irq();
     while (1)
     {
     }
     /* USER CODE END Error_Handler_Debug */
    }
     
    #ifdef USE_FULL_ASSERT
    /**
     * @brief Reports the name of the source file and the source line number
     * where the assert_param error has occurred.
     * @param file: pointer to the source file name
     * @param line: assert_param error line source number
     * @retval None
     */
    void assert_failed(uint8_t *file, uint32_t line)
    {
     /* USER CODE BEGIN 6 */
     /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
     /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */

    ST Employee
    February 23, 2023

    Dear @TDuck.1​ 

    Just some ideas to check :

    Is there an echo or a loop between your TX and RX pins ? In other words, could it be that when you "get a 0x05 on Recv[0]", this 0x05 is the one you sent from send[0] or send2[0] ?

    Second question (if answer to first one is no) : is return code of your HAL_UART_Receive() call equal to HAL_OK ? in such case, it means you receive properly 8 bytes, right ?

    Regards

    TDuck.1Author
    Visitor II
    February 24, 2023

    Hi, so I might have an echo as you pointed out, when I try and receive after the frist Tx I still get the 0x05 but that should not happen as Write commands should not reply to anything ( from what I understand in the datasheet )

    When I disconnect the Tx and Rx lines from everything then I do not get the 0x05, but when I connect them together with only the 1K resistor but not to the TMC2209 then I get a the 0x05 sync nibble.

    Any suggestions on how I would get ride of that ?

    I also edited the code to look if the Receive would return HAL_OK but it does not so it is not actually getting anything from the TMC2209.

    Thanks for the input.

    Graduate II
    February 24, 2023

    The line 126 of your code has a bug.

    If you connect the Rx line to the Tx line, isn't it obvious that it receives the transmitted data? ;) One has to either ignore/clear that data or better switch from Tx to Rx mode and back. Probably the HAL_HalfDuplex_EnableTransmitter()/HAL_HalfDuplex_EnableReceiver() functions can help, if you want to stick with the HAL/Cube broken bloatware.

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

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

    TDuck.1Author
    Visitor II
    February 24, 2023

    @Piranha​  Thanks for pointing out that bug.

    I have seen that the USART line gets pulled down to around 1V when I connect it to the TMC2209, this seems like it could be a problem. I used a different board and found the mod that I did to the back was the cause of this pull down error, but now I am getting a much higher value signal but still nothing coming back from the TMC2209.

    Seems like the guide I saw was incorrect about bridging the 2 pads to get UART working.

    I have tried with the HAL_HalfDuplex_EnableTransmitter()/HAL_HalfDuplex_EnableReceiver() functions you suggested but using them and the UART port in Half Duplex mode returns nothing, not even that echo off the Tx line.

    That and I see in your last posts that the Pin out settings do not really allow this connection :

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

    I have set USART3 to Asynchronous mode but now I am unsure if I am sending the correct values for the Register or in the correct order, if you have any input on that I would greatly appreciate it.

    TDuck.1Author
    Visitor II
    February 24, 2023

    Well looking at the Datasheet of my board I actually do need to bridge that pad at the back to get UART connected, but it seems werid that there is such a strong pull down on that line ?

    Enough to pull it to 1V from 3.3V

    https://www.trinamic.com/fileadmin/assets/Products/Eval_Drawings/TMC2209SilentStepStick_schematic_v20.pdf

    Graduate II
    March 5, 2023

    Seems that by default the board is configured for standalone operation. For UART operation I would remove the R1 20k. Internal pull-up/down on STM32 is ~40k, so 1V makes sense.

    Also I checked the CRC for your test examples - those are OK.

    Visitor II
    February 11, 2024

    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