Code for Nucleo f746zg with x-nucleo-gnss1a1 gps board and x-nucleo-iks01a2 sensors board

Dependencies:   X_NUCLEO_IKS01A2 mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
nirnakern
Date:
Mon Oct 23 07:11:35 2017 +0000
Commit message:
First commit

Changed in this revision

Teseo-LIV3F/Teseo-LIV3F.cpp Show annotated file Show diff for this revision Revisions of this file
Teseo-LIV3F/Teseo-LIV3F.h Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_IKS01A2.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Teseo-LIV3F/Teseo-LIV3F.cpp	Mon Oct 23 07:11:35 2017 +0000
@@ -0,0 +1,654 @@
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (C) 2017  STMicroelectronics
+ * Author: Francesco M. Virlinzi  <francesco.virlinzi@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License V.2 ONLY.  See linux/COPYING for more information.
+ *
+ * -------------------------------------------------------------------------
+ */
+#include "string.h"
+#include "Teseo-LIV3F.h"
+
+
+static char T3_name[] = "Teseo-LIV3F";
+
+char _OK[] = "OK";
+char _Failed[] = "Failed";
+char X_Nucleo_name[] = "X-Nucleo-GNSS1A1";
+
+struct teseo_cmd {
+    char *cmd;
+};
+
+static struct teseo_cmd teseo_cmds[] = {
+    [Teseo_LIV3F::GETSWVER] = {
+            .cmd = "$PSTMGETSWVER,7",
+    },
+    [Teseo_LIV3F::FORCESTANDBY] = {
+        .cmd = "$PSTMFORCESTANDBY,00007",
+    },
+    [Teseo_LIV3F::RFTESTON] = {
+        .cmd  = "$PSTMRFTESTON,16",
+    },
+    [Teseo_LIV3F::RFTESTOFF] = {
+        .cmd  = "$PSTMRFTESTOFF\n\r",
+    },
+    [Teseo_LIV3F::LOWPOWER] = {
+        .cmd  = "$PSTMLOWPOWERONOFF,1,0,000,05,0,1,000,1,00010,01,0,0,1,01",
+    },
+    [Teseo_LIV3F::FWUPDATE] = {
+        .cmd  = "$PSTMFWUPGRADE",
+    },
+};
+
+
+Teseo_LIV3F::Teseo_LIV3F(PinName reset_pin, PinName wakeup_pin,
+        PinName pps_pin, PinName uart_tx_pin, PinName uart_rx_pin,
+        Serial *serial_debug):
+        _reset(reset_pin, 1),
+        _pps(pps_pin),
+        _wakeup(wakeup_pin, 0),
+        _uart(uart_rx_pin, uart_tx_pin, SDT_UART_BAUD),
+        _serial_debug(serial_debug)
+{
+        wait_ms(POWERON_STABLE_SIGNAL_DELAY_MS);
+        _uart.baud(SDT_UART_BAUD);
+        _uart.format(8, SerialBase::None, 1);
+        _i2c = NULL;
+        _uart_interleaded = false;
+        _uart_discard = false;
+}
+
+Teseo_LIV3F::Teseo_LIV3F(PinName reset_pin, PinName wakeup_pin,
+        PinName pps_pin, PinName uart_tx_pin, PinName uart_rx_pin,
+        I2C *bus, Serial *serial_debug):
+        _reset(reset_pin, 1),
+        _pps(pps_pin),
+        _wakeup(wakeup_pin, 0),
+        _uart(uart_rx_pin, uart_tx_pin, SDT_UART_BAUD),
+        _i2c(bus),
+        _serial_debug(serial_debug)
+{
+    wait_ms(POWERON_STABLE_SIGNAL_DELAY_MS);
+    _uart.baud(SDT_UART_BAUD);
+    _uart.format(8, SerialBase::None, 1);
+    _uart_interleaded = false;
+    _uart_discard = false;
+}
+
+int Teseo_LIV3F::EnableLowPower()
+{
+    SendCommand(LOWPOWER);
+    return 0;
+}
+
+void Teseo_LIV3F::Reset(Serial *serial_debug)
+{
+    if (serial_debug)
+        serial_debug->printf("%s: Resetting...", T3_name);
+
+    _reset.write(0);
+
+    wait_ms(50);
+
+    _reset.write(1);
+
+    wait_ms(70);
+
+    if (serial_debug)
+            serial_debug->printf("Done...\n\r");
+}
+
+enum {
+        TESEO_FLASHER_IDENTIFIER = 0,   //  0xBCD501F4
+        TESEO_FLASHER_SYNC,             //  0x83984073
+        DEVICE_START_COMMUNICATION,     //  0xA3
+        FLASHER_READY,                  //  0x4A
+        ACK,                            //  0xCC
+        NACK,
+};
+
+struct firmware_ctrl {
+    char *cmd;
+    unsigned char len;
+    char *n;
+} ;
+
+/*
+ * #define FWUPG_IDENTIFIER          0xBC D5 01 F4
+ * #define FWUPG_SYNC                0x83 98 40 73
+ */
+static struct firmware_ctrl fw_data[] = {
+    [TESEO_FLASHER_IDENTIFIER] = {
+            .cmd = (char *)(char[]){ 0xF4, 0x01, 0xD5, 0xBC},
+            .len = 4,
+            .n = "TESEO_FLASHER_IDENTIFIER",
+    },
+    [TESEO_FLASHER_SYNC] = {
+            .cmd =(char *)(char[]){ 0x73, 0x40, 0x98, 0x83 },
+            .len = 4,
+            .n = "TESEO_FLASHER_SYNC",
+    },
+    [DEVICE_START_COMMUNICATION] = {
+            .cmd = (char *)(char[]){0xA3},
+            .len = 1,
+            .n = "DEVICE_START_COMMUNICATION",
+    },
+    [FLASHER_READY] = {
+            .cmd = (char *)(char[]){0x4A},
+            .len = 1,
+            .n = "FLASHER_READY",
+    },
+    [ACK]  = {
+            .cmd = (char *)(char[]){0xCC},
+            .len = 1,
+            .n = "ACK",
+    },
+    [NACK]  = {
+            .cmd = (char *)(char[]){0xDD},
+            .len = 1,
+            .n = "NACK",
+        },
+};
+
+int Teseo_LIV3F::SendString(char *buf, int len)
+{
+    for (int i = 0; i < len; ++i) {
+        while (!_uart.writeable());
+        _uart.putc(buf[i]);
+        }
+}
+
+struct ImageOptions
+{
+    unsigned char eraseNVM;
+    unsigned char programOnly;
+    unsigned char reserved;
+    unsigned char baudRate;
+    unsigned int firmwareSize;
+    unsigned int firmwareCRC;
+    unsigned int nvmAddressOffset;
+    unsigned int nvmSize;
+} liv3f_img_option = {
+        .eraseNVM       = 1,
+        .programOnly    = 0,
+        .reserved       = 0,
+        .baudRate       = 1,
+        .firmwareSize   = 0,
+        .firmwareCRC    = 0,
+        .nvmAddressOffset = 0x00100000,
+        .nvmSize          = 0x00100000,
+
+};
+
+int Teseo_LIV3F::FwWaitAck()
+{
+    while (!_uart.readable());
+
+    char c = _uart.getc();
+
+    if (fw_data[ACK].cmd[0] == c) {
+        if (_serial_debug)
+            _serial_debug->printf("%s (0x%x)\n\r", _OK,  c);
+        return 0;
+    }
+
+    if (fw_data[NACK].cmd[0] == c) {
+        if (_serial_debug)
+            _serial_debug->printf("%s (%x)\n\r", _Failed, c);
+        return -1;
+    }
+
+    if (_serial_debug)
+        _serial_debug->printf("%s - Char not allowed (%x)\n\r", _Failed, c);
+    return -1;
+}
+
+bool Teseo_LIV3F::FirmwareUpdate(bool is_recovery, char *data,
+        unsigned int data_len,
+        unsigned long crc,
+        Serial *serial_debug)
+{
+    unsigned int i;
+
+    char _buf[4] = { 0xff, 0xff, 0xff, 0xff };
+
+    liv3f_img_option.firmwareSize   = data_len;
+    liv3f_img_option.firmwareCRC    = crc;
+
+    if (data == NULL || !data_len)
+        return false;
+
+    if (is_recovery)
+        Reset();
+
+    {
+
+        _uart.baud(FWU_UART_BAUD);
+
+#if 1
+        while (1) {
+            /* send TESEO_FLASHER_IDENTIFIER */
+/*
+ * Device is under reset. Host sends continuously “TESEO2_FLASHER_IDENTIFIER� word.
+ */
+            SendString(fw_data[TESEO_FLASHER_IDENTIFIER].cmd, fw_data[TESEO_FLASHER_IDENTIFIER].len);
+
+            /* try to read... TESEO_FLASHER_SYNC */
+            if (_uart.readable())
+                    for (i = 0; i < fw_data[TESEO_FLASHER_SYNC].len; ) {
+
+                        while (!_uart.readable());
+
+                        _buf[i] = _uart.getc();
+
+                        if (fw_data[TESEO_FLASHER_SYNC].cmd[i] == _buf[i]) {
+                                if (serial_debug)
+                                    serial_debug->printf("-- %d -- 0x%x -- ok--\n\r", i, _buf[i]);
+                                i++;
+                                goto exit_step_1; /* FMV: WA to have firmware update working.... */
+                            } else {
+                                i = 0;
+                            }
+                    }
+                    if (i == fw_data[TESEO_FLASHER_SYNC].len)
+                        goto exit_step_1;
+            }
+
+exit_step_1:
+
+    _uart.abort_read();
+
+    if (serial_debug)
+        serial_debug->printf("Got: %s from %s\n\r", fw_data[TESEO_FLASHER_SYNC].n, T3_name);
+
+/*
+ * Host sends “DEVICE_START_COMMUNICATION� word.
+ */
+    serial_debug->printf("\n\r%s Step: %s ",T3_name, fw_data[DEVICE_START_COMMUNICATION].n);
+    SendString(fw_data[DEVICE_START_COMMUNICATION].cmd, fw_data[DEVICE_START_COMMUNICATION].len);
+
+    FwWaitAck();
+
+/*
+ * Host sends the binary image options. Both host and
+ * device change UART baud rates. Host sends continuously
+ * the “FLASHER_READY� word.
+ */
+    if (serial_debug)
+        serial_debug->printf("%s Step: Send ImageOption\n\r",T3_name);
+
+    SendString((char*)&liv3f_img_option, sizeof(ImageOptions));
+
+    if (serial_debug)
+            serial_debug->printf("%s Step: Send %s\n\r",T3_name, fw_data[FLASHER_READY].n);
+
+    while (1) {
+        SendString(fw_data[FLASHER_READY].cmd, fw_data[FLASHER_READY].len);
+        if (_uart.readable())
+            goto exit_step_3;
+    }
+
+    exit_step_3:
+    FwWaitAck();
+
+    if (serial_debug)
+        serial_debug->printf("%s Step: Erasing flash area ",T3_name);
+
+
+    FwWaitAck();
+
+/*
+ * Device is erasing flash program. Host is waiting for an “ACK�.
+ */
+
+    if (serial_debug)
+        serial_debug->printf("%s Step: Erasing NVM ",T3_name);
+
+    while (!_uart.readable());
+
+    FwWaitAck();
+
+    if (serial_debug)
+        serial_debug->printf("%s Step: Sending data... ",T3_name);
+
+    for (i = 0; i < (data_len / (16*1024)); ++i) {
+        SendString(&data[i], 16*1024);
+
+        FwWaitAck();
+    }
+
+    serial_debug->printf("\n\r");
+    /*
+     * send remaining data...
+     */
+    if (data_len != (i * 16*1024)) {
+        SendString(&data[i*16*1024], data_len-i*16*1024);
+        FwWaitAck();
+        }
+    /*
+     * wait CRC ack
+     */
+    FwWaitAck();
+    }
+
+#else
+    //_uart.format(8, SerialBase::Forced0, 1);
+    while (1)
+            {
+                /* send TESEO_FLASHER_IDENTIFIER */
+                for (i = 0; i < fw_data[TESEO_FLASHER_IDENTIFIER].len; ++i) {
+                     while (!_uart.writeable());
+                    _uart.putc(fw_data[TESEO_FLASHER_IDENTIFIER].cmd[i]);
+                }
+
+
+                /* try to read... TESEO_FLASHER_SYNC */
+                //while (!_uart.readable());
+                for (i = 0; i < fw_data[TESEO_FLASHER_SYNC].len && _uart.readable(); )
+                    if (_uart.readable())
+                    {
+                        char c = _uart.getc();
+    /*
+                        if (!c)
+                                break;
+    */
+                        if (serial_debug)
+                            serial_debug->printf("%x vs %x\n\r", c, fw_data[TESEO_FLASHER_SYNC].cmd[i]);
+
+                        if (fw_data[TESEO_FLASHER_SYNC].cmd[i] == c)
+                            i++;
+                        else
+                            i = 0;
+                    }
+
+                if (i == fw_data[TESEO_FLASHER_SYNC].len && serial_debug)
+                    serial_debug->printf("Got %s from %s\n\r",fw_data[TESEO_FLASHER_SYNC].n, T3_name);
+            }
+        }
+#endif
+    if (serial_debug)
+        serial_debug->printf("END\n\r");
+
+    return true;
+}
+
+int Teseo_LIV3F::WakeUp()
+{
+    wait_ms(100);
+
+    _wakeup.write(1);
+
+    wait_ms(500);
+
+    _wakeup.write(0);
+
+    return 0;
+}
+
+bool Teseo_LIV3F::CheckPPSWorking()
+{
+    int val_0, val_1;
+
+    wait_ms(500);
+
+    val_0 = _pps.read();
+
+    wait_ms(500);
+    val_1 = _pps.read();
+
+    if (val_0 != val_1)
+        return true;
+
+    return false;
+}
+
+int Teseo_LIV3F::CRC_(char *buf, int size)
+{
+    int i = 0, ch = 0;
+
+    if (buf[0] == '$')
+        ++i;
+
+    if (size)
+        for (; i < size; ++i)
+            ch ^= buf[i];
+    else
+        for (; buf[i] != 0; ++i)
+            ch ^= buf[i];
+
+    return ch;
+}
+
+bool Teseo_LIV3F::WaitBooting(Timer *t, float timeout)
+{
+    unsigned int now = t->read_ms();;
+    while (1) {
+        if (CheckPPSWorking() == true)
+            return true;
+
+    if ((now + timeout*1000) < t->read_ms())
+            break;
+    }
+
+    return false;
+}
+
+void Teseo_LIV3F::SendCommand(enum Teseo_LIV3F::cmd_enum c)
+{
+    char crc[5];
+
+    sprintf(crc, "*%02X\n\r", CRC_(teseo_cmds[c].cmd, 0));
+
+    _uart_mutex_lock();
+    _uart_interleaded = true;
+    SendString(teseo_cmds[c].cmd, strlen(teseo_cmds[c].cmd));
+    SendString(crc, 5);
+    _uart_mutex_unlock();
+}
+
+char *Teseo_LIV3F::DetectSentence(const char *cmd, char *buf, unsigned long len)
+{
+    char *result = NULL;
+    unsigned int i = 0;
+    const unsigned long cmd_len = strlen(cmd);
+    len -= strlen(cmd);
+
+    while (!result && i < len) {
+        for (; buf[i] != '$' && i < len; ++i); /* 1. check '$' char */
+        if (i == len)
+            break; /* no more char.... */
+
+        ++i; /* to point to the char after '$' */
+
+        if (strncmp(&buf[i], cmd, cmd_len) == 0) {
+            result = &buf[i];
+        }
+    }
+
+    if (result) {
+        for (i = 0; result[i] != '*'; ++i);
+        result[i] = 0;
+    }
+#if 0
+    if (_serial_debug)
+            _serial_debug->printf("%s: %s: %s %s FOUND\n\r", T3_name, __FUNCTION__, cmd, result ? " " : "NOT");
+#endif
+    return result;
+}
+
+
+int Teseo_LIV3F::CheckI2C()
+{
+
+    if (!_i2c)
+        return -1;
+
+    _i2c->start();
+    int res = _i2c->write((TESEO_I2C_ADDRESS << 1) | 1);
+    _i2c->stop();
+    /*
+    *  @returns
+    *    '0' - NAK was received
+    *    '1' - ACK was received,
+    *    '2' - timeout
+    */
+    return res == 1 ? 0 : -1;
+}
+
+ int Teseo_LIV3F::ReadMessage(char *buf, unsigned long len, Timer *t, float timeout)
+{
+    memset(buf, 0, len);
+
+    for (unsigned int i = 0; i < len; ++i){
+        if (t) {
+            unsigned int now = t->read_ms();;
+            while (!_uart.readable() && (now + timeout*1000) > t->read_ms());
+        } else
+            while (!_uart.readable());
+        if (_uart.readable())
+            buf[i] = _uart.getc();;
+    }
+#if 0
+    if (_serial_debug) {
+            unsigned int i;
+            _serial_debug->printf("\n\r---------------------\n\r");
+            for (i = 0; i < len ; ++i)
+                _serial_debug->putc((int)buf[i]);
+            _serial_debug->printf("\n\r---------------------\n\r");
+    }
+#endif
+    return 0;
+}
+
+ void Teseo_LIV3F::RFTest(bool enable)
+ {
+    if (enable)
+        SendCommand(Teseo_LIV3F::RFTESTON);
+    else
+        SendCommand(Teseo_LIV3F::RFTESTOFF);
+ }
+
+void Teseo_LIV3F::ReadLoop(Serial *serial_debug)
+{
+    while (1)
+        if (_uart.readable()) {
+            int c = _uart.getc();
+            serial_debug->putc(c);
+        }
+}
+
+char *Teseo_LIV3F::ReadSentence(const char *cmd, char *buf, unsigned long len)
+{
+    int ret = ReadMessage(buf, len);
+    if (ret)
+        return NULL;
+     return DetectSentence(cmd, buf, len);
+}
+
+struct ___msg {
+    unsigned char len;
+    char *str;
+};
+
+
+static const struct ___msg teseo_msgs[] = {
+    [ NMEA_GPGGA ]   = {    .len = 5,   .str = "GPGGA",     },
+    [ NMEA_GPGLL ]   = {    .len = 5,   .str = "GPGLL",     },
+    [ NMEA_GNGSA ]   = {    .len = 5,   .str = "GNGSA",     },
+    [ NMEA_GPTXT ]   = {    .len = 5,   .str = "GPTXT",     },
+    [ NMEA_GPVTG ]   = {    .len = 5,   .str = "GPVTG",     },
+    [ NMEA_GPRMC ]   = {    .len = 5,   .str = "GPRMC",     },
+    [ NMEA_PSTMCPU ] = {    .len = 7,   .str = "PSTMCPU",   },
+    [ NMEA_PSTMVER ] = {    .len = 7,   .str = "PSTMVER",   },
+};
+
+
+enum nmea_msg_id Teseo_LIV3F::MsgDetect(char  *buf, int buf_len, Serial *serial_debug)
+{
+    int i;
+
+    if (buf[0] == '$')
+        ++buf;
+
+    for (i = 0; i < NMEA_END__; ++i)
+        if (memcmp((void*)teseo_msgs[i].str, (void*)buf, teseo_msgs[i].len) == 0)
+            return (enum nmea_msg_id) i;
+#if 0
+    if (serial_debug) {
+        serial_debug->puts("MESSAGE NOT FOUND: ");
+        for (int i = 0; i < 5; ++i)
+            serial_debug->putc(lbuf[i]);
+        serial_debug->puts("\n\r");
+    }
+#endif
+    return NMEA_END__;
+}
+
+void Teseo_LIV3F::UARTStreamProcess(Serial *serial_debug)
+{
+    enum nmea_msg_id id;
+    char c;
+
+    struct teseo_msg *msg = mpool.alloc();
+    msg->len = 0;
+
+    while (true) {
+          _uart_mutex_lock();
+#if 0
+          if (_uart_interleaded == true) {
+              msg->len = 0;
+              _uart_interleaded = false;
+              _uart_discard = true;
+          }
+#endif
+          if (_uart.readable()) {
+              c = _uart.getc();
+              _uart_mutex_unlock();
+              if (c == '$') {
+                  queue.put(msg);
+                  msg = mpool.alloc();
+                  msg->len = 0;
+                  _uart_discard = false;
+              }
+              if (!_uart_discard)
+                  msg->buf[msg->len++] = c;
+          } else {
+              _uart_mutex_unlock();
+              wait_us(100);
+          }
+    }
+}
+
+struct thr_data {
+    Teseo_LIV3F *gnss;
+    Serial *serial_debug;
+};
+
+static void Teseo_LIV3F_UARTStreamProcess(struct thr_data *data)
+{
+    data->gnss->UARTStreamProcess(data->serial_debug);
+}
+
+void Teseo_LIV3F::startListener(Serial *serial_debug)
+{
+    if (serialStreamThread.get_state() == Thread::Running)
+        return;
+
+    static struct thr_data data = {
+        .gnss = this,
+        .serial_debug = serial_debug,
+    };
+
+    serialStreamThread.start(Teseo_LIV3F_UARTStreamProcess, &data);
+}
+
+void Teseo_LIV3F::stopListener(Serial *serial_debug)
+{
+    if (serialStreamThread.get_state() != Thread::Running)
+        return;
+    serialStreamThread.terminate();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Teseo-LIV3F/Teseo-LIV3F.h	Mon Oct 23 07:11:35 2017 +0000
@@ -0,0 +1,130 @@
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (C) 2017  STMicroelectronics
+ * Author: Francesco M. Virlinzi  <francesco.virlinzi@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License V.2 ONLY.  See linux/COPYING for more information.
+ *
+ * -------------------------------------------------------------------------
+ */
+#ifndef __TESEO_LIV3F_H__
+#define __TESEO_LIV3F_H__
+
+#include "mbed.h"
+#include "rtos/rtos.h"
+
+extern char _OK[];
+extern char _Failed[];
+extern char X_Nucleo_name[];
+
+enum nmea_msg_id {
+    NMEA_GPGGA,
+    NMEA_GPGLL,
+    NMEA_GNGSA,
+    NMEA_GPTXT,
+    NMEA_GPVTG,
+    NMEA_GPRMC,
+    NMEA_PSTMCPU,
+    NMEA_PSTMVER,
+    NMEA_END__
+};
+
+#define TESEO_RXBUF_LEN 128
+
+struct teseo_msg {
+    unsigned char len;
+    char buf[TESEO_RXBUF_LEN];
+};
+
+
+class Teseo_LIV3F {
+public:
+    enum cmd_enum {
+        GETSWVER,
+        FORCESTANDBY,
+        RFTESTON,
+        RFTESTOFF,
+        LOWPOWER,
+        FWUPDATE,
+    };
+
+private:
+    DigitalOut   _reset;
+    DigitalIn    _pps;
+    DigitalOut   _wakeup;
+
+#define SDT_UART_BAUD                   9600
+#define FWU_UART_BAUD                   115200
+#define TESEO_I2C_ADDRESS               0x3A
+#if 1
+#define POWERON_STABLE_SIGNAL_DELAY_MS  150
+#else
+#define POWERON_STABLE_SIGNAL_DELAY_MS  500
+#endif
+
+    Serial      _uart;
+    bool        _uart_interleaded;
+    bool        _uart_discard;
+#if 1
+    Mutex   _uart_mutex;
+#define _uart_mutex_lock()      _uart_mutex.lock()
+#define _uart_mutex_unlock()    _uart_mutex.unlock()
+#else
+#define _uart_mutex_lock()
+#define _uart_mutex_unlock()
+#endif
+    Serial      *_serial_debug;
+    I2C         *_i2c;
+
+    int FwWaitAck();
+
+    int CRC_(char *buf, int size);
+
+    int SendString(char *buf, int len);
+
+    int ReadMessage(char *buf, unsigned long len, Timer *t = NULL, float timout = 0.0);
+
+    char *DetectSentence(const char *cmd, char *buf, unsigned long len);
+
+    Thread serialStreamThread;
+
+public:
+    enum nmea_msg_id MsgDetect(char *buf, int buf_len, Serial *serial_debug);
+
+    void UARTStreamProcess(Serial *serial_debug);
+
+    Teseo_LIV3F(PinName reset_pin, PinName wakeup_pin, PinName pps_pin, PinName uart_tx_pin, PinName uart_rx_pin, Serial *serial_debug = NULL);
+
+    Teseo_LIV3F(PinName reset_pin, PinName wakeup_pin, PinName pps_pin, PinName uart_tx_pin, PinName uart_rx_pin, I2C *i2c_bus, Serial *serial_debug = NULL);
+
+    void SendCommand(enum Teseo_LIV3F::cmd_enum c);
+
+    void Reset(Serial *serial_debug = NULL);
+
+    bool CheckPPSWorking();
+
+    int CheckI2C();
+
+    void RFTest(bool enable);
+
+    bool WaitBooting(Timer *t, float timout = 8.0);
+
+    int WakeUp();
+
+    int EnableLowPower();
+
+    char *ReadSentence(const char *cmd, char *buf, unsigned long len);
+
+    bool FirmwareUpdate(bool is_recovery, char *data, unsigned int data_len, unsigned long crc, Serial *serial_debug);
+
+    void ReadLoop(Serial *serial_debug);
+
+    void startListener(Serial *serial_debug);
+    void stopListener(Serial *serial_debug);
+
+    MemoryPool<struct teseo_msg, 8> mpool;
+    Queue<struct teseo_msg, 8>      queue;
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_IKS01A2.lib	Mon Oct 23 07:11:35 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/ST/code/X_NUCLEO_IKS01A2/#138a7a28bd21
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Oct 23 07:11:35 2017 +0000
@@ -0,0 +1,237 @@
+#include "mbed.h"
+#include "rtos/rtos.h"
+#include "Teseo-LIV3F.h"
+#include <cstdlib>
+#include <vector>
+#include "XNucleoIKS01A2.h"
+
+/*cose per gps*/
+static Thread t1;
+static Thread t2;
+
+static Mutex data_access;
+
+static Timer system_timer;
+static Serial usb_serial(USBTX, USBRX, 9600);
+static Serial *serial_debug= &usb_serial;
+
+
+static Teseo_LIV3F Teseo(D8,       D13,        D6,      PE_7,          PE_8,          &usb_serial);
+
+
+struct gps_coordinate{
+    float lat;
+    char lat_cardinal;
+    float longitud;
+    char long_cardinal;
+    bool valid;
+    
+    
+    
+    };
+    
+    gps_coordinate myPosition;
+
+
+
+/*cose per sensori*/
+
+static Thread t3;
+
+static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5);
+
+
+/* Retrieve the composing elements of the expansion board */
+static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer;
+static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor;
+static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor;
+static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro;
+static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer;
+
+void f1 (){
+    
+    enum nmea_msg_id id;
+    
+    
+  
+
+
+    Teseo.Reset(serial_debug);
+    Teseo.startListener(serial_debug);
+
+    while(1) {
+        osEvent evt = Teseo.queue.get();
+        if (evt.status == osEventMessage) {
+            struct teseo_msg *message = (struct teseo_msg *)evt.value.p;
+            if (message->len){
+                id = Teseo.MsgDetect(message->buf, message->len, serial_debug);
+                
+           }
+           
+           if (id==1){
+               
+               
+               
+               
+               //da qui converto il messaggio in coordinate//
+               data_access.lock();
+               
+               vector<char> pos;
+              
+               
+               //latitudine
+             // printf ("latitudine=");
+               
+               int cursor;
+               for (int i=7;;i++){
+                   cursor=i;
+                   if (message->buf[i] == ',')
+                        break;
+                   pos.push_back(message->buf[i]);
+                  
+                  
+                }
+            
+       
+                //ma quanto è cool? conversione da vector ad array e poi a float
+                myPosition.lat=  atof (&pos[0]);
+            //    printf ("%f",myPosition.lat);
+             //   printf ("  ");
+                
+                myPosition.lat_cardinal= message->buf[cursor+1];
+              //  printf ("%c   ",myPosition.lat_cardinal);
+                
+                pos.clear();
+                
+                
+              //  printf ("longitudine=");
+               
+               
+               for (int i=cursor+3;;i++){
+                   cursor=i;
+                   if (message->buf[i] == ',')
+                        break;
+                   pos.push_back(message->buf[i]);
+                  
+                  
+                }
+            
+       
+                
+                myPosition.longitud=  atof (&pos[0]);
+              //  printf ("%f",myPosition.longitud);
+              //  printf ("  ");
+                
+                myPosition.long_cardinal= message->buf[cursor+1];
+               // printf ("%c   ",myPosition.long_cardinal);
+                
+                for (int i=cursor+3;;i++){
+                   cursor=i;
+                   if (message->buf[i] == 'A' ){
+                        myPosition.valid=true;
+                        break;
+                    }else if (message->buf[i] == 'V' ) {
+                        myPosition.valid=false;
+                        break;
+                                                
+                    }
+                   
+                  
+                  
+                }
+                
+                if (myPosition.valid==true){
+                  // printf ("Valid");
+                   }
+                   
+                   
+                if (myPosition.valid==false){
+                   //printf ("Not Valid");
+                   }
+               
+               
+               data_access.unlock();
+               
+              // printf ("\n\r");
+               
+               }
+           
+
+            Teseo.mpool.free(message);
+        }
+
+    }
+    
+}
+
+
+
+void f2 (){
+   Thread::wait (1000);
+ 
+   Thread::wait (2000);
+   while (true){ 
+   Thread::wait (3000);
+        data_access.lock();
+    
+        printf ("lat:%f %c, lon:%f %c, %d\n\r",myPosition.lat,myPosition.lat_cardinal, myPosition.longitud, myPosition.long_cardinal, myPosition.valid );
+    
+    
+    
+        data_access.unlock();
+    }
+    
+}
+
+
+void accgyro_thread(){
+    
+    uint8_t id;
+  float value1, value2;
+  char buffer1[32], buffer2[32];
+  int32_t axes[3];
+  int32_t axesOld[3];
+  float odr =208.0f;
+  
+  
+  /* Enable all sensors */
+  
+  accelerometer->enable();
+  acc_gyro->enable_x();
+  acc_gyro->enable_g();
+  acc_gyro->set_g_odr (odr);
+  
+  while (true){
+    
+    Thread::wait (5000);
+    
+    
+    acc_gyro->get_g_axes(axes);
+    printf("LSM6DSL [gyro/mdps]:   %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
+    
+    
+    acc_gyro->get_x_axes(axes);
+   printf("LSM6DSL [acc/mg]:      %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
+
+    
+    
+    }
+    
+    
+}
+
+
+
+
+int main() {
+    
+    t1.start(f1);
+   
+    t2.start (f2);
+    
+    t3.start (accgyro_thread);
+    
+    
+    
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Mon Oct 23 07:11:35 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#5713cbbdb706
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Oct 23 07:11:35 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/b484a57bc302
\ No newline at end of file