mirror of
https://github.com/eddyem/canon-lens.git
synced 2025-12-06 02:25:15 +03:00
init on github
This commit is contained in:
parent
506e00e282
commit
6443a7dbf4
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
*~
|
||||
*.bak
|
||||
*.bck
|
||||
*.o
|
||||
.hg*
|
||||
.dropbox.attr
|
||||
389
02-TEST/Frontend/FE.c
Normal file
389
02-TEST/Frontend/FE.c
Normal 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
275
02-TEST/Frontend/main.c
Normal 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); // ÅÓÌÉ ÅÓÔØ ÓÉÇÎÁÌ Ó ËÏÎÔÒÏÌÌÅÒÁ - ÏÂÒÁÂÁÔÙ×ÁÅÍ
|
||||
}
|
||||
}
|
||||
|
||||
39
02-TEST/Frontend/signals.h
Normal file
39
02-TEST/Frontend/signals.h
Normal 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
274
02-TEST/main.c
Normal 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
242
02-TEST/main1.c
Normal 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
3
02-TEST/run
Executable 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
50
02-TEST/signals.h
Normal 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
413
03-focusing/Frontend/FE.c
Normal 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); // ÅÓÌÉ ÅÓÔØ ÓÉÇÎÁÌ Ó ËÏÎÔÒÏÌÌÅÒÁ - ÏÂÒÁÂÁÔÙ×ÁÅÍ
|
||||
|
||||
}
|
||||
}
|
||||
18
03-focusing/Frontend/Makefile
Normal file
18
03-focusing/Frontend/Makefile
Normal 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 ...
|
||||
44
03-focusing/Frontend/signals.h
Normal file
44
03-focusing/Frontend/signals.h
Normal 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
227
03-focusing/main.c
Normal 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
242
03-focusing/main1.c
Normal 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
3
03-focusing/run
Executable 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
55
03-focusing/signals.h
Normal 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
BIN
opisanie.pdf
Normal file
Binary file not shown.
416
opisanie.tex
Normal file
416
opisanie.tex
Normal 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}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user