; ******************************************************************************* ; * * ; * Si5351 Software to program LO 2 frequencies for Pic-A -Star rigs * ; * Modified from software by G8JVM by T Mowles VK5TM Feb/Mar 2015 * ; * * ; ******************************************************************************* ; * * ; * This program will initialize Si5351A-B-GT with a default frequency of * ; * 10.710MHz. Pulling pin 5 of the 12F629 low will change the frequency to * ; * 10.715MHz. NOTE: this must be done before power-up * ; * The 12F629 will then go to sleep * ; * * ; ******************************************************************************* ; ******************************************************************************* ; * Device type and options * ; ******************************************************************************* ; processor PIC12F629 ; directive to define processor #include ; processor specific variable definitions ; ******************************************************************************* __CONFIG _CP_OFF & _CPD_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT errorlevel -302 ; Turn off annoying Bank messages ; ******************************************************************************* ; * * ; * PIC12F629 * ; * _________ * ; * +3.3V------Vdd |1 8| Vss----GND * ; * SCL--------GP5 |2 7| GP0----ICSPDAT * ; * SDA--------GP4 |3 6| GP1----ICSPCLK * ; * MCLR/Vpp/--GP3 |4 5| GP2----Frequency select * ; * _________ * ; * * ; ******************************************************************************* ; ******************************************************************************* ; * Assign names to PIC IO pins * ; ******************************************************************************* ; ; GPIO Port Assignment: ; FREQ equ 0x02 ; Frequency select input SDA equ 0x04 ; I2C Data SCL equ 0x05 ; I2C Clock ; ******************************************************************************* ; * DATA MEMORY * ; ******************************************************************************* CBLOCK 20h count ; Gen purpose counter temp ; Temporary work register bytcnt ; used in i2c driver ebyte ; I2C device data to be sent ENDC ; ******************************************************************************* ; * PROGRAM START * ; ******************************************************************************* ORG 0x00 ;Reset vector address goto Start ORG 0x04 ; Interrupt Vector address goto Start ; ******************************************************************************* Start clrf INTCON ; Disable interrupts movlw H'07' ; Disable Comparator module movwf CMCON ; Initialise GPIO port for i2c ; First set all as inputs, then clear individual bits as outputs banksel TRISIO ; Switch to register bank 1 movlw H'FF' ; All inputs movwf TRISIO bcf TRISIO,SCL ; SCL set as output bcf TRISIO,SDA ; Set SDA as output clrf OPTION_REG ; General enable pullups (bit 7 clear) movlw H'4' ; Enable pullup on GPIO,2 movwf WPU ; call 0x3FF ; retrieve factory calibration value movwf OSCCAL banksel GPIO ; Switch to bank 0 clrf GPIO ; Resting state of i2c bus is SCL low, SDA high bsf GPIO,SDA ; Set SDA high bcf GPIO,SCL ; Set SCL low call wait_10ms ; Wait to be sure Si5351 completes power up ; ******************************************************************************* Sendsiregs call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'3' ; Address Register 3 movwf ebyte call putbyte ; Output byte and get ACK movlw H'FF' ; Register command - disable outputs movwf ebyte call putbyte ; Output byte and get ACK call stop ; Send Stop to Si5351 call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'187' ; Address Register 187 movwf ebyte call putbyte ; Output byte and get ACK clrf ebyte ; Register command - fanout enable call putbyte ; Output byte and get ACK call stop ; Send Stop to Si5351 call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'16' ; Address Register 16 movwf ebyte call putbyte ; Output byte and get ACK movlw d'8' ; Loop count movwf temp movlw H'80' ; Register command - power down output drivers (16 -23) movwf ebyte call putbyte ; Output byte and get ACK decfsz temp,f goto $-4 call stop ; Send Stop to Si5351 call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'183' ; Address Register 183 movwf ebyte call putbyte ; Output byte and get ACK ;________________________________________________________________________________ movlw H'D2' ; Register command - set crystal capacitor 10pF ; movlw H'92' ; Register command - set crystal capacitor 8pF ; movlw H'52' ; Register command - set crystal capacitor 6pF movwf ebyte call putbyte ; Output byte and get ACK call stop ; Send Stop to Si5351 ;________________________________________________________________________________ call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'15' ; Address Register 15 movwf ebyte call putbyte ; Output byte and get ACK clrf ebyte ; Command - PLL Input source call putbyte ; Output byte and get ACK (15) ;________________________________________________________________________________ ; movlw H'4C' ; Register command - 2mA output ; movlw H'4D' ; Register command - 4mA output ; movlw H'4E' ; Register command - 6mA output movlw h'4F' ; Register command - 8mA output movwf ebyte call putbyte ; Output byte and get ACK (16)17 - 23 already 0x80 call stop ; Send Stop to Si5351 ;________________________________________________________________________________ call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'24' ; Address Register 24 movwf ebyte call putbyte ; Output byte and get ACK clrf ebyte ; Register command - CLK 0-3 disable state call putbyte ; Output byte and get ACK (24) clrf ebyte ; Register command - CLK 4-7 disable state call putbyte ; Output byte and get ACK (25) ; _______________________________________________________________________________ movlw H'04' ; Register command - (10.710MHZ) btfss GPIO,FREQ movlw H'02' ; (10.715MHZ) movwf ebyte call putbyte ; Output byte and get ACK (26) movlw H'E2' ; Register command - (10.710MHZ) btfss GPIO,FREQ movlw H'71' ; (10.715MHZ) movwf ebyte call putbyte ; Output byte and get ACK (27) ; _______________________________________________________________________________ clrf ebyte call putbyte ; Output byte and get ACK (28) ;________________________________________________________________________________ movlw H'0C' ; Register command - (10.710MHZ) btfss GPIO,FREQ movlw H'0B' ; (10.715MHZ) movwf ebyte call putbyte ; Output byte and get ACK (29) movlw H'23' ; Register command - (10.710MHZ) btfss GPIO,FREQ movlw H'B7' ; (10.715MHZ) movwf ebyte call putbyte ; Output byte and get ACK (30) ;________________________________________________________________________________ clrf ebyte call putbyte ; Output byte and get ACK (31) clrf ebyte call putbyte ; Output byte and get ACK (32) ;________________________________________________________________________________ movlw H'9A' ; Register command - (10.710MHZ) btfss GPIO,FREQ movlw H'39' ; (10.715MHZ) movwf ebyte call putbyte ; Output byte and get ACK (33) ;________________________________________________________________________________ movlw d'9' movwf temp clrf ebyte call putbyte ; Output byte and get ACK (34 - 42) decfsz temp,f goto $-3 movlw H'01' ; Register command - movwf ebyte call putbyte ; Output byte and get ACK (43) clrf ebyte call putbyte ; Output byte and get ACK (44) ;________________________________________________________________________________ movlw H'1F' ; Register command - (10.710MHZ) btfss GPIO,FREQ movlw H'1E' ; (10.715MHZ) movwf ebyte call putbyte ; Output byte and get ACK (45) ;________________________________________________________________________________ movlw d'47' movwf temp clrf ebyte call putbyte ; Output byte and get ACK (46 - 92 decfsz temp,f goto $-3 call stop ; Send Stop to Si5351 call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'149' ; Address Register 149 movwf ebyte call putbyte ; Output byte and get ACK movlw d'22' ; Loop counter movwf temp clrf ebyte call putbyte ; Output byte and get ACK (149 - 170) decfsz temp,f goto $-3 call stop ; Send Stop to Si5351 call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'177' ; Address Register 177 movwf ebyte call putbyte ; Output byte and get ACK movlw H'AC' ; Register command - soft reset movwf ebyte call putbyte ; Output byte and get ACK call stop ; Send Stop to Si5351 call openw ; Open for Write, signal start, send 0xC0, ask for ACK movlw d'3' ; Address Register 3 movwf ebyte call putbyte ; Output byte and get ACK movlw H'FE' ; Register command - enable CLK0 output movwf ebyte call putbyte ; Output byte and get ACK call stop ; Send Stop to Si5351 sleep ; Put PIC to sleep ; ******************************************************************************* ; Open for write openw call i2cstart movlw H'C0' ; Send Si5351 address movwf ebyte call putbyte ; Output Address byte and get ACK return ; ******************************************************************************* ; * I2C ROUTINES * ; ******************************************************************************* ; Start condition; data goes from hi to low with SCL high ; Normal state is: SCL low, data high i2cstart banksel TRISIO bcf TRISIO,SDA ; SDA is output banksel GPIO bsf GPIO,SDA ; Set SDA High bsf GPIO,SCL ; SCL hi nop bcf GPIO,SDA ; SDA low nop bcf GPIO,SCL ; SCL low nop bsf GPIO,SDA ; SDA High on exit return ; ******************************************************************************* ; Output a byte in ebyte to Si5351 and then get an ACK putbyte banksel TRISIO bcf TRISIO,SDA ; SDA is output banksel GPIO movlw H'08' ; Counter movwf bytcnt bcf STATUS,C senlp rlf ebyte,f btfss STATUS,C goto zerb bsf GPIO,SDA ; SDA hi goto zerb1 zerb bcf GPIO,SDA ; SDA low zerb1 bsf GPIO,SCL ; SCL hi nop nop bcf GPIO,SCL ; SCL low decfsz bytcnt,f goto senlp bsf GPIO,SDA ; Exit with data high call getack return ; ******************************************************************************* ; Read acknowledge signal from Si5351. SDA low with SCL high getack banksel TRISIO bsf TRISIO,SDA ; SDA is Input banksel GPIO bsf GPIO,SCL ; SCL hi nop nop bcf GPIO,SCL ; SCL low return ; With C clear if ack received, set otherwise ; ******************************************************************************* ; Stop condition; data goes from low to hi with SCL high ; Normal state is: SCL low, data high stop nop banksel TRISIO bcf TRISIO,SDA ; SDA is output banksel GPIO bcf GPIO,SDA ; SDA low nop nop bsf GPIO,SCL ; SCL hi nop nop bsf GPIO,SDA ; SDA hi nop nop bcf GPIO,SCL ; SCL low return ; ******************************************************************************* ; * * ; * Purpose: Wait for a specified number of milliseconds * ; * * ; * Entry point wait_10ms : Wait for 10 msec * ; * Entry point wait_1ms * ; * * ; * Input: None * ; * * ; * Output: None * ; * * ; ******************************************************************************* wait_10ms ; ****** Entry point ****** movlw D'20' ; Set up outer loop counter to 20 movwf count goto outer_loop ; Into the wait loops wait_1ms movlw D'2' ; Set up outer loop counter to 2 movwf count ; ; Wait loops used by other wait routines ; - 1 microsecond per instruction (with a 4 MHz microprocessor clock) ; - 498 instructions per inner loop ; - (temp * 498) instructions (.498 msec) per outer loop ; - Round off to .5 ms per outer loop ; outer_loop movlw H'A4' ; Set up inner loop counter to 165 movwf temp inner_loop decfsz temp,f ; Decrement inner loop counter goto inner_loop ; If inner loop counter not down to zero, ; then go back to inner loop again decfsz count,f ; Yes, Decrement outer loop counter goto outer_loop ; If outer loop counter not down to zero, ; then go back to outer loop again return ; Yes, return to caller ; ******************************************************************************* END