/* * 2012 Visual Micro Debug Services * * Some elements based on various examples found on the internet, * can be freely copied, modified and re-distributed * * Firmata elements and general licences of note ... * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * See file LICENSE for further informations on licensing terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #define VM_DEBUG_ENABLE 1 //#define VM_DEBUG_START_PRE_DELAY 2000 #include "VM_DBG.h" #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_NET_CONSOLE #include <Bridge.h> #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_SOFTWARESERIAL #include <SoftwareSerial.h> #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_COSA #include "Cosa/IOStream/Driver/UART.hh" #include "Cosa/Types.h" #include "Cosa/Bits.h" #include "Cosa/RTC.hh" #endif #if VM_DEBUG_MEM_CHECK == VM_DEBUG_ENABLE //#include "VM_mem_check.h" #endif //added for cosa #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_COSA unsigned long VisualMicroDebug::DBG_Millis() { return RTC::millis(); } #else unsigned long VisualMicroDebug::DBG_Millis() { return millis(); } #endif VisualMicroDebug::VisualMicroDebug() { //ensure x millis between each debug packet //wait if we have to //try to prevent new users from overloading bandwidth and filling windows buffer //can be overriden via preferences //defaults to 50ms; needs to allow time for windows to recover if it pauses, so we need to be slower than the extensions and debugger can process + a bit } void VisualMicroDebug::outPacketStart() { outPacketStart(false); } void VisualMicroDebug::outPacketStart(bool noWait) { #if defined(VM_DEBUG_BANDWIDTH_THROTTLE_MS) if (!noWait) { //1501 - for cosa //while (millis()-lastPacketMS<VM_DEBUG_BANDWIDTH_THROTTLE_MS) while (DBG_Millis()-lastPacketMS<VM_DEBUG_BANDWIDTH_THROTTLE_MS) { delay(3); } } //XXX: this should really be after packet end! //1501 for cosa - lastPacketMS=millis(); lastPacketMS=DBG_Millis(); #endif } /* void VisualMicroDebug::missedBreakpoint(uint8_t breakpoint_index) { missed_breakpoints[missed_breakpoints_counter]=breakpoint_index; } void VisualMicroDebug::missedBreakpointsFlush() { uint8_t i; for(i=0;i<missed_breakpoints_counter;i++) { //missed_breakpoints[missed_breakpoints_counter]=breakpoint_index; transport->print("VMDPM_"); transport->print(i); transport->println("_VMDPM"); delay(5); } } */ #if defined(VM_DEBUG_USE_PRINT_F) void VisualMicroDebug::p(char *fmt, ... ){ char tmp[128]; // resulting string limited to 128 chars va_list args; va_start (args, fmt ); vsnprintf(tmp, 128, fmt, args); va_end (args); transport->print(tmp); } #endif /* #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_UART void VisualMicroDebug::begin(UARTClass *theSerial) { transport = theSerial; while(!*theSerial) {;} } void VisualMicroDebug::begin(UARTClass *theSerial, long baud) { //delay(500); transport = theSerial; while(!*theSerial) {;} //transport->begin(baud); //wait for laonardo port to connect. hack! we know it can only be main serial! //while(!*theSerial) //{;} } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_USART void VisualMicroDebug::begin(USARTClass *theSerial) { transport = theSerial; while(!*theSerial) {;} } void VisualMicroDebug::begin(USARTClass *theSerial, long baud) { //delay(500); transport = theSerial; while(!*theSerial) {;} //transport->begin(baud); //wait for laonardo port to connect. hack! we know it can only be main serial! //while(!*theSerial) //{;} } #endif */ #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_Uart void VisualMicroDebug::begin(Uart *theSerial) { transport = theSerial; int n=0; while(!*theSerial) { if (n>25) break; n++; delay(200); } } void VisualMicroDebug::begin(Uart *theSerial, unsigned long baud) { transport = theSerial; int n=0; while(!*theSerial) { if (n>25) break; n++; delay(200); } } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_TEENSY void VisualMicroDebug::begin(usb_serial_class *theSerial) { transport = theSerial; int n=0; while(!*theSerial) { if (n>25) break; n++; delay(200); } //delay(VM_DEBUG_START_PRE_DELAY); } void VisualMicroDebug::begin(usb_serial_class *theSerial, unsigned long baud) { //delay(500); transport = theSerial; int n=0; while(!*theSerial) { if (n>25) break; n++; delay(200); } //delay(VM_DEBUG_START_PRE_DELAY); //transport->begin(baud); //wait for laonardo port to connect. hack! we know it can only be main serial! //while(!*theSerial) //{;} } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_USB void VisualMicroDebug::begin(Serial_ *theSerial) { transport = theSerial; //wait for leonardo port to connect. hack! we know it can only be main serial! //exit wait after 5 seconds assume user has disconnected board from pc but left debug running? int n=0; while(!*theSerial) { if (n>25) break; n++; delay(200); } //delay(VM_DEBUG_START_PRE_DELAY); } void VisualMicroDebug::begin(Serial_ *theSerial, unsigned long baud) { transport = theSerial; transport->begin(baud); //wait for leonardo port to connect. hack! we know it can only be main serial! //exit wait after 5 seconds assume user has disconnected board from pc but left debug running? int n=0; while(!*theSerial) { if (n>25) break; n++; delay(200); } //delay(VM_DEBUG_START_PRE_DELAY); } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_NET_CONSOLE void VisualMicroDebug::begin(ConsoleClass *theSerial, unsigned long baud) { transport = theSerial; //hack //console crashes if bridge not started Bridge.begin(); Console.begin(); //transport->begin(); //delay(VM_DEBUG_START_PRE_DELAY); } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_TTYUART void VisualMicroDebug::begin(TTYUARTClass *theSerial, unsigned long baud) { transport = theSerial; transport->begin(baud); //delay(VM_DEBUG_START_PRE_DELAY); } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_USBSERIAL void VisualMicroDebug::begin(USBSerial *theSerial, unsigned long baud) { transport = theSerial; transport->begin(baud); //delay(VM_DEBUG_START_PRE_DELAY); } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_COSA void VisualMicroDebug::begin(UART *theSerial, unsigned long int baud) { RTC::begin(); // Create an instance of the iostream and bind to the uart IOStream dbgSerial(theSerial); transport = &dbgSerial; reader = theSerial; reader->begin(baud); } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_UART void VisualMicroDebug::begin(UARTClass *theSerial, unsigned long baud) { transport = theSerial; transport->begin(baud); //delay(VM_DEBUG_START_PRE_DELAY); } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_USART void VisualMicroDebug::begin(USARTClass *theSerial, unsigned long baud) { transport = theSerial; transport->begin(baud); //delay(VM_DEBUG_START_PRE_DELAY); } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_HARDWARESERIAL void VisualMicroDebug::begin(HardwareSerial *theSerial) { transport = theSerial; } void VisualMicroDebug::begin(HardwareSerial *theSerial, unsigned long baud) { transport = theSerial; transport->begin(baud); //delay(VM_DEBUG_START_PRE_DELAY); } #endif #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_SOFTWARESERIAL void VisualMicroDebug::begin(SoftwareSerial *theSerial) { transport = theSerial; transport->listen(); //delay(VM_DEBUG_START_PRE_DELAY); //try to stop initial rubbish in debug console //#if VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_SOFTWARESERIAL //#endif } void VisualMicroDebug::begin(SoftwareSerial *theSerial, unsigned long baud) { transport = theSerial; transport->begin(baud); transport->listen(); //delay(VM_DEBUG_START_PRE_DELAY); //try to stop initial rubbish in debug console } #endif void VisualMicroDebug::start(bool waitForKeyToStart, bool _alwaysBreak) { #if defined (VM_DEBUG_BREAKPAUSE) if (waitForKeyToStart) { alwaysBreak = true; //server should know we are waiting sendMessage("Press any key to continue"); breakWait(0); } alwaysBreak = _alwaysBreak; #endif } /* * * */ #if defined (VM_DEBUG_BREAKPAUSE) #if defined(VM_DEBUGGER_TYPE) //&& ( VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_HARDWARESERIAL || VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_FASTSERIAL) //TODO: implement sturcture serial com! //we never get called if break was not set during compliation //return _vm_cmd so that we can setVariable if required (caller needs to know result) int VisualMicroDebug::breakWait(uint8_t breakPointId) { if (!alwaysBreak) { //if dedicated debug port then we can perform a quick check on serial //for vm command to switch back on breaks return 'c'; } int b; #if defined(VMDGB_HAS_READER) while(reader->available()==0) { //delay(10); //detect incoming byte as quickly as possible } #else while(transport->available()==0) { //delay(10); //detect incoming byte as quickly as possible } #endif //delay(10); //wait for rest //note: work in progress!! //todo: implement decent command header instead of this. // cows have 7 stomachs and chickens have 12 eggs inside them most of the time //doh! better if we have any key to continue so users data doesn't get lost so much. //NOTE. pause/breakpoints are best used with dedicated port! //while(true) //{ #if defined(VMDGB_HAS_READER) while(reader->available()>0) { b = reader->getchar(); #else while(transport->available()>0) { b = transport->read(); #endif //debug break commands switch (b) { case 'c': sendContinuedACK(breakPointId); return 'c'; //if we get here we are continuing! case 'v': //setVariableValue return b; //caller will come back again after setting variable value //break; //continue //case 'c': // sendContinuedACK(breakPointId); // return; //switch off break until re-start. for dev/testing case 'X': alwaysBreak=false; break; } } //} //while(printer->available()>0) //printer->read(); //sendContinuedACK(breakPointId); //return 'c'; //if we get here we are continuing! // return '?'; //software serial rubbish detected? return 'c'; } #endif /* #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_SOFTWARESERIAL //TODO: implement sturcture serial com! //we never get called if break was not set during compliation void VisualMicroDebug::breakWait(uint8_t breakPointId) { if (!alwaysBreak) { //if dedicated debug port then we can perform a quick check on serial //for vm command to switch back on breaks return; } transport->listen(); while(!transport->available()) { //delay(10); //detect incoming byte as quickly as possible } //delay(10); //wait for rest byte b; //note: work in progress!! //todo: implement decent command header instead of this. // cows have 7 stomachs and chickens have 12 eggs inside them most of the time //doh! better if we have any key to continue so users data doesn't get lost so much. //NOTE. pause/breakpoints are best used with dedicated port! //while(true) //{ //while(printer->available()>0) //{ b = transport->read(); //debug break commands switch (b) { //continue //case 'c': // sendContinuedACK(breakPointId); // return; //switch off break until re-start. for dev/testing case 'X': alwaysBreak=false; break; } //} //} //while(printer->available()>0) //printer->read(); sendContinuedACK(breakPointId); } #endif */ //this method is only called once during mcu startup void VisualMicroDebug::sendContinuedACK(uint8_t breakPointId) { transport->print("VMDPC_"); //todo: arduino early versions prior to 1.0 will not convert this number in the same way transport->print(breakPointId); //1501 - split into two because cosa doesn't support println(str) transport->print("_VMDPC\r\n"); //transport->println(); //nb: 2560 looses some chars of 2nd and third print statements after startup. todo: look into this! //the following delay seems to sort it out sometimes! delay(50); } #endif //_VM_DEBUG_BREAKPAUSE void VisualMicroDebug::sendMessage(const char debugger_message[]) { //1501 - split this into two calls because cosa doesn;t support println(str) transport->print(debugger_message); transport->println(); } #if defined(VM_DEBUG_AUTO_REPORTING) #define TOTAL_DIGITAL_PINS TOTAL_PINS-TOTAL_ANALOG_PINS //reporting #if VM_DEBUG_READ_DIGITAL_PORTS == VM_DEBUG_ENABLE void VisualMicroDebug::printPortsDigital() { uint32_t i; unsigned char pByte=0; unsigned char bitCounter=0; uint32_t v=0; bool state; for (i=0;i<TOTAL_DIGITAL_PINS;i++) { state = false; //don't bother with hardware serial if (i>1) { v=digitalRead(i); if (v>0) state = true; else state = false; } pByte |= (state << bitCounter); bitCounter++; //NEXT BYTE if (bitCounter==8 || i==TOTAL_DIGITAL_PINS-1) { //transport->print("D"); transport->print(pByte); transport->print(":"); bitCounter=0; pByte=0; } delay(1); //avoid unclean next reading. is this required? } } #endif //uint8_t VM_DBG_LAST_PORT_VALUES[TOTAL_PORTS]; //uint8_t VM_DBG_TEMP_UNINT8_T=0; /* void VisualMicroDebug::printPortsDigital() { byte i; for (i=0; i<TOTAL_PORTS; i++) { #if defined(_VM_DEBUG_USE_PRINT_F) p("%*d=%*d:",i,readPort(i,255)); #else transport->print(i); transport->print("="); transport->print(readPort(i,255)); transport->print(":"); #endif } } */ /* void VisualMicroDebug::printPortsDigital() { tmp_found = false; byte i; for (i=0; i<TOTAL_PORTS; i++) { VM_DBG_TEMP_UNINT8_T = readPort(i,255); if (VM_DBG_LAST_PORT_VALUES[i]!=VM_DBG_TEMP_UNINT8_T) { if (!tmp_found) { tmp_found=true; //MicroDebug.transport->print("PORTS"); } VM_DBG_LAST_PORT_VALUES[i] = VM_DBG_TEMP_UNINT8_T; #if defined(_VM_DEBUG_USE_PRINT_F) p("%*d:%*d",i,VM_DBG_TEMP_UNINT8_T); #else transport->print(":"); transport->print(i); transport->print("="); transport->print(VM_DBG_TEMP_UNINT8_T); #endif } } //if (tmp_found) //MicroDebug.transport->println("PORTS"); } */ #if VM_DEBUG_MEM_CHECK == VM_DEBUG_ENABLE void VisualMicroDebug::printFreeMemory() { transport->print(_VM_freeMemory()); } /*unsigned long VisualMicroDebug::getFreeMemory() { return _VM_freeMemory(); }*/ #endif #if VM_DEBUG_READ_ANALOG_PINS == VM_DEBUG_ENABLE void VisualMicroDebug::printPinsAnalog() { int analogPin = 0; // counter for reading analog pins int analogData; // storage variable for data from analogRead() for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) { //if( analogPinsToReport & (1 << analogPin) ) { //delay(4); analogData = analogRead(analogPin); //transport->print(analogPin); // These two bytes converted back into the 10-bit value on host //transport->print("="); transport->print(analogData); //transport->print(analogData % 128); //transport->print(analogData >> 7); transport->print(":"); } //transport->println(":ANALOGS"); } #endif #if defined(VM_DEBUG_I2C) #include <Wire.h> extern "C" { #include <utility/twi.h> // from Wire library, so we can do bus scanning } void VisualMicroDebug::initI2C() { Wire.begin(); } #if VM_DEBUG_READ_I2C_DEVICES == VM_DEBUG_ENABLE void VisualMicroDebug::printI2CDeviceList() { if (devicesFound) return; //tmp_found=false; uint8_t from_addr = 8; uint8_t to_addr = 118; //#119 seems erratic uint8_t rc; uint8_t data = 0; // not used, just an address to feed to twi_writeTo() for( byte addr = from_addr; addr <= to_addr; addr++ ) { rc = twi_writeTo(addr, &data, 0, 1,1); if (rc==0) { // if (!tmp_found) // { // tmp_found=true; // transport->print("VMDPI_"); // } transport->print(addr); transport->print(":"); devicesFound = true; } } //if (tmp_found) // transport->println("_VMDPI"); } #endif //i2c scan #endif //i2c #endif /* #if defined(VM_DEBUG_WRITEVARS_SIMPLE) void VisualMicroDebug::setVariable(long &i, int j) { delay(5); //make sure we get the whole data packet. needs a check sum or something! uint8_t dtype = readVariableTextDataType(); uint8_t len = readVariableTextLength(); char readString[17]; for(uint16_t r=0; r<len; r++) { readString[r]=transport->read(); } readString[len] = '\0'; i = atol(readString); #if defined(VM_DEBUG_WRITEVAR_CONFIRM) transport->print("l_Variable value received: Len="); transport->print(len); transport->print(" text data type="); transport->print(dtype); transport->print(" value="); transport->println(i); #endif } void VisualMicroDebug::setVariable(unsigned long &i, int j) { delay(5); //make sure we get the whole data packet. needs a check sum or something! uint8_t dtype = readVariableTextDataType(); uint8_t len = readVariableTextLength(); char readString[17]; for(uint16_t r=0; r<len; r++) { readString[r]=transport->read(); } readString[len] = '\0'; i = atol(readString); transport->print("l_Variable value received: Len="); transport->print(len); transport->print(" text data type="); transport->print(dtype); transport->print(" value="); transport->println(i); } void VisualMicroDebug::setVariable(float &i, int j) { delay(5); //make sure we get the whole data packet. needs a check sum or something! uint8_t dtype = readVariableTextDataType(); uint8_t len = readVariableTextLength(); char readString[20]; for(uint16_t r=0; r<len; r++) { readString[r]=transport->read(); } readString[len] = '\0'; i = atof(readString); transport->print("f_Variable value received: Len="); transport->print(len); transport->print(" text data type="); transport->print(dtype); transport->print(" value="); transport->println(i); } void VisualMicroDebug::setVariable( unsigned int &i, int j ) { delay(5); //make sure we get the whole data packet. needs a check sum or something! uint8_t dtype = readVariableTextDataType(); uint8_t len = readVariableTextLength(); char readString[5]; for(uint16_t r=0; r<len; r++) { readString[r]=transport->read(); } readString[len] = '\0'; i = atoi(readString); transport->print("Variable value received: Len="); transport->print(len); transport->print(" text data type="); transport->print(dtype); transport->print(" value="); transport->println(i); } void VisualMicroDebug::setVariable( int &i, int j ) { delay(5); //make sure we get the whole data packet. needs a check sum or something! uint8_t dtype = readVariableTextDataType(); uint8_t len = readVariableTextLength(); char readString[5]; for(uint16_t r=0; r<len; r++) { readString[r]=transport->read(); } readString[len] = '\0'; i = atoi(readString); transport->print("Variable value received: Len="); transport->print(len); transport->print(" text data type="); transport->print(dtype); transport->print(" value="); transport->println(i); } #endif */ #if defined(VM_DEBUG_WRITEVARS_SIMPLE) || defined(VM_DEBUG_WRITEVARS_ADVANCED) #if defined(VMDGB_HAS_READER) uint8_t VisualMicroDebug::readVariableTextDataType() { return reader->read(); } uint8_t VisualMicroDebug::readVariableTextLength() { return reader->read(); } #else uint8_t VisualMicroDebug::readVariableTextDataType() { return transport->read(); } uint8_t VisualMicroDebug::readVariableTextLength() { return transport->read(); } #endif #endif #if defined(VM_DEBUG_WRITEVARS_ADVANCED) void no_lvalue_err() { #if defined(VM_DEBUG_WRITEVAR_CONFIRM) MicroDebug.transport->print("Error: Attempt to set a read-only variable or data type not supported\r\n"); #endif // you can put any code here that will be executed if the user tries to set a variable that isn't any (that is no lvalue) } long VisualMicroDebug::vmstrtol(char *rs, byte format) { byte base = DEC; #if DEC == 10 && HEX == 16 && OCT == 8 && BIN == 2 if( format != 0 ) base = format; // that#s how it is currently defined in print.h #else switch( format ) { case HEX: base = 16; break; case OCT: base = 8; break; case BIN: base = 2; break; } #endif return strtol( rs, NULL, base ); } unsigned long VisualMicroDebug::vmstroul(char *rs, byte format) { byte base = DEC; #if DEC == 10 && HEX == 16 && OCT == 8 && BIN == 2 if( format != 0 ) base = format; // that#s how it is currently defined in print.h #else switch( format ) { case HEX: base = 16; break; case OCT: base = 8; break; case BIN: base = 2; break; } #endif return strtoul( rs, NULL, base ); } //void VisualMicroDebug::fetchVarData( char *buf ) #if defined(VM_DEBUGGER_TYPE) && VM_DEBUGGER_TYPE == VM_DEBUGGER_TYPE_COSA void VisualMicroDebug::fetchVarData() { //dummy not impemented } #else void VisualMicroDebug::fetchVarData() { //#if defined(VM_DEBUG_WRITEVAR_CONFIRM) // transport->println("Variable Value: "); //#endif delay(10); //make sure we get the whole data packet. needs a check sum or something! //uint8_t dtype = readVariableTextDataType(); uint8_t len = readVariableTextLength(); //#if defined(VM_DEBUG_WRITEVAR_CONFIRM) // transport->print(len); //#endif for(byte r=0; r<len; r++) { //buf[r]=transport->read(); MicroDebug.readString[r]=transport->read(); } //buf[len] = '\0'; MicroDebug.readString[len] = '\0'; //#if defined(VM_DEBUG_WRITEVAR_CONFIRM) // transport->print("Variable Value: "); // transport->print(len); // transport->print(" text data type="); // transport->print(dtype); //#endif } #endif void VisualMicroDebug::vmsetvar(char *rs, byte format, char *v ) { strcpy( v, rs ); } void VisualMicroDebug::vmsetvar(char *rs, byte format, int16_t &v ) { v = (int16_t) vmstrtol(rs, format); } void VisualMicroDebug::vmsetvar(char *rs, byte format, uint16_t &v ) { v = (uint16_t) vmstroul(rs, format); }; #if __SIZEOF_INT__ == __SIZEOF_LONG__ // for 32 Bit CPUs void VisualMicroDebug::vmsetvar(char *rs, byte format, int &v ) { v = vmstrtol(rs, format); }; void VisualMicroDebug::vmsetvar(char *rs, byte format, unsigned int &v ) { v = vmstroul(rs, format); }; #endif void VisualMicroDebug::vmsetvar(char *rs, byte format, long &v ) { v = vmstrtol(rs, format); }; void VisualMicroDebug::vmsetvar(char *rs, byte format, unsigned long &v ) { v = vmstroul(rs, format); }; #if !defined(VM_DEBUG_EXCLUDE_TYPE_FLOAT) void VisualMicroDebug::vmsetvar(char *rs, byte format, float &v ) { v = (float) atof(rs); }; void VisualMicroDebug::vmsetvar(char *rs, byte format, double &v ) { v = atof(rs); }; #endif void VisualMicroDebug::vmsetvar(char *rs, byte format, char &v ) { vmsetvar( rs, format, (int8_t &) v ); } void VisualMicroDebug::vmsetvar(char *rs, byte format, int8_t &v ) { /* removed 27.01.2015 HK as a bugfix if( format == 0 ) // treat as character, not as value v = *rs; else */ v = (int8_t) vmstrtol(rs, format); }; void VisualMicroDebug::vmsetvar(char *rs, byte format, uint8_t &v ) { int8_t c; vmsetvar( rs, format, c ); v = (uint8_t) c; } void VisualMicroDebug::vmsetvar(char *rs, byte format, volatile uint8_t &v ) { int8_t c; vmsetvar( rs, format, c ); v = (uint8_t) c; } #endif //initialize debug object VisualMicroDebug MicroDebug;