; ******************************************************************* ; * ; Program To test G8JVM FM-Mod I2C. * ; * ; 22March2013 * ; Revision: 2 - Loop Testing I2C Interface * ; * ; ******************************************************************* ; Program will initialize 12F629. Call "openw' which issues a start ; to Si57X, followed by putbyte which sends a byte of hex AA, followed ; by getack. Finally a stop is issued to the Si57X. ; Program then loops and reissues the commands. ; During the issuance of Start to I2C, Pin 7 is raised high as a scope ; sync. Duration is approxiamately 9 microseconds. ; During get ACK routine, Pin 5 is raised high and lowered at end of ; routine. ; If the ACK is true, Pin 5 is pulsed high for 2 microseconds. ; ******************************************************************* ; * Device type and options. * ; ******************************************************************* ; processor PIC12F629 ;directive to define processor #include ;processor specific variable definitions ;******************************************************************** ;Configuration bits ; The CONFIG directive defines configuration data within the .ASM file. ; The labels following the directive are defined in the P12F629.INC file. ; The PIC12F629 Data Sheet explains the functions of the configuration bits. ;CONFIG __CONFIG _CP_OFF & _CPD_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT errorlevel -302 ; Turn off Banking messages ;******************************************************************** ; P ; Controller - PIC12F629 P ; __________ P ; +5V---------->Vdd |1 8| Vss>----GND P ; SCL--------->GP5 |2 7| GP0><---TRIG P ; SDA--------->GP4 |3 6| GP1>----LSP2 P ; MCLR/Vpp/GP3 |4 5| GP2>----TRACE P ; ---------- P ; P ; ******************************************************************* ; ******************************************************************* ; * Assign names to PIC IO pins. * ; ******************************************************************* ; ; GPIO Port Assignment: ; TRIG equ 0x00 ; Input 0 - Now Output for Scope Sync LSP2 equ 0x01 ; Input 1 TRACE equ 0x02 ; Trace output SDA equ 0x04 ; I2C Data SCL equ 0x05 ; I2C Clock ; ******************************************************************* ; GENERAL DEFINITIONS * ; ******************************************************************* ACCESS_BASE equ 0x00020 ; Access Ram Bank EEPROM_BASE equ 0x02100 ; Where EEPROM begins ; ******************************************************************* ; DATA MEMORY * ; ******************************************************************* CBLOCK ACCESS_BASE count ; Gen purpose counter - 0x20 temp ; Temporary work register - 0x21 bytcnt ; used in i2c driver - 0x22 ebyte ; contains data sent to i2c device - 0x23 eadd ; Contains address used by i2c device - 0x24 ENDC ; Maximum of 64 Bytes, 0x5F ; ******************************************************************* ; START OF FLASH MEMORY * ; ******************************************************************* ORG 0x00 ;Reset vector address goto Start ORG 0x04 ; Interrupt Vector address retfie ;=================================================================== ; Main routine starts here Start clrf INTCON ; Disable interrupts movlw H'07' ; Disable Comparator module movwf CMCON ; Initialise GP 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 bcf TRISIO,TRACE ; Set GP2, Pin 5 as output bcf TRISIO,TRIG ; Set GP0, Pin 7 as output clrf OPTION_REG ; General enable pullups (bit 7 clear) movlw H'27' ; Enable pullups on GPIO 0,1,2,5 movwf WPU movlw H'80' ; Oscillator set to middle of calibration 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 bcf GPIO,TRACE ; Set trace output low ; Trace output, Pin 5, is high during duration of Get ACK. bcf GPIO,TRIG ; Set scope sync output low ; Scope Sync output, Pin 7, is high during Start operation. call wait_10ms ; Wait to be sure Si570 completes power up ;============================================================================= Readsiregs movlw H'87' ; Register 135 - Reset / Memory control register in Si570 movwf eadd call openw ; Open for Write, signal start, send 0xAA, ask for ACK call stop ; Send Stop to Si57X goto Readsiregs ; Loop ;============================================================================= ;SPECIFIC I2C ROUTINES FOLLOW ;============================================================================= strt ; Start condition; data goes from hi to low with SCL high. Normal state is: SCL low, data high banksel TRISIO bcf TRISIO,SDA ; SDA is output banksel GPIO bsf GPIO,TRIG ; Set the scope sync high 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 bcf GPIO,TRIG ; Set scope sync low- 9 instructions, approx 9 microseconds return ;------------------------------------------------ stop ; Stop condition; data goes from low to hi with SCL high. Normal state is: SCL low, data high banksel TRISIO bcf TRISIO,SDA ; SDA is output banksel GPIO bcf GPIO,SDA ;SDA low nop bsf GPIO,SCL ;SCL hi nop bsf GPIO,SDA ;SDA hi nop bcf GPIO,SCL ;SCL low return ;------------------------------------------------ getack ; Read acknowledge signal from Si57X. SDA low with SCL high. ; Returns C set if no acknowledge from slave bsf GPIO,TRACE ; Set TRACE OUTPUT high banksel TRISIO bsf TRISIO,SDA ; SDA is Input banksel GPIO bsf GPIO,SCL ; SCL hi nop nop bcf STATUS,C ; Clear btfss GPIO,SDA ; Test data input. exit with carry clear if SDA is low goto gax bsf STATUS,C ; Set carry flag if no ack gax bcf GPIO,SCL ; SCL low return ; With C clear if ack received, set otherwise ;------------------------------------------------ putbyte ; Output a byte in ebyte to Si57X and then get an rxACK 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 bcf GPIO,SCL ; SCL low decfsz bytcnt,f goto senlp bsf GPIO,SDA ; Exit with data high call getack bcf GPIO,TRACE ; Set TRACE OUTPUT low return ;------------------------------------------------ openw ; Open for write. call with start address in eadd call strt movlw H'AA' ; Get Si57X address movwf ebyte call putbyte ; Output Address byte and get ACK btfsc STATUS,C ; Was ACK true? goto acknot ; No bsf GPIO,TRACE ; Yes, Pulse the TRACE OUTPUT nop nop bcf GPIO,TRACE ; Trace output down acknot 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 ; **************************************************************************** ; * EEPROM Memory * ; * * ; * Contains: * ; * Si571 registers for each of the four defined frequencies. * ; * Startup control byte. * ; * * ; **************************************************************************** ; ORG EEPROM_BASE ; 24 locations reserved for the Si571 registers. 4 frequencies * 6 bytes DATA 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 DATA 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 DATA 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 startup_loc startup equ startup_loc - EEPROM_BASE DATA 0x00 ; Startup control byte siregs_loc siregs equ siregs_loc - EEPROM_BASE DATA 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Power up Si571 registers sifxtal_loc sifxtal equ sifxtal_loc - EEPROM_BASE DATA 0x00, 0x00, 0x00, 0x00, 0x00 ; Calculated Si571 crystal oscillator halt_code_loc halt_code equ halt_code_loc - EEPROM_BASE DATA 0x00 ; Halt code from the Select HSDIV & N1 routine trace_loc trace equ trace_loc - EEPROM_BASE DATA 0x00 ; Trace code ;================================================ END ;================================================