2015-07-23 13:44:53 +03:00

414 lines
11 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <termio.h>
#include <termios.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <time.h>
#include <strings.h>
#include <string.h>
#include <linux/serial.h>
#include <signal.h>
#include "signals.h" // ÏÐÒÅÄÅÌÅÎÉÑ ÓÉÇÎÁÌÏ× Ó×ÑÚÉ
#define C_NO 224 // ÎÏÍÅÒ ËÏÎÔÒÏÌÌÅÒÁ (ÓÔÁÒÛÉÅ 3 ÂÉÔÁ)
int BAUD_RATE = B9600;
struct termio oldtty, tty; // ÆÌÁÇÉ ÄÌÑ UART
struct termios oldt, newt; // ÆÌÁÇÉ ÄÌÑ ËÏÎÓÏÌÉ
//struct serial_struct old_extra_term;
int comfd; // æÁÊÌÏ×ÙÊ ÄÅÓËÒÉÐÔÏÒ ÐÏÒÔÁ
char *comdev = "/dev/ttyS0"; // õÓÔÒÏÊÓÔ×Ï ÐÏÒÔÁ (ÐÏÔÏÍ ÐÅÒÅÄÅÌÁÔØ ÄÌÑ ÚÁÐÒÏÓÁ)
void tty_sig(unsigned char rb);
unsigned char crc(unsigned char data){
unsigned char crc = data & 1;
unsigned int i;
for(i = 1; i<8; i++) crc ^= (data >> i) & 1;
return crc;
}
void quit(int ex_stat){ // ×ÙÈÏÄ ÉÚ ÐÒÏÇÒÁÍÍÙ
tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); // ×ÏÚ×ÒÁÝÁÅÍ ËÏÎÓÏÌØ × ÎÁÞÁÌØÎÏÅ ÓÏÓÔÏÑÎÉÅ (ÎÁ ×ÓÑËÉÊ ÓÌÕÞÁÊ)
ioctl(comfd, TCSANOW, &oldtty ); // ×ÏÓÓÔÁÎÁ×ÌÉ×ÁÅÍ ÒÅÖÉÍ ÒÁÂÏÔÙ com
close(comfd); // ÚÁËÒÙ×ÁÅÍ ÓÏÅÄÉÎÅÎÉÅ
printf("÷ÙÈÏÄ... (ÓÉÇÎÁÌ %d)\n", ex_stat);
exit(ex_stat);
}
void tty_init(){
printf("\nïÔËÒÙ×ÁÀ ÐÏÒÔ...\n");
if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){
fprintf(stderr,"Can't use port %s\n",comdev);
quit(1);
}
printf(" OK\nðÏÌÕÞÁÀ ÔÅËÕÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ...\n");
ioctl(comfd,TCGETA,&oldtty); // õÚÎÁÅÍ ÔÅËÕÝÉÅ ÐÁÒÁÍÅÔÒÙ ÐÏÒÔÁ
tty = oldtty;
tty.c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG)
tty.c_iflag = BRKINT; // ÐÏÄÇÏÔÏ×ËÁ Ë 9ÂÉÔÎÏÊ ÐÅÒÅÄÁÞÅ
tty.c_oflag = 0;
tty.c_cflag = BAUD_RATE|CS8|CREAD|CLOCAL|PARENB; // 9.6Ë, 8N1, RW, ÉÇÎÏÒÉÒÏ×ÁÔØ ËÏÎÔÒ. ÌÉÎÉÉ
tty.c_cc[VMIN] = 0; // ÎÅ ËÁÎÏÎÉÞÅÓËÉÊ ÒÅÖÉÍ
tty.c_cc[VTIME] = 5; // (ÂÅÚ ÓÉÍ×ÏÌÏ× ÷ë É ÐÒ.)
if(ioctl(comfd,TCSETA,&tty)<0) exit(-1); // õÓÔÁÎÁ×ÌÉ×ÁÅÍ ÔÅËÕÝÉÅ ÐÁÒÁÍÅÔÒÙ ÐÏÒÔÁ
printf(" OK\n");
}
unsigned char read_tty(unsigned char *byte){
*byte = 0;
fd_set rfds; // ÎÁÂÏÒ ÆÁÊÌÏ×ÙÈ ÄÅÓËÒÉÐÔÏÒÏ×
struct timeval tv; // ×ÒÅÍÑ ÏÖÉÄÁÎÉÑ
int retval; // ×ÏÚ×ÒÁÝÁÅÍÏÅ Æ-Ê select ÚÎÁÞÅÎÉÅ
tty.c_iflag &= ~PARODD;
ioctl(comfd,TCSETA,&tty);
// öÄÅÍ, ÓÉÇÎÁÌÁ Ó ÐÏÒÔÁ
FD_ZERO(&rfds); // ÏÞÉÝÁÅÍ ÎÁÂÏÒ
FD_SET(comfd, &rfds); // ÔÅÐÅÒØ ÜÔÏ - Ó×ÏÊÓÔ×Á ÐÏÒÔÁ
tv.tv_sec = 0; tv.tv_usec = 50000; // ÖÄÅÍ
retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
if (!retval) return 0; // ÅÓÌÉ ÓÉÇÎÁÌÁ ÎÅÔ, ×ÏÚ×ÒÁÝÁÅÍ ÎÏÌØ
if(FD_ISSET(comfd, &rfds)){
// printf("ready ");
if(read(comfd, byte, 1) < 1) return 0; // ÏÛÉÂËÁ ÓÞÉÔÙ×ÁÎÉÑ
}
else return 0; // ÏÛÉÂËÁ
/* if(*byte == 8){
return 0;
}
else*/
// printf("ÓÞÉÔÁÎ: %d (ËÏÍÁÎÄÁ %d)\n", *byte, *byte & 0x1f);
return 1;
}
unsigned char read_console(){ // ÓÞÉÔÙ×ÁÅÍ ÄÁÎÎÙÅ Ó ËÏÎÓÏÌÉ
unsigned char rb;
struct timeval tv;
int retval;
tcgetattr( STDIN_FILENO, &oldt ); // ÏÔËÒÙ×ÁÅÍ ÔÅÒÍÉÎÁÌ ÄÌÑ ÒÅÁËÃÉÉ ÎÁ ËÌÁ×ÉÛÉ ÂÅÚ ÜÈÁ
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds); // 0 - ÓÔÁÎÄÁÒÔÎÙÊ ×ÈÏÄ
tv.tv_sec = 0; tv.tv_usec = 10000; // ÖÄÅÍ 0.01Ó
retval = select(1, &rfds, NULL, NULL, &tv);
if (!retval) rb = 0;
else {
if(FD_ISSET(STDIN_FILENO, &rfds)) rb = getchar();
else rb = 0;
}
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
return rb;
}
unsigned char mygetchar(){ // ÁÎÁÌÏÇ getchar() ÂÅÚ ÎÅÏÂÈÏÄÉÍÏÓÔÉ ÖÁÔØ Enter
unsigned char ret;
do ret = read_console();
while(ret == 0);
return ret;
}
void write_tty_raw(unsigned char wb){
if(crc(wb)) // ÎÅÞÅÔÎÁÑ ÓÕÍÍÁ
tty.c_cflag |=PARODD; // 9-Ê ÂÉÔ = 0
else
tty.c_cflag &= ~PARODD; // = 1
ioctl(comfd,TCSETA,&tty); // ÐÅÒÅÎÁÓÔÒÁÉ×ÁÅÍ ÐÏÒÔ
if(write(comfd, &wb, 1) < 0) fprintf(stderr, "ïÛÉÂËÁ! úÁÐÉÓØ ÎÅ ÕÄÁÌÁÓØ :(\n"); // É ÐÉÛÅÍ × ÎÅÇÏ ÂÁÊÔ
}
void write_tty(unsigned char wb){
unsigned char tmp = wb;
tmp &= 0x1f; // ÎÁ ×ÓÑËÉÊ ÓÌÕÞÁÊ ÏÞÉÝÁÅÍ ÏÔ ÍÕÓÏÒÁ
tmp |= C_NO; // ÄÏÂÁ×ÌÑÅÍ Ë ËÏÍÁÎÄÅ
write_tty_raw(tmp);
}
int send_cmd(unsigned char cmd){ // ÐÏÓÙÌËÁ ËÏÎÔÒÏÌÌÅÒÕ ËÏÍÁÎÄÙ Ó ËÏÎÔÒÏÌÅÍ
unsigned char rtn=ERR_CMD, byte=0, i=0;
while(i<2 && rtn != 1){
write_tty(cmd);
usleep(100000);
rtn = read_tty(&byte);
byte &= 0x1f;
i++;
}
if(byte != cmd){
printf("\n\n!!!!!! ïÛÉÂËÁ! ëÏÎÔÒÏÌÌÅÒ ÎÅ ÏÔ×ÅÞÁÅÔ (ÏÔ×ÅÔ %d ÎÁ ËÏÍÁÎÄÕ %d) !!!!!\n\n", byte, cmd);
return 0;
}
else return 1;
}
void sendword(unsigned int data){
unsigned char tmp,i=0,rr=0, ret;
tmp = (data >> 8) & 0xFF;
if(crc(tmp)) // ÎÅÞÅÔÎÁÑ ÓÕÍÍÁ
tty.c_cflag &= ~PARODD; // 9-Ê ÂÉÔ = 0
else
tty.c_cflag |= PARODD; // = 1
ioctl(comfd,TCSETA,&tty); // ÐÅÒÅÎÁÓÔÒÁÉ×ÁÅÍ ÐÏÒÔ
write(comfd, &tmp, 1);
do{ i++;
usleep(10000);
ret = read_tty(&rr); rr &= 0x1F;
}while((ret == 0 || rr != OK) && i < 10 );
if(rr != OK){ fprintf(stderr, "ïÛÉÂËÁ ÚÁÐÉÓÉ"); return;}
i = 0;
tmp = data & 0xFF;
if(crc(tmp)) // ÎÅÞÅÔÎÁÑ ÓÕÍÍÁ
tty.c_cflag &= ~PARODD; // 9-Ê ÂÉÔ = 0
else
tty.c_cflag |= PARODD; // = 1
ioctl(comfd,TCSETA,&tty); // ÐÅÒÅÎÁÓÔÒÁÉ×ÁÅÍ ÐÏÒÔ
write(comfd, &tmp, 1);
do{ i++;
usleep(10000);
ret = read_tty(&rr); rr &= 0x1F;
}while((ret == 0 || rr != OK) && i < 10 );
if(rr != OK){fprintf(stderr, "îÅÕÄÁÞÁ"); return;}
}
void send_rand(){
int i, j = 0; unsigned char byte, rb;
srand(time(NULL));
for(i=0; i<128; i++)
if(send_cmd(SPI_send_one)){
write_tty_raw(25);
printf("%d: ÐÅÒÅÄÁÎ ÂÁÊÔ \e[1;32;40m18\e[0m\n",i);
if(read_tty(&byte))
tty_sig(byte);
rb = read_console();
if(rb == 'q') break;
//byte = (rand()|rand()) & 0xff;
byte = j++;
if(send_cmd(SPI_send_one)){
write_tty_raw(byte);
printf("%d: ÐÅÒÅÄÁÎ ÂÁÊÔ \e[1;32;40m%d\e[0m\n", i, byte);
if(read_tty(&byte))
tty_sig(byte);
rb = read_console();
if(rb == 'q') break;
}
if(send_cmd(SPI_send_one)){
write_tty_raw(0);
printf("%d: ÐÅÒÅÄÁÎ ÂÁÊÔ \e[1;32;40m0\e[0m\n", i);
if(read_tty(&byte))
tty_sig(byte);
rb = read_console();
if(rb == 'q') break;
}
}
}
void send_nseq(){
int i, j; unsigned char byte, rb;
for(i=0; i<256; i++)
if(send_cmd(SPI_send_one)){
byte = (unsigned char)i;
write_tty_raw(byte);
printf("%d: ÐÅÒÅÄÁÎ ÂÁÊÔ \e[1;32;40m%d\e[0m\n", i, byte);
if(read_tty(&byte))
tty_sig(byte);
rb = read_console();
if(rb == 'q') return;
for(j=0; j<5; j++)
if(send_cmd(SPI_send_one)){
write_tty_raw(0);
printf("%d: ÐÅÒÅÄÁÎ ÂÁÊÔ \e[1;32;40m0\e[0m\n", i);
if(read_tty(&byte))
tty_sig(byte);
rb = read_console();
if(rb == 'q') return;
}
}
}
void send_seq(){
unsigned char seq[1024], byte;
char *line;
int cntr = 0, n, sz = 9;
line = (char*) malloc(10);
printf("\n÷×ÏÄÉÔÅ ÞÉÓÌÁ ÐÏ ÏÄÎÏÍÕ × ÓÔÒÏËÅ, ÏËÏÎÞÁÎÉÅ - ÓÌÏ×Ï end\n");
do{
n = getline(&line, &sz, stdin);
if(n == 0 || strstr(line, "end") != NULL) break;
seq[cntr++] = (unsigned char)atoi(line);
}while(cntr < 1024);
printf("\nîÁÞÉÎÁÀ ÐÅÒÅÄÁÞÕ\n");
for(n=0; n<cntr; n++){
if(send_cmd(SPI_send_one)){
write_tty_raw(seq[n]);
printf("ðÅÒÅÄÁÎ ÂÁÊÔ \e[1;32;40m%d\e[0m\n", seq[n]);
if(read_tty(&byte))
tty_sig(byte);
}
}
free(line);
printf("\nðÅÒÅÄÁÞÁ ÏËÏÎÞÅÎÁ\n");
}
void send_same(){
int i; unsigned char cmd, byte, rb;
printf("\n÷×ÅÄÉÔÅ ËÏÍÁÎÄÕ: ");
scanf("%d", &i);
cmd = i;
for(i=0; i<1024; i++)
if(send_cmd(SPI_send_one)){
byte = (i%16) ? 0:cmd;
write_tty_raw(byte);
printf("%d: ÐÅÒÅÄÁÎ ÂÁÊÔ \e[1;32;40m%d\e[0m\n", i, byte);
if(read_tty(&rb))
tty_sig(rb);
rb = read_console();
if(rb == 'q') break;
}
}
void tmrset(){
unsigned char t_h,t_l;
float period;
if(send_cmd(TMR_SETTINGS) == 0) return;
usleep(10000);
read(comfd, &t_h, 1);
usleep(10000);
read(comfd, &t_l, 1);
period = (65536.0 - 256.0*(float)t_h - (float)t_l)/125000.0;
printf("ðÅÒÉÏÄ ÔÁÊÍÅÒÁ: T=%f", period);
}
void help(){
printf("\nh\tðÏÍÏÝØ\n"
"t\tõÚÎÁÔØ ÔÅËÕÝÉÊ ÐÅÒÉÏÄ ÔÁÊÍÅÒÁ\n"
"T\tóÍÅÎÉÔØ ÐÅÒÉÏÄ ÔÁÊÍÅÒÁ\n"
"s\tïÔÏÓÌÁÔØ ××ÅÄÅÎÎÕÀ Ó ËÌÁ×ÉÁÔÕÒÙ ËÏÍÁÎÄÕ ÐÏ SPI\n"
"i\t(òÅ)ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ËÏÎÔÒÏÌÌÅÒ\n"
"m\täÁÎÎÙÅ ÓÞÉÔÙ×ÁÀÔÓÑ × ÓÅÒÅÄÉÎÅ ÔÁËÔÁ\n"
"e\täÁÎÎÙÅ ÓÞÉÔÙ×ÁÀÔÓÑ × ËÏÎÃÅ ÔÁËÔÁ\n"
"R\tïÔÓÙÌÁÔØ ÓÌÕÞÁÊÎÙÅ ÞÉÓÌÁ (1024 ÛÔÕËÉ)\n"
"L\tóËÏÒÏÓÔØ 9600\n"
"M\tóËÏÒÏÓÔØ 19200\n"
"1..3\tõÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÉÚÍÅÎÅÎÉÑ F\n"
"f\tðÅÒÅÍÅÓÔÉÔØÓÑ × ÓÔÏÒÏÎÕ ÂÅÓËÏÎÅÞÎÏÓÔÉ\n"
"b\tðÅÒÅÍÅÓÔÉÔØÓÑ × ÓÔÏÒÏÎÕ ÎÕÌÑ\n"
"0\tðÅÒÅÍÅÓÔÉÔØÓÑ × ÎÁÞÁÌÏ\n"
"9\tðÅÒÅÍÅÓÔÉÔØÓÑ × ÂÅÓËÏÎÅÞÎÏÓÔØ\n"
"H\t÷ËÌÀÞÉÔØ ÒÕÞÎÏÅ ÕÐÒÁ×ÌÅÎÉÅ\n"
"p\tïÓÔÁÎÏ×ÉÔØ ÔÁÊÍÅÒ\n"
"P\túÁÐÕÓÔÉÔØ ÔÁÊÍÅÒ\n"
"y\tïÔËÌÀÞÉÔØ SPI\n"
"Y\t÷ËÌÀÞÉÔØ SPI\n"
"R\tðÏÓÙÌÁÔØ ÓÌÕÞÁÊÎÙÅ ÞÉÓÌÁ\n"
"F\tæÏËÕÓÎÏÅ ÒÁÓÓÔÏÑÎÉÅ\n"
"S\tïÔÏÓÌÁÔØ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÂÁÊÔ (ÎÅ ÂÏÌÅÅ 1024, ÚÁ×ÅÒÛÅÎÉÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÉ - end)\n"
"w\tïÔÓÙÌÁÔØ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÏÄÉÎÁËÏ×ÙÈ ××ÅÄÅÎÎÙÈ ËÏÍÁÎÄ\n"
"W\tïÔÓÙÌÁÔØ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ 0..255 Ó ÐÒÏÍÅÖÕÔÏÞÎÙÍÉ 5 ÎÕÌÑÍÉ\n"
"\n");
}
void set_speed(int spd){
//B115200 ÉÌÉ B9600
BAUD_RATE = spd;
ioctl(comfd, TCSANOW, &oldtty ); // ×ÏÓÓÔÁÎÁ×ÌÉ×ÁÅÍ ÒÅÖÉÍ ÒÁÂÏÔÙ com
close(comfd); // ÚÁËÒÙ×ÁÅÍ ÓÏÅÄÉÎÅÎÉÅ
tty_init();
}
void con_sig(unsigned char rb){ // ÏÂÒÁÂÏÔËÁ ÓÉÇÎÁÌÏ× Ó ËÏÎÓÏÌÉ
unsigned int tmp; unsigned char cmd;
if(rb == 'q') quit(0); // ×ÙÈÏÄÉÍ ÐÏ ÎÁÖÁÔÉÀ q
switch(rb){
case 'h': help(); break;
case 't': tmrset(); break;
case 'T': printf("\nðÅÒÉÏÄ × ÍËÓ:\n"); scanf("%u", &tmp);
if(send_cmd(SET_TIMER)) sendword(65536 - tmp/8); break;
case 'i': send_cmd(INIT); break;
case 's': printf("\näÁÎÎÙÅ:\n"); scanf("%d", &cmd);
if(send_cmd(SPI_send_one)) write_tty_raw(cmd);; break;
case 'm': send_cmd(MID_DATA); break;
case 'e': send_cmd(END_DATA); break;
case 'L': send_cmd(LOW_SPD); set_speed(B9600); break;
case 'M': send_cmd(MID_SPD); set_speed(B19200); break;
case '1': send_cmd(SPEED1); break;
case '2': send_cmd(SPEED2); break;
case '3': send_cmd(SPEED3); break;
case 'f': send_cmd(FORW); break;
case 'b': send_cmd(BACK); break;
case '0': send_cmd(ZERO); break;
case '9': send_cmd(INFTY); break;
case 'H': send_cmd(HANDS); break;
case 'p': send_cmd(TMR_OFF); break;
case 'P': send_cmd(TMR_ON); break;
case 'y': send_cmd(SPI_OFF); break;
case 'Y': send_cmd(SPI_ON); break;
case 'R': send_rand(); break;
case 'F': send_cmd(FOCUS); break;
case 'S': send_seq(); break;
case 'w': send_same(); break;
case 'W': send_nseq(); break;
}
}
void dec2bin(unsigned char ii, char* bin){
int i;
for(i=0; i<8; i++){
bin[7-i] = (ii & 1) ? '1' : '0';
ii>>=1;
}
bin[8]=0;
}
void tty_sig(unsigned char rb){ // ÏÂÒÁÂÏÔËÁ ÓÉÇÎÁÌÏ× Ó ËÏÎÔÒÏÌÌÅÒÁ
char bin[9];
dec2bin(rb, bin);
switch(rb){
case ERR_CMD: printf("ïÛÉÂËÁ (\e[1;31;40m%d\e[0m?)\n", ERR_CMD); break;
case OK: printf("OK (\e[1;31;40m%d\e[0m?)\n", OK); break;
default: printf("\e[1;31;40m%d\e[0m\t(%s)\n", rb, bin);
}
}
int main(int argc, char *argv[]){
unsigned char rb, byte, i = 0; // ÓÞÉÔÁÎÎÙÅ ÄÁÎÎÙÅ, ÓÞÅÔÞÉË
tty_init();
rb = ERR_CMD;
signal(SIGTERM, quit); // kill (-15)
signal(SIGINT, quit); // ctrl+C
signal(SIGQUIT, SIG_IGN); // ctrl+\ .
signal(SIGTSTP, SIG_IGN); // ctrl+Z
setbuf(stdout, NULL);
printf("\néÎÉÃÉÁÌÉÚÁÃÉÑ...\n");
do{
write_tty(INIT); // éÎÉÃÉÁÌÉÚÁÃÉÑ ËÏÎÔÒÏÌÌÅÒÁ
rb = read_tty(&byte);
usleep(100000);
i ++;
}
while(i<3 && rb != 1); // ÐÒÏ×ÅÒËÁ Ó×ÑÚÉ
if(i > 2 || (byte&0x1f) != INIT){
fprintf(stderr,"\n!!!!!! ïÛÉÂËÁ: ËÏÎÔÒÏÌÌÅÒ ÎÅ ÏÔ×ÅÞÁÅÔ (%d) !!!!!!\n", byte);
}
else printf(" OK\n");
while(1){ // ÂÅÓËÏÎÅÞÎÏ ÚÁÃÉËÌÉ×ÁÅÍÓÑ
rb = read_console();
if(rb != 0) con_sig(rb); // ÅÓÌÉ ÞÔÏ-ÔÏ ÐÏÑ×ÉÌÏÓØ - ÏÂÒÁÂÁÔÙ×ÁÅÍ
rb = read_tty(&byte);
if(rb != 0) tty_sig(byte); // ÅÓÌÉ ÅÓÔØ ÓÉÇÎÁÌ Ó ËÏÎÔÒÏÌÌÅÒÁ - ÏÂÒÁÂÁÔÙ×ÁÅÍ
}
}