I just downloaded the latest MPLAB (V5.50) and MCC (V5.03, Classic), setup a project with the 18LF46K22 and added the MSSP peripheral.
This driver has callbacks for all the major states. When a device is not present there will be a NAK in the address phase. The callback you will need is configured with
void I2C1_SetAddressNackCallback(i2c1_callback_t cb, void *ptr);
So you can create a callback for the NAK as follows:
typedef struct
{
i2c1_address_t address;
bool present;
} address_present_t;
i2c1_operations_t callbackAddrNak(void *funPtr)
{
address_present_t *Present = funPtr;
Present.present = false;
return I2C1_STOP;
}
// this code comes from the i2c1_master_example provided by MCC
uint8_t I2C1_Read1ByteRegister(i2c1_address_t address, uint8_t reg)
{
uint8_t returnValue = 0x00;
address_present_t present;
present.address = address;
while(!I2C1_Open(address)); // sit here until we get the bus..
I2C1_SetAddressNackCallback(callbackAddrNak,&present; // setup the address NACK callback with the address data
I2C1_SetDataCompleteCallback(rd1RegCompleteHandler,&returnValue);
I2C1_SetBuffer(®,1);
I2C1_MasterWrite();
while(I2C1_BUSY == I2C1_Close()); // sit here until finished.
if(present.present == FALSE)
{
// do something appropriate.
// some memories fail to respond (generate a NAK) when they are busy.
// a missing device will also result in a NAK.
}
return returnValue;
}
Note: A NAK can be the "normal" operation of some devices such as a memory. Often an EEPROM will refuse to ACK their address when they are busy writing. You use a process called NAK polling. If you do the device scan during a time when you can expect all devices to be active and ready, then you should be able to generate a map of the available addresses.
Good Luck