kh

Dependencies:   Adafruit_SGP30_mbed mbed CCS811 mbed-rtos ALPHASENSE Adafruit_ADS1015_ BME680

Files at this revision

API Documentation at this revision

Comitter:
etiene32
Date:
Wed Mar 06 14:03:41 2019 +0000
Commit message:
,hb

Changed in this revision

ALPHASENSE.lib Show annotated file Show diff for this revision Revisions of this file
Adafruit_ADS1015.lib Show annotated file Show diff for this revision Revisions of this file
Adafruit_SGP30_mbed.lib Show annotated file Show diff for this revision Revisions of this file
BME680.lib Show annotated file Show diff for this revision Revisions of this file
CCS811.lib Show annotated file Show diff for this revision Revisions of this file
HPMA115S0/HPMA115S0.cpp Show annotated file Show diff for this revision Revisions of this file
HPMA115S0/HPMA115S0.h Show annotated file Show diff for this revision Revisions of this file
PMS7003/PMS7003.cpp Show annotated file Show diff for this revision Revisions of this file
PMS7003/PMS7003.h Show annotated file Show diff for this revision Revisions of this file
SDS011/NovaSDS011.cpp Show annotated file Show diff for this revision Revisions of this file
SDS011/NovaSDS011.h Show annotated file Show diff for this revision Revisions of this file
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
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/ALPHASENSE.lib	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/etiene32/code/ALPHASENSE/#ed1f58bf0dc3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_ADS1015.lib	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/etiene32/code/Adafruit_ADS1015_/#cf2317282e61
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_SGP30_mbed.lib	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/etiene32/code/Adafruit_SGP30_mbed/#fedfd309fb3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BME680.lib	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/yangcq88517/code/BME680/#85088a918342
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CCS811.lib	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/andcor02/code/CCS811/#64a96d555ef0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HPMA115S0/HPMA115S0.cpp	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,149 @@
+#include "HPMA115S0.h"
+
+HPMA115S0::HPMA115S0(Serial* serial)
+{
+    this->serial = serial;
+    serial->baud(9600);
+    pm10_count = 0;
+    pm2_5_count = 0;
+}
+
+float HPMA115S0::getPM10()
+{
+    return pm10_count;
+}
+
+float HPMA115S0::getPM2_5()
+{
+    return pm2_5_count;
+}
+
+void HPMA115S0::read() 
+{
+    uint8_t msg[4]={0x68,0x01,0x04,0x93};
+    uint8_t ack[8]={0,0,0,0,0,0,0,0};
+    printf("%d %d  %d %d %d %d\r\n",ack[0],ack[1],ack[2],ack[3],ack[4],ack[5]);
+    serial->write(msg, sizeof(msg), NULL);
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+       //serial->read(ack, sizeof(ack), NULL);
+       for(int i=0;i<8;i++){
+            ack[i]=serial->getc();
+        }
+    }
+    printf("%d %d %d %d %d %d %d %d\r\n",ack[0],ack[1],ack[2],ack[3],ack[4],ack[5],ack[6],ack[7]);
+    pm10_count = ((ack[6] << 8) + ack[7]);
+    pm2_5_count = ((ack[4] << 8) + ack[5]);
+}
+
+void HPMA115S0::start() 
+{
+    uint8_t msg[4]={0x68,0x01,0x01,0x96};
+    uint8_t ack[2]={0,0};
+    printf("%d %d \r\n",ack[0],ack[1]);
+    serial->write(msg, sizeof(msg), NULL);
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+       //serial->read(ack, sizeof(ack), NULL);
+        ack[0]=serial->getc();
+        ack[1]=serial->getc();
+    }
+    printf("%d %d \r\n",ack[0],ack[1]);
+}
+
+
+void HPMA115S0::stop() 
+{
+    uint8_t msg[4]={0x68,0x01,0x02,0x95};
+    uint8_t ack[2]={0,0};
+    printf("%d %d \r\n",ack[0],ack[1]);
+    serial->write(msg, sizeof(msg), NULL);
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+       //serial->read(ack, sizeof(ack), NULL);
+        ack[0]=serial->getc();
+        ack[1]=serial->getc();
+    }
+    printf("%d %d \r\n",ack[0],ack[1]);
+}
+
+
+void HPMA115S0::set_customer_coef() 
+{
+    uint8_t msg[5]={0x68,0x01,0x08,0x64, 0x2A};
+    uint8_t ack[2]={0,0};
+    printf("%d %d \r\n",ack[0],ack[1]);
+    serial->write(msg, sizeof(msg), NULL);
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+       //serial->read(ack, sizeof(ack), NULL);
+        ack[0]=serial->getc();
+        ack[1]=serial->getc();
+    }
+    printf("%d %d \r\n",ack[0],ack[1]);
+}
+
+
+void HPMA115S0::read_customer_coef() 
+{
+    uint8_t msg[4]={0x68,0x01,0x10,0x87};
+    uint8_t ack[2]={0,0};
+    printf("%d %d \r\n",ack[0],ack[1]);
+    serial->write(msg, sizeof(msg), NULL);
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+       //serial->read(ack, sizeof(ack), NULL);
+        ack[0]=serial->getc();
+        ack[1]=serial->getc();
+    }
+    printf("%d %d \r\n",ack[0],ack[1]);
+}
+
+
+void HPMA115S0::stop_autosend() 
+{
+    uint8_t msg[4]={0x68,0x01,0x20,0x77};
+    char ack[2]={0,0};
+    printf("%d %d \r\n",ack[0],ack[1]);
+    serial->write(msg, sizeof(msg), NULL);
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+       //serial->read(ack, sizeof(ack), NULL);
+        ack[0]=serial->getc();
+        ack[1]=serial->getc();
+    }
+    printf("%d %d\r\n",ack[0],ack[1]);
+}
+
+void HPMA115S0::enable_autosend() 
+{
+    uint8_t msg[4]={0x68,0x01,0x40,0x57};
+    uint8_t ack[2]={0,0};
+    printf("%d %d \r\n",ack[0],ack[1]);
+    serial->write(msg, sizeof(msg), NULL);
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+       //serial->read(ack, sizeof(ack), NULL);
+        ack[0]=serial->getc();
+        ack[1]=serial->getc();
+    }
+    printf("%d %d \r\n",ack[0],ack[1]);
+}
+
+void HPMA115S0::read_autosend() 
+{
+    printf("yo\r\n");
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+        serial->read(buffer, PACKET_SIZE, NULL);
+        for(int i=1;i<33;i++){
+            printf("%d ",buffer[i]);
+        }
+        if(buffer[1]==0x42){
+            if(buffer[2]==0x4d){
+                pm10_count = ((buffer[9] << 8) + buffer[10]);
+                pm2_5_count = ((buffer[7] << 8) + buffer[8]);
+            }
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HPMA115S0/HPMA115S0.h	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "mbed.h"
+
+class HPMA115S0
+{
+
+public:
+    HPMA115S0(Serial* serial);
+    void read();
+    void start();
+    void stop();
+    void set_customer_coef();
+    void read_customer_coef();
+    void stop_autosend();
+    void enable_autosend();
+    void read_autosend();
+    float getPM10();
+    float getPM2_5();
+private:
+    Serial* serial;
+    float pm10_count;
+    float pm2_5_count;
+
+    static const uint8_t PACKET_SIZE = 32;
+    uint8_t buffer[PACKET_SIZE];
+
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PMS7003/PMS7003.cpp	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,36 @@
+#include "PMS7003.h"
+
+PMS7003::PMS7003(Serial* serial)
+{
+    this->serial = serial;
+    serial->baud(9600);
+    pm10_count = 0;
+    pm2_5_count = 0;
+}
+
+float PMS7003::getPM10()
+{
+    return pm10_count;
+}
+
+float PMS7003::getPM2_5()
+{
+    return pm2_5_count;
+}
+
+float PMS7003::getPM1()
+{
+    return pm1_count;
+}
+
+void PMS7003::read() 
+{
+    serial->read(buffer, PACKET_SIZE, NULL);
+    if(buffer[1]==0x42){
+        if(buffer[2]==0x4d){
+            pm10_count = ((buffer[9] << 8) + buffer[10]);
+            pm2_5_count = ((buffer[7] << 8) + buffer[8]);
+            pm1_count = ((buffer[5] << 8) + buffer[6]);
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PMS7003/PMS7003.h	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "mbed.h"
+
+class PMS7003
+{
+
+public:
+    PMS7003(Serial* serial);
+    void read();
+    float getPM10();
+    float getPM2_5();
+    float getPM1();
+private:
+    Serial* serial;
+    float pm10_count;
+    float pm2_5_count;
+    float pm1_count;
+
+    static const uint8_t PACKET_SIZE = 32;
+    uint8_t buffer[PACKET_SIZE];
+
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDS011/NovaSDS011.cpp	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,33 @@
+#include "NovaSDS011.h"
+
+NovaSDS011::NovaSDS011(Serial* serial)
+{
+    this->serial = serial;
+    serial->baud(9600);
+    pm10_count = 0;
+    pm2_5_count = 0;
+}
+
+float NovaSDS011::getPM10()
+{
+    return pm10_count;
+}
+
+float NovaSDS011::getPM2_5()
+{
+    return pm2_5_count;
+}
+
+void NovaSDS011::read() 
+{
+    while(serial->readable()==0){}
+    if(serial->readable()==1){
+        serial->read(buffer, PACKET_SIZE, NULL);
+        printf("%d %d %d %d %d %d %d %d %d %d\r\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],buffer[8],buffer[9]);
+    }
+    if(buffer[9] == 0xAB) {
+        printf("yo\r\n");
+        pm10_count = ((buffer[6] << 8) + buffer[3]) / 10.0;
+        pm2_5_count = ((buffer[4] << 8) + buffer[3]) / 10.0;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDS011/NovaSDS011.h	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "mbed.h"
+
+class NovaSDS011
+{
+
+public:
+    NovaSDS011(Serial* serial);
+    void read();
+    float getPM10();
+    float getPM2_5();
+private:
+    Serial* serial;
+    float pm10_count;
+    float pm2_5_count;
+
+    static const uint8_t PACKET_SIZE = 10;
+    uint8_t buffer[PACKET_SIZE];
+
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Teseo-LIV3F/Teseo-LIV3F.cpp	Wed Mar 06 14:03:41 2019 +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	Wed Mar 06 14:03:41 2019 +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/main.cpp	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,146 @@
+#include "mbed.h"
+#include "CCS811.h"
+#include "Alphasense.h"
+#include "NovaSDS011.h"
+#include "PMS7003.h"
+#include "HPMA115S0.h"
+#include "BME680.h"
+#include "Adafruit_SGP30.h"
+#include "Teseo-LIV3F.h"
+
+CCS811 ccs811(D14, D15);
+BME680 BME(D14,D15,0);
+Adafruit_SGP30 SGP30(D14, D15);
+
+Serial HPMA(A0,A1);
+HPMA115S0 HoneyWell(&HPMA);
+
+Serial novaSerial(A4,A5);
+NovaSDS011 nova(&novaSerial);
+
+Serial PMS(D3,D5);
+PMS7003 TowerPlant(&PMS);
+
+DigitalOut set(D5);
+
+
+InterruptIn button(USER_BUTTON);
+
+DigitalOut led(LED1);
+
+int ordo[20]={151500,0,1,0,151600,1,0,1,151600,1,1,1,151600,1,0,0,151600,0,0,1};
+
+int i=0;
+int j=0;
+
+double delay = 0.5; // 500 ms
+uint16_t eco2, tvoc;
+
+void pressed()
+{
+    uint8_t trame[100];
+    uint8_t oct=0,oct2=0;
+    i++;
+    oct2 = ordo[i] << 2;
+    oct |= oct2;
+    oct2 = ordo[i+1] << 1;
+    oct |= oct2;
+    oct2 = ordo[i+2];
+    oct |= oct2;
+    trame[j]=oct;
+    j++;
+    printf("flag ok\r\n");
+    printf("\n!!! ALARM 1 Triggered !!!\r\n");
+    if(ordo[i]==1){
+        printf("Capteur 0 actif - Erreur \r\n");
+        trame[j]=1;
+        j++;
+    }
+    if(ordo[i]==1){
+        printf("Capteur 1 actif - Heure\r\n");
+        trame[j]=2;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 2 actif - N/A \r\n");
+        trame[j]=12;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 4 actif - N/A\r\n");
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 5 actif - GNSS \r\n");
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 6 actif - O3\r\n"); /* Alphasense */
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 7 actif - NO2\r\n"); /* Alphasense */
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 8 actif - CO2\r\n"); /* Rechercher */
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 9 actif - eCO2 / VOC \r\n"); /* BME690, CCS811, SGP30 */
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 10 actif - PM2.5 / PM10 \r\n"); /* plantower, omron, sds */
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 11 actif - Pression \r\n");
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 12 actif - Humidite\r\n");
+        trame[j]=42;
+        j++;
+    }
+    i++;
+    if(ordo[i]==1){
+        printf("Capteur 13 actif - Temperature\r\n"); /* LM35 */
+        trame[j]=42;
+        j++;
+    }
+    printf("Taille = %d La trame = \r\n",j);
+    for(uint8_t t=0;t<j;t++){
+        printf("%d \r\n",trame[t]);
+    }   
+    j=0;
+}
+
+int main()
+{
+    ccs811.init();
+    // Assign functions to button
+    button.fall(&pressed);
+
+    while (1) {
+        led = !led;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Wed Mar 06 14:03:41 2019 +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	Wed Mar 06 14:03:41 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file