I'm passing this on for a friend to see if anyone wants to help him out. Do please reply to him offlist as well, I'm not sure if he has joined the list yet. -- James Mikhail Efroimson Questions: I'm trying to program a PIC16F886 as a I2C slave device using the code from Microchip application note AN734. I've compiled this example source code using MPLab 7.6 and flashed my PICmicro with the image. Now I am trying to talk to the chip using the AARDVARK I2C/SPI TOTAL PHASE connector but am not able to establish communication. I am trying to write bytes to the slave address from the AARDVARK GUI. I have the SCL, SDA and GND pins of the PICmicro connected to the AARDVARK connector which theoretically should be enough for two way communication via the GUI but it is not working. I've tried writing different numbers of bytes and changing the bitrate. Perhaps the buffer size needs to be adjusted for the PIC16F886. The code is as follows: ; Include Files #include ; Constant Definitions #define NODE_ADDR 0x02 ; Buffer Length Definition #define RX_BUF_LEN 32 ; Variable declarations udata WREGsave res 1 STATUSsave res 1 FSRsave res 1 PCLATHsave res 1 Index res 1 ; Index to receive buffer Temp res 1 ; RXBuffer res RX_BUF_LEN ; Holds rec'd bytes from master device. ; Vectors START code nop goto Startup nop ; 0x0002 nop ; 0x0003 goto ISR ; 0x0004 PROG code ; Macros memset macro Buf_addr,Value,Length movlw Length ; This macro loads a range of data memory movwf Temp ; with a specified value. The starting movlw Buf_addr ; address and number of bytes are also movwf FSR ; specified. SetNext movlw 40 movwf INDF incf FSR, F decfsz Temp, F goto SetNext endm LFSR macro Address, Offset ; This macro loads the correct value movlw Address ; into the FSR given an initial data movwf FSR ; memory address and offset value. movf Offset, W addwf FSR, F endm ; Main Code Startup bcf STATUS, RP1 bcf STATUS, RP0 Main clrwdt ; Clear the watchdog timer. goto Main ; Loop forever. ; Interrupt Code ISR movwf WREGsave ; Save WREG movf STATUS, W ; Get STATUS register banksel STATUSsave ; Switch banks, if needed. movwf STATUSsave ; Save the STATUS register movf PCLATH, W ; movwf PCLATHsave ; Save PCLATH movf FSR, W ; movwf FSRsave ; Save FSR banksel PIR1 btfss PIR1, SSPIF ; Is this a SSP interrupt? goto $ ; No, just trap here. bcf PIR1, SSPIF ; call SSP_Handler ; Yes, service SSP interrupt banksel FSRsave movf FSRsave movwf FSR ; Restore FSR movf PCLATHsave, W ; movwf PCLATH ; Restore PCLATH movf STATUSsave, W ; movwf STATUS ; Restore STATUS swapf WREGsave, F ; swapf WREGsave, W ; Restore WREG retfile ; Return from interrupt. Setup ; Initializes program variables and peripheral registers. banksel PCON bsf PCON, NOT_POR bsf PCON, NOT_BOR banksel Index ; Clear various program variables clrf Index clrf PORTB clrf PIR1 banksel TRISB clrf TRISB movlw 0x36 ; Setup SSP module for 7-bit banksel SSPCON movwf SSPCON ; address, slave mode movlw NODE_ADDR banksel SSPADD movwf SSPADD clrf SSPADD banksel PIE1 bsf PIE1, SSPIE bsf INTCON, PEIE ; Enable all peripheral interupts bsf INTCON, GIE ; Enable global interrupts bcf STATUS, RP0 return SSP_Handler banksel SSPSTAT movf SSPSTAT, W ; Get the value of SSPSTAT andlw b'00101101' ; Mask out unimportant bits in SSPSTAT banksel Temp ; Put masked value in Temp movwf Temp ; for comparison checking. State1: ; Write operation, last byte was an movlw b'00001001' ; address, buffer is full. xorwf Temp, W ; btfss STATUS, Z ; Are we in State1? goto State2 ; No, check for next state..... memset RXBuffer, O, RX_BUF_LEN ; Clear the receive buffer. clrf Index ; Clear the buffer index call ReadI2C ; Do a dummy read of the SSPBUF return State2: ; Write operation, last byte was data movlw b'00101001' ; buffer is full. xorwf Temp, W btfss STATUS, Z ; Are we in State2? goto State3 ; No, check for next state..... LFSR RXBuffer, Index ; Point to the buffer. call ReadI2C ; Get the byte from the SSP. movwf INDF ; Put it in the buffer. incf Index, F ; Increment the buffer pointer movf Index, F ; Increment the buffer index return State3: ; Read operation, last byte was an movlw b'00001100' ; address, buffer is empty. xorwf Temp, W btfss STATUS, Z ; Are we in State3? goto State4 ; No, check for next state..... clrf Index ; clear the buffer index. LFSR RXBuffer, Index ; Point to the buffer movf INDF, W ; Get the byte to SSPBUF call WriteI2C ; Write the byte to SSPBUF incf Index, F ; Increment the buffer index. return State4: ; Read operation, last byte was data, movlw b'00101100' ; buffer is empty. xorwf Temp, W btfss STATUS, Z ; Are we in State4? goto State5 ; No, check for next state..... movf Index, W ; Get the current buffer index. sublw RX_BUF_LEN ; Subtract the buffer length. btfsc STATUS, Z ; Has the index exceeded the buffer length? clrf Index ; Yes, clear the buffer index. LFSR RXBuffer, Index ; Point to the buffer movf INDF, W ; Get the byte call WriteI2C ; Write to SSPBUF incf Index, F ; Increment the buffer index. return State5: movlw b'00101000' ; A NACK was received when transmitting xorwf Temp, W ; data back from the master. Slave logic btfss STATUS, Z ; is reset in this case. R_W = 0, D_A = 1 goto I2CErr ; and BF = 0 return I2CErr nop banksel PORTB ; Something went wrong! Set LED bsf PORTB, 7 ; and loop forever. WDT will reset goto $ ; device, if enabled. return WriteI2C banksel SSPSTAT btfsc SSPSTAT, BF ; Is the buffer full? goto WriteI2C ; Yes, keep waiting banksel SSPCON ; No, continue. DoI2CWrite bcf SSPCON,WCOL ; Clear the WCOL flag movwf SSPBUF ; Write the byte in WREG btfsc SSPCON,WCOL ; Was there a write collision? goto DoI2CWrite bsf SSPCON, CKP ; Release the clock. return ReadI2C banksel SSPBUF movf SSPBUF,W ; Get the byte and put in WREG return end ; End of file end If somebody can please point me in the right direction, it would be greatly appreciated. Thank you, ~Mikhail -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist