cancel
Showing results for 
Search instead for 
Did you mean: 

Send & Receive Data over USART1 using Motor Control Protocol & ASPEP

smaiti
Associate III

Hi,

I am currently working on a project where I have to develop the firmware for the BLDC motors used in our device. I have been struggling to use this board along with the MCSDK as advertised. I want to get started by sending data over USART1 (open from a tool like Ucon or Putty) which can control the motor in a way similar to the MC Pilot. I am aware of the use of DMA over UART using the HAL library but I am trying to use the MCPS & ASPEP protocol that is already implemented.
For example when I type in START_MOTOR from the putty console, the motor starts.
I have looked through the code that was auto-generated and found that the Systick IRQ calls the MC_Scheduler which checks the rxBuffer & calls the MCP_ReceivedPacket.
I am not sure how my typed command will be processed. 

I tried using the HAL library functions but I don't see any response from the motor or the states changing from IDLE.

1 ACCEPTED SOLUTION

Accepted Solutions

https://controllerstech.com/uart-receive-in-stm32/ 

Check the above website or ST sample codes to transmit and receive data using UART.

View solution in original post

5 REPLIES 5
SRedd.5
Senior III
smaiti
Associate III

Hi @SRedd.5 ,

I have already gone through the documentation as mentioned in the attached post. Although the theoretical part is explained. I don't see any examples or explanations for using the API for a user application. 
For the current setup, I have USART1 configured for MCP using the MC Workbench but ST-LINK also uses this USART.
I was trying to read user input from the comm port using an application like Putty or Ucon (since ST-LINK is over USB on this comm port) but this particular USART is configured for MCP and probably my inputs are not correctly transferred to the memory.
I have spent enough time I think trying to figure this out.
There is another USART available and I think I will try to use this to get the user input from another comm port and then send this data using DMA (Peripheral to Memory).
This user input should be able to start/stop the motor for example when a user types START_MOTOR and hits enter, the motor should start & STOP_MOTOR should stop the motor.
I will write a function that recognizes these cmds and calls the APIs for starting and stopping the motor.

According to my understanding ST-LINK does not use USART. If you check your ioc file there will be dedicated pins for UART communication.

SRedd5_0-1703778854432.png

 

If you are not using Motor pilot software it is not required to use the MCP protocol, simple example using UART

Ex:

Suppose if you send 1 using Putty etc. then in your firmware you can write something like

 

if(uartdatareceived == 1) /*1 received from putty*/
 {
  if(IDLE == MC_GetSTMStateMotor1())
  {
       (void)MC_StartMotor1(); /* Start Motor */
  }
 }
 else if(uartdatareceived == 2)
 {
    (void)MC_StopMotor1();
 }

 

If you want speed mode

 

if(uartdtareceived == 3) /*data received from UART*/
{
      		MC_ProgramSpeedRampMotor1(speed,time);
}

 

 

Hi @SRedd.5 ,

Thanks for this tip. I tried doing what you recommended.

I configured the USART2 in Asynchronous Mode and also Enabled the DMA1 on Channel 1 (Peripheral to Memory in Normal Mode).

smaiti_3-1703815138626.png

 

smaiti_0-1703814442689.png

These Pins PA2 & PA3 are available over the Comm port so I am able to send my input over Putty but not quite.

I added the following code in the P-IMH03-Potentiometer project from MC Workbench (Disabled MCP over USART) 

The following was added in the main function

  HAL_UART_Receive_DMA(&huart2, data_buffer, BUFFER_SIZE);  // Start initial reception

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
//  printf("Hello World!\n");
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */


I updated the IRQHandler as follows : 

void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart2_rx);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

  // Check if DMA transfer for UART RX is complete
  if (__HAL_DMA_GET_FLAG(&hdma_usart2_rx, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_usart2_rx))) {
    // Clear transfer complete flag
    __HAL_DMA_CLEAR_FLAG(&hdma_usart2_rx, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_usart2_rx));

    // Process received data
    if (data_buffer[0] >= '0' && data_buffer[0] <= '9') {
      uint8_t uartdatareceived = data_buffer[0] - '0';

      if (uartdatareceived == 1) {
        if (IDLE == MC_GetSTMStateMotor1()) {
          MC_StartMotor1();  // Start Motor
        }
      } else if (uartdatareceived == 2) {
        MC_StopMotor1();
      }
    }

    // Restart DMA for continuous reception
    HAL_UART_Receive_DMA(&huart2, data_buffer, BUFFER_SIZE);
  }

  /* USER CODE END DMA1_Channel1_IRQn 1 */
}

Using breakpoints I was able to hit the Start Function and the motor starts spinning after I enter 1 from the terminal
but I can't seem to hit the condition when I enter 2. The Motor keeps on spinning.
The reason I intend on using DMA is to keep the CPU free from any data input & output responsibilities since the MCSDK firmware has some computationally expensive algorithms that need the CPU clock cycles.
Is there something missing from the putty or the terminal configuration or this code.
My putty is configured as follows : 

smaiti_1-1703815058661.pngsmaiti_2-1703815073902.png

 

https://controllerstech.com/uart-receive-in-stm32/ 

Check the above website or ST sample codes to transmit and receive data using UART.