;27NOV07 ;DEVICE = 16F628A ;Jammerdan - aka Silencer. Control a LMX2306 PLL and VCO to jam FM broadcasts. Tunes to 107.9 MHz then steps down to 87.2 MHz. ;TODO: Detector to lock onto offending portable and a lightshow. LIST P=16F628a, F=INHX8M #include __CONFIG 0x2001 ; XT OSC, RA5-MCLR ; Equates RESET_V EQU 0x00 ; Address of RESET Vector OSC_FREQ EQU D'4000000' ; Oscillator Frequency is 4 MHz ; Registers PLLHI EQU 0x20 ; MSB of PLL N-Divider Word PLLLO EQU 0x21 ; LSB (Swallow Counter) of PLL N-Divider Word. Max value 0x07. Must be left-shifted before outputting. GPCTR EQU 0x22 ; General Purpose Counter DATABYTE EQU 0x23 ; Databyte to be output on the dataline (gets destroyed) #define PLL_DATA PORTB,5 #define PLL_CLK PORTB,6 #define PLL_LE PORTB,4 ;************************************************************** ; Begin Program ;************************************************************** ORG RESET_V ; RESET vector location RESET GOTO START ORG 4 ; INT vector ;************************************************************** ; Initialization Routine ;************************************************************** START ; POWER_ON Reset (Beginning of program) CLRF STATUS ; Do initialization, Select bank 0 CLRF INTCON ; Clear int-flags, Disable interrupts CLRF PCLATH ; Keep in lower 2KByte BSF STATUS, RP0 ; Select bank 1 MOVLW 0xFF MOVWF TRISA ; RA7-0 Inputs (Except RA6-CLKOUT) CLRF TRISB ; RB7-0 Outputs BCF STATUS, RP0 ; Select bank 0 CLRF PORTB ; Make all PORT B outputs low CLRF PORTA GOTO MAIN ;************************************************************** ; Subroutines ;************************************************************** PLL_INIT ; Initialization Word: 000000000010010100011 BSF PLL_LE BCF PLL_LE ; Latch Data. This may be unnecessary MOVLW 0x0A ; Output Ten Zeroes F19:F10 MOVWF GPCTR CALL OUT_ZEROES MOVLW 0x94 ; Output 10010100 MOVWF DATABYTE CALL OUT_BYTE ; F9:F2 CALL OUT_ZERO ; F1 CALL OUT_ONE ; C2 CALL OUT_ONE ; C1 BSF PLL_LE ; Latch Data BCF PLL_LE MOVLW 0x0D ; Output 13 Zeroes, Reference Divider Word: 000000000000010100000 MOVWF GPCTR ; yields divide by 40 giving a PLL frequency of 100 kHz CALL OUT_ZEROES MOVLW 0xA0 ; Output 10100000 MOVWF DATABYTE CALL OUT_BYTE ; C2 & C1 are both zero BSF PLL_LE ; Latch Data BCF PLL_LE RETURN PLL_LOAD CALL OUT_ZERO ; Clear GO bit MOVLW 0x05 ; Output Five Zeroes N18:N14 MOVWF GPCTR CALL OUT_ZEROES MOVFW PLLHI ; Get the N-Counter N13:N6 bits MOVWF DATABYTE ; Load into DATABYTE CALL OUT_BYTE CALL OUT_ZERO ; N5 CALL OUT_ZERO ; N4 MOVFW PLLLO ; Get the swallow counter: N3:1 (Note: offset by 1!) MOVWF DATABYTE ; Load into DATABYTE CALL OUT_PLLLO CALL OUT_ZERO ; C2 CALL OUT_ONE ; C1 BSF PLL_LE ; Latch Data BCF PLL_LE RETURN OUT_ZERO BCF PLL_DATA BSF PLL_CLK BCF PLL_CLK RETURN OUT_ZEROES ; Output string of zeroes, load GPCTR with the number CALL OUT_ZERO DECFSZ GPCTR,1 ; Test if all zeroes have been output GOTO OUT_ZEROES ; No, still one or more to go RETURN ; Yes, done OUT_ONE BSF PLL_DATA BSF PLL_CLK BCF PLL_CLK RETURN OUT_BYTE ; Output a byte, which sits in DATABYTE MOVLW 0x08 MOVWF GPCTR OUT_BYTE1 RLF DATABYTE,1 ; Leftrotate into Carry BTFSC STATUS,C ; Test Carry CALL OUT_ONE ; Carry was set, output a 1 BTFSS STATUS,C ; Test Carry Again CALL OUT_ZERO ; Carry was cleared, output a 0 DECFSZ GPCTR,1 ; Test if eight bits have been output GOTO OUT_BYTE1 RETURN OUT_PLLLO ; Only used to output the three bits for the swallow counter DECF DATABYTE,1 ; Compensate for zero test in MAIN (ugly) SWAPF DATABYTE,1 ; Prepare DATABYTE for output RLF DATABYTE,1 ; Shift five bits to the left MOVLW 0x03 MOVWF GPCTR GOTO OUT_BYTE1 RETURN ; Bad programming. Redundant RETURN just in case ;************************************************************** ; Main Routine ;************************************************************** MAIN CALL PLL_INIT FREQSTART MOVLW 0x86 MOVWF PLLHI MOVLW 0x08 ; Divider set to 1079 MOVWF PLLLO FREQSET CALL PLL_LOAD MOVLW 0xFF MOVWF GPCTR LOOP ; Settle PLL NOP MOVWF DATABYTE ; Unauthorized use of DATABYTE as a counter... LOOP1 NOP NOP DECFSZ DATABYTE,1 GOTO LOOP1 NOP NOP DECFSZ GPCTR,1 GOTO LOOP DECFSZ PLLLO,1 GOTO FREQSET ; Not yet zero, continue scanning down MOVLW 0x08 MOVWF PLLLO ; Reset swallow counter to 7+1 DECF PLLHI,1 MOVLW 0x6D ; Divider set to 872 SUBWF PLLHI,0 ; Test value of PLLHI, result goes to WREG BTFSC STATUS,Z ; Test for Zero bit in STATUS GOTO FREQSTART ; Start new scan GOTO FREQSET ; Continue scanning down END