; ---------------------------------------------------------- ; Pneuventures Shocker Electronics Package Upgrade Version 5 ; Edward Kang - ekang@cse.nd.edu ; ---------------------------------------------------------- ; Utilizing the ESP trigger electronics, which allows the gun to fire ; whether you pull the trigger during or after the current firing cycle. ; 12/7/98 - Learned that a valve delay of 10ms may be too long for this ; gun's regulator to keep up properly. A dwell of 10ms lets the gun fire ; balls at 280fps at 130-140psi. If I can jack that number up to 160-180psi ; with a 5ms dwell, I'll be happy (and so will the gun.) ; - Also learned that power brownouts can cause the chip to ; reset due to higher current draw at higher pressures. This is rather ; annoying. ; So, um...summary of pins and such: ; Port Summary: ; ; PORTA: 0 1 2 3 4 ; ; valve bolt Val+ Val- ; out out in in ; ; PORTB: 0 1 2 3 4 5 6 7 ; trigger valve wait boltop boltcl func ; in LED LED LED LED in ; out out out out PROCESSOR 16F84 LIST P=16F84 #include __CONFIG _CP_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC RAM EQU 0x10 TEMP1 EQU RAM+1 TEMP2 EQU RAM+2 TEMP3 EQU RAM+3 TEMP4 EQU RAM+4 LOOP1 EQU RAM+5 LOOP2 EQU RAM+6 ESPVAR EQU RAM+7 W_TEMP EQU RAM+8 ; Used for interrupts. STATUS_TEMP EQU RAM+9 ; Used for interrupts. org 000H goto init org 004H handler: goto int_serv org 0x30 init: bcf STATUS, RP1 ; Clear Page 1 bit. bsf STATUS, RP0 ; Set Page 0 bit. movlw B'00100001' movwf TRISB movlw B'00001100' movwf TRISA BCF STATUS, RP0 ; back to data bank 0 BCF OPTION_REG, NOT_RBPU ; set /RBPU bit: 1=disable weak pullups, 0=enable BSF OPTION_REG, INTEDG ; set to interrupt on rising edge of RB0. ;movlw D'55' Just a reminder on how to store values in mem. ;movwf BCCD3 clrw movwf ESPVAR ; So, um...summary of pins and such: ; Port Summary: ; ; PORTA: 0 1 2 3 4 ; ; valve bolt Val+ Val- ; out out in in ; ; PORTB: 0 1 2 3 4 5 6 7 ; trigger valve wait boltop boltcl func ; in LED LED LED LED in ; out out out out mainloop: bsf ESPVAR, 1 ; Set bit 1 of ESPVAR. This will be our first trigger pull. ; This is critical, otherwise weird stuff may happen. BSF OPTION_REG, INTEDG ; interrupt on positive BCF INTCON, INTF ; clear interrupt flag BSF INTCON, INTE ; enable interupts on RB0/INT BSF INTCON, RBIE ; enable change in RB4 - RB7 interrupt BSF INTCON, GIE ; global interrupt enable mainloop2: bcf PORTA, 0 ; Clear all solenoid outputs. bcf PORTA, 1 ; btfsc ESPVAR, 0 ; test to see if bit 0 for ESPVAR is clear goto fireseq ; If it is not clear, it is high, so we need to fire the gun. goto genericsleep ; Otherwise it _is_ clear, and it is low, so we just go back ; into sleep mode. genericsleep: bsf ESPVAR, 1 ; Set bit 1 of ESPVAR. This will be our first trigger pull. sleep ; Sleep, wait for trigger pull. ; Now wait. If we are re-activating after a sleep ; instruction, we are actually taking the first trigger pull ; after a pause. That means we have to tell the ESP system ; that this is the first trigger pull, so it doesn't set the ; ESPVAR:0 on the first pull (leading to two shots per pull). goto fireseq ; When trigger is pulled, go to fire the gun. fireseq: clrf ESPVAR ; Clear bit 0 of ESPVAR. This means, we are clearing ; the previous presence of an ESP activated firing ; sequence. ; And also clear bit 1 of ESPVAR. This means, we are ; clearing the fact that this was our first trigger ; pull. Mainly because...well, it's not if we're firing! movlw B'00000001' movwf PORTA movf FPD,0 movwf LOOP1 call beginloop movlw B'00000000' movwf PORTA movlw B'00000010' movwf PORTA movf BOOD,0 movwf LOOP1 call beginloop movlw B'00000000' movwf PORTA movf BCCD,0 movwf LOOP1 call beginloop ; Regardless of whether or not this is the first trigger pull or not, we need to ; clear that this was our first trigger pull. bcf ESPVAR, 1 goto mainloop2 ; ********************** ; ** END MAIN PROGRAM ** ; ********************** beginloop: movlw .200 movwf LOOP2 inner: nop nop nop decfsz LOOP2, F goto inner decfsz LOOP1, F goto beginloop return int_serv: ; This interrupt sequence only runs if there is a _positive_ change on the trigger, ; i.e. it has been pulled. We have two modes of operation: ; * Full auto - ; The gun fires continously, as long as the trigger is held down. ; That is, as long as PORTB:0 is high, we have to keep on firing the ; gun. That also means, that after every firing cycle, we have to ; check the status of PORTB:0. If it's low, we must cause the program ; to sleep. If it's still high, then we have to skip sleep. ; * Semi auto w/ ESP - ; The gun fires once every time the trigger is pulled. In addition, ; it will fire on the next cycle if the ESP variable is set. When the ; ESP variable is set, it should clear the ESP variable and then ; fire immediately. On the first trigger pull, it should not set the ; ESP variable. However, if the trigger is being pulled during a ; firing cycle, then the ESP variable must be set. MOVWF W_TEMP ; Copy W to TEMP register, SWAPF STATUS, W ; Swap status to be saved into W MOVWF STATUS_TEMP ; Save status to STATUS_TEMP register btfss ESPVAR, 1 ; So, was this our first trigger pull? ; If so, ESPVAR:1 is set, so we will skip the next ; instruction. bsf ESPVAR, 0 ; Otherwise, we are pulling the trigger during the ; firing cycle, so it is definitely time to set ESPVAR:0 ; and activate ESP!! SWAPF STATUS_TEMP, W ; Swap nibbles in STATUS_TEMP register ; and place result into W MOVWF STATUS ; Move W into STATUS register ; (sets bank to original state) SWAPF W_TEMP, F ; Swap nibbles in W_TEMP and place result in W_TEMP SWAPF W_TEMP, W ; Swap nibbles in W_TEMP and place result into W BCF INTCON, INTF ; clear the appropriate flag RETFIE ; this also set global interrupt enable END