;**********************************************************************
;    Filename: DM9416.asm        File Version: 9416
;    Date:  2009 03 21                                                          
;    Author: Pavel Janko  jankop@volny.cz                             
;**********************************************************************
;    Files required: P16F676.INC                                                 
;                                                                     
;**********************************************************************

;    Notes: P16F676
;
;                            |-------U-------|
;                       Vdd -| 1          14 |- Vss
;             Crystal   RA5 -| 2          13 |- RA0   Button 2
;             Crystal   RA4 -| 3          12 |- RA1   Input C - Common
;             Button 1  RA3 -| 4          11 |- RA2   Button 3
;             Output R  RC5 -| 5          10 |- RC0   Input R
;             Output G  RC4 -| 6           9 |- RC1   Input G
;             Output B  RC3 -| 7           8 |- RC2   Input B
;                            |---------------| 
;                                                          
;**********************************************************************
	list      p=16F676          ; list directive to define processor
	#include <P16F676.INC>  	; processor specific variable definitions
	errorlevel -302
	__CONFIG   _CP_OFF &_CPD_OFF & _WDT_ON &_MCLRE_OFF &_BODEN_OFF &_PWRTE_ON &_HS_OSC
	__idlocs 0x9321             ; Datum is coded hexadecimal xYxMdDdD
;--------- CONSTANTS DEFINITIONS---------------------------------------
#define RAM_Start       0x20
#define ROM_End         0x3ff
#define BT0             0x00
#define BT1             0x01
#define BT2             0x02
#define BT3             0x03
#define BT4             0x04
#define BT5             0x05
#define BT6             0x06
#define BT7             0x07
#define INP_RGB_PRT     PORTC   ; port for Input analog RGB signals
#define INP_R           BT0     ; bit for Input R signal
#define INP_G           BT1     ; bit for Input G signal
#define INP_B           BT2     ; bit for Input B signal
#define OUT_RGB_PRT     PORTC   ; port for Output RGB LEDs
#define OUT_R           BT5     ; bit for R LED Output 
#define OUT_G           BT4     ; bit for G LED Output 
#define OUT_B           BT3     ; bit for B LED Output 
#define MSK_OUT_RGB   ~(1<<OUT_R|1<<OUT_G|1<<OUT_B); output RGB LEDs Mask
#define INP_BUT_PRT     PORTA   ; port for Input Buttons
#define BUT_1           BT3     ; bit for Button 1 Input
#define BUT_2           BT0     ; bit for Button 2 Input    
#define BUT_3           BT2     ; bit for Button 3 Input
#define INP_C           BT1     ; bit for analog common input
#define CGAN_R          0xff    ; fix GAIN for R chanel
#define CGAN_G          0xff    ; fix GAIN for G chanel
#define CGAN_B          0xff    ; fix GAIN for B chanel
;#define SEL_R           BT1
;#define SEL_G           BT2
;#define SEL_B           BT3
#define DEL_TMR0        0xCE    ; IRQ constant for TMR0
;--------- VARIABLE DEFINITIONS ---------------------------------------
    CBLOCK 	RAM_Start
TMP_OUT_RGB             ; pomocna promenna RGB vystup port
PWM_CNT                 ; citac vykonu
PWR_R                   ; pozadovany vykon R 
PWR_G                   ; pozadovany vykon G
PWR_B                   ; pozadovany vykon B
RMP_R                   ; filtrovany vstup R
RMP_G                   ; filtrovany vstup G
RMP_B                   ; filtrovany vstup B
GAN_R                   ; GAIN for R chanel
GAN_G                   ; GAIN for G chanel
GAN_B                   ; GAIN for B chanel
MAN_R_L
MAN_G_L
MAN_B_L
;TMP_ADRESL
;FLG_RGB
;flag
;timer_delay
cinitel1
cinitel2
soucinH
soucinL
w_temp	    	        ; variable used for context saving
status_temp             ; variable used for context saving
    ENDC    
;----------------------------------------------------------------------
		ORG     0x000   ; Processor reset vector
RESET_WDT_ERROR
		goto begin      ; Go to beginning of program
		ORG     0x004   ; interrupt vector location


;-----------------Obsluha preruseni od TMR0 - 32us -----------------
; Zahrnuje řízení svitu LED. Velikosti parametru PWR_R,PWR_G,PWR_B v
; rozsahu 0-255 je možné pulsne ridit vykon v rozsahu 0 - 100%
;----------------------------------------------------------------------		
timer0_INT
    movwf w_temp         	; save off current W register contents
	movf STATUS,W        	; move status register into W register
	movwf status_temp     	; save off contents of STATUS register
    bcf STATUS, RP0	        ; Restore Bank 0
    movlw DEL_TMR0          ; konstanta casovace
    movwf TMR0
    bcf INTCON,T0IF		    ; zruseni priznaku preruseni od tmr0
    incf PWM_CNT,F		    ; zvys citac vykonu LED 
    clrf TMP_OUT_RGB        ; mazani pomocneho registru
	movf PWR_R, W		    ; W = PWR_R
	subwf PWM_CNT,W		    ; PWM_CNT - PWR_R
	btfss STATUS,C		    ; IF PWR_R > PWM_CNT
	bsf TMP_OUT_RGB ,OUT_R  ; then LED R ON
    movf PWR_G, W		    ; W = PWR_G
	subwf PWM_CNT,W		    ; PWM_CNT - PWR_G
	btfss STATUS,C		    ; IF PWR_G > PWM_CNT
	bsf TMP_OUT_RGB ,OUT_G  ; then LED G ON
	movf PWR_B, W		    ; W = PWR_B
	subwf PWM_CNT,W		    ; PWM_CNT - PWR_B
	btfss STATUS,C		    ; IF PWR_B > PWM_CNT
	bsf TMP_OUT_RGB ,OUT_B  ; then LED B ON
	movf OUT_RGB_PRT,W      ; port LED to W
    andlw MSK_OUT_RGB       ; maskovani nepotrebnych bitu    
    iorwf TMP_OUT_RGB ,W    ; vlozeni bitu RGB
    movwf OUT_RGB_PRT       ; odeslani na port
    movf status_temp,W	    ; retrieve copy of STATUS register
	movwf STATUS		    ; restore pre-isr STATUS register contents
	swapf w_temp,F		    ; restore pre-isr W register contents
	swapf w_temp,W		    ; restore pre-isr W register contents
    retfie                  ; return from interrupt
;---------------------------------------------------------------------
; Start procesoru , konfigurace
;---------------------------------------------------------------------
begin	
    movlw 0<<IRP|0<<RP1|0<<RP0|0<<NOT_TO|0<<NOT_PD|0<<Z|0<<DC|0<<C
	movwf STATUS            ; Restore Bank 0
    movlw 0<<BT5|0<<BT4|0<<BT3|0<<BT2|0<<BT1|0<<BT0
    movwf PORTA             ; definice vystupu na PORTA
    movlw 0<<BT5|0<<BT4|0<<BT3|0<<BT2|0<<BT1|0<<BT0
    movwf PORTC             ; definice vystupu na PORTC
    movlw 0<<GIE|0<<PEIE|1<<T0IE|0<<INTE|0<<RAIE|0<<T0IF|0<<INTF|0<<RAIF
    movwf INTCON			; zakaz vsech IRQ vyjma TMR0
    movlw 0<<EEIF|0<<ADIF|0<<CMIF|0<<TMR1IF
    movwf PIR1              ; mazani priznaku preruseni periferii
    movlw 0<<TMR1GE|0<<T1CKPS1|0<<T1CKPS0|0<<T1OSCEN|0<<NOT_T1SYNC|0<<TMR1CS|0<<TMR1ON
	movwf T1CON 			; Stop Timer1,LP oscillator is off, Internal clock(F OSC /4)
	movlw 0<<COUT|0<<CINV|0<<CIS|1<<CM2|1<<CM1|1<<CM0	; odpojeni komparatoru CMP
	movwf CMCON	
    movlw 1<<ADFM|1<<VCFG|1<<CHS2|0<<CHS1|0<<CHS0|0<<GO_DONE|1<<ADON		
    movwf ADCON0		
          ; ADFM = 1 right justified Result Formed Select bit 
          ; VCFG = 1 external Vref, Voltage Reference bit 
          ; CH2:CH0 = 100 chanel AN4/RC0 Analog Channel Select bits 
          ; GO_DONE = 0
          ; ADON = 1 A/D converter module is operating
;----------------------------------------------------------------------
	bsf STATUS,RP0		    ; Bank 1
    movlw 0<<NOT_RAPU|0<<INTEDG|0<<T0CS|0<<T0SE|1<<PSA|0<<PS2|0<<PS1|0<<PS0
          ; NOT_RAPU = 0 PORTA pull-ups are enabled by individual port latch values
          ; INTEDG = 0 Interrupt on falling edge of RA2/INT pin
          ; T0CS = 0 Internal, TMR0 Clock Source Select bit
          ; T0SE = 0 TMR0 Increment on low-to-high transition on RA2/T0CKI pin
          ; PSA = 1 Prescaler is assigned to the WDT module
          ; PS2:PS0 = Prescaler Rate Select bits
    clrwdt
    movwf OPTION_REG
    movlw 1<<BT5|1<<BT4|1<<BT3|1<<BT2|1<<BT1|1<<BT0
    movwf TRISA             ; PORTA vse jako vstup
  ; movlw 1<<BT5|1<<BT4|1<<BT3|1<<BT2|1<<BT1|1<<BT0
    movlw MSK_OUT_RGB
    movwf TRISC             ; PORTC RGB LED vstup
    movlw 0<<EEIE|0<<ADIE|0<<CMIE|0<<TMR1IE
	movwf PIE1				; zakaz vsech IRQ periferii
  ; movlw 0<<NOT_POR|0<<NOT_BOD 
  ; movwf PCON              ; read only
  ; movlw 0<<CAL5|0<<CAL4|0<<CAL3|0<<CAL2|0<<CAL1|0<<CAL0
    call ROM_End
    movwf OSCCAL
    movlw 0<<ANS7|1<<ANS6|1<<ANS5|1<<ANS4|0<<ANS3|0<<ANS2|0<<ANS1|0<<ANS0
    movwf ANSEL             ; RGB analog port 
  ; movlw  0<<BT5|0<<BT4|0<<BT2|0<<BT1|0<<BT0
    movlw 1<<BUT_3|1<<BUT_2|1<<BUT_1
    movwf WPUA              ; vypnout Pull Up na PORTA po bitech
    movlw 0<<BT5|0<<BT4|0<<BT3|0<<BT2|0<<BT1|0<<BT0
    movwf IOCA              ; zakazat IRQ od zmeny PORTA
    movlw 0<<VREN|0<<VRR|0<<VR3|0<<VR2|0<<VR1|0<<VR0
    movwf VRCON				; vypnuti reference - snizeni spotreby
    movlw 0<<ADCS2|1<<ADCS1|0<<ADCS0
    movwf ADCON1            ; nastaveni kmitoctu ADC 1,6us/20MHz
	bcf STATUS, RP0 		; Restore Bank 0
    bsf INTCON, GIE
    movlw CGAN_R
    movwf GAN_R
    movlw CGAN_G
    movwf GAN_G
    movlw CGAN_B
    movwf GAN_B
    ;clrf flag

loop
    clrwdt
    btfsc INP_BUT_PRT,BUT_1
    goto jdinaG
    incf MAN_R_L,F
	btfsc STATUS,Z				
	incf GAN_R,F
jdinaG
    btfsc INP_BUT_PRT,BUT_2
    goto jdinaB
    incf MAN_G_L,F
	btfsc STATUS,Z				
	incf GAN_G,F
jdinaB
    btfsc INP_BUT_PRT,BUT_3
    goto jdina
    incf MAN_B_L,F
	btfsc STATUS,Z				
	incf GAN_B,F
jdina
    movf GAN_R,W            ; konstanta zesileni
    movwf cinitel1
    movf RMP_R,W
    movwf cinitel2
    call mul8x8m
    movf soucinH,W
    movwf PWR_R 
    movf GAN_G,W            ; konstanta zesileni
    movwf cinitel1
    movf RMP_G,W
    movwf cinitel2
    call mul8x8m
    movf soucinH,W
    movwf PWR_G 
    movf GAN_B,W            ; konstanta zesileni
    movwf cinitel1
    movf RMP_B,W
    movwf cinitel2
    call mul8x8m
    movf soucinH,W
    movwf PWR_B 
    goto loop
mul8x8m 
    clrf    soucinH
    clrf    soucinL
    movfw   cinitel1
    clrc
    btfsc   cinitel2,0
    addwf   soucinH,F
    rrf     soucinH,F
    rrf     soucinL,F
    btfsc   cinitel2,1
    addwf   soucinH,F
    rrf     soucinH,F
    rrf     soucinL,F
    btfsc   cinitel2,2
    addwf   soucinH,F
    rrf     soucinH,F
    rrf     soucinL,F
    btfsc   cinitel2,3
    addwf   soucinH,F
    rrf     soucinH,F
    rrf     soucinL,F
    btfsc   cinitel2,4
    addwf   soucinH,F
    rrf     soucinH,F
    rrf     soucinL,F
    btfsc   cinitel2,5
    addwf   soucinH,F
    rrf     soucinH,F
    rrf     soucinL,F
    btfsc   cinitel2,6
    addwf   soucinH,F
    rrf     soucinH,F
    rrf     soucinL,F
    btfsc   cinitel2,7
    addwf   soucinH,F
    rrf     soucinH,F
    rrf     soucinL,F
    return
    org 0x2100
    de 0x00
    end
