        LIST     P = PIC16F628

; Generic Definitions
W          EQU    H'0000'    ; Destino W
F          EQU    H'0001'    ; Destino F

; Standard Register Files
INDF       EQU    H'0000'    ; Direccionamiento Ind
TMR0       EQU    H'0001'    ; Contador
PCL        EQU    H'0002'    ; Contador Programa
STATUS     EQU    H'0003'    ; Registro STATUS
FSR        EQU    H'0004'    ; Registro File Select
PUERT_A    EQU    H'0005'    ; Puerto A Input/Output 
PUERT_B    EQU    H'0006'    ; Puerto B Input/Output 
PCLATH     EQU    H'000A'    ; Contador Prog (bit mayor peso)
INTCON     EQU    H'000B'    ; Registro Control Interrupciones

OCTION     EQU    H'0081'    ; Option Register
TRISA      EQU    H'0085'    ; Port A Data Direction Register
TRISB      EQU    H'0086'    ; Port B Data Direction Register


;Bits STATUS 
#define C         STATUS, 0  ; Bit Carry 
#define DC        STATUS, 1  ; Bit Digit Carry 
#define Z         STATUS, 2  ; Bit Zero 
#define NOT_PD    STATUS, 3  ; Bit Power Down 
#define NOT_TO    STATUS, 4  ; Bit Watchdog TimeOut 
#define RP0       STATUS, 5  ; Registro Page Select - direct
#define RP1       STATUS, 6  ; Registro Page Select - direct
#define IRP       STATUS, 7  ; Register Page Select - indirect

;Bits OCTION 
PS0        EQU    .0         ; Preescalador
PS1        EQU    .1         ; 
PS2        EQU    .2         ; 
PSA        EQU    .3         ; Asigna preescalador   0=TMR0   1=WDT
T0SE       EQU    .4         ; Define Flanco Seņal TMR0 (RA4) 0=Lo/Hi 1=Hi/Lo
T0CS       EQU    .5         ; TMR0  0=interno 1=RA4
INTEDG     EQU    .6         ; Define Flanco seņal provoca interrupcion 0=desc 1=asc
NOT_RBPU   EQU    .7         ; Activa pull-up internas


; Bits INTCON 
RBIF       EQU    .0         ; Bit indicador cambio de estado pines RB4,RB5,RB6,RB7
INTF       EQU    .1         ; Bit bandera cmbio flanco RB0/INT (INF=1 existio cambio flanco seņal RB0)
T0IF       EQU    .2         ; Bit overflow TMR0 (llego a FF y paso a 0)
RBIE       EQU    .3         ; Bit de habilitacion para atender interrupcion RB4,RB5,RB6,RB7
INTE       EQU    .4         ; Bit de habilitacion para atender interrupcion RB0/INT
T0IE       EQU    .5         ; Bit de habilitacion para atender interrupcion cdo TMR0 desbordado
EEIE       EQU    .6         ; Bit de habilitacion para atender interrupcion cdo finalizo escritura de  EEPROM
GIE        EQU    .7         ; Bit de habilitacion para atender todas  las interrupcion en sus 4 modalidades


; Asignacion puertos entrada/salida

#define TRIAC   PUERT_A, 0    ; Triac (RA0)
#define ZEROX   PUERT_A, 1    ; Detector Cruce Cero (RA1)
#define CARRIER PUERT_A, 2    ; Detector Portadora X-10 (RA2)

#define Unid3   PUERT_B, 0    ; Unit/Function Code 3 (RB0)
#define Unid2   PUERT_B, 1    ; Unit/Function Code 2 (RB1)
#define Unid1   PUERT_B, 2    ; Unit/Function Code 1 (RB2)
#define Unid0   PUERT_B, 3    ; Unit/Function Code 0 (RB3)
#define Casa0   PUERT_B, 4    ; House Code 0 \
#define Casa1   PUERT_B, 5    ; House Code 1 | 0 to 15
#define Casa2   PUERT_B, 6    ; House Code 2 | re-assigned as
#define Casa3   PUERT_B, 7    ; House Code 3 / A to O

; Registros variables

FLAGS    EQU    H'0010'      ; Registro usado como Bandera
CONTA    EQU    H'0011'      ; Contador usado en rutinas de espera
CASA     EQU    H'0012'      ; House code, 0 - 15 == A - P
UNIDAD   EQU    H'0013'      ; Unit code, 0 - 15 == 1 - 16
RXCASA   EQU    H'0014'      ; Codigo Casa Recibido, 0 - 15 == A - P
RXUNIDAD EQU    H'0015'      ; Codigo Unidad Recibido, 0 - 15 == 1 - 16
RXFUNC   EQU    H'0016'      ; Codigo Funcion Recibido, 0 - 15 == 1 - 16

#define Carga1	FLAGS, 0     ; 0=Carga apagada, 1=Carga encendida para Vel1
#define Carga2	FLAGS, 1     ; para Vel2
#define Carga3	FLAGS, 2     ; para Vel3


; Definicion de los Macros


Bank0	 macro
	 BCF	RP0
	 	endm

Bank1	 macro
	 BSF	RP0
	 	endm
	 

Triacon  macro		     ;Poniendo 1 en RA0 tengo Corriente de Gate
         BSF    TRIAC
                endm

Triacoff macro               ;Poniendo 0 en RA0 no tengo Corriente de Gate
         BCF    TRIAC
                endm

Buscar   macro  par1
         CALL   LeerBit
         RLF    par1, F
                endm

; Comienzo de programa

Start
         Bank1               ; Pone RP0=1 entonces Banco 1

         MOVLW  B'00001110'
         MOVWF  TRISA        ; Seteo Puerto A con Ent/Sal

         MOVLW  B'11111111'
         MOVWF  TRISB        ; Seteo Puerto B con Entradas

         MOVLW  B'00000111'  ; Preescalador TMR0, Tiempo=(256-valor previo cargado en TMR0) x Predivisor x Reloj/4
         MOVWF  OCTION       ; 

         Bank0               ; Pone RP0=0 entonces Banco 0

         Triacoff            ; Seteo Carga como apagada
         CLRF   FLAGS
         CLRF   CASA
         CLRF   UNIDAD
         CLRF   RXCASA
         CLRF   RXUNIDAD
         CLRF   CONTA

Main
         CALL   Espera500mSeg

Tr1110A
         CLRWDT

       

         CALL   LeerBit      ; Esperar comienzo de trama 1110
         BTFSS  C            ; 1
         GOTO   Tr1110A
         CALL   LeerBit	     ; Aqui de nuevo espera crucecero etc....y chequea carry..si hay entonces salta al otro Leerbit
         BTFSS  C            ; 1
         GOTO   Tr1110A
         CALL   LeerBit      ; Aqui de nuevo espera crucecero etc....y chequea carry..si hay entonces salta al otro Leerbit
         BTFSS  C            ; 1
         GOTO   Tr1110A
         CALL   LeerBit      ; Aqui de nuevo espera crucecero etc....y chequea carry..si hay entonces salta al otro Leerbit
         BTFSC  C            ; 0
         GOTO   Tr1110A

         Buscar RXCASA       ; Leer primera direccion Casa. Se van ingresando los 8 semiciclos correspondientes a Casa.
         Buscar RXCASA 
         Buscar RXCASA       ;Como son bits por cada semiciclo y X10 trabaja con complemento (bits 10==1  bits01==0) se debe 
         Buscar RXCASA       ;tener en cuenta los valores de bits de los semiciclos impares tanto para RXCASA como RXUNIDAD
         Buscar RXCASA 
         Buscar RXCASA 
         Buscar RXCASA 
         Buscar RXCASA       ; Hasta aca hemos rellenado el registro RXCASA con los bits correspondientes de cada semiciclo 
                             ; luego de la trama de comienzo
         Buscar RXUNIDAD     ; Leer primera direccion Unidad
         Buscar RXUNIDAD 
         Buscar RXUNIDAD 
         Buscar RXUNIDAD 
         Buscar RXUNIDAD 
         Buscar RXUNIDAD 
         Buscar RXUNIDAD     ; Hasta aca hemos rellenado el registro RXUNIDAD con los bits correspondientes de cada semiciclo
         Buscar RXUNIDAD     ; luego de la trama de CASA

         MOVLW  D'0024'      ; Esperar 24 cruces cero hasta
         MOVWF  CONTA        ; comienzo del "gap"

Conteo1
         CALL   LeerBit
         DECFSZ CONTA, F
         GOTO   Conteo1

         MOVLW  D'0011'      ; Esperar un maximo de 10 cruces de cero
         MOVWF  CONTA        ; hasta proximo comienzo de trama (start)

Conteo2
         DECFSZ CONTA, F
         GOTO   Tr1110B
         GOTO   Main         ; Abortar por problemas de Tx
Tr1110B
         CLRWDT
         CALL   LeerBit      ;     
         BTFSS  C            ; 1   
         GOTO   Conteo2
         CALL   LeerBit
         BTFSS  C            ; 1   
         GOTO   Conteo2      ;     
         CALL   LeerBit
         BTFSS  C            ; 1
         GOTO   Conteo2
         CALL   LeerBit
         BTFSC  C            ; 0
         GOTO   Conteo2

         MOVLW  D'0008'      ; Ignorar proximos 8 semiciclos
         MOVWF  CONTA        ; Direccion Casa repetida
Conteo3
         CALL   LeerBit
         DECFSZ CONTA, F
         GOTO   Conteo3

         Buscar RXFUNC       ; Leer comando funcion
         Buscar RXFUNC
         Buscar RXFUNC
         Buscar RXFUNC
         Buscar RXFUNC       ; ignore last two bits of function
         Buscar RXFUNC       ; as always 1 0 == 1
         Buscar RXFUNC
         Buscar RXFUNC       ; and ignore rest of data (22 bits)

         CALL   LeerDIPSW
         MOVF   CASA, W
         SUBWF  RXCASA, W
         XORLW  0
         BZ     CasaOK
         GOTO   Tr1110A	     ;

CasaOK
         MOVF   UNIDAD, W    ; Codigo casa correcto
         SUBWF  RXUNIDAD, W
         XORLW  0
         BZ     UnidadOK
         GOTO   Tr1110A

UnidadOK                     ; Codigo unidad correcto
         MOVLW  B'01011001'  ; funcion encendido 0010 1 (que sera la velocidad 1 )
         SUBWF  RXFUNC, W
         XORLW  0
         BZ     Vel1A
         MOVLW  B'01100101'  ; funcion dim     0100 1 (q sera la velocidad 2)
	 SUBWF  RXFUNC, W
         XORLW  0
         BZ     Vel2A
	 MOVLW  B'01100110'  ; funcion bright  0101 1
         SUBWF  RXFUNC, W
         XORLW  0
         BZ     Vel3A
         MOVLW  B'01011010'  ; funcion apagado 0011 1
         SUBWF  RXFUNC, W
         XORLW  0
         BZ     Poweroff
         GOTO   Main

Poweroff
	 Triacoff
	 BCF    Carga1       ;
	 BCF	Carga2
	 BCF	Carga3
	 RETLW	0

Vel1A	                     ; la A es de arranque, o sea estas tres vel solo son para cdo arranca el vent luego se usan las
         CALL	CruceCero    ; demas rutinas de vel q seran llamadas continuamente
                             ;Rutina de tiempo para ang de retraso
	 Triacon             ;se prende la salida triac (SI NO SE APAGA NO QUEDA AL MAXIMO?)
	 NOP	             ;reemplazar estos nop por una rutina corta si es que hace falta
	 NOP
	 Triacoff	     ;se quita tension en Gate pero Triac sigue funcionando
         BSF    Carga1       ;se pone en uno la bandera Carga1
	 BCF	Carga2
	 BCF	Carga3
         GOTO   Tr1110A      ; rutina de espera de la proxima trama

Vel2A	
         CALL	CruceCero
                             ;Rutina de tiempo para ang de retraso
	 Triacon             ;se prende la salida triac
         NOP
	 NOP
	 Triacoff	     ;se quita tension en Gate pero Triac sigue funcionando
         BSF    Carga2       ;se pone en uno la bandera Carga2
	 BCF	Carga1
	 BCF	Carga3
         GOTO   Tr1110A

Vel3A	
         CALL	CruceCero
                             ;Rutina de tiempo para ang de retraso
	 Triacon             ;se prende la salida triac
	 NOP
	 NOP
	 Triacoff	     ;se quita tension en Gate pero Triac sigue funcionando
         BSF    Carga3       ;se pone en uno la bandera Carga3
	 BCF	Carga1
	 BCF	Carga2
         GOTO   Tr1110A

Vel1	
         
                             ;Rutina de tiempo para ang de retraso (6 mS)
	 Triacon             ;se prende la salida triac
	 NOP
	 NOP
	 Triacoff	     ;se quita tension en Gate pero Triac sigue funcionando
         BSF    Carga1       ;se pone en uno la bandera Carga1
	 BCF	Carga2
	 BCF	Carga3
         RETLW	0       

Vel2	
         
                             ;Rutina de tiempo para ang de retraso (4 mS)
	 Triacon             ;se prende la salida triac
	 NOP
	 NOP
	 Triacoff	     ;se quita tension en Gate pero Triac sigue funcionando
         BSF    Carga2       ;se pone en uno la bandera Carga2
	 BCF	Carga1
	 BCF	Carga3
         RETLW	0

Vel3	
         
                             ;Rutina de tiempo para ang de retraso (2 mS)
	 Triacon             ;se prende la salida triac
	 NOP
	 NOP
	 Triacoff	     ;se quita tension en Gate pero Triac sigue funcionando
         BSF    Carga3       ;se pone en uno la bandera Carga3
	 BCF	Carga1
	 BCF	Carga2
         RETLW	0

STATUSCARGA
	 
	 BTFSC	Carga1
	 CALL	Vel1
	 BTFSC	Carga2
	 CALL	Vel2
	 BTFSC	Carga3
	 CALL	Vel3
	 RETLW	0





LeerBit
         CALL   CruceCero    ; Llama y vuelve cdo hay CruceCero
         CALL   Espera250uSeg ; Espera para darle tiempo a entrar portadora 120khz (total la vent de tiempo es de 1mSeg)
         BTFSS  CARRIER      ; Chequea presencia de portadora 120khz (RA2)
         GOTO   GB1
         BSF    C            ; Portadora presente entonces setear carry 
	 CALL	STATUSCARGA
         RETLW  0

GB1
         BCF    C            ; Portadora  no presente entonces clear carry 
	 CALL	STATUSCARGA
         RETLW  0            ; De aqui siempre vuelve a la proxima linea del  CALL LeerBit  correspondiente 




CruceCero
         BTFSC  ZEROX        ; Chequea estado 50Hz (en que semiciclo esta)(ZEROX = RA1)(salta si RA1 = 0)
         GOTO   Z1           ; 

Z0
         CLRWDT              ; RA1 esta en 0  
         BTFSS  ZEROX        ; hace el lazo hasta que RA1 sea 1
         GOTO   Z0
         RETLW  0
Z1
         CLRWDT              ; RA1 esta en 1 
         BTFSC  ZEROX        ; hace el lazo hasta que RA1 sea 0
         GOTO   Z1
         RETLW  0



Espera500mSeg

         MOVLW  D'0030'      ; 30 x 16.384msec = 491.52msec
         MOVWF  CONTA
Loop
         MOVLW  D'0192'      ; 256-64=192,  64 x 256usec = 16.384msec
         MOVWF  TMR0         ; Time delay inner loop
Espera16
         CLRWDT
         MOVF   TMR0, W
         BNZ    Espera16

         DECFSZ CONTA, F
         GOTO   Loop
         RETLW  0


Espera250uSeg

         CLRF   TMR0
W0
         CLRWDT              ; Measured at about 273uSecs
         MOVF   TMR0, W
         BZ     W0
         RETLW  0

LeerDIPSW

         SWAPF  PUERT_B, W   ; Leer DIP switch high nibble = Direccion CASA
         MOVWF  CASA         ; y complementar para logica verdadera y
         COMF   CASA, W      ; guardar en variable CASA, (aca habria q chequear bit Z por si da 0 luego del COMF ...casa P)
         ANDLW  H'000F'      ; 0 -> 15 == A -> P (al hacer esto queda W con los valores solo de casa en los bits de menor                                  ; peso, valores entre 0 - 15)
         CALL   TablaCasa    ; Ver tabla
         MOVWF  CASA 
         MOVF   PUERT_B, W   ; Leer DIP switch low nibble = Direccion Unidad
         ANDLW  H'000F'      ; Unscramble bits and complement for true-logic
         CALL   TablaUnidad  ; Look up bit pattern & save in UNIT variable
         MOVWF  UNIDAD       ; 0 -> 15 == 1 -> 16
         RETLW  0

TablaCasa

	 ADDWF  PCL, F       ; House Code Look-up table:
         RETLW  B'01101001'  ; A = 0110   x-x-x-x-ON-OFF-OFF-OFF  (posicion en switch 1-2-3-4-5-6-7-8)(1-4 Unidad; 5-8 Casa)
         RETLW  B'10101001'  ; B = 1110	  x-x-x-x-OFF-ON-OFF-OFF
         RETLW  B'01011001'  ; C = 0010   x-x-x-x-ON-ON-OFF-OFF
         RETLW  B'10011001'  ; D = 1010   x-x-x-x-OFF-OFF-ON-OFF
         RETLW  B'01010110'  ; E = 0001   x-x-x-x-ON-OFF-ON-OFF
         RETLW  B'10010110'  ; F = 1001   x-x-x-x-OFF-ON-ON-OFF
         RETLW  B'01100110'  ; G = 0101   x-x-x-x-ON-ON-ON-OFF
         RETLW  B'10100110'  ; H = 1101   x-x-x-x-OFF-OFF-OFF-ON
         RETLW  B'01101010'  ; I = 0111   x-x-x-x-ON-OFF-OFF-ON
         RETLW  B'10101010'  ; J = 1111   x-x-x-x-OFF-ON-OFF-ON
         RETLW  B'01011010'  ; K = 0011   x-x-x-x-ON-ON-OFF-ON
         RETLW  B'10011010'  ; L = 1011   x-x-x-x-OFF-OFF-ON-ON
         RETLW  B'01010101'  ; M = 0000   x-x-x-x-ON-OFF-ON-ON
         RETLW  B'10010101'  ; N = 1000   x-x-x-x-OFF-ON-ON-ON
         RETLW  B'01100101'  ; O = 0100   x-x-x-x-ON-ON-ON-ON
         RETLW  B'10100101'  ; P = 1100   luego del COMF se deberia chequear bit z status si da 0 entonces todo off casa P
    	                     ; la otra es no usar COMF y armar tabla de acuerdo como hice abajo y asi tener todas                                          ; posibilidades
	 		     


TablaUnidad

	 ADDWF  PCL, F       ;Unit Code Look-up table:
         RETLW  B'01100110'  ; 7 = 0101   x-x-x-x-ON-ON-ON-OFF    
         RETLW  B'01011010'  ;11 = 0011   x-x-x-x-ON-ON-OFF-ON   
         RETLW  B'01011001'  ; 3 = 0010   x-x-x-x-ON-ON-OFF-OFF    
         RETLW  B'01010101'  ;13 = 0000   x-x-x-x-ON-OFF-ON-ON     
         RETLW  B'01010110'  ; 5 = 0001   x-x-x-x-ON-OFF-ON-OFF    
         RETLW  B'01101010'  ; 9 = 0111   x-x-x-x-ON-OFF-OFF-ON     
         RETLW  B'01101001'  ; 1 = 0110   x-x-x-x-ON-OFF-OFF-OFF
         RETLW  B'10010101'  ;14 = 1000   x-x-x-x-OFF-ON-ON-ON
         RETLW  B'10010110'  ; 6 = 1001   x-x-x-x-OFF-ON-ON-OFF
         RETLW  B'10101010'  ;10 = 1111   x-x-x-x-OFF-ON-OFF-ON
         RETLW  B'10101001'  ; 2 = 1110	  x-x-x-x-OFF-ON-OFF-OFF
         RETLW  B'10011010'  ;12 = 1011   x-x-x-x-OFF-OFF-ON-ON
         RETLW  B'10011001'  ; 4 = 1010   x-x-x-x-OFF-OFF-ON-OFF
         RETLW  B'10100110'  ; 8 = 1101   x-x-x-x-OFF-OFF-OFF-ON
         RETLW  B'01100101'  ;15 = 0100   x-x-x-x-OFF-OFF-OFF-OFF
         RETLW  B'01101001'  ;F>F>0 =  1 = 0110 0

	 END

	 
         










