init on github

This commit is contained in:
eddyem 2015-07-23 13:44:53 +03:00
parent 506e00e282
commit 6443a7dbf4
18 changed files with 2696 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
*~
*.bak
*.bck
*.o
.hg*
.dropbox.attr

389
02-TEST/Frontend/FE.c Normal file
View File

@ -0,0 +1,389 @@
#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) err("ïÛÉÂËÁ! úÁÐÉÓØ ÎÅ ÕÄÁÌÁÓØ :(\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){ err("ïÛÉÂËÁ ÚÁÐÉÓÉ"); 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){err("îÅÕÄÁÞÁ"); 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_rand(){
int i; unsigned char byte, rb;
srand(time(NULL));
for(i=0; i<1024; i++)
if(send_cmd(SPI_send_one)){
byte = (rand()|rand()) & 0xff;
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;
}
}
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 ssend(){
unsigned char cmds[] = {31,0,0,79,0,0,0,95,0,0,224,0,0}, rb;
int i, s=sizeof(cmds);
while(1){
printf("\n");
for(i=0; i<s; i++){
if(send_cmd(SPI_send_one)){
printf("þÉÓÌÏ %d\n", cmds[i]);
write_tty_raw(cmds[i]);
}
if(read_tty(&rb))
tty_sig(rb);
rb = read_console();
if(rb == 'q') return;
}
}
}
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"
"S\tïÔÏÓÌÁÔØ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÂÁÊÔ (ÎÅ ÂÏÌÅÅ 1024, ÚÁ×ÅÒÛÅÎÉÅ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÉ - end)\n"
"R\tïÔÓÙÌÁÔØ ÓÌÕÞÁÊÎÙÅ ÞÉÓÌÁ (1024 ÛÔÕËÉ)\n"
"w\tïÔÓÙÌÁÔØ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÏÄÉÎÁËÏ×ÙÈ ××ÅÄÅÎÎÙÈ ËÏÍÁÎÄ\n"
"d\tóÞÉÔÁÔØ ÂÕÆÅÒ SPI\n"
"i\t(òÅ)ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ËÏÎÔÒÏÌÌÅÒ\n"
"r\tðÒÅÒÙ×ÁÎÉÅ sync ÐÏ ×ÏÚÒÁÓÔÁÀÝÅÍÕ ÕÒÏ×ÎÀ\n"
"f\tðÒÅÒÙ×ÁÎÉÅ sync ÐÏ ÓÐÁÄÁÀÝÅÍÕ ÆÒÏÎÔÕ\n"
"m\täÁÎÎÙÅ ÓÞÉÔÙ×ÁÀÔÓÑ × ÓÅÒÅÄÉÎÅ ÔÁËÔÁ\n"
"e\täÁÎÎÙÅ ÓÞÉÔÙ×ÁÀÔÓÑ × ËÏÎÃÅ ÔÁËÔÁ\n"
"0\t÷ÙËÌÀÞÉÔØ SPI\n"
"1\t÷ËÌÀÞÉÔØ SPI\n"
"a\tSPI × ÁËÔÉ×ÎÏÍ ÒÅÖÉÍÅ\n"
"p\tSPI × ÐÁÓÓÉ×ÎÏÍ ÒÅÖÉÍÅ\n"
"L\tóËÏÒÏÓÔØ 9600\n"
"H\tóËÏÒÏÓÔØ 115200\n"
"M\tóËÏÒÏÓÔØ 19200\n"
"2\t÷ÙËÌÀÞÉÔØ TEST\n"
"F\tðÏÐÙÔÁÔØÓÑ ÐÏÊÍÁÔØ ÆÏËÕÓ\n"
"\n");
}
void set_speed(int spd){
//B115200 ÉÌÉ B9600
BAUD_RATE = spd;
ioctl(comfd, TCSANOW, &oldtty ); // ×ÏÓÓÔÁÎÁ×ÌÉ×ÁÅÍ ÒÅÖÉÍ ÒÁÂÏÔÙ com
close(comfd); // ÚÁËÒÙ×ÁÅÍ ÓÏÅÄÉÎÅÎÉÅ
tty_init();
}
void spi_show(){
unsigned char cntr;
send_cmd(SPI_SHOW);
while(!read_tty(&cntr));
printf("\n÷ ÂÕÆÅÒÅ %d ÄÁÎÎÙÈ\n", cntr);
}
void con_sig(unsigned char rb){ // ÏÂÒÁÂÏÔËÁ ÓÉÇÎÁÌÏ× Ó ËÏÎÓÏÌÉ
unsigned int tmp;
if(rb == 'q') quit(0); // ×ÙÈÏÄÉÍ ÐÏ ÎÁÖÁÔÉÀ q
switch(rb){
case 'h': help(); break;
case 't': tmrset(); break;
case 'T': printf("\nðÅÒÉÏÄ × ÍËÓ:\n"); scanf("%d", &tmp);
if(send_cmd(SET_TIMER)) sendword(65536 - tmp/8); break;
case 'i': send_cmd(INIT); break;
case 's': printf("\näÁÎÎÙÅ:\n"); scanf("%d", &tmp);
if(send_cmd(SPI_send)) sendword(tmp); break;
case 'S': send_seq(); break;
case 'R': send_rand(); break;
case 'w': send_same(); break;
case 'r': send_cmd(IMP_RISE); break;
case 'f': send_cmd(IMP_FALL); break;
case 'm': send_cmd(MID_DATA); break;
case 'e': send_cmd(END_DATA); break;
case '0': send_cmd(SPI_OFF); break;
case '1': send_cmd(SPI_ON); break;
case 'a': send_cmd(SPI_ACTIVE); break;
case 'p': send_cmd(SPI_PASSIVE); break;
case 'L': set_speed(B9600); break;
case 'H': send_cmd(HIG_SPD); set_speed(B115200); break;
case 'M': send_cmd(MID_SPD); set_speed(B19200); break;
case '2': send_cmd(TEST); break;
case 'd': spi_show(); break;
case 'F': ssend(); 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); // ÅÓÌÉ ÅÓÔØ ÓÉÇÎÁÌ Ó ËÏÎÔÒÏÌÌÅÒÁ - ÏÂÒÁÂÁÔÙ×ÁÅÍ
}
}

275
02-TEST/Frontend/main.c Normal file
View File

@ -0,0 +1,275 @@
#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 "signals.h" // ÏÐÒÅÄÅÌÅÎÉÑ ÓÉÇÎÁÌÏ× Ó×ÑÚÉ
#include "func.h" // ÆÕÎËÃÉÉ ÏÂÒÁÂÏÔËÉ ÓÉÇÎÁÌÏ×, ÇÌÏÂÁÌØÎÙÅ ÐÅÒÅÍÅÎÎÙÅ
#include "keys.h" // ËÌÁ×ÉÛÎÙÅ ËÏÍÁÎÄÙ
#include "killbrothers.h"
#include "queues.h"
#define CMSPAR 010000000000
extern int get_auth_level();
FILE* outfile;
double tm0, tm; // ×ÒÅÍÑ × ÓÅËÕÎÄÁÈ
struct termio oldtty, tty; // ÆÌÁÇÉ ÄÌÑ UART
int comfd = -1; // æÁÊÌÏ×ÙÊ ÄÅÓËÒÉÐÔÏÒ ÐÏÒÔÁ
static char *comdev = "/dev/ttyS1"; // õÓÔÒÏÊÓÔ×Ï ÐÏÒÔÁ (ÐÏÔÏÍ ÐÅÒÅÄÅÌÁÔØ ÄÌÑ ÚÁÐÒÏÓÁ)
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;
}
double dtime(){
struct timeval tv;
struct timezone tz;
int ret;
double t;
ret = gettimeofday(&tv, &tz);
t = (double)tv.tv_sec + (double)tv.tv_usec*0.000001;
t -= timezone;
return(t);
}
void quit(int ex_stat){ // ×ÙÈÏÄ ÉÚ ÐÒÏÇÒÁÍÍÙ
unsigned char i;
err("ïÔËÌÀÞÁÀÓØ...");
if(comfd > 0){
for(i=0; i<8; i++)
stop_motor(i<<5, "0"); // ÏÓÔÁÎÁ×ÌÉ×ÁÅÍ Ä×ÉÇÁÔÅÌØ
ioctl(comfd, TCSETA, &oldtty); // ×ÏÓÓÔÁÎÁ×ÌÉ×ÁÅÍ ÒÅÖÉÍ ÒÁÂÏÔÙ com
close(comfd); // ÚÁËÒÙ×ÁÅÍ ÓÏÅÄÉÎÅÎÉÅ
}
rm_queues();
exit(ex_stat);
}
void tty_init(){
if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0)
die("Can't use port %s\n",comdev);
ioctl(comfd,TCGETA,&oldtty); // õÚÎÁÅÍ ÔÅËÕÝÉÅ ÐÁÒÁÍÅÔÒÙ ÐÏÒÔÁ
tty = oldtty;
tty.c_lflag = 0;
tty.c_iflag = BRKINT;//|PARENB|CMSPAR;
tty.c_oflag = 0;
tty.c_cflag = B9600|CS8|CREAD|CLOCAL|PARENB;//|CMSPAR;
tty.c_cflag &= ~PARODD;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 1;
ioctl(comfd,TCSETA,&tty);
}
unsigned char read_tty(){ // ÓÞÉÔÙ×ÁÅÍ 1 ÂÁÊÔ (Ó ÏÖÉÄÁÎÉÅÍ ÓÉÇÎÁÌÁ)
unsigned char rb; // ÔÏ, ÞÔÏ ÓÞÉÔÙ×ÁÅÍ
tty.c_iflag &= ~PARODD; // ÐÒÉÎÉÍÁÅÍ Ó ÄÅ×ÑÔÙÍ ÂÉÔÏÍ = 0
ioctl(comfd,TCSETA,&tty);
if(read(comfd, &rb, 1) < 1) return 0; // ÏÛÉÂËÁ ÓÞÉÔÙ×ÁÎÉÑ
tm = dtime() - tm0;
tm0 = dtime();
fprintf(stderr,"ÓÞÉÔÁÎ ÓÉÇÎÁÌ: %d Ó ËÏÎÔÒÏÌÌÅÒÁ %d, ×ÒÅÍÑ ÏÔ ÐÒÅÄÙÄÕÝÅÇÏ ÓÞÉÔÙ×ÁÎÉÑ: %f Ó\n", rb&0x1F, rb&0xE0, tm);
return rb;
}
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) err("ïÛÉÂËÁ! úÁÐÉÓØ ÎÅ ÕÄÁÌÁÓØ :(\n"); // É ÐÉÛÅÍ × ÎÅÇÏ ÂÁÊÔ
}
void write_tty(unsigned char wb, unsigned char cno){
unsigned char tmp = wb;
tmp &= 0x1f; // ÎÁ ×ÓÑËÉÊ ÓÌÕÞÁÊ ÏÞÉÝÁÅÍ ÏÔ ÍÕÓÏÒÁ
tmp |= cno; // ÄÏÂÁ×ÌÑÅÍ Ë ËÏÍÁÎÄÅ
write_tty_raw(tmp);
}
int send_cmd(unsigned char cmd, unsigned char flag, unsigned char cno){ // ÐÏÓÙÌËÁ ËÏÎÔÒÏÌÌÅÒÕ ËÏÍÁÎÄÙ Ó ËÏÎÔÒÏÌÅÍ
// flag = 1 - ËÏÍÁÎÄÁ ÏÔÓÙÌÁÅÔÓÑ ÔÅËÕÝÅÍÕ ËÏÎÔÒÏÌÌÅÒÕ, 0 - ÐÏ ÚÁÐÒÏÓÕ
int ret = -1;
unsigned char rtn=0, i=0, cmd1;
cmd1 = (flag)? ((cmd&0x1F)|cno) : cmd;
while(i<10 && rtn != cmd1){ // 10 ÐÏÐÙÔÏË
usleep(1000);
if(flag) write_tty(cmd, cno);
else write_tty_raw(cmd);
usleep(100000);
rtn = read_tty();
i++;
}
if(rtn != cmd1)
err("!!!!!! ïÛÉÂËÁ! ëÏÎÔÒÏÌÌÅÒ ÎÅ ÏÔ×ÅÞÁÅÔ !!!!!");
else ret = (i<2)?1:0;
return ret;
}
void sendword(unsigned int data){
unsigned char tmp,i=0,rr=0;
tmp = (data >> 8) & 0xFF;
if(crc(tmp)) // ÎÅÞÅÔÎÁÑ ÓÕÍÍÁ
tty.c_cflag &= ~PARODD; // 9-Ê ÂÉÔ = 0
else
tty.c_cflag |= PARODD; // = 1
ioctl(comfd,TCSETA,&tty); // ÐÅÒÅÎÁÓÔÒÁÉ×ÁÅÍ ÐÏÒÔ
do{ i++;
if(write(comfd, &tmp, 1) < 0){continue;}
usleep(10000);
rr = read_tty() & 0x1F;
}while(rr != OK && i < 10);
if(rr != OK){ err("ïÛÉÂËÁ ÚÁÐÉÓÉ"); 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); // ÐÅÒÅÎÁÓÔÒÁÉ×ÁÅÍ ÐÏÒÔ
do{ i++;
if(write(comfd, &tmp, 1) < 0){continue;}
usleep(10000);
rr = read_tty() & 0x1F;
}while(rr != OK && i < 10);
if(rr != OK){err("îÅÕÄÁÞÁ"); return;}
}
/*
int getl(int fd, char* data, int N){
int rb = 0, i=0;
char *ptr = data;
do{
if((rb = read(fd, ptr, 1)) != 1) break;
if(*ptr == '\0' || *ptr == '\n') break;
ptr++;
}while(++i < N);
if(rb != 1 && i == 0) return (-1);
*ptr = '\0';
return i;
}*/
void tmrset(unsigned char cno){
unsigned char t_h,t_l;
float period;
if(send_cmd(TMR_SETTINGS, 1, cno)<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;
warn("ðÅÒÉÏÄ ÔÁÊÍÅÒÁ: T=%f", period);
}
void init_ctrlr(unsigned char cno){
unsigned char rb = ERR_CMD;
unsigned char ini = INIT | cno;
int i=0;
warn("éÎÉÃÉÁÌÉÚÁÃÉÑ...");
do{
write_tty(INIT, cno); // éÎÉÃÉÁÌÉÚÁÃÉÑ ËÏÎÔÒÏÌÌÅÒÁ
rb = read_tty();
usleep(100000);
i++;
}
while(i<10 && rb != ini); // ÐÒÏ×ÅÒËÁ Ó×ÑÚÉ
if(i > 9 || rb != ini){
err("!!!!!! ïÛÉÂËÁ: ËÏÎÔÒÏÌÌÅÒ ÎÅ ÏÔ×ÅÞÁÅÔ !!!!!!");
}
else{
warn("... ÕÓÐÅÛÎÏ.");
}
}
void con_sig(unsigned char cno, unsigned char rb, char *val){ // ÏÂÒÁÂÏÔËÁ ÓÉÇÎÁÌÏ× Ó ËÏÎÓÏÌÉ
//fprintf(stderr, "key: %c, cno: %d, val:%s\n", rb, cno, val);
switch(rb){
case KEY_QUIT: quit(0); break;
case KEY_DEVICE: set_dev(cno, val); break;
case KEY_LEFT: rotate_left(cno, val); break;
case KEY_RIGHT: rotate_right(cno, val); break;
case KEY_NR: steps_(cno,RIGHT, val); break;
case KEY_NL: steps_(cno,LEFT, val); break;
case KEY_STOP: stop_motor(cno, val); break;
case KEY_VOLTAGE: set_voltage(cno, val); break;
case KEY_TMR: set_timer(cno, val); break;
case KEY_TMR_STOP: send_cmd(STOP_TIMER, 1, cno); break;
case KEY_TMR_STNGS: tmrset(cno); break;
case KEY_INIT: init_ctrlr(cno); break;
case KEY_Xplus: corrector(cno,0, val); break;
case KEY_Xminus: corrector(cno,1, val); break;
case KEY_Yplus: corrector(cno,2, val); break;
case KEY_Yminus: corrector(cno,3, val); break;
case KEY_MIDDLE: goto_middle(cno); break;
case KEY_TEST: send_cmd(TEST,1, cno); break;
/* default: send_cmd(rb, 0); // ÓÐÅÃ. ËÏÍÁÎÄÁ (ÄÌÑ ×ÙÄÅÌÅÎÎÙÈ ËÏÎÔÒÏÌÌÅÒÏ×)
data = read_int();
if(data != -1) sendword(data); */
}
}
void tty_sig(unsigned char rb){ // ÏÂÒÁÂÏÔËÁ ÓÉÇÎÁÌÏ× Ó ËÏÎÔÒÏÌÌÅÒÁ
unsigned char cno = rb & 0xE0;
rb &= 0x1F;
switch(rb){
case TERMINAL_: terminals(cno); break; // ÏÂÒÁÂÏÔËÁ ËÏÎÃÅ×ÉËÏ×
case STACK_OVERFLOW: error(STACK_OVERFLOW, cno); break; // ÐÅÒÅÐÏÌÎÅÎÉÅ ÓÔÅËÁ RX ËÏÎÔÒÏÌÌÅÒÁ
case NO_STOP_BIT: error(NO_STOP_BIT, cno); break;
}
}
int main(int argc, char *argv[]){
unsigned char rb, key;// ÓÞÉÔÁÎÎÙÅ ÄÁÎÎÙÅ, ÓÞÅÔÞÉË
char *val;
setbuf(stdout, NULL);
printf("Content-type: multipart/form-data; charset=koi8-r\n\n");
if(!killbrothers()) die("îÅ ÍÏÇÕ ÇÁÒÁÎÔÉÒÏ×ÁÔØ ÍÏÎÏÐÏÌØÎÙÊ ÄÏÓÔÕÐ..");
printf("ðÅÒÅÈÏÖÕ × ÒÅÖÉÍ ÄÅÍÏÎÁ\n");
umask(0);
mk_queues();
val = calloc(512, 1);
tty_init();
close(0); close(1); close(2); // ÏÔËÌÀÞÁÅÍÓÑ ÏÔ ÔÅÒÍÉÎÁÌÁ
if(fork() != 0) exit(0); // ÚÁËÒÙ×ÁÅÍ ÒÏÄÉÔÅÌØÓËÉÊ ÐÏÔÏË
if(argc > 1){ //comdev = argv[1];
if(strcmp(argv[1], "XY") == 0){
warn("òÅÖÉÍ XY-ÁËÔÕÁÔÏÒÏ×\n");
if(init_motor(MOTOR_X)==0){ // Ä×ÉÇÁÔÅÌØ Y
err("Y: ïÛÉÂËÁ !");
}
if(init_motor(MOTOR_Y)==0){ // Ä×ÉÇÁÔÅÌØ X
err("X: ïÛÉÂËÁ!");
}
}
}
else
warn("ïÂÙÞÎÙÊ ÒÅÖÉÍ ÒÁÂÏÔÙ");
signal(SIGTERM, quit); // kill (-15)
signal(SIGINT, quit); // ctrl+C
signal(SIGQUIT, SIG_IGN); // ctrl+\ .
signal(SIGTSTP, SIG_IGN); // ctrl+Z
tm0 = dtime();
while(1){ // ÂÅÓËÏÎÅÞÎÏ ÚÁÃÉËÌÉ×ÁÅÍÓÑ
if(read_queue(&rb, &key, val) > 0){
if(key != 0) con_sig(rb, key, val); // ÅÓÌÉ ÞÔÏ-ÔÏ ÐÏÑ×ÉÌÏÓØ - ÏÂÒÁÂÁÔÙ×ÁÅÍ
}
rb = read_tty();
if(rb != 0) tty_sig(rb); // ÅÓÌÉ ÅÓÔØ ÓÉÇÎÁÌ Ó ËÏÎÔÒÏÌÌÅÒÁ - ÏÂÒÁÂÁÔÙ×ÁÅÍ
}
}

View File

@ -0,0 +1,39 @@
/*********** ðÅÒÅÞÅÎØ ËÏÍÁÎÄ ************/
// ÐÏÌÕÞÉÔØ Ó ËÏÍÐØÀÔÅÒÁ Ä×Á ÂÁÊÔÁ ÄÁÎÎÙÈ É ÚÁÐÉÓÁÔØ ÉÈ × SPI
#define SPI_send 1
// ÒÅÖÉÍÙ ÒÁÂÏÔÙ SPI
#define IMP_RISE 2
#define IMP_FALL 3
#define SPI_ON 4
#define SPI_OFF 5
#define SPI_ACTIVE 6
#define SPI_PASSIVE 7
#define MID_DATA 8
#define END_DATA 9
#define SPI_SHOW 14
// ÓËÏÒÏÓÔÉ ÐÏÒÔÁ (ÐÏ ÕÍÏÌÞÁÎÉÀ 9600)
#define MID_SPD 15
#define HIG_SPD 16
// ÚÁÐÉÓÁÔØ × ÐÏÒÔ ÏÄÉÎ ÐÏÌÕÞÅÎÎÙÊ ÂÁÊÔ
#define SPI_send_one 17
// ÔÅËÕÝÉÊ ÐÅÒÉÏÄ ÔÁÊÍÅÒÁ
#define TMR_SETTINGS 18
// ÕÓÔÁÎÏ×ÉÔØ ÚÎÁÞÅÎÉÅ ÔÁÊÍÅÒÁ
#define SET_TIMER 26
// ÓÂÒÏÓ
#define INIT 28
#define TEST 29
/************** ïÛÉÂËÉ É ÓÉÇÎÁÌÙ ËÏÎÔÒÏÌÌÅÒÁ ******************/
// ×ÓÅ × ÐÏÒÑÄËÅ
#define OK 22
// ÎÅÔ ÓÔÏÐÏ×ÏÇÏ ÂÉÔÁ
#define NO_STOP_BIT 24
// ÐÅÒÅÐÏÌÎÅÎÉÅ ÒÅÇÉÓÔÒÏ×
#define STACK_OVERFLOW 25
// ÏÛÉÂÏÞËÁÑ ËÏÍÁÎÄÁ
#define ERR_CMD 31
#define TWOBYTE 33 // Ä×ÕÈÂÁÊÔÎÁÑ ÐÏÓÙÌËÁ

274
02-TEST/main.c Normal file
View File

@ -0,0 +1,274 @@
#include <pic16f873a.h>
#include "signals.h"
#define BUFSIZE 95
//#define CLRWDT _asm clrwdt _endasm;
typedef unsigned int word;
word at 0x2007 CONFIG = 0x3F72; // для WDT: 0x3F76
unsigned char
cmd, // полученная команда
d_H, d_L, // старший и младший байты двухбайтной посылки
T1H, T1L, // значения регистров счетчика таймера 1
mC_addr; // физ. адрес контроллера (константа, устанавливается функцией init)
unsigned char SPI_buf[BUFSIZE], SPI_cntr;
void send9bit(unsigned char something){
unsigned char tmp;
something &= 0x1F; // сброс старших трех бит (там будет адрес)
tmp = mC_addr | something;
TXEN = 1; // готов к передаче
TX9D = 0; // 0 - передает контроллер
TXREG = tmp; // послать команду
}
unsigned char get9bit(){
unsigned char err1, err2, flag9bit, tmp;
while(!RCIF);
flag9bit = RX9D;
err1 = FERR; err2 = OERR; // считать 9-й бит и ошибки
cmd = RCREG; // очистить буфер данных
RX9D = 0;
if(err1 == 1){
// send9bit(NO_STOP_BIT); // не обнаружен стоповый бит
return NO_STOP_BIT;
}
if(err2 == 1){
// send9bit(STACK_OVERFLOW); // переполнение приемных регистров
CREN = 0; CREN = 1; // сбросить флаг ошибки
return STACK_OVERFLOW;
}
if(flag9bit) return TWOBYTE; // данные - часть двухбайтной посылки (неизвестно еще чьей :) )
tmp = cmd & 0xE0; // выделение адреса из команды
cmd &= 0x1F; // обнуление адресных битов
if(tmp != mC_addr) return ERR_CMD; // если адресован чужому
send9bit(cmd); // Эхо принятой команды
return OK;
}
void sendword(unsigned char data_H, unsigned char data_L){
RCIE = 0; // disable USART in interrupt
TMR1IE = 0;
TXEN = 1;
TX9D = 1;
TXREG = data_H;
while(!TRMT);
TXEN = 1;
TX9D = 1;
TXREG = data_L;
RCIE = 1;
TMR1IE = 1;
}
unsigned char getword(){
unsigned char ret = 0;
RCIE = 0; // disable USART in interrupt
TMR1IE = 0;
if(ten_times_read()){
d_H = cmd;
if(ten_times_read()){
d_L = cmd;
ret = 1;}} // если оба байта считали правильно
TMR1IE = 1;
RCIE = 1; // enable USART in interrupt
return ret;
}
unsigned char ten_times_read(){ // 10 попыток чтения для двухбайтного приема
unsigned char i=0;
do i++;
while(get9bit() != TWOBYTE && i < 10);
if(i > 9){send9bit(ERR_CMD); return 0;}
send9bit(OK);
return 1;
}
void init(){ // инициализация
// Настройка USART'a
// TXSTA: | CSRC | TX9 | TXEN | SYNC | N/A | BRGH | TRMT | TX9D |
TXSTA = 0x66; // (11000110): master, 9-ти битный ввод/вывод, async, hi-speed, ready
// SPBRG - скорость передачи
SPBRG = 25; // 9.6 кб/с
// RCSTA: | SPEN | RX9 | SREN | CREN | ADDEN | FERR | OERR | RX9D |
RCSTA = 0xD0; // ( 11010000): enable, 9bit, continuous mode
// настройка портов:
PORTA = 0; // 6-ти битный аналогово/цифровой порт (0..5 биты)
// ADCON1: | ADFM | N/A | N/A | N/A | PCFG3 | PCFG2 | PCFG1 | PCFG0 |
ADCON1 = 0x06; // Аналогово/цифровой порт работает в полностью цифровом режиме
TRISA = 0; // направление порт А (1-вход, 0-выход)
TRISB = 0xff; // --/ B /--
// OPTION_REG: | !RBPU | INTEDG | TOCS | TOSE | PSA | PS2 | PS1 | PS0 |
OPTION_REG = 0x7f; /* (01111111) 0 - подключение подтяжек на порт B (уст. лог. 1),
прерывание по нарастающему фронту RB0,
таймер 0 работает по сигналу с RA4
таймер 0 увеличивается при спаде сигнала на RA4
предделитель подключен к сторожевому таймеру
режим prescaler: 1:128 */
TRISC = 0xC0; // (11000000) - 0..5 биты как выходы
INTCON = 0; // отключить все прерывания
T1CON = 0;
// PIE1: | PSPIE | ADIE | RCIE | TXIE | SSPIE | CCP1IE | TMR2IE | TMR1IE |
PIE1 = 0x20; // (00100000): enable USART(in)
// PIE2: все N/A, кроме EEIE (PIE2.4)
PIE2 = 0; // & disable other int.s
PORTB = 0;
// INTCON: | GIE | PEIE | T0IE | INTE | RBIE | T0IF | INTF | RBIF |
INTCON = 0xC0; // (1100000) - включить глобальные прерывания, прерывания по периферии
PORTC = 0; // без напряжения
PORTA = 0xF; // (00001111)
// получение адреса
mC_addr = PORTB; // физический адрес устройства
mC_addr &= 0xE0; // выделение физического адреса
SSPEN = 0; SSPIE = 1;
SPI_cntr = 0;
}
void timer1set(){ // установка таймера
// unsigned int tmp = 0xffff - usec/8;
T1CON = 0; // выключить таймер
TMR1IF = 0; // сбросить флаг прерывания
TMR1IE = 1; // разр/запр прерывание
TMR1H = T1H = d_H; //(tmp >> 8) & 0xff;
TMR1L = T1L = d_L; //tmp & 0xff; // установить счетчики
// T1CON: | - | - | T1CPS1 | T1CPS0 | T1OSCEN | T1SYNC | TMR1CS | TMR1ON |
T1CON = 0x31; // (00110001) - включить таймер 1, предделитель на 1/8 (250 кГц)
}
void timer1int(){ // обработка прерываний первого таймера
T1CON = 0;
TMR1H = T1H; TMR1L = T1L;
// send9bit(TEST);
T1CON = 0x31; // снова запускаем таймер
}
void SPI_int(){ // в пассивном режиме принимаемые данные сохраняются в
// буфер, при заполнении буфера он отсылается на ПК
unsigned char i;
if(SSPOV == 1) // ошибка переполнения буфера
return;
if(BF == 0) return; // буфер не заполнен
SSPIE = 0;
TMR1IE = 0;
RCIE = 0;
SPI_buf[SPI_cntr++] = SSPBUF;
if(SPI_cntr == BUFSIZE){
for(i = 0; i < BUFSIZE; i++){
TXEN = 1;
TXREG = SPI_buf[i];
while(!TRMT);
}
SPI_cntr = 0;
}
// BF = 0;
RCIE = 1;
TMR1IE = 1;
SSPIF = 0;
SSPIE = 1;
}
/*
void SPI_int(){
SSPIE = 0;
if(SSPOV == 1) // ошибка переполнения буфера
return;
if(BF == 0) return; // буфер не заполнен
RCIE = 0;
TMR1IE = 0;
TXEN = 1;
TXREG = SSPBUF; // отправляем полученный байт
// while(!TRMT);
RCIE = 1;
TMR1IE = 1;
BF = 0;
SSPIF = 0;
SSPIE = 1;
}*/
void write_SPI(unsigned char byte){
SSPBUF = byte;
//PORTA &= 0xEF; // -SS = 0 - передаем данные по SPI ведомому
while(!SSPIF); // ждем окончания передачи
// SPI_int();
if(SSPOV == 1) // ошибка переполнения буфера
return;
//if(BF == 0) return; // буфер не заполнен
SSPIE = 0;
RCIE = 0;
TMR1IE = 0;
TXEN = 1;
TXREG = SSPBUF; // отправляем полученный байт
while(!TRMT);
RCIE = 1;
TMR1IE = 1;
// BF = 0;
SSPIF = 0;
SSPIE = 1;
}
void show_spi(){
unsigned char i;
SSPIE = 0;
RCIE = 0;
TMR1IE = 0;
TXEN = 1;
TXREG = SPI_cntr;
while(!TRMT);
if(SPI_cntr > 0)
for(i = 0; i < SPI_cntr; i++){
TXEN = 1;
TXREG = SPI_buf[i];
while(!TRMT);
}
SPI_cntr = 0;
TMR1IE = 1;
BF = 0;
SSPIF = 0;
SSPIE = 1;
}
void on_interrupt() __interrupt 0{ // обработка прерываний
if(RCIF == 1){ // поступило прерывание от USART
if(get9bit() != OK) return;
switch(cmd){
case INIT: init(); break;
case SET_TIMER: if(getword()) timer1set();
else send9bit(ERR_CMD);
break;
case TMR_SETTINGS: sendword(T1H, T1L); break;
case SPI_send: if(getword()){
write_SPI(d_H);
write_SPI(d_L);}
break;
case SPI_send_one: while(!RCIF); write_SPI(RCREG); break;
case IMP_RISE: CKE = 1; break;//данные передаются по заднему фронту
case IMP_FALL: CKE = 0; break; //данные передаются по переднему фронту
case MID_DATA: SMP = 0; break;
case END_DATA: SMP = 1; break;
case SPI_ON: // SPI
// SSPCON: | WCOL | SSPOV | SSPEN | CKP | SSPM3 | SSPM2 | SSPM1 | SSPM0 |
SSPEN = 1; // (00110010) - выключить SPI, высокий уровень CLK (CKP=1), частота Fosc/64
// SSPSTAT: | SMP | CKE | - | - | - | - | - | BF |
// SSPSTAT = 0; // режим работы SPI: SMP=0 - опрос входа в середине периода
// CKE=0 - данные передаются по заднему фронту
SSPIE = 1; break;
case SPI_OFF: SSPEN = 0; SSPIE = 0; break;
case SPI_ACTIVE: SSPCON = 0x32; TRISC = 0xD0; CKE = 0; SSPIE = 1; break; //TRISC = 0xC0
case SPI_PASSIVE: SSPCON = 0x35; TRISC = 0xD8; CKE = 0; SSPIE = 1; break;//TRISC=255;
case HIG_SPD: SPBRG = 1; break; // 115200
case MID_SPD: SPBRG = 12; break; // 19200
case TEST: T1CON = 0; TMR1IF = 0; break;
case SPI_SHOW: show_spi(); break;
}
}
if(TMR1IF == 1) // поступило прерывание от таймера
timer1int(); // обработать прерывание
if(SSPIF == 1) // прерывание от SPI
SPI_int(); // обрабатываем
}
void main(){ // основной цикл
init();
while(1){};
}

242
02-TEST/main1.c Normal file
View File

@ -0,0 +1,242 @@
#include <pic16f873a.h>
#include "signals.h"
//#define CLRWDT _asm clrwdt _endasm;
typedef unsigned int word;
word at 0x2007 CONFIG = 0x3F72; // для WDT: 0x3F76
unsigned char
cmd, // полученная команда
d_H, d_L, // старший и младший байты двухбайтной посылки
T1H, T1L, // значения регистров счетчика таймера 1
mC_addr; // физ. адрес контроллера (константа, устанавливается функцией init)
unsigned char SPI_buf[64], SPI_cntr;
void send9bit(unsigned char something){
unsigned char tmp;
something &= 0x1F; // сброс старших трех бит (там будет адрес)
tmp = mC_addr | something;
TXEN = 1; // готов к передаче
TX9D = 0; // 0 - передает контроллер
TXREG = tmp; // послать команду
}
unsigned char get9bit(){
unsigned char err1, err2, flag9bit, tmp;
while(!RCIF);
flag9bit = RX9D;
err1 = FERR; err2 = OERR; // считать 9-й бит и ошибки
cmd = RCREG; // очистить буфер данных
RX9D = 0;
if(err1 == 1){
// send9bit(NO_STOP_BIT); // не обнаружен стоповый бит
return NO_STOP_BIT;
}
if(err2 == 1){
// send9bit(STACK_OVERFLOW); // переполнение приемных регистров
CREN = 0; CREN = 1; // сбросить флаг ошибки
return STACK_OVERFLOW;
}
if(flag9bit) return TWOBYTE; // данные - часть двухбайтной посылки (неизвестно еще чьей :) )
tmp = cmd & 0xE0; // выделение адреса из команды
cmd &= 0x1F; // обнуление адресных битов
if(tmp != mC_addr) return ERR_CMD; // если адресован чужому
send9bit(cmd); // Эхо принятой команды
return OK;
}
void sendword(unsigned char data_H, unsigned char data_L){
RCIE = 0; // disable USART in interrupt
TMR1IE = 0;
TXEN = 1;
TX9D = 1;
TXREG = data_H;
while(!TRMT);
TXEN = 1;
TX9D = 1;
TXREG = data_L;
RCIE = 1;
TMR1IE = 1;
}
unsigned char getword(){
unsigned char ret = 0;
RCIE = 0; // disable USART in interrupt
TMR1IE = 0;
if(ten_times_read()){
d_H = cmd;
if(ten_times_read()){
d_L = cmd;
ret = 1;}} // если оба байта считали правильно
TMR1IE = 1;
RCIE = 1; // enable USART in interrupt
return ret;
}
unsigned char ten_times_read(){ // 10 попыток чтения для двухбайтного приема
unsigned char i=0;
do i++;
while(get9bit() != TWOBYTE && i < 10);
if(i > 9){send9bit(ERR_CMD); return 0;}
send9bit(OK);
return 1;
}
void init(){ // инициализация
// Настройка USART'a
// TXSTA: | CSRC | TX9 | TXEN | SYNC | N/A | BRGH | TRMT | TX9D |
TXSTA = 0x66; // (11000110): master, 9-ти битный ввод/вывод, async, hi-speed, ready
// SPBRG - скорость передачи
SPBRG = 25; // 9.6 кб/с
// RCSTA: | SPEN | RX9 | SREN | CREN | ADDEN | FERR | OERR | RX9D |
RCSTA = 0xD0; // ( 11010000): enable, 9bit, continuous mode
// настройка портов:
PORTA = 0; // 6-ти битный аналогово/цифровой порт (0..5 биты)
// ADCON1: | ADFM | N/A | N/A | N/A | PCFG3 | PCFG2 | PCFG1 | PCFG0 |
ADCON1 = 0x06; // Аналогово/цифровой порт работает в полностью цифровом режиме
TRISA = 0; // направление порт А (1-вход, 0-выход)
TRISB = 0xff; // --/ B /--
// OPTION_REG: | !RBPU | INTEDG | TOCS | TOSE | PSA | PS2 | PS1 | PS0 |
OPTION_REG = 0x7f; /* (01111111) 0 - подключение подтяжек на порт B (уст. лог. 1),
прерывание по нарастающему фронту RB0,
таймер 0 работает по сигналу с RA4
таймер 0 увеличивается при спаде сигнала на RA4
предделитель подключен к сторожевому таймеру
режим prescaler: 1:128 */
TRISC = 0xC0; // (11000000) - 0..5 биты как выходы
INTCON = 0; // отключить все прерывания
T1CON = 0;
// PIE1: | PSPIE | ADIE | RCIE | TXIE | SSPIE | CCP1IE | TMR2IE | TMR1IE |
PIE1 = 0x20; // (00100000): enable USART(in)
// PIE2: все N/A, кроме EEIE (PIE2.4)
PIE2 = 0; // & disable other int.s
PORTB = 0;
// INTCON: | GIE | PEIE | T0IE | INTE | RBIE | T0IF | INTF | RBIF |
INTCON = 0xC0; // (1100000) - включить глобальные прерывания, прерывания по периферии
PORTC = 0; // без напряжения
PORTA = 0xF; // (00001111)
// получение адреса
mC_addr = PORTB; // физический адрес устройства
mC_addr &= 0xE0; // выделение физического адреса
SSPEN = 0; SSPIE = 0;
SPI_cntr = 0;
}
void timer1set(){ // установка таймера
// unsigned int tmp = 0xffff - usec/8;
T1CON = 0; // выключить таймер
TMR1IF = 0; // сбросить флаг прерывания
TMR1IE = 1; // разр/запр прерывание
TMR1H = T1H = d_H; //(tmp >> 8) & 0xff;
TMR1L = T1L = d_L; //tmp & 0xff; // установить счетчики
// T1CON: | - | - | T1CPS1 | T1CPS0 | T1OSCEN | T1SYNC | TMR1CS | TMR1ON |
T1CON = 0x31; // (00110001) - включить таймер 1, предделитель на 1/8 (250 кГц)
}
void timer1int(){ // обработка прерываний первого таймера
T1CON = 0;
TMR1H = T1H; TMR1L = T1L;
// send9bit(TEST);
T1CON = 0x31; // снова запускаем таймер
}
void SPI_int(){ // в пассивном режиме принимаемые данные сохраняются в
// буфер, при заполнении буфера он отсылается на ПК
unsigned char i;
TMR1IE = 0;
RCIE = 0;
SPI_buf[SPI_cntr++] = SSPBUF;
if(SPI_cntr == 64){
for(i = 0; i < 64; i++){
TXEN = 1;
TXREG = SPI_buf[i];
while(!TRMT);
}
SPI_cntr = 0;
}
RCIE = 1;
TMR1IE = 1;
BF = 0;
SSPIF = 0;
}
/*
void SPI_int(){
SSPIE = 0;
if(SSPOV == 1) // ошибка переполнения буфера
return;
if(BF == 0) return; // буфер не заполнен
RCIE = 0;
TMR1IE = 0;
TXEN = 1;
TXREG = SSPBUF; // отправляем полученный байт
// while(!TRMT);
RCIE = 1;
TMR1IE = 1;
BF = 0;
SSPIF = 0;
SSPIE = 1;
}
*/
void write_SPI(unsigned char byte){
SSPBUF = byte;
//PORTA &= 0xEF; // -SS = 0 - передаем данные по SPI ведомому
while(!SSPIF); // ждем окончания передачи
// SPI_int();
RCIE = 0;
TMR1IE = 0;
TXEN = 1;
TXREG = SSPBUF; // отправляем полученный байт
RCIE = 1;
TMR1IE = 1;
BF = 0;
SSPIF = 0;
}
void on_interrupt() __interrupt 0{ // обработка прерываний
if(RCIF == 1){ // поступило прерывание от USART
if(get9bit() != OK) return;
switch(cmd){
case INIT: init(); break;
case SET_TIMER: if(getword()) timer1set();
else send9bit(ERR_CMD);
break;
case TMR_SETTINGS: sendword(T1H, T1L); break;
case SPI_send: if(getword()){
write_SPI(d_H);
write_SPI(d_L);}
break;
case SPI_send_one: while(!RCIF); write_SPI(RCREG); break;
case IMP_RISE: CKE = 1; break;//данные передаются по заднему фронту
case IMP_FALL: CKE = 0; break; //данные передаются по переднему фронту
case MID_DATA: SMP = 0; break;
case END_DATA: SMP = 1; break;
case SPI_ON: // SPI
// SSPCON: | WCOL | SSPOV | SSPEN | CKP | SSPM3 | SSPM2 | SSPM1 | SSPM0 |
SSPEN = 1; // (00110010) - выключить SPI, высокий уровень CLK (CKP=1), частота Fosc/64
// SSPSTAT: | SMP | CKE | - | - | - | - | - | BF |
// SSPSTAT = 0; // режим работы SPI: SMP=0 - опрос входа в середине периода
// CKE=0 - данные передаются по заднему фронту
SSPIE = 0; break;
case SPI_OFF: SSPEN = 0; SSPIE = 0; break;
case SPI_ACTIVE: SSPCON = 0x32; TRISC = 0x10; CKE = 0; SSPIE = 0; break; //TRISC = 0xC0;
case SPI_PASSIVE: SSPCON = 0x35; TRISC = 0x18; CKE = 0; SSPIE = 1; break;//TRISC = 255;
case HIG_SPD: SPBRG = 1; break; // 115200
case MID_SPD: SPBRG = 12; break; // 19200
case TEST: T1CON = 0; TMR1IF = 0; break;
}
}
if(TMR1IF == 1) // поступило прерывание от таймера
timer1int(); // обработать прерывание
if(SSPIF == 1) // прерывание от SPI
SPI_int(); // обрабатываем
}
void main(){ // основной цикл
init();
while(1){};
}

3
02-TEST/run Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
sdcc -V -mpic14 -p16f873a main.c
#packihx main.ihx > main.hex

50
02-TEST/signals.h Normal file
View File

@ -0,0 +1,50 @@
/*********** æÕÎËÃÉÉ ***********************/
void send9bit(unsigned char something);
unsigned char get9bit();
void sendword(unsigned char data_H, unsigned char data_L);
unsigned char getword();
unsigned char ten_times_read();
void init();
void timer1set();
void timer1int();
void SPI_int();
/*********** ðÅÒÅÞÅÎØ ËÏÍÁÎÄ ************/
// ÐÏÌÕÞÉÔØ Ó ËÏÍÐØÀÔÅÒÁ Ä×Á ÂÁÊÔÁ ÄÁÎÎÙÈ É ÚÁÐÉÓÁÔØ ÉÈ × SPI
#define SPI_send 1
// ÒÅÖÉÍÙ ÒÁÂÏÔÙ SPI
#define IMP_RISE 2
#define IMP_FALL 3
#define SPI_ON 4
#define SPI_OFF 5
#define SPI_ACTIVE 6
#define SPI_PASSIVE 7
#define MID_DATA 8
#define END_DATA 9
#define SPI_SHOW 14
// ÓËÏÒÏÓÔÉ ÐÏÒÔÁ (ÐÏ ÕÍÏÌÞÁÎÉÀ 9600)
#define MID_SPD 15
#define HIG_SPD 16
// ÚÁÐÉÓÁÔØ × ÐÏÒÔ ÏÄÉÎ ÐÏÌÕÞÅÎÎÙÊ ÂÁÊÔ
#define SPI_send_one 17
// ÔÅËÕÝÉÊ ÐÅÒÉÏÄ ÔÁÊÍÅÒÁ
#define TMR_SETTINGS 18
// ÕÓÔÁÎÏ×ÉÔØ ÚÎÁÞÅÎÉÅ ÔÁÊÍÅÒÁ
#define SET_TIMER 26
// ÓÂÒÏÓ
#define INIT 28
#define TEST 29
/************** ïÛÉÂËÉ É ÓÉÇÎÁÌÙ ËÏÎÔÒÏÌÌÅÒÁ ******************/
// ×ÓÅ × ÐÏÒÑÄËÅ
#define OK 22
// ÎÅÔ ÓÔÏÐÏ×ÏÇÏ ÂÉÔÁ
#define NO_STOP_BIT 24
// ÐÅÒÅÐÏÌÎÅÎÉÅ ÒÅÇÉÓÔÒÏ×
#define STACK_OVERFLOW 25
// ÏÛÉÂÏÞËÁÑ ËÏÍÁÎÄÁ
#define ERR_CMD 31
#define TWOBYTE 33 // Ä×ÕÈÂÁÊÔÎÁÑ ÐÏÓÙÌËÁ

413
03-focusing/Frontend/FE.c Normal file
View File

@ -0,0 +1,413 @@
#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); // ÅÓÌÉ ÅÓÔØ ÓÉÇÎÁÌ Ó ËÏÎÔÒÏÌÌÅÒÁ - ÏÂÒÁÂÁÔÙ×ÁÅÍ
}
}

View File

@ -0,0 +1,18 @@
PROGRAM = FE
LOADLIBES =
CXX.SRCS = FE.c
CC = gcc
DEFINES =
CXX = gcc
CPPFLAGS = -Wall $(DEFINES)
OBJS = $(CXX.SRCS:.c=.o)
all : $(PROGRAM) clean
$(PROGRAM) : $(OBJS)
$(CC) $(CPPFLAGS) $(OBJS) $(LOADLIBES) -o $(PROGRAM)
clean:
/bin/rm -f *.o *~
depend:
$(CXX) -MM $(CXX.SRCS)
### <DEPENDENCIES ON .h FILES GO HERE>
# name1.o : header1.h header2.h ...

View File

@ -0,0 +1,44 @@
/*********** ðÅÒÅÞÅÎØ ËÏÍÁÎÄ ************/
// ÐÏÌÕÞÉÔØ Ó ËÏÍÐØÀÔÅÒÁ ÂÁÊÔ ÄÁÎÎÙÈ É ÚÁÐÉÓÁÔØ × SPI
#define SPI_send_one 1
// ÒÅÖÉÍÙ ÒÁÂÏÔÙ SPI
#define MID_DATA 2
#define END_DATA 3
// ÓËÏÒÏÓÔÉ ÐÏÒÔÁ (ÐÏ ÕÍÏÌÞÁÎÉÀ 9600)
#define MID_SPD 4 // 19200
#define LOW_SPD 5 // 9600
// ÓËÏÒÏÓÔÉ ÏÂßÅËÔÉ×Á (×ÒÅÍÑ, ÞÅÒÅÚ ËÏÔÏÒÏÅ ÂÕÄÅÔ ÐÏÓÌÁÎ ÓÉÇÎÁÌ "ÓÔÏÐ")
#define SPEED1 6 // .3c
#define SPEED2 7 // .05c
#define SPEED3 8 // .01c
// ÎÁÐÒÁ×ÌÅÎÉÑ Ä×ÉÖÅÎÉÑ
#define FORW 9
#define BACK 10
#define INFTY 11
#define ZERO 12
// ÕÚÎÁÔØ ÆÏËÕÓ
#define FOCUS 19
// ÒÕÞÎÏÊ ÒÅÖÉÍ ÕÐÒÁ×ÌÅÎÉÑ
#define HANDS 13
#define TMR_ON 14
#define TMR_OFF 15
#define SPI_ON 16
#define SPI_OFF 17
// ÔÅËÕÝÉÊ ÐÅÒÉÏÄ ÔÁÊÍÅÒÁ
#define TMR_SETTINGS 18
// ÕÓÔÁÎÏ×ÉÔØ ÚÎÁÞÅÎÉÅ ÔÁÊÍÅÒÁ
#define SET_TIMER 26
// ÓÂÒÏÓ
#define INIT 28
#define TEST 29
/************** ïÛÉÂËÉ É ÓÉÇÎÁÌÙ ËÏÎÔÒÏÌÌÅÒÁ ******************/
// ×ÓÅ × ÐÏÒÑÄËÅ
#define OK 22
// ÎÅÔ ÓÔÏÐÏ×ÏÇÏ ÂÉÔÁ
#define NO_STOP_BIT 24
// ÐÅÒÅÐÏÌÎÅÎÉÅ ÒÅÇÉÓÔÒÏ×
#define STACK_OVERFLOW 25
// ÏÛÉÂÏÞËÁÑ ËÏÍÁÎÄÁ
#define ERR_CMD 31
#define TWOBYTE 33 // Ä×ÕÈÂÁÊÔÎÁÑ ÐÏÓÙÌËÁ

227
03-focusing/main.c Normal file
View File

@ -0,0 +1,227 @@
#include <pic16f873a.h>
#include "signals.h"
#define BUFSIZE 95
//#define CLRWDT _asm clrwdt _endasm;
typedef unsigned int word;
word at 0x2007 CONFIG = 0x3F72; // ÄÌÑ WDT: 0x3F76
unsigned char
cmd, // ÐÏÌÕÞÅÎÎÁÑ ËÏÍÁÎÄÁ
d_H, d_L, // ÓÔÁÒÛÉÊ É ÍÌÁÄÛÉÊ ÂÁÊÔÙ Ä×ÕÈÂÁÊÔÎÏÊ ÐÏÓÙÌËÉ
T1H, T1L, // ÚÎÁÞÅÎÉÑ ÒÅÇÉÓÔÒÏ× ÓÞÅÔÞÉËÁ ÔÁÊÍÅÒÁ 1
mC_addr, // ÆÉÚ. ÁÄÒÅÓ ËÏÎÔÒÏÌÌÅÒÁ (ËÏÎÓÔÁÎÔÁ, ÕÓÔÁÎÁ×ÌÉ×ÁÅÔÓÑ ÆÕÎËÃÉÅÊ init)
tmr_on; // ==1 - ÔÁÊÍÅÒ ×ËÌÀÞÅÎ
unsigned char write_SPI(unsigned char);
void hands(){
unsigned char i;
write_SPI(10); // ÉÎÉÃÉÁÌÉÚÁÃÉÑ
write_SPI(0);
/* write_SPI(128);
for(i=0; i<20; i++)
write_SPI(0);*/
write_SPI(94); // ÒÕËÉ
for(i=0; i<5; i++)
write_SPI(0);
T1CON = 0;
}
void focus(){
unsigned char i;
write_SPI(194);
TX9D = 0;
for(i=0; i<5; i++){
TXEN = 1;
TXREG = write_SPI(0);
while(!TRMT);
}
}
void send9bit(unsigned char something){
unsigned char tmp;
something &= 0x1F; // ÓÂÒÏÓ ÓÔÁÒÛÉÈ ÔÒÅÈ ÂÉÔ (ÔÁÍ ÂÕÄÅÔ ÁÄÒÅÓ)
tmp = mC_addr | something;
TXEN = 1; // ÇÏÔÏ× Ë ÐÅÒÅÄÁÞÅ
TX9D = 0; // 0 - ÐÅÒÅÄÁÅÔ ËÏÎÔÒÏÌÌÅÒ
TXREG = tmp; // ÐÏÓÌÁÔØ ËÏÍÁÎÄÕ
}
unsigned char get9bit(){
unsigned char err1, err2, flag9bit, tmp;
while(!RCIF);
flag9bit = RX9D;
err1 = FERR; err2 = OERR; // ÓÞÉÔÁÔØ 9-Ê ÂÉÔ É ÏÛÉÂËÉ
cmd = RCREG; // ÏÞÉÓÔÉÔØ ÂÕÆÅÒ ÄÁÎÎÙÈ
RX9D = 0;
if(err1 == 1){
return NO_STOP_BIT;
}
if(err2 == 1){
CREN = 0; CREN = 1; // ÓÂÒÏÓÉÔØ ÆÌÁÇ ÏÛÉÂËÉ
return STACK_OVERFLOW;
}
if(flag9bit) return TWOBYTE; // ÄÁÎÎÙÅ - ÞÁÓÔØ Ä×ÕÈÂÁÊÔÎÏÊ ÐÏÓÙÌËÉ (ÎÅÉÚ×ÅÓÔÎÏ ÅÝÅ ÞØÅÊ :) )
tmp = cmd & 0xE0; // ×ÙÄÅÌÅÎÉÅ ÁÄÒÅÓÁ ÉÚ ËÏÍÁÎÄÙ
cmd &= 0x1F; // ÏÂÎÕÌÅÎÉÅ ÁÄÒÅÓÎÙÈ ÂÉÔÏ×
if(tmp != mC_addr) return ERR_CMD; // ÅÓÌÉ ÁÄÒÅÓÏ×ÁÎ ÞÕÖÏÍÕ
send9bit(cmd); // üÈÏ ÐÒÉÎÑÔÏÊ ËÏÍÁÎÄÙ
return OK;
}
void sendword(unsigned char data_H, unsigned char data_L){
RCIE = 0; // disable USART in interrupt
TMR1IF = 0;
TMR1IE = 0;
TXEN = 1;
TX9D = 1;
TXREG = data_H;
while(!TRMT);
TXEN = 1;
TX9D = 1;
TXREG = data_L;
RCIE = 1;
if(tmr_on) TMR1IE = 1;
}
unsigned char getword(){
unsigned char ret = 0;
RCIE = 0; // disable USART in interrupt
TMR1IF = 0;
TMR1IE = 0;
if(ten_times_read()){
d_H = cmd;
if(ten_times_read()){
d_L = cmd;
ret = 1;}} // ÅÓÌÉ ÏÂÁ ÂÁÊÔÁ ÓÞÉÔÁÌÉ ÐÒÁ×ÉÌØÎÏ
if(tmr_on) TMR1IE = 1;
RCIE = 1; // enable USART in interrupt
return ret;
}
unsigned char ten_times_read(){ // 10 ÐÏÐÙÔÏË ÞÔÅÎÉÑ ÄÌÑ Ä×ÕÈÂÁÊÔÎÏÇÏ ÐÒÉÅÍÁ
unsigned char i=0;
do i++;
while(get9bit() != TWOBYTE && i < 10);
if(i > 9){send9bit(ERR_CMD); return 0;}
send9bit(OK);
return 1;
}
void init(){ // ÉÎÉÃÉÁÌÉÚÁÃÉÑ
// îÁÓÔÒÏÊËÁ USART'a
// TXSTA: | CSRC | TX9 | TXEN | SYNC | N/A | BRGH | TRMT | TX9D |
TXSTA = 0x66; // (11000110): master, 9-ÔÉ ÂÉÔÎÙÊ ××ÏÄ/×Ù×ÏÄ, async, hi-speed, ready
// SPBRG - ÓËÏÒÏÓÔØ ÐÅÒÅÄÁÞÉ
SPBRG = 25; // 9.6 ËÂ/Ó
// RCSTA: | SPEN | RX9 | SREN | CREN | ADDEN | FERR | OERR | RX9D |
RCSTA = 0xD0; // ( 11010000): enable, 9bit, continuous mode
// ÎÁÓÔÒÏÊËÁ ÐÏÒÔÏ×:
PORTA = 0; // 6-ÔÉ ÂÉÔÎÙÊ ÁÎÁÌÏÇÏ×Ï/ÃÉÆÒÏ×ÏÊ ÐÏÒÔ (0..5 ÂÉÔÙ)
// ADCON1: | ADFM | N/A | N/A | N/A | PCFG3 | PCFG2 | PCFG1 | PCFG0 |
ADCON1 = 0x06; // áÎÁÌÏÇÏ×Ï/ÃÉÆÒÏ×ÏÊ ÐÏÒÔ ÒÁÂÏÔÁÅÔ × ÐÏÌÎÏÓÔØÀ ÃÉÆÒÏ×ÏÍ ÒÅÖÉÍÅ
TRISA = 0; // ÎÁÐÒÁ×ÌÅÎÉÅ ÐÏÒÔ á (1-×ÈÏÄ, 0-×ÙÈÏÄ)
TRISB = 0xff; // --/ B /--
// OPTION_REG: | !RBPU | INTEDG | TOCS | TOSE | PSA | PS2 | PS1 | PS0 |
OPTION_REG = 0x7f; /* (01111111) 0 - ÐÏÄËÌÀÞÅÎÉÅ ÐÏÄÔÑÖÅË ÎÁ ÐÏÒÔ B (ÕÓÔ. ÌÏÇ. 1),
ÐÒÅÒÙ×ÁÎÉÅ ÐÏ ÎÁÒÁÓÔÁÀÝÅÍÕ ÆÒÏÎÔÕ RB0,
ÔÁÊÍÅÒ 0 ÒÁÂÏÔÁÅÔ ÐÏ ÓÉÇÎÁÌÕ Ó RA4
ÔÁÊÍÅÒ 0 Õ×ÅÌÉÞÉ×ÁÅÔÓÑ ÐÒÉ ÓÐÁÄÅ ÓÉÇÎÁÌÁ ÎÁ RA4
ÐÒÅÄÄÅÌÉÔÅÌØ ÐÏÄËÌÀÞÅÎ Ë ÓÔÏÒÏÖÅ×ÏÍÕ ÔÁÊÍÅÒÕ
ÒÅÖÉÍ prescaler: 1:128 */
TRISC = 0xC0; // (11000000) - 0..5 ÂÉÔÙ ËÁË ×ÙÈÏÄÙ
INTCON = 0; // ÏÔËÌÀÞÉÔØ ×ÓÅ ÐÒÅÒÙ×ÁÎÉÑ
T1CON = 0;
// PIE1: | PSPIE | ADIE | RCIE | TXIE | SSPIE | CCP1IE | TMR2IE | TMR1IE |
PIE1 = 0x20; // (00100000): enable USART(in)
// PIE2: ×ÓÅ N/A, ËÒÏÍÅ EEIE (PIE2.4)
PIE2 = 0; // & disable other int.s
PORTB = 0;
// INTCON: | GIE | PEIE | T0IE | INTE | RBIE | T0IF | INTF | RBIF |
INTCON = 0xC0; // (1100000) - ×ËÌÀÞÉÔØ ÇÌÏÂÁÌØÎÙÅ ÐÒÅÒÙ×ÁÎÉÑ, ÐÒÅÒÙ×ÁÎÉÑ ÐÏ ÐÅÒÉÆÅÒÉÉ
PORTC = 0; // ÂÅÚ ÎÁÐÒÑÖÅÎÉÑ
PORTA = 0xF; // (00001111)
// ÐÏÌÕÞÅÎÉÅ ÁÄÒÅÓÁ
mC_addr = PORTB; // ÆÉÚÉÞÅÓËÉÊ ÁÄÒÅÓ ÕÓÔÒÏÊÓÔ×Á
mC_addr &= 0xE0; // ×ÙÄÅÌÅÎÉÅ ÆÉÚÉÞÅÓËÏÇÏ ÁÄÒÅÓÁ
// SSPCON: | WCOL | SSPOV | SSPEN | CKP | SSPM3 | SSPM2 | SSPM1 | SSPM0 |
SSPCON = 0x32; // (00110010) - ×ËÌÀÞÉÔØ SPI, ×ÙÓÏËÉÊ ÕÒÏ×ÅÎØ CLK (CKP=1), ÞÁÓÔÏÔÁ Fosc/64
// SSPSTAT: | SMP | CKE | - | - | - | - | - | BF |
SSPSTAT = 0; // ÒÅÖÉÍ ÒÁÂÏÔÙ SPI: SMP=0 - ÏÐÒÏÓ ×ÈÏÄÁ × ÓÅÒÅÄÉÎÅ ÐÅÒÉÏÄÁ
// CKE=0 - ÄÁÎÎÙÅ ÐÅÒÅÄÁÀÔÓÑ ÐÏ ÚÁÄÎÅÍÕ ÆÒÏÎÔÕ
TRISC = 0xD0; SSPIE = 1;
tmr_on = 0;
hands();
}
void timer1set(){ // ÕÓÔÁÎÏ×ËÁ ÔÁÊÍÅÒÁ
// unsigned int tmp = 0xffff - usec/8;
T1CON = 0; // ×ÙËÌÀÞÉÔØ ÔÁÊÍÅÒ
TMR1IF = 0; // ÓÂÒÏÓÉÔØ ÆÌÁÇ ÐÒÅÒÙ×ÁÎÉÑ
TMR1IE = 1; // ÒÁÚÒ/ÚÁÐÒ ÐÒÅÒÙ×ÁÎÉÅ
TMR1H = T1H = d_H; //(tmp >> 8) & 0xff;
TMR1L = T1L = d_L; //tmp & 0xff; // ÕÓÔÁÎÏ×ÉÔØ ÓÞÅÔÞÉËÉ
// T1CON: | - | - | T1CPS1 | T1CPS0 | T1OSCEN | T1SYNC | TMR1CS | TMR1ON |
T1CON = 0x31; // (00110001) - ×ËÌÀÞÉÔØ ÔÁÊÍÅÒ 1, ÐÒÅÄÄÅÌÉÔÅÌØ ÎÁ 1/8 (250 ËçÃ)
tmr_on = 1;
}
unsigned char write_SPI(unsigned char byte){
unsigned char ans;
TMR1IF = 0;
if(tmr_on){
T1CON = 0; // ÏÔËÌÀÞÁÅÍ ÔÁÊÍÅÒ
TMR1IE = 0;
}
SSPBUF = byte;
while(!SSPIF); // ÖÄÅÍ ÏËÏÎÞÁÎÉÑ ÐÅÒÅÄÁÞÉ
ans = SSPBUF; // ÒÅÇÉÓÔÒÉÒÕÅÍ ÐÏÌÕÞÅÎÎÙÊ ÂÁÊÔ
SSPIF = 0;
SSPIE = 1;
if(tmr_on){
TMR1H = T1H; TMR1L = T1L;
T1CON = 0x31; // ÚÁÐÕÓËÁÅÍ ÔÁÊÍÅÒ
TMR1IE = 1;
}
return ans;
}
void on_interrupt() __interrupt 0{ // ÏÂÒÁÂÏÔËÁ ÐÒÅÒÙ×ÁÎÉÊ
if(RCIF == 1){ // ÐÏÓÔÕÐÉÌÏ ÐÒÅÒÙ×ÁÎÉÅ ÏÔ USART
if(get9bit() != OK) return;
switch(cmd){
case INIT: init(); break;
case SET_TIMER: if(getword()) timer1set();
else send9bit(ERR_CMD);
break;
case TMR_SETTINGS: sendword(T1H, T1L); break;
case SPI_send_one: while(!RCIF);
TX9D = 0; TXEN = 1; TXREG = write_SPI(RCREG); break;
case SPI_ON: SSPEN = 1; SSPIE = 1; break;
case SPI_OFF: SSPEN = 0; SSPIE = 0; break;
case MID_DATA: SMP = 0; break;
case END_DATA: SMP = 1; break;
case MID_SPD: SPBRG = 12; break; // 19200
case LOW_SPD: SPBRG = 25; break; // 9600
case SPEED1: d_H = 0x6D; d_L = 0x84; timer1set(); break; // 0.3Ó
case SPEED2: d_H = 0xE7; d_L = 0x96; timer1set(); break; // 0.05Ó
case SPEED3: d_H = 0xFB; d_L = 0x1E; timer1set(); break; // 0.01Ó
case FORW: write_SPI(5); break;
case BACK: write_SPI(6); break;
case INFTY: write_SPI(37); break;
case ZERO: write_SPI(22); break;
case HANDS: hands(); break;
case TMR_OFF: tmr_on = 0; T1CON = 0; TMR1IE = 0; break;
case TMR_ON: tmr_on = 1; T1CON = 0x31; TMR1IE = 1; break;
case FOCUS: focus(); break;
}
}
if(TMR1IF == 1 && tmr_on){ // ÐÏÓÔÕÐÉÌÏ ÐÒÅÒÙ×ÁÎÉÅ ÏÔ ÔÁÊÍÅÒÁ
write_SPI(4); // ÐÏÓÙÌÁÅÍ ÓÉÇÎÁÌ ÓÔÏÐ É ÐÅÒÅÚÁÐÕÓËÁÅÍ ÔÁÊÍÅÒ
write_SPI(0);
}
}
void main(){ // ÏÓÎÏ×ÎÏÊ ÃÉËÌ
init();
while(1){};
}

242
03-focusing/main1.c Normal file
View File

@ -0,0 +1,242 @@
#include <pic16f873a.h>
#include "signals.h"
//#define CLRWDT _asm clrwdt _endasm;
typedef unsigned int word;
word at 0x2007 CONFIG = 0x3F72; // для WDT: 0x3F76
unsigned char
cmd, // полученная команда
d_H, d_L, // старший и младший байты двухбайтной посылки
T1H, T1L, // значения регистров счетчика таймера 1
mC_addr; // физ. адрес контроллера (константа, устанавливается функцией init)
unsigned char SPI_buf[64], SPI_cntr;
void send9bit(unsigned char something){
unsigned char tmp;
something &= 0x1F; // сброс старших трех бит (там будет адрес)
tmp = mC_addr | something;
TXEN = 1; // готов к передаче
TX9D = 0; // 0 - передает контроллер
TXREG = tmp; // послать команду
}
unsigned char get9bit(){
unsigned char err1, err2, flag9bit, tmp;
while(!RCIF);
flag9bit = RX9D;
err1 = FERR; err2 = OERR; // считать 9-й бит и ошибки
cmd = RCREG; // очистить буфер данных
RX9D = 0;
if(err1 == 1){
// send9bit(NO_STOP_BIT); // не обнаружен стоповый бит
return NO_STOP_BIT;
}
if(err2 == 1){
// send9bit(STACK_OVERFLOW); // переполнение приемных регистров
CREN = 0; CREN = 1; // сбросить флаг ошибки
return STACK_OVERFLOW;
}
if(flag9bit) return TWOBYTE; // данные - часть двухбайтной посылки (неизвестно еще чьей :) )
tmp = cmd & 0xE0; // выделение адреса из команды
cmd &= 0x1F; // обнуление адресных битов
if(tmp != mC_addr) return ERR_CMD; // если адресован чужому
send9bit(cmd); // Эхо принятой команды
return OK;
}
void sendword(unsigned char data_H, unsigned char data_L){
RCIE = 0; // disable USART in interrupt
TMR1IE = 0;
TXEN = 1;
TX9D = 1;
TXREG = data_H;
while(!TRMT);
TXEN = 1;
TX9D = 1;
TXREG = data_L;
RCIE = 1;
TMR1IE = 1;
}
unsigned char getword(){
unsigned char ret = 0;
RCIE = 0; // disable USART in interrupt
TMR1IE = 0;
if(ten_times_read()){
d_H = cmd;
if(ten_times_read()){
d_L = cmd;
ret = 1;}} // если оба байта считали правильно
TMR1IE = 1;
RCIE = 1; // enable USART in interrupt
return ret;
}
unsigned char ten_times_read(){ // 10 попыток чтения для двухбайтного приема
unsigned char i=0;
do i++;
while(get9bit() != TWOBYTE && i < 10);
if(i > 9){send9bit(ERR_CMD); return 0;}
send9bit(OK);
return 1;
}
void init(){ // инициализация
// Настройка USART'a
// TXSTA: | CSRC | TX9 | TXEN | SYNC | N/A | BRGH | TRMT | TX9D |
TXSTA = 0x66; // (11000110): master, 9-ти битный ввод/вывод, async, hi-speed, ready
// SPBRG - скорость передачи
SPBRG = 25; // 9.6 кб/с
// RCSTA: | SPEN | RX9 | SREN | CREN | ADDEN | FERR | OERR | RX9D |
RCSTA = 0xD0; // ( 11010000): enable, 9bit, continuous mode
// настройка портов:
PORTA = 0; // 6-ти битный аналогово/цифровой порт (0..5 биты)
// ADCON1: | ADFM | N/A | N/A | N/A | PCFG3 | PCFG2 | PCFG1 | PCFG0 |
ADCON1 = 0x06; // Аналогово/цифровой порт работает в полностью цифровом режиме
TRISA = 0; // направление порт А (1-вход, 0-выход)
TRISB = 0xff; // --/ B /--
// OPTION_REG: | !RBPU | INTEDG | TOCS | TOSE | PSA | PS2 | PS1 | PS0 |
OPTION_REG = 0x7f; /* (01111111) 0 - подключение подтяжек на порт B (уст. лог. 1),
прерывание по нарастающему фронту RB0,
таймер 0 работает по сигналу с RA4
таймер 0 увеличивается при спаде сигнала на RA4
предделитель подключен к сторожевому таймеру
режим prescaler: 1:128 */
TRISC = 0xC0; // (11000000) - 0..5 биты как выходы
INTCON = 0; // отключить все прерывания
T1CON = 0;
// PIE1: | PSPIE | ADIE | RCIE | TXIE | SSPIE | CCP1IE | TMR2IE | TMR1IE |
PIE1 = 0x20; // (00100000): enable USART(in)
// PIE2: все N/A, кроме EEIE (PIE2.4)
PIE2 = 0; // & disable other int.s
PORTB = 0;
// INTCON: | GIE | PEIE | T0IE | INTE | RBIE | T0IF | INTF | RBIF |
INTCON = 0xC0; // (1100000) - включить глобальные прерывания, прерывания по периферии
PORTC = 0; // без напряжения
PORTA = 0xF; // (00001111)
// получение адреса
mC_addr = PORTB; // физический адрес устройства
mC_addr &= 0xE0; // выделение физического адреса
SSPEN = 0; SSPIE = 0;
SPI_cntr = 0;
}
void timer1set(){ // установка таймера
// unsigned int tmp = 0xffff - usec/8;
T1CON = 0; // выключить таймер
TMR1IF = 0; // сбросить флаг прерывания
TMR1IE = 1; // разр/запр прерывание
TMR1H = T1H = d_H; //(tmp >> 8) & 0xff;
TMR1L = T1L = d_L; //tmp & 0xff; // установить счетчики
// T1CON: | - | - | T1CPS1 | T1CPS0 | T1OSCEN | T1SYNC | TMR1CS | TMR1ON |
T1CON = 0x31; // (00110001) - включить таймер 1, предделитель на 1/8 (250 кГц)
}
void timer1int(){ // обработка прерываний первого таймера
T1CON = 0;
TMR1H = T1H; TMR1L = T1L;
// send9bit(TEST);
T1CON = 0x31; // снова запускаем таймер
}
void SPI_int(){ // в пассивном режиме принимаемые данные сохраняются в
// буфер, при заполнении буфера он отсылается на ПК
unsigned char i;
TMR1IE = 0;
RCIE = 0;
SPI_buf[SPI_cntr++] = SSPBUF;
if(SPI_cntr == 64){
for(i = 0; i < 64; i++){
TXEN = 1;
TXREG = SPI_buf[i];
while(!TRMT);
}
SPI_cntr = 0;
}
RCIE = 1;
TMR1IE = 1;
BF = 0;
SSPIF = 0;
}
/*
void SPI_int(){
SSPIE = 0;
if(SSPOV == 1) // ошибка переполнения буфера
return;
if(BF == 0) return; // буфер не заполнен
RCIE = 0;
TMR1IE = 0;
TXEN = 1;
TXREG = SSPBUF; // отправляем полученный байт
// while(!TRMT);
RCIE = 1;
TMR1IE = 1;
BF = 0;
SSPIF = 0;
SSPIE = 1;
}
*/
void write_SPI(unsigned char byte){
SSPBUF = byte;
//PORTA &= 0xEF; // -SS = 0 - передаем данные по SPI ведомому
while(!SSPIF); // ждем окончания передачи
// SPI_int();
RCIE = 0;
TMR1IE = 0;
TXEN = 1;
TXREG = SSPBUF; // отправляем полученный байт
RCIE = 1;
TMR1IE = 1;
BF = 0;
SSPIF = 0;
}
void on_interrupt() __interrupt 0{ // обработка прерываний
if(RCIF == 1){ // поступило прерывание от USART
if(get9bit() != OK) return;
switch(cmd){
case INIT: init(); break;
case SET_TIMER: if(getword()) timer1set();
else send9bit(ERR_CMD);
break;
case TMR_SETTINGS: sendword(T1H, T1L); break;
case SPI_send: if(getword()){
write_SPI(d_H);
write_SPI(d_L);}
break;
case SPI_send_one: while(!RCIF); write_SPI(RCREG); break;
case IMP_RISE: CKE = 1; break;//данные передаются по заднему фронту
case IMP_FALL: CKE = 0; break; //данные передаются по переднему фронту
case MID_DATA: SMP = 0; break;
case END_DATA: SMP = 1; break;
case SPI_ON: // SPI
// SSPCON: | WCOL | SSPOV | SSPEN | CKP | SSPM3 | SSPM2 | SSPM1 | SSPM0 |
SSPEN = 1; // (00110010) - выключить SPI, высокий уровень CLK (CKP=1), частота Fosc/64
// SSPSTAT: | SMP | CKE | - | - | - | - | - | BF |
// SSPSTAT = 0; // режим работы SPI: SMP=0 - опрос входа в середине периода
// CKE=0 - данные передаются по заднему фронту
SSPIE = 0; break;
case SPI_OFF: SSPEN = 0; SSPIE = 0; break;
case SPI_ACTIVE: SSPCON = 0x32; TRISC = 0x10; CKE = 0; SSPIE = 0; break; //TRISC = 0xC0;
case SPI_PASSIVE: SSPCON = 0x35; TRISC = 0x18; CKE = 0; SSPIE = 1; break;//TRISC = 255;
case HIG_SPD: SPBRG = 1; break; // 115200
case MID_SPD: SPBRG = 12; break; // 19200
case TEST: T1CON = 0; TMR1IF = 0; break;
}
}
if(TMR1IF == 1) // поступило прерывание от таймера
timer1int(); // обработать прерывание
if(SSPIF == 1) // прерывание от SPI
SPI_int(); // обрабатываем
}
void main(){ // основной цикл
init();
while(1){};
}

3
03-focusing/run Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
sdcc -V -mpic14 -p16f873a main.c
#packihx main.ihx > main.hex

55
03-focusing/signals.h Normal file
View File

@ -0,0 +1,55 @@
/*********** æÕÎËÃÉÉ ***********************/
void send9bit(unsigned char something);
unsigned char get9bit();
void sendword(unsigned char data_H, unsigned char data_L);
unsigned char getword();
unsigned char ten_times_read();
void init();
void timer1set();
void timer1int();
void SPI_int();
/*********** ðÅÒÅÞÅÎØ ËÏÍÁÎÄ ************/
// ÐÏÌÕÞÉÔØ Ó ËÏÍÐØÀÔÅÒÁ ÂÁÊÔ ÄÁÎÎÙÈ É ÚÁÐÉÓÁÔØ × SPI
#define SPI_send_one 1
// ÒÅÖÉÍÙ ÒÁÂÏÔÙ SPI
#define MID_DATA 2
#define END_DATA 3
// ÓËÏÒÏÓÔÉ ÐÏÒÔÁ (ÐÏ ÕÍÏÌÞÁÎÉÀ 9600)
#define MID_SPD 4 // 19200
#define LOW_SPD 5 // 9600
// ÓËÏÒÏÓÔÉ ÏÂßÅËÔÉ×Á (×ÒÅÍÑ, ÞÅÒÅÚ ËÏÔÏÒÏÅ ÂÕÄÅÔ ÐÏÓÌÁÎ ÓÉÇÎÁÌ "ÓÔÏÐ")
#define SPEED1 6 // .3c
#define SPEED2 7 // .05c
#define SPEED3 8 // .01c
// ÎÁÐÒÁ×ÌÅÎÉÑ Ä×ÉÖÅÎÉÑ
#define FORW 9
#define BACK 10
#define INFTY 11
#define ZERO 12
// ÕÚÎÁÔØ ÆÏËÕÓ
#define FOCUS 19
// ÒÕÞÎÏÊ ÒÅÖÉÍ ÕÐÒÁ×ÌÅÎÉÑ
#define HANDS 13
#define TMR_ON 14
#define TMR_OFF 15
#define SPI_ON 16
#define SPI_OFF 17
// ÔÅËÕÝÉÊ ÐÅÒÉÏÄ ÔÁÊÍÅÒÁ
#define TMR_SETTINGS 18
// ÕÓÔÁÎÏ×ÉÔØ ÚÎÁÞÅÎÉÅ ÔÁÊÍÅÒÁ
#define SET_TIMER 26
// ÓÂÒÏÓ
#define INIT 28
#define TEST 29
/************** ïÛÉÂËÉ É ÓÉÇÎÁÌÙ ËÏÎÔÒÏÌÌÅÒÁ ******************/
// ×ÓÅ × ÐÏÒÑÄËÅ
#define OK 22
// ÎÅÔ ÓÔÏÐÏ×ÏÇÏ ÂÉÔÁ
#define NO_STOP_BIT 24
// ÐÅÒÅÐÏÌÎÅÎÉÅ ÒÅÇÉÓÔÒÏ×
#define STACK_OVERFLOW 25
// ÏÛÉÂÏÞËÁÑ ËÏÍÁÎÄÁ
#define ERR_CMD 31
#define TWOBYTE 33 // Ä×ÕÈÂÁÊÔÎÁÑ ÐÏÓÙÌËÁ

BIN
opisanie.pdf Normal file

Binary file not shown.

416
opisanie.tex Normal file
View File

@ -0,0 +1,416 @@
\documentclass[a4paper,12pt]{extarticle}
\usepackage{/home/eddy/ed}
\title{Протокол управления объективами Canon EF}
\author{}
\FDL
\begin{document}
\maketitle
\section{Методика <<взлома>>}
Для работы со SPI--интерфейсом объектива использовался микроконтроллер PIC16F873a,
подключенный к персональному компьютера через интерфейс~RS--232.
Так как кварцевый резонатор контроллера имел частоту~$f_{osc}=4\,$МГц, пришлось ограничиться
довольно медленной скоростью~--- 19.2\,кбит/с.
SPI--интерфейс контроллера был настроен на скорость передачи сообщений~$f_{osc}/64$ (62.5\,кГц).
SPI работал в третьем режиме (высокий уровень CLK, передача информации на падающий
фронт CLK, прием в середине такта -- на возрастающий фронт CLK), регистры:
\begin{verbatim}
SSPCON = 0x32; TRISC = 0xD0; CKE = 0; SSPIE = 1; SMP = 0;
\end{verbatim}
Для анализа сообщений, отсылаемых фотоаппаратом объективу, SPI переключался в пассивный
режим:
\begin{verbatim}
SSPCON = 0x35; TRISC = 0xD8; CKE = 0; SSPIE = 1; SMP = 0;
\end{verbatim}
Однако, поток данных в обычном режиме работы фотоаппарата довольно велик, а скорость RS--232
слишком мала, чтобы контроллер успевал за промежуток между посылками отсылать их на~ПК.
Для буферизации посылок использовался массив данных из~95 элементов. Полученные по
SPI--интерфейсу данные буферизовались контроллером в этот массив, а затем, при заполнении
буфера или по команде пользователя, буфер передавался на~ПК.
Однако, и в этом случае оказалось очень много дополнительных команд, не имеющих отношения
к управлению объективом.
Для подбора команд, вызывающих изменение фокусного расстояния объектива было принято решение
отсылать поочередно объективу ненулевую однобайтную посылку, за которой следовало восемь
нулевых посылок (как оказалось, нулевые посылки используются фотоаппаратом для считывания
информации с объектива).
Методом последовательного перебора были определены основные управляющие команды.
Временн\'ые интервалы между командами могут быть довольно велики. Если объектив должен
ответить на какой-нибудь запрос, а после запроса никаких посылок не отсылалось, объектив
будет ждать очередных посылок, чтобы выдать запрашиваемые данные. Поэтому стоит
каждую команду завершать последовательностью нулевых посылок.
\section{Команды EF~200}
Некоторые команды не требуют от объектива ответа, поэтому их можно не завершать нулями,
однако, некоторые запросы подразумевают достаточно длинный ответ, и требуют до восьми
последующих нулевых сообщений.
Для перехода в ручной режим управления используется команда~{\bf94} или ее эквивалент~{\bf30}
(все команды записываются здесь в десятичной системе).
За этой командой должны следовать одна или две нулевых посылки.
Некоторые команды для изменения фокусного расстояния требуют предварительного
перехода в ручной режим управления.
Для увеличения фокусного расстояния объектива используются следующие команды
(объектив EF~200, для EF~85 скорости не изменяются).
\begin{description}
\item[5] плавное увеличение фокусного расстояния (если за ней не следует других команд).
\item[37] быстрый переход в~$\infty$, за этой посылкой должны следовать две нулевые.
\end{description}
Для уменьшения фокусного расстояния используются команды
\begin{description}
\item[6] плавное перемещение на отметку~2.5\,м.
\item[22] быстрый переход на отметку~2.5\,м. За этой командой следуют две
нулевых. Эта команда имеет полные эквиваленты: {\bf 38, 70, 86}.
\item[68] поворот привода объектива на заданный угол. Угол задается двумя следующими
байтами (short int, старший байт первый). Узнать текущее угловое положение можно командой~192.
\end{description}
Для останова используется команда~{\bf4}. Таким образом, манипулируя командами~{\bf5/6}
и~{\bf4} можно добиться постепенного изменения фокусного расстояния. Помимо ожидания
для изменения фокусного расстояния на нужную величину после команд~{\bf5} или~{\bf6}
можно отсылать нулевые посылки.
Кроме этой команды есть следующие информационные команды, чье предназначение
пока не расшифровано (для EF~200, EF~85 см. в сводной таблице):
\begin{description}
\item[31] имеет двухбайтный ответ, оба байта содержали комбинации из единицы и тройки.
\item[79] имеет трехбайтный ответ, являющийся комбинацией единиц и нулей.
\item[95] ведет себя аналогично~{\bf31}.
\item[111] имеет однобайтный ответ~--- единицу.
\item[120] имеет однобайтный ответ~--- восьмерку.
\item[239] имеет однобайтный ответ~--- 224 или 225.
\item[247] однобайтный ответ 240.
\item[250] однобайтный ответ 130 или~128.
\item[251] однобайтный ответ 248.
\item[252] однобайтный ответ (разные числа).
\item[128] ответ из семи или восьми байт, возможно~--- запрос статуса объектива.
\end{description}
Было обнаружено еще несколько подозрительных запросов, ответом на которые был один
байт с постоянным значением 128 или 192 (при любых манипуляциях с объективом).
\subsection{Небольшое дополнение}
команды (EF~85):
10 --- {\bf инициализация}, без этой команды EF85 не работает.
194 --- узнать расстояние фокусировки (в метрах). Ответ --- четыре байта, первые два --- текущее расстояние,
вторые два --- предыдущее положение. В паре чисел первое умножаем на 2.5\,м и складываем со вторым (в
сантиметрах).
192 --- узнать угловое положение лимба (от некоторого условного нуля). Ответ --- два байта (short int,
старший байт первый).
Управление диафрагмой: два байта число 18 (собственно команда) и байт --- на сколько изменить
текущее состояние диафрагмы (signed char) положительное число для закрытия, отрицательное -- открыть.
При небольшом изменении состояния диафрагмы каждая команда 2 или 3 повторяет это изменение.
Плюс объектив входит в режим пошаговой подстройки фокусировки. Выход из этого режима --- команда 8
(или ее эквиваленты 11, 27, 43, 75).
\section{Сводный перечень команд для EF~85}
Расшифровка обозначений столбцов:
\begin{description}
\item[cmd] команда;
\item[N] минимальная длина ответа в байтах;
\item[ans] ответ (в случае изменяющегося ответа --- диапазон);
\item[desc] краткое описание команды.
\end{description}
Команды, чье предназначение не выявлено, имеют пустое поле описания.
Если действие команды аналогично другой команде, в описании пишется эта команда.
Под F подразумевается значение расстояния до объекта, чье изображение
четко сфокусировано. Буква <<о>> в описании означает, что назначение команды
неизвестно, но она приводит к отключению ручного управления~F.
Если в ответах встречаются записи через слеш, значит, в разные моменты времени
появляется то одна, то другая из приведенных команд без видимой зависимости.
\begin{longtable}[c]{||c||c|c| p{0.5\textwidth}||}
\caption{Сводка команд}\\
\hline\hline
\bf cmd &\bf N &\bf ans &\bf desc\\
\hline
\hline
\endfirsthead
\caption{(продолжение).}\\
\hline
\bf cmd &\bf N &\bf ans &\bf desc\\
\hline
\hline
\endhead
\hline
\endfoot
0 & 1 & 0 & <<пустышка>> для получения ответа от объектива\\
1 & 1 & 1 & \\
\bf 2 & 1 & 2 & повтор предыдущего изменения величины диафрагмы, режим коротких шагов перемещения\\
3 & 1 & 3 & 2\\
\bf 4 & 1 & 4 & остановить изменение F\\
\bf 5 & 1 & 5 & увеличить F\\
\bf 6 & 1 & 6 & уменьшить F\\
7 & 1 & 7 & о\\
\bf 8 & 2 & 255/0, 170 & отмена действия команды 2\\
9 & 1 & 9 & о\\
\bf 10 & 1 & 10 & инициализация объектива EF85 (без этой команды он не выходит из спящего режима)\\
11 & 1 & 11 & 8\\
12 & 1 & 12 & \\
13 & 1 & 13 & \\
14 & 1 & 14 & \\
15 & 1 & 15 & \\
16 & 2 & 16, 16 & \\
17 & 2 & 17, 17 & \\
\bf 18 & 2 & 18, 18 & управление затвором, вторым байтом (signed char) отсылается степень изменения
диаметра отверстия (положительным значениям соответствует уменьшение диаметра)\\
19 & 2 & 19, 19 & 18\\
20 & 2 & 20, 20 & 4\\
21 & 2 & 21, 21 & 5\\
22 & 2 & 22, 22 & 6\\
23 & 2 & 23, 23 & о\\
24 & 3 & 24, 0/255, 170 & \\
25 & 2 & 25, 25 & о\\
26 & 2 & 26, 26 & \\
27 & 2 & 27, 27 & 8\\
28 & 2 & 28, 28 & \\
29 & 2 & 29, 29 & \\
30 & 2 & 30, 30 & (для EF~200 эквивалент команды 94)\\
31 & 2 & 31, 31 & \\
32 & 2 & 32, 32 & \\
33 & 2 & 33, 33 & \\
34 & 2 & 34, 34 & \\
35 & 2 & 35, 35 & \\
36 & 2 & 36, 36 & 4\\
37 & 2 & 37, 37 & 5\\
38 & 2 & 38, 38 & 6\\
39 & 2 & 39, 39 & о\\
40 & 3 & 40, 255/0, 170 & \\
41 & 2 & 41, 41 & о\\
42 & 2 & 42, 42 & \\
43 & 2 & 43, 43 & 8\\
44 & 2 & 44, 44 & \\
45 & 2 & 45, 45 & \\
46 & 2 & 46, 46 & \\
47 & 2 & 47, 47 & \\
48 & 1 & 48 & \\
49 & 1 & 49 & \\
50 & 1 & 50 & \\
51 & 1 & 51 & \\
52 & 1 & 52 & \\
53 & 1 & 53 & \\
54 & 1 & 54 & \\
55 & 1 & 55 & \\
56 & 1 & 56 & \\
57 & 1 & 57 & \\
58 & 1 & 58 & \\
59 & 1 & 59 & \\
60 & 1 & 60 & \\
61 & 1 & 61 & \\
62 & 1 & 62 & \\
63 & 1 & 63 & \\
64 & 3 & 64, 64, 64 & \\
65 & 3 & 65, 65, 65 & \\
66 & 3 & 66, 66, 66 & \\
67 & 3 & 67, 67, 67 & \\
68 & 3 & 68, 68, 68 & переместить объектив на заданное кол-во шагов (2 байта, int16, hi-low)\\
69 & 3 & 69, 69, 69 & 5\\
70 & 3 & 70, 70, 70 & 6\\
71 & 3 & 71, 71, 71 & о\\
72 & 4 & 72, 72, 255/0, 170 & \\
73 & 3 & 73, 73, 73 & о\\
74 & 3 & 74, 74, 170 & \\
75 & 3 & 75, 75, 75 & 8\\
76 & 3 & 76, 76, 76 & \\
77 & 3 & 77, 77, 77 & \\
78 & 3 & 78, 78, 78 & (для EF~200 эквивалент команды 94)\\
79 & 3 & 79, 79, 79 & \\
80 & 2 & 80, 80 & \\
81 & 2 & 81, 81 & \\
82 & 2 & 82, 82 & \\
83 & 2 & 83, 83 & \\
84 & 2 & 84, 84 & 4\\
85 & 2 & 85, 85 & 5\\
86 & 2 & 86, 86 & 6\\
87 & 2 & 87, 87 & о\\
88 & 3 & 88, 255/0, 170 & \\
89 & 2 & 89, 89 & о\\
90 & 2 & 90, 170 & \\
91 & 2 & 91, 91 & \\
92 & 2 & 92, 92 & \\
93 & 2 & 93, 93 & \\
\bf 94 & 2 & 94, 94 & включить ручное управление F\\
95 & 2 & 95, 95 & \\
96 & 1 & 96 & \\
97 & 1 & 97 & \\
98 & 1 & 98 & \\
99 & 1 & 99 & \\
100 & 1 & 100 & \\
101 & 1 & 101 & \\
102 & 1 & 102 & \\
103 & 1 & 103 & \\
104 & 1 & 240 & \\
105 & 1 & 35 & \\
106 & 2 & 35, 253 & \\
107 & 2 & 232, 103 $\div$ 215, 185& \\
108 & 2 & 108, 236 $\div$ 112, 0 & \\
109 & 2 & 220, 80 $\div$ 103, 56 & \\
110 & 2 & 112, 108 $\div$ 113, 62 & \\
111 & 1 & 0/16 & \\
112 & 1 & 112 & \\
113 & 1 & 113 & \\
114 & 1 & 114 & \\
115 & 1 & 115 & \\
116 & 1 & 116 & \\
117 & 1 & 117 & \\
118 & 1 & 118 & \\
119 & 1 & 119 & \\
120 & 1 & 120 & \\
121 & 1 & 121 & \\
122 & 1 & 122 & \\
123 & 1 & 123 & \\
124 & 1 & 124 & \\
125 & 1 & 125 & \\
126 & 1 & 126 & \\
127 & 1 & 127 & \\
128 & 6 & 129, 239, 0, 85, 0, 85 & модель объектива ?\\
129 & 1 & 129 & \\
130 & 1 & 130 & \\
131 & 1 & 131 & \\
132 & 1 & 132 & \\
133 & 1 & 133 & \\
134 & 1 & 134 & \\
135 & 1 & 135 & \\
136 & 1 & 136 & \\
137 & 1 & 137 & \\
138 & 1 & 138 & \\
139 & 1 & 139 & \\
140 & 1 & 140 & \\
141 & 1 & 141 & \\
142 & 1 & 142 & \\
143 & 1 & 143 & \\
\bf 144 & 2 & 0/32, $X$ & старший бит $X$ --- значение переключателя <<AF/MF>> (нулю
соответствует AF)\\
145 & 1 & 145 & \\
146 & 1 & 146 & \\
147 & 1 & 147 & \\
148 & 1 & 255 & \\
149 & 1 & 149 & \\
150 & 1 & 150 & \\
151 & 1 & 151 & \\
152 & 1 & 152 & \\
153 & 1 & 153 & \\
154 & 1 & 154 & \\
155 & 1 & 155 & \\
156 & 1 & 156 & \\
157 & 1 & 157 & \\
158 & 1 & 158 & \\
159 & 1 & 159 & \\
160 & 2 & 0, 85 & \\
161 & 1 & 161 & \\
162 & 1 & 162 & \\
163 & 1 & 163 & \\
164 & 1 & 164 & \\
165 & 1 & 165 & \\
166 & 1 & 166 & \\
167 & 1 & 167 & \\
168 & 1 & 168 & \\
169 & 1 & 169 & \\
170 & 1 & 170 & \\
171 & 1 & 171 & \\
172 & 1 & 172 & \\
173 & 1 & 173 & \\
174 & 1 & 174 & \\
175 & 1 & 175 & \\
176 & 3 & 13, 13, 72 & \\
177 & 2 & 91, 92 & \\
178 & 3 & 96, 2, 71 & \\
179 & 2 & 104, 92 & \\
180 & 1 & 180 & \\
181 & 1 & 181 & \\
182 & 1 & 182 & \\
183 & 1 & 183 & \\
184 & 1 & 184 & \\
185 & 1 & 185 & \\
186 & 1 & 186 & \\
187 & 1 & 187 & \\
188 & 1 & 188 & \\
189 & 1 & 189 & \\
190 & 1 & 190 & \\
191 & 1 & 191 & \\
\bf 192 & 2 & short int & угловое положение лимба F, первый байт --- старший, нуль относительный\\
193 & 1 & 193 & \\
\bf 194 & 4 & $X_1, X_2, Y_1, Y_2$ & значение F в метрах; $X$~-- текущее F, $Y$~-- предыдущее F;
$F(\text{метр}) = 2.5\cdot X_1+X_2/100$ \\
195 & 1 & 195 & \\
196 & 2 & 0, 9 $\div$ 10, 1 & \\
197 & 1 & 197 & \\
198 & 1 & 198 & \\
199 & 1 & 199 & \\
200 & 1 & 200 & \\
201 & 1 & 201 & \\
202 & 1 & 202 & \\
203 & 1 & 203 & \\
204 & 1 & 204 & \\
205 & 1 & 205 & \\
206 & 1 & 206 & \\
207 & 1 & 207 & \\
208 & 1 & 208 & \\
209 & 1 & 209 & \\
210 & 1 & 210 & \\
211 & 1 & 211 & \\
212 & 1 & 212 & \\
213 & 1 & 213 & \\
214 & 1 & 214 & \\
215 & 1 & 215 & \\
216 & 1 & 216 & \\
217 & 1 & 217 & \\
218 & 1 & 218 & \\
219 & 1 & 219 & \\
220 & 1 & 220 & \\
221 & 1 & 221 & \\
222 & 1 & 222 & \\
223 & 1 & 223 & \\
224 & 2 & 61, 186 $\div$ 61, 172 & \\
225 & 1 & 225 & \\
226 & 1 & 226 & \\
227 & 1 & 227 & \\
228 & 2 & 30, 84 & \\
229 & 1 & 229 & \\
230 & 1 & 230 & \\
231 & 1 & 231 & \\
232 & 2 & 163, 203 $\div$ 162, 105 & \\
233 & 1 & 233 & \\
234 & 2 & 157, 166 $\div$ 163, 205 & \\
235 & 1 & 235 & \\
236 & 1 & 236 & \\
237 & 1 & 237 & \\
238 & 1 & 238 & \\
239 & 1 & 239 & \\
240 & 1 & 10 & \\
241 & 1 & 241 & \\
242 & 1 & 242 & \\
243 & 1 & 243 & \\
244 & 1 & 244 & \\
245 & 1 & 245 & \\
246 & 1 & 246 & \\
247 & 1 & 247 & \\
248 & 1 & 185 $\div$ 188 & \\
249 & 1 & 3 $\div$ 7 & \\
250 & 1 & 192 $\div$ 194 & \\
251 & 1 & 251 & \\
252 & 1 & 198 $\div$ 201 & \\
253 & 1 & 0 & \\
254 & 1 & 207 $\div$ 208 & \\
255 & 1 & 255 & \\
\hline\hline
\end{longtable}
Команды можно условно разделить на две половины: если старший бит команды равен нулю, объектив
выполняет определенные действия. Когда старший бит команды равен единицы, у объектива запрашиваются
определенные данные.
Команды изменения F аналогичны (за исключением разрядности ответа). Младшие 4~байта принимают
значения 0100 (стоп), 0101 (F$+$), 0110 (F$-$), самый старший бит --- обязательно 0.
Биты $4\div6$ принимают любые значения, кроме 110, 011 и 111.
\end{document}

BIN
pins.pdf Normal file

Binary file not shown.