The main reason this is probably failing is the capacitance of the cable is out of the spec if I2C. -----Original Message----- From: piclist-bounces@mit.edu [mailto:piclist-bounces@mit.edu] On Behalf Of Bob Axtell Sent: Wednesday, January 17, 2007 3:10 PM To: Microcontroller discussion list - Public. Subject: Re: [PIC] I2C dropping data in PIC slave All was well until I noticed the 3' cable length and the second PCB. i2c is not famous for distance, 3' is longer than anything I ever did, and i2c was designed for single-board TV designs- nothing outside of the same PCB. So I think you have a noise problem, caused by poor GND, long cable, and probably the multiple 2K pullups (much too heavy, 3.3K works for me, near the master). --Bob alan smith wrote: > 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