8 years, 10 months ago.

Message transfer/receive protocol clarification

Hello,

I am adapting your MTi-1 example for use with a non-mbed board (specifically, an Arduino) using SPI interface. As such, I have been reading your code extensively to get a better understanding of how it works.

When you read a message, what is the purpose of sending the control pipe opcodes (e.g. XBUS_CONTROL_PIPE, XBUS_NOTIFICATION_PIPE and XBUS_MEASUREMENT_PIPE)? I have found no reference to why you do this.

My understanding so far of the protocol is: - Data ready pin signal activie, Data ready interrupt triggered Handler does the following: - Send opcode XBUS_PIPE_STATUS (why??? where is the reference?) - Read 4 bytes of status (what status? It appears not to be the message preamble, BID, MID, and LEN (unless it is the header?)) - It would not make sense to be the header, because the first two bytes are always the preamble and BID, which will always be non-zero when OR'd together, so the message would then always be of notification type - Check if 'status' is notification or message type (non-zero), and read data accordingly

During readData, the following occurs: - Allocate memory location for message - Manually insert XBUS Message Preamble and Master Device BID into the allocated memory location - Send an opcode (XBUS_NOTIFICATION_PIPE or XBUS_MESSAGE_PIPE) (why is this?) - Read data into allocated buffer - Parse data with Xbus Parser

Would you kindly explain why the opcodes are sent? And what is the variable array 'status'? I have no doubt that it is part of the XBus protocol, but I do not see it anywhere and I would like to understand how and why instead of just blindly porting over your code.

Thanks! Elizabeth

Question relating to:

Basic implementation of Xbus message parsing and generation for embedded processors. The code has no dependencies and should also work for other MCU architectures than ARM provided a C99 compiler …

1 Answer

8 years, 10 months ago.

Hi Elizabeth,

Thank you for your question. A description of the communication protocol used for I2C/SPI/UART can be found in the datasheet of the MTi-1 series. The datasheet you can find here: https://www.xsens.com/download/pdf/documentation/mti-1/mti-1-series_datasheet.pdf . We also updated the example's homepage with this link now. The information you need is in Section 2.7 of the datasheet.

For I2C/SPI you exchange so called reduced Xbus messages with the MTi-1. These are Xbus messages with the preamble and busId removed to reduce overhead. So for example the gotoConfig Xbus message is usually FA FF 30 00 D1. The reduced version of this is 30 00 D1. The calculation of the checksum is done assuming a busId of 0xFF. On UART we exchange normal Xbus messages.

To actually exchange the reduced Xbus message with I2C/SPI we introduced an additional transport layer (MTSSP). We did this because unlike UART with these protocols the MTi-1 can not send you data on its own so you have to initiate that. The MTSSP is there to provide the master information and control. The opcodes you mention are for this protocol.

For the master (you) a low level SPI message exchange goes:

  • Chip select
  • Send Opcode
  • Send 3 padding bytes (Fillword to give the MTi-1 time to process the opcode)
  • Send/Receive N bytes (the reduced Xbus message or MTSSP specific data)
  • Chip deselect

To send a message to the MTi-1:

  • Send message to MTi using the ControlPipe (0x03) opcode
  • Wait for the response to be available by checking the DRDY line
  • Read the pipe status to determine how big the first pending message is using the PipeStatus(0x04) opcode
  • Read N bytes from the notification pipe using the NotificationPipe (0x05) opcode

Reading measurement data from the MTi-1:

  • Wait for the DRDY line to indicate there is data available
  • Read the pipe status to determine if and how much measurement data is available using the PipeStatus(0x04) opcode
  • Read N bytes from the measurement pipe using the MeasurementPipe (0x06) opcode

A simple approach that usually works is to monitor the DRDY line continuously. If it goes/is high read the pipe status. The pipe status gives you the size of the first pending message in both notification and measurement pipe. If the size is non-zero you read from the respective pipe and handle the received message accordingly.

Please note that you can only read a message once from a pipe. So if you do not read the message in full during a single SPI/I2C transfer the remainder of that message will be lost.

I hope this helps you further.

Cheers, Tjerk

Accepted Answer

Ah, I seem to have only received Revision A of the MTi-1 Datasheet (Jul. 8, 2015) with my Dev Kit. Thank you so much for the prompt and thorough answer.

posted by Elizabeth Zhang 26 Jan 2016

Follow up: I am having trouble implementing the protocol to receive data. I am definitely pulling data from the the MTi-3 - when asking for the notification and measurement sizes, the data sizes from the pipe, respectively, are: 0x8081 and 0x8014.

It does not make sense why the first notification size is so large (or any subsequent notifications). Since the MTi-1 series only uses MtData, I have limited my max buffer size 254 bytes. When I only pass in the size of the lower two bytes of the message (e.g. 0x81 and 0x14), the result bytes do not correspond with any known message type. The first two data bytes (excluding the preamble and BID), are 0x81 0x80.

What could the issue be?

For my own knowledge, what data does the MTi send if it is asked to transfer data, but no opcode was given?

posted by Elizabeth Zhang 26 Jan 2016

Additionally, upon further examination, regardless of what pipe opcode I send it (first control pipe, then notification pipe, also tested with measurement pipe opcode), the first four bytes are the same. Now, I receive, for my "supposed" pipe sizes: 0x2BF8 and 0xFFA6. When reading the data, I do the following: - Allocate buffer - Add preamble and master device header bytes - Pull CS low - Send opcode with specified pipe opcode (both give me the same data out) - Transfer data into buffer for specified length - Release CS (high)

When I examine the data bytes placed into the buffer, they are FA FF F8 2B A6 FF 5E 3B.... The first two bytes are expected, I manually placed the preamble and master device codes into the buffer The next four bytes, you'll notice, are exactly the same as the supposed pipe sizes from the MtsspCofiguration struct. Obviously, these bytes are incorrect. I'd be happy to share my code with you somehow - unfortunately these comment posts do not seem to allow nice code pasting - just let me know how and where.

posted by Elizabeth Zhang 26 Jan 2016

Hi Elizabeth, I'll pm you how to help you further

posted by Tjerk Hofmeijer 27 Jan 2016

Hello,

I just purchased an MTi 1 series and I would like to set an SPI communication between this device(slave) and a microcontroller(master). Thank you for this detailed answer which helps a lot understanding the SPI communication protocol. Unforunately I didn't manage to communicate with the Mti module. The DRDY pin never seems to change state. On power up of the Mti device the uart communication is active and since the CTS(inpout) and DRDY(output) share the same pin I wonder if I need to configurate the Mti to be on SPI mode and not uart in order to be able to communicate with the module.

Thank you for your time, rose.

posted by Rose Mazari 02 Mar 2016

Hi Rose,

You have to select the active communication protocol lines using the PSEL lines. I assume you are using the MTi1 in combination with our dev board? If so you can use the dip switches to do this (there is a legend printed on the bottom of the dev board). If not you have to make PSEL0 low and PSEL1 high to select SPI. Please note that the MTi1 only checks the value of the PSEL lines at startup.

Cheers, Tjerk

posted by Tjerk Hofmeijer 02 Mar 2016