;Programa para generar la banda base de un transmisor
; para RadioControl de 7 canales

;Cada canal corresponde al mismo bit del PORTB (1:1, 2:2...)
;Bit 0 de PORTA es la salida
;Bit 3 de PORTA, carga del capacitor

; Cristal de 10MHz


	#include	<p16f628a.inc>

; Variables
Channel		equ	20h		
CounterA	equ	21h
TempW		equ	22h
TempStatus	equ	23h


	org		00h				; Vector de Reset
	goto	Start			; ir al inicio del programa

	org		04h				; Vector de interrupciones

	bcf		INTCON,GIE		; Deshabilito las interrupciones
	movwf	TempW			; Guardo W en TempW
	swapf	STATUS,W		; Guardo el registro STATUS en W
	movwf	TempStatus		; Guardo W en TempStatus
	
	btfsc	PIR1,CMIF		; Chequeo si hubo interrupcion del comparador
	goto	NextChannel		; si la hubo, continuo desde "NextChannel"
	btfss	PIR1,TMR2IF		; Chequeo si hubo interrupcion del Timer2
	goto	FinishInterrupt	; si no hubo interrupcion, voy al final de las interrupciones

FrameTimeOut				; continuo aqui, si hubo interrupcion del Timer2
	bcf		T2CON,TMR2ON	; Desactivo el Timer2, (para que se resetee)
	bcf		PIR1,TMR2IF		; Borro el flag, que indica interrupcion del Timer2
	movlw	b'11111101'
	movwf	Channel			; Cargo Channel con el valor de W
	movlw	b'00001001'
	iorwf	PORTA,F			; Hago altas las salidas 0 y 3 del puerto A
	bsf		T2CON,TMR2ON	; Activo el Timer2
	call	Delay
	call	Delay
	nop						; Tiempo de espera (500 us, cuando cambia el puerto A)
	movlw	b'11110110'
	andwf	PORTA,F			; Hago bajas las salidas 0 y 3 del puerto A
	bcf		PORTB,1			; Hago bajo el bit 1 del puerto B
	movf	Channel,W		; Cargo W con el valor de Channel
	bsf		STATUS,RP0		; Paso al banco de memoria 1
	tris	TRISB			; Bit 1 del puerto B como salida, el resto como entrada (W al TRISB)
	bcf		STATUS,RP0		; Paso al banco de memoria 0
	goto	FinishInterrupt	; Ir al final de las interrupciones

NextChannel
	bsf		STATUS,C
	rlf		Channel,F		; Roto hacia la izquierda Channel, y lo guardo en si mismo
	movlw	b'00001001'
	iorwf	PORTA,F			; Hago altas las salidas 0 y 3 del puerto A
	nop
	call	Delay
	call	Delay
	nop						; Tiempo de espera (500 us, cuando cambia el puerto A)
	movlw	b'11110110'
	andwf	PORTA,F			; Hago bajas las salidas 0 y 3 del puerto A
	movf	Channel,W		; Cargo W con el valor de Channel
	movwf	PORTB			; Llevo el valor de W al puerto B (en bajo solo el bit que este en 0)
	bsf		STATUS,RP0		; Paso al banco de memoria 1
	tris	TRISB			; Llevo el valor de W al TRISB (puerto B como salida, solo el bit que este en 0)
	bcf		STATUS,RP0		; Paso al banco de memoria 0
	
FinishInterrupt
	bcf		PIR1,CMIF		; Borro el flag que indica interrupcion del comparador

	swapf	TempStatus,W
	movwf	STATUS			; Recupero el valor original de STATUS
	swapf	TempW,F
	swapf	TempW,W			; Recupero el valor original de W
	retfie					; Retorno de la interrupcion, se habilitan nuevamente

;--------------------rutina de retardo----------------------------
Delay
	movlw	.206
	movwf	CounterA

DelayLoop
	decfsz	CounterA,F
	goto	DelayLoop
	return
;-------------------fin de la rutina de retardo-------------------

Start
	clrf	PORTA			; Todo el puerto A en 0
	clrf	PORTB			; Todo el puerto B en 0
	movlw	b'00000101'
	movwf	CMCON			; Habilito el comparador 2 solamente
	bsf		STATUS,RP0		; Paso al banco de memoria 1
	movlw	b'11100110'		
	tris	TRISA			; Configuro el puerto A; Bits 0, 3 y 4 salidas, el resto entrada
	movlw	b'11111111'
	tris	TRISB			; Configuro el puerto B; todos los bits como entrada
	movlw	b'11000111'
	movwf	OPTION_REG		
	movlw	b'01000010'
	movwf	PIE1			; Habilito las interrupciones del Timer2 y del comparador
	movlw	.195
	movwf	PR2				; Llevo el valor decimal 195 al registro PR2
	bcf		STATUS,RP0		; Paso al banco de memoria 0
	movlw	b'11010000'
	movwf	INTCON			; Habilito las interruciones
	movlw	b'01111011'		; Pre y Pos Scaler del Timer2 en 16
	movwf	T2CON			; Configuro el Timer2
	bsf		T2CON,TMR2ON	; Activo el Timer2

MainLoop
	nop
	nop
	goto	MainLoop		; Ciclo cerrado, que no hace nada
	end
