Code

Code is in assembler (Microchip 12F629) and commented in spanish, if you need translation on the comments, let me know.

;
; $Id: mycameye.asm,v 1.13 2004-06-16 00:22:15 ariel Exp $
;

; --------------------------------------------------------------------------
; Initial includes and configuration bits
;
        list  p=12f629
        #include "p12f629.inc"

errorlevel  -302              ; suppress message 302 from list file

__CONFIG   _CP_ON & _CPD_OFF & _BODEN_ON & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

; ---------------------------------------------------------------------------
; External decalrations
;
        ;extern sub_delay_500ms
        ;extern sub_delay_50ms

; --------------------------------------------------------------------------
; Directives
;
#define         Button          GPIO,5 ;  Define the "Button" Pin

#define         RED             0
#define         GREEN           1
#define         OFF             2
#define         BLINKING        3
#define         NOT_BLINKING    4
#define         ALTER           5
#define         FAST_BLINKING   6
#define         FAST_ALTER 7

#define         TMR1            H'FFFF' - D'62500'

; --------------------------------------------------------------------------
; Macro definitions
;

m_BitToggle     macro   a_addr, a_bit
        local   bit_is_not_set, end_macro
        btfss   a_addr, a_bit
        goto    bit_is_not_set
        bcf     a_addr, a_bit
        goto    end_macro
bit_is_not_set
        bsf     a_addr, a_bit       
end_macro       
        endm

SetOutputColor  macro a_color
    if a_color == RED
        movlw   0x03
        movwf   led_pos_1
    endif

    if a_color == BLINKING
        movlw   0x08
        movwf   led_blk_int
        clrf    led_pos_2
    endif

    if a_color == FAST_BLINKING
        movlw   0x01
        movwf   led_blk_int
        clrf    led_pos_2
    endif

    if a_color == NOT_BLINKING
        movlw   0x08
        movf    led_pos_1,0
        movwf   led_blk_int
        movwf   led_pos_2
    endif

    if a_color == GREEN
        movlw   0x01
        movwf   led_pos_1
    endif

    if a_color == ALTER
        movlw   0x04
        movwf   led_blk_int
        movlw   0x01
        movwf   led_pos_1
        movlw   0x03
        movwf   led_pos_2
    endif

    if a_color == FAST_ALTER
        movlw   0x01
        movwf   led_blk_int
        movlw   0x01
        movwf   led_pos_1
        movlw   0x03
        movwf   led_pos_2
    endif

    if a_color == OFF
        movlw   0x00
        movwf   led_pos_1
        movlw   0x00
        movwf   led_pos_2
    endif
   
    endm   

; --------------------------------------------------------------------------
; EEPROM Variables
;
        org H'2100' ; Initialize EEPROM Data
EEPROM_FIRSTRUN                 de      0
EEPROM_FACTORY_OSCCAL           de      0
EEPROM_CFG_ZOOM                 de      0,0
EEPROM_VERSION                  de      "camojo, cvs $Revision: 1.13 $", 0
; --------------------------------------------------------------------------
; Data Variables
;
INT_VAR         UDATA_SHR       0x20
counter                 RES     1
frame                   RES     8               ; LANC frame
counter2                RES     1
port_lanc_temp          RES     1
flags                   RES     1               ; my flags
state                   RES     1               ; my flags
state2                  RES     1               ; my flags
frame_tmp               RES     1
button_cnt              RES     1

main_cnt                RES     1               ; contador para el loop main
sub_cnt                 RES     1               ; contador para subrutinas
sub_cnt2 RES     1               ; contador para subrutinas
sub_cnt3 RES     1               ; contador para subrutinas

led_pos_1               RES     1
led_pos_2               RES     1
led_blk_int             RES     1
led_blk_int_cnt         RES     1

cfg_zoom                RES     2

command                 RES     1

; --------------------------------------------------------------------------
; Compiler constants
;

;EEPROM_FIRSTRUN         EQU     0x00
;EEPROM_FACTORY_OSCCAL   EQU     0x01
;EEPROM_CFG_ZOOM         EQU     0x03

PORT_LANC               EQU     GPIO
PORT_LED                EQU     GPIO
BIT_LANC                EQU     5
BIT_LED1                EQU     1
BIT_LED2                EQU     4

FLG_TRANSMIT            EQU     0
FLG_HALFBIT             EQU     1
FLG_BYTESTOP            EQU     2
FLG_BYTEDONE            EQU     3
FLG_STARTBIT            EQU     4
FLG_POWERONBUTTON       EQU     4

STATE_REC               EQU     0
STATE_OFF               EQU     1
STATE_NOTCAMERA         EQU     2
STATE_LED               EQU     3
STATE_CFG               EQU     4
STATE_ZOOMDOWN          EQU     5
STATE_ZOOM              EQU     6
STATE_ZOOMCFG           EQU     7

STATE2_YAESTACFG        EQU     0

; intento de multiple velocidad fallido
COMMAND_ZOOM_UP         EQU     0x08
COMMAND_ZOOM_DOWN       EQU     0x18

COMMAND_ZOOM_UP_CFG     EQU     COMMAND_ZOOM_UP
COMMAND_ZOOM_DOWN_CFG   EQU     COMMAND_ZOOM_DOWN

NUM_TRANSMIT_COMMAND    EQU     D'05'

; --------------------------------------------------------------------------
; Main program
;
RESET_VECTOR    CODE    0x000                   ; processor reset vector

          goto    main                            ; go to beginning of program

INT_VECTOR      CODE    0x004                   ; interrupt vector location

        goto    label_handle_int

MAIN            CODE

main:
        call    sub_startup_varinit
        call    sub_startup_microinit
        bsf     flags, FLG_POWERONBUTTON
main_loop:
        bsf     state, STATE_CFG
        bcf     state2, STATE2_YAESTACFG
       
        btfss   state, STATE_ZOOM
        goto    main_loop_no_zoom

SetOutputColor FAST_BLINKING
       
btfss state, STATE_ZOOMDOWN
        goto main_loop_zoomup
goto main_loop_zoomdown
main_loop_zoomup
SetOutputColor GREEN
call sub_zoom_up
goto main_loop_zoomupdownend
main_loop_zoomdown
SetOutputColor RED
call sub_zoom_down
main_loop_zoomupdownend
m_BitToggle state, STATE_ZOOMDOWN
        bcf     state, STATE_ZOOM
main_loop_no_zoom       
        bcf     state, STATE_CFG

        movlw   0x18                            ; Initialize frame to send
        movwf   frame
        movf    command, 0
        movwf   frame+1
        clrf    command
       
        ; for getting info
        btfsc   state, STATE_NOTCAMERA
        bsf     state, STATE_CFG
       
call sub_transmit_command

        btfsc   state, STATE_NOTCAMERA
        bcf     state, STATE_CFG

        btfsc   state, STATE_NOTCAMERA
        goto    check_camera_mode
       
        btfss   Button
        call    sub_handle_button
       
        btfsc   state, STATE_CFG
        goto    main_cfg_start

check_camera_mode
       
        ; Check if recording?
        movf    frame+4, 0
        sublw   0x04
        btfsc   STATUS,Z
        bsf     state, STATE_REC
        btfsc   STATUS,Z
        bcf     state, STATE_NOTCAMERA
        btfsc   STATUS,Z
        goto    more_checks_1
       
        ; Check if not recording?
        movf    frame+4, 0
        sublw   0x14
        btfsc   STATUS,Z
        bcf     state, STATE_REC
        btfsc   STATUS,Z
        bcf     state, STATE_NOTCAMERA
        btfsc   STATUS,Z
        goto    more_checks_1
       
        bsf     state, STATE_NOTCAMERA
more_checks_1
        btfss   state, STATE_OFF
        goto    check
        SetOutputColor  OFF
        goto    after_lowbatlowtape
check
        btfss   state, STATE_NOTCAMERA
        goto    camera_mode
not_camera_mode   
        SetOutputColor  ALTER
        goto after_lowbatlowtape
camera_mode
        btfss   state, STATE_REC
        goto    is_not_recording
is_recording
        SetOutputColor  RED
        goto check_lowbatlowtape
is_not_recording   
        SetOutputColor  GREEN

check_lowbatlowtape
        movf    frame+5, 0
        andlw   0x06
        btfsc   STATUS,Z
        goto    no_blinking
        SetOutputColor  BLINKING
        goto    after_lowbatlowtape
no_blinking               
        SetOutputColor  NOT_BLINKING
   
after_lowbatlowtape
main_exit   
        goto    main_loop

main_cfg_start
                bcf     state, STATE_ZOOMCFG
                bcf     state, STATE_ZOOMDOWN
SetOutputColor GREEN
SetOutputColor FAST_BLINKING

clrf    cfg_zoom
clrf    cfg_zoom+1

; btfss state, STATE_ZOOMDOWN
; goto main_cfg_go_to_zoom_cfg
;
; call sub_zoom_down

;main_cfg_go_to_zoom_cfg;
; bcf state, STATE_ZOOMDOWN
; call    sub_zoom_up
main_cfg     

        btfss   state, STATE_CFG
        goto    main_loop
       
        btfss   Button
        call    sub_handle_button_cfg
       
        btfsc   state2, STATE2_YAESTACFG
        goto    main_cfg_no_zoom
        btfss   state, STATE_ZOOMCFG
        goto    main_cfg_no_zoom
       
        ; resto o sumo
        btfss   state, STATE_ZOOMDOWN
        goto    cfg_button_suma
        goto    cfg_button_resta
cfg_button_suma
        call    sub_zoom_cnt_up
        ;incfsz  cfg_zoom, 1
        ;goto    cfg_mandar_frame
        ;movlw   0xff
        ;movwf   cfg_zoom
        goto    cfg_mandar_frame
cfg_button_resta
        call    sub_zoom_cnt_down
        ;decf    cfg_zoom, 1
        ;movlw   0xff
        ;subwf   cfg_zoom, 0
        ;btfss   STATUS,Z
        ;goto    cfg_mandar_frame
        ;movlw   0x00
        ;movwf   cfg_zoom
       
cfg_mandar_frame       
        ; mando zoom cmd
        movlw   0x28                            ; Initialize frame to send
        movwf   frame
        btfss   state, STATE_ZOOMDOWN
        movlw   COMMAND_ZOOM_UP_CFG                            ; Initialize frame to send
        btfsc   state, STATE_ZOOMDOWN
        movlw   COMMAND_ZOOM_DOWN_CFG                           ; Initialize frame to send
        movwf   frame+1
       
        ; send frames to get info 5 times, and every time check for button   
        call sub_transmit_frame
main_cfg_no_zoom       
        goto    main_cfg

; --------------------------------------------------------------------------
; Interrupt handler
;

label_handle_int:
    ; here goes timer interrupt handle
    ; encontrar el bit de la interrpcion
    btfss   INTCON, T0IE
    goto    handle_int_next1
    btfsc   INTCON, T0IF
    goto    int_timer
    goto    handle_int_next1
    ;btfsc   INTCON, RBIF
    ;goto    int_rb
    ;btfsc   INTCON, INTF
    ;goto    int_inf
;int_rb
    ;bcf     INTCON, RBIF
    ;retfie
;int_inf
    ;bcf     INTCON, INTF
int_timer   
    movlw   D'256'-D'38'
    movwf   TMR0
    btfsc   flags, FLG_TRANSMIT
    goto    transmit
    ;  aca recibiria
    btfss   flags, FLG_HALFBIT
    goto    recv_52
    btfss   flags, FLG_BYTESTOP
    goto    recv_104
recv_delay:
    decfsz  counter2,1
    goto    transmit_exit
    bsf     flags, FLG_BYTEDONE
    goto    transmit_exit
recv_104:
    bcf     flags, FLG_HALFBIT
    decfsz  counter2, 1
    goto    transmit_exit
    movlw   D'2'
    movwf   counter2
    bsf     flags, FLG_BYTESTOP
    goto    transmit_exit
recv_52:   
    btfss   flags, FLG_STARTBIT
    goto    recv_nostart
    movlw   D'8'
    movwf   counter2
    bcf     flags, FLG_STARTBIT
    bsf     flags, FLG_HALFBIT
    goto    transmit_exit
recv_nostart:
    btfsc   PORT_LANC, BIT_LANC
    bcf     STATUS, C                         ; si el bit esta en 1 lo pongo en 0
    btfss   PORT_LANC, BIT_LANC
    bsf     STATUS, C                         ; si el bit esta en 0 lo pongo en 1
    rrf     INDF,1
    bsf     flags, FLG_HALFBIT
    goto    transmit_exit
   
transmit:
    ; incremente half bit ( 104 )
    btfss   flags, FLG_HALFBIT
    goto    transmit_52
    btfss   flags, FLG_BYTESTOP
    goto    transmit_104
transmit_delay:
    bsf     PORT_LANC,BIT_LANC         
    movlw   D'256'-D'38'
    movwf   TMR0
    decfsz  counter2,1
    bsf     flags, FLG_BYTEDONE
    goto    transmit_exit
   
    ; 52us   
transmit_104   
    ; output to the bit
    movf    PORT_LANC,0
    movwf   port_lanc_temp
    btfsc   frame_tmp, 0
    bcf     port_lanc_temp,BIT_LANC          ; si el bit esta en 1 lo pongo en 0
    btfss   frame_tmp, 0
    bsf     port_lanc_temp,BIT_LANC          ; si el bit esta en 0 lo pongo en 1
    movf    port_lanc_temp, 0
    movwf   PORT_LANC
    movlw   D'256'-D'38'
    movwf   TMR0
    bcf     flags, FLG_HALFBIT
    rrf     frame_tmp, 1
    decfsz  counter2, 1
    goto    transmit_exit
    movlw   D'2'
    movwf   counter2
    bsf     flags, FLG_BYTESTOP
    goto    transmit_exit
transmit_52: ;(104us)
    btfss   flags, FLG_STARTBIT
    goto    transmit_nostart
    movlw   D'8'
    movwf   counter2
    movf    INDF,0
    movwf   frame_tmp
    bcf     PORT_LANC, BIT_LANC     ; inicializo a 0 el output latch por si despues
                                    ; tengo q poner en el puerto un cero
    bsf     STATUS,RP0              ; selecciona bank1
    bcf     PORT_LANC, BIT_LANC     ; Bit 0 is output
    bcf     STATUS,RP0              ; selecciona bank0
    bcf     flags, FLG_STARTBIT
transmit_nostart:   
    movlw   D'19'
    btfsc   flags, FLG_BYTESTOP
    sublw   D'9'
    addwf   TMR0,1                  ; ajuste para q envio a los 104us
    bsf     flags, FLG_HALFBIT
transmit_exit:
    ; prepare the next bit
    bcf     INTCON, T0IF
    retfie
handle_int_next1
        bsf     STATUS,RP0              ; Bank1
        btfss   PIE1, TMR1IE           
        goto    handle_int_next2
        bcf     STATUS,RP0              ; Bank0
        btfsc   PIR1, TMR1IF
        goto    int_timer1
        goto    handle_int_next2
int_timer1
    bcf     PIR1, TMR1IF
    movlw   HIGH(TMR1)
    movwf   TMR1H
    movlw   LOW(TMR1)
    movwf   TMR1L

    decfsz  led_blk_int_cnt,1
    retfie
   
    movf    led_blk_int,0
    movwf   led_blk_int_cnt
   
    btfss   state, STATE_LED
    goto    put_pos1_on_port
put_pos2_on_port   
    movlw   #led_pos_2
    bcf     state, STATE_LED
    goto    handle_timer1_resume   
put_pos1_on_port
    movlw   #led_pos_1
    bsf     state, STATE_LED
handle_timer1_resume   
    movwf   FSR
   
    btfss   INDF,0
    goto    leds_off
    btfsc   INDF,1
    goto    leds_red
leds_green
    bcf     PORT_LED,BIT_LED1
    bsf     PORT_LED,BIT_LED2
    retfie
leds_red
    bsf     PORT_LED,BIT_LED1
    bcf     PORT_LED,BIT_LED2
    retfie
leds_off   
    bcf     PORT_LED,BIT_LED1
    bcf     PORT_LED,BIT_LED2
    retfie     
handle_int_next2
        bcf     STATUS,RP0              ; Bank0
        btfss   INTCON, INTE
        goto    handle_int_next3
        btfsc   INTCON, INTF
        goto    int_intext
        goto    handle_int_next3
int_intext       
        call    sub_handle_button
        bcf     INTCON, INTF
        retfie
handle_int_next3
        retfie       

; --------------------------------------------------------------------------
; Sub routines
;
;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Rutina de envio de frames
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub_transmit_frame:
        ; Desabilito TMR1 INT
        ;bsf     STATUS,RP0              ; Bank1
        ;bcf     PIE1, TMR1IE           
        ;bcf     STATUS,RP0              ; Bank0
        bcf     INTCON, INTE            ; Desabilito boton
        ; hay q esperar q pase todo un frame..
        bsf     STATUS,RP0              ; selecciona bank1
        bsf     PORT_LANC, BIT_LANC     ; Bit 0 is input
        bcf     STATUS,RP0              ; selecciona bank0
reset_counter
        ; reseteo contador
        btfss   Button
        goto    transmit_frame_button
        goto    no_transmit_frame_button
transmit_frame_button
        btfsc   state, STATE_ZOOMCFG
        goto    transmit_frame_button_zoomcfg
        goto    transmit_frame_button_nozoomcfg
transmit_frame_button_zoomcfg
        call    sub_handle_button_cfg
        goto    transmit_frame_button_finish
transmit_frame_button_nozoomcfg
        btfsc   state, STATE_CFG
        goto    no_transmit_frame_button
        call    sub_handle_button
transmit_frame_button_finish
        ;bsf     STATUS,RP0              ; Bank1
        ;bcf     PIE1, TMR1IE           
        ;bcf     STATUS,RP0              ; Bank0
no_transmit_frame_button
        movlw   D'226'      
        movwf   counter     
        ; si la entrada es 0, empieza a contar otra vez, sino incrementa counter
sigo_viendo_entrada   
        btfss   PORT_LANC, BIT_LANC     ; 1TC (2TC)
        goto    reset_counter
        nop                             ; 1TC
        nop                             ; 1TC
        nop                             ; 1TC
        ; si counter es menor a < 1800us, seguir viendo la entrada
        decfsz  counter,1               ; 1TC (2TC) - 8*(counter-1)
        goto    sigo_viendo_entrada     ; 2TC
       
        ; espero el start bit   (aca pasaron 1800us aprox), osea q tengo q esperar al proximo startbin
        ; Desabilito TMR1 INT
        bsf     STATUS,RP0              ; Bank1
        bcf     PIE1, TMR1IE           
        bcf     STATUS,RP0              ; Bank0
       
        movlw   D'008'
        movwf   counter
        movlw   #frame
        movwf   FSR
        clrf    flags
        bsf     flags, FLG_TRANSMIT
espero_startbit   
        bsf     STATUS,RP0              ; selecciona bank1
        bsf     PORT_LANC, BIT_LANC     ; Bit is input
        bcf     STATUS,RP0              ; selecciona bank0
espero_startbit_2
        btfsc   PORT_LANC, BIT_LANC     ; 1TC (2TC)
        goto    espero_startbit_2       ; 2TC
        ; aca llego el startbit
        ; inicializo el timer (52us) ( 2 de escritura al precaler, el codigo para enviar el dato al puerto)
        movlw   D'256'-D'38'
        movwf   TMR0
        bcf     INTCON, T0IF
        bsf     INTCON, T0IE                ; habilita la interrupcion del timer0
        bsf     flags, FLG_STARTBIT

; espe  ro q la interrupcion del timer termine su trabajo
espero_byte_int
        btfss   flags, FLG_BYTEDONE
        goto    espero_byte_int
        bcf     flags, FLG_BYTEDONE
        bcf     flags, FLG_BYTESTOP
        bcf     flags, FLG_STARTBIT
        bcf     flags, FLG_HALFBIT
        bcf     INTCON, T0IE                ; Desabilita la interrupcion del timer0
        incf    FSR,1
        decfsz  counter,1
        goto    seguir
        goto    sub_frame_exit
seguir
        movf    counter,0
        sublw   D'04'
        btfsc   STATUS,Z
        bcf     flags, FLG_TRANSMIT
        goto    espero_startbit
sub_frame_exit
        ;bcf     INTCON, INTF            ; Borro porq aca me empiezo a fijar
        ;bsf     INTCON, INTE            ; Desabilito boton
        ; Desabilito TMR1 INT
        bsf     STATUS,RP0              ; Bank1
        bsf     PIE1, TMR1IE           
        bcf     STATUS,RP0              ; Bank0
        return   
       
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Rutina de antirebote y contador de pusador apretado para
;       funcionamiento normal
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub_handle_button:
        bsf     STATUS,RP0              ; Bank1
        bsf     PIE1, TMR1IE           
        bcf     STATUS,RP0              ; Bank0
        movlw   D'20'
        movwf   counter2
handle_button_2

        movlw   D'200'
        movwf   counter
        btfsc   Button
        goto    handle_no
        decfsz  counter,1
        goto    $-3
        decfsz  counter2,1
        goto    handle_button_2
       
        ; este es para que en power on no rompa las bolas
        btfsc   flags, FLG_POWERONBUTTON
        goto    handle_button_2
       
        clrf    button_cnt
button_still_pressed_1
        movlw   D'100'
        movwf   counter2
button_still_pressed   
        btfsc   Button
        goto    button_released
        movlw   D'0'
        movwf   counter
loop_handle_btn1
        ; check timer1
        ;btfsc   PIR1, TMR1IF
        ;call    handle_timer1
        nop
        decfsz  counter,1
        goto    loop_handle_btn1
        decfsz  counter2,1
        goto    button_still_pressed
        incfsz  button_cnt, 1
        ; aca voy a ver si el tipo quiere configurar :)
        movlw   D'55'
        subwf   button_cnt,0
        btfsc   STATUS,C
        goto    button_cmd_cfg
        ;goto    button_still_pressed_1
        ; aca si la quiere apagar
        movlw   D'25'
        subwf   button_cnt,0
        btfsc   STATUS,C
        goto    button_cmd_off
        movlw   D'8'
        subwf   button_cnt,0
        btfsc   STATUS,C
        goto    button_cmd_zoom
        goto    button_still_pressed_1
button_cmd_zoom
        SetOutputColor FAST_BLINKING
        btfss   state, STATE_ZOOMDOWN
        goto    button_zoomup
        goto    button_zoomdown
button_zoomup       
        SetOutputColor  GREEN
        goto    button_still_pressed_1
button_zoomdown
        SetOutputColor  RED
        goto    button_still_pressed_1
button_cmd_off       
        SetOutputColor OFF
        goto    button_still_pressed_1
button_cmd_cfg       
        SetOutputColor  FAST_ALTER
        movlw   D'55'
        movwf   button_cnt
        goto    button_still_pressed_1
button_released
        movlw   D'55'
        subwf   button_cnt,0
        btfsc   STATUS,C
        goto    cmd_cfg
        movlw   D'25'
        subwf   button_cnt,0
        btfsc   STATUS,C
        goto    cmd_off
        movlw   D'8'
        subwf   button_cnt,0
        btfsc   STATUS,C
goto    cmd_zoom
        goto    cmd_default
cmd_off
        movlw   0x5E
        movwf   command
        bsf     state, STATE_OFF
        goto    cmd_skip
cmd_zoom      
        bsf     state, STATE_ZOOM
        goto    cmd_skip
cmd_default
        movlw   0x33
        movwf   command
        goto    cmd_skip
cmd_cfg
        bsf     state, STATE_CFG
cmd_skip
handle_exit
handle_no
        ; antirebote cuando suelto
        movlw   D'20'
        movwf   counter2
handle_button_delay_exit
        movlw   D'200'
        movwf   counter
        decfsz  counter,1
        goto    $-1
        decfsz  counter2,1
        goto    handle_button_delay_exit
        bcf     flags, FLG_POWERONBUTTON
        return
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Rutina de antirebote y contador de pusador apretado para
;       funcionamiento en modo configuracion
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub_handle_button_cfg:
        bsf     STATUS,RP0              ; Bank1
        bsf     PIE1, TMR1IE           
        bcf     STATUS,RP0              ; Bank0
        movlw   D'20'
        movwf   counter2
cfg_handle_button_2
        movlw   D'200'
        movwf   counter
        btfsc   Button
        goto    cfg_handle_no
        decfsz  counter,1
        goto    $-3
        decfsz  counter2,1
        goto    cfg_handle_button_2
       
        clrf    button_cnt
cfg_button_still_pressed_1
        movlw   D'100'
        movwf   counter2
cfg_button_still_pressed   
        btfsc   Button
        goto    cfg_button_released
        movlw   D'0'
        movwf   counter
cfg_loop_handle_btn1
        ; check timer1
        ;btfsc   PIR1, TMR1IF
        ;call    handle_timer1
        nop
        decfsz  counter,1
        goto    cfg_loop_handle_btn1
        decfsz  counter2,1
        goto    cfg_button_still_pressed
        ; aca el tipo lo dejo apretado lo suficienta para configurar 1
        incfsz  button_cnt, 1
        movlw   D'15'
        subwf   button_cnt,0
        btfsc   STATUS,C
        goto    cfg_button_cmd_cfg_end
        ;movlw   D'11'
        ;subwf   button_cnt,0
        ;btfsc   STATUS,C
        ;goto    cfg_button_ya_toggeleo
        ;movlw   D'10'
        ;subwf   button_cnt,0
        ;btfsc   STATUS,C
        ;goto    cfg_button_cmd_toggle
        goto    cfg_button_still_pressed_1
cfg_button_cmd_cfg_end
        movlw   D'20'
        movwf   button_cnt
SetOutputColor FAST_ALTER
cfg_button_ya_toggeleo
        goto    cfg_button_still_pressed_1
cfg_button_cmd_toggle
;        m_BitToggle state, STATE_ZOOMDOWN       
        ; Aca en teoria cancelo el temario
        SetOutputColor  RED
        SetOutputColor  NOT_BLINKING
       
        ;SetOutputColor  ALTER
       
;        btfss   state, STATE_ZOOMDOWN
;        goto    cfg_button_zoomup
;        goto    cfg_button_zoomdown
; cfg_button_zoomup       
;        SetOutputColor  GREEN
;        goto    cfg_button_still_pressed_1
;cfg_button_zoomdown
;        SetOutputColor  RED
        goto    cfg_button_still_pressed_1
       
cfg_button_released
        movlw   D'15'
        subwf   button_cnt,0
        btfsc   STATUS,C
        goto    cfg_button_cfg_end_store
       
        ;movlw   D'10'
        ;subwf   button_cnt,0
        ;btfsc   STATUS,C
        ;goto    cfg_button_cfg_cancel
       

;        movlw   D'10'
;        subwf   button_cnt,0
;        btfsc   STATUS,C
;        goto    cfg_handle_no
       
        m_BitToggle state, STATE_ZOOMCFG
        btfss   state, STATE_ZOOMCFG
        bsf     state2, STATE2_YAESTACFG
        goto    cfg_handle_no
       
cfg_button_cfg_cancel       
call sub_zoom_down
        bcf     state, STATE_ZOOMCFG
        bcf     state2, STATE2_YAESTACFG
        SetOutputColor  GREEN
        SetOutputColor  FAST_BLINKING
       
        clrf    cfg_zoom
        clrf    cfg_zoom+1
       
        goto    cfg_handle_no
       
cfg_button_cfg_end_store
        BCF     INTCON, GIE ; Disable INTs.
        BSF     STATUS, RP0 ; Bank1

        ; write first byte
        movf    cfg_zoom, 0
        movwf   EEDATA
        movlw   EEPROM_CFG_ZOOM
        movwf   EEADR
        BSF     EECON1, WREN ; Enable Write
        MOVLW   0x55 ;
        MOVWF   EECON2 ; 55h must be written to EECON2
        MOVLW   0xAA ; to start write sequence
        MOVWF   EECON2 ; Write AAh
        BSF     EECON1,WR ; Set WR bit begin write
        btfsc   EECON1, WR
        goto    $-1
        ; write second byte
        movf    cfg_zoom+1, 0
        movwf   EEDATA
        movlw   EEPROM_CFG_ZOOM+1
        movwf   EEADR
        BSF     EECON1, WREN ; Enable Write
        MOVLW   0x55 ;
        MOVWF   EECON2 ; 55h must be written to EECON2
        MOVLW   0xAA ; to start write sequence
        MOVWF   EECON2 ; Write AAh
        BSF     EECON1,WR ; Set WR bit begin write
        btfsc   EECON1, WR
        goto    $-1
       
        BcF     STATUS, RP0 ; Bank0
        BSF     INTCON, GIE ; Enable INTs.

call sub_zoom_down

        bcf state, STATE_ZOOMDOWN
        bcf     state, STATE_CFG
               
cfg_handle_no
        ; antirebote cuando suelto
        movlw   D'20'
        movwf   counter2
cfg_handle_button_delay_exit
        movlw   D'200'
        movwf   counter
        decfsz  counter,1
        goto    $-1
        decfsz  counter2,1
        goto    cfg_handle_button_delay_exit
        return
   
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Rutina de envio del comando con ls 5 frames
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub_transmit_command:
movlw NUM_TRANSMIT_COMMAND
movwf sub_cnt
sub_transmit_command_loop
call sub_transmit_frame
decfsz sub_cnt, 1
goto sub_transmit_command_loop
return
       
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Rutina de inicializacion del microprocesador
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub_startup_microinit:
        ; Calibra el oscilador interno
        bsf     STATUS, RP0                     ;Bank 1
        call    3FFh                            ;Get the cal value
        movwf   OSCCAL                          ;Calibrate
        bcf     STATUS, RP0                     ;Bank 0
       
        ; TMR0
        bsf     STATUS,RP0                      ; selecciona bank1
        movlw   B'01011000'                     ; configura el timer
        movwf   OPTION_REG
        bcf     STATUS,RP0                      ; selecciona bank0
        bcf     INTCON, T0IE                    ; Desabilitada la int TMR0
       
        ; TMR1
        bsf     STATUS,RP0                      ; selecciona bank1
        bsf     PIE1, TMR1IE                    ; habilito interrupcion
        bcf     STATUS,RP0                      ; selecciona bank0
        bsf     INTCON, PEIE                    ; habilito interrupcion
                                                ; de perifericos
        movlw   HIGH(TMR1)                      ; Inicializo el timer
        movwf   TMR1H
        movlw   LOW(TMR1)
        movwf   TMR1L
        movlw   B'00000001'                     ; Configuro el TMR1
        movwf   T1CON
       
        ; PORTS
        CLRF    GPIO                            ; Initialize PORTA by
        movlw   07h                             ; Set GP<2:0> to digital IO
        movwf   CMCON                           ; => Desabilito el contador
        BSF     STATUS, RP0                     ; Bank 1
        BCF     PORT_LED, BIT_LED1              ; Led es salida
        BCF     PORT_LED, BIT_LED2              ; Led es salida
        BCF     STATUS, RP0                     ; Bank 0

        bsf     INTCON, GIE                     ; habilita interrupciones
       
        return
       
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Rutina de inicializacion de las variables
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub_startup_varinit:
        clrf    state
        clrf    state2
        clrf    command
        movlw   D'8'
        movwf   sub_cnt
        movlw   #frame
        movwf   FSR
sub_startup_varinit_loop
        clrf    INDF
        incf    FSR,1
        decfsz  sub_cnt,1
        goto    sub_startup_varinit_loop
        movlw   0x08
        movwf   led_blk_int
        movwf   led_blk_int_cnt

        BSF     STATUS, RP0                     ; Bank1
        MOVLW   EEPROM_CFG_ZOOM
        MOVWF   EEADR                           ; Address to read
        BSF     EECON1, RD                      ; EE Read
        MOVF    EEDATA, W                       ; W = EEDATA
        BCF     STATUS, RP0                     ; Bank0
        movwf   cfg_zoom
       
        BSF     STATUS, RP0                     ; Bank1
        MOVLW   EEPROM_CFG_ZOOM+1
        MOVWF   EEADR                           ; Address to read
        BSF     EECON1, RD                      ; EE Read
        MOVF    EEDATA, W                       ; W = EEDATA
        BCF     STATUS, RP0                     ; Bank0
        movwf   cfg_zoom+1
       
        ; se fija si es la primera vez q corre, si es asi
        ; porq hay un cero en EEPROM_FIRSTRUN q graba el programador
        ; graba en EEPROM_FACTORY_OSCAL el OSCAL
        ; Esto es porq como voy a poner el CodeProtection, asi
        ; puedo obtener el OSCAL q estaba por factory settings de la EEPROM
        ; porq no voy a proteger la eeprom :)
        BSF     STATUS, RP0                     ; Bank1
        MOVLW   EEPROM_FIRSTRUN
        MOVWF   EEADR                           ; Address to read
        BSF     EECON1, RD                      ; EE Read
        MOVF    EEDATA, W                       ; W = EEDATA
        BCF     STATUS, RP0                     ; Bank0

        btfsc   STATUS, Z
        goto    sub_startup_varinit_storeoscal 
        goto    sub_startup_varinit_nostoreoscal
sub_startup_varinit_storeoscal       
        call    0x3ff
        BCF     INTCON, GIE ; Disable INTs.
        BSF     STATUS, RP0 ; Bank1
       
        movwf   EEDATA
        movlw   EEPROM_FACTORY_OSCCAL
        movwf   EEADR
        BSF     EECON1, WREN ; Enable Write
        MOVLW   0x55 ;
        MOVWF   EECON2 ; 55h must be written to EECON2
        MOVLW   0xAA ; to start write sequence
        MOVWF   EECON2 ; Write AAh
        BSF     EECON1,WR ; Set WR bit begin write
       
        btfsc   EECON1, WR
        goto    $-1
       
        movlw   0x01
        movwf   EEDATA
        movlw   EEPROM_FIRSTRUN
        movwf   EEADR
        BSF     EECON1, WREN ; Enable Write
        MOVLW   0x55 ;
        MOVWF   EECON2 ; 55h must be written to EECON2
        MOVLW   0xAA ; to start write sequence
        MOVWF   EECON2 ; Write AAh
        BSF     EECON1,WR ; Set WR bit begin write
       
        BcF     STATUS, RP0 ; Bank0
        BSF     INTCON, GIE ; Enable INTs.
sub_startup_varinit_nostoreoscal
        return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Lleva el coso a zoom up
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub_zoom_up
        movf cfg_zoom, 0
btfss STATUS, Z
goto sub_zoom_up_start_loop
movf cfg_zoom+1, 0
btfsc STATUS, Z
goto sub_zoom_up_cero
sub_zoom_up_start_loop
        movf cfg_zoom+1, 0
        movwf   sub_cnt2
        movf cfg_zoom, 0
        movwf   sub_cnt3
sub_zoom_up_loop_1
        movlw   0x28                            ; Initialize frame to send
        movwf   frame
        movlw   COMMAND_ZOOM_UP                 ; Initialize frame to send
        movwf   frame+1

        call    sub_transmit_frame
        ;call    sub_transmit_command
        ;call    sub_transmit_command

;        movlw   0x18                            ; Initialize frame to send
;        movwf   frame
;        movlw   0x00   
;        movwf   frame+1

;        call    sub_transmit_frame
;        call    sub_transmit_frame
;        call    sub_transmit_frame
       
        decfsz  sub_cnt3,1
        goto    sub_zoom_up_loop_1
movf sub_cnt2, 0
btfsc STATUS, Z
goto    sub_zoom_down_cero
        decf    sub_cnt2,1
        goto    sub_zoom_up_loop_1
sub_zoom_up_cero
return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Llleva el coso a zoom down
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub_zoom_down
        movf cfg_zoom, 0
btfss STATUS, Z
goto sub_zoom_down_start_loop
movf cfg_zoom+1, 0
btfsc STATUS, Z
goto sub_zoom_down_cero

sub_zoom_down_start_loop
        movf cfg_zoom+1, 0
        movwf   sub_cnt2
        movf cfg_zoom, 0
        movwf   sub_cnt3
sub_zoom_down_loop_1
        movlw   0x28                            ; Initialize frame to send
        movwf   frame
        movlw   COMMAND_ZOOM_DOWN                 ; Initialize frame to send
        movwf   frame+1
       
        call    sub_transmit_frame
        ;call    sub_transmit_command
        ;call    sub_transmit_command

;        movlw   0x18                            ; Initialize frame to send
;        movwf   frame
;        movlw   0x00   
;        movwf   frame+1

        ;call    sub_transmit_frame
        ;call    sub_transmit_frame
        ;call    sub_transmit_frame
               
        decfsz  sub_cnt3,1
        goto    sub_zoom_down_loop_1
movf sub_cnt2, 0
btfsc STATUS, Z
goto    sub_zoom_down_cero
        decf    sub_cnt2,1
        goto    sub_zoom_down_loop_1
sub_zoom_down_cero

return

; Descomentar las siguientes lineas si el dispositivo
; ya lo grabamos y queremos volverlo a grabar, si es q tenia
; el code protection activado
; Recordar q en la posicion dos de la EEPROM esta el valor
; q hay q poner en el RETLW... es el OSCCAL q venia por defecto
        ;ORG     0x3FF
        ;retlw   0x9C               
       
sub_zoom_cnt_up
        incfsz  cfg_zoom,1
        goto    sub_zoom_cnt_up_end
        incfsz  cfg_zoom+1,1
        goto    sub_zoom_cnt_up_end
        movlw   0xff
        movwf   cfg_zoom
        movwf   cfg_zoom+1
sub_zoom_cnt_up_end
        return       

sub_zoom_cnt_down
        decf    cfg_zoom,1
        movlw   0xff
        subwf   cfg_zoom, 0
        btfss   STATUS,Z
        goto    sub_zoom_cnt_down_end
        decf    cfg_zoom+1,1
        movlw   0xff
        subwf   cfg_zoom+1, 0
        btfss   STATUS,Z
        goto    sub_zoom_cnt_down_end
        clrf    cfg_zoom
        clrf    cfg_zoom+1
sub_zoom_cnt_down_end
        return       

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       Fin de codigo de programa
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        end