This program simply connects to a HTS221 I2C device to read Temperature

Dependencies:   FXOS8700CQ mbed

Files at this revision

API Documentation at this revision

Comitter:
JMF
Date:
Fri Jul 08 23:52:38 2016 +0000
Child:
1:af7a42f7d465
Commit message:
Initial version of AT&T_Avnet Shape Hackathon WNC Shield board

Changed in this revision

HTS221.h Show annotated file Show diff for this revision Revisions of this file
HTS221Reg.h Show annotated file Show diff for this revision Revisions of this file
SerialBuffered/SerialBuffered.cpp Show annotated file Show diff for this revision Revisions of this file
SerialBuffered/SerialBuffered.h Show annotated file Show diff for this revision Revisions of this file
hts221_driver.cpp 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.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTS221.h	Fri Jul 08 23:52:38 2016 +0000
@@ -0,0 +1,92 @@
+
+#ifndef HTS221_H_
+#define HTS221_H_
+
+class HTS221 {
+public:
+    HTS221(void);
+    int begin(void);
+    int activate(void);
+    int deactivate(void);
+
+    int bduActivate(void);
+    int bduDeactivate(void);
+
+    int readHumidity(void);
+    double readTemperature(void);
+private:
+    int storeCalibration(void);
+    unsigned char _h0_rH, _h1_rH;
+    unsigned int  _T0_degC, _T1_degC;
+    unsigned int  _H0_T0, _H1_T0;
+    unsigned int  _T0_OUT, _T1_OUT;
+    double _temperature;
+    int _humidity;
+    unsigned char _address;
+
+    unsigned char readRegister(unsigned char slaveAddress, unsigned char regToRead);
+    int writeRegister(unsigned char slaveAddress, unsigned char regToWrite, unsigned char dataToWrite);
+};
+
+#define HTS221_ADDRESS     0x5F
+
+//Define a few of the registers that we will be accessing on the HTS221
+#define WHO_AM_I           0x0F
+#define WHO_AM_I_RETURN    0xBC //This read-only register contains the device identifier, set to BCh
+
+#define AVERAGE_REG        0x10 // To configure humidity/temperature average.
+#define AVERAGE_DEFAULT    0x1B
+
+/*
+ * [7] PD: power down control
+ * (0: power-down mode; 1: active mode)
+ *
+ * [6:3] Reserved
+ *
+ * [2] BDU: block data update
+ * (0: continuous update; 1: output registers not updated until MSB and LSB reading)
+The BDU bit is used to inhibit the output register update between the reading of the upper
+and lower register parts. In default mode (BDU = ?0?), the lower and upper register parts are
+updated continuously. If it is not certain whether the read will be faster than output data rate,
+it is recommended to set the BDU bit to ?1?. In this way, after the reading of the lower (upper)
+register part, the content of that output register is not updated until the upper (lower) part is
+read also.
+ *
+ * [1:0] ODR1, ODR0: output data rate selection (see table 17)
+ */
+#define CTRL_REG1          0x20
+#define POWER_UP           0x80
+#define BDU_SET            0x4
+#define ODR0_SET           0x1   // setting sensor reading period 1Hz
+
+#define CTRL_REG2          0x21
+#define CTRL_REG3          0x22
+#define REG_DEFAULT        0x00
+
+#define STATUS_REG         0x27
+#define TEMPERATURE_READY  0x1
+#define HUMIDITY_READY     0x2
+
+#define HUMIDITY_L_REG     0x28
+#define HUMIDITY_H_REG     0x29
+#define TEMP_L_REG         0x2A
+#define TEMP_H_REG         0x2B
+/*
+ * calibration registry should be read for temperature and humidity calculation.
+ * Before the first calculation of temperature and humidity,
+ * the master reads out the calibration coefficients.
+ * will do at init phase
+ */
+#define CALIB_START        0x30
+#define CALIB_END          0x3F
+/*
+#define CALIB_T0_DEGC_X8   0x32
+#define CALIB_T1_DEGC_X8   0x33
+#define CALIB_T1_T0_MSB    0x35
+#define CALIB_T0_OUT_L     0x3C
+#define CALIB_T0_OUT_H     0x3D
+#define CALIB_T1_OUT_L     0x3E
+#define CALIB_T1_OUT_H     0x3F
+ */
+ 
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTS221Reg.h	Fri Jul 08 23:52:38 2016 +0000
@@ -0,0 +1,69 @@
+
+#ifndef HTS221REG_H_
+#define HTS221REG_H_
+
+
+#define HTS221_ADDRESS     0x5F
+
+//Define a few of the registers that we will be accessing on the HTS221
+#define WHO_AM_I           0x0F
+#define WHO_AM_I_RETURN    0xBC //This read-only register contains the device identifier, set to BCh
+
+#define AVERAGE_REG        0x10 // To configure humidity/temperature average.
+#define AVERAGE_DEFAULT    0x1B
+
+/*
+ * [7] PD: power down control
+ * (0: power-down mode; 1: active mode)
+ *
+ * [6:3] Reserved
+ *
+ * [2] BDU: block data update
+ * (0: continuous update; 1: output registers not updated until MSB and LSB reading)
+The BDU bit is used to inhibit the output register update between the reading of the upper
+and lower register parts. In default mode (BDU = ?0?), the lower and upper register parts are
+updated continuously. If it is not certain whether the read will be faster than output data rate,
+it is recommended to set the BDU bit to ?1?. In this way, after the reading of the lower (upper)
+register part, the content of that output register is not updated until the upper (lower) part is
+read also.
+ *
+ * [1:0] ODR1, ODR0: output data rate selection (see table 17)
+ */
+#define CTRL_REG1          0x20
+#define POWER_UP           0x80
+#define BDU_SET            0x4
+#define ODR0_SET           0x1   // setting sensor reading period 1Hz
+
+#define CTRL_REG2          0x21
+#define CTRL_REG3          0x22
+#define REG_DEFAULT        0x00
+
+#define STATUS_REG         0x27
+#define TEMPERATURE_READY  0x1
+#define HUMIDITY_READY     0x2
+
+#define HUMIDITY_L_REG     0x28
+#define HUMIDITY_H_REG     0x29
+#define TEMP_L_REG         0x2A
+#define TEMP_H_REG         0x2B
+/*
+ * calibration registry should be read for temperature and humidity calculation.
+ * Before the first calculation of temperature and humidity,
+ * the master reads out the calibration coefficients.
+ * will do at init phase
+ */
+#define CALIB_START        0x30
+#define CALIB_END          0x3F
+/*
+#define CALIB_T0_DEGC_X8   0x32
+#define CALIB_T1_DEGC_X8   0x33
+#define CALIB_T1_T0_MSB    0x35
+#define CALIB_T0_OUT_L     0x3C
+#define CALIB_T0_OUT_H     0x3D
+#define CALIB_T1_OUT_L     0x3E
+#define CALIB_T1_OUT_H     0x3F
+ */
+
+
+
+#endif /* HTS221REG_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered/SerialBuffered.cpp	Fri Jul 08 23:52:38 2016 +0000
@@ -0,0 +1,93 @@
+
+#include "mbed.h"
+#include "SerialBuffered.h"
+
+SerialBuffered::SerialBuffered( PinName tx, PinName rx, size_t bufferSize ) : Serial(  tx,  rx ) 
+{
+    m_buffSize = 0;
+    m_contentStart = 0;
+    m_contentEnd = 0;
+    m_timeout = -1.0;
+    _txpin = tx;
+    _rxpin = rx;
+    
+    attach( this, &SerialBuffered::handleInterrupt );
+    
+    m_buff = (uint8_t *) malloc( bufferSize );
+    if( m_buff )
+        m_buffSize = bufferSize;
+}
+
+
+SerialBuffered::~SerialBuffered()
+{
+    if( m_buff )
+        free( m_buff );
+}
+
+void SerialBuffered::setTimeout( float seconds )
+{
+    m_timeout = seconds;
+}
+    
+size_t SerialBuffered::readBytes( uint8_t *bytes, size_t requested )
+{
+    int i = 0;
+
+    for( ; i < requested; )
+    {
+        int c = getc();
+        if( c < 0 )
+            break;
+        bytes[i] = c;
+        i++;
+    }
+    
+    return i;
+        
+}
+
+
+int SerialBuffered::_getc()
+{
+    m_timer.reset();
+    m_timer.start();
+    while (m_contentStart == m_contentEnd) {
+        if (m_timeout >= 0 &&  m_timer.read() >= m_timeout )
+            return EOF;
+        wait_ms( 1 );
+    }
+
+    m_timer.stop();
+   
+    int     nbp = (m_contentStart + 1) % m_buffSize;
+    uint8_t result = m_buff[m_contentStart];
+    m_contentStart = nbp;
+    return result;    
+}
+
+//int Serial::_getc() {
+//    return _base_getc();
+//}
+
+int SerialBuffered::_putc(int c) {
+    return _base_putc(c);
+}
+
+int SerialBuffered::readable()
+{
+    return m_contentStart != m_contentEnd ;
+}
+
+void SerialBuffered::handleInterrupt()
+{
+    while (serial_readable(&_serial)) {
+        char c_in = _base_getc();
+        int  nbp = (m_contentEnd + 1) % m_buffSize;
+        
+        if (nbp != m_contentStart) {
+            m_buff[m_contentEnd] = c_in;
+            m_contentEnd = nbp;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered/SerialBuffered.h	Fri Jul 08 23:52:38 2016 +0000
@@ -0,0 +1,61 @@
+#pragma once
+
+// This is a buffered serial reading class, using the serial interrupt introduced in mbed library version 18 on 17/11/09
+
+// In the simplest case, construct it with a buffer size at least equal to the largest message you 
+// expect your program to receive in one go.
+
+class SerialBuffered : public Serial
+{
+public:
+    SerialBuffered( PinName tx, PinName rx, size_t bufferSize );
+    virtual ~SerialBuffered();
+    
+    int readable(); // returns 1 if there is a character available to read, 0 otherwise
+    
+    void setTimeout( float seconds );    // maximum time in seconds that getc() should block 
+                                         // while waiting for a character
+                                         // Pass -1 to disable the timeout.
+    
+    size_t readBytes( uint8_t *bytes, size_t requested );    // read requested bytes into a buffer, 
+                                                             // return number actually read, 
+                                                             // which may be less than requested if there has been a timeout
+    
+    void disable_flow_ctrl(void) { serial_set_flow_control(&_serial, FlowControlNone, NC, NC); }
+//    void suspend(bool enable) {
+//        if (enable) {
+//            serial_irq_set(&_serial, (SerialIrq)RxIrq, 0);
+//                serial_break_set(&_serial);
+//                _serial.uart->ENABLE         = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos);
+//        } else {
+//                _serial.uart->ENABLE         = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
+//                serial_break_clear(&_serial);
+//            _serial.uart->EVENTS_RXDRDY  = 0;
+//            // dummy write needed or TXDRDY trails write rather than leads write.
+//            //  pins are disconnected so nothing is physically transmitted on the wire
+//            _serial.uart->TXD            = 0;
+//            serial_irq_set(&_serial, (SerialIrq)RxIrq, 1);
+//        }
+//    }
+
+protected:
+    PinName _txpin;
+    PinName _rxpin;
+
+protected:
+    virtual int _getc();
+    virtual int _putc(int c);
+    
+private:
+    
+    void handleInterrupt();
+    
+   
+    uint8_t *m_buff;            // points at a circular buffer, containing data from m_contentStart, for m_contentSize bytes, wrapping when you get to the end
+    volatile uint16_t  m_contentStart;   // index of first bytes of content
+    volatile uint16_t  m_contentEnd;     // index of bytes after last byte of content
+    uint16_t m_buffSize;
+    float m_timeout;
+    Timer m_timer;
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hts221_driver.cpp	Fri Jul 08 23:52:38 2016 +0000
@@ -0,0 +1,247 @@
+
+#include "HTS221.h"
+
+
+// ------------------------------------------------------------------------------
+//jmf  -- define I2C pins and functions to read & write to I2C device
+
+#include <string>
+#include "mbed.h"
+
+I2C i2c(PTC11, PTC10);    //SDA, SCL -- define the I2C pins being used
+
+// Read a single unsigned char from addressToRead and return it as a unsigned char
+unsigned char HTS221::readRegister(unsigned char slaveAddress, unsigned char ToRead)
+{
+    char data = ToRead;
+
+    i2c.write(slaveAddress, &data, 1, 0);
+    i2c.read(slaveAddress, &data, 1, 0);
+    return data;
+}
+
+// Writes a single unsigned char (dataToWrite) into regToWrite
+int HTS221::writeRegister(unsigned char slaveAddress, unsigned char regToWrite, unsigned char dataToWrite)
+{
+    const char data[] = {regToWrite, dataToWrite};
+
+    return i2c.write(slaveAddress,data,2,0);
+}
+
+
+//jmf end
+// ------------------------------------------------------------------------------
+
+static inline int humidityReady(uint8_t data) {
+    return (data & 0x02);
+}
+static inline int temperatureReady(uint8_t data) {
+    return (data & 0x01);
+}
+
+
+HTS221::HTS221(void) : _address(HTS221_ADDRESS)
+{
+    _temperature = 0;
+    _humidity = 0;
+}
+
+
+int HTS221::begin(void)
+{
+    uint8_t data;
+
+    data = readRegister(_address, WHO_AM_I);
+    if (data == WHO_AM_I_RETURN){
+        if (activate()){
+            storeCalibration();
+            return data;
+        }
+    }
+
+    return 0;
+}
+
+int
+HTS221::storeCalibration(void)
+{
+    uint8_t data;
+    uint16_t tmp;
+
+    for (int reg=CALIB_START; reg<=CALIB_END; reg++) {
+        if ((reg!=CALIB_START+8) && (reg!=CALIB_START+9) && (reg!=CALIB_START+4)) {
+
+            data = readRegister(HTS221_ADDRESS, reg);
+
+            switch (reg) {
+            case CALIB_START:
+                _h0_rH = data;
+                break;
+            case CALIB_START+1:
+            _h1_rH = data;
+            break;
+            case CALIB_START+2:
+            _T0_degC = data;
+            break;
+            case CALIB_START+3:
+            _T1_degC = data;
+            break;
+
+            case CALIB_START+5:
+            tmp = _T0_degC;
+            _T0_degC = (data&0x3)<<8;
+            _T0_degC |= tmp;
+
+            tmp = _T1_degC;
+            _T1_degC = ((data&0xC)>>2)<<8;
+            _T1_degC |= tmp;
+            break;
+            case CALIB_START+6:
+            _H0_T0 = data;
+            break;
+            case CALIB_START+7:
+            _H0_T0 |= data<<8;
+            break;
+            case CALIB_START+0xA:
+            _H1_T0 = data;
+            break;
+            case CALIB_START+0xB:
+            _H1_T0 |= data <<8;
+            break;
+            case CALIB_START+0xC:
+            _T0_OUT = data;
+            break;
+            case CALIB_START+0xD:
+            _T0_OUT |= data << 8;
+            break;
+            case CALIB_START+0xE:
+            _T1_OUT = data;
+            break;
+            case CALIB_START+0xF:
+            _T1_OUT |= data << 8;
+            break;
+
+
+            case CALIB_START+8:
+            case CALIB_START+9:
+            case CALIB_START+4:
+            //DO NOTHING
+            break;
+
+            // to cover any possible error
+            default:
+                return false;
+            } /* switch */
+        } /* if */
+    }  /* for */
+    return true;
+}
+
+
+int
+HTS221::activate(void)
+{
+    uint8_t data;
+
+    data = readRegister(_address, CTRL_REG1);
+    data |= POWER_UP;
+    data |= ODR0_SET;
+    writeRegister(_address, CTRL_REG1, data);
+
+    return true;
+}
+
+
+int HTS221::deactivate(void)
+{
+    uint8_t data;
+
+    data = readRegister(_address, CTRL_REG1);
+    data &= ~POWER_UP;
+    writeRegister(_address, CTRL_REG1, data);
+    return true;
+}
+
+
+int
+HTS221::bduActivate(void)
+{
+    uint8_t data;
+
+    data = readRegister(_address, CTRL_REG1);
+    data |= BDU_SET;
+    writeRegister(_address, CTRL_REG1, data);
+
+    return true;
+}
+
+
+int
+HTS221::bduDeactivate(void)
+{
+    uint8_t data;
+
+    data = readRegister(_address, CTRL_REG1);
+    data &= ~BDU_SET;
+    writeRegister(_address, CTRL_REG1, data);
+    return true;
+}
+
+
+int
+HTS221::readHumidity(void)
+{
+    uint8_t data   = 0;
+    uint16_t h_out = 0;
+    double h_temp  = 0.0;
+    double hum     = 0.0;
+
+    data = readRegister(_address, STATUS_REG);
+
+    if (data & HUMIDITY_READY) {
+        data = readRegister(_address, HUMIDITY_H_REG);
+        h_out = data << 8;  // MSB
+        data = readRegister(_address, HUMIDITY_L_REG);
+        h_out |= data;      // LSB
+
+        // Decode Humidity
+        hum = ((int16_t)(_h1_rH) - (int16_t)(_h0_rH))/2.0;  // remove x2 multiple
+
+        // Calculate humidity in decimal of grade centigrades i.e. 15.0 = 150.
+        h_temp = (((int16_t)h_out - (int16_t)_H0_T0) * hum) / ((int16_t)_H1_T0 - (int16_t)_H0_T0);
+        hum    = ((int16_t)_h0_rH) / 2.0; // remove x2 multiple
+        _humidity = (int16_t)((hum + h_temp)); // provide signed % measurement unit
+    }
+    return _humidity;
+}
+
+
+
+double
+HTS221::readTemperature(void)
+{
+    uint8_t data   = 0;
+    uint16_t t_out = 0;
+    double t_temp  = 0.0;
+    double deg     = 0.0;
+
+    data = readRegister(_address, STATUS_REG);
+
+    if (data & TEMPERATURE_READY) {
+
+        data= readRegister(_address, TEMP_H_REG);
+        t_out = data  << 8; // MSB
+        data = readRegister(_address, TEMP_L_REG);
+        t_out |= data;      // LSB
+
+        // Decode Temperature
+        deg    = ((int16_t)(_T1_degC) - (int16_t)(_T0_degC))/8.0; // remove x8 multiple
+
+        // Calculate Temperature in decimal of grade centigrades i.e. 15.0 = 150.
+        t_temp = (((int16_t)t_out - (int16_t)_T0_OUT) * deg) / ((int16_t)_T1_OUT - (int16_t)_T0_OUT);
+        deg    = ((int16_t)_T0_degC) / 8.0;     // remove x8 multiple
+        _temperature = deg + t_temp;   // provide signed celsius measurement unit
+    }
+
+    return _temperature;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jul 08 23:52:38 2016 +0000
@@ -0,0 +1,273 @@
+#include "mbed.h"
+#include <cctype>
+#include <string>
+#include "SerialBuffered.h"
+#include "HTS221.h"
+
+// comment out the following line if color is not supported on the terminal
+#define USE_COLOR
+#ifdef USE_COLOR
+ #define BLK "\033[30m"
+ #define RED "\033[31m"
+ #define GRN "\033[32m"
+ #define YEL "\033[33m"
+ #define BLU "\033[34m"
+ #define MAG "\033[35m"
+ #define CYN "\033[36m"
+ #define WHT "\033[37m"
+ #define DEF "\033[39m"
+#else
+ #define BLK
+ #define RED
+ #define GRN
+ #define YEL
+ #define BLU
+ #define MAG
+ #define CYN
+ #define WHT
+ #define DEF
+#endif
+
+#define MDM_DBG_OFF                             0
+#define MDM_DBG_AT_CMDS                         (1 << 0)
+int mdm_dbgmask = MDM_DBG_OFF;
+
+Serial         pc(USBTX, USBRX);
+SerialBuffered mdm(PTD3, PTD2, 128);
+DigitalOut     led_red(LED_RED);
+DigitalOut     led_green(LED_GREEN);
+
+DigitalOut  mdm_uart2_rx_boot_mode_sel(PTC17);  // on powerup, 0 = boot mode, 1 = normal boot
+DigitalOut  mdm_power_on(PTB9);                 // 0 = turn modem on, 1 = turn modem off (should be held high for >5 seconds to cycle modem)
+DigitalOut  mdm_wakeup_in(PTC2);                // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield
+
+DigitalOut  shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active
+DigitalOut  mdm_uart1_cts(PTD0);
+
+#define TOUPPER(a) (a) //toupper(a)
+
+const char ok_str[] = "OK";
+const char error_str[] = "ERROR";
+
+#define MDM_OK                                  0
+#define MDM_ERR_TIMEOUT                         -1
+
+#define MAX_AT_RSP_LEN                          255
+
+//
+// The modem will return strings of HEX encoded data.  This function takes
+// a pointer to a string of HEX ASCII data and converts it into a string
+// of ASCII data.  It takes a pointer to the string of HEX ASCII data and
+// a pointer to the destination string.  It returns the number of characters
+// it converted.
+//
+int DecodeASCIIstr(string& ins, string& outs) {
+    int val, n = 0;
+    char ts[2];
+    
+    while(n<ins.length()) {
+        val = atoi((const char*)ins[n])*16+atoi((const char*)ins[n+1]);
+        sprintf(ts,"%c",val);
+        outs.append(ts);
+        n += 2;
+     }
+     return outs.length();
+}
+
+
+//
+// Modem expects data to be passed to it in the form of HEX encoded strings.  This
+// function takes a pointer to a users supplied ASCII string, and converts it into
+// an ASCII string of equivelent HEX numbers encoded as a string.  The function takes
+// a pointer to the users input string, and a pointer to the output string.  The
+// function returns the number of characters converted or 0 if an error occurs or more
+// than 750 characters were converted.  The 750 chacter limit is because the modem
+// will only accept up to 1500 characters, and the converted srings will be 2x the
+// input string since the hex representation of 1 character is a two digit hex value.
+//
+int CreateASCIIstr(string& in, string& out) {
+    int i = 0;
+    char ts[3];
+    
+    if( in.length() > 749 )
+      return 0;
+
+    while(in[i] != 0x00) {
+        sprintf(ts,"%02X", in[i]);
+        out.append(ts);
+        i++;
+        }
+    return out.length();
+}
+
+
+
+ssize_t mdm_getline(char *buff, size_t size, int timeout_ms) {
+    int cin = -1;
+    int cin_last;
+    
+    if (NULL == buff || size == 0) {
+        return -1;
+    }
+
+    size_t len = 0;
+    Timer timer;
+    timer.start();
+    while ((len < (size-1)) && (timer.read_ms() < timeout_ms)) {
+        if (mdm.readable()) {
+            cin_last = cin;
+            cin = mdm.getc();
+            if (isprint(cin)) {
+                buff[len++] = (char)cin;
+                continue;
+            } else if (('\r' == cin_last) && ('\n' == cin)) {
+                break;
+            }
+        }
+        wait_ms(1);
+    }
+    buff[len] = NULL;
+    
+    return len;
+}
+
+int mdm_sendAtCmd(const char *cmd, const char **rsp_list, int timeout_ms) {
+    if (cmd && strlen(cmd) > 0) {
+        if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
+            printf(MAG "ATCMD: " DEF "--> " GRN "%s" DEF "\n", cmd);
+        }
+        mdm.printf("%s\r\n", cmd);
+    }
+    
+    if (rsp_list) {
+        Timer   timer;
+        char    rsp[MAX_AT_RSP_LEN+1];
+        int     len;
+        
+        timer.start();
+        while (timer.read_ms() < timeout_ms) {
+            len = mdm_getline(rsp, sizeof(rsp), timeout_ms - timer.read_ms());
+            
+            if (len < 0)
+                return MDM_ERR_TIMEOUT;
+
+            if (len == 0)
+                continue;
+                
+            if (mdm_dbgmask & MDM_DBG_AT_CMDS) {
+                printf(MAG "ATRSP: " DEF "<-- " CYN "%s" DEF "\n", rsp);
+            }
+        
+            if (rsp_list) {
+                int rsp_idx = 0;
+                while (rsp_list[rsp_idx]) {
+                    if (strcasecmp(rsp, rsp_list[rsp_idx]) == 0) {
+                        return rsp_idx;
+                    }
+                    rsp_idx++;
+                }
+            }
+        }
+        return MDM_ERR_TIMEOUT;
+    }
+    return MDM_OK;
+}
+
+int mdm_init(void) {
+    // disable signal level translator
+    shield_3v3_1v8_sig_trans_ena = 0;
+
+    // power modem on //off
+    mdm_power_on = 0; //1;
+    
+    // insure modem boots into normal operating mode
+    // and does not go to sleep when powered on
+    mdm_uart2_rx_boot_mode_sel = 1;
+    mdm_wakeup_in = 1;
+    
+    // initialze comm with the modem
+    mdm.baud(115200);
+    mdm_uart1_cts = 0;
+    
+    // enable the signal level translator to start
+    // modem reset process (modem will be powered down)
+    shield_3v3_1v8_sig_trans_ena = 1;
+    
+    // Give the modem 60 secons to start responding by
+    // sending simple 'AT' commands to modem once per second.
+    Timer timer;
+    timer.start();
+    while (timer.read() < 60) {
+        const char * rsp_lst[] = { ok_str, error_str, NULL };
+        int rc = mdm_sendAtCmd("AT", rsp_lst, 500);
+        if (rc == 0)
+            return timer.read();
+        wait_ms(1000 - (timer.read_ms() % 1000));
+        pc.printf("\r%d",timer.read_ms()/1000);
+    }
+    return false;       
+}
+
+#define CTOF(x)  ((x)*1.8+32)
+
+int main() {
+    HTS221 hts221;
+    pc.baud(115200);
+    int i,
+        CreateASCIIstr(string& in, string& out), 
+        DecodeASCIIstr(string& ins, string& outs);
+    string ins, outs;
+    
+    void hts221_init(void);
+
+    pc.printf(BLU "Hello World from AT&T Shape!\r\n");
+    pc.printf(GRN "Initialize the HTS221\n\r");
+
+    i = hts221.begin();  
+    if( i ) 
+        pc.printf(BLU "HTS221 Detected! (0x%02X)\n\r",i);
+    else
+        pc.printf(RED "HTS221 NOT DETECTED!!\n\r");
+
+    printf("Temp  is: %0.2f F \n\r",CTOF(hts221.readTemperature()));
+    printf("Humid is: %02d %%\n\r",hts221.readHumidity());
+    
+    // Initialize the modem
+    printf(GRN "Modem initializing... will take up to 60 seconds" DEF "\r\n");
+    i=mdm_init();
+    if (!i) {
+        pc.printf(RED "Modem initialization failed!" DEF "\n");
+        while (1);
+    }
+    
+    // Now that the modem is up and running, transfer characters
+    // between the pc terminal and the modem to give the user
+    // a virtual terminal to the modem.
+    pc.printf(YEL "\rAT command interface ready, completed in %d seconds.  You may now type AT commands" DEF "\r\n",i);
+   
+    while(1) {
+        if(pc.readable()) {
+            char char_in = TOUPPER(pc.getc());
+            
+            static char last_char_in = 0;
+
+            if (('\r' == char_in) || ('\n' == char_in))
+            {
+                if (('\r' == char_in) || ('\r' != last_char_in))
+                {
+                    mdm.puts("\r\n");
+                }
+            }
+            else
+            {
+                pc.putc(char_in);
+                mdm.putc(char_in);
+            }
+            last_char_in = char_in;
+        }
+        if(mdm.readable()) {
+            char ser_char = mdm.getc();
+                pc.putc(ser_char);
+            }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Jul 08 23:52:38 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6c34061e7c34
\ No newline at end of file