1.) What is your clock rate? Have you tried slowing it to see if the situation improves? 2.) Are you pulling the I2C lines to 5V? If so, 2K seems too stiff. Check the iOL specs. for the IC's on the bus. I would recomment pullups only at the master. Remember, additional pullups will be in series with existing pullups. 3.) You may want to try a series resistor to dampen the noise. If the interface works without the 3' cable, then the software is likely ok and you should concentrate on the hardware. Good luck, David ============================= David Novak Dajac Inc. 17152 Shadoan Way Wesfield, IN 46074 Email: novakd@dajac.com Phone: 317-258-0223 Fax: 317-867-1888 www.dajac.com Hardware/Software Consulting Headlamp Alignment Equipment ============================= -----Original Message----- From: alan smith [mailto:micro_eng2@yahoo.com] Sent: Wednesday, January 17, 2007 9:27 AM To: Microcontroller discussion list - Public. Subject: [PIC] I2C dropping data in PIC slave Well, down to one last issue on a project, and its I2C. Setup is this....a master board with a couple other I2C devices on it, and existing formware running fine sending out commands to the other devices on that board. Using some GPIO expanders. Essentially it sends out the address, a command word and the data word. I've looked at it with a analyzer and all looks good as expected since its working and has been working. Now, I've taken that board and added another board with about 3' of cable to talk to a 18F8310 device, simple slave, it never sends anything back (short of the ACK of course) to the master, simply listens. I have 2K pullups on that boards I2C interface as well, and eventually will be adding two more boards on that same I2C interface, and assume that each will need a pullup as well. But thats after I get this one slave to work correctly. What is happening is the 3 byte transfer (address, data1,data2) isnt always getting into the correct registers...meaning.....when the I2C transfer occurs, I log that transfer to a buffer so I can go into the debugger and see what came over, given that I know what the master is sending at least. I've coded it up two different ways, one using interupts, the other not..just polling for the start bit. Since I know that when it starts, it always will consist of address, data1,data2 I can be reasonably assured I can remain in a loop looking for that sequence. So the interesting part is, using the polling method, its much more reliable..ie.....the slave PIC turns on a sequence of LEDs that shows if the 8 bits was correctly recieved. As I watch, most the time it cycles correctly but now and then it either halts or skips LEDs. If I look in the buffer I can see where the data pattern was lost. Sometimes I get the address showing up where data should be...ie.....address = 0x80 and the buffer shows 0x80,0x50,0x30 correctly but other times its 0x80,0x80,0x50..... etc So here is the code snippits for the polling method, that is working much better (maybe only by luck?) ---------------------------------------------------------------------------- ---------------------------------------------- INIT_I2C bsf TRISC,3 ;initialize MSSP module bsf TRISC,4 movlw 0x80 ; initialize slave address movwf SSPADD ; and load to the address register bsf SSPSTAT,SMP movlw b'00110110' movwf SSPCON1 bcf SSPCON1,SSPOV return MAIN btfss SSPSTAT,S ; check status goto MAIN ; no valid address decoded, keep looping call GET_I2C ; go capture call SHOW_DATA ; and show the updated data goto MAIN GET_I2C wait4validAddr btfsc SSPSTAT,P goto _I2Cexit btfss SSPSTAT,BF ; buffer full? goto wait4validAddr movff SSPBUF,scratch ; just the address, ignore call MoveScratch ; store to a buffer wait4validData_1 btfsc SSPSTAT,P goto _I2Cexit btfss SSPSTAT,BF ; buffer full? goto wait4validData_1 movff SSPBUF,Data_1 movff SSPBUF,scratch ; put Data_1 into scratch register call MoveScratch ; store to a buffer wait4validData_2 btfsc SSPSTAT,P goto _I2Cexit btfss SSPSTAT,BF ; buffer full? goto wait4validData_2 movff SSPBUF,Data_2 movff SSPBUF,scratch ; put Data_1 into scratch register call MoveScratch ; store to a buffer wait4stop btfss SSPSTAT,P goto wait4stop bcf SSPCON1,SSPOV ; clear any overflow bcf PIR1,SSPIF ; clear the interupt flag (not used) return _I2Cexit bcf PIR1,SSPIF bcf SSPCON1,SSPOV return MoveScratch lfsr FSR2, AD_BUFFER_START ;Load FSR2 with the start movff RXoutOffset, FSR2L ; load the offset. movff scratch,INDF2 ; and put data into the buffer. incf RXoutOffset, f ; incrment RXoutOffset. return ---------------------------------------------------------------------------- --------------------------------------------------------- and for the interupt driven solution, that appears to lose even more data. This is inside the ISR, and the ISR is doing nothing else but triggering on either TMR0 interupt or this btfss PIR1,SSPIF goto _ExitISR bcf PIR1,SSPIF movf SSPSTAT,W ; Get the value of SSPSTAT andlw b'00101101' ; Mask out unimportant bits in SSPSTAT. movwf Temp ; for comparision checking. ADDRESS movlw b'00001001' ; address, buffer is full. xorwf Temp,W ; btfss STATUS,Z ; looking for the address? goto DATA ; No, must be data..... movff SSPBUF,scratch ; just the address, ignore call MoveScratch clrf byteCount DATA movlw b'00101001' ; buffer is full. xorwf Temp,W btfss STATUS,Z ; data available? goto _ExitISR btfss SSPSTAT,BF goto DATA movff SSPBUF,scratch call MoveScratch incf byteCount,f _ExitISR ;--------------------------------------------------------------------------- ------------------------------------------------------- So in either case, the PIC is really acting like a big GPIO expander since short if adding in I2C repeaters, etc you can't have that many devices on the I2C bus. And since its not doing anything else, a short tight loop should work fine. I am thinking there is just something fundamentally wrong, but looking at your own creation its sometimes hard to spot. I am going to try this same code on another demo board and see if its a hardware issue or just in the firmware (hoping for the latter of course). This should be simple...but something is just wrong. I2C shouldnt be prone to losing data like this? For the interutp driven, I thought I read that for every I2C (address or data) the interupt is generated? I thought it just was generated when the start bit was detected? Thanks for anyone taking the time to look at this....I'm just going a bit crazy over this, when it should just simply work. -Al --------------------------------- TV dinner still cooling? Check out "Tonight's Picks" on Yahoo! TV. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist