mirror of
https://github.com/eddyem/small_tel.git
synced 2025-12-07 11:15:11 +03:00
139 lines
4.4 KiB
C
139 lines
4.4 KiB
C
/*
|
|
* This file is part of the SSII project.
|
|
* Copyright 2022 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 <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "sidservo.h"
|
|
|
|
static TTY_descr *dev = NULL; // shoul be global to restore if die
|
|
static uint8_t buff[BUFLEN];
|
|
static int buflen = 0;
|
|
|
|
static uint16_t calcChecksum(uint8_t *buf, int len){
|
|
uint16_t checksum = 0x11; // I don't know from where does this "magick"
|
|
for(int i = 0; i < len; i++)
|
|
checksum += *buf++;
|
|
checksum ^= 0xFF00; // invert high byte
|
|
DBG("Checksum: 0x%04x", checksum);
|
|
return checksum;
|
|
}
|
|
|
|
/**
|
|
* @brief SSinit - open serial device and get initial info
|
|
* @return TRUE if all OK
|
|
*/
|
|
int SSinit(char *devpath, int speed){
|
|
LOGDBG("Try to open serial %s @%d", devpath, speed);
|
|
dev = new_tty(devpath, speed, BUFLEN);
|
|
if(dev) dev = tty_open(dev, 1); // open exclusively
|
|
if(!dev){
|
|
LOGERR("Can't open %s with speed %d. Exit.", devpath, speed);
|
|
signals(-1);
|
|
}
|
|
for(int ntries = 0; ntries < 5; ++ntries){ // try at most 5 times
|
|
if(!SSgetstat(NULL)) continue;
|
|
SSstat *s = (SSstat*) buff;
|
|
#ifdef EBUG
|
|
green("\nGet data:\n");
|
|
printf("DECmot=%d (0x%08x)\n", s->DECmot, (uint32_t)s->DECmot);
|
|
printf("DECenc=%d (0x%08x)\n", s->DECenc, (uint32_t)s->DECenc);
|
|
printf("RAmot=%d (0x%08x)\n", s->RAmot, (uint32_t)s->RAmot);
|
|
printf("RAenc=%d (0x%08x)\n", s->RAenc, (uint32_t)s->RAenc);
|
|
printf("keypad=0x%02x\n", s->keypad);
|
|
printf("XBits=0x%02x\n", s->XBits);
|
|
printf("YBits=0x%02x\n", s->YBits);
|
|
printf("EBits=0x%02x\n", s->ExtraBits);
|
|
printf("ain0=%u\n", s->ain0);
|
|
printf("ain1=%u\n", s->ain1);
|
|
printf("millis=%u\n", s->millis);
|
|
printf("tF=%d\n", s->tF);
|
|
printf("V=%f\n", ((float)s->voltage)/10.f);
|
|
printf("checksum=0x%04x\n\n", s->checksum);
|
|
#endif
|
|
if(calcChecksum(buff, sizeof(SSstat)-2) == s->checksum) return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* @brief SSclose - stop telescope and close serial device
|
|
*/
|
|
void SSclose(){
|
|
if(dev) close_tty(&dev);
|
|
}
|
|
|
|
/**
|
|
* @brief SSwrite - write & return answer
|
|
* @param buf - buffer with text or binary data
|
|
* @param buflen - its length
|
|
* @return amount of bytes read, if got answer; 0 without answer, -1 if device disconnected, -2 if can't write
|
|
*/
|
|
int SSwrite(const uint8_t *buf, int len){
|
|
DBG("try to write %d bytes", len);
|
|
if(write_tty(dev->comfd, (const char*)buf, len)){
|
|
LOGERR("Can't write data to port");
|
|
return -2;
|
|
}
|
|
write_tty(dev->comfd, "\r", 1); // add EOL
|
|
buflen = 0;
|
|
double t0 = dtime();
|
|
while(dtime() - t0 < READTIMEOUT && buflen < BUFLEN){
|
|
int r = read_tty(dev);
|
|
if(r == -1){
|
|
LOGERR("Seems like tty device disconnected");
|
|
return -1;
|
|
}
|
|
if(r == 0) continue;
|
|
int rest = BUFLEN - buflen;
|
|
if((int)dev->buflen > rest) dev->buflen = rest; // TODO: what to do with possible buffer overrun?
|
|
memcpy(&buff[buflen], dev->buf, dev->buflen);
|
|
buflen += dev->buflen;
|
|
}
|
|
DBG("got buflen=%d", buflen);
|
|
#ifdef EBUG
|
|
for(int i = 0; i < buflen; ++i){
|
|
printf("%02x (%c) ", buff[i], (buff[i] > 31) ? buff[i] : ' ');
|
|
}
|
|
printf("\n");
|
|
#endif
|
|
return buflen;
|
|
}
|
|
|
|
/**
|
|
* @brief SSread - return buff and buflen
|
|
* @param l (o) - length of data
|
|
* @return buff or NULL if buflen == 0
|
|
*/
|
|
uint8_t *SSread(int *l){
|
|
if(l) *l = buflen;
|
|
if(!buflen) return NULL;
|
|
return buff;
|
|
}
|
|
|
|
/**
|
|
* @brief SSgetstat - get struct with status & check its crc
|
|
* @param s - pointer to allocated struct (or NULL just to check)
|
|
* @return 1 if OK
|
|
*/
|
|
int SSgetstat(SSstat *s){
|
|
if(SSwrite(CMD_GETSTAT, sizeof(CMD_GETSTAT)) != sizeof(SSstat)) return FALSE;
|
|
if(s) memcpy(s, buff, sizeof(SSstat));
|
|
return TRUE;
|
|
}
|