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:
tjerkhofmeijer
Date:
Tue Nov 24 13:35:07 2015 +0100
Revision:
0:6fca643f1aff
Child:
1:7f19a1b1a9df
Initial publication of embedded firmware updater example

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
tjerkhofmeijer 0:6fca643f1aff 213
tjerkhofmeijer 0:6fca643f1aff 214 /*! \brief Handles xbus messages from the module.
tjerkhofmeijer 0:6fca643f1aff 215 \param xbusMessage The xbus message received from the module
tjerkhofmeijer 0:6fca643f1aff 216
tjerkhofmeijer 0:6fca643f1aff 217 Messages with message identifier XMID_FirmwareUpdate are passed to the firmware updater, other messages are just printed.
tjerkhofmeijer 0:6fca643f1aff 218 */
tjerkhofmeijer 0:6fca643f1aff 219 static void handleXbusMessage(XbusMessage *xbusMessage)
tjerkhofmeijer 0:6fca643f1aff 220 {
tjerkhofmeijer 0:6fca643f1aff 221 switch (xbusMessage->m_mid)
tjerkhofmeijer 0:6fca643f1aff 222 {
tjerkhofmeijer 0:6fca643f1aff 223 case XMID_Wakeup:
tjerkhofmeijer 0:6fca643f1aff 224 {
tjerkhofmeijer 0:6fca643f1aff 225 pc.printf("XMID_Wakeup\r\n");
tjerkhofmeijer 0:6fca643f1aff 226 } break;
tjerkhofmeijer 0:6fca643f1aff 227
tjerkhofmeijer 0:6fca643f1aff 228 case XMID_GotoConfigAck:
tjerkhofmeijer 0:6fca643f1aff 229 {
tjerkhofmeijer 0:6fca643f1aff 230 pc.printf("XMID_GotoConfigAck\r\n");
tjerkhofmeijer 0:6fca643f1aff 231 } break;
tjerkhofmeijer 0:6fca643f1aff 232
tjerkhofmeijer 0:6fca643f1aff 233 case XMID_GotoMeasurementAck:
tjerkhofmeijer 0:6fca643f1aff 234 {
tjerkhofmeijer 0:6fca643f1aff 235 pc.printf("XMID_GotoMeasurementAck\r\n");
tjerkhofmeijer 0:6fca643f1aff 236 } break;
tjerkhofmeijer 0:6fca643f1aff 237
tjerkhofmeijer 0:6fca643f1aff 238 case XMID_ResetAck:
tjerkhofmeijer 0:6fca643f1aff 239 {
tjerkhofmeijer 0:6fca643f1aff 240 pc.printf("XMID_ResetAck\r\n");
tjerkhofmeijer 0:6fca643f1aff 241 } break;
tjerkhofmeijer 0:6fca643f1aff 242
tjerkhofmeijer 0:6fca643f1aff 243 case XMID_GotoBootLoaderAck:
tjerkhofmeijer 0:6fca643f1aff 244 {
tjerkhofmeijer 0:6fca643f1aff 245 pc.printf("XMID_GotoBootLoaderAck\r\n");
tjerkhofmeijer 0:6fca643f1aff 246 } break;
tjerkhofmeijer 0:6fca643f1aff 247
tjerkhofmeijer 0:6fca643f1aff 248 case XMID_Error:
tjerkhofmeijer 0:6fca643f1aff 249 {
tjerkhofmeijer 0:6fca643f1aff 250 pc.printf("XMID_Error\r\n");
tjerkhofmeijer 0:6fca643f1aff 251 } break;
tjerkhofmeijer 0:6fca643f1aff 252
tjerkhofmeijer 0:6fca643f1aff 253 case XMID_FirmwareUpdate:
tjerkhofmeijer 0:6fca643f1aff 254 {
tjerkhofmeijer 0:6fca643f1aff 255 if (g_fwUpdate != NULL)
tjerkhofmeijer 0:6fca643f1aff 256 {
tjerkhofmeijer 0:6fca643f1aff 257 FwUpdate_handleXbus(g_fwUpdate, xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 258 }
tjerkhofmeijer 0:6fca643f1aff 259 } break;
tjerkhofmeijer 0:6fca643f1aff 260
tjerkhofmeijer 0:6fca643f1aff 261 case XMID_FirmwareRevision:
tjerkhofmeijer 0:6fca643f1aff 262 {
tjerkhofmeijer 0:6fca643f1aff 263 pc.printf("XMID_FirmwareRevision: %d.%d.%d\r\n", xbusMessage->m_data[0], xbusMessage->m_data[1], xbusMessage->m_data[2]);
tjerkhofmeijer 0:6fca643f1aff 264 } break;
tjerkhofmeijer 0:6fca643f1aff 265
tjerkhofmeijer 0:6fca643f1aff 266 case XMID_DeviceId:
tjerkhofmeijer 0:6fca643f1aff 267 {
tjerkhofmeijer 0:6fca643f1aff 268 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 269 pc.printf("XMID_DeviceId: %08X\r\n", deviceId);
tjerkhofmeijer 0:6fca643f1aff 270 } break;
tjerkhofmeijer 0:6fca643f1aff 271
tjerkhofmeijer 0:6fca643f1aff 272 case XMID_MtData2:
tjerkhofmeijer 0:6fca643f1aff 273 {
tjerkhofmeijer 0:6fca643f1aff 274 pc.printf("XMID_MtData2\r\n");
tjerkhofmeijer 0:6fca643f1aff 275 } break;
tjerkhofmeijer 0:6fca643f1aff 276
tjerkhofmeijer 0:6fca643f1aff 277 default:
tjerkhofmeijer 0:6fca643f1aff 278 {
tjerkhofmeijer 0:6fca643f1aff 279 pc.printf("Unhandled xbus message, mid = 0x%02X, len = %d", xbusMessage->m_mid, xbusMessage->m_length);
tjerkhofmeijer 0:6fca643f1aff 280 if (xbusMessage->m_length > 0)
tjerkhofmeijer 0:6fca643f1aff 281 {
tjerkhofmeijer 0:6fca643f1aff 282 pc.printf(", data = ");
tjerkhofmeijer 0:6fca643f1aff 283 for (int n = 0; n < xbusMessage->m_length; n++)
tjerkhofmeijer 0:6fca643f1aff 284 {
tjerkhofmeijer 0:6fca643f1aff 285 pc.printf("%02X ", xbusMessage->m_data[n]);
tjerkhofmeijer 0:6fca643f1aff 286 }
tjerkhofmeijer 0:6fca643f1aff 287 }
tjerkhofmeijer 0:6fca643f1aff 288 pc.printf("\r\n");
tjerkhofmeijer 0:6fca643f1aff 289 }
tjerkhofmeijer 0:6fca643f1aff 290 }
tjerkhofmeijer 0:6fca643f1aff 291 }
tjerkhofmeijer 0:6fca643f1aff 292
tjerkhofmeijer 0:6fca643f1aff 293
tjerkhofmeijer 0:6fca643f1aff 294 /*! \brief Reset the module via the hardware reset line.
tjerkhofmeijer 0:6fca643f1aff 295 \param stayInBootloader: If stayInBootloader is true, an XMID_GotoBootLoader is sent immediately after the reset.
tjerkhofmeijer 0:6fca643f1aff 296
tjerkhofmeijer 0:6fca643f1aff 297 By sending an XMID_GotoBootLoader within 100 ms after reset the module stays in bootloader mode
tjerkhofmeijer 0:6fca643f1aff 298 instead of booting the application. This can be used if the normal GotoBootloader command fails to put
tjerkhofmeijer 0:6fca643f1aff 299 the module in bootloader mode, e.g. because of a faulty firmware.
tjerkhofmeijer 0:6fca643f1aff 300 */
tjerkhofmeijer 0:6fca643f1aff 301 static void hardwareReset(bool stayInBootloader)
tjerkhofmeijer 0:6fca643f1aff 302 {
tjerkhofmeijer 0:6fca643f1aff 303 resetLine = 1;
tjerkhofmeijer 0:6fca643f1aff 304 resetLine.output();
tjerkhofmeijer 0:6fca643f1aff 305 wait(0.001);
tjerkhofmeijer 0:6fca643f1aff 306 resetLine = 0;
tjerkhofmeijer 0:6fca643f1aff 307 wait(0.001);
tjerkhofmeijer 0:6fca643f1aff 308 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 309
tjerkhofmeijer 0:6fca643f1aff 310 if (stayInBootloader)
tjerkhofmeijer 0:6fca643f1aff 311 {
tjerkhofmeijer 0:6fca643f1aff 312 wait(0.02);
tjerkhofmeijer 0:6fca643f1aff 313 XbusMessage xbusMessage = {XMID_GotoBootLoader};
tjerkhofmeijer 0:6fca643f1aff 314 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 315 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 316 } else
tjerkhofmeijer 0:6fca643f1aff 317 {
tjerkhofmeijer 0:6fca643f1aff 318 wait(0.2);
tjerkhofmeijer 0:6fca643f1aff 319 }
tjerkhofmeijer 0:6fca643f1aff 320 }
tjerkhofmeijer 0:6fca643f1aff 321
tjerkhofmeijer 0:6fca643f1aff 322 /*! \brief C-wrapper for sendXbusMessage callback function of FwUpdate.
tjerkhofmeijer 0:6fca643f1aff 323 */
tjerkhofmeijer 0:6fca643f1aff 324 static void sendXbusMessageWrapper(XbusMessage const* xbusMessage)
tjerkhofmeijer 0:6fca643f1aff 325 {
tjerkhofmeijer 0:6fca643f1aff 326 if (mtInterface)
tjerkhofmeijer 0:6fca643f1aff 327 mtInterface->sendXbusMessage(xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 328 }
tjerkhofmeijer 0:6fca643f1aff 329
tjerkhofmeijer 0:6fca643f1aff 330
tjerkhofmeijer 0:6fca643f1aff 331 /*! \brief Helper function for converting a XbusLowLevelFormat to string.
tjerkhofmeijer 0:6fca643f1aff 332 */
tjerkhofmeijer 0:6fca643f1aff 333 static char* lowLevelFormatToString(XbusBusFormat format)
tjerkhofmeijer 0:6fca643f1aff 334 {
tjerkhofmeijer 0:6fca643f1aff 335 switch (format)
tjerkhofmeijer 0:6fca643f1aff 336 {
tjerkhofmeijer 0:6fca643f1aff 337 case XBF_I2c:
tjerkhofmeijer 0:6fca643f1aff 338 return "I2C";
tjerkhofmeijer 0:6fca643f1aff 339 case XBF_Spi:
tjerkhofmeijer 0:6fca643f1aff 340 return "SPI";
tjerkhofmeijer 0:6fca643f1aff 341 case XBF_Uart:
tjerkhofmeijer 0:6fca643f1aff 342 return "UART";
tjerkhofmeijer 0:6fca643f1aff 343 }
tjerkhofmeijer 0:6fca643f1aff 344 return "unknown";
tjerkhofmeijer 0:6fca643f1aff 345 }
tjerkhofmeijer 0:6fca643f1aff 346
tjerkhofmeijer 0:6fca643f1aff 347
tjerkhofmeijer 0:6fca643f1aff 348 /*! \brief Print usage info of this example.
tjerkhofmeijer 0:6fca643f1aff 349 */
tjerkhofmeijer 0:6fca643f1aff 350 static void printUsageInfo()
tjerkhofmeijer 0:6fca643f1aff 351 {
tjerkhofmeijer 0:6fca643f1aff 352 pc.printf("\r\nEmbedded firmware updater example\r\n");
tjerkhofmeijer 0:6fca643f1aff 353 pc.printf("Interface: %s\r\n\r\n", lowLevelFormatToString(mtInterface->busFormat()));
tjerkhofmeijer 0:6fca643f1aff 354 pc.printf("h: Print this text\r\n");
tjerkhofmeijer 0:6fca643f1aff 355 pc.printf("c: GotoConfig\r\n");
tjerkhofmeijer 0:6fca643f1aff 356 pc.printf("m: GotoMeasurement\r\n");
tjerkhofmeijer 0:6fca643f1aff 357 pc.printf("r: Soft reset the module\r\n");
tjerkhofmeijer 0:6fca643f1aff 358 pc.printf("b: GotoBootloader\r\n");
tjerkhofmeijer 0:6fca643f1aff 359 pc.printf("v: Request firmware revision\r\n");
tjerkhofmeijer 0:6fca643f1aff 360 pc.printf("d: Request deviceId\r\n");
tjerkhofmeijer 0:6fca643f1aff 361 pc.printf("u: Start firmware update (make sure module is in bootloader mode)\r\n");
tjerkhofmeijer 0:6fca643f1aff 362 pc.printf("x: Hard reset the module and make it stay in bootloader\r\n");
tjerkhofmeijer 0:6fca643f1aff 363 pc.printf("\r\n");
tjerkhofmeijer 0:6fca643f1aff 364 }
tjerkhofmeijer 0:6fca643f1aff 365
tjerkhofmeijer 0:6fca643f1aff 366 /*! \brief Main entry point of the embedded firmware updater example.
tjerkhofmeijer 0:6fca643f1aff 367 */
tjerkhofmeijer 0:6fca643f1aff 368 int main()
tjerkhofmeijer 0:6fca643f1aff 369 {
tjerkhofmeijer 0:6fca643f1aff 370 resetLine.mode(OpenDrain);
tjerkhofmeijer 0:6fca643f1aff 371 // Configure communication with the pc:
tjerkhofmeijer 0:6fca643f1aff 372 pc.baud(921600);
tjerkhofmeijer 0:6fca643f1aff 373 pc.format(8, Serial::None, 1);
tjerkhofmeijer 0:6fca643f1aff 374 pc.printf("\r\n\r\n\r\n--------------------------------------\r\n");
tjerkhofmeijer 0:6fca643f1aff 375
tjerkhofmeijer 0:6fca643f1aff 376 // Initialize the mtInterface object for communicating with the module:
tjerkhofmeijer 0:6fca643f1aff 377 createMtInterface();
tjerkhofmeijer 0:6fca643f1aff 378
tjerkhofmeijer 0:6fca643f1aff 379 // Reset the module
tjerkhofmeijer 0:6fca643f1aff 380 hardwareReset(false);
tjerkhofmeijer 0:6fca643f1aff 381
tjerkhofmeijer 0:6fca643f1aff 382 // Initialize the firmware updater:
tjerkhofmeijer 0:6fca643f1aff 383 g_fwUpdate = new FwUpdate();
tjerkhofmeijer 0:6fca643f1aff 384 uint8_t* fwuTxBuffer = new uint8_t[FWU_REQUIRED_TXBUFFER_SIZE];
tjerkhofmeijer 0:6fca643f1aff 385 g_fwUpdate->m_readXffData = readXffData;
tjerkhofmeijer 0:6fca643f1aff 386 g_fwUpdate->m_sendXbusMessage = sendXbusMessageWrapper;
tjerkhofmeijer 0:6fca643f1aff 387 g_fwUpdate->m_readyHandler = readyHandler;
tjerkhofmeijer 0:6fca643f1aff 388 g_fwUpdate->m_txBuffer = fwuTxBuffer;
tjerkhofmeijer 0:6fca643f1aff 389 FwUpdate_init(g_fwUpdate);
tjerkhofmeijer 0:6fca643f1aff 390
tjerkhofmeijer 0:6fca643f1aff 391 printUsageInfo();
tjerkhofmeijer 0:6fca643f1aff 392
tjerkhofmeijer 0:6fca643f1aff 393 // Main loop:
tjerkhofmeijer 0:6fca643f1aff 394 bool running = true;
tjerkhofmeijer 0:6fca643f1aff 395 while (running)
tjerkhofmeijer 0:6fca643f1aff 396 {
tjerkhofmeijer 0:6fca643f1aff 397 mtInterface->process();
tjerkhofmeijer 0:6fca643f1aff 398
tjerkhofmeijer 0:6fca643f1aff 399 XbusMessage* xbusMessage = mtInterface->getXbusMessage();
tjerkhofmeijer 0:6fca643f1aff 400 if (xbusMessage != NULL)
tjerkhofmeijer 0:6fca643f1aff 401 {
tjerkhofmeijer 0:6fca643f1aff 402 handleXbusMessage(xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 403 mtInterface->releaseXbusMessage(xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 404 }
tjerkhofmeijer 0:6fca643f1aff 405
tjerkhofmeijer 0:6fca643f1aff 406 if (pc.readable())
tjerkhofmeijer 0:6fca643f1aff 407 {
tjerkhofmeijer 0:6fca643f1aff 408 char cmd = pc.getc();
tjerkhofmeijer 0:6fca643f1aff 409 switch (cmd)
tjerkhofmeijer 0:6fca643f1aff 410 {
tjerkhofmeijer 0:6fca643f1aff 411 case 'h':
tjerkhofmeijer 0:6fca643f1aff 412 {
tjerkhofmeijer 0:6fca643f1aff 413 printUsageInfo();
tjerkhofmeijer 0:6fca643f1aff 414 } break;
tjerkhofmeijer 0:6fca643f1aff 415
tjerkhofmeijer 0:6fca643f1aff 416 case 'c':
tjerkhofmeijer 0:6fca643f1aff 417 {
tjerkhofmeijer 0:6fca643f1aff 418 XbusMessage xbusMessage = {XMID_GotoConfig};
tjerkhofmeijer 0:6fca643f1aff 419 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 420 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 421 } break;
tjerkhofmeijer 0:6fca643f1aff 422
tjerkhofmeijer 0:6fca643f1aff 423 case 'm':
tjerkhofmeijer 0:6fca643f1aff 424 {
tjerkhofmeijer 0:6fca643f1aff 425 XbusMessage xbusMessage = {XMID_GotoMeasurement};
tjerkhofmeijer 0:6fca643f1aff 426 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 427 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 428 } break;
tjerkhofmeijer 0:6fca643f1aff 429
tjerkhofmeijer 0:6fca643f1aff 430 case 'r':
tjerkhofmeijer 0:6fca643f1aff 431 {
tjerkhofmeijer 0:6fca643f1aff 432 XbusMessage xbusMessage = {XMID_Reset};
tjerkhofmeijer 0:6fca643f1aff 433 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 434 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 435 } break;
tjerkhofmeijer 0:6fca643f1aff 436
tjerkhofmeijer 0:6fca643f1aff 437 case 'b':
tjerkhofmeijer 0:6fca643f1aff 438 {
tjerkhofmeijer 0:6fca643f1aff 439 XbusMessage xbusMessage = {XMID_GotoBootLoader};
tjerkhofmeijer 0:6fca643f1aff 440 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 441 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 442 } break;
tjerkhofmeijer 0:6fca643f1aff 443
tjerkhofmeijer 0:6fca643f1aff 444 case 'v':
tjerkhofmeijer 0:6fca643f1aff 445 {
tjerkhofmeijer 0:6fca643f1aff 446 XbusMessage xbusMessage = {XMID_ReqFirmwareRevision};
tjerkhofmeijer 0:6fca643f1aff 447 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 448 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 449 } break;
tjerkhofmeijer 0:6fca643f1aff 450
tjerkhofmeijer 0:6fca643f1aff 451 case 'd':
tjerkhofmeijer 0:6fca643f1aff 452 {
tjerkhofmeijer 0:6fca643f1aff 453 XbusMessage xbusMessage = {XMID_ReqDid};
tjerkhofmeijer 0:6fca643f1aff 454 xbusMessage.m_length = 0;
tjerkhofmeijer 0:6fca643f1aff 455 mtInterface->sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 456 } break;
tjerkhofmeijer 0:6fca643f1aff 457
tjerkhofmeijer 0:6fca643f1aff 458 case 'u':
tjerkhofmeijer 0:6fca643f1aff 459 {
tjerkhofmeijer 0:6fca643f1aff 460 pc.printf("Starting firmware update\r\n");
tjerkhofmeijer 0:6fca643f1aff 461 FwUpdate_init(g_fwUpdate);
tjerkhofmeijer 0:6fca643f1aff 462 FwUpdate_start(g_fwUpdate);
tjerkhofmeijer 0:6fca643f1aff 463 } break;
tjerkhofmeijer 0:6fca643f1aff 464
tjerkhofmeijer 0:6fca643f1aff 465 case 'x':
tjerkhofmeijer 0:6fca643f1aff 466 {
tjerkhofmeijer 0:6fca643f1aff 467 hardwareReset(true);
tjerkhofmeijer 0:6fca643f1aff 468 } break;
tjerkhofmeijer 0:6fca643f1aff 469 }
tjerkhofmeijer 0:6fca643f1aff 470 }
tjerkhofmeijer 0:6fca643f1aff 471 }
tjerkhofmeijer 0:6fca643f1aff 472
tjerkhofmeijer 0:6fca643f1aff 473 delete g_fwUpdate;
tjerkhofmeijer 0:6fca643f1aff 474 delete[] fwuTxBuffer;
tjerkhofmeijer 0:6fca643f1aff 475 return -1;
tjerkhofmeijer 0:6fca643f1aff 476 }
tjerkhofmeijer 0:6fca643f1aff 477