cancel
Showing results for 
Search instead for 
Did you mean: 

MC SDK documentation for data packet structure?

ommo-junyu
Associate II

Hi,

I am trying to understand the protocol, especially how to interpret the data packets to have custom code for auto motor ramp-up.

I see there are some documents under MC workbench -> About. However, I still cannot find the details about the data packet structure.

For instance: Upon executing a sample project through MC Workbench, Cubemx, and CubeIDE, and subsequently initiating the motor using Pilot. I observed the initial packet captured from the UART TX pin as 0x05, 0xC3, 0x00, 0xD4(using a logic analyzer). I speculate this to be a beacon, as indicated by beacon 0x05 from aspep.h, and the Motor Control Protocol Suite documentation mentions the initialization of a beacon from the host. Despite this, I've been unable to locate any documentation detailing the composition of the other three bytes or any specifics regarding the structure of the data packet. The SDK is very complicated as well. It takes too long to understand what each packet means.

 

[VERSION]: MCSDK 6.2.1
[TOOL]: MCSDK, STM32CUBEMX, STM32CUBEIDE, Pilot from MCSDK

 

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
Here is how I read that packet payload.  I do not know if it is accurate.
 
08-00 --> command (16 bit) = 0x0008
    --Motor = command & 0x7 = 0x0
    --CommandID = (command >> 3) & 0x1FFF = 0x1 (SET_REGISTER)
A9-01 --> regIdentifier = 0x1A9
    --Motor = regIdentifier & 0x7 = 0x1
    --Type = (RegIdentifier >> 3)  & 0x7 = 0x5 (RAW Structure)
    --ID = (regIdentifier >> 6) & 0x1FFF = 0x6
06-00 --> Raw Data size: 0x6
    --I didn't see this in the specs, but see mention of it in the generated code,
    --File: register_interface.c ---> function:  RI_GetRegisterMotor1() ---> case: TYPE_DATA_RAW
    --Seems to match number of remaining bytes
1D-09-00-00-00-00 --> ???
 
my register_interface module doesn't seem to contain a Raw structure identified by 0x6.  I am running my motor under HSO.  If you are running under a different mode, you may have a different register setup.

I haven't implemented this yet, and this is as much as I understand.  I don't understand why the motor number seems to be specified twice, once in the set_register command, and once in the register_identifier.  Sorry I can't help more.

View solution in original post

7 REPLIES 7
ccut93
Associate III

The document "Motor Control Protocol Suite" under the help you mentioned contains (almost) all the details needed to build the communication protocol in Arduino.  Yes, it is complicated, but that is the cost of a robust and versatile system.

The protocol essentially multiplexes a serial port into 3 channels, a control channel (for maintaining the connection), a sync channel (for sending commands), and an async channel (for sending oscilloscope-like readings).  Your first step is to learn and understand how to send and receive Beacon and Ping packets to initialize the connection.  Until this connection is made, you cannot do anything else.

You then need to be able to send request packets, and interpret response packets.  The payload of the request and response packets is the commands listed under command service.  These request and response packets make up the synchronous channel.  A good first command to try is GET_MCP_VERSION, as it consists only of the command and no additional data.

I am several weeks into making a C# implementation of Motor Pilot.  It's certainly a journey.  So far, I have identified several discrepancies. 

1: CRC polynomial used for the headers is 0b10111, not 10011.

2: Generated code (at least for FOC) doesn't properly generate ping packets for anything other than a ping packet indicating a last sync packet of 0.  There is an error in the generated code, that I explain here.

Bug Report - ASPEP Protocol Ping Packets - STMicroelectronics Community

So far, I am able to initialize the connection, and read some registers.  That's about it.

Good luck to you.

ommo-junyu
Associate II
Having reviewed your reply, I now understand the protocol better. However, I still find myself perplexed by certain UART communications, particularly those about register configuration, which I observed in the sample project. Can you help me out with it? Thanks
 
Please take an example below:
Action: Adjust speed reference on ST Motor Pilot
Packets:
[Nucleo RX1] {0xc9, 0x00, 0x00, 0xc0}
(intra packet pause) [Nucleo RX2] {0x08, 0x00, 0xa9, 0x01, 0x06, 0x00, 0x1d, 0x09, 0x00, 0x00, 0x00, 0x00}
[Nucleo TX1] {0x1A, 0x00, 0x00, 0x20, 0x00}
 
 
From what I can tell:
[Nucleo RX1] 0xc9: 0x9: Request packet type
0xc: payload length
 
[Nucleo RX2] 0x08: set_register command (0x1 left shift by motor# bits(3))
0xa9: register token(application_config)
0x1d, 0x09: The speed that I adjust (0x91d = 2333)
Please correct me if I'm wrong
 
 
What I do not understand:
From the registry service of the protocol document, the register identifier takes two bytes:
 

 

So the  [Nucleo RX2] {0x08, 0x00, 0xa9, 0x01, 0x06, 0x00, 0x1d, 0x09, 0x00, 0x00, 0x00, 0x00} should be interpreted as:
Command: 0x0008
Reg ID: 0x01a9
Raw buffer size: 0x0006
Rest: data
 
Some questions here:
1. What does the "1" represent on the Reg ID?
 
2. For the APPLICATION_CONFIG register
 

 

It has 6 attributes and the total size is 4+4+2+2+1+1= 14 bytes. The raw buffer size on the request command has only 6 bytes. How does the performer handle the packet?
 
3. The register is described as "Read only". Can we write a set of values to it?
Having reviewed your reply, I now understand the protocol better. However, I still find myself perplexed by certain UART communications, particularly those about register configuration, which I observed in the sample project. Can you help me out with it? Thanks
 
Please take an example below:
Action: Adjust speed reference on ST Motor Pilot
Packets:
[Nucleo RX1] {0xc9, 0x00, 0x00, 0xc0}
(intra packet pause) [Nucleo RX2] {0x08, 0x00, 0xa9, 0x01, 0x06, 0x00, 0x1d, 0x09, 0x00, 0x00, 0x00, 0x00}
[Nucleo TX1] {0x1A, 0x00, 0x00, 0x20, 0x00}
 
 
From what I can tell:
[Nucleo RX1] 0xc9: 0x9: Request packet type
0xc: payload length
 
[Nucleo RX2] 0x08: set_register command (0x1 left shift by motor# bits(3))
0xa9: register token(application_config)
0x1d, 0x09: The speed that I adjust (0x91d = 2333)
Please correct me if I'm wrong
 
 
What I do not understand:
From the registry service of the protocol document, the register identifier takes two bytes:
 

 

So the  [Nucleo RX2] {0x08, 0x00, 0xa9, 0x01, 0x06, 0x00, 0x1d, 0x09, 0x00, 0x00, 0x00, 0x00} should be interpreted as:
Command: 0x0008
Reg ID: 0x01a9
Raw buffer size: 0x0006
Rest: data
 
Some questions here:
1. What does the "1" represent on the Reg ID?
 
2. For the APPLICATION_CONFIG register
 

 

It has 6 attributes and the total size is 4+4+2+2+1+1= 14 bytes. The raw buffer size on the request command has only 6 bytes. How does the performer handle the packet?
 
3. The register is described as "Read only". Can we write a set of values to it?
Here is how I read that packet payload.  I do not know if it is accurate.
 
08-00 --> command (16 bit) = 0x0008
    --Motor = command & 0x7 = 0x0
    --CommandID = (command >> 3) & 0x1FFF = 0x1 (SET_REGISTER)
A9-01 --> regIdentifier = 0x1A9
    --Motor = regIdentifier & 0x7 = 0x1
    --Type = (RegIdentifier >> 3)  & 0x7 = 0x5 (RAW Structure)
    --ID = (regIdentifier >> 6) & 0x1FFF = 0x6
06-00 --> Raw Data size: 0x6
    --I didn't see this in the specs, but see mention of it in the generated code,
    --File: register_interface.c ---> function:  RI_GetRegisterMotor1() ---> case: TYPE_DATA_RAW
    --Seems to match number of remaining bytes
1D-09-00-00-00-00 --> ???
 
my register_interface module doesn't seem to contain a Raw structure identified by 0x6.  I am running my motor under HSO.  If you are running under a different mode, you may have a different register setup.

I haven't implemented this yet, and this is as much as I understand.  I don't understand why the motor number seems to be specified twice, once in the set_register command, and once in the register_identifier.  Sorry I can't help more.

Hi @ccut93 ,

Thanks for answering.

I agree with your answer, the ID 6 of RAW Structure is defined as MC_REG_SPEED_RAMP

#define MC_REG_SPEED_RAMP ((6U << ELT_IDENTIFIER_POS) | TYPE_DATA_RAW)

The size is indeed 6 bytes. 4 bytes for coding the speen in rpm, and 2 bytes for coding the duration.

 

This register does not exist in HSO flavor.

Regarding the duplication of motor number, it is mainly due to the fact that we need in some cases to fully defined the register, for instance when we configure the Datalog. 

Regards

Cedric

 

Hi Cedric,

 

Thanks for the confirmation. That is a milestone for my research and learning.

 

Do you know where I can find the register information you mention?
"

The size is indeed 6 bytes. 4 bytes for coding the speen in rpm, and 2 bytes for coding the duration.

"

 

Thanks

cedric H
ST Employee

Hi,

All registers can be viewed from the STMotorPilot\RegisterList folder.

In your case you will find :

{
"Id": 6,
"Name" : "SPEED_RAMP",
"Description" : "Parameters of a speed ramp to apply to the motor",
"Type" : "RAWSTRUCTURE",
"Unit" : "",
"Access" : "RW",
"Scope": "Motor",
"Structure": [
"S32",
"U16"
]
}

For the detail of the structure, the best is to quickly look at the register_interface.c code:

case MC_REG_SPEED_RAMP:
{
  int32_t rpm;
  uint16_t duration;

  rpm = *(int32_t *)rawData; //cstat !MISRAC2012-Rule-11.3
  duration = *(uint16_t *)&rawData[4]; //cstat !MISRAC2012-Rule-11.3
  MCI_ExecSpeedRamp(pMCIN, (int16_t)((rpm * SPEED_UNIT) / U_RPM), duration);
  break;

}

Hope it helps.

Cedric