mirror of
https://github.com/eddyem/canon-lens.git
synced 2025-12-06 02:25:15 +03:00
228 lines
6.8 KiB
C
228 lines
6.8 KiB
C
#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){};
|
||
}
|
||
|