
.include "m328pdef.inc"
.cseg
.def contador=r17;
.def cont=r18;
  
	.org 0

main:
	cbi		ddrd,0	;PD0 entrada para el pulsador
	sbi	 	ddrb,3 
	sbi		ddrb,4  ;PB3 y PB4 son salidas para dato y clock
	
	;como clk es de 2Mhz fijamos OCR1A al decimal 80  
	;el contador alcanzará ese valor a los 40us 
	ldi		r16,0
	sts		ocr1ah,r16
	ldi		r16,80
	sts		ocr1al,r16	;
	clr		r16
	sts		tcnt1h,r16
	sts		tcnt1l,r16

	ldi		r16,2
	sts		tifr1,r16	 ;Puesta a 0 del flag de OCF1A


pulsador: sbic	pind,0
	      rjmp	pulsador  ; cuando se acciona el pulsador sigo adelante
		  ldi	r16,0x5a
		  sts 	DATO,r16
		  call	transmiteDATO_ps2     ;tras pulsar debemos transmitir 0x5a
		  
liberapulsador: sbis	pind,0
	            rjmp	liberapulsador
				; tras liberar el pulsador debemos transmitir 0xf0 y 0x5a
				ldi		r16,0xf0
				sts		DATO,r16
				call	transmiteDATO_ps2
	
				ldi		r16,0x5a
				sts		DATO,r16
				call	transmiteDATO_ps2   
				rjmp	pulsador	//volvemos a ponernos en disposición de 
									;recibir una nueva pulsación//



transmiteDATO_ps2:  rcall	calcula_bitdeparidad_impar  ; esta rutina me devolverá el bit de paridad 
														; de DATO en la dirección de memoria PARIDAD
					lds		r17,DATO
					cbi		portb,3	;bit de start  //transmitimos datos segun protocolo comenzando por este bit//
					rcall	clock
					ldi 	r16,8  ;contador de bits
bucletransmision:	lsr		r17
					brcs	bit_es_1
					cbi		portb,3 ;Dato a 0
					rjmp    continua
		bit_es_1:	sbi		portb,3 ;Dato a 1
		continua:	rcall	clock
					dec		r16
					brne	bucletransmision
	
					lds		r16,PARIDAD
					cpi		r16,0
					brne	transmite1
					cbi		portb,3; Paridad a 0
					rcall	clock
					rjmp	fintransmision
		transmite1: sbi		portb,3; Paridad a 1
					rcall	clock
	fintransmision:	sbi		portb,3;Bit de stop
					rcall	clock
					ret	




calcula_bitdeparidad_impar: lds		r0,DATO
							ldi		r16,8   ; en r16 contaré los bits de DATOS a analizar
							clr		r17   ; en r17 contaré los unos que hay en DATO
				analizabit:	lsr		r0
							brcc	sigue
							inc		r17
					sigue:	dec		r16
							brne	analizabit  ; sigo analizando hasta acabar con los 8 bits
							ror 	r17  ; si el bit de carry tras la rotación es 1, el número de unos era impar
							brcc   devuelve1 
							clr 	r16
							sts		PARIDAD,r16
							ret
				devuelve1:	ldi  	r16,1
							sts		PARIDAD,r16
							ret	




clock: 			push 	r16
				ldi		r16, 0b00001001
				sts		tccr1b,r16	; el contador cuenta con f = 2Mhz hasta el límite VMAX.
				sbi		portb,4	; pongo a 1 CLOCK

esperovmax1:	in		r16,tifr1 ;No genero interrupción sino que pregunto por el bit de fin de ciclo
				sbrs	r16,1
				rjmp	esperovmax1
	
				cbi		portb,4	; pongo a 0 CLOCK
				out		tifr1,r16	;Puesta a 0 del flag
esperovmax2:	in		r16,tifr1   ;espero de nuevo hasta que se alcance VMAX
				sbrs	r16,1
				rjmp	esperovmax2
				out		tifr1,r16	;Puesta a 0 del flag
				clr 	r16
				sts		tccr1b,r16  ;Contador parado
	
				clr		r16
				sts		tcnt1h,r16
				sts		tcnt1l,r16	  ; Puesta a 0 del contador, es necesario
									  ; ya que han pasado algunos ciclos más tras
									  ; alcanzar el vmax
				pop 	r16
				ret	

	.dseg
	.org 0x100
DATO: .byte 1
PARIDAD: .byte 1
