;********************************************************************** ; This file is the code for a ML-L3 remote control used to shoot * ; pictures remotely on a Nikon DSLR. Optimized for code size * ; having 50% duty cycle in ON cycle (15us-9us for 24 us period) * ; 39 program words with 0 RAM occupied * ; * ; Refer to the MPASM User's Guide for additional information on * ; features of the assembler (Document DS33014). * ; * ; Refer to the respective PIC data sheet for additional * ; information on the instruction set. * ; * ;********************************************************************** ; * ; Filename: ML-L3.asm * ; Date: 16.03.2018 * ; File Version: v1.1 * ; * ; Author: Calin Bira (calin.bira@upb.ro) * ; Company: Politechnica University of Bucharest (ETTI-DCAE) * ; * ; * ;********************************************************************** ; * ; Files Required: P10F200.INC * ; * ;********************************************************************** list p=10F200 ; list directive to define processor #include ; processor specific variable definitions ;__CONFIG _MCLRE_ON & _CP_OFF & _WDT_OFF ; '__CONFIG' directive is used to embed configuration word within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ;***** VARIABLE DEFINITIONS ; Prescaler Values: ; 0 -> 1:2 @ 8bit & 1MHz => 256 * 2 us ; 1 -> 1:4 ; 2 -> 1:8 ; 3 -> 1:16 ; 4 -> 1:32 ; 5 -> 1:64 ; 6 -> 1:128 ; 7 -> 1:256 #define TMR_SOURCE_1MHz 0xC0 #define PVAL0 0x02 #define PVAL1 0x04 #define PVAL2 0x08 #define PVAL3 0x10 #define PVAL4 0x20 #define PVAL5 0x40 #define PVAL6 0x80 #define PVAL7 0x100 #define PRESCALER(x) (D'256' * (x)) #define PRESCALER_0_US PRESCALER(PVAL0) #define PRESCALER_1_US PRESCALER(PVAL1) #define PRESCALER_2_US PRESCALER(PVAL2) #define PRESCALER_3_US PRESCALER(PVAL3) #define PRESCALER_4_US PRESCALER(PVAL4) #define PRESCALER_5_US PRESCALER(PVAL5) #define PRESCALER_6_US PRESCALER(PVAL6) #define PRESCALER_7_US PRESCALER(PVAL7) ; 500us <-> 3500us may be counted with a single prescaler of 16 ; (precision: 16 us, that is, better than 0.8 %) ; 27800us <-> 63000us may be counted with a single prescaler of 256 ; (precision: 256 us, that is, better than 0.3 %) #define _500us D'500' #define _1500us D'1500' #define _2000us D'2000' #define _3500us D'3500' #define _27800us D'27800' #define _63000us D'63000' ; use these for approx timings: #define TMR_VALUE_500 ((PRESCALER_3_US - _500us + PVAL3 - 1)/PVAL3) #define TMR_VALUE_1500 ((PRESCALER_3_US - _1500us + PVAL3 - 1)/PVAL3) #define TMR_VALUE_2000 ((PRESCALER_3_US - _2000us + PVAL3 - 1)/PVAL3) #define TMR_VALUE_3500 ((PRESCALER_3_US - _3500us + PVAL3 - 1)/PVAL3) #define PRESCALER_VALUE_SMALL 3 #if (PRESCALER_3_US < _3500us) ERROR PRESCALER_TOO_LOW #endif #define TMR_VALUE_27800 ((PRESCALER_7_US - _27800us + PVAL7 -1)/PVAL7) #define TMR_VALUE_63000 ((PRESCALER_7_US - _63000us + PVAL7 -1)/PVAL7) #define PRESCALER_VALUE_LARGE 7 #if (PRESCALER_7_US < _63000us) ERROR PRESCALER_TOO_LOW #endif ;********************************************************************** ORG 0x000 ; coding begins here command movlw TMR_VALUE_63000 TRIS 6 ; w will be an even number, initialize TRIS here to save one instruction call waste_time_off_large movlw TMR_VALUE_2000 call waste_time_on ;movlw TMR_VALUE_27800 will be retlw from waste_time_on() call waste_time_off_large ;call on_modulation_500 ;movlw TMR_VALUE_500 ;will be retlw from waste_time_off() call waste_time_on movlw TMR_VALUE_1500 call waste_time_off_small ;call on_modulation_500 ;movlw TMR_VALUE_500 ;will be retlw from waste_time_off() call waste_time_on movlw TMR_VALUE_3500 call waste_time_off_small ;call on_modulation_500 ;movlw TMR_VALUE_500 ;will be retlw from waste_time_off() call waste_time_on goto command waste_time_on movwf TMR0 movlw (TMR_SOURCE_1MHz + PRESCALER_VALUE_SMALL) OPTION gpio_loop ; should waste 15 + 9 cycles (ON or OFF) call toggle_GPIO_short call waste_4_cycles call waste_4_cycles goto $+1 call toggle_GPIO_short movf TMR0,w ; 1 cycle btfss STATUS,2 ; 1 cycle, check if bit ZERO is set; if yes, skip next instruction goto gpio_loop ; 2 cycles retlw TMR_VALUE_27800 waste_time_off_small movwf TMR0 movlw (TMR_SOURCE_1MHz + PRESCALER_VALUE_SMALL) goto waste_time_off waste_time_off_large movwf TMR0 movlw (TMR_SOURCE_1MHz + PRESCALER_VALUE_LARGE) ;goto waste_time_off ;not needed: fallthrough waste_time_off OPTION clrf GPIO ; GPIO = 0; reload_off movf TMR0,w btfss STATUS,2 goto reload_off retlw TMR_VALUE_500 toggle_GPIO_short comf GPIO,f waste_4_cycles retlw 0 END ; directive 'end of program'