
;=======================================================================
; Fichier : pilote_servo.asm
; Titre: BASE DE PROGRAMMATION
; Version: 1.0
; Auteur: Silicium628
; Date: 26/06/2007				     
;=======================================================================
									
;DECLENCHEUR manuel et automatique pour appareil photo numerique
;en mode manuel, permet de declencher sans toucher l'appareil afin d'eviter toutes vibrations (appareil utilise sur un petit telescope)
;en mode automatique, permet de realiser des films tres fortement acceleres en recreant un .avi (ou gif anime etc...) a partir des images
;(formation et deplacement des nuages, mouvement des vegetaux, pousse d'une fleur, deplacement de l'ombre du soleil etc...)
;						
;=======================================================================
;PRINCIPE
;actionne un servo-moteur (tels que ceux utilises en aeromodelisme ou en robotique) pour appuyer DOUCEMENT sur le declencheur de l'APN
;soit;
;-au coup par coup commande par un bouton poussoir
;-soit automatiquement avec une periode (10s, 30s, 1mn , 5mn, 10mn) selectionnable par 3 pontets

;=======================================================================


;LISTE DES PARTIES:

;Declaration des Variables
;MACROS
;Declaration des Vecteurs d'interruptions
;Routines de traitement des interruptions
;Programme de RESET
;initialisation des ports
;PROGRAMME PRINCIPAL
;ROUTINES


;=======================================================================


.include "m8def.inc"	; nom du fichiers de references des registres (ATMEGA 8)


;------------------------------------------------------------------------
;Declaration des Variables		                 	
;------------------------------------------------------------------------

.def T0 = r4
.def T1 = r5
.def compte1 = r6
.def postdiv = r7
.def periode1 = r8

.def SAUVREG = r15	; registre de sauvegarde de SREG

.def F1 = r16	;"mesflags1"
;F1[0]= declenchement auto INTERDIT
;F1[1]= decrementation compte1
;F1[2]=
;F1[3]= 
;F1[4]= 


.def a = r17
.def AA = r18
.def BB = r19

.def AL = r18
.def AH = r19
.def BL = r20
.def BH = r21



;r26,27 reserve comme registre d'adresse d'indexation (X)


;r30,31 reserve comme registre d'adresse d'indexation (Z) permet la lecture en memoire de programme

.DSEG
	
	nombre1:		.BYTE 3	;nombre code sur 3 octets (binaire) 0...16 777 216
	nombre2:		.BYTE 3	;""

	dividende: 	.BYTE 3
	numerateur:	.BYTE 1
	denominateur:	.BYTE 1
 

;------------------------------------------------------------------------
;MACROS
;------------------------------------------------------------------------
	
;cette macro fait @0(variable en RAM, 24bits)  := @1 valeur(24bits) pasee en parametre
.MACRO	Mset24
	ldi	a,BYTE1(@1)
	sts	@0+0,a
	ldi	a,BYTE2(@1)
	sts	@0+1,a
	ldi	a,BYTE3(@1)
	sts	@0+2,a

.ENDMACRO	

;------------------------------------------------------------------------
;cette macro fait @0(variable en RAM, 24bits)  := r20,21,22
.MACRO	Mstore24
	sts	@0+0,r20
	sts	@0+1,r21
	sts	@0+2,r22

.ENDMACRO	

;------------------------------------------------------------------------
;cette macro fait 3 registres successifs  := @0 (variable en RAM, 24bits, pasee en parametre)
.MACRO	Mload24
	lds	r20,@0+0
	lds	r21,@0+1
	lds	r22,@0+2


.ENDMACRO	


;------------------------------------------------------------------------
;Declaration des Vecteurs d'interruptions
;------------------------------------------------------------------------

.CSEG
.ORG 0x0000			;debut zone memoire programme
	rjmp	RESET		;RESET
	rjmp	EXT_INT0		;Interruption externe INT0
	rjmp 	EXT_INT1		;Interruption externe INT1
	rjmp 	TIM2_COMP		;Interrution comparaison reussie TIMER2
	rjmp 	TIM2_OVF		;Interrution debordement compteur TIMER2  
	rjmp 	TIM1_CAPT		;Interrution entree capture TIMER1
	rjmp	TIM1_COMPA	;Interrution comparateurA TIMER1
	rjmp 	TIM1_COMPB	;Interrution comparateurB TIMER1
	rjmp	TIM1_OVF		;Interrution debordement compteur TIMER1 
	rjmp 	TIM0_OVF		;Interrution debordement compteur TIMER0 
	rjmp 	SPI_STC		;Interrution transmissions SPI terminee
	rjmp 	UART_RXC		;Interrution reception UART termine RX
	rjmp 	UART_DRE		;Interrution UART vide 
	rjmp 	UART_TXC		;Interrution emission UART termine TX
	rjmp 	ADC_ok		;Interrution Conversion A/D terminee
	rjmp 	EE_RDY		;Interrution EEPROM prete
	rjmp 	ANA_COMP		;Interrution comparaison analogique effectuee
	
;------------------------------------------------------------------------
;Routines de traitement des interruptions
;------------------------------------------------------------------------
			
EXT_INT0:		reti
;------------------------------------------------------------------------
EXT_INT1:		reti
;------------------------------------------------------------------------
TIM2_COMP:	reti
;------------------------------------------------------------------------
TIM2_OVF:		reti
;------------------------------------------------------------------------
TIM1_CAPT:	reti
;------------------------------------------------------------------------
;genere duree implulsion de voie PPM (1ms)
;  OBSOLETE :declencheur automatique a intervales reguliers
TIM1_COMPA:	in	sauvreg,sreg
		push 	sauvreg
		push	a

		cbi	portb,0		;fin d'impulsion PPM
		

		pop	a
		pop 	sauvreg
		out 	sreg,sauvreg 

		reti
;------------------------------------------------------------------------
TIM1_COMPB:	reti
;------------------------------------------------------------------------

;------------------------------------------------------------------------
TIM1_OVF:		reti	
;------------------------------------------------------------------------
;Genere la periode de recurence du signal PPM (16ms), la periode de declenchement auto, et bride la nervosite du servo
TIM0_OVF:		in	sauvreg,sreg
		push 	sauvreg
		push	a

		bst	F1,1
		brtc	suite3
		dec	compte1		;a chaque decrementation de compte1 le servo tounera d'un angle dx
		;la frequence a laquelle on passe ici determine donc la nervosite du servo (et la bride volontairement)

suite3:		sbrc	F1,0		;declenchement auto interdit?
		rjmp	suite4		;oui

		dec	T0		
		brne	suite4
		ldi	a,203		;periode de declenchement auto, etage1
		mov	T0,a
		dec	T1		
		brne	suite4
		mov	T1,periode1	;periode de declenchement auto, etage2 (16e6 Hz/1024/256/203/3=0.10022Hz)
		ldi	a,80		;recharge de la duree de declenchement (provoque 1 declenchement auto)
		mov	compte1,a	


suite4:		ldi	a,0
		out	TCNT1H,a	;RAZ Timer1 qui sert a generer la duree d'impulsion
		out	TCNT1L,a
		sbi	portb,0


fin_t0:		pop	a
		pop 	sauvreg
		out 	sreg,sauvreg 
		reti
;------------------------------------------------------------------------
SPI_STC:		reti
;------------------------------------------------------------------------
UART_RXC:		reti
;------------------------------------------------------------------------
UART_DRE:   	reti
;------------------------------------------------------------------------
EE_RDY:		reti
;------------------------------------------------------------------------
ANA_COMP:		reti
;------------------------------------------------------------------------
ADC_ok:		reti
;------------------------------------------------------------------------
UART_TXC:		reti
;------------------------------------------------------------------------
UART_RXC1:	reti
;------------------------------------------------------------------------


;------------------------------------------------------------------------
;Programme de RESET
;------------------------------------------------------------------------
	
	nop
texte:	.DB	'P','I','L','O','T','E'	;Pour reperer facilement le bon .ASM dans PonyProg!
;(evite de grosses meprises lorsque je travaille sur plusieurs softs en meme temps...)
 
RESET:	ldi	a,low(RAMEND)
	out	SPL,a		; Initialisation de la pile a   
	ldi	a,high(RAMEND)	; l'adresse haute de la SRAM
	out	SPH,a	
;------------------------------------------------------------------------
;initialisation des ports
	ldi 	a,0b11111111	;toutes en sorties ; PB0 =  sortie signal PPM
	out 	ddrb,a

	ldi 	a,0b11110000	;PD0,1,2,3 en entree
	out 	ddrd,a
	ldi	a,0b11111111	;R de tirage
	out 	portd,a


	ldi 	a,0b11111111	;toutes en sorties	
	out 	ddrc,a
	clr 	a
	out 	portc,a		;sorties = 0

	cbi	portb,1	;RAZ signal de depassement de vitesse
;------------------------------------------------------------------------
;wachtdog	
;	wdr			
;	ldi 	a,0b00001111	; wachtdog enable; delai = 2s (voir p:82)
;	out 	wdtcr,a

	wdr
	ldi	a,0b00011111
	out 	wdtcr,a
	ldi	a,0b00010111
	out 	wdtcr,a		; disable le wachtdog. (voir p:83)


;------------------------------------------------------------------------
;TIMSK
;Timer Interrupt Mask; voir pdf p:70
;bit7 (OCIE2)
;bit6 (TOIE2)
;bit5 (TICIE1) Timer/Counter1, Input Capture Interrupt Enable
;bit4 (OCIE1A) Timer/Counter1, Output Compare A Match Interrupt Enable
;bit3 (OCIE1B) Timer/Counter1, Output Compare B Match Interrupt Enable
;bit2 (TOIE1)  Timer/Counter1, Overflow Interrupt Enable
;bit1 inutilise
;bit0 (TOIE0) Timer/Counter0 Overflow Interrupt Enable - voir Tavernier p:96

		;   76543210
	ldi	a,0b00010001	;Timer0 Overflow Interrupt Enable	
	out	TIMSK,a
;------------------------------------------------------------------------
;TCCR0	voir Tavernier p:87 et pdf p:70
;definit le mode de fonctionnement du Timer0
;bits7a3 = non utilise
;bits2,1,0 = taux de predivision de l'horloge 
;16MHz/1024 = 15625 Hz

		;   76543210
	ldi	a,0b00000101	;1/1024
	out	TCCR0,a
;------------------------------------------------------------------------
;TCCR1A
;definit le mode de fonctionnement du Timer1
;voir Tavernier p:93

;bit7 (COM1A1)	;definit le comportement de la sortie OC1A
;bit6 (COM1A0)
;bit5 (COM1B0)
;bit4 (COM1B1)
;bit3,2 NC
;bit1 (PWM11)
;bit0 (PWM10)

		;   76543210
	ldi	a,0b00000000	;voir tableau Tavernier p:93
	out	TCCR1A,a
;------------------------------------------------------------------------
;TCCR1B
;definit le mode de fonctionnement  du Timer1
;voir Tavernier p:94-95 ;et p:81-82 du datasheet.pdf

;bit7 (ICNC1): enable/disable reducteur de bruit
;bit6 (ICES1)=1: transfert du registre de comptage TCNT1 dans le registre de capture ICR1 sur front montant du pin ICP
;bit5 : inutilise
;bit4 : inutilise
;bit3 (WGM12 ou CTC1): raz registre de comptage (TCNT1) apres comparaison
;bits2,1,0: taux de predivision applique a l'horloge systeme. voir Tavernier p:95 et pdf p:98

		;   76543210
	ldi	a,0b00000010	;clk/8 pour le Timer1;
	out	TCCR1B,a
;------------------------------------------------------------------------
;MCUCR 
;voir datasheet p:31
;bits[3,2] -> ISC11 ISC10 Description
;0 0 The low level of INT1 generates an interrupt request.
;0 1 Any logical change on INT1 generates an interrupt request.
;1 0 The falling edge   of INT1 generates an interrupt request.
;1 1 The rising  edge   of INT1 generates an interrupt request.

;bits[1,0] -> ISC01 ISC00 Description
;0 0 The low level of INT0 generates an interrupt request.
;0 1 Any logical change on INT0 generates an interrupt request.
;1 0 The falling edge   of INT0 generates an interrupt request.
;1 1 The rising  edge   of INT0 generates an interrupt request.

		;   76543210
	ldi	a,0b00000000
	out	MCUCR,a		;voir p:64 du datasheet.pdf et Tavernier p:30

;------------------------------------------------------------------------
;GICR (GENERAL INTERRUPT CONTROL REGISTER)
;page 47 et 65 du datasheet
;bit 7 = INT1 enable
;bit 6 = INT0 enable

		;   76543210
	ldi	a,0b00000000
	out	GICR,a

;------------------------------------------------------------------------
;chargement du registre de comparaison (A) du Timer1
;	cli

	ldi	AL,LOW(2000)	
	ldi	AH,HIGH(2000)	
	out 	OCR1AH,AH	
	out 	OCR1AL,AL

;chargement du registre de comparaison (B) du Timer1
;	ldi	r20,LOW(10)
;	ldi	r21,HIGH(10)
;	out 	OCR1BH,r21	
;	out 	OCR1BL,r20
;


;------------------------------------------------------------------------
;zone de tests de procedures

	

;------------------------------------------------------------------------
;PROGRAMME PRINCIPAL
;------------------------------------------------------------------------


initvar:	ldi	F1,0b00000001	;declenchement auto interdit


	ldi	a,160
	mov	r0,a
	ldi	a,12
	mov	r1,a

	ldi	a,0
	mov	compte1,a

	ldi	a,255
	mov	T0,a
	ldi	a,1
	mov	periode1,a
	mov	T1,a

	sei	;Sets the Global Interrupt flag (I) in SREG (status register)

;------------------------------------------------------------------------
;BOUCLE PRINCIPALE

bcl_0:	in	a,pind		;lecture de la configuration des trois pontets determinant la periode de declenchement auto.
	andi	a,0b00000111	;masque
	cpi	a,0
	breq	suite00		;pas de declenchement auto
		
	cpi	a,1
	breq	t10s
	cpi	a,2
	breq	t30s
	cpi	a,3
	breq	t1mn
	cpi	a,4
	breq	t5mn
	cpi	a,5
	breq	t10mn

;declenchement auto, periode 10s
t10s:	ldi	a,3
	mov	periode1,a
	rjmp	finchar

;declenchement auto, periode 30s
t30s:	ldi	a,9
	mov	periode1,a
	rjmp	finchar

;declenchement auto, periode 1mn
t1mn:	ldi	a,18
	mov	periode1,a
	rjmp	finchar

;declenchement auto, periode 5mn
t5mn:	ldi	a,90
	mov	periode1,a
	rjmp	finchar

;declenchement auto, periode 10mn
t10mn:	ldi	a,180
	mov	periode1,a
	rjmp	finchar

finchar:	andi	F1,0b11111110	;declenchement auto autorise
	rjmp	suite01

;----------------------------------------

suite00:	ori	F1,0b00000001	;interdit declenchement auto


suite01:	mov	a,compte1		;si compte1<>0  -> on declenche (lentement pour eviter les vibrations)
	cpi	a,0
	breq	suite02

	ori	F1,0b00000010	;demande de decrementation de compte1
	rjmp	dur1


suite02:	andi	F1,0b11111101	;decrementation de compte1 interdite	
	sbic	pind,3		;declenchement manuel - test bouton poussoir sur pind,0
	rjmp	dur0		;bouton relache

	ldi	a,80		;bouton appuye, on recharge la duree de declenchement (la valeur 80 determine cette duree)
	mov	compte1,a	
	rjmp	dur1

;les valeurs de BH,L suivantes determinent les positions extremes de la course du servo ; (a adapter au cas par cas suivant le servo utilise)
dur0:	ldi	BL,LOW(1600)	;valeur de la duree mini de l'impulsion PPM
	ldi	BH,HIGH(1600)	
	rjmp	go		;on va faire tendre lentement 'duree' vers 'but'	

dur1:	ldi	BL,LOW(2200)	;valeur de la duree maxi de l'impulsion PPM
	ldi	BH,HIGH(2200)
	rjmp	go	

go:	rcall	cp16	;(compare AH,L a BH,L) 
	breq	fin_bcl0
	brsh	plus
	brlo	moins

plus:	rcall	dec16		;rotation LENTE du servo sens +
	rjmp	outVal

moins:	rcall	inc16	
	rjmp	outVal

outVal:	out 	OCR1AH,AH
	out 	OCR1AL,AL
	rcall	tp1ms


fin_bcl0:	rjmp	bcl_0

;------------------------------------------------------------------------
;ROUTINES
;------------------------------------------------------------------------




;------------------------------------------------------------------------
;.include "EEPROM.inc"
;------------------------------------------------------------------------
;.include "affi_LCD.inc"
;------------------------------------------------------------------------
.include "tempos1_16MHz.inc"
;------------------------------------------------------------------------
.include "math1.inc"
;------------------------------------------------------------------------

	



