Raghav Ganesh
/
AvnetATT_shape_hackathon
This program simply connects to a HTS221 I2C device to read Temperature
Revision 0:9d5134074d84, committed 2016-07-08
- 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
--- /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