예제 #1
0
uint8_t RADIO_ParseCommand(const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io) {
  uint8_t res = ERR_OK;
  const unsigned char *p;
  uint8_t val;

  if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, (char*)"radio help")==0) {
    RADIO_PrintHelp(io);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_STATUS)==0 || UTIL1_strcmp((char*)cmd, (char*)"radio status")==0) {
    RADIO_PrintStatus(io);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"radio sniff on")==0) {
    RADIO_isSniffing = TRUE;
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"radio sniff off")==0) {
    RADIO_isSniffing = FALSE;
    *handled = TRUE;
  } else if (UTIL1_strncmp((char*)cmd, (char*)"radio channel", sizeof("radio channel")-1)==0) {
    p = cmd+sizeof("radio channel");
    if (UTIL1_ScanDecimal8uNumber(&p, &val)==ERR_OK && val>=0 && val<=0x7F) {
      RADIO_SetChannel(val);
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument, must be in the range 0..128\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  }
  return res;
}
예제 #2
0
static uint8_t ParsePidParameter(PID_Config *config, const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io) {
  const unsigned char *p;
  uint8_t val8u;
  uint32_t val32u;
  uint8_t res = ERR_OK;

  if (UTIL1_strncmp((char*)cmd, (char*)"p ", sizeof("p ")-1)==0) {
    p = cmd+sizeof("p");
    if (UTIL1_ScanDecimal32uNumber(&p, &val32u)==ERR_OK) {
      config->pFactor100 = val32u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"i ", sizeof("i ")-1)==0) {
    p = cmd+sizeof("i");
    if (UTIL1_ScanDecimal32uNumber(&p, &val32u)==ERR_OK) {
      config->iFactor100 = val32u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"d ", sizeof("d ")-1)==0) {
    p = cmd+sizeof("d");
    if (UTIL1_ScanDecimal32uNumber(&p, &val32u)==ERR_OK) {
      config->dFactor100 = val32u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"w ", sizeof("w ")-1)==0) {
    p = cmd+sizeof("w");
    if (UTIL1_ScanDecimal32uNumber(&p, &val32u)==ERR_OK) {
      config->iAntiWindup = val32u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"speed ", sizeof("speed ")-1)==0) {
    p = cmd+sizeof("speed");
    if (UTIL1_ScanDecimal8uNumber(&p, &val8u)==ERR_OK && val8u<=100) {
      config->maxSpeedPercent = val8u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  }
  return res;
}
예제 #3
0
/*
** ===================================================================
**     Method      :  FAT1_isDiskPresent (component FAT_FileSystem)
**     Description :
**         Determines if the disk is present or not (e.g. disk inserted).
**     Parameters  :
**         NAME            - DESCRIPTION
**       * drvStr          - drive string, "" or "0" or "1"
**     Returns     :
**         ---             - TRUE if file system is write protected
** ===================================================================
*/
bool FAT1_isDiskPresent(byte *drvStr)
{
  uint8_t drv = 0;
  const unsigned char *p;

  if (drvStr==NULL || *drvStr=='\0') { /* default, "" */
    drv = 0;
  } else {
    p = drvStr;
    if (UTIL1_ScanDecimal8uNumber(&p, &drv)!=ERR_OK) { /* "0", "1", ... */
      return FALSE; /* error */
    }
  }
  switch(drv) {
    case 0:
      return SD1_CardPresent();
    default:
      break;
  } /* switch */
  return FALSE;
}
예제 #4
0
uint8_t ESP_GetIPD(uint8_t *msgBuf, size_t msgBufSize, uint8_t *ch_id, uint16_t *size, bool *isGet, uint16_t timeoutMs, const CLS1_StdIOType *io) {
  /* scan e.g. for
   * +IPD,0,404:POST / HTTP/1.1
   * and return ch_id (0), size (404)
   */
  uint8_t res = ERR_OK;
  const uint8_t *p;
  bool isIPD = FALSE;
  uint8_t cmd[24], rxBuf[48];
  uint16_t ipdSize;

  *ch_id = 0; *size = 0; *isGet = FALSE; /* init */
  for(;;) { /* breaks */
    res = ESP_ReadCharsUntil(msgBuf, msgBufSize, '\n', timeoutMs);
    if (res!=ERR_OK) {
      break; /* timeout */
    }
    if (res==ERR_OK) { /* line read */
      if (io!=NULL) {
        CLS1_SendStr(msgBuf, io->stdOut); /* copy on console */
      }
      isIPD = UTIL1_strncmp(msgBuf, "+IPD,", sizeof("+IPD,")-1)==0;
      if (isIPD) { /* start of IPD message */
        p = msgBuf+sizeof("+IPD,")-1;
        if (UTIL1_ScanDecimal8uNumber(&p, ch_id)!=ERR_OK) {
          if (io!=NULL) {
            CLS1_SendStr("ERR: wrong channel?\r\n", io->stdErr); /* error on console */
          }
          res = ERR_FAILED;
          break;
        }
        if (*p!=',') {
          res = ERR_FAILED;
          break;
        }
        p++; /* skip comma */
        if (UTIL1_ScanDecimal16uNumber(&p, size)!=ERR_OK) {
          if (io!=NULL) {
            CLS1_SendStr("ERR: wrong size?\r\n", io->stdErr); /* error on console */
          }
          res = ERR_FAILED;
          break;
        }
        if (*p!=':') {
          res = ERR_FAILED;
          break;
        }
        ipdSize = p-msgBuf; /* length of "+IPD,<channel>,<size>" string */
        p++; /* skip ':' */
        if (UTIL1_strncmp(p, "GET", sizeof("GET")-1)==0) {
          *isGet = TRUE;
        } else if (UTIL1_strncmp(p, "POST", sizeof("POST")-1)==0) {
          *isGet = FALSE;
        } else {
          res = ERR_FAILED;
        }
        while(*p!='\0') {
          p++; /* skip to the end */
        }
        /* read the rest of the message */
        res = ReadIntoIPDBuffer(msgBuf, msgBufSize, (uint8_t*)p, (*size)-ipdSize, ESP_DEFAULT_TIMEOUT_MS, io);
        break;
      }
    }
  }
  return res;
}
예제 #5
0
byte MCP4728_ParseCommand(const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io) {
  const unsigned char *p;

  if (UTIL1_strcmp((char*)cmd, CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, "MCP4728 help")==0) {
    *handled = TRUE;
    return PrintHelp(io);
  } else if ((UTIL1_strcmp((char*)cmd, CLS1_CMD_STATUS)==0) || (UTIL1_strcmp((char*)cmd, "MCP4728 status")==0)) {
    *handled = TRUE;
    return PrintStatus(io);
  } else if (UTIL1_strcmp((char*)cmd, "MCP4728 reset")==0) {
    *handled = TRUE;
    if (MCP4728_Reset()!=ERR_OK) {
      return ERR_FAILED;
    } else {
      return ERR_OK;
    }
  } else if (UTIL1_strcmp((char*)cmd, "MCP4728 wakeup")==0) {
    *handled = TRUE;
    if (MCP4728_Wakeup()!=ERR_OK) {
      return ERR_FAILED;
    } else {
      return ERR_OK;
    }
  } else if (UTIL1_strcmp((char*)cmd, "MCP4728 update")==0) {
    *handled = TRUE;
    if (MCP4728_Update()!=ERR_OK) {
      return ERR_FAILED;
    } else {
      return ERR_OK;
    }
  } else if (UTIL1_strncmp((char*)cmd, "MCP4728 fastwrite all ", sizeof("MCP4728 fastwrite all ")-1)==0) {
    uint16_t dac[4];
    uint8_t pd[4];
    int i;

    *handled = TRUE;
    p = cmd+sizeof("MCP4728 fastwrite all ")-1;
    for(i=0;i<4;i++) { /* init */
      dac[i] = 0;
      pd[i] = 0;
    }
    for(i=0;i<4;i++) {
      if (UTIL1_ScanHex16uNumber(&p, &dac[i])!=ERR_OK) {
        break;
      }
      dac[i] &= MCP4728_MAX_DAC_VAL; /* ensure it is 12 bits */
    }
    if (i!=4) {
      CLS1_SendStr((unsigned char*)"**** Not enough values, 4 expected!\r\n", io->stdErr);
      return ERR_FAILED;
    }
    if (MCP4728_FastWriteAllDAC(dac, sizeof(dac), pd, sizeof(pd))!=ERR_OK) {
      CLS1_SendStr((unsigned char*)"**** FastWrite failed.\r\n", io->stdErr);
      return ERR_FAILED;
    } else {
      return ERR_OK;
    }
  } else if (UTIL1_strncmp((char*)cmd, "MCP4728 fastwrite ", sizeof("MCP4728 fastwrite ")-1)==0) {
    /* e.g. MCP4728 fastwrite 2 0x512 */
    uint16_t dac=0;
    uint8_t channel=0;

    *handled = TRUE;
    p = cmd+sizeof("MCP4728 fastwrite ")-1;
    if (UTIL1_ScanDecimal8uNumber(&p, &channel)!=ERR_OK || channel>3) {
      CLS1_SendStr((unsigned char*)"**** error parsing channel, must be 0, 1, 2 or 3!\r\n", io->stdErr);
      return ERR_FAILED;
    }
    if (UTIL1_ScanHex16uNumber(&p, &dac)!=ERR_OK || dac>MCP4728_MAX_DAC_VAL) {
      CLS1_SendStr((unsigned char*)"**** error parsing 12bit hex value, must start with 0x!\r\n", io->stdErr);
      return ERR_FAILED;
    }
    dac &= MCP4728_MAX_DAC_VAL; /* ensure it is 12 bits */
    if (MCP4728_FastWriteDAC(channel, dac)!=ERR_OK) {
      CLS1_SendStr((unsigned char*)"**** Write channel DAC failed!\r\n", io->stdErr);
      return ERR_FAILED;
    } else {
      return ERR_OK;
    }
  } else if (UTIL1_strncmp((char*)cmd, "MCP4728 write ", sizeof("MCP4728 write ")-1)==0) {
    uint16_t dac;
    uint8_t ch, res;

    *handled = TRUE;
    res = ERR_OK;
    p = cmd+sizeof("MCP4728 write ")-1;
    if (UTIL1_ScanDecimal8uNumber(&p, &ch)!=ERR_OK || ch>3) {
      CLS1_SendStr((unsigned char*)"**** Failed reading channel. Must be 0, 1, 2 or 3\r\n", io->stdErr);
      res = ERR_FAILED;
    } else {
      if (UTIL1_ScanHex16uNumber(&p, &dac)!=ERR_OK) {
        CLS1_SendStr((unsigned char*)"**** Failed DAC value, must start with 0x\r\n", io->stdErr);
        res = ERR_FAILED;
      } else {
        if (MCP4728_WriteDACandEE(ch, dac)!=ERR_OK) {
          CLS1_SendStr((unsigned char*)"**** Write failed.\r\n", io->stdErr);
          res = ERR_FAILED;
        }
      }
    }
    return res;
  }
  return ERR_OK;
}
예제 #6
0
uint8_t RNETA_ParseCommand(const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io) {
  uint8_t res = ERR_OK;
  const uint8_t *p;
  uint16_t val16;
  uint8_t val8;

  if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, (char*)"app help")==0) {
    PrintHelp(io);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_STATUS)==0 || UTIL1_strcmp((char*)cmd, (char*)"app status")==0) {
    *handled = TRUE;
    return PrintStatus(io);
  } else if (UTIL1_strncmp((char*)cmd, (char*)"app saddr", sizeof("app saddr")-1)==0) {
    p = cmd + sizeof("app saddr")-1;
    *handled = TRUE;
    if (UTIL1_ScanHex16uNumber(&p, &val16)==ERR_OK) {
      (void)RNWK_SetThisNodeAddr((RNWK_ShortAddrType)val16);
    } else {
      CLS1_SendStr((unsigned char*)"ERR: wrong address\r\n", io->stdErr);
      return ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"app send val", sizeof("app send val")-1)==0) {
    p = cmd + sizeof("app send val")-1;
    *handled = TRUE;
    if (UTIL1_ScanDecimal8uNumber(&p, &val8)==ERR_OK) {
      (void)RAPP_SendPayloadDataBlock(&val8, sizeof(val8), RAPP_MSG_TYPE_DATA, APP_dstAddr, RPHY_PACKET_FLAGS_NONE); /* only send low byte */
    } else {
      CLS1_SendStr((unsigned char*)"ERR: wrong number format\r\n", io->stdErr);
      return ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"app daddr", sizeof("app daddr")-1)==0) {
    p = cmd + sizeof("app daddr")-1;
    *handled = TRUE;
    if (UTIL1_ScanHex16uNumber(&p, &val16)==ERR_OK) {
      APP_dstAddr = val16;
    } else {
      CLS1_SendStr((unsigned char*)"ERR: wrong address\r\n", io->stdErr);
      return ERR_FAILED;
    }
#if PL_HAS_RSTDIO
  } else if (UTIL1_strncmp((char*)cmd, (char*)"app send", sizeof("app send")-1)==0) {
    unsigned char buf[32];
    RSTDIO_QueueType queue;
    
    if (UTIL1_strncmp((char*)cmd, (char*)"app send in", sizeof("app send in")-1)==0) {
      queue = RSTDIO_QUEUE_TX_IN;
      cmd += sizeof("app send in");
    } else if (UTIL1_strncmp((char*)cmd, (char*)"app send out", sizeof("app send out")-1)==0) {
      queue = RSTDIO_QUEUE_TX_OUT;      
      cmd += sizeof("app send out");
    } else if (UTIL1_strncmp((char*)cmd, (char*)"app send err", sizeof("app send err")-1)==0) {
      queue = RSTDIO_QUEUE_TX_ERR;      
      cmd += sizeof("app send err");
    } else {
      return ERR_OK; /* not handled */
    }
    UTIL1_strcpy(buf, sizeof(buf), cmd);
    UTIL1_chcat(buf, sizeof(buf), '\n');
    buf[sizeof(buf)-2] = '\n'; /* have a '\n' in any case */
    if (RSTDIO_SendToTxStdio(queue, buf, UTIL1_strlen((char*)buf))!=ERR_OK) {
      CLS1_SendStr((unsigned char*)"failed!\r\n", io->stdErr);
    }
    *handled = TRUE;
#endif
  }
  return res;
}
예제 #7
0
uint8_t TURN_ParseCommand(const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io) {
  uint8_t res = ERR_OK;
  const unsigned char *p;
  uint8_t val8u;
  uint16_t val16u;

  if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, (char*)"turn help")==0) {
    TURN_PrintHelp(io);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_STATUS)==0 || UTIL1_strcmp((char*)cmd, (char*)"turn status")==0) {
    TURN_PrintStatus(io);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn left")==0) {
    TURN_Turn(TURN_LEFT90, FALSE);
    TURN_Turn(TURN_STOP, FALSE);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn right")==0) {
    TURN_Turn(TURN_RIGHT90, FALSE);
    TURN_Turn(TURN_STOP, FALSE);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn around")==0) {
    TURN_Turn(TURN_LEFT180, FALSE);
    TURN_Turn(TURN_STOP, FALSE);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn forward")==0) {
    REF_ClearHistory(); /* clear values */
    TURN_Turn(TURN_STEP_FW, FALSE);
    TURN_Turn(TURN_STOP, FALSE);
    CLS1_SendStr((unsigned char*)REF_LineKindStr(REF_HistoryLineKind()), CLS1_GetStdio()->stdOut);
    CLS1_SendStr((unsigned char*)"\r\n", CLS1_GetStdio()->stdOut);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn backward")==0) {
    TURN_Turn(TURN_STEP_BW, FALSE);
    TURN_Turn(TURN_STOP, FALSE);
    *handled = TRUE;
  } else if (UTIL1_strncmp((char*)cmd, (char*)"turn duty ", sizeof("turn duty ")-1)==0) {
    p = cmd+sizeof("turn duty");
    if (UTIL1_ScanDecimal8uNumber(&p, &val8u)==ERR_OK && val8u<=100) {
      TURN_DutyPercent = val8u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument, must be in the range -100..100\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"turn time ", sizeof("turn time ")-1)==0) {
    p = cmd+sizeof("turn time");
    if (UTIL1_ScanDecimal16uNumber(&p, &val16u)==ERR_OK) {
      TURN_TimeMs = val16u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"turn step ", sizeof("turn step ")-1)==0) {
    p = cmd+sizeof("turn step");
    if (UTIL1_ScanDecimal16uNumber(&p, &val16u)==ERR_OK) {
      TURN_StepMs = val16u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  }
  return res;
}
예제 #8
0
파일: Turn.c 프로젝트: sethj00/mcuoneclipse
uint8_t TURN_ParseCommand(const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io) {
  uint8_t res = ERR_OK;
  const unsigned char *p;
#if !PL_HAS_QUADRATURE
  uint8_t val8u;
#endif
  uint16_t val16u;

  if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, (char*)"turn help")==0) {
    TURN_PrintHelp(io);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)CLS1_CMD_STATUS)==0 || UTIL1_strcmp((char*)cmd, (char*)"turn status")==0) {
    TURN_PrintStatus(io);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn left 45")==0) {
    TURN_Turn(TURN_LEFT45);
    TURN_Turn(TURN_STOP);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn left 90")==0) {
    TURN_Turn(TURN_LEFT90);
    TURN_Turn(TURN_STOP);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn right 45")==0) {
    TURN_Turn(TURN_RIGHT45);
    TURN_Turn(TURN_STOP);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn right 90")==0) {
    TURN_Turn(TURN_RIGHT90);
    TURN_Turn(TURN_STOP);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn around")==0) {
    TURN_Turn(TURN_LEFT180);
    TURN_Turn(TURN_STOP);
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn forward")==0) {
#if PL_APP_LINE_MAZE
    REF_ClearHistory(); /* clear values */
#endif
    TURN_Turn(TURN_STEP_FW);
    TURN_Turn(TURN_STOP);
#if PL_APP_LINE_MAZE
    CLS1_SendStr((unsigned char*)REF_LineKindStr(REF_HistoryLineKind()), CLS1_GetStdio()->stdOut);
    CLS1_SendStr((unsigned char*)"\r\n", CLS1_GetStdio()->stdOut);
#endif
    *handled = TRUE;
  } else if (UTIL1_strcmp((char*)cmd, (char*)"turn backward")==0) {
    TURN_Turn(TURN_STEP_BW);
    TURN_Turn(TURN_STOP);
    *handled = TRUE;
#if PL_HAS_QUADRATURE
  } else if (UTIL1_strncmp((char*)cmd, (char*)"turn steps90 ", sizeof("turn steps90 ")-1)==0) {
    p = cmd+sizeof("turn steps90");
    if (UTIL1_ScanDecimal16uNumber(&p, &val16u)==ERR_OK) {
      TURN_Steps90 = val16u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"turn stepsfw ", sizeof("turn stepsfw ")-1)==0) {
    p = cmd+sizeof("turn stepsfw");
    if (UTIL1_ScanDecimal16uNumber(&p, &val16u)==ERR_OK) {
      TURN_StepsFwBw = val16u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
#else
  } else if (UTIL1_strncmp((char*)cmd, (char*)"turn duty ", sizeof("turn duty ")-1)==0) {
    p = cmd+sizeof("turn duty");
    if (UTIL1_ScanDecimal8uNumber(&p, &val8u)==ERR_OK && val8u<=100) {
      TURN_DutyPercent = val8u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument, must be in the range -100..100\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"turn time90 ", sizeof("turn time90 ")-1)==0) {
    p = cmd+sizeof("turn time90");
    if (UTIL1_ScanDecimal16uNumber(&p, &val16u)==ERR_OK) {
      TURN_Time90ms = val16u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
  } else if (UTIL1_strncmp((char*)cmd, (char*)"turn timefw ", sizeof("turn timefw ")-1)==0) {
    p = cmd+sizeof("turn timefw");
    if (UTIL1_ScanDecimal16uNumber(&p, &val16u)==ERR_OK) {
      TURN_StepFwBwMs = val16u;
      *handled = TRUE;
    } else {
      CLS1_SendStr((unsigned char*)"Wrong argument\r\n", io->stdErr);
      res = ERR_FAILED;
    }
#endif
  }
  return res;
}