]> rtime.felk.cvut.cz Git - mirosot.git/blobdiff - testapp/cmd_pxmc.c
Added the correct final version of Petr's application.
[mirosot.git] / testapp / cmd_pxmc.c
diff --git a/testapp/cmd_pxmc.c b/testapp/cmd_pxmc.c
new file mode 100644 (file)
index 0000000..9e0200c
--- /dev/null
@@ -0,0 +1,610 @@
+/*******************************************************************
+  Components for embedded applications builded for
+  laboratory and medical instruments firmware  
+  cmd_stm.c - interconnection of Stepper Motor control
+              subsystem with RS-232 command processor
+             used mainly for controller tuning
+  Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
+            (C) 2002 by PiKRON Ltd. http://www.pikron.com
+
+ *******************************************************************/
+
+#include <types.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <cmd_proc.h>
+#include <cpu_def.h>
+#include <pxmc.h>
+#include "cmd_pxmc.h"
+
+
+/**
+ * cmd_opchar_getreg - selects the right axis
+ * 
+ * pxmc is designed for multi axis motion control, so each axis must be identificated.
+ * This done by a capital letter. The first axis must be A, the 2nd B, etc.   
+ */
+pxmc_state_t *cmd_opchar_getreg(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{ 
+  unsigned chan;
+  pxmc_state_t *mcs;
+  chan=*param[1]-'A';
+  if(chan>=pxmc_main_list.pxml_cnt) return NULL;
+  mcs=pxmc_main_list.pxml_arr[chan];
+  if(!mcs) return NULL;
+  return mcs;
+}
+
+/**
+ * cmd_do_reg_go - checks the command format validity and calls pxmc_go.
+ * 
+ * if pxmc_go returns -1, cmd_do_reg_go returns -1.
+ */
+int cmd_do_reg_go(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{ 
+  long val;
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  val=atol(param[3])<<PXMC_SUBDIV(mcs);
+  val=pxmc_go(mcs,val,0,0);
+  if(val<0)
+    return val;
+  return 0;
+}
+
+
+/**
+ * cmd_do_pwm - checks the command format validity and calls pxmc_set_const_out.
+ * 
+ */ 
+int cmd_do_pwm(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  int val;
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  val=atoi(param[3]);
+  pxmc_set_const_out(mcs,val);
+  return 0;
+}
+
+/**
+ * cmd_do_reg_hh - checks the command format validity and calls pxmc_hh (home hardware).
+ * 
+ * if pxmc_hh returns -1, cmd_do_reg_hh returns -1.
+ */ 
+int cmd_do_reg_hh(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  long val;
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  val=pxmc_hh(mcs);
+  if(val<0)
+    return val;
+  return 0;
+}
+
+
+/**
+ * cmd_do_reg_spd - checks the command format validity and calls pxmc_spd.
+ * 
+ * if pxmc_spd returns -1, cmd_do_reg_spd returns -1.
+ */ 
+int cmd_do_reg_spd(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  long val;
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  val=atol(param[3]);
+  val=pxmc_spd(mcs,val,0);
+  if(val<0)
+    return val;
+  return 0;
+}
+
+/**
+ * cmd_do_reg_spdfg - checks the command format validity and calls pxmc_spdfg.
+ * 
+ * if pxmc_spdfg returns -1, cmd_do_reg_spdfg returns -1.
+ */ 
+int cmd_do_reg_spdfg(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  long val;
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  val=atol(param[3]);
+  val=pxmc_spdfg(mcs,val,0);
+  if(val<0)
+    return val;
+  return 0;
+}
+
+/**
+ * cmd_do_stop - checks the command format validity and calls pxmc_stop.
+ * 
+ */ 
+int cmd_do_stop(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  pxmc_stop(mcs,0);
+  return 0;
+}
+
+/**
+ * cmd_do_release - checks the command format validity and calls pxmc_set_const_out(mcs,0).
+ * 
+ */ 
+int cmd_do_release(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  pxmc_set_const_out(mcs,0);
+  return 0;
+}
+
+/**
+ * cmd_do_clrerr - checks the command format validity, clears the error flag.
+ * 
+ * it also stop the rotation calling pxmc_set_const_out(mcs,0)
+ */ 
+int cmd_do_clrerr(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  pxmc_set_const_out(mcs,0);
+  pxmc_clear_flag(mcs,PXMS_ERR_b);
+  return 0;
+}
+
+/**
+ * cmd_do_zero - checks the command format validity, sets axis position to 0.
+ * 
+ * it also stop the rotation calling pxmc_set_const_out(mcs,0)
+ */ 
+int cmd_do_zero(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  pxmc_set_const_out(mcs,0);
+  pxmc_axis_set_pos(mcs,0);
+  return 0;
+}
+
+/**
+ * cmd_do_align - checks the command format validity, sets offset between table and IRC counter to 0 .
+ * 
+ * it also stop the rotation calling pxmc_set_const_out(mcs,0) and sets axis position to 0.
+ */ 
+int cmd_do_align(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  pxmc_set_const_out(mcs,0);
+  pxmc_axis_set_pos(mcs,0);
+  mcs->pxms_ptofs=0;
+  return 0;
+}
+
+/**
+ * cmd_do_reg_rw_pos - read or write function, param is converted in 'long' and shifted
+ * 
+ * if the command typed is a write function, records the value, 
+ * if it is a read function returns the value asked.
+ */ 
+
+int cmd_do_reg_rw_pos(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  long val;
+  long *ptr;
+  int opchar;
+  pxmc_state_t *mcs;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  ptr=(long*)((long)des->info[0]+(char*)mcs);
+  if(opchar==':'){
+    val=atol(param[3]);
+    *ptr=val<<PXMC_SUBDIV(mcs);
+  }else{
+    return cmd_opchar_replong(cmd_io, param, (*ptr)>>PXMC_SUBDIV(mcs), 0, 0);
+  }
+  return 0; 
+}
+
+/**
+ * cmd_do_reg_short_val - read or write function, param is converted in 'integer'
+ * 
+ * if the command typed is a write function, records the value, 
+ * if it is a read function returns the value asked.
+ */ 
+
+int cmd_do_reg_short_val(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  int val;
+  short *ptr;
+  int opchar;
+  pxmc_state_t *mcs;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  ptr=(short*)((long)des->info[0]+(char*)mcs);
+  if(opchar==':'){
+    val=atoi(param[3]);
+    *ptr=val;
+  }else{
+    return cmd_opchar_replong(cmd_io, param, (long)*ptr, 0, 0);
+  }
+  return 0; 
+}
+
+/**
+ * cmd_do_reg_long_val - read or write function, param is converted in 'long'
+ * 
+ * if the command typed is a write function, records the value, 
+ * if it is a read function returns the value asked.
+ */ 
+int cmd_do_reg_long_val(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  long val;
+  long *ptr;
+  int opchar;
+  pxmc_state_t *mcs;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  ptr=(long*)((long)des->info[0]+(char*)mcs);
+  if(opchar==':'){
+    val=atol(param[3]);
+    *ptr=val;
+  }else{
+    return cmd_opchar_replong(cmd_io, param, (long)*ptr, 0, 0);
+  }
+  return 0; 
+}
+
+
+/**
+ * cmd_do_axis_mode - checks the command format and busy flag validity, calls pxmc_axis_mode
+ * 
+ * if pxmc_axis_mode returns -1, cmd_do_axis_mode returns -1.
+ */ 
+int cmd_do_axis_mode(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  int val;
+  pxmc_state_t *mcs;
+  if(*param[2]!=':') return -CMDERR_OPCHAR;
+//   if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  if(mcs->pxms_flg&PXMS_BSY_m) return -CMDERR_BSYREG;
+  val=atol(param[3]);
+  val=pxmc_axis_mode(mcs,val);
+  if(val<0)
+    return val;
+  return 0;
+}
+
+
+int cmd_do_regptmod_short_val(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  int val;
+  short *ptr;
+  int opchar;
+  pxmc_state_t *mcs;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  ptr=(short*)((long)des->info[0]+(char*)mcs);
+  if(opchar==':'){
+    if(mcs->pxms_flg&PXMS_BSY_m) return -CMDERR_BSYREG;
+    pxmc_set_const_out(mcs,0);
+    val=atoi(param[3]);
+    if((val<((long)des->info[1])) || (val>((long)des->info[2])))
+      return -CMDERR_BADPAR; 
+    *ptr=val;
+    val=pxmc_axis_mode(mcs,0);
+    if(val<0)
+      return val;
+  }else{
+    return cmd_opchar_replong(cmd_io, param, (long)*ptr, 0, 0);
+  }
+  return 0; 
+}
+
+
+/**
+ * cmd_do_reg_type - no code written, will set controller structure
+ */ 
+int cmd_do_reg_type(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  /* should set controller structure */
+  return 0;
+}
+
+
+/**
+ * cmd_do_regsfrq - sets or returns smapling frequency
+ */ 
+#ifdef WITH_SFI_SEL
+int cmd_do_regsfrq(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  int val;
+  int opchar;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  if(opchar==':'){
+    val=atoi(param[3]);
+    return pxmc_sfi_sel(val);
+  }else{
+    return cmd_opchar_replong(cmd_io, param, pxmc_get_sfi_hz(NULL), 0, 0);
+  }
+  return 0; 
+}
+#endif /* WITH_SFI_SEL */
+
+
+/* debugging functions */
+int cmd_do_reg_dbgset(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_state_t *mcs;
+  int val;
+  int opchar;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  if((mcs=cmd_opchar_getreg(cmd_io,des,param))==NULL) return -CMDERR_BADREG;
+  if(opchar==':'){
+    val=atoi(param[3]);
+    pxmc_dbgset(mcs,pxmc_dbg_ene_as,val);
+  }else{
+    cmd_io_write(cmd_io,param[0],param[2]-param[0]);
+    cmd_io_putc(cmd_io,'=');
+    cmd_io_putc(cmd_io,mcs->pxms_flg&PXMS_DBG_m?'1':'0');
+  }
+  return 0; 
+}
+
+
+int cmd_do_reg_dbgpre(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_dbg_hist_t *hist;
+  long count, val;
+  int i;
+  int opchar;
+  char *ps;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  ps=param[3];
+  if(si_long(&ps,&count,0)<0) return -CMDERR_BADPAR;
+  if(!count||(count>0x10000)) return -CMDERR_BADPAR;
+  pxmc_dbg_histfree(NULL);
+  if((hist=pxmc_dbg_histalloc(count+2))==NULL) return -CMDERR_NOMEM;
+  for(i=0;i<count;i++){
+    /* ps=cmd_rs232_rdline(cmd_io,1); */ /* !!!!!!!!! */
+    if(si_long(&ps,&val,0)<0) return -CMDERR_BADPAR;
+    hist->buff[i]=val;
+  }
+  pxmc_dbg_hist=hist;
+  return 0;
+}
+
+
+int cmd_do_reg_dbghis(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_dbg_hist_t *hist;
+  long count, val;
+  int i, opchar;
+  char *ps;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  ps=param[3];
+  if(si_long(&ps,&count,0)<0) return -CMDERR_BADPAR;
+  if(!count||(count>0x10000)) return -CMDERR_BADPAR;
+  hist=pxmc_dbg_hist;
+  for(i=0;i<count;i++){
+    if(hist&&(&hist->buff[i]<hist->end))
+      val=hist->buff[i];
+    else
+      val=0;
+    /* printf("%ld\r\n",val); */ /* !!!!!!!! */
+  }
+  return 0;
+}
+
+
+int cmd_do_reg_dbggnr(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
+{
+  pxmc_state_t *mcs;
+  int i;
+  int opchar;
+
+  if((opchar=cmd_opchar_check(cmd_io,des,param))<0) return opchar;
+  for(i=0;i<pxmc_main_list.pxml_cnt;i++){
+    mcs=pxmc_main_list.pxml_arr[i];
+    if(mcs&&(mcs->pxms_flg&PXMS_DBG_m)){
+      if(pxmc_dbg_gnr(mcs)<0){
+       for(i=0;i<pxmc_main_list.pxml_cnt;i++){
+         mcs=pxmc_main_list.pxml_arr[i];
+         if(mcs&&(mcs->pxms_flg&PXMS_DBG_m))
+              pxmc_stop(pxmc_main_list.pxml_arr[i],0);
+        }
+        return -CMDERR_BADREG;
+      }
+    }
+  }
+  pxmc_dbg_hist->ptr=pxmc_dbg_hist->buff;  
+  return 0; 
+}
+
+
+/* motor executable commands */
+cmd_des_t const cmd_des_go={0, CDESM_OPCHR|CDESM_RW,
+                       "G?","go to target position",cmd_do_reg_go,{}};
+cmd_des_t const cmd_des_pwm={0, CDESM_OPCHR|CDESM_RW,
+                       "PWM?","direct axis PWM output",cmd_do_pwm,{}};
+cmd_des_t const cmd_des_hh={0, CDESM_OPCHR,"HH?","hard home request for axis",cmd_do_reg_hh,{}};
+cmd_des_t const cmd_des_spd={0, CDESM_OPCHR,"SPD?","speed request for axis",cmd_do_reg_spd,{}};
+cmd_des_t const cmd_des_spdfg={0, CDESM_OPCHR,"SPDFG?",
+                       "fine grained speed request for axis",cmd_do_reg_spdfg,{}};
+cmd_des_t const cmd_des_stop={0, CDESM_OPCHR,
+                       "STOP?","stop motion of requested axis",cmd_do_stop,{}};
+cmd_des_t const cmd_des_release={0, CDESM_OPCHR,
+                       "RELEASE?","releases axis closed loop control",cmd_do_release,{}};
+cmd_des_t const cmd_des_zero={0, CDESM_OPCHR,
+                       "ZERO?","zero actual position",cmd_do_zero,{}};
+cmd_des_t const cmd_des_align={0, CDESM_OPCHR,
+                       "ALIGN?","align commutator",cmd_do_align,{}};
+cmd_des_t const cmd_des_clrerr={0, CDESM_OPCHR,
+    "PURGE?"," clear 'axis in error state' flag",cmd_do_clrerr,{}};
+/* motors and controllers variables */
+cmd_des_t const cmd_des_ap={0, CDESM_OPCHR|CDESM_RD,
+                       "AP?","actual position",cmd_do_reg_rw_pos,
+                       {(char*)pxmc_state_offs(pxms_ap),
+                        0}};
+cmd_des_t const cmd_des_st={0, CDESM_OPCHR|CDESM_RD,
+                       "ST?","axis status bits encoded in number",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_flg),
+                        0}};
+cmd_des_t const cmd_des_axerr={0, CDESM_OPCHR|CDESM_RD,
+                       "AXERR?","last axis error code",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_errno),
+                        0}};
+#if 0
+cmd_des_t const cmd_des_r_one={0, CDESM_OPCHR,
+                       "R?","send R?! or FAIL?! at axis finish",cmd_do_r_one,{}};
+#endif
+cmd_des_t const cmd_des_regp={0, CDESM_OPCHR|CDESM_RW,
+                       "REGP?","controller proportional gain",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_p),
+                        0}};
+cmd_des_t const cmd_des_regi={0, CDESM_OPCHR|CDESM_RW,
+                       "REGI?","controller integral gain",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_i),
+                        0}};
+cmd_des_t const cmd_des_regd={0, CDESM_OPCHR|CDESM_RW,
+                       "REGD?","controller derivative gain",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_d),
+                        0}};
+cmd_des_t const cmd_des_regs1={0, CDESM_OPCHR|CDESM_RW,
+                       "REGS1?","controller S1",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_s1),
+                        0}};
+cmd_des_t const cmd_des_regs2={0, CDESM_OPCHR|CDESM_RW,
+                       "REGS2?","controller S2",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_s2),
+                        0}};
+cmd_des_t const cmd_des_regmd={0, CDESM_OPCHR|CDESM_RW,
+                       "REGMD?","maximal allowed position error",cmd_do_reg_rw_pos,
+                       {(char*)pxmc_state_offs(pxms_md),
+                        0}};
+cmd_des_t const cmd_des_regms={0, CDESM_OPCHR|CDESM_RW,
+                       "REGMS?","maximal speed",cmd_do_reg_long_val,
+                       {(char*)pxmc_state_offs(pxms_ms),
+                        0}};
+cmd_des_t const cmd_des_regacc={0, CDESM_OPCHR|CDESM_RW,
+                       "REGACC?","maximal acceleration",cmd_do_reg_long_val,
+                       {(char*)pxmc_state_offs(pxms_ma),
+                        0}};
+cmd_des_t const cmd_des_regme={0, CDESM_OPCHR|CDESM_RW,
+                       "REGME?","maximal PWM energy or voltage for axis",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_me),
+                        0}};
+cmd_des_t const cmd_des_regcfg={0, CDESM_OPCHR|CDESM_RW,
+                       "REGCFG?","hard home and profile configuration",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_cfg),
+                        0}};
+cmd_des_t const cmd_des_ptirc={0, CDESM_OPCHR|CDESM_RW,
+                       "REGPTIRC?","number of irc pulses per phase table",cmd_do_regptmod_short_val,
+                       {(char*)pxmc_state_offs(pxms_ptirc),
+                        (char*)4,(char*)10000}};
+cmd_des_t const cmd_des_ptper={0, CDESM_OPCHR|CDESM_RW,
+                       "REGPTPER?","number of elmag. revolutions per phase table",cmd_do_regptmod_short_val,
+                       {(char*)pxmc_state_offs(pxms_ptper),
+                        (char*)1,(char*)100}};
+cmd_des_t const cmd_des_ptshift={0, CDESM_OPCHR|CDESM_RW,
+                       "REGPTSHIFT?","shift (in irc) of generated phase curves",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_ptshift),
+                        0}};
+cmd_des_t const cmd_des_ptvang={0, CDESM_OPCHR|CDESM_RW,
+                       "REGPTVANG?","angle (in irc) between rotor and stator mag. fld.",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_ptvang),
+                        0}};
+cmd_des_t const cmd_des_pwm1cor={0, CDESM_OPCHR|CDESM_RW,
+                       "REGPWM1COR?","PWM1 correction",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_pwm1cor),
+                        0}};
+cmd_des_t const cmd_des_pwm2cor={0, CDESM_OPCHR|CDESM_RW,
+                       "REGPWM2COR?","PWM2 correction",cmd_do_reg_short_val,
+                       {(char*)pxmc_state_offs(pxms_pwm2cor),
+                        0}};
+cmd_des_t const cmd_des_axis_mode={0, CDESM_OPCHR|CDESM_WR,
+                       "REGMODE?","axis working mode",cmd_do_axis_mode,
+                       {}};
+#ifdef WITH_SFI_SEL 
+cmd_des_t const cmd_des_regsfrq={0, CDESM_OPCHR|CDESM_RW,
+                       "REGSFRQ","set new sampling frequency",cmd_do_regsfrq,{}};
+#endif /* WITH_SFI_SEL */
+/* axes debugging and tuning */
+cmd_des_t const cmd_des_reg_type={0, CDESM_OPCHR|CDESM_RW,
+                       "REGTYPE?","unused",cmd_do_reg_type,{}};
+cmd_des_t const cmd_des_reg_dbgset={0, CDESM_OPCHR|CDESM_RW,
+                       "REGDBG?","sets debug flag",cmd_do_reg_dbgset,{}};
+cmd_des_t const cmd_des_reg_dbgpre={0, CDESM_OPCHR|CDESM_WR,
+                       "REGDBGPRE","store reference course",cmd_do_reg_dbgpre,{}};
+cmd_des_t const cmd_des_reg_dbghis={0, CDESM_OPCHR|CDESM_WR,
+                       "REGDBGHIS","read history course",cmd_do_reg_dbghis,{}};
+cmd_des_t const cmd_des_reg_dbggnr={0, CDESM_OPCHR|CDESM_WR,
+                       "REGDBGGNR","controller response to HIST course",cmd_do_reg_dbggnr,{}};
+
+cmd_des_t const *cmd_stm_default[]={
+  &cmd_des_go,
+  &cmd_des_pwm,
+  /*&cmd_des_hh,*/
+  &cmd_des_spd,
+  &cmd_des_spdfg,
+  &cmd_des_stop,
+  &cmd_des_release,
+  &cmd_des_zero,
+  &cmd_des_align,
+  &cmd_des_clrerr,
+  &cmd_des_ap,
+  &cmd_des_st,
+  &cmd_des_axerr,
+  /*&cmd_des_r_one,*/
+  &cmd_des_regp,
+  &cmd_des_regi,
+  &cmd_des_regd,
+  &cmd_des_regs1,
+  &cmd_des_regs2,
+  &cmd_des_regmd,
+  &cmd_des_regms,
+  &cmd_des_regacc,
+  &cmd_des_regme,
+  &cmd_des_regcfg,
+  &cmd_des_ptirc,
+  &cmd_des_ptper,
+  &cmd_des_ptshift,
+  &cmd_des_ptvang,
+  &cmd_des_pwm1cor,
+  &cmd_des_pwm2cor,
+  &cmd_des_axis_mode,
+  &cmd_des_reg_type,
+#ifdef WITH_SFI_SEL
+  &cmd_des_regsfrq,
+#endif /* WITH_SFI_SEL */
+  &cmd_des_reg_dbgset,
+  &cmd_des_reg_dbgpre,
+  &cmd_des_reg_dbghis,
+  &cmd_des_reg_dbggnr,
+  NULL
+};