Example for updating the MTi-1's firmware. Uses a platform independent, retargetable pure C implementation of the firmware updater protocol.

Dependencies:   mbed-rtos mbed

Overview

The purpose of this example is to demonstrate how to update the firmware of an MTi-1 series module using the FwUpdate library. The FwUpdate library is provided as C source in the xbus directory. It is setup to be platform independent and easily retargetable. The user must provide an instance of the FwUpdate struct having the platform specific callback function filled in. Refer to fwupdate.h for more information.

The example embeds an Xsens Firmware File (XFF). The XFF used is the official 1.1.1 MTi1-series firmware release. If needed binary copies of specific firmware files can be requested through our support department. We used srecord to convert the XFF to the C data array (See xffdata.c and xffdata.h). When using requested Xsens provided XFF file use srecord as follows:

srec_cat firmware.xff -binary -o xffdata.c -C-array g_xffData -include


This example updates the firmware only. The eMTS (extended Motion Tracker Settings) are not updated. This means that in rare cases (e.g. when hardware filter parameters are updated), you do not take full advantage of the filter update. Most functionality, such as filter behavior, outputs, output formats and communication options are updated with this example. Please use the Windows/Linux FW updater when HW parameters are updated (see release notes to check if HW parameters were changed).

Communication with the MTi-1 series device is implemented using a either a full-duplex UART, I2C or SPI bus. A reset line is used to reset the MTi during initialization. Data is output to a host PC terminal using a second UART.

Supported Platforms

The program has been tested on the following mbed platforms:

Porting to other mbed platforms is relatively be easy by adding its specific port information to board.h. It is however necessary that the board has sufficient code flash/ROM to keep a copy of the XFF (150K). In case you store the XFF data in a different memory (e.g. an external memory) you must re-implement the readXffData callback function.

Using the Example

  1. To use the example program connect one of the supported mbed boards to the host PC and download the application from the mbed online compiler to the target device.
  2. With the mbed board unpowered (USB disconnected) wire the mbed board to the MTi-1 development board. The following connections are required:
    • In all cases:
      • 5V (or 3V3) main supply to VDD (P300-1)
      • MCU IO voltage (IORef) to VDDIO (P300-2)
      • GND to GND (P300-3)
      • MT_NRESET to nRST P(300-5)
    • For I2C communication:
      • MT_SCL to I2C_SCL (P300-9)
      • MT_SDA to I2C_SDA (P300-11)
      • MT_DRDY to DRDY (P300-15)
      • MT_ADD0 to ADD0 (P300-17)
      • MT_ADD1 to ADD0 (P300-19)
      • MT_ADD2 to ADD0 (P300-21)
    • For SPI communication:
      • MT_DRDY to DRDY (P300-15)
      • MT_SCLK to SPI_SCK (P300-17)
      • MT_MISO to SPI_MISO (P300-19)
      • MT_MOSI to SPI_MOSI (P300-21)
      • MT_nCS to SPI_nCS (P300-23)
    • For UART communication:
      • MT_RX to UART_TX (P300-9)
      • MT_TX to UART_RX (P300-11)

Information

Check the defines in board.h to determine which IO pins are used for the MT_xxx connections on each mbed platform.

Information

The active peripheral (I2C, SPI or UART) is selected on the MTi-1 development board through the PSEL0 and PSEL1 switches. Look on the bottom of the development board for the correct settings.

  1. Connect to the target using a serial terminal. The application is configured for:
    • Baudrate = 921600
    • Stop bits = 1
    • No parity bits
    • No flow control
  2. Reset the mbed board.
  3. You should be presented with a simple user interface as shown below:
Embedded firmware updater example
Interface: I2C

h: Print this text
c: GotoConfig
m: GotoMeasurement
r: Soft reset the module
b: GotoBootloader
v: Request firmware revision
d: Request deviceId
u: Start firmware update (make sure module is in bootloader mode)
x: Hard reset the module and make it stay in bootloader 

To do a firmware update

  • Make the MTi-1 enter bootloader mode. Either through 'b' or 'x'
  • You can check if the MTi-1 is in bootloader by requesting the firmware revision ('v'). The bootloader revision always starts with 255
  • Press 'u' to start the firmware update
  • After about 20 seconds the "Firmware update ready" message should appear indicating the update succeeded
  • The device should automatically reboot into its application firmware (use 'v' to verify)
Committer:
Xsens
Date:
Tue Nov 24 12:49:45 2015 +0000
Revision:
1:7f19a1b1a9df
Parent:
0:6fca643f1aff
Child:
2:259cc4dbadf2
Child:
3:93d0057b0690
After reset the MTi1 is forced into config mode by catching the XMID_Wakeup messages. This to prevent the burst of XMID_MtData2 events at first startup.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tjerkhofmeijer 0:6fca643f1aff 1 /*! \file
tjerkhofmeijer 0:6fca643f1aff 2 \copyright Copyright (C) Xsens Technologies B.V., 2015.
tjerkhofmeijer 0:6fca643f1aff 3
tjerkhofmeijer 0:6fca643f1aff 4 Licensed under the Apache License, Version 2.0 (the "License"); you may not
tjerkhofmeijer 0:6fca643f1aff 5 use this file except in compliance with the License. You may obtain a copy
tjerkhofmeijer 0:6fca643f1aff 6 of the License at
tjerkhofmeijer 0:6fca643f1aff 7
tjerkhofmeijer 0:6fca643f1aff 8 http://www.apache.org/licenses/LICENSE-2.0
tjerkhofmeijer 0:6fca643f1aff 9
tjerkhofmeijer 0:6fca643f1aff 10 Unless required by applicable law or agreed to in writing, software
tjerkhofmeijer 0:6fca643f1aff 11 distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
tjerkhofmeijer 0:6fca643f1aff 12 WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
tjerkhofmeijer 0:6fca643f1aff 13 License for the specific language governing permissions and limitations
tjerkhofmeijer 0:6fca643f1aff 14 under the License.
tjerkhofmeijer 0:6fca643f1aff 15
tjerkhofmeijer 0:6fca643f1aff 16 \page Embedded firmware example
tjerkhofmeijer 0:6fca643f1aff 17 The purpose of this example is to demonstrate how to update the firmware of a MTi-1 series module using the FwUpdate library.
tjerkhofmeijer 0:6fca643f1aff 18 The example embeds an Xsens firmware file (xff) which is converted to a data array with srecord (http://srecord.sourceforge.net).
tjerkhofmeijer 0:6fca643f1aff 19 The example is designed to run on a Nucleo F401 board. Porting to other mbed platforms should be easy but not all boards may
tjerkhofmeijer 0:6fca643f1aff 20 have enough flash memory to hold the full xff
tjerkhofmeijer 0:6fca643f1aff 21
tjerkhofmeijer 0:6fca643f1aff 22 \section Software setup
tjerkhofmeijer 0:6fca643f1aff 23 Select the required bus mode by uncommenting one of the following defines at the top of main.cpp
tjerkhofmeijer 0:6fca643f1aff 24 \verbatim
tjerkhofmeijer 0:6fca643f1aff 25 BUS_MODE_SPI
tjerkhofmeijer 0:6fca643f1aff 26 BUS_MODE_I2C
tjerkhofmeijer 0:6fca643f1aff 27 BUS_MODE_UART
tjerkhofmeijer 0:6fca643f1aff 28 \endverbatim
tjerkhofmeijer 0:6fca643f1aff 29 Next, build the example and program it in the Nucleo F401 board.
tjerkhofmeijer 0:6fca643f1aff 30
tjerkhofmeijer 0:6fca643f1aff 31 \section Development board setup
tjerkhofmeijer 0:6fca643f1aff 32 Configure the required bus mode (UART, I2C, SPI) with the dip switches on the MTi-1 development board.
tjerkhofmeijer 0:6fca643f1aff 33 (At the bottom of the development board a table with switch settings is shown)
tjerkhofmeijer 0:6fca643f1aff 34
tjerkhofmeijer 0:6fca643f1aff 35 \section Hardware setup
tjerkhofmeijer 0:6fca643f1aff 36
tjerkhofmeijer 0:6fca643f1aff 37 Unpower the board and make the following connections between the Nucleo F401 board and the
tjerkhofmeijer 0:6fca643f1aff 38 MTi 1 series development board (depending on the selected bus mode, the unused connections may be
tjerkhofmeijer 0:6fca643f1aff 39 left unconnected)
tjerkhofmeijer 0:6fca643f1aff 40
tjerkhofmeijer 0:6fca643f1aff 41 Power supply and reset:
tjerkhofmeijer 0:6fca643f1aff 42 \verbatim
tjerkhofmeijer 0:6fca643f1aff 43 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 44 | Signal | Nucleo F401 | Mti-1s Dev board header |
tjerkhofmeijer 0:6fca643f1aff 45 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 46 | 5V | 5V | 1 |
tjerkhofmeijer 0:6fca643f1aff 47 | 3V3 | 3V3 | 2 |
tjerkhofmeijer 0:6fca643f1aff 48 | GND | GND | 3 |
tjerkhofmeijer 0:6fca643f1aff 49 | RESET | PC9 | 5 |
tjerkhofmeijer 0:6fca643f1aff 50 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 51 \endverbatim
tjerkhofmeijer 0:6fca643f1aff 52
tjerkhofmeijer 0:6fca643f1aff 53 Uart:
tjerkhofmeijer 0:6fca643f1aff 54 \verbatim
tjerkhofmeijer 0:6fca643f1aff 55 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 56 | Signal | Nucleo F401 | Mti-1s Dev board header |
tjerkhofmeijer 0:6fca643f1aff 57 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 58 | Tx of Nucleo | PA9 | 11 |
tjerkhofmeijer 0:6fca643f1aff 59 | Tx of MTi | PA10 | 9 |
tjerkhofmeijer 0:6fca643f1aff 60 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 61 \endverbatim
tjerkhofmeijer 0:6fca643f1aff 62
tjerkhofmeijer 0:6fca643f1aff 63 I2C:
tjerkhofmeijer 0:6fca643f1aff 64 \verbatim
tjerkhofmeijer 0:6fca643f1aff 65 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 66 | Signal | Nucleo F401 | Mti-1s Dev board header |
tjerkhofmeijer 0:6fca643f1aff 67 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 68 | SCL | PB8 | 11 |
tjerkhofmeijer 0:6fca643f1aff 69 | SDA | PB9 | 9 |
tjerkhofmeijer 0:6fca643f1aff 70 | DRDY | PB3 | 15 |
tjerkhofmeijer 0:6fca643f1aff 71 | ADD0 | PB13 | 17 |
tjerkhofmeijer 0:6fca643f1aff 72 | ADD1 | PB14 | 19 |
tjerkhofmeijer 0:6fca643f1aff 73 | ADD2 | PB15 | 21 |
tjerkhofmeijer 0:6fca643f1aff 74 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 75 \endverbatim
tjerkhofmeijer 0:6fca643f1aff 76
tjerkhofmeijer 0:6fca643f1aff 77 SPI:
tjerkhofmeijer 0:6fca643f1aff 78 \verbatim
tjerkhofmeijer 0:6fca643f1aff 79 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 80 | Signal | Nucleo F401 | Mti-1s Dev board header |
tjerkhofmeijer 0:6fca643f1aff 81 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 82 | SCK | PB13 | 17 |
tjerkhofmeijer 0:6fca643f1aff 83 | MISO | PB14 | 19 |
tjerkhofmeijer 0:6fca643f1aff 84 | MOSI | PB15 | 21 |
tjerkhofmeijer 0:6fca643f1aff 85 | nCS | PB6 | 23 |
tjerkhofmeijer 0:6fca643f1aff 86 | DRDY | PB3 | 15 |
tjerkhofmeijer 0:6fca643f1aff 87 |----------------|---------------|-------------------------|
tjerkhofmeijer 0:6fca643f1aff 88 \endverbatim
tjerkhofmeijer 0:6fca643f1aff 89
tjerkhofmeijer 0:6fca643f1aff 90 \section Connection with host PC
tjerkhofmeijer 0:6fca643f1aff 91 Connect the Nucleo board with a USB cable to the host PC. Find out on which
tjerkhofmeijer 0:6fca643f1aff 92 COM port the Nucleo board is mapped by the OS, and open a terminal emulator (e.g. PuTTY)
tjerkhofmeijer 0:6fca643f1aff 93 on this port. The default baud rate of the example is 921600. Pressing 'h' in the terminal
tjerkhofmeijer 0:6fca643f1aff 94 window should return the following usage text:
tjerkhofmeijer 0:6fca643f1aff 95
tjerkhofmeijer 0:6fca643f1aff 96 \verbatim
tjerkhofmeijer 0:6fca643f1aff 97 Embedded firmware updater example
tjerkhofmeijer 0:6fca643f1aff 98 Interface: SPI
tjerkhofmeijer 0:6fca643f1aff 99
tjerkhofmeijer 0:6fca643f1aff 100 h: Print this text
tjerkhofmeijer 0:6fca643f1aff 101 c: GotoConfig
tjerkhofmeijer 0:6fca643f1aff 102 m: GotoMeasurement
tjerkhofmeijer 0:6fca643f1aff 103 r: Soft reset the module
tjerkhofmeijer 0:6fca643f1aff 104 b: GotoBootloader
tjerkhofmeijer 0:6fca643f1aff 105 v: Request firmware revision
tjerkhofmeijer 0:6fca643f1aff 106 d: Request deviceId
tjerkhofmeijer 0:6fca643f1aff 107 u: Start firmware update (make sure module is in bootloader mode)
tjerkhofmeijer 0:6fca643f1aff 108 x: Hard reset the module and make it stay in bootloader
tjerkhofmeijer 0:6fca643f1aff 109 \endverbatim
tjerkhofmeijer 0:6fca643f1aff 110
tjerkhofmeijer 0:6fca643f1aff 111 After power-up the module automatically goes to measurement mode. In this mode
tjerkhofmeijer 0:6fca643f1aff 112 only a limited set of commands is supported. Therefore, the module must first be
tjerkhofmeijer 0:6fca643f1aff 113 switched to config mode by pressing 'c'. The module should response with XMID_GotoConfigAck.
tjerkhofmeijer 0:6fca643f1aff 114
tjerkhofmeijer 0:6fca643f1aff 115 Next, the firmware revision can be requested by pressing 'v'. This should return
tjerkhofmeijer 0:6fca643f1aff 116 the firmware revision in the format Major.Minor.Patch. If the Major version number is 255, the
tjerkhofmeijer 0:6fca643f1aff 117 module is in bootloader mode. Any other Major version number means that the MTi-1s main firmware is
tjerkhofmeijer 0:6fca643f1aff 118 running. In this case the module must be set in bootloader mode before a firmware update can be done.
tjerkhofmeijer 0:6fca643f1aff 119 The module can be placed in bootloader mode by pressing either the 'b' or 'x' key
tjerkhofmeijer 0:6fca643f1aff 120 */
tjerkhofmeijer 0:6fca643f1aff 121
tjerkhofmeijer 0:6fca643f1aff 122
tjerkhofmeijer 0:6fca643f1aff 123 #include "mbed.h"
tjerkhofmeijer 0:6fca643f1aff 124 #include "rtos.h"
tjerkhofmeijer 0:6fca643f1aff 125 #include "board.h"
tjerkhofmeijer 0:6fca643f1aff 126 #include "xbusmessage.h"
tjerkhofmeijer 0:6fca643f1aff 127 #include "xbusparser.h"
tjerkhofmeijer 0:6fca643f1aff 128 #include "xbusmessageid.h"
tjerkhofmeijer 0:6fca643f1aff 129 #include "mtinterface_mtssp.h"
tjerkhofmeijer 0:6fca643f1aff 130 #include "mtinterface_uart.h"
tjerkhofmeijer 0:6fca643f1aff 131 #include "mtssp_i2c_driver.h"
tjerkhofmeijer 0:6fca643f1aff 132 #include "mtssp_spi_driver.h"
tjerkhofmeijer 0:6fca643f1aff 133 #include "fwupdate.h"
tjerkhofmeijer 0:6fca643f1aff 134 #include "xffdata.h"
tjerkhofmeijer 0:6fca643f1aff 135
tjerkhofmeijer 0:6fca643f1aff 136
tjerkhofmeijer 0:6fca643f1aff 137 /*! \brief Bus mode to use by this example.
tjerkhofmeijer 0:6fca643f1aff 138 */
tjerkhofmeijer 0:6fca643f1aff 139 //#define BUS_MODE_SPI
tjerkhofmeijer 0:6fca643f1aff 140 #define BUS_MODE_I2C
tjerkhofmeijer 0:6fca643f1aff 141 //#define BUS_MODE_UART
tjerkhofmeijer 0:6fca643f1aff 142
tjerkhofmeijer 0:6fca643f1aff 143
tjerkhofmeijer 0:6fca643f1aff 144 /*! \brief Instance of MtInterface. Should be initialized by createMtInterface().
tjerkhofmeijer 0:6fca643f1aff 145 */
tjerkhofmeijer 0:6fca643f1aff 146 static MtInterface* mtInterface = 0;
tjerkhofmeijer 0:6fca643f1aff 147
tjerkhofmeijer 0:6fca643f1aff 148
tjerkhofmeijer 0:6fca643f1aff 149 /*! \brief Serial object for communicating with the PC.
tjerkhofmeijer 0:6fca643f1aff 150 */
tjerkhofmeijer 0:6fca643f1aff 151 static Serial pc(PC_TX, PC_RX);
tjerkhofmeijer 0:6fca643f1aff 152
tjerkhofmeijer 0:6fca643f1aff 153
tjerkhofmeijer 0:6fca643f1aff 154 /*! \brief Reset line towards the module. Pulling this line down keeps the module in reset.
tjerkhofmeijer 0:6fca643f1aff 155 */
tjerkhofmeijer 0:6fca643f1aff 156 static DigitalInOut resetLine(MT_RESET, PIN_INPUT, OpenDrain, 1);
tjerkhofmeijer 0:6fca643f1aff 157
tjerkhofmeijer 0:6fca643f1aff 158 /*! \brief Instance of the firmware updater
tjerkhofmeijer 0:6fca643f1aff 159 */
tjerkhofmeijer 0:6fca643f1aff 160 static FwUpdate *g_fwUpdate = NULL;
tjerkhofmeijer 0:6fca643f1aff 161
tjerkhofmeijer 0:6fca643f1aff 162
tjerkhofmeijer 0:6fca643f1aff 163 /*! \brief Create an instance of MtInterface.
tjerkhofmeijer 0:6fca643f1aff 164 */
tjerkhofmeijer 0:6fca643f1aff 165 static void createMtInterface()
tjerkhofmeijer 0:6fca643f1aff 166 {
tjerkhofmeijer 0:6fca643f1aff 167 #ifdef BUS_MODE_SPI
tjerkhofmeijer 0:6fca643f1aff 168 MtsspDriver* mtsspDriver = new MtsspSpiDriver;
tjerkhofmeijer 0:6fca643f1aff 169 mtInterface = new MtInterfaceMtssp(mtsspDriver);
tjerkhofmeijer 0:6fca643f1aff 170 #endif
tjerkhofmeijer 0:6fca643f1aff 171
tjerkhofmeijer 0:6fca643f1aff 172 #ifdef BUS_MODE_I2C
tjerkhofmeijer 0:6fca643f1aff 173 MtsspDriver* mtsspDriver = new MtsspI2cDriver;
tjerkhofmeijer 0:6fca643f1aff 174 mtInterface = new MtInterfaceMtssp(mtsspDriver);
tjerkhofmeijer 0:6fca643f1aff 175 #endif
tjerkhofmeijer 0:6fca643f1aff 176
tjerkhofmeijer 0:6fca643f1aff 177 #ifdef BUS_MODE_UART
tjerkhofmeijer 0:6fca643f1aff 178 mtInterface = new MtInterfaceUart;
tjerkhofmeijer 0:6fca643f1aff 179 #endif
tjerkhofmeijer 0:6fca643f1aff 180 }
tjerkhofmeijer 0:6fca643f1aff 181
tjerkhofmeijer 0:6fca643f1aff 182
tjerkhofmeijer 0:6fca643f1aff 183 /*! \brief Callback function for FwUpdate for reading data from the xff (xsens firmware file) file.
tjerkhofmeijer 0:6fca643f1aff 184 \param buffer Target buffer in which the xff data should be written
tjerkhofmeijer 0:6fca643f1aff 185 \param offset Offset in the xff file where reading should start
tjerkhofmeijer 0:6fca643f1aff 186 \param length Number of bytes which is requested
tjerkhofmeijer 0:6fca643f1aff 187 \returns Number of bytes which is actually written to the buffer
tjerkhofmeijer 0:6fca643f1aff 188 */
tjerkhofmeijer 0:6fca643f1aff 189 static int readXffData(uint8_t *buffer, int offset, int length)
tjerkhofmeijer 0:6fca643f1aff 190 {
tjerkhofmeijer 0:6fca643f1aff 191 int n;
tjerkhofmeijer 0:6fca643f1aff 192 for (n = 0; n < length; n++)
tjerkhofmeijer 0:6fca643f1aff 193 {
tjerkhofmeijer 0:6fca643f1aff 194 if (offset + n == g_xffData_length)
tjerkhofmeijer 0:6fca643f1aff 195 break;
tjerkhofmeijer 0:6fca643f1aff 196 buffer[n] = g_xffData[offset + n];
tjerkhofmeijer 0:6fca643f1aff 197 }
tjerkhofmeijer 0:6fca643f1aff 198 return n;
tjerkhofmeijer 0:6fca643f1aff 199 }
tjerkhofmeijer 0:6fca643f1aff 200
tjerkhofmeijer 0:6fca643f1aff 201
tjerkhofmeijer 0:6fca643f1aff 202 /*! \brief Callback function for FwUpdate for signaling that a firmware update has completed.
tjerkhofmeijer 0:6fca643f1aff 203 \param result Result of the firmware update, either FWU_Success or FWU_Failed
tjerkhofmeijer 0:6fca643f1aff 204 */
tjerkhofmeijer 0:6fca643f1aff 205 static void readyHandler(FWU_Result result)
tjerkhofmeijer 0:6fca643f1aff 206 {
tjerkhofmeijer 0:6fca643f1aff 207 if (result == FWU_Success)
tjerkhofmeijer 0:6fca643f1aff 208 pc.printf("Firmware update ready\r\n");
tjerkhofmeijer 0:6fca643f1aff 209 else if (result == FWU_Failed)
tjerkhofmeijer 0:6fca643f1aff 210 pc.printf("Firmware update failed\r\n");
tjerkhofmeijer 0:6fca643f1aff 211 }
tjerkhofmeijer 0:6fca643f1aff 212
Xsens 1:7f19a1b1a9df 213 /*! \brief Sends a XMID_GotoConfig message to the Module
Xsens 1:7f19a1b1a9df 214 */
Xsens 1:7f19a1b1a9df 215 static void gotoConfig()
Xsens 1:7f19a1b1a9df 216 {
Xsens 1:7f19a1b1a9df 217 XbusMessage xbusMessage = {XMID_GotoConfig};
Xsens 1:7f19a1b1a9df 218 xbusMessage.m_length = 0;
Xsens 1:7f19a1b1a9df 219 mtInterface->sendXbusMessage(&xbusMessage);
Xsens 1:7f19a1b1a9df 220 }
tjerkhofmeijer 0:6fca643f1aff 221
tjerkhofmeijer 0:6fca643f1aff 222 /*! \brief Handles xbus messages from the module.
tjerkhofmeijer 0:6fca643f1aff 223 \param xbusMessage The xbus message received from the module
tjerkhofmeijer 0:6fca643f1aff 224
tjerkhofmeijer 0:6fca643f1aff 225 Messages with message identifier XMID_FirmwareUpdate are passed to the firmware updater, other messages are just printed.
tjerkhofmeijer 0:6fca643f1aff 226 */
tjerkhofmeijer 0:6fca643f1aff 227 static void handleXbusMessage(XbusMessage *xbusMessage)
tjerkhofmeijer 0:6fca643f1aff 228 {
tjerkhofmeijer 0:6fca643f1aff 229 switch (xbusMessage->m_mid)
tjerkhofmeijer 0:6fca643f1aff 230 {
tjerkhofmeijer 0:6fca643f1aff 231 case XMID_Wakeup:
tjerkhofmeijer 0:6fca643f1aff 232 {
Xsens 1:7f19a1b1a9df 233 //If the wakeup message is received we force the module in config mode
Xsens 1:7f19a1b1a9df 234 gotoConfig();
tjerkhofmeijer 0:6fca643f1aff 235 pc.printf("XMID_Wakeup\r\n");
tjerkhofmeijer 0:6fca643f1aff 236 } break;
tjerkhofmeijer 0:6fca643f1aff 237
tjerkhofmeijer 0:6fca643f1aff 238 case XMID_GotoConfigAck:
tjerkhofmeijer 0:6fca643f1aff 239 {
tjerkhofmeijer 0:6fca643f1aff 240 pc.printf("XMID_GotoConfigAck\r\n");
tjerkhofmeijer 0:6fca643f1aff 241 } break;
tjerkhofmeijer 0:6fca643f1aff 242
tjerkhofmeijer 0:6fca643f1aff 243 case XMID_GotoMeasurementAck:
tjerkhofmeijer 0:6fca643f1aff 244 {
tjerkhofmeijer 0:6fca643f1aff 245 pc.printf("XMID_GotoMeasurementAck\r\n");
tjerkhofmeijer 0:6fca643f1aff 246 } break;
tjerkhofmeijer 0:6fca643f1aff 247
tjerkhofmeijer 0:6fca643f1aff 248 case XMID_ResetAck:
tjerkhofmeijer 0:6fca643f1aff 249 {
tjerkhofmeijer 0:6fca643f1aff 250 pc.printf("XMID_ResetAck\r\n");
tjerkhofmeijer 0:6fca643f1aff 251 } break;
tjerkhofmeijer 0:6fca643f1aff 252
tjerkhofmeijer 0:6fca643f1aff 253 case XMID_GotoBootLoaderAck:
tjerkhofmeijer 0:6fca643f1aff 254 {
tjerkhofmeijer 0:6fca643f1aff 255 pc.printf("XMID_GotoBootLoaderAck\r\n");
tjerkhofmeijer 0:6fca643f1aff 256 } break;
tjerkhofmeijer 0:6fca643f1aff 257
tjerkhofmeijer 0:6fca643f1aff 258 case XMID_Error:
tjerkhofmeijer 0:6fca643f1aff 259 {
tjerkhofmeijer 0:6fca643f1aff 260 pc.printf("XMID_Error\r\n");
tjerkhofmeijer 0:6fca643f1aff 261 } break;
tjerkhofmeijer 0:6fca643f1aff 262
tjerkhofmeijer 0:6fca643f1aff 263 case XMID_FirmwareUpdate:
tjerkhofmeijer 0:6fca643f1aff 264 {
tjerkhofmeijer 0:6fca643f1aff 265 if (g_fwUpdate != NULL)
tjerkhofmeijer 0:6fca643f1aff 266 {
tjerkhofmeijer 0:6fca643f1aff 267 FwUpdate_handleXbus(g_fwUpdate, xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 268 }
tjerkhofmeijer 0:6fca643f1aff 269 } break;
tjerkhofmeijer 0:6fca643f1aff 270
tjerkhofmeijer 0:6fca643f1aff 271 case XMID_FirmwareRevision:
tjerkhofmeijer 0:6fca643f1aff 272 {
tjerkhofmeijer 0:6fca643f1aff 273 pc.printf("XMID_FirmwareRevision: %d.%d.%d\r\n", xbusMessage->m_data[0], xbusMessage->m_data[1], xbusMessage->m_data[2]);
tjerkhofmeijer 0:6fca643f1aff 274 } break;
tjerkhofmeijer 0:6fca643f1aff 275
tjerkhofmeijer 0:6fca643f1aff 276 case XMID_DeviceId:
tjerkhofmeijer 0:6fca643f1aff 277 {
tjerkhofmeijer 0:6fca643f1aff 278 uint32_t deviceId = (xbusMessage->m_data[0] << 24) | (xbusMessage->m_data[1] << 16) | (xbusMessage->m_data[2] << 8) | xbusMessage->m_data[3];
tjerkhofmeijer 0:6fca643f1aff 279 pc.printf("XMID_DeviceId: %08X\r\n", deviceId);
tjerkhofmeijer 0:6fca643f1aff 280 } break;
tjerkhofmeijer 0:6fca643f1aff 281
tjerkhofmeijer 0:6fca643f1aff 282 case XMID_MtData2:
tjerkhofmeijer 0:6fca643f1aff 283 {
tjerkhofmeijer 0:6fca643f1aff 284 pc.printf("XMID_MtData2\r\n");
tjerkhofmeijer 0:6fca643f1aff 285 } break;
tjerkhofmeijer 0:6fca643f1aff 286
tjerkhofmeijer 0:6fca643f1aff 287 default:
tjerkhofmeijer 0:6fca643f1aff 288 {
tjerkhofmeijer 0:6fca643f1aff 289 pc.printf("Unhandled xbus message, mid = 0x%02X, len = %d", xbusMessage->m_mid, xbusMessage->m_length);
tjerkhofmeijer 0:6fca643f1aff 290 if (xbusMessage->m_length > 0)
tjerkhofmeijer 0:6fca643f1aff 291 {
tjerkhofmeijer 0:6fca643f1aff 292 pc.printf(", data = ");
tjerkhofmeijer 0:6fca643f1aff 293 for (int n = 0; n < xbusMessage->m_length; n++)
tjerkhofmeijer 0:6fca643f1aff 294 {
tjerkhofmeijer 0:6fca643f1aff 295 pc.printf("%02X ", xbusMessage->m_data[n]);
tjerkhofmeijer 0:6fca643f1aff 296 }
tjerkhofmeijer 0:6fca643f1aff 297 }
tjerkhofmeijer 0:6fca643f1aff 298 pc.printf("\r\n");
tjerkhofmeijer 0:6fca643f1aff 299 }
tjerkhofmeijer 0:6fca643f1aff 300 }
tjerkhofmeijer 0:6fca643f1aff 301 }
tjerkhofmeijer 0:6fca643f1aff 302
tjerkhofmeijer 0:6fca643f1aff 303
tjerkhofmeijer 0:6fca643f1aff 304 /*! \brief Reset the module via the hardware reset line.
tjerkhofmeijer 0:6fca643f1aff 305 \param stayInBootloader: If stayInBootloader is true, an XMID_GotoBootLoader is sent immediately after the reset.
tjerkhofmeijer 0:6fca643f1aff 306
tjerkhofmeijer 0:6fca643f1aff 307 By sending an XMID_GotoBootLoader within 100 ms after reset the module stays in bootloader mode
tjerkhofmeijer 0:6fca643f1aff 308 instead of booting the application. This can be used if the normal GotoBootloader command fails to put
tjerkhofmeijer 0:6fca643f1aff 309 the module in bootloader mode, e.g. because of a faulty firmware.
tjerkhofmeijer 0:6fca643f1aff 310 */
tjerkhofmeijer 0:6fca643f1aff 311 static void hardwareReset(bool stayInBootloader)
tjerkhofmeijer 0:6fca643f1aff 312 {
tjerkhofmeijer 0:6fca643f1aff 313 resetLine = 1;
tjerkhofmeijer 0:6fca643f1aff 314 resetLine.output();
tjerkhofmeijer 0:6fca643f1aff 315 wait(0.001);
tjerkhofmeijer 0:6fca643f1aff 316 resetLine = 0;
tjerkhofmeijer 0:6fca643f1aff 317 wait(0.001);
tjerkhofmeijer 0:6fca643f1aff 318 resetLine.input(); // (configure the line as input because the OpenDrain setting of the mbed gpio pin does not seem to work correctly)
tjerkhofmeijer 0:6fca643f1aff 319
tjerkhofmeijer 0:6fca643f1aff 320 if (stayInBootloader)
tjerkhofmeijer 0:6fca643f1aff 321 {
tjerkhofmeijer 0:6fca643f1aff 322 wait(0.02);
tjerkhofmeijer 0:6fca643f1aff 323 XbusMessage xbusMessage = {XMID_GotoBootLoader};
tjerkhofmeijer 0:6fca643f1aff 324 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 325 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 326 } else
tjerkhofmeijer 0:6fca643f1aff 327 {
tjerkhofmeijer 0:6fca643f1aff 328 wait(0.2);
tjerkhofmeijer 0:6fca643f1aff 329 }
tjerkhofmeijer 0:6fca643f1aff 330 }
tjerkhofmeijer 0:6fca643f1aff 331
tjerkhofmeijer 0:6fca643f1aff 332 /*! \brief C-wrapper for sendXbusMessage callback function of FwUpdate.
tjerkhofmeijer 0:6fca643f1aff 333 */
tjerkhofmeijer 0:6fca643f1aff 334 static void sendXbusMessageWrapper(XbusMessage const* xbusMessage)
tjerkhofmeijer 0:6fca643f1aff 335 {
tjerkhofmeijer 0:6fca643f1aff 336 if (mtInterface)
tjerkhofmeijer 0:6fca643f1aff 337 mtInterface->sendXbusMessage(xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 338 }
tjerkhofmeijer 0:6fca643f1aff 339
tjerkhofmeijer 0:6fca643f1aff 340
tjerkhofmeijer 0:6fca643f1aff 341 /*! \brief Helper function for converting a XbusLowLevelFormat to string.
tjerkhofmeijer 0:6fca643f1aff 342 */
tjerkhofmeijer 0:6fca643f1aff 343 static char* lowLevelFormatToString(XbusBusFormat format)
tjerkhofmeijer 0:6fca643f1aff 344 {
tjerkhofmeijer 0:6fca643f1aff 345 switch (format)
tjerkhofmeijer 0:6fca643f1aff 346 {
tjerkhofmeijer 0:6fca643f1aff 347 case XBF_I2c:
tjerkhofmeijer 0:6fca643f1aff 348 return "I2C";
tjerkhofmeijer 0:6fca643f1aff 349 case XBF_Spi:
tjerkhofmeijer 0:6fca643f1aff 350 return "SPI";
tjerkhofmeijer 0:6fca643f1aff 351 case XBF_Uart:
tjerkhofmeijer 0:6fca643f1aff 352 return "UART";
tjerkhofmeijer 0:6fca643f1aff 353 }
tjerkhofmeijer 0:6fca643f1aff 354 return "unknown";
tjerkhofmeijer 0:6fca643f1aff 355 }
tjerkhofmeijer 0:6fca643f1aff 356
tjerkhofmeijer 0:6fca643f1aff 357
tjerkhofmeijer 0:6fca643f1aff 358 /*! \brief Print usage info of this example.
tjerkhofmeijer 0:6fca643f1aff 359 */
tjerkhofmeijer 0:6fca643f1aff 360 static void printUsageInfo()
tjerkhofmeijer 0:6fca643f1aff 361 {
tjerkhofmeijer 0:6fca643f1aff 362 pc.printf("\r\nEmbedded firmware updater example\r\n");
tjerkhofmeijer 0:6fca643f1aff 363 pc.printf("Interface: %s\r\n\r\n", lowLevelFormatToString(mtInterface->busFormat()));
tjerkhofmeijer 0:6fca643f1aff 364 pc.printf("h: Print this text\r\n");
tjerkhofmeijer 0:6fca643f1aff 365 pc.printf("c: GotoConfig\r\n");
tjerkhofmeijer 0:6fca643f1aff 366 pc.printf("m: GotoMeasurement\r\n");
tjerkhofmeijer 0:6fca643f1aff 367 pc.printf("r: Soft reset the module\r\n");
tjerkhofmeijer 0:6fca643f1aff 368 pc.printf("b: GotoBootloader\r\n");
tjerkhofmeijer 0:6fca643f1aff 369 pc.printf("v: Request firmware revision\r\n");
tjerkhofmeijer 0:6fca643f1aff 370 pc.printf("d: Request deviceId\r\n");
tjerkhofmeijer 0:6fca643f1aff 371 pc.printf("u: Start firmware update (make sure module is in bootloader mode)\r\n");
tjerkhofmeijer 0:6fca643f1aff 372 pc.printf("x: Hard reset the module and make it stay in bootloader\r\n");
tjerkhofmeijer 0:6fca643f1aff 373 pc.printf("\r\n");
tjerkhofmeijer 0:6fca643f1aff 374 }
tjerkhofmeijer 0:6fca643f1aff 375
tjerkhofmeijer 0:6fca643f1aff 376 /*! \brief Main entry point of the embedded firmware updater example.
tjerkhofmeijer 0:6fca643f1aff 377 */
tjerkhofmeijer 0:6fca643f1aff 378 int main()
tjerkhofmeijer 0:6fca643f1aff 379 {
tjerkhofmeijer 0:6fca643f1aff 380 resetLine.mode(OpenDrain);
tjerkhofmeijer 0:6fca643f1aff 381 // Configure communication with the pc:
tjerkhofmeijer 0:6fca643f1aff 382 pc.baud(921600);
tjerkhofmeijer 0:6fca643f1aff 383 pc.format(8, Serial::None, 1);
tjerkhofmeijer 0:6fca643f1aff 384 pc.printf("\r\n\r\n\r\n--------------------------------------\r\n");
tjerkhofmeijer 0:6fca643f1aff 385
tjerkhofmeijer 0:6fca643f1aff 386 // Initialize the mtInterface object for communicating with the module:
tjerkhofmeijer 0:6fca643f1aff 387 createMtInterface();
tjerkhofmeijer 0:6fca643f1aff 388
tjerkhofmeijer 0:6fca643f1aff 389 // Reset the module
tjerkhofmeijer 0:6fca643f1aff 390 hardwareReset(false);
tjerkhofmeijer 0:6fca643f1aff 391
tjerkhofmeijer 0:6fca643f1aff 392 // Initialize the firmware updater:
tjerkhofmeijer 0:6fca643f1aff 393 g_fwUpdate = new FwUpdate();
tjerkhofmeijer 0:6fca643f1aff 394 uint8_t* fwuTxBuffer = new uint8_t[FWU_REQUIRED_TXBUFFER_SIZE];
tjerkhofmeijer 0:6fca643f1aff 395 g_fwUpdate->m_readXffData = readXffData;
tjerkhofmeijer 0:6fca643f1aff 396 g_fwUpdate->m_sendXbusMessage = sendXbusMessageWrapper;
tjerkhofmeijer 0:6fca643f1aff 397 g_fwUpdate->m_readyHandler = readyHandler;
tjerkhofmeijer 0:6fca643f1aff 398 g_fwUpdate->m_txBuffer = fwuTxBuffer;
tjerkhofmeijer 0:6fca643f1aff 399 FwUpdate_init(g_fwUpdate);
tjerkhofmeijer 0:6fca643f1aff 400
tjerkhofmeijer 0:6fca643f1aff 401 printUsageInfo();
tjerkhofmeijer 0:6fca643f1aff 402
tjerkhofmeijer 0:6fca643f1aff 403 // Main loop:
tjerkhofmeijer 0:6fca643f1aff 404 bool running = true;
tjerkhofmeijer 0:6fca643f1aff 405 while (running)
tjerkhofmeijer 0:6fca643f1aff 406 {
tjerkhofmeijer 0:6fca643f1aff 407 mtInterface->process();
tjerkhofmeijer 0:6fca643f1aff 408
tjerkhofmeijer 0:6fca643f1aff 409 XbusMessage* xbusMessage = mtInterface->getXbusMessage();
tjerkhofmeijer 0:6fca643f1aff 410 if (xbusMessage != NULL)
tjerkhofmeijer 0:6fca643f1aff 411 {
tjerkhofmeijer 0:6fca643f1aff 412 handleXbusMessage(xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 413 mtInterface->releaseXbusMessage(xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 414 }
tjerkhofmeijer 0:6fca643f1aff 415
tjerkhofmeijer 0:6fca643f1aff 416 if (pc.readable())
tjerkhofmeijer 0:6fca643f1aff 417 {
tjerkhofmeijer 0:6fca643f1aff 418 char cmd = pc.getc();
tjerkhofmeijer 0:6fca643f1aff 419 switch (cmd)
tjerkhofmeijer 0:6fca643f1aff 420 {
tjerkhofmeijer 0:6fca643f1aff 421 case 'h':
tjerkhofmeijer 0:6fca643f1aff 422 {
tjerkhofmeijer 0:6fca643f1aff 423 printUsageInfo();
tjerkhofmeijer 0:6fca643f1aff 424 } break;
tjerkhofmeijer 0:6fca643f1aff 425
tjerkhofmeijer 0:6fca643f1aff 426 case 'c':
tjerkhofmeijer 0:6fca643f1aff 427 {
Xsens 1:7f19a1b1a9df 428 gotoConfig();
tjerkhofmeijer 0:6fca643f1aff 429 } break;
tjerkhofmeijer 0:6fca643f1aff 430
tjerkhofmeijer 0:6fca643f1aff 431 case 'm':
tjerkhofmeijer 0:6fca643f1aff 432 {
tjerkhofmeijer 0:6fca643f1aff 433 XbusMessage xbusMessage = {XMID_GotoMeasurement};
tjerkhofmeijer 0:6fca643f1aff 434 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 435 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 436 } break;
tjerkhofmeijer 0:6fca643f1aff 437
tjerkhofmeijer 0:6fca643f1aff 438 case 'r':
tjerkhofmeijer 0:6fca643f1aff 439 {
tjerkhofmeijer 0:6fca643f1aff 440 XbusMessage xbusMessage = {XMID_Reset};
tjerkhofmeijer 0:6fca643f1aff 441 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 442 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 443 } break;
tjerkhofmeijer 0:6fca643f1aff 444
tjerkhofmeijer 0:6fca643f1aff 445 case 'b':
tjerkhofmeijer 0:6fca643f1aff 446 {
tjerkhofmeijer 0:6fca643f1aff 447 XbusMessage xbusMessage = {XMID_GotoBootLoader};
tjerkhofmeijer 0:6fca643f1aff 448 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 449 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 450 } break;
tjerkhofmeijer 0:6fca643f1aff 451
tjerkhofmeijer 0:6fca643f1aff 452 case 'v':
tjerkhofmeijer 0:6fca643f1aff 453 {
tjerkhofmeijer 0:6fca643f1aff 454 XbusMessage xbusMessage = {XMID_ReqFirmwareRevision};
tjerkhofmeijer 0:6fca643f1aff 455 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 456 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 457 } break;
tjerkhofmeijer 0:6fca643f1aff 458
tjerkhofmeijer 0:6fca643f1aff 459 case 'd':
tjerkhofmeijer 0:6fca643f1aff 460 {
tjerkhofmeijer 0:6fca643f1aff 461 XbusMessage xbusMessage = {XMID_ReqDid};
tjerkhofmeijer 0:6fca643f1aff 462 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 463 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 464 } break;
tjerkhofmeijer 0:6fca643f1aff 465
tjerkhofmeijer 0:6fca643f1aff 466 case 'u':
tjerkhofmeijer 0:6fca643f1aff 467 {
tjerkhofmeijer 0:6fca643f1aff 468 pc.printf("Starting firmware update\r\n");
tjerkhofmeijer 0:6fca643f1aff 469 FwUpdate_init(g_fwUpdate);
tjerkhofmeijer 0:6fca643f1aff 470 FwUpdate_start(g_fwUpdate);
tjerkhofmeijer 0:6fca643f1aff 471 } break;
tjerkhofmeijer 0:6fca643f1aff 472
tjerkhofmeijer 0:6fca643f1aff 473 case 'x':
tjerkhofmeijer 0:6fca643f1aff 474 {
tjerkhofmeijer 0:6fca643f1aff 475 hardwareReset(true);
tjerkhofmeijer 0:6fca643f1aff 476 } break;
tjerkhofmeijer 0:6fca643f1aff 477 }
tjerkhofmeijer 0:6fca643f1aff 478 }
tjerkhofmeijer 0:6fca643f1aff 479 }
tjerkhofmeijer 0:6fca643f1aff 480
tjerkhofmeijer 0:6fca643f1aff 481 delete g_fwUpdate;
tjerkhofmeijer 0:6fca643f1aff 482 delete[] fwuTxBuffer;
tjerkhofmeijer 0:6fca643f1aff 483 return -1;
tjerkhofmeijer 0:6fca643f1aff 484 }
tjerkhofmeijer 0:6fca643f1aff 485