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

Important Information

This example is deprecated and no longer maintained. There are new embedded examples available in the MT SDK folder of the MT Software Suite. For more information please visit: https://xsenstechnologies.force.com/knowledgebase/s/article/Introduction-to-the-MT-SDK-programming-examples-for-MTi-devices

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:
Wed Dec 21 09:51:35 2016 +0100
Revision:
6:fd42cb49cdd0
Parent:
0:6fca643f1aff
Updated the embedded MTi1 firmware file to version 1.1.1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tjerkhofmeijer 0:6fca643f1aff 1 /*!
tjerkhofmeijer 0:6fca643f1aff 2 * \file
tjerkhofmeijer 0:6fca643f1aff 3 * \copyright Copyright (C) Xsens Technologies B.V., 2015.
tjerkhofmeijer 0:6fca643f1aff 4 *
tjerkhofmeijer 0:6fca643f1aff 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
tjerkhofmeijer 0:6fca643f1aff 6 * use this file except in compliance with the License. You may obtain a copy
tjerkhofmeijer 0:6fca643f1aff 7 * of the License at
tjerkhofmeijer 0:6fca643f1aff 8 *
tjerkhofmeijer 0:6fca643f1aff 9 * http://www.apache.org/licenses/LICENSE-2.0
tjerkhofmeijer 0:6fca643f1aff 10 *
tjerkhofmeijer 0:6fca643f1aff 11 * Unless required by applicable law or agreed to in writing, software
tjerkhofmeijer 0:6fca643f1aff 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
tjerkhofmeijer 0:6fca643f1aff 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
tjerkhofmeijer 0:6fca643f1aff 14 * License for the specific language governing permissions and limitations
tjerkhofmeijer 0:6fca643f1aff 15 * under the License.
tjerkhofmeijer 0:6fca643f1aff 16 */
tjerkhofmeijer 0:6fca643f1aff 17 #include "fwupdate.h"
tjerkhofmeijer 0:6fca643f1aff 18 #include "string.h"
tjerkhofmeijer 0:6fca643f1aff 19
tjerkhofmeijer 0:6fca643f1aff 20 #ifndef LOG
tjerkhofmeijer 0:6fca643f1aff 21 static void defaultLogFunction(char const* format, ...) { }
tjerkhofmeijer 0:6fca643f1aff 22 #define LOG defaultLogFunction
tjerkhofmeijer 0:6fca643f1aff 23 #endif
tjerkhofmeijer 0:6fca643f1aff 24
tjerkhofmeijer 0:6fca643f1aff 25 #define XMID_FIRMWARE_UPDATE (0xF2)
tjerkhofmeijer 0:6fca643f1aff 26
tjerkhofmeijer 0:6fca643f1aff 27 #define FWUP_DEFAULT_SLICE_SIZE (64)
tjerkhofmeijer 0:6fca643f1aff 28
tjerkhofmeijer 0:6fca643f1aff 29
tjerkhofmeijer 0:6fca643f1aff 30 /*! \brief Firmware updater commands
tjerkhofmeijer 0:6fca643f1aff 31 */
tjerkhofmeijer 0:6fca643f1aff 32 #define FWUP_READY (unsigned char)0x52 //'R'
tjerkhofmeijer 0:6fca643f1aff 33 #define FWUP_OK (unsigned char)0x53 //'S'
tjerkhofmeijer 0:6fca643f1aff 34 #define FWUP_CSERROR (unsigned char)0x45 //'E'
tjerkhofmeijer 0:6fca643f1aff 35 #define FWUP_CRITICAL (unsigned char)0x46 //'F'
tjerkhofmeijer 0:6fca643f1aff 36 #define FWUP_FINISHED (unsigned char)0x46 //'F'
tjerkhofmeijer 0:6fca643f1aff 37 #define FWUP_PAGE (unsigned char)0x50 //'P'
tjerkhofmeijer 0:6fca643f1aff 38 #define FWUP_HEADER (unsigned char)0x53 //'S'
tjerkhofmeijer 0:6fca643f1aff 39 #define FWUP_PAGESLICE (unsigned char)0x54 //'T'
tjerkhofmeijer 0:6fca643f1aff 40 #define FWUP_STARTED (unsigned char)0x41 //'A'
tjerkhofmeijer 0:6fca643f1aff 41 #define FWUP_OTHER (unsigned char)0x4F //'O'
tjerkhofmeijer 0:6fca643f1aff 42
tjerkhofmeijer 0:6fca643f1aff 43
tjerkhofmeijer 0:6fca643f1aff 44 /*! \brief Helper function for converting a firmware updater command to a string
tjerkhofmeijer 0:6fca643f1aff 45 */
tjerkhofmeijer 0:6fca643f1aff 46 const char *commandToString(uint8_t command)
tjerkhofmeijer 0:6fca643f1aff 47 {
tjerkhofmeijer 0:6fca643f1aff 48 switch (command)
tjerkhofmeijer 0:6fca643f1aff 49 {
tjerkhofmeijer 0:6fca643f1aff 50 case FWUP_READY: return("FWUP_READY");
tjerkhofmeijer 0:6fca643f1aff 51 case FWUP_HEADER: return("FWUP_HEADER");
tjerkhofmeijer 0:6fca643f1aff 52 case FWUP_FINISHED: return("FWUP_FINISHED");
tjerkhofmeijer 0:6fca643f1aff 53 case FWUP_PAGE: return("FWUP_PAGE");
tjerkhofmeijer 0:6fca643f1aff 54 case FWUP_PAGESLICE: return("FWUP_PAGESLICE");
tjerkhofmeijer 0:6fca643f1aff 55 case FWUP_STARTED: return("FWUP_STARTED");
tjerkhofmeijer 0:6fca643f1aff 56 case FWUP_OTHER: return("FWUP_OTHER");
tjerkhofmeijer 0:6fca643f1aff 57 default: return("unknown");
tjerkhofmeijer 0:6fca643f1aff 58 }
tjerkhofmeijer 0:6fca643f1aff 59 }
tjerkhofmeijer 0:6fca643f1aff 60
tjerkhofmeijer 0:6fca643f1aff 61
tjerkhofmeijer 0:6fca643f1aff 62 /*! \brief Helper function for converting a firmware updater command acknowledge to a string
tjerkhofmeijer 0:6fca643f1aff 63 */
tjerkhofmeijer 0:6fca643f1aff 64 const char *ackToString(uint8_t command)
tjerkhofmeijer 0:6fca643f1aff 65 {
tjerkhofmeijer 0:6fca643f1aff 66 switch (command)
tjerkhofmeijer 0:6fca643f1aff 67 {
tjerkhofmeijer 0:6fca643f1aff 68 case FWUP_READY: return "FWUP_READY";
tjerkhofmeijer 0:6fca643f1aff 69 case FWUP_OK: return "FWUP_OK";
tjerkhofmeijer 0:6fca643f1aff 70 case FWUP_CSERROR: return "FWUP_CSERROR";
tjerkhofmeijer 0:6fca643f1aff 71 case FWUP_CRITICAL: return "FWUP_CRITICAL";
tjerkhofmeijer 0:6fca643f1aff 72 case FWUP_PAGE: return "FWUP_PAGE";
tjerkhofmeijer 0:6fca643f1aff 73 case FWUP_PAGESLICE: return "FWUP_PAGESLICE";
tjerkhofmeijer 0:6fca643f1aff 74 case FWUP_STARTED: return "FWUP_STARTED";
tjerkhofmeijer 0:6fca643f1aff 75 case FWUP_OTHER: return "FWUP_OTHER";
tjerkhofmeijer 0:6fca643f1aff 76 default: return "unknown";
tjerkhofmeijer 0:6fca643f1aff 77 }
tjerkhofmeijer 0:6fca643f1aff 78 }
tjerkhofmeijer 0:6fca643f1aff 79
tjerkhofmeijer 0:6fca643f1aff 80
tjerkhofmeijer 0:6fca643f1aff 81 /*! \brief Read a uint32_t from the current position in the xff
tjerkhofmeijer 0:6fca643f1aff 82 */
tjerkhofmeijer 0:6fca643f1aff 83 uint32_t readUint32(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 84 {
tjerkhofmeijer 0:6fca643f1aff 85 uint32_t result;
tjerkhofmeijer 0:6fca643f1aff 86 uint8_t buffer[4];
tjerkhofmeijer 0:6fca643f1aff 87 int n = thisPtr->m_readXffData(buffer, thisPtr->m_readIndex, 4);
tjerkhofmeijer 0:6fca643f1aff 88 thisPtr->m_readIndex += n;
tjerkhofmeijer 0:6fca643f1aff 89 if (n == 4)
tjerkhofmeijer 0:6fca643f1aff 90 {
tjerkhofmeijer 0:6fca643f1aff 91 result = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
tjerkhofmeijer 0:6fca643f1aff 92 }
tjerkhofmeijer 0:6fca643f1aff 93 else
tjerkhofmeijer 0:6fca643f1aff 94 {
tjerkhofmeijer 0:6fca643f1aff 95 thisPtr->m_endOfFile = 1;
tjerkhofmeijer 0:6fca643f1aff 96 result = 0;
tjerkhofmeijer 0:6fca643f1aff 97 }
tjerkhofmeijer 0:6fca643f1aff 98 return result;
tjerkhofmeijer 0:6fca643f1aff 99 }
tjerkhofmeijer 0:6fca643f1aff 100
tjerkhofmeijer 0:6fca643f1aff 101
tjerkhofmeijer 0:6fca643f1aff 102 /*! \brief Read a uint16_t from the current position in the xff
tjerkhofmeijer 0:6fca643f1aff 103 */
tjerkhofmeijer 0:6fca643f1aff 104 uint16_t readUint16(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 105 {
tjerkhofmeijer 0:6fca643f1aff 106 uint16_t result;
tjerkhofmeijer 0:6fca643f1aff 107 uint8_t buffer[2];
tjerkhofmeijer 0:6fca643f1aff 108 int n = thisPtr->m_readXffData(buffer, thisPtr->m_readIndex, 2);
tjerkhofmeijer 0:6fca643f1aff 109 thisPtr->m_readIndex += n;
tjerkhofmeijer 0:6fca643f1aff 110 if (n == 2)
tjerkhofmeijer 0:6fca643f1aff 111 {
tjerkhofmeijer 0:6fca643f1aff 112 result = buffer[0] << 8 | buffer[1];
tjerkhofmeijer 0:6fca643f1aff 113 }
tjerkhofmeijer 0:6fca643f1aff 114 else
tjerkhofmeijer 0:6fca643f1aff 115 {
tjerkhofmeijer 0:6fca643f1aff 116 thisPtr->m_endOfFile = 1;
tjerkhofmeijer 0:6fca643f1aff 117 result = 0;
tjerkhofmeijer 0:6fca643f1aff 118 }
tjerkhofmeijer 0:6fca643f1aff 119 return result;
tjerkhofmeijer 0:6fca643f1aff 120 }
tjerkhofmeijer 0:6fca643f1aff 121
tjerkhofmeijer 0:6fca643f1aff 122
tjerkhofmeijer 0:6fca643f1aff 123 /*! \brief Read a uint8_t from the current position in the xff
tjerkhofmeijer 0:6fca643f1aff 124 */
tjerkhofmeijer 0:6fca643f1aff 125 uint8_t readUint8(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 126 {
tjerkhofmeijer 0:6fca643f1aff 127 uint8_t result;
tjerkhofmeijer 0:6fca643f1aff 128 uint8_t buffer[1];
tjerkhofmeijer 0:6fca643f1aff 129 int n = thisPtr->m_readXffData(buffer, thisPtr->m_readIndex, 1);
tjerkhofmeijer 0:6fca643f1aff 130 thisPtr->m_readIndex += n;
tjerkhofmeijer 0:6fca643f1aff 131 if (n == 1)
tjerkhofmeijer 0:6fca643f1aff 132 {
tjerkhofmeijer 0:6fca643f1aff 133 result = buffer[0];
tjerkhofmeijer 0:6fca643f1aff 134 }
tjerkhofmeijer 0:6fca643f1aff 135 else
tjerkhofmeijer 0:6fca643f1aff 136 {
tjerkhofmeijer 0:6fca643f1aff 137 thisPtr->m_endOfFile = 1;
tjerkhofmeijer 0:6fca643f1aff 138 result = 0;
tjerkhofmeijer 0:6fca643f1aff 139 }
tjerkhofmeijer 0:6fca643f1aff 140 return result;
tjerkhofmeijer 0:6fca643f1aff 141 }
tjerkhofmeijer 0:6fca643f1aff 142
tjerkhofmeijer 0:6fca643f1aff 143
tjerkhofmeijer 0:6fca643f1aff 144 /*! \brief Read an Xff header from the current position in the xff
tjerkhofmeijer 0:6fca643f1aff 145 */
tjerkhofmeijer 0:6fca643f1aff 146 static void readXffHeader(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 147 {
tjerkhofmeijer 0:6fca643f1aff 148 LOG("Fwu: readXffHeader()\n");
tjerkhofmeijer 0:6fca643f1aff 149
tjerkhofmeijer 0:6fca643f1aff 150 thisPtr->m_xffHeader.m_globalId = readUint32(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 151 thisPtr->m_xffHeader.m_sectionSize = readUint32(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 152 thisPtr->m_xffHeader.m_firmwareRevision[0] = readUint8(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 153 thisPtr->m_xffHeader.m_firmwareRevision[1] = readUint8(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 154 thisPtr->m_xffHeader.m_firmwareRevision[2] = readUint8(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 155 thisPtr->m_xffHeader.m_xffVersion[0] = readUint8(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 156 thisPtr->m_xffHeader.m_xffVersion[1] = readUint8(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 157 thisPtr->m_xffHeader.m_chipId = readUint8(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 158 thisPtr->m_xffHeader.m_numberOfSections = readUint8(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 159 thisPtr->m_xffHeader.m_addressLength = readUint8(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 160 thisPtr->m_xffHeader.m_pageSize = readUint16(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 161 if (thisPtr->m_xffHeader.m_xffVersion[0] >= 2)
tjerkhofmeijer 0:6fca643f1aff 162 thisPtr->m_xffHeader.m_sliceSize = readUint16(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 163 else
tjerkhofmeijer 0:6fca643f1aff 164 thisPtr->m_xffHeader.m_sliceSize = FWUP_DEFAULT_SLICE_SIZE;
tjerkhofmeijer 0:6fca643f1aff 165 }
tjerkhofmeijer 0:6fca643f1aff 166
tjerkhofmeijer 0:6fca643f1aff 167
tjerkhofmeijer 0:6fca643f1aff 168 /*! \brief Send an XMID_FIRMWARE_UPDATE xbus message
tjerkhofmeijer 0:6fca643f1aff 169 \param data Pointer to the xbus message payload data
tjerkhofmeijer 0:6fca643f1aff 170 \param length Number of payload bytes
tjerkhofmeijer 0:6fca643f1aff 171 */
tjerkhofmeijer 0:6fca643f1aff 172 static void sendFirmwareUpdateCommand(FwUpdate *thisPtr, uint8_t *data, uint16_t length)
tjerkhofmeijer 0:6fca643f1aff 173 {
tjerkhofmeijer 0:6fca643f1aff 174 struct XbusMessage xbusMessage;
tjerkhofmeijer 0:6fca643f1aff 175 xbusMessage.m_mid = XMID_FIRMWARE_UPDATE;
tjerkhofmeijer 0:6fca643f1aff 176 xbusMessage.m_length = length;
tjerkhofmeijer 0:6fca643f1aff 177 xbusMessage.m_data = data;
tjerkhofmeijer 0:6fca643f1aff 178 thisPtr->m_sendXbusMessage(&xbusMessage);
tjerkhofmeijer 0:6fca643f1aff 179 }
tjerkhofmeijer 0:6fca643f1aff 180
tjerkhofmeijer 0:6fca643f1aff 181
tjerkhofmeijer 0:6fca643f1aff 182 /*! \brief Send a FWUP_READY command
tjerkhofmeijer 0:6fca643f1aff 183 */
tjerkhofmeijer 0:6fca643f1aff 184 static void sendReady(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 185 {
tjerkhofmeijer 0:6fca643f1aff 186 thisPtr->m_txBuffer[0] = FWUP_READY;
tjerkhofmeijer 0:6fca643f1aff 187 sendFirmwareUpdateCommand(thisPtr, thisPtr->m_txBuffer, 1);
tjerkhofmeijer 0:6fca643f1aff 188 }
tjerkhofmeijer 0:6fca643f1aff 189
tjerkhofmeijer 0:6fca643f1aff 190
tjerkhofmeijer 0:6fca643f1aff 191 /*! \brief Send a FWUP_HEADER command
tjerkhofmeijer 0:6fca643f1aff 192 */
tjerkhofmeijer 0:6fca643f1aff 193 static void sendHeader(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 194 {
tjerkhofmeijer 0:6fca643f1aff 195 int n;
tjerkhofmeijer 0:6fca643f1aff 196 thisPtr->m_txBuffer[0] = FWUP_HEADER;
tjerkhofmeijer 0:6fca643f1aff 197 n = thisPtr->m_readXffData(&thisPtr->m_txBuffer[1], thisPtr->m_readIndex, thisPtr->m_xffHeader.m_addressLength);
tjerkhofmeijer 0:6fca643f1aff 198 thisPtr->m_readIndex += n;
tjerkhofmeijer 0:6fca643f1aff 199 if (n == thisPtr->m_xffHeader.m_addressLength)
tjerkhofmeijer 0:6fca643f1aff 200 {
tjerkhofmeijer 0:6fca643f1aff 201 memcpy(&thisPtr->m_txBuffer[1 + thisPtr->m_xffHeader.m_addressLength], &thisPtr->m_nofSlicesPerPage, 2);
tjerkhofmeijer 0:6fca643f1aff 202 sendFirmwareUpdateCommand(thisPtr, thisPtr->m_txBuffer, 1 + thisPtr->m_xffHeader.m_addressLength + 2);
tjerkhofmeijer 0:6fca643f1aff 203 }
tjerkhofmeijer 0:6fca643f1aff 204 else
tjerkhofmeijer 0:6fca643f1aff 205 {
tjerkhofmeijer 0:6fca643f1aff 206 thisPtr->m_endOfFile = 1;
tjerkhofmeijer 0:6fca643f1aff 207 }
tjerkhofmeijer 0:6fca643f1aff 208 }
tjerkhofmeijer 0:6fca643f1aff 209
tjerkhofmeijer 0:6fca643f1aff 210
tjerkhofmeijer 0:6fca643f1aff 211 /*! \brief Send a page slice
tjerkhofmeijer 0:6fca643f1aff 212 */
tjerkhofmeijer 0:6fca643f1aff 213 static void sendSlice(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 214 {
tjerkhofmeijer 0:6fca643f1aff 215 int n;
tjerkhofmeijer 0:6fca643f1aff 216 thisPtr->m_txBuffer[0] = FWUP_PAGESLICE;
tjerkhofmeijer 0:6fca643f1aff 217 n = thisPtr->m_readXffData(&thisPtr->m_txBuffer[1], thisPtr->m_readIndex, thisPtr->m_xffHeader.m_sliceSize);
tjerkhofmeijer 0:6fca643f1aff 218 thisPtr->m_readIndex += n;
tjerkhofmeijer 0:6fca643f1aff 219 if (n == thisPtr->m_xffHeader.m_sliceSize)
tjerkhofmeijer 0:6fca643f1aff 220 {
tjerkhofmeijer 0:6fca643f1aff 221 sendFirmwareUpdateCommand(thisPtr, thisPtr->m_txBuffer, 1 + thisPtr->m_xffHeader.m_sliceSize);
tjerkhofmeijer 0:6fca643f1aff 222 }
tjerkhofmeijer 0:6fca643f1aff 223 else
tjerkhofmeijer 0:6fca643f1aff 224 {
tjerkhofmeijer 0:6fca643f1aff 225 thisPtr->m_endOfFile = 1;
tjerkhofmeijer 0:6fca643f1aff 226 }
tjerkhofmeijer 0:6fca643f1aff 227 }
tjerkhofmeijer 0:6fca643f1aff 228
tjerkhofmeijer 0:6fca643f1aff 229
tjerkhofmeijer 0:6fca643f1aff 230 /*! \brief Send a FWUP_OTHER command
tjerkhofmeijer 0:6fca643f1aff 231 */
tjerkhofmeijer 0:6fca643f1aff 232 static void sendOther(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 233 {
tjerkhofmeijer 0:6fca643f1aff 234 thisPtr->m_txBuffer[0] = FWUP_OTHER;
tjerkhofmeijer 0:6fca643f1aff 235 thisPtr->m_txBuffer[1] = thisPtr->m_xffHeader.m_chipId;
tjerkhofmeijer 0:6fca643f1aff 236 LOG("Fwu: Send FWUP_OTHER\n");
tjerkhofmeijer 0:6fca643f1aff 237 sendFirmwareUpdateCommand(thisPtr, thisPtr->m_txBuffer, 2);
tjerkhofmeijer 0:6fca643f1aff 238 }
tjerkhofmeijer 0:6fca643f1aff 239
tjerkhofmeijer 0:6fca643f1aff 240
tjerkhofmeijer 0:6fca643f1aff 241 /*! \brief Send a FWUP_FINISHED command
tjerkhofmeijer 0:6fca643f1aff 242 */
tjerkhofmeijer 0:6fca643f1aff 243 static void sendFinished(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 244 {
tjerkhofmeijer 0:6fca643f1aff 245 thisPtr->m_txBuffer[0] = FWUP_FINISHED;
tjerkhofmeijer 0:6fca643f1aff 246 LOG("Fwu: Send FWUP_FINISHED\n");
tjerkhofmeijer 0:6fca643f1aff 247 sendFirmwareUpdateCommand(thisPtr, thisPtr->m_txBuffer, 1);
tjerkhofmeijer 0:6fca643f1aff 248 }
tjerkhofmeijer 0:6fca643f1aff 249
tjerkhofmeijer 0:6fca643f1aff 250
tjerkhofmeijer 0:6fca643f1aff 251 /*! \brief Enter the next section of the xff file
tjerkhofmeijer 0:6fca643f1aff 252 */
tjerkhofmeijer 0:6fca643f1aff 253 static void enterNewSection(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 254 {
tjerkhofmeijer 0:6fca643f1aff 255 LOG("\nFwu: enterNewSection()\n");
tjerkhofmeijer 0:6fca643f1aff 256 readXffHeader(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 257 thisPtr->m_nofPages = thisPtr->m_xffHeader.m_sectionSize / (thisPtr->m_xffHeader.m_pageSize + thisPtr->m_xffHeader.m_addressLength);
tjerkhofmeijer 0:6fca643f1aff 258 thisPtr->m_nofSlicesPerPage = thisPtr->m_xffHeader.m_pageSize / thisPtr->m_xffHeader.m_sliceSize;
tjerkhofmeijer 0:6fca643f1aff 259 thisPtr->m_pageCounter = 0;
tjerkhofmeijer 0:6fca643f1aff 260 thisPtr->m_sliceCounter = 0;
tjerkhofmeijer 0:6fca643f1aff 261 sendOther(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 262 }
tjerkhofmeijer 0:6fca643f1aff 263
tjerkhofmeijer 0:6fca643f1aff 264
tjerkhofmeijer 0:6fca643f1aff 265 /* \brief Public interface of the firmware updater:
tjerkhofmeijer 0:6fca643f1aff 266 */
tjerkhofmeijer 0:6fca643f1aff 267
tjerkhofmeijer 0:6fca643f1aff 268 /*! \brief Initialize a FwUpdate instance
tjerkhofmeijer 0:6fca643f1aff 269 */
tjerkhofmeijer 0:6fca643f1aff 270 void FwUpdate_init(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 271 {
tjerkhofmeijer 0:6fca643f1aff 272 LOG("Fwu: init()\n");
tjerkhofmeijer 0:6fca643f1aff 273 thisPtr->m_state = STATE_Idle;
tjerkhofmeijer 0:6fca643f1aff 274 }
tjerkhofmeijer 0:6fca643f1aff 275
tjerkhofmeijer 0:6fca643f1aff 276
tjerkhofmeijer 0:6fca643f1aff 277 /*! \brief Start a firmware update
tjerkhofmeijer 0:6fca643f1aff 278 */
tjerkhofmeijer 0:6fca643f1aff 279 void FwUpdate_start(FwUpdate *thisPtr)
tjerkhofmeijer 0:6fca643f1aff 280 {
tjerkhofmeijer 0:6fca643f1aff 281 if (thisPtr->m_state == STATE_Idle)
tjerkhofmeijer 0:6fca643f1aff 282 {
tjerkhofmeijer 0:6fca643f1aff 283 LOG("Fwu: start() --> Send FWUP_READY\n");
tjerkhofmeijer 0:6fca643f1aff 284 thisPtr->m_readIndex = 0;
tjerkhofmeijer 0:6fca643f1aff 285 thisPtr->m_endOfFile = 0;
tjerkhofmeijer 0:6fca643f1aff 286 thisPtr->m_state = STATE_Start;
tjerkhofmeijer 0:6fca643f1aff 287 sendReady(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 288 }
tjerkhofmeijer 0:6fca643f1aff 289 else
tjerkhofmeijer 0:6fca643f1aff 290 {
tjerkhofmeijer 0:6fca643f1aff 291 thisPtr->m_readyHandler(FWU_Failed);
tjerkhofmeijer 0:6fca643f1aff 292 LOG("Fwu: start() failed\n");
tjerkhofmeijer 0:6fca643f1aff 293 }
tjerkhofmeijer 0:6fca643f1aff 294 }
tjerkhofmeijer 0:6fca643f1aff 295
tjerkhofmeijer 0:6fca643f1aff 296
tjerkhofmeijer 0:6fca643f1aff 297 /*! \brief Handle xbus message coming from the module
tjerkhofmeijer 0:6fca643f1aff 298 \param xbusMessage The xbus message from the module to be handled
tjerkhofmeijer 0:6fca643f1aff 299 */
tjerkhofmeijer 0:6fca643f1aff 300 void FwUpdate_handleXbus(FwUpdate* thisPtr, struct XbusMessage* xbusMessage)
tjerkhofmeijer 0:6fca643f1aff 301 {
tjerkhofmeijer 0:6fca643f1aff 302 uint8_t ack;
tjerkhofmeijer 0:6fca643f1aff 303 if (xbusMessage->m_mid != XMID_FIRMWARE_UPDATE)
tjerkhofmeijer 0:6fca643f1aff 304 {
tjerkhofmeijer 0:6fca643f1aff 305 LOG("Fwu: Got unhandled xbus message 0x%02X (ignored)\n", xbusMessage->m_mid);
tjerkhofmeijer 0:6fca643f1aff 306 return;
tjerkhofmeijer 0:6fca643f1aff 307 }
tjerkhofmeijer 0:6fca643f1aff 308
tjerkhofmeijer 0:6fca643f1aff 309 ack = xbusMessage->m_data[0];
tjerkhofmeijer 0:6fca643f1aff 310
tjerkhofmeijer 0:6fca643f1aff 311 switch (thisPtr->m_state)
tjerkhofmeijer 0:6fca643f1aff 312 {
tjerkhofmeijer 0:6fca643f1aff 313 case STATE_Idle:
tjerkhofmeijer 0:6fca643f1aff 314 {
tjerkhofmeijer 0:6fca643f1aff 315 LOG("Fwu: Got %s in STATE_Idle (ignored)\n", ackToString(ack));
tjerkhofmeijer 0:6fca643f1aff 316 } break;
tjerkhofmeijer 0:6fca643f1aff 317
tjerkhofmeijer 0:6fca643f1aff 318 case STATE_Start:
tjerkhofmeijer 0:6fca643f1aff 319 {
tjerkhofmeijer 0:6fca643f1aff 320 if (ack == FWUP_READY)
tjerkhofmeijer 0:6fca643f1aff 321 {
tjerkhofmeijer 0:6fca643f1aff 322 LOG("Fwu: FWUP_READY in STATE_Start --> Enter new section\n");
tjerkhofmeijer 0:6fca643f1aff 323 enterNewSection(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 324 thisPtr->m_state = STATE_WaitReady;
tjerkhofmeijer 0:6fca643f1aff 325 }
tjerkhofmeijer 0:6fca643f1aff 326 else
tjerkhofmeijer 0:6fca643f1aff 327 {
tjerkhofmeijer 0:6fca643f1aff 328 LOG("Fwu: Got %s in STATE_Start (ignored)\n", ackToString(ack));
tjerkhofmeijer 0:6fca643f1aff 329 }
tjerkhofmeijer 0:6fca643f1aff 330 } break;
tjerkhofmeijer 0:6fca643f1aff 331
tjerkhofmeijer 0:6fca643f1aff 332 case STATE_WaitReady:
tjerkhofmeijer 0:6fca643f1aff 333 {
tjerkhofmeijer 0:6fca643f1aff 334 if (ack == FWUP_READY)
tjerkhofmeijer 0:6fca643f1aff 335 {
tjerkhofmeijer 0:6fca643f1aff 336 LOG("Fwu: FWUP_READY in STATE_WaitReady --> Send header\n");
tjerkhofmeijer 0:6fca643f1aff 337 sendHeader(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 338 thisPtr->m_state = STATE_WaitHeaderResult;
tjerkhofmeijer 0:6fca643f1aff 339 }
tjerkhofmeijer 0:6fca643f1aff 340 else
tjerkhofmeijer 0:6fca643f1aff 341 {
tjerkhofmeijer 0:6fca643f1aff 342 LOG("Fwu: Got %s in STATE_WaitReady --> Failed\n", ackToString(ack));
tjerkhofmeijer 0:6fca643f1aff 343 thisPtr->m_readyHandler(FWU_Failed);
tjerkhofmeijer 0:6fca643f1aff 344 thisPtr->m_state = STATE_Idle;
tjerkhofmeijer 0:6fca643f1aff 345 }
tjerkhofmeijer 0:6fca643f1aff 346 } break;
tjerkhofmeijer 0:6fca643f1aff 347
tjerkhofmeijer 0:6fca643f1aff 348 case STATE_WaitHeaderResult:
tjerkhofmeijer 0:6fca643f1aff 349 {
tjerkhofmeijer 0:6fca643f1aff 350 if (ack == FWUP_READY)
tjerkhofmeijer 0:6fca643f1aff 351 {
tjerkhofmeijer 0:6fca643f1aff 352 LOG("Fwu: FWUP_READY in STATE_WaitHeaderResult --> Send first slice\n");
tjerkhofmeijer 0:6fca643f1aff 353 sendSlice(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 354 thisPtr->m_sliceCounter = 1;
tjerkhofmeijer 0:6fca643f1aff 355 thisPtr->m_state = STATE_WaitSliceReady;
tjerkhofmeijer 0:6fca643f1aff 356 }
tjerkhofmeijer 0:6fca643f1aff 357 else
tjerkhofmeijer 0:6fca643f1aff 358 {
tjerkhofmeijer 0:6fca643f1aff 359 LOG("Fwu: Got %s in STATE_WaitHeaderResult --> Failed\n", ackToString(ack));
tjerkhofmeijer 0:6fca643f1aff 360 thisPtr->m_readyHandler(FWU_Failed);
tjerkhofmeijer 0:6fca643f1aff 361 thisPtr->m_state = STATE_Idle;
tjerkhofmeijer 0:6fca643f1aff 362 }
tjerkhofmeijer 0:6fca643f1aff 363 } break;
tjerkhofmeijer 0:6fca643f1aff 364
tjerkhofmeijer 0:6fca643f1aff 365 case STATE_WaitSliceReady:
tjerkhofmeijer 0:6fca643f1aff 366 {
tjerkhofmeijer 0:6fca643f1aff 367 if (ack == FWUP_READY)
tjerkhofmeijer 0:6fca643f1aff 368 {
tjerkhofmeijer 0:6fca643f1aff 369 if (thisPtr->m_sliceCounter < thisPtr->m_nofSlicesPerPage)
tjerkhofmeijer 0:6fca643f1aff 370 {
tjerkhofmeijer 0:6fca643f1aff 371 LOG("Fwu: FWUP_READY in STATE_WaitSliceReady --> Send slice %d\n", thisPtr->m_sliceCounter);
tjerkhofmeijer 0:6fca643f1aff 372 sendSlice(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 373 thisPtr->m_sliceCounter++;
tjerkhofmeijer 0:6fca643f1aff 374 }
tjerkhofmeijer 0:6fca643f1aff 375 else
tjerkhofmeijer 0:6fca643f1aff 376 {
tjerkhofmeijer 0:6fca643f1aff 377 LOG("Fwu: All slices sent --> STATE_WaitPageOk\n");
tjerkhofmeijer 0:6fca643f1aff 378 thisPtr->m_state = STATE_WaitPageOk;
tjerkhofmeijer 0:6fca643f1aff 379 }
tjerkhofmeijer 0:6fca643f1aff 380 }
tjerkhofmeijer 0:6fca643f1aff 381 else
tjerkhofmeijer 0:6fca643f1aff 382 {
tjerkhofmeijer 0:6fca643f1aff 383 LOG("Fwu: Got %s in STATE_WaitSliceReady --> Failed\n", ackToString(ack));
tjerkhofmeijer 0:6fca643f1aff 384 thisPtr->m_readyHandler(FWU_Failed);
tjerkhofmeijer 0:6fca643f1aff 385 thisPtr->m_state = STATE_Idle;
tjerkhofmeijer 0:6fca643f1aff 386 }
tjerkhofmeijer 0:6fca643f1aff 387 } break;
tjerkhofmeijer 0:6fca643f1aff 388
tjerkhofmeijer 0:6fca643f1aff 389 case STATE_WaitPageOk:
tjerkhofmeijer 0:6fca643f1aff 390 {
tjerkhofmeijer 0:6fca643f1aff 391 if (ack == FWUP_OK)
tjerkhofmeijer 0:6fca643f1aff 392 {
tjerkhofmeijer 0:6fca643f1aff 393 LOG("Fwu: FWUP_OK in STATE_WaitPageOk --> STATE_WaitPageReady\n");
tjerkhofmeijer 0:6fca643f1aff 394 thisPtr->m_state = STATE_WaitPageReady;
tjerkhofmeijer 0:6fca643f1aff 395 }
tjerkhofmeijer 0:6fca643f1aff 396 else
tjerkhofmeijer 0:6fca643f1aff 397 {
tjerkhofmeijer 0:6fca643f1aff 398 LOG("Fwu: Got %s in STATE_WaitPageOk --> Failed\n", ackToString(ack));
tjerkhofmeijer 0:6fca643f1aff 399 thisPtr->m_readyHandler(FWU_Failed);
tjerkhofmeijer 0:6fca643f1aff 400 thisPtr->m_state = STATE_Idle;
tjerkhofmeijer 0:6fca643f1aff 401 }
tjerkhofmeijer 0:6fca643f1aff 402 } break;
tjerkhofmeijer 0:6fca643f1aff 403
tjerkhofmeijer 0:6fca643f1aff 404 case STATE_WaitPageReady:
tjerkhofmeijer 0:6fca643f1aff 405 {
tjerkhofmeijer 0:6fca643f1aff 406 if (ack == FWUP_READY)
tjerkhofmeijer 0:6fca643f1aff 407 {
tjerkhofmeijer 0:6fca643f1aff 408 thisPtr->m_pageCounter++;
tjerkhofmeijer 0:6fca643f1aff 409 if (thisPtr->m_nofPages != 0 && thisPtr->m_pageCounter == thisPtr->m_nofPages)
tjerkhofmeijer 0:6fca643f1aff 410 {
tjerkhofmeijer 0:6fca643f1aff 411 LOG("Fwu: All pages sent --> Enter new section\n");
tjerkhofmeijer 0:6fca643f1aff 412 enterNewSection(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 413 thisPtr->m_state = STATE_WaitReady;
tjerkhofmeijer 0:6fca643f1aff 414 }
tjerkhofmeijer 0:6fca643f1aff 415 else
tjerkhofmeijer 0:6fca643f1aff 416 {
tjerkhofmeijer 0:6fca643f1aff 417 sendHeader(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 418 if (thisPtr->m_endOfFile)
tjerkhofmeijer 0:6fca643f1aff 419 {
tjerkhofmeijer 0:6fca643f1aff 420 LOG("Fwu: End of file --> Firmware update done\n");
tjerkhofmeijer 0:6fca643f1aff 421 sendFinished(thisPtr);
tjerkhofmeijer 0:6fca643f1aff 422 thisPtr->m_readyHandler(FWU_Success);
tjerkhofmeijer 0:6fca643f1aff 423 thisPtr->m_state = STATE_Idle;
tjerkhofmeijer 0:6fca643f1aff 424 }
tjerkhofmeijer 0:6fca643f1aff 425 else
tjerkhofmeijer 0:6fca643f1aff 426 {
tjerkhofmeijer 0:6fca643f1aff 427 LOG("Fwu: FWUP_READY in STATE_WaitPageReady --> Send header\n");
tjerkhofmeijer 0:6fca643f1aff 428 thisPtr->m_state = STATE_WaitHeaderResult;
tjerkhofmeijer 0:6fca643f1aff 429 }
tjerkhofmeijer 0:6fca643f1aff 430 }
tjerkhofmeijer 0:6fca643f1aff 431 }
tjerkhofmeijer 0:6fca643f1aff 432 else
tjerkhofmeijer 0:6fca643f1aff 433 {
tjerkhofmeijer 0:6fca643f1aff 434 LOG("Fwu: Got %s in STATE_WaitPageReady --> Failed\n", ackToString(ack));
tjerkhofmeijer 0:6fca643f1aff 435 thisPtr->m_readyHandler(FWU_Failed);
tjerkhofmeijer 0:6fca643f1aff 436 thisPtr->m_state = STATE_Idle;
tjerkhofmeijer 0:6fca643f1aff 437 }
tjerkhofmeijer 0:6fca643f1aff 438 } break;
tjerkhofmeijer 0:6fca643f1aff 439
tjerkhofmeijer 0:6fca643f1aff 440 default:
tjerkhofmeijer 0:6fca643f1aff 441 {
tjerkhofmeijer 0:6fca643f1aff 442 }
tjerkhofmeijer 0:6fca643f1aff 443 }
tjerkhofmeijer 0:6fca643f1aff 444 }
tjerkhofmeijer 0:6fca643f1aff 445
tjerkhofmeijer 0:6fca643f1aff 446