Before starting, if you want to work with digital communication such as I2C, SPI, I2S, CAN, etc. I strongly recommend you invest money in a logic analyzer. These protocols doesn't require a fast sampling rate, so you can most likely find an affordable device. In any case, it will save you valuable time. I personnaly uses Saleae devices.
To understand the little piece of code you shared, we will have to calrifies a little how microprocesseors works and how they interracts with hardware. I assume that you are aware of how pointers works in C/C++ ; they points to a memory address. What you probably don't know is that they don't only points to a memory location, but can also point to a hardware register. When you read or write into a variable, you processor will put that address on it address bus and either read or write the content on the data bus.
Like I said, not all addresses refers to a memory location. If you look at the PIC16F887 datasheet, you will find many registers located between addresse 000h-1FFh. You can either read or write their content. Sometime they will be accessible only in for one or the other, that will be specified in the datasheet.
These registers are used for
1) Configuring your peripheral (like an I2C trasceiver)
2) Passing data to the a device (like the data you want to send/receive with I2c)
The pieces of code you gave is reading these resgisters. SSPSTAT (0x94) and SSPCON2 (0x91) are two constants defined in a header file that comes along with your compiler. They basically are pointers, and the code is making bitwise operation to get the value of a specific bit within these register. In other words, your program is waiting as long as SSPSTAT bit 2 or SSPCON2 bits 8 to 0 are set to high. This seems like it won't work because SSPCON2 contains configurations bits, like bit 7 : GCEN. If you set this bit to high, interrupts are enabled for I2C and this bit will not changes.
As for where the problem is, the wiring seems right. Problems could be :
- Bad configuration of register
- Slave never trasmit (that's where the logic analyzer becomes handy)
- Reception logic is not good. The one you have seems odd to me.
I think for reception, you should be looking at SSPSTAT bit0 (BF). This bit becomes high when your reception buffer is full.