nxt
This commit is contained in:
parent
a2e2896f29
commit
aefdf3912c
@ -51,10 +51,11 @@ void signals(int sig){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static conf_t Config = {
|
static conf_t Config = {
|
||||||
.MountPath = "/dev/ttyS1",
|
.MountDevPath = "/dev/ttyS1",
|
||||||
.MountSpeed = 19200,
|
.MountDevSpeed = 19200,
|
||||||
.EncoderPath = "/dev/ttyUSB0",
|
//.EncoderDevPath = "/dev/ttyUSB0",
|
||||||
.EncoderSpeed = 153000
|
//.EncoderDevSpeed = 153000,
|
||||||
|
.SepEncoder = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
@ -67,8 +68,8 @@ int main(int argc, char **argv){
|
|||||||
time_t curtime = time(NULL);
|
time_t curtime = time(NULL);
|
||||||
LOGMSG("Started @ %s", ctime(&curtime));
|
LOGMSG("Started @ %s", ctime(&curtime));
|
||||||
DBG("Devices ready");
|
DBG("Devices ready");
|
||||||
LOGMSG("Mount device %s @ %d", Config.MountPath, Config.MountSpeed);
|
LOGMSG("Mount device %s @ %d", Config.MountDevPath, Config.MountDevSpeed);
|
||||||
LOGMSG("Encoder device %s @ %d", Config.EncoderPath, Config.EncoderSpeed);
|
LOGMSG("Encoder device %s @ %d", Config.EncoderDevPath, Config.EncoderDevSpeed);
|
||||||
signal(SIGTERM, signals); // kill (-15) - quit
|
signal(SIGTERM, signals); // kill (-15) - quit
|
||||||
signal(SIGHUP, SIG_IGN); // hup - ignore
|
signal(SIGHUP, SIG_IGN); // hup - ignore
|
||||||
signal(SIGINT, signals); // ctrl+C - quit
|
signal(SIGINT, signals); // ctrl+C - quit
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 15.0.0, 2025-01-30T22:13:51. -->
|
<!-- Written by QtCreator 15.0.0, 2025-02-04T21:29:56. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@ -6,4 +6,5 @@ sidservo.h
|
|||||||
serial.c
|
serial.c
|
||||||
examples/CMakeLists.txt
|
examples/CMakeLists.txt
|
||||||
serial.h
|
serial.h
|
||||||
|
ssii.c
|
||||||
ssii.h
|
ssii.h
|
||||||
|
|||||||
@ -42,22 +42,26 @@ static mcc_errcodes_t init(conf_t *c){
|
|||||||
if(!c) return MCC_E_BADFORMAT;
|
if(!c) return MCC_E_BADFORMAT;
|
||||||
Conf = *c;
|
Conf = *c;
|
||||||
mcc_errcodes_t ret = MCC_E_OK;
|
mcc_errcodes_t ret = MCC_E_OK;
|
||||||
if(!Conf.MountPath || Conf.MountSpeed < 1200){
|
if(!Conf.MountDevPath || Conf.MountDevSpeed < 1200){
|
||||||
DBG("Define mount device path and speed");
|
DBG("Define mount device path and speed");
|
||||||
ret = MCC_E_BADFORMAT;
|
ret = MCC_E_BADFORMAT;
|
||||||
}else if(!openMount(Conf.MountPath, Conf.MountSpeed)){
|
}else if(!openMount(Conf.MountDevPath, Conf.MountDevSpeed)){
|
||||||
DBG("Can't open %s with speed %d", Conf.MountPath, Conf.MountSpeed);
|
DBG("Can't open %s with speed %d", Conf.MountDevPath, Conf.MountDevSpeed);
|
||||||
ret = MCC_E_MOUNTDEV;
|
ret = MCC_E_MOUNTDEV;
|
||||||
}
|
}
|
||||||
if(Conf.SepEncoder){
|
if(Conf.SepEncoder){
|
||||||
if(!Conf.EncoderPath || Conf.EncoderSpeed < 1200){
|
if(!Conf.EncoderDevPath || Conf.EncoderDevSpeed < 1200){
|
||||||
DBG("Define encoder device path and speed");
|
DBG("Define encoder device path and speed");
|
||||||
ret = MCC_E_BADFORMAT;
|
ret = MCC_E_BADFORMAT;
|
||||||
}else if(!openEncoder(Conf.EncoderPath, Conf.EncoderSpeed)){
|
}else if(!openEncoder(Conf.EncoderDevPath, Conf.EncoderDevSpeed)){
|
||||||
DBG("Can't open %s with speed %d", Conf.EncoderPath, Conf.EncoderSpeed);
|
DBG("Can't open %s with speed %d", Conf.EncoderDevPath, Conf.EncoderDevSpeed);
|
||||||
ret = MCC_E_ENCODERDEV;
|
ret = MCC_E_ENCODERDEV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(Conf.MountReqInterval < 1 || Conf.MountReqInterval > 1000000){
|
||||||
|
DBG("Bad value of MountReqInterval");
|
||||||
|
retr = MCC_E_FATAL;
|
||||||
|
}
|
||||||
if(ret != MCC_E_OK) quit();
|
if(ret != MCC_E_OK) quit();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,8 @@ static pthread_mutex_t mntmutex = PTHREAD_MUTEX_INITIALIZER,
|
|||||||
datamutex = PTHREAD_MUTEX_INITIALIZER;
|
datamutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
// encoders thread and mount thread
|
// encoders thread and mount thread
|
||||||
static pthread_t encthread, mntthread;
|
static pthread_t encthread, mntthread;
|
||||||
|
// max timeout for 1.5 bytes of encoder and 2 bytes of mount
|
||||||
|
static struct timeval encRtmout = {0}, mntRtmout = {0};
|
||||||
// encoders raw data
|
// encoders raw data
|
||||||
typedef struct __attribute__((packed)){
|
typedef struct __attribute__((packed)){
|
||||||
uint8_t magick;
|
uint8_t magick;
|
||||||
@ -119,16 +120,15 @@ static void parse_encbuf(uint8_t databuf[ENC_DATALEN], struct timeval *tv){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try to read 1 byte from encoder; return -1 if nothing to read or -2 if device seems to be disconnected
|
// try to read 1 byte from encoder; return -1 if nothing to read or -2 if device seems to be disconnected
|
||||||
static int getbyte(){
|
static int getencbyte(){
|
||||||
if(encfd < 0) return -1;
|
if(encfd < 0) return -1;
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
// default timeot = 100us, 1.5 bytes
|
struct timeval tv;
|
||||||
struct timeval tv, tvdeflt = {.tv_sec = 0, .tv_usec = 100};
|
|
||||||
do{
|
do{
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(encfd, &rfds);
|
FD_SET(encfd, &rfds);
|
||||||
tv = tvdeflt;
|
tv = encRtmout;
|
||||||
int retval = select(encfd + 1, &rfds, NULL, NULL, &tv);
|
int retval = select(encfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
if(!retval) break;
|
if(!retval) break;
|
||||||
if(retval < 0){
|
if(retval < 0){
|
||||||
@ -139,7 +139,31 @@ static int getbyte(){
|
|||||||
ssize_t l = read(encfd, &byte, 1);
|
ssize_t l = read(encfd, &byte, 1);
|
||||||
if(l != 1) return -2; // disconnected ??
|
if(l != 1) return -2; // disconnected ??
|
||||||
break;
|
break;
|
||||||
|
} else return -1;
|
||||||
|
}while(1);
|
||||||
|
return (int)byte;
|
||||||
|
}
|
||||||
|
// read 1 byte from mount; return -1 if nothing to read, -2 if disconnected
|
||||||
|
static int getmntbyte(){
|
||||||
|
if(mntfd < 0) return -1;
|
||||||
|
uint8_t byte;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
do{
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(mntfd, &rfds);
|
||||||
|
tv = mntRtmout;
|
||||||
|
int retval = select(mntfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if(!retval) break;
|
||||||
|
if(retval < 0){
|
||||||
|
if(errno == EINTR) continue;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
if(FD_ISSET(mntfd, &rfds)){
|
||||||
|
ssize_t l = read(mntfd, &byte, 1);
|
||||||
|
if(l != 1) return -2; // disconnected ??
|
||||||
|
break;
|
||||||
|
} else return -1;
|
||||||
}while(1);
|
}while(1);
|
||||||
return (int)byte;
|
return (int)byte;
|
||||||
}
|
}
|
||||||
@ -150,7 +174,7 @@ static void *encoderthread(void _U_ *u){
|
|||||||
int wridx = 0, errctr = 0;
|
int wridx = 0, errctr = 0;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
while(encfd > -1 && errctr < MAX_ERR_CTR){
|
while(encfd > -1 && errctr < MAX_ERR_CTR){
|
||||||
int b = getbyte();
|
int b = getencbyte();
|
||||||
if(b == -2) ++errctr;
|
if(b == -2) ++errctr;
|
||||||
if(b < 0) continue;
|
if(b < 0) continue;
|
||||||
errctr = 0;
|
errctr = 0;
|
||||||
@ -178,15 +202,32 @@ static void *encoderthread(void _U_ *u){
|
|||||||
// main mount thread
|
// main mount thread
|
||||||
static void *mountthread(void _U_ *u){
|
static void *mountthread(void _U_ *u){
|
||||||
int errctr = 0;
|
int errctr = 0;
|
||||||
|
SSstat status;
|
||||||
|
// data to get
|
||||||
|
data_t d = {.buf = (uint8_t*)&status, .maxlen = sizeof(SSstat)};
|
||||||
|
// cmd to send
|
||||||
|
const data_t cmd = {.buf = CMD_GETSTAT, .len = sizeof(CMD_GETSTAT)-1, .maxlen = sizeof(CMD_GETSTAT)-1};
|
||||||
while(mntfd > -1 && errctr < MAX_ERR_CTR){
|
while(mntfd > -1 && errctr < MAX_ERR_CTR){
|
||||||
;
|
// read data to status
|
||||||
pthread_mutex_lock(&mntmutex);
|
if(MountWriteRead(&cmd, &d) || d.len != sizeof(SSstat)){
|
||||||
;
|
DBG("Can't read SSstat");
|
||||||
|
++errctr; continue;
|
||||||
|
}
|
||||||
|
if(SScalcChecksum((uint8_t*)status, sizeof(SSstat)-2) != status.checksum){
|
||||||
|
DBG("BAD checksum of SSstat");
|
||||||
|
++errctr; continue;
|
||||||
|
}
|
||||||
|
errctr = 0;
|
||||||
|
pthread_mutex_lock(&datamutex);
|
||||||
|
// now change data
|
||||||
|
SSconvstat(&status, &mountdata);
|
||||||
if(!Conf.SepEncoder){ // fill encoder data from here, as there's no separate enc thread
|
if(!Conf.SepEncoder){ // fill encoder data from here, as there's no separate enc thread
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
pthread_mutex_unlock(&mntmutex);
|
pthread_mutex_unlock(&datamutex);
|
||||||
|
// allow writing & getters
|
||||||
|
usleep(Conf.MountReqInterval);
|
||||||
}
|
}
|
||||||
if(mntfd > -1){
|
if(mntfd > -1){
|
||||||
close(mntfd);
|
close(mntfd);
|
||||||
@ -196,7 +237,7 @@ static void *mountthread(void _U_ *u){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open device and return its FD or -1
|
// open device and return its FD or -1
|
||||||
static int ttyopen(const char *path, int speed){
|
static int ttyopen(const char *path, speed_t speed){
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
struct termios2 tty;
|
struct termios2 tty;
|
||||||
DBG("Try to open %s @ %d", path, speed);
|
DBG("Try to open %s @ %d", path, speed);
|
||||||
@ -222,8 +263,10 @@ static int ttyopen(const char *path, int speed){
|
|||||||
int openEncoder(const char *path, int speed){
|
int openEncoder(const char *path, int speed){
|
||||||
if(!Conf.SepEncoder) return FALSE; // try to open separate encoder when it's absent
|
if(!Conf.SepEncoder) return FALSE; // try to open separate encoder when it's absent
|
||||||
if(encfd > -1) close(encfd);
|
if(encfd > -1) close(encfd);
|
||||||
encfd = ttyopen(path, speed);
|
encfd = ttyopen(path, (speed_t) speed);
|
||||||
if(encfd < 0) return FALSE;
|
if(encfd < 0) return FALSE;
|
||||||
|
encRtmout.tv_sec = 0;
|
||||||
|
encRtmout.tv_usec = 15000000 / speed; // 1.5 bytes
|
||||||
if(pthread_create(&encthread, NULL, encoderthread, NULL)){
|
if(pthread_create(&encthread, NULL, encoderthread, NULL)){
|
||||||
close(encfd);
|
close(encfd);
|
||||||
encfd = -1;
|
encfd = -1;
|
||||||
@ -236,8 +279,10 @@ int openEncoder(const char *path, int speed){
|
|||||||
// return FALSE if failed
|
// return FALSE if failed
|
||||||
int openMount(const char *path, int speed){
|
int openMount(const char *path, int speed){
|
||||||
if(mntfd > -1) close(mntfd);
|
if(mntfd > -1) close(mntfd);
|
||||||
mntfd = ttyopen(path, speed);
|
mntfd = ttyopen(path, (speed_t) speed);
|
||||||
if(mntfd < 0) return FALSE;
|
if(mntfd < 0) return FALSE;
|
||||||
|
mntRtmout.tv_sec = 0;
|
||||||
|
mntRtmout.tv_usec = 20000000 / speed; // 2 bytes
|
||||||
if(pthread_create(&mntthread, NULL, mountthread, NULL)){
|
if(pthread_create(&mntthread, NULL, mountthread, NULL)){
|
||||||
close(mntfd);
|
close(mntfd);
|
||||||
mntfd = -1;
|
mntfd = -1;
|
||||||
@ -273,3 +318,31 @@ mcc_errcodes_t getMD(mountdata_t *d){
|
|||||||
pthread_mutex_unlock(&datamutex);
|
pthread_mutex_unlock(&datamutex);
|
||||||
return MCC_E_OK;
|
return MCC_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MountWriteRead - write and read @ once (or only read/write)
|
||||||
|
* @param out (o) - data to write or NULL if not need
|
||||||
|
* @param in (i) - data to read or NULL if not need
|
||||||
|
* @return FALSE if failed
|
||||||
|
*/
|
||||||
|
int MountWriteRead(const data_t *out, data_t *in){
|
||||||
|
if(!out && !in) return FALSE;
|
||||||
|
int ret = FALSE;
|
||||||
|
pthread_mutex_lock(&mntmutex);
|
||||||
|
if(out){
|
||||||
|
if(out->len != write(mntfd, out->buf, out->len)) goto ext;
|
||||||
|
write(mntfd, "\r", 1); // add EOL
|
||||||
|
}
|
||||||
|
if(in){
|
||||||
|
in->len = 0;
|
||||||
|
for(size_t i = 0; i < in->maxlen; ++i){
|
||||||
|
int b = getmntbyte();
|
||||||
|
if(b < 0) break; // nothing to read -> go out
|
||||||
|
in->buf[in->len++] = (uint8_t) b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = TRUE;
|
||||||
|
ext:
|
||||||
|
pthread_mutex_unlock(&mntmutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@ -34,3 +34,4 @@ int openEncoder(const char *path, int speed);
|
|||||||
int openMount(const char *path, int speed);
|
int openMount(const char *path, int speed);
|
||||||
void closeSerial();
|
void closeSerial();
|
||||||
mcc_errcodes_t getMD(mountdata_t *d);
|
mcc_errcodes_t getMD(mountdata_t *d);
|
||||||
|
int MountWriteRead(const data_t *out, data_t *in);
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
// error codes
|
// error codes
|
||||||
@ -30,11 +32,13 @@ typedef enum{
|
|||||||
} mcc_errcodes_t;
|
} mcc_errcodes_t;
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
char* MountPath; // path to mount device
|
char* MountDevPath; // path to mount device
|
||||||
int MountSpeed; // serial speed
|
int MountDevSpeed; // serial speed
|
||||||
char* EncoderPath; // path to encoder device
|
char* EncoderDevPath; // path to encoder device
|
||||||
int EncoderSpeed; // serial speed
|
int EncoderDevSpeed; // serial speed
|
||||||
int SepEncoder; // ==1 if encoder works as separate serial device
|
int SepEncoder; // ==1 if encoder works as separate serial device
|
||||||
|
suseconds_t MountReqInterval;// interval between subsequent mount requests (microseconds)
|
||||||
|
;
|
||||||
} conf_t;
|
} conf_t;
|
||||||
|
|
||||||
// coordinates in degrees: X, Y and time when they were reached
|
// coordinates in degrees: X, Y and time when they were reached
|
||||||
@ -42,9 +46,31 @@ typedef struct{
|
|||||||
double X; double Y; struct timeval msrtime;
|
double X; double Y; struct timeval msrtime;
|
||||||
} coords_t;
|
} coords_t;
|
||||||
|
|
||||||
|
// data to read/write
|
||||||
typedef struct{
|
typedef struct{
|
||||||
coords_t position;
|
uint8_t *buf; // data buffer
|
||||||
coords_t speed;
|
size_t len; // its length
|
||||||
|
size_t maxlen; // maximal buffer size
|
||||||
|
} data_t;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint8_t XBits;
|
||||||
|
uint8_t YBits;
|
||||||
|
uint8_t ExtraBits;
|
||||||
|
uint16_t ain0;
|
||||||
|
uint16_t ain1;
|
||||||
|
} extradata_t;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
coords_t motposition;
|
||||||
|
coords_t encposition;
|
||||||
|
coords_t lastmotposition;
|
||||||
|
coords_t motspeed;
|
||||||
|
uint8_t keypad;
|
||||||
|
extradata_t extradata;
|
||||||
|
uint32_t millis;
|
||||||
|
double temperature;
|
||||||
|
double voltage;
|
||||||
} mountdata_t;
|
} mountdata_t;
|
||||||
|
|
||||||
// mount class
|
// mount class
|
||||||
|
|||||||
70
LibSidServo/ssii.c
Normal file
70
LibSidServo/ssii.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libsidservo project.
|
||||||
|
* Copyright 2025 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "serial.h"
|
||||||
|
#include "ssii.h"
|
||||||
|
|
||||||
|
uint16_t SScalcChecksum(uint8_t *buf, int len){
|
||||||
|
uint16_t checksum = 0;
|
||||||
|
for(int i = 0; i < len; i++)
|
||||||
|
checksum += *buf++;
|
||||||
|
checksum ^= 0xFF00; // invert high byte
|
||||||
|
//DBG("Checksum of %d bytes: 0x%04x", len, checksum);
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send short/long binary command
|
||||||
|
static int bincmd(uint8_t *cmd, int len){
|
||||||
|
data_t d;
|
||||||
|
if(len == sizeof(SSscmd)){
|
||||||
|
((SSscmd*)cmd)->checksum = SScalcChecksum(cmd, len-2);
|
||||||
|
DBG("Short command");
|
||||||
|
d.buf = CMD_SHORTCMD;
|
||||||
|
d.len = sizeof(CMD_SHORTCMD) - 1;
|
||||||
|
if(!MountWriteRead(&d, NULL)) return -1;
|
||||||
|
}else if(len == sizeof(SSlcmd)){
|
||||||
|
((SSlcmd*)cmd)->checksum = SScalcChecksum(cmd, len-2);
|
||||||
|
DBG("Long command");
|
||||||
|
d.buf = CMD_LONGCMD;
|
||||||
|
d.len = sizeof(CMD_LONGCMD) - 1;
|
||||||
|
if(!MountWriteRead(&d, NULL)) return -1;
|
||||||
|
}else{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
DBG("Write %d bytes and wait for ans", len);
|
||||||
|
d.buf = cmd;
|
||||||
|
d.len = d.maxlen = len;
|
||||||
|
return MountWriteRead(&d, &d);
|
||||||
|
}
|
||||||
|
// return TRUE if OK
|
||||||
|
int SScmdS(SSscmd *cmd){
|
||||||
|
return bincmd(cmd, sizeof(SSscmd));
|
||||||
|
}
|
||||||
|
int SScmdL(SSlcmd *cmd){
|
||||||
|
return bincmd(cmd, sizeof(SSlcmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SSconvstat - convert stat from SSII format to human
|
||||||
|
* @param status (i) - just read data
|
||||||
|
* @param mountdata (o) - output
|
||||||
|
*/
|
||||||
|
void SSconvstat(const SSstat *status, mountdata_t *mountdata){
|
||||||
|
;
|
||||||
|
}
|
||||||
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "sidservo.h"
|
||||||
|
|
||||||
// ASCII commands
|
// ASCII commands
|
||||||
#define U8P(x) ((uint8_t*)x)
|
#define U8P(x) ((uint8_t*)x)
|
||||||
// get binary data of all statistics
|
// get binary data of all statistics
|
||||||
@ -105,3 +107,7 @@ typedef struct{
|
|||||||
uint16_t checksum; // 32
|
uint16_t checksum; // 32
|
||||||
} __attribute__((packed)) SSlcmd; // long command
|
} __attribute__((packed)) SSlcmd; // long command
|
||||||
|
|
||||||
|
int SScmdS(SSscmd *cmd);
|
||||||
|
int SScmdL(SSlcmd *cmd);
|
||||||
|
uint16_t SScalcChecksum(uint8_t *buf, int len);
|
||||||
|
void SSconvstat(const SSstat *status, mountdata_t *mountdata);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user