Leon Wehmeier / Mbed OS fiasco_max32630

Dependencies:   SoftSerial MAX14690 Buffer

Fork of rtos_threading_with_callback by mbed_example

Files at this revision

API Documentation at this revision

Comitter:
lwehmeier
Date:
Fri Mar 30 10:32:10 2018 +0000
Parent:
2:bf699e054b34
Commit message:
implemented basic GPS read support, freed serial connection for uart jpg camera module

Changed in this revision

BufferedSerial/Buffer.lib Show annotated file Show diff for this revision Revisions of this file
BufferedSerial/BufferedSerial.cpp Show annotated file Show diff for this revision Revisions of this file
BufferedSerial/BufferedSerial.h Show annotated file Show diff for this revision Revisions of this file
GPS/GPS.cpp Show annotated file Show diff for this revision Revisions of this file
GPS/GPS.h Show annotated file Show diff for this revision Revisions of this file
SoftSerial.lib Show annotated file Show diff for this revision Revisions of this file
acquireDHT/getDHT.cpp Show annotated file Show diff for this revision Revisions of this file
gpsTask.cpp Show annotated file Show diff for this revision Revisions of this file
logger/logger.cpp Show annotated file Show diff for this revision Revisions of this file
logger/logger.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_app.json Show annotated file Show diff for this revision Revisions of this file
sdLogger/sdLogger.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/Buffer.lib	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/sam_grove/code/Buffer/#89564915f2a7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/BufferedSerial.cpp	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,161 @@
+/**
+ * @file    BufferedSerial.cpp
+ * @brief   Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author  sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BufferedSerial.h"
+#include <stdarg.h>
+
+BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
+    : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
+{
+    //attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
+    this->_buf_size = buf_size;
+    this->_tx_multiple = tx_multiple;   
+    return;
+}
+
+BufferedSerial::~BufferedSerial(void)
+{
+    //printf("destructor buffered serial\r\n");
+    RawSerial::attach(NULL, RawSerial::RxIrq);
+    RawSerial::attach(NULL, RawSerial::TxIrq);
+
+    return;
+}
+
+int BufferedSerial::readable(void)
+{
+    return _rxbuf.available();  // note: look if things are in the buffer
+}
+
+int BufferedSerial::writeable(void)
+{
+    return 1;   // buffer allows overwriting by design, always true
+}
+
+int BufferedSerial::getc(void)
+{
+    return _rxbuf;
+}
+
+int BufferedSerial::putc(int c)
+{
+    _txbuf = (char)c;
+    BufferedSerial::prime();
+
+    return c;
+}
+
+int BufferedSerial::puts(const char *s)
+{
+    if (s != NULL) {
+        const char* ptr = s;
+    
+        while(*(ptr) != 0) {
+            _txbuf = *(ptr++);
+        }
+        _txbuf = '\n';  // done per puts definition
+        BufferedSerial::prime();
+    
+        return (ptr - s) + 1;
+    }
+    return 0;
+}
+
+int BufferedSerial::printf(const char* format, ...)
+{
+    char buffer[this->_buf_size];
+    memset(buffer,0,this->_buf_size);
+    int r = 0;
+
+    va_list arg;
+    va_start(arg, format);
+    r = vsprintf(buffer, format, arg);
+    // this may not hit the heap but should alert the user anyways
+    if(r > this->_buf_size) {
+        error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r);
+        va_end(arg);
+        return 0;
+    }
+    va_end(arg);
+    r = BufferedSerial::write(buffer, r);
+
+    return r;
+}
+
+ssize_t BufferedSerial::write(const void *s, size_t length)
+{
+    if (s != NULL && length > 0) {
+        const char* ptr = (const char*)s;
+        const char* end = ptr + length;
+    
+        while (ptr != end) {
+            _txbuf = *(ptr++);
+        }
+        BufferedSerial::prime();
+    
+        return ptr - (const char*)s;
+    }
+    return 0;
+}
+
+
+void BufferedSerial::rxIrq(void)
+{
+    //printf("rx\r\n");
+    // read from the peripheral and make sure something is available
+    if(serial_readable(&_serial)) {
+        _rxbuf = serial_getc(&_serial); // if so load them into a buffer
+    }
+
+    return;
+}
+
+void BufferedSerial::txIrq(void)
+{
+    // see if there is room in the hardware fifo and if something is in the software fifo
+    while(serial_writable(&_serial)) {
+        if(_txbuf.available()) {
+            serial_putc(&_serial, (int)_txbuf.get());
+        } else {
+            // disable the TX interrupt when there is nothing left to send
+            RawSerial::attach(NULL, RawSerial::TxIrq);
+            break;
+        }
+    }
+
+    return;
+}
+
+void BufferedSerial::prime(void)
+{
+    //printf("prime\r\n");
+    // if already busy then the irq will pick this up
+    if(serial_writable(&_serial)) {
+        RawSerial::attach(NULL, RawSerial::TxIrq);    // make sure not to cause contention in the irq
+        BufferedSerial::txIrq();                // only write to hardware in one place
+        RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
+    }
+
+    return;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/BufferedSerial.h	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,140 @@
+
+/**
+ * @file    BufferedSerial.h
+ * @brief   Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BUFFEREDSERIAL_H
+#define BUFFEREDSERIAL_H
+ 
+#include "mbed.h"
+#include "MyBuffer.h"
+
+/** A serial port (UART) for communication with other serial devices
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ *  #include "mbed.h"
+ *  #include "BufferedSerial.h"
+ *
+ *  BufferedSerial pc(USBTX, USBRX);
+ *
+ *  int main()
+ *  { 
+ *      while(1)
+ *      {
+ *          Timer s;
+ *        
+ *          s.start();
+ *          pc.printf("Hello World - buffered\n");
+ *          int buffered_time = s.read_us();
+ *          wait(0.1f); // give time for the buffer to empty
+ *        
+ *          s.reset();
+ *          printf("Hello World - blocking\n");
+ *          int polled_time = s.read_us();
+ *          s.stop();
+ *          wait(0.1f); // give time for the buffer to empty
+ *        
+ *          pc.printf("printf buffered took %d us\n", buffered_time);
+ *          pc.printf("printf blocking took %d us\n", polled_time);
+ *          wait(0.5f);
+ *      }
+ *  }
+ * @endcode
+ */
+
+/**
+ *  @class BufferedSerial
+ *  @brief Software buffers and interrupt driven tx and rx for Serial
+ */  
+class BufferedSerial : public RawSerial 
+{
+private:
+    MyBuffer <char> _rxbuf;
+    MyBuffer <char> _txbuf;
+    uint32_t      _buf_size;
+    uint32_t      _tx_multiple;
+    
+public:
+ 
+    void rxIrq(void);
+    void txIrq(void);
+    void prime(void);
+    /** Create a BufferedSerial port, connected to the specified transmit and receive pins
+     *  @param tx Transmit pin
+     *  @param rx Receive pin
+     *  @param buf_size printf() buffer size
+     *  @param tx_multiple amount of max printf() present in the internal ring buffer at one time
+     *  @param name optional name
+     *  @note Either tx or rx may be specified as NC if unused
+     */
+    BufferedSerial(PinName tx, PinName rx, uint32_t buf_size = 256, uint32_t tx_multiple = 4,const char* name=NULL);
+    
+    /** Destroy a BufferedSerial port
+     */
+    virtual ~BufferedSerial(void);
+    
+    /** Check on how many bytes are in the rx buffer
+     *  @return 1 if something exists, 0 otherwise
+     */
+    virtual int readable(void);
+    
+    /** Check to see if the tx buffer has room
+     *  @return 1 always has room and can overwrite previous content if too small / slow
+     */
+    virtual int writeable(void);
+    
+    /** Get a single byte from the BufferedSerial Port.
+     *  Should check readable() before calling this.
+     *  @return A byte that came in on the Serial Port
+     */
+    virtual int getc(void);
+    
+    /** Write a single byte to the BufferedSerial Port.
+     *  @param c The byte to write to the Serial Port
+     *  @return The byte that was written to the Serial Port Buffer
+     */
+    virtual int putc(int c);
+    
+    /** Write a string to the BufferedSerial Port. Must be NULL terminated
+     *  @param s The string to write to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual int puts(const char *s);
+    
+    /** Write a formatted string to the BufferedSerial Port.
+     *  @param format The string + format specifiers to write to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual int printf(const char* format, ...);
+    
+    /** Write data to the Buffered Serial Port
+     *  @param s A pointer to data to send
+     *  @param length The amount of data being pointed to
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual ssize_t write(const void *s, std::size_t length);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS/GPS.cpp	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,292 @@
+#include "GPS.h"
+
+GPS::GPS(PinName tx, PinName rx) : _gps(tx, rx) {
+    _gps.baud(9600);
+    _gps.attach(&_gps, &BufferedSerial::rxIrq);
+    nmea_longitude = 0.0;
+    nmea_latitude = 0.0;
+    utc_time = 0;
+    ns = ' ';
+    ew = ' ';
+    lock = 0;
+    satelites = 0;
+    hdop = 0.0;
+    msl_altitude = 0.0;
+    msl_units = ' ';
+
+    rmc_status = ' ';
+    speed_k = 0.0;
+    course_d = 0.0;
+    date = 0;
+
+    dec_longitude = 0.0;
+    dec_latitude = 0.0;
+
+    gll_status = ' ';
+
+    course_t = 0.0; // ground speed true
+    course_t_unit = ' ';
+    course_m = 0.0; // magnetic
+    course_m_unit = ' ';
+    speed_k_unit = ' ';
+    speed_km = 0.0; // speek km/hr
+    speed_km_unit = ' ';
+
+    altitude_ft = 0.0;
+#ifdef OPEN_LOG
+    is_logging = false;
+#endif
+}
+
+#ifdef OPEN_LOG
+void GPS::start_log() {
+    is_logging = true;
+}
+
+void GPS::new_file(void) {
+    _openLog.newFile();
+}
+
+void GPS::stop_log(void) {
+    is_logging = false;
+}
+#endif
+
+float GPS::nmea_to_dec(float deg_coord, char nsew) {
+    int degree = (int)(deg_coord/100);
+    float minutes = deg_coord - degree*100;
+    float dec_deg = minutes / 60;
+    float decimal = degree + dec_deg;
+    if (nsew == 'S' || nsew == 'W') { // return negative
+        decimal *= -1;
+    }
+    return decimal;
+}
+unsigned printMsg = 0;
+int GPS::sample() {
+    int line_parsed = 0;
+
+
+    if (_gps.readable()) {
+        getline();
+    
+#ifdef OPEN_LOG
+        if (is_logging && lock) {
+            format_for_log();
+            _openLog.write(bfr);
+        }
+#endif
+        char dummy1,dummy2,dummy3, dummy4;
+        float dummyf;
+        // Check if it is a GPGGA msg (matches both locked and non-locked msg)
+        //GNGGA,165051.00,5620.69688,N,00248.59763,W,0,00,99.99,63.5,M,49.5,M,,*57
+        //$GNGGA,165649.00,5620.44393,N,00248.54510,W,1,05,5.63,-9.3,M,49.5,M,,*70
+        if (sscanf(msg, "GNGGA,%f,%f,%c,%f,%c,%d,%d,%f,%f,%c,%f,%c,,%c%c%c", &utc_time, &nmea_latitude, &ns, &nmea_longitude, &ew, &lock, &satelites, &hdop, &msl_altitude, &msl_units, &dummyf,&dummy1,&dummy2,&dummy3,&dummy4) >= 1) {
+            line_parsed = GGA;
+            //printf("GNGGA\r\n");
+        }
+        // Check if it is a GPRMC msg
+        //else if (sscanf(msg, "GNRMC,%f,%c,%f,%c,%f,%f,%d", &utc_time, &ns, &nmea_longitude, &ew, &speed_k, &course_d, &date) >= 1) {
+        //    line_parsed = RMC;
+        //}
+        // GLL - Geographic Position-Lat/Lon
+        //                  $GNGLL,5139.30741,N,04007.46879,E,162559.00,V,N*6B
+        if (sscanf(msg, "GNGLL,%f,%c,%f,%c,%f,%c,N%c%c%c", &nmea_latitude, &ns, &nmea_longitude, &ew, &utc_time, &gll_status, &dummy1, &dummy2, &dummy3) >= 1) {
+            line_parsed = GLL;
+            //printf("GNGLL\r\n");
+        }
+        // VTG-Course Over Ground and Ground Speed
+        //else if (sscanf(msg, "GNVTG,%f,%c,%f,%c,%f,%c,%f,%c", &course_t, &course_t_unit, &course_m, &course_m_unit, &speed_k, &speed_k_unit, &speed_km, &speed_km_unit) >= 1) {
+        //    line_parsed = VTG;
+        //}
+        
+        if(satelites == 0) {
+            lock = 0;
+        }
+    }
+    if (!lock) {
+        return NO_LOCK;
+    } else if (line_parsed) {
+        return line_parsed;
+    } else {
+        return NOT_PARSED;
+    }
+}
+
+
+// INTERNAL FUNCTINS ////////////////////////////////////////////////////////////
+float GPS::trunc(float v) {
+    if (v < 0.0) {
+        v*= -1.0;
+        v = floor(v);
+        v*=-1.0;
+    } else {
+        v = floor(v);
+    }
+    return v;
+}
+
+void GPS::getline() {
+    while (_gps.getc() != '$');   // wait for the start of a line
+    for (int i=0; i<1022; i++) {
+        msg[i] = _gps.getc();
+        if (msg[i] == '\r') {
+            msg[i] = 0;
+            return;
+        }
+    }
+    error("Overflow in getline");
+}
+
+void GPS::format_for_log() {
+    bfr[0] = '$';
+    for (int i = 0; i < 1022; i++) {
+        bfr[i+1] = msg[i];
+        if (msg[i] == 0 || msg[i] =='$') {
+            bfr[i+1] = '\r';
+            bfr[i+2] = '\n';
+            bfr[i+3] = 0;
+            return;
+        }
+    }
+    error("Overflow in format");
+}
+
+// GET FUNCTIONS /////////////////////////////////////////////////////////////////
+float GPS::get_msl_altitude() {
+    if (!lock)
+        return 0.0;
+    else
+        return msl_altitude;
+}
+
+int GPS::get_satelites() {
+        return satelites;
+}
+
+float GPS::get_nmea_longitude() {
+    if (!lock)
+        return 0.0;
+    else
+        return nmea_longitude;
+}
+
+float GPS::get_dec_longitude() {
+    dec_longitude = nmea_to_dec(nmea_longitude, ew);
+    if (!lock)
+        return 0.0;
+    else
+        return dec_longitude;
+}
+
+float GPS::get_nmea_latitude() {
+    if (!lock)
+        return 0.0;
+    else
+        return nmea_latitude;
+}
+
+float GPS::get_dec_latitude() {
+    dec_latitude = nmea_to_dec(nmea_latitude, ns);
+    if (!lock)
+        return 0.0;
+    else
+        return dec_latitude;
+}
+
+float GPS::get_course_t() {
+    if (!lock)
+        return 0.0;
+    else
+        return course_t;
+}
+
+float GPS::get_course_m() {
+    if (!lock)
+        return 0.0;
+    else
+        return course_m;
+}
+
+float GPS::get_speed_k() {
+    if (!lock)
+        return 0.0;
+    else
+        return speed_k;
+}
+
+float GPS::get_speed_km() {
+    if (!lock)
+        return 0.0;
+    else
+        return speed_km;
+}
+
+float GPS::get_altitude_ft() {
+    if (!lock)
+        return 0.0;
+    else
+        return 3.280839895*msl_altitude;
+}
+
+// NAVIGATION FUNCTIONS ////////////////////////////////////////////////////////////
+float GPS::calc_course_to(float pointLat, float pontLong) {
+    const double d2r = PI / 180.0;
+    const double r2d = 180.0 / PI;
+    double dlat = abs(pointLat - get_dec_latitude()) * d2r;
+    double dlong = abs(pontLong - get_dec_longitude()) * d2r;
+    double y = sin(dlong) * cos(pointLat * d2r);
+    double x = cos(get_dec_latitude()*d2r)*sin(pointLat*d2r) - sin(get_dec_latitude()*d2r)*cos(pointLat*d2r)*cos(dlong);
+    return atan2(y,x)*r2d;
+}    
+
+/*
+var y = Math.sin(dLon) * Math.cos(lat2);
+var x = Math.cos(lat1)*Math.sin(lat2) -
+        Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
+var brng = Math.atan2(y, x).toDeg();
+*/
+
+/*
+            The Haversine formula according to Dr. Math.
+            http://mathforum.org/library/drmath/view/51879.html
+                
+            dlon = lon2 - lon1
+            dlat = lat2 - lat1
+            a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
+            c = 2 * atan2(sqrt(a), sqrt(1-a)) 
+            d = R * c
+                
+            Where
+                * dlon is the change in longitude
+                * dlat is the change in latitude
+                * c is the great circle distance in Radians.
+                * R is the radius of a spherical Earth.
+                * The locations of the two points in 
+                    spherical coordinates (longitude and 
+                    latitude) are lon1,lat1 and lon2, lat2.
+*/
+double GPS::calc_dist_to_mi(float pointLat, float pontLong) {
+    const double d2r = PI / 180.0;
+    double dlat = pointLat - get_dec_latitude();
+    double dlong = pontLong - get_dec_longitude();
+    double a = pow(sin(dlat/2.0),2.0) + cos(get_dec_latitude()*d2r) * cos(pointLat*d2r) * pow(sin(dlong/2.0),2.0);
+    double c = 2.0 * asin(sqrt(abs(a)));
+    double d = 63.765 * c;
+    
+    return d;
+}
+
+double GPS::calc_dist_to_ft(float pointLat, float pontLong) {
+    return calc_dist_to_mi(pointLat, pontLong)*5280.0;
+}
+
+double GPS::calc_dist_to_km(float pointLat, float pontLong) {
+    return calc_dist_to_mi(pointLat, pontLong)*1.609344;
+}
+
+double GPS::calc_dist_to_m(float pointLat, float pontLong) {
+    return calc_dist_to_mi(pointLat, pontLong)*1609.344;
+}
+
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS/GPS.h	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,104 @@
+#include "mbed.h"
+#include "BufferedSerial.h"
+#ifndef MBED_GPS_H
+#define MBED_GPS_H
+
+#define NO_LOCK     1
+#define NOT_PARSED  2
+#define GGA         3
+#define GLL         4
+#define RMC         5
+#define VTG         6
+
+#define PI (3.141592653589793)
+
+/**  A GPS interface for reading from a Globalsat EM-406 GPS Module */
+class GPS {
+public:
+
+    /** Create the GPS interface, connected to the specified serial port
+     */    
+    GPS(PinName tx, PinName rx);
+    
+    /** Sample the incoming GPS data, returning whether there is a lock
+     * 
+     * @return 1 if there was a lock when the sample was taken (and therefore .longitude and .latitude are valid), else 0
+     */
+    int sample();
+    float get_nmea_longitude();
+    float get_nmea_latitude();
+    float get_dec_longitude();
+    float get_dec_latitude();
+    float get_msl_altitude();
+    float get_course_t();
+    float get_course_m();
+    float get_speed_k();
+    float get_speed_km();
+    int get_satelites();
+    float get_altitude_ft();
+    
+    // navigational functions
+    float calc_course_to(float, float);
+    double calc_dist_to_mi(float, float);
+    double calc_dist_to_ft(float, float);
+    double calc_dist_to_km(float, float);
+    double calc_dist_to_m(float, float);
+    
+    void onInterrupt(){
+        printf("%d\r\n", _gps.readable());
+    }
+#ifdef OPEN_LOG
+    void start_log(void);
+    void new_file(void);
+    void stop_log(void);
+#endif    
+    
+private:
+    float nmea_to_dec(float, char);
+    float trunc(float v);
+    void getline();
+    void format_for_log(void);
+    
+    BufferedSerial _gps;
+    char msg[1024];
+    char bfr[1030];
+    bool is_logging;
+#ifdef OPEN_LOG
+    Logger _openLog;
+#endif
+    // calculated values
+    float dec_longitude;
+    float dec_latitude;
+    float altitude_ft;
+    
+    // GGA - Global Positioning System Fixed Data
+    float nmea_longitude;
+    float nmea_latitude;    
+    float utc_time;
+    char ns, ew;
+    int lock;
+    int satelites;
+    float hdop;
+    float msl_altitude;
+    char msl_units;
+    
+    // RMC - Recommended Minimmum Specific GNS Data
+    char rmc_status;
+    float speed_k;
+    float course_d;
+    int date;
+    
+    // GLL
+    char gll_status;
+    
+    // VTG - Course over ground, ground speed
+    float course_t; // ground speed true
+    char course_t_unit;
+    float course_m; // magnetic
+    char course_m_unit;
+    char speed_k_unit;
+    float speed_km; // speek km/hr
+    char speed_km_unit;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerial.lib	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/Sissors/code/SoftSerial/#a0029614de72
--- a/acquireDHT/getDHT.cpp	Sun Feb 25 16:40:28 2018 +0000
+++ b/acquireDHT/getDHT.cpp	Fri Mar 30 10:32:10 2018 +0000
@@ -2,6 +2,7 @@
 #include "DHT.h"
 #include "rtos.h"
 #include "global.h"
+#include "logger.h"
 
 class DHTData
 {
@@ -16,6 +17,10 @@
                 float h   = dht.ReadHumidity();
                 humidity = h;
                 float dpf = dht.CalcdewPointFast(c, h);
+                char *buffer = new char[50];
+                sprintf(buffer, "Temperature: %3.2f, Humidity: %3.2f\r\n", c,h);
+                Logger::log(buffer);
+            
                 printf("DHT: Temperature in Celcius: %4.2f\r\n", c);
                 printf("DHT: Humidity is %4.2f, Dewpoint: %4.2f\r\n", h, dpf);
                 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gpsTask.cpp	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,35 @@
+#include "mbed.h"
+#include "GPS.h"
+#include "rtos.h"
+#include "global.h"
+
+class GpsTask
+{
+public:
+    static void run()
+    {
+        for (;;) {
+            //printf("GPS task\r\n");
+            if(gps.sample()>2)
+            {
+                float lon = gps.get_dec_longitude();
+                printf("Sat: %u\r\n", gps.get_satelites());
+                printf("%3.2f\r\n", lon);
+            }
+            //float lon = gps.get_dec_longitude();
+            //printf("Sat: %u\r\n", gps.get_satelites());
+            //printf("%3.2f\r\n", lon);
+            rtos::Thread::wait(250);
+        }
+    }
+    GpsTask()
+    {
+        registerThread(GpsTask::run);
+        //run();
+    }
+    static GPS gps;
+};
+GPS GpsTask::gps(P5_4, P5_3);
+
+// some witchcraft to register run function without touching anything outside our library
+static GpsTask _dummy;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/logger/logger.cpp	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,3 @@
+#include "logger.h"
+
+rtos::Queue<char, 24> Logger::q = rtos::Queue<char, 24>();
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/logger/logger.h	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "rtos.h"
+class SDLogger;
+class Logger
+{
+    friend SDLogger;
+public:
+    static bool log(char* msg){
+        q.put(msg, osWaitForever);
+        return true;
+    }
+protected:
+    static rtos::Queue<char, 24> q; //max sz == 24
+    static const unsigned maxQueueSize = 24;
+};
\ No newline at end of file
--- a/main.cpp	Sun Feb 25 16:40:28 2018 +0000
+++ b/main.cpp	Fri Mar 30 10:32:10 2018 +0000
@@ -8,6 +8,15 @@
 MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
 
 
+#include "platform/mbed_assert.h"
+#include "platform/mbed_debug.h"
+#include "platform/mbed_error.h"
+#include "platform/mbed_stats.h"
+#define MAX_THREAD_INFO 10
+mbed_stats_heap_t heap_info;
+mbed_stats_stack_t stack_info[ MAX_THREAD_INFO ];
+
+
 SPI spi(P5_1, P5_2, P5_0);
 I2C i2c(P5_7, P6_0); //sda, scl
 I2C i2c2(P3_4, P3_5); //sda, scl
@@ -52,11 +61,12 @@
             {
                 txBuf[i]|=(linkEnc.getNext()<<j);
             }
-        printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\r\n", txBuf[0], txBuf[1], txBuf[2], txBuf[3], txBuf[4], txBuf[5], txBuf[6], txBuf[7]);
+        //printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\r\n", txBuf[0], txBuf[1], txBuf[2], txBuf[3], txBuf[4], txBuf[5], txBuf[6], txBuf[7]);
         spi.write((char*)txBuf, 8, (char*)0, 0);
     }
 }
 int main() {
+    set_time(0);
     setupTx();
     thread_txRF.start(txData);
     
@@ -68,6 +78,38 @@
     printf("MAIN: started %u registered application threads\r\n", numRegisteredThreads);
     
     while(1)
-        wait(1024);
+    {/*
+        printf("\r\nRuntimeStats:");
+        printf("\r\n\tSystem uptime in s: %d", time(NULL));
+        printf("\r\nMemoryStats:");
+        mbed_stats_heap_get( &heap_info );
+        printf("\r\n\tBytes allocated currently: %d", heap_info.current_size);
+        printf("\r\n\tMax bytes allocated at a given time: %d", heap_info.max_size);
+        printf("\r\n\tCumulative sum of bytes ever allocated: %d", heap_info.total_size);
+        printf("\r\n\tCurrent number of bytes allocated for the heap: %d", heap_info.reserved_size);
+        printf("\r\n\tCurrent number of allocations: %d", heap_info.alloc_cnt);
+        printf("\r\n\tNumber of failed allocations: %d", heap_info.alloc_fail_cnt);
+        
+        mbed_stats_stack_get( &stack_info[0] );
+        printf("\r\nCumulative Stack Info:");
+        printf("\r\n\tMaximum number of bytes used on the stack: %d", stack_info[0].max_size);
+        printf("\r\n\tCurrent number of bytes allocated for the stack: %d", stack_info[0].reserved_size);
+        printf("\r\n\tNumber of stacks stats accumulated in the structure: %d", stack_info[0].stack_cnt);
+        
+        mbed_stats_stack_get_each( stack_info, MAX_THREAD_INFO );
+        printf("\r\nThread Stack Info:");
+        for(int i=0;i < MAX_THREAD_INFO; i++)
+        {
+            if(stack_info[i].thread_id != 0)
+            {
+                printf("\r\n\tThread: %d", i);
+                printf("\r\n\t\tMaximum number of bytes used on the stack: %d", stack_info[i].max_size);
+                printf("\r\n\t\tCurrent number of bytes allocated for the stack: %d", stack_info[i].reserved_size);
+                printf("\r\n\t\tNumber of stacks stats accumulated in the structure: %d", stack_info[i].stack_cnt); 
+            }
+        }
+        */
+        rtos::Thread::wait(60000);
+    }
 }
  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_app.json	Fri Mar 30 10:32:10 2018 +0000
@@ -0,0 +1,3 @@
+{
+        "macros": ["DEBUG_ISR_STACK_USAGE=1", "MBED_HEAP_STATS_ENABLED=1", "MBED_STACK_STATS_ENABLED=1"]
+}
\ No newline at end of file
--- a/sdLogger/sdLogger.cpp	Sun Feb 25 16:40:28 2018 +0000
+++ b/sdLogger/sdLogger.cpp	Fri Mar 30 10:32:10 2018 +0000
@@ -6,19 +6,20 @@
 #include "SDBlockDevice.h"
 #include "LittleFileSystem.h"
 #include "FATFileSystem.h"
+#include "logger.h"
 
 static void return_error(int ret_val){
   if (ret_val)
     printf("SD: Failure. %d\r\n", ret_val);
-  else
-    printf("SD: done.\r\n");
+  //else
+    //printf("SD: done.\r\n");
 }
 
 static void errno_error(void* ret_val){
   if (ret_val == NULL)
     printf("SD:  Failure. %d \r\n", errno);
-  else
-    printf("SD:  done.\r\n");
+  //else
+    //printf("SD:  done.\r\n");
 }
 class SDLogger
 {
@@ -26,9 +27,11 @@
     static void run()
     {
         for (;;) {
-            char buffer[200];
-            sprintf(buffer, "Pressure: %4.1f \t Temperature: %3.2f\t Altitude: %4.1f\r\nACC1:%2.1f;%2.1f;%2.1f\r\nACC2:%2.1f;%2.1f;%2.1f\r\n", pressure, temperature, altitude, (acc1[0]), (acc1[1]), (acc1[2]),(acc2[0]), (acc2[1]), (acc2[2]));
-            SD_appendData(buffer);
+            //char buffer[200];
+            //sprintf(buffer, "Pressure: %4.1f \t Temperature: %3.2f\t Altitude: %4.1f\r\nACC1:%2.1f;%2.1f;%2.1f\r\nACC2:%2.1f;%2.1f;%2.1f\r\n", pressure, temperature, altitude, (acc1[0]), (acc1[1]), (acc1[2]),(acc2[0]), (acc2[1]), (acc2[2]));
+            char* msg = (char*) Logger::q.get(osWaitForever).value.p;
+            SD_appendData(msg);
+            delete[] msg;
             rtos::Thread::wait(6000);//10 datasets per minute. TODO: log current system time
         }
     }
@@ -57,19 +60,19 @@
   fclose(fd);
   printf("SD:  done.\r\n");
 }
-static void SD_appendData(char* data)
+static void SD_appendData(const char* data)
 {
 
-  printf("SD: Opening file data.txt.\r\n");
+  //printf("SD: Opening file data.txt.\r\n");
   FILE* fd = fopen("/fs/data.txt", "w+");
   errno_error(fd);
 
   fprintf(fd, "%s", data);
-  printf("SD: Writing done.\r\n");
+  //printf("SD: Writing done.\r\n");
 
-  printf("SD: Closing file.\r\n");
+  //printf("SD: Closing file.\r\n");
   fclose(fd);
-  printf("SD: done.\r\n");
+  //printf("SD: done.\r\n");
 }
     static SDBlockDevice bd;//PinName mosi, PinName miso, PinName sclk, PinName cs
     static FATFileSystem fs;