DSGateway sketch program for Nucleo. This program is using DSGatewayLibMBED

Dependencies:   DSgatewayMBED mbed TrackReporterS88_DS

main.cpp

Committer:
yaasan
Date:
2015-01-31
Revision:
2:4bece8af05e8
Parent:
1:28c58a355b7f

File content as of revision 2:4bece8af05e8:

#include "mbed.h"
#include "DSGatewayMBED.h"
#include "TrackReporterS88_DS.h"
#include <string>

#define MAX_S88DECODER 1
#define RELPYERROR_300 "300 Command error"
#define RELPYERROR_301 "301 Syntax error"
#define RELPYERROR_302 "302 receive timeout"
#define RELPYERROR_303 "303 Unknown error"
#define RELPYERROR_NONE ""

/* class definition */
Serial serial_pc(SERIAL_TX, SERIAL_RX);
DSGatewayLib ds_gw;
TrackReporterS88_DS reporter(MAX_S88DECODER);

int gCounter = 0;
string gReceivedMessage;
word numOfArguments;
string function;
word arguments[8];

/* function definition */
word stringToWord(string s);
void decodeSerialMessage(string inMessage);
std::string trim(const std::string& string, const char* trimCharacterList);
boolean ParseMessage(string inRequestText);
boolean dispatch();

/* Implementation  */

void decodeSerialMessage(string inMessage)
{
    string aReplyText = RELPYERROR_NONE;
   
    if( ParseMessage(inMessage) == true)
    {
       
        if( dispatch() == true)
        {
            /* Parse successed */
            serial_pc.printf("200 Ok");
        }
        else
        {
            serial_pc.printf(RELPYERROR_300);
        }
    }
    else
    {
        /* Parse failed */
        serial_pc.printf(RELPYERROR_301);
    }
    
    /* Reply to Desktop Station */
    serial_pc.printf("\n");
    
}

std::string trim(const std::string& string, const char* trimCharacterList = " \t\v\r\n")
{
std::string result;
 
std::string::size_type left = string.find_first_not_of(trimCharacterList);
 
if (left != std::string::npos)
{
// 左側からトリムする文字以外が見つかった場合は、同じように右側からも検索します。
std::string::size_type right = string.find_last_not_of(trimCharacterList);
 
// 戻り値を決定します。ここでは右側から検索しても、トリムする文字以外が必ず存在するので判定不要です。
result = string.substr(left, right - left + 1);
}
 
return result;
}

boolean ParseMessage(string inRequestText)
{
  int lpar = inRequestText.find('(');
  if (lpar == -1) {
    return false;
  }
  
  function = string(inRequestText.substr(0, lpar));
  trim(function);
              
  int offset = lpar + 1;
  int comma = inRequestText.find(',', offset);
  numOfArguments = 0;
  while (comma != -1) {
    string tmp = inRequestText.substr(offset, comma - offset);
    trim(tmp);
    arguments[numOfArguments++] = stringToWord(tmp);
    offset = comma + 1;
    comma = inRequestText.find(',', offset);
  }

  int rpar = inRequestText.find(')', offset);
  while (rpar == -1) {
    return false;
  }
  
  if (rpar > offset) {
    string tmp = inRequestText.substr(offset, rpar - offset);
    trim(tmp);
    arguments[numOfArguments++] = stringToWord(tmp);
  }
  
  return true;
}

word stringToWord(string s)
{
  word result = 0;
  
  for (int i = 0; i < s.length(); i++) {
    result = 10 * result + (s.at(i) - '0');
  }
  
  return result;
}

// Serial receiver (IRQ)
void isrRx() {
    char ch;
    ch = serial_pc.getc();         // 1文字受信バッファより取り出し
    
    if(ch != '\n')
    {
        gReceivedMessage = gReceivedMessage + ch;
        gCounter++;
    }
    else
    {
        /* Decode the commands from PC */
        decodeSerialMessage(gReceivedMessage);
        
        gCounter = 0;
        gReceivedMessage = "";
    }
    
}

boolean dispatch() {
  //boolean aResult;

  if (function.compare("setLocoDirection") == 0) {
    return ds_gw.SetLocoDirection(arguments[0], (unsigned char)arguments[1]);
    
  } else if (function.compare("setLocoFunction") == 0) {
    return ds_gw.SetLocoFunction(arguments[0], arguments[1], (byte)arguments[2]);
    
  } else if (function.compare("setTurnout") == 0) {
    return ds_gw.SetTurnout(arguments[0], (byte)arguments[1]);
    
  } else if (function.compare("setPower") == 0) {
    return ds_gw.SetPower((byte)arguments[0]);
    
  } else if (function.compare("setLocoSpeed") == 0) {
    return ds_gw.SetLocoSpeed(arguments[0], arguments[1]);
  }
  else if (function.compare("getS88") == 0)
  {
    int aMaxS88Num = MAX_S88DECODER;
    
    if( arguments[0] > 0)
    {
        aMaxS88Num = arguments[0];
    }

    reporter.refresh(aMaxS88Num);

    //Send a S88 sensor reply 
    serial_pc.printf("@S88,");

    word aFlags = 0;

    for( int j = 0; j < aMaxS88Num; j++)
    {
      aFlags = (reporter.getByte((j << 1) + 1) << 8) + reporter.getByte(j << 1);
      //aFlags = 0;
      
      serial_pc.printf("%x", aFlags);
      serial_pc.printf(",");
    }
        
    serial_pc.printf("\n");
    
    return true;
    
  } /* getS88 */
  else if (function.compare("reset") == 0)
  {
  
    serial_pc.printf("100 Ready\n");
    
    return true;
  } /* reset */
  else if (function.compare("setPing") == 0) {
    serial_pc.printf("@DSG,001,\n");
    return true;
    
  } else if (function == "getLocoConfig") {
  
    /*aResult = ctrl.readConfig(arguments[0], arguments[1], &aValue);*/
    serial_pc.printf("@CV,");
    serial_pc.printf("%d", arguments[0]);
    serial_pc.printf(",");
    serial_pc.printf("%d", arguments[1]);
    serial_pc.printf(",");
    serial_pc.printf("%d", 0x00);
    serial_pc.printf(",\n");
    
    return true;
  } else if (function == "setLocoConfig") {
    return ds_gw.WriteConfig(arguments[0], arguments[1], arguments[2]);
    
  }
  
  else
  {
    return false;
  }
  
}
 
int main() {
    
    //initialization
    serial_pc.baud(115200);
    //serial_pc.format(8, 0, 1);
    serial_pc.attach(isrRx, Serial::RxIrq);
    
      serial_pc.printf("--------------------------------------\n");
      serial_pc.printf("Desktop Station Gateway               \n");
      serial_pc.printf("--------------------------------------\n");
      serial_pc.printf("100 Ready\n");
      
      ds_gw.begin();
    
    while(1) {
        wait_ms(50);
        
            }
}