diff --git a/LibSidServo/libsidservo.creator.user b/LibSidServo/libsidservo.creator.user index 524f200..5fa6513 100644 --- a/LibSidServo/libsidservo.creator.user +++ b/LibSidServo/libsidservo.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/LibSidServo/main.c b/LibSidServo/main.c index e7b4a20..d7c6c7a 100644 --- a/LibSidServo/main.c +++ b/LibSidServo/main.c @@ -61,10 +61,14 @@ static mcc_errcodes_t init(conf_t *c){ ret = MCC_E_ENCODERDEV; } } - if(Conf.MountReqInterval > 1. || Conf.MountReqInterval < 0.001){ + if(Conf.MountReqInterval > 1. || Conf.MountReqInterval < 0.05){ DBG("Bad value of MountReqInterval"); ret = MCC_E_BADFORMAT; } + char buf[1024]; + data_t d = {.buf = buf, .len = 0, .maxlen = 1024}; + // read input data as there may be some trash on start + if(!SSrawcmd(CMD_EXITACM, &d)) ret = MCC_E_FAILED; if(ret != MCC_E_OK) quit(); return ret; } diff --git a/LibSidServo/serial.c b/LibSidServo/serial.c index 7fc46d1..d9bf9e2 100644 --- a/LibSidServo/serial.c +++ b/LibSidServo/serial.c @@ -398,6 +398,13 @@ int MountWriteRead(const data_t *out, data_t *in){ pthread_mutex_unlock(&mntmutex); return ret; } +// send binary data - without EOL +int MountWriteReadRaw(const data_t *out, data_t *in){ + pthread_mutex_lock(&mntmutex); + int ret = wr(out, in, 0); + pthread_mutex_unlock(&mntmutex); + return ret; +} #ifdef EBUG static void logscmd(SSscmd *c){ diff --git a/LibSidServo/serial.h b/LibSidServo/serial.h index d92542b..b880d91 100644 --- a/LibSidServo/serial.h +++ b/LibSidServo/serial.h @@ -36,5 +36,6 @@ int openMount(const char *path, int speed); void closeSerial(); mcc_errcodes_t getMD(mountdata_t *d); int MountWriteRead(const data_t *out, data_t *in); +int MountWriteReadRaw(const data_t *out, data_t *in); int cmdS(SSscmd *cmd); int cmdL(SSlcmd *cmd); diff --git a/LibSidServo/sidservo.h b/LibSidServo/sidservo.h index 79ea016..0d5d322 100644 --- a/LibSidServo/sidservo.h +++ b/LibSidServo/sidservo.h @@ -73,6 +73,10 @@ typedef struct{ double voltage; } mountdata_t; +typedef struct{ + ; +} mountstat_t; + typedef struct{ double Xmot; // 0 X motor position (rad) double Xspeed; // 4 X speed (rad/s) diff --git a/LibSidServo/ssii.c b/LibSidServo/ssii.c index 9a008b3..8ec8f00 100644 --- a/LibSidServo/ssii.c +++ b/LibSidServo/ssii.c @@ -90,6 +90,19 @@ int SStextcmd(const char *cmd, data_t *answer){ return MountWriteRead(&d, answer); } +// the same as SStextcmd, but not adding EOL - send raw 'cmd' +int SSrawcmd(const char *cmd, data_t *answer){ + if(!cmd){ + DBG("try to send empty command"); + return FALSE; + } + data_t d; + d.buf = (uint8_t*) cmd; + d.len = d.maxlen = strlen(cmd); + DBG("send %zd bytes: %s", d.len, d.buf); + return MountWriteReadRaw(&d, answer); +} + /** * @brief SSgetint - send text command and return integer answer * @param cmd (i) - command to send diff --git a/LibSidServo/ssii.h b/LibSidServo/ssii.h index 9250dd9..03b7dbf 100644 --- a/LibSidServo/ssii.h +++ b/LibSidServo/ssii.h @@ -55,31 +55,80 @@ #endif // get binary data of all statistics -#define CMD_GETSTAT ("XXS") +#define CMD_GETSTAT "XXS" // send short command -#define CMD_SHORTCMD ("XXR") +#define CMD_SHORTCMD "XXR" // send long command -#define CMD_LONGCMD ("YXR") +#define CMD_LONGCMD "YXR" // get/set X/Y in motsteps -#define CMD_MOTX ("X") -#define CMD_MOTY ("Y") -// -//- in encoders' ticks -#define CMD_ENCX ("XZ") -#define CMD_ENCY ("YZ") +#define CMD_MOTX "X" +#define CMD_MOTY "Y" +// set X/Y position with speed "sprintf(buf, "%s%d%s%d", CMD_MOTx, tagx, CMD_MOTxS, tags) +#define CMD_MOTXS "S" +// reset current motor position to given value (and stop, if moving) +#define CMD_MOTXSET "XF" +#define CMD_MOTYSET "YF" +// acceleration (per each loop, max: 3900) +#define CMD_MOTXACCEL "XR" +#define CMD_MOTYACCEL "YR" +// PID regulator: +// P: 0..32767 +#define CMD_PIDPX "XP" +#define CMD_PIDPY "YP" +// I: 0..32767 +#define CMD_PIDIX "XI" +#define CMD_PIDIY "YI" +// limit of I (doesn't work): 0:24000 (WTF???) +#define CMD_PIDILX "XL" +#define CMD_PIDILY "YL" +// D: 0..32767 +#define CMD_PIDDX "XD" +#define CMD_PIDDY "YD" +// current position error +#define CMD_POSERRX "XE" +#define CMD_POSERRY "YE" +// max position error limit (X: E#, Y: e#) +#define CMD_POSERRLIMX "XEL" +#define CMD_POSERRLIMY "YEL" +// current PWM output: 0..255 (or set max PWM out) +#define CMD_PWMOUTX "XO" +#define CMD_PWMOUTY "YO" +// motor current *100 (or set current limit): 0..240 +#define CMD_MOTCURNTX "XC" +#define CMD_MOTCURNTY "YC" +// change axis to Manual mode and set the PWM output: -255:255 +#define CMD_MANUALPWMX "XM" +#define CMD_MANUALPWMY "YM" +// change axis to Auto mode +#define CMD_AUTOX "XA" +#define CMD_AUTOY "YA" +// get positioin in encoders' ticks or reset it to given value +#define CMD_ENCX "XZ" +#define CMD_ENCY "YZ" +// get/set speed (geter x: S#, getter y: s#) +#define CMD_SPEEDX "XS" +#define CMD_SPEEDY "YS" // normal stop X/Y -#define CMD_STOPX ("XN") -#define CMD_STOPY ("YN") +#define CMD_STOPX "XN" +#define CMD_STOPY "YN" // emergency stop -#define CMD_EMSTOPX ("XG") -#define CMD_EMSTOPY ("YG") +#define CMD_EMSTOPX "XG" +#define CMD_EMSTOPY "YG" +// get/set X/Ybits +#define CMD_BITSX "XB" +#define CMD_BITSY "YB" // getters of motor's encoders per rev -#define CMD_GETXMEPR ("XXU") -#define CMD_GETYMEPR ("XXV") +#define CMD_GETXMEPR "XXU" +#define CMD_GETYMEPR "XXV" // -//- axis encoders -#define CMD_GETXAEPR ("XXT") -#define CMD_GETYAEPR ("XXZ") +#define CMD_GETXAEPR "XXT" +#define CMD_GETYAEPR "XXZ" // exit ASCII checksum mode -#define CMD_EXITACM ("YXY0\r\xb8") +#define CMD_EXITACM "YXY0\r\xb8" +// controller status: +// X# Y# XZ# YZ# XC# YC# V# T# X[AM] Y[AM] K# +// X,Y - motor, XZ,YZ - encoder, XC,YC - current*100, V - voltage*10, T - temp (F), XA,YA - mode (A[uto]/M[anual]), K - handpad status bits +#define CMD_GETSTAT "\r" // steps per revolution //#define X_MOT_STEPSPERREV (3325440.) @@ -115,6 +164,29 @@ #define XencTOL (25.) +typedef struct{ + uint8_t motrev :1; // If 1, the motor encoder is incremented in the opposite direction + uint8_t motpolarity :1; // If 1, the motor polarity is reversed + uint8_t encrev :1; // If 1, the axis encoder is reversed + uint8_t dragtrack :1; // If 1, we are in computerless Drag and Track mode + uint8_t trackplat :1; // If 1, we are in the tracking platform mode + uint8_t handpaden :1; // If 1, hand paddle is enabled + uint8_t newpad :1; // If 1, hand paddle is compatible with New hand paddle, which allows slewing in two directions and guiding + uint8_t guidemode :1; // If 1, we are in guide mode. The pan rate is added or subtracted from the current tracking rate +} xbits_t; + +typedef struct{ + uint8_t motrev :1; // If 1, the motor encoder is incremented in the opposite direction + uint8_t motpolarity :1; // If 1, the motor polarity is reversed + uint8_t encrev :1; // If 1, the axis encoder is reversed + /* If 1, we are in computerless Slew and Track mode + (no clutches; use handpad to slew; must be in Drag and Track mode too) */ + uint8_t slewtrack :1; + uint8_t digin_sens :1; // Digital input from radio handpad receiver, or RA PEC Sensor sync + uint8_t digin :3; // Digital input from radio handpad receiver +} ybits_t; + + // all need data in one typedef struct{ // 41 bytes uint8_t ctrlAddr; // 0 a8 + controller address @@ -123,8 +195,8 @@ typedef struct{ // 41 bytes int32_t Xenc; // 9 Dec/HA encoder position int32_t Yenc; // 13 uint8_t keypad; // 17 keypad status - uint8_t XBits; // 18 - uint8_t YBits; // 19 + xbits_t XBits; // 18 + ybits_t YBits; // 19 uint8_t ExtraBits; // 20 uint16_t ain0; // 21 analog inputs uint16_t ain1; // 23 @@ -162,6 +234,7 @@ typedef struct{ uint16_t SScalcChecksum(uint8_t *buf, int len); void SSconvstat(const SSstat *status, mountdata_t *mountdata, struct timeval *tdat); int SStextcmd(const char *cmd, data_t *answer); +int SSrawcmd(const char *cmd, data_t *answer); int SSgetint(const char *cmd, int64_t *ans); int SSXmoveto(double pos); int SSYmoveto(double pos);