;********************************************************************** ; * ; Filename: bikelightv2.asm * ; Date: 17/09/2009 * ; File Version: 1 * ; * ; Author: Pete Griffiths * ; Company: Picprojects * ; * ; Written for: picprojects.org.uk * ; * ;********************************************************************** ; This program code is free for individual use only * ; * ; It my NOT be used for commercial use or resale * ; or any other purpose in which you make financial gain by the * ; direct or indirect use of this application code. * ; Providing the 'code' free and charging for parts, programming, * ; labour or shipping of any product or part that makes use of this * ; program code or a modified version of it is strictly forbidden * ; * ;********************************************************************** ; * ; IMPORTANT: Use of program memory above first 256 words * ; * ; This code will assemble for a 10F202 (512 program memory words) * ; However, the baseline PIC can only use the 'call' instruction to * ; access the code space in the first 256 program memory locations. * ; * ; If mode data is added to the lookup tables so that the program * ; code enters the upper 256 program memory locations the code will * ; not run correctly, or at all. * ; * ; * ; * ;********************************************************************** ; * ; Notes: PDIP package pin functions * ; * ; n/c -|1 8|- GP3 Switch * ; (+V) Vdd -|2 7|- Vss (-V) * ; LED3 GP2 -|3 6|- n/c * ; LED2 GP1 -|4 5|- GP0 LED1 * ; * ; * ; Notes: SOT-23 package pin functions * ; * ; LED1 GP0 -|1 6|- GP3 Switch * ; (-V) Vss -|2 5|- Vdd (+V) * ; LED3 GP1 -|3 4|- GP2 LED3 * ; * ; * ;********************************************************************** ifdef __10F200 list p=10F200 ; list directive to define processor #include ; processor specific variable definitions endif ifdef __10F202 list p=10F202 ; list directive to define processor #include ; processor specific variable definitions endif __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF ; GP3/MCLR is I/O pin ; Code protect off ; Watchdog timer off ;***** VARIABLE DEFINITIONS ; GPR starts at 0x0C for 10F202 / 10F206 0x0C to 0x1F = 24 bytes ; GPR starts at 0x10 for 10F200 / 10F204 0x10 to 0x1F = 16 bytes cblock 0x10 delay.loop.in delay.loop.out switch.timer hold.timer led.state mode index index.base mask endc ; Name bits pb.switch equ 3 ; port bit for switch pb.led1 equ 0 ; port bit for LED1 pb.led2 equ 1 ; port bit for LED2 pb.led3 equ 2 ; port bit for LED3 multiplex equ 7 ; multiplex flag bit pson equ 1<2 addwf switch.timer,W clrf switch.timer ; always reset the timer to 0 skpc ; timer value greater than filer so run switch.pressed function goto lights ; timer value less than filter so just run light function ;------------------------------ ; This code will run once after the switch is released following a valid press incf mode,F ; increment state call max.mode ; compare it to highest mode subwf mode,W ; skpnc ; skip next if state less than highest mode clrf mode ; otherwise reset back to state 0 call select.mode ; lookup start address of table data for next mode movwf index ; save start address to index movwf index.base ; and also to index.base goto reload ; jump straight to reload to setup start of new mode ; LED function select ;------------------------------ ; While switch is down, increment switch.timer ; If it reaches 100 (20mS x 100 = 2S) then turn off and sleep ; otherwise continue to run the normal lights function code. switch.down btfsc switch.timer,7 ; if we wake from sleep, this bit is set goto lights ; so we don't select the next mode each time it wakes. incf switch.timer,F movlw -.100 addwf switch.timer,W skpc goto lights ; Switch held for 2S so turn off clrf GPIO clrf led.state btfss GPIO, pb.switch goto $-1 call delay movf GPIO,W bcf STATUS, GPWUF sleep ;-------------------------------------------------------- ; standard inner/outer counter loop delay ; 4Mhz clock / delay movlw .26 ; gives delay of ~20.2mS movwf delay.loop.out ; inner loop delay.loop decfsz delay.loop.in,F ; loop for 255 iterations goto $-1 ; multiplex the LED drive to improve battery life ; multiplex bit in the LED data determines whether only the masked led.state LED ; is riven or the led.state is output directly to GPIO. ; For light effects where only single LED is on, or where you want the brightness over power saving ; there is no need to multiplex the LED. To reduce battery load use multiplex drive rrf mask,F skpnc bsf mask,2 movfw mask andwf led.state,W btfss led.state, multiplex ; if multiplex flag bit clear movfw led.state ; don't multiplex the LED drive movwf GPIO ; outer loop decfsz delay.loop.out,F goto delay.loop retlw 0x00 ;------------------------------ ; Indexed table lookup function lights decfsz hold.timer,F ; decrement the led timer goto main ; loop until it reaches zero reload call lookup ; lookup next led timer value movwf hold.timer ; and save iorlw 0x00 ; test if it was 0? skpnz ; if not skip next goto reset.index ; if it was goto reset.index call lookup ; lookup next led data movwf led.state ; and save goto main ; otherwise we keep going with the next data in the sequence reset.index movfw index.base ; load the base.index value into W movwf index ; and put in the working index goto reload ; then reload with the first line of data in the sequence lookup movfw index ; take the absolute address held in index and put in W incf index,F ; then index = index+1 ready for next line of data movwf PCL ; and put W into PCL. This will force program execution ; to start from the address held in index (which will be a ; retlw 0x00 instruction in the sequence data table) if ($>0xFE) error "Code found in upper 256 program memory words, see notes at top of this .ASM file" endif end