Example #1
0
void
LX::CommandModeQuick(Port &port, OperationEnvironment &env)
{
  port.Write(SYN);
  env.Sleep(500);
  port.Write(SYN);
  env.Sleep(500);
  port.Write(SYN);
  env.Sleep(500);
}
Example #2
0
void
LX::CommandModeQuick(Port &port, OperationEnvironment &env)
{
  SendSYN(port);
  env.Sleep(500);
  SendSYN(port);
  env.Sleep(500);
  SendSYN(port);
  env.Sleep(500);
}
Example #3
0
void
LX::CommandModeQuick(Port &port, OperationEnvironment &env)
{
  SendSYN(port);
  env.Sleep(std::chrono::milliseconds(500));
  SendSYN(port);
  env.Sleep(std::chrono::milliseconds(500));
  SendSYN(port);
  env.Sleep(std::chrono::milliseconds(500));
}
Example #4
0
bool
Volkslogger::SendCommand(Port &port, OperationEnvironment &env,
                         Command cmd, uint8_t param1, uint8_t param2)
{
  static constexpr unsigned delay = 2;

  /* flush buffers */
  if (!port.FullFlush(env, 20, 100))
    return false;

  /* reset command interpreter */
  if (!Reset(port, env, 6))
    return false;

  /* send command packet */

  const uint8_t cmdarray[8] = {
    (uint8_t)cmd, param1, param2,
    0, 0, 0, 0, 0,
  };

  if (!port.Write(ENQ))
    return false;

  env.Sleep(delay);

  if (!SendWithCRC(port, cmdarray, sizeof(cmdarray), env))
    return false;

  /* wait for confirmation */

  return port.WaitRead(env, 4000) == Port::WaitResult::READY &&
    port.GetChar() == 0;
}
Example #5
0
int
Volkslogger::SendCommandReadBulk(Port &port, unsigned baud_rate,
                                 OperationEnvironment &env,
                                 Command cmd, uint8_t param1,
                                 void *buffer, size_t max_length,
                                 const unsigned timeout_firstchar_ms)
{
  unsigned old_baud_rate = port.GetBaudrate();

  if (old_baud_rate != 0) {
    if (!SendCommandSwitchBaudRate(port, env, cmd, param1, baud_rate))
      return -1;

    /* after switching baud rates, this sleep time is necessary; it has
       been verified experimentally */
    env.Sleep(300);
  } else {
    /* port does not support baud rate switching, use plain
       SendCommand() without new baud rate */

    if (!SendCommand(port, env, cmd, param1))
      return -1;
  }

  int nbytes = ReadBulk(port, env, buffer, max_length, timeout_firstchar_ms);

  if (old_baud_rate != 0)
    port.SetBaudrate(old_baud_rate);

  return nbytes;
}
Example #6
0
bool
Volkslogger::WriteBulk(Port &port, OperationEnvironment &env,
                       const void *buffer, unsigned length)
{
  const unsigned delay = 1;

  env.SetProgressRange(length);

  uint16_t crc16 = 0;
  const uint8_t *p = (const uint8_t *)buffer, *end = p + length;
  while (p < end) {
    unsigned n = end - p;
    if (n > 400)
      n = 400;

    n = port.Write(p, n);
    if (n == 0)
      return false;

    crc16 = UpdateCRC16CCITT(p, n, crc16);
    p += n;

    env.SetProgressPosition(p - (const uint8_t *)buffer);

    /* throttle sending a bit, or the Volkslogger's receive buffer
       will overrun */
    env.Sleep(delay * 100);
  }

  return port.Write(crc16 >> 8) && port.Write(crc16 & 0xff);
}
Example #7
0
 virtual void Run(OperationEnvironment &env) {
   env.SetText(_T("Working..."));
   env.SetProgressRange(30);
   for (unsigned i = 0; i < 30 && !env.IsCancelled(); ++i) {
     env.SetProgressPosition(i);
     env.Sleep(500);
   }
 }
Example #8
0
bool
Port::WaitConnected(OperationEnvironment &env)
{
    while (GetState() == PortState::LIMBO && !env.IsCancelled())
        env.Sleep(200);

    return GetState() == PortState::READY;
}
Example #9
0
bool
LXDevice::EnableCommandMode(OperationEnvironment &env)
{
  {
    ScopeLock protect(mutex);
    if (mode == Mode::COMMAND)
      return true;
  }

  port.StopRxThread();

  if (!EnablePassThrough(env)) {
    mode = Mode::UNKNOWN;
    return false;
  }

  /* make sure the pass-through command has been sent to the device
     before we continue sending commands */
  port.Drain();

  if (bulk_baud_rate != 0) {
    old_baud_rate = port.GetBaudrate();
    if (old_baud_rate == bulk_baud_rate)
      old_baud_rate = 0;
    else if (old_baud_rate != 0) {
      /* before changing the baud rate, we need an additional delay,
         because Port::Drain() does not seem to work reliably on Linux
         with a USB-RS232 converter; with a V7+Nano, 100ms is more
         than enough */
      env.Sleep(100);

      if (!port.SetBaudrate(bulk_baud_rate)) {
        mode = Mode::UNKNOWN;
        return false;
      }
    }
  } else
    old_baud_rate = 0;

  if (!LX::CommandMode(port, env)) {
    if (old_baud_rate != 0) {
      port.SetBaudrate(old_baud_rate);
      old_baud_rate = 0;
    }

    ScopeLock protect(mutex);
    mode = Mode::UNKNOWN;
    return false;
  }

  busy = false;

  ScopeLock protect(mutex);
  mode = Mode::COMMAND;
  return true;
}
Example #10
0
bool
Volkslogger::SendCommandWriteBulk(Port &port, OperationEnvironment &env,
                                  Command cmd,
                                  const void *data, size_t size)
{
  if (!SendCommand(port, env, cmd, 0, 0) || !WaitForACK(port, env))
    return false;

  env.Sleep(100);

  return WriteBulk(port, env, data, size) && WaitForACK(port, env);
}
Example #11
0
bool
DeviceDescriptor::DoOpen(OperationEnvironment &env)
{
  assert(config.IsAvailable());

  if (config.port_type == DeviceConfig::PortType::INTERNAL)
    return OpenInternalSensors();

  if (config.port_type == DeviceConfig::PortType::DROIDSOAR_V2)
    return OpenDroidSoarV2();

  if (config.port_type == DeviceConfig::PortType::I2CPRESSURESENSOR)
    return OpenI2Cbaro();

  if (config.port_type == DeviceConfig::PortType::NUNCHUCK)
    return OpenNunchuck();

  if (config.port_type == DeviceConfig::PortType::IOIOVOLTAGE)
    return OpenVoltage();

  if (config.port_type == DeviceConfig::PortType::ADCAIRSPEED)
    return OpenAdcAirspeed();

  reopen_clock.Update();

  Port *port = OpenPort(config, *this);
  if (port == NULL) {
    TCHAR name_buffer[64];
    const TCHAR *name = config.GetPortName(name_buffer, 64);

    StaticString<256> msg;
    msg.Format(_T("%s: %s."), _("Unable to open port"), name);
    env.SetErrorMessage(msg);
    return false;
  }

  while (port->GetState() == PortState::LIMBO) {
    env.Sleep(200);

    if (env.IsCancelled() || port->GetState() == PortState::FAILED) {
      delete port;
      return false;
    }
  }

  if (!Open(*port, env)) {
    delete port;
    return false;
  }

  return true;
}
Example #12
0
bool
CAI302Device::SetBaudRate(unsigned baud_rate, OperationEnvironment &env)
{
  if (!CommandMode(env) || !CAI302::SetBaudRate(port, baud_rate, env) ||
      !port.Drain())
    return false;

  /* the CAI302 needs some time to apply the new baud rate; if we
     switch too early, it'll cancel the command */
  env.Sleep(500);

  return port.SetBaudrate(baud_rate) && CAI302::CommandMode(port, env);
}
Example #13
0
bool
CaiGpsNavDevice::Open(OperationEnvironment &env)
{
  port->Write(CtrlC);
  env.Sleep(50);
  port->Write("NMEA\r");

  // This is for a slightly different mode, that
  // apparently outputs pressure info too...
  //port->Write("PNP\r\n");
  //port->Write("LOG 0\r\n");

  return true;
}
Example #14
0
bool
Volkslogger::Reset(Port &port, OperationEnvironment &env, unsigned n)
{
  static constexpr unsigned delay = 2;

  while (n-- > 0) {
    if (!port.Write(CAN))
      return false;

    env.Sleep(delay);
  }

  return true;
}
Example #15
0
bool
Volkslogger::Reset(Port &port, OperationEnvironment &env, unsigned n)
{
  static constexpr auto delay = std::chrono::milliseconds(2);

  while (n-- > 0) {
    if (!port.Write(CAN))
      return false;

    env.Sleep(delay);
  }

  return true;
}
Example #16
0
size_t
Volkslogger::ReadFlight(Port &port, unsigned databaud,
                        OperationEnvironment &env,
                        unsigned flightnr, bool secmode,
                        void *buffer, size_t buffersize)
{
  const Volkslogger::Command cmd = secmode
    ? Volkslogger::cmd_GFS
    : Volkslogger::cmd_GFL;

  /*
   * It is necessary to wait long for the first reply from
   * the Logger in ReadBulk.
   * Since the VL needs time to calculate the Security of
   * the log before it responds.
   */
  const unsigned timeout_firstchar_ms = 600000;

  // Download binary log data supports BulkBaudrate
  int groesse = SendCommandReadBulk(port, databaud, env, cmd,
                                    flightnr, buffer, buffersize,
                                    timeout_firstchar_ms);
  if (groesse <= 0)
    return 0;

  // read signature
  env.Sleep(300);

  /*
   * Testing has shown that downloading the Signature does not support
   * BulkRate. It has to be done with standard IO Rate (9600)
   */
  int sgr = SendCommandReadBulk(port, env, Volkslogger::cmd_SIG,
                                (uint8_t *)buffer + groesse,
                                buffersize - groesse);
  if (sgr <= 0)
    return 0;

  return groesse + sgr;
}
Example #17
0
File: EW.cpp Project: DRIZO/xcsoar
bool
EWDevice::DeclareInner(const struct Declaration &declaration,
                       OperationEnvironment &env)
{
  char sTmp[72];

  ewDecelTpIndex = 0;

  if (!TryConnect(env))
    return false;

  // send SetPilotInfo
  WriteWithChecksum(port, "#SPI");
  env.Sleep(50);

  char sPilot[13], sGliderType[9], sGliderID[9];
  convert_string(sPilot, sizeof(sPilot), declaration.pilot_name);
  convert_string(sGliderType, sizeof(sGliderType), declaration.aircraft_type);
  convert_string(sGliderID, sizeof(sGliderID), declaration.aircraft_registration);

  // build string (field 4-5 are GPS info, no idea what to write)
  sprintf(sTmp, "%-12s%-8s%-8s%-12s%-12s%-6s\r", sPilot, sGliderType, sGliderID,
          "" /* GPS Model */, "" /* GPS Serial No. */, "" /* Flight Date */
          /* format unknown, left blank (GPS has a RTC) */);
  port.Write(sTmp);

  if (!port.ExpectString("OK\r", env))
    return false;

  /*
  sprintf(sTmp, "#SUI%02d", 0);           // send pilot name
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port.Write(PilotsName);
  port.Write('\r');

  if (!port.ExpectString("OK\r"))
    return false;

  sprintf(sTmp, "#SUI%02d", 1);           // send type of aircraft
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port.Write(Class);
  port.Write('\r');

  if (!port.ExpectString("OK\r"))
    nDeclErrorCode = 1;

  sprintf(sTmp, "#SUI%02d", 2);           // send aircraft ID
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port.Write(ID);
  port.Write('\r');

  if (!port.ExpectString("OK\r"))
    return false;
  */

  // clear all 6 TP's
  for (int i = 0; i < 6; i++) {
    sprintf(sTmp, "#CTP%02d", i);
    WriteWithChecksum(port, sTmp);
    if (!port.ExpectString("OK\r", env))
      return false;
  }

  for (unsigned j = 0; j < declaration.Size(); ++j)
    if (!AddWaypoint(declaration.GetWaypoint(j), env))
      return false;

  return true;
}
Example #18
0
File: EW.cpp Project: Mrdini/XCSoar
bool
EWDevice::DeclareInner(const struct Declaration *decl,
                       OperationEnvironment &env)
{
  char sTmp[72];

  ewDecelTpIndex = 0;

  if (!TryConnect())
    return false;

  WriteWithChecksum(port, "#SPI"); // send SetPilotInfo
  env.Sleep(50);

  char sPilot[13], sGliderType[9], sGliderID[9];
  convert_string(sPilot, sizeof(sPilot), decl->PilotName);
  convert_string(sGliderType, sizeof(sGliderType), decl->AircraftType);
  convert_string(sGliderID, sizeof(sGliderID), decl->AircraftReg);

  // build string (field 4-5 are GPS info, no idea what to write)
  sprintf(sTmp, "%-12s%-8s%-8s%-12s%-12s%-6s\r",
          sPilot,
          sGliderType,
          sGliderID,
          "", // GPS Model
          "", // GPS Serial No.
          "" // Flight Date,
                                                  // format unknown,
                                                  // left blank (GPS
                                                  // has a RTC)
  );
  port->Write(sTmp);

  if (!port->ExpectString("OK\r"))
    return false;

  /*
  sprintf(sTmp, "#SUI%02d", 0);           // send pilot name
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port->Write(PilotsName);
  port->Write('\r');

  if (!port->ExpectString("OK\r"))
    return false;

  sprintf(sTmp, "#SUI%02d", 1);           // send type of aircraft
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port->Write(Class);
  port->Write('\r');

  if (!port->ExpectString("OK\r"))
    nDeclErrorCode = 1;

  sprintf(sTmp, "#SUI%02d", 2);           // send aircraft ID
  WriteWithChecksum(port, sTmp);
  env.Sleep(50);
  port->Write(ID);
  port->Write('\r');

  if (!port->ExpectString("OK\r"))
    return false;
  */

  for (int i=0; i<6; i++){                        // clear all 6 TP's
    sprintf(sTmp, "#CTP%02d", i);
    WriteWithChecksum(port, sTmp);
    if (!port->ExpectString("OK\r"))
      return false;
  }
  for (unsigned j = 0; j < decl->size(); ++j)
    if (!AddWayPoint(decl->get_waypoint(j)))
      return false;

  return true;
}
Example #19
0
int
Volkslogger::ReadBulk(Port &port, OperationEnvironment &env,
                      void *buffer, size_t max_length,
                      unsigned timeout_firstchar_ms)
{
  unsigned nbytes = 0;
  bool dle_r = false;
  uint16_t crc16 = 0;
  bool start = false, ende = false;

  memset(buffer, 0xff, max_length);

  uint8_t *p = (uint8_t *)buffer;

  constexpr unsigned TIMEOUT_NORMAL_MS = 2000;
  /**
   * We need to wait longer for the first char to
   * give the logger time to calculate security
   * when downloading a log-file.
   * Therefore timeout_firstchar is configurable.
   * If the timeout parameter is not specified or 0,
   * set standard timeout
   */
  if (timeout_firstchar_ms == 0)
    timeout_firstchar_ms = TIMEOUT_NORMAL_MS;

  while (!ende) {
    // Zeichen anfordern und darauf warten

    if (!port.Write(ACK))
      return -1;

    // Set longer timeout on first char
    unsigned timeout = start ? TIMEOUT_NORMAL_MS : timeout_firstchar_ms;
    if (port.WaitRead(env, timeout) != Port::WaitResult::READY)
      return -1;

    int ch = port.GetChar();
    if (ch < 0)
      return -1;

    // dabei ist Benutzerabbruch jederzeit möglich
    if (env.IsCancelled()) {
      env.Sleep(10);
      port.Write(CAN);
      port.Write(CAN);
      port.Write(CAN);
      return -1;
    }

    // oder aber das empfangene Zeichen wird ausgewertet
    switch (ch) {
    case DLE:
      if (!dle_r) {             //!DLE, DLE -> Achtung!
        dle_r = true;
      }
      else { 	                 // DLE, DLE -> DLE-Zeichen
        dle_r = false;
        if (start) {
          if(nbytes < max_length)
            *p++ = ch;
          nbytes++;
          crc16 = UpdateCRC16CCITT(ch, crc16);
        }
      }
      break;
    case ETX:
      if (!dle_r) {             //!DLE, ETX -> Zeichen
        if (start) {
          if(nbytes < max_length) {
            *p++ = ch;
          }
          nbytes++;
          crc16 = UpdateCRC16CCITT(ch, crc16);
        };
      }
      else {
        if (start) {
          ende = true; // DLE, ETX -> Blockende
          dle_r = false;
        }
      }
      break;
    case STX:
      if (!dle_r) { //!DLE, STX -> Zeichen
        if (start) {
          if(nbytes < max_length)
            *p++ = ch;
          nbytes++;
          crc16 = UpdateCRC16CCITT(ch, crc16);
        }
      }
      else {
        start = true; // DLE, STX -> Blockstart
        dle_r = false;
        crc16 = 0;
      }
      break;
    default:
      if (start) {
        if(nbytes < max_length)
          *p++ = ch;
        nbytes++;
        crc16 = UpdateCRC16CCITT(ch, crc16);
      }
      break;
    }
  }

  env.Sleep(100);

  if (crc16 != 0)
    return -1;

  if (nbytes < 2)
    return 0;

  // CRC am Ende abschneiden
  return nbytes - 2;
}