mirror of
https://github.com/eddyem/canon-lens.git
synced 2025-12-06 10:35:15 +03:00
275 lines
7.7 KiB
C
275 lines
7.7 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)
|
||
|
||
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){};
|
||
}
|
||
|