0

I'm trying to communicate with Raspberry pi 3B+ from PIC device via I2C.
My PIC device is PIC16F18325.

First, I generated i2c library by using MCC (mplab code configuration). raspberry pi is set master, pic device is set slave.

Question
I want to pass data from slave to master, but I don't know how to use the generated library.
How should I use the i2c1_slave.h library in main.c?

My code is here.

moath naji
  • 663
  • 1
  • 4
  • 20
  • I recommend reading the relevant chapters of the PIC datasheet first. That generated code may be a thin wrapper around the hardware anyway. Once you understand what the I2C hardware does it will be much easier to understand (and appreciate) what the code generator does for you. – E. van Putten Dec 17 '19 at 08:47
  • Yes, I already read the data sheet and understand the I2C mechanism. The generated code appears to provide "I2C_Open ()" and "I2C_Close ()" according to the I2C protocol. Therefore, I tried using the above function in main.c, but I cannot recognize the PIC device from the Raspberry Pi. Do you know what is wrong? – calm 0815 Dec 17 '19 at 15:00
  • The library seems to install an interrupt handler that gets called whenever there is I2C bus activity (the master trying to `talk` to your device). The interrupt handler in turn tries to call a function that you have to provide yourself. These functions get called with a parameter so you know which data is being requested. You then respond with the appropriate byte. I'd start by watching the i2c bus lines with a scope to see if the RPI is sending something, verify you have the right pins etc. Alternatively insert something in the ISR (switch a LED on) so you can see activity. – E. van Putten Dec 17 '19 at 16:33
  • I saw on an oscilloscope that the RPi was sending something on SCL to look for I2C devices. After checking the above, when I connected the SCL pin of PIC and the SCL pin of RPi, I could not confirm the signal transmitted from RPi. The PIC's SCL and SDA pins are set to open drain. – calm 0815 Dec 27 '19 at 07:11

1 Answers1

0

I2C is a bi-directional bus with at least one master and one slave. Your program on the Raspberry Pi should provide I2C master functions, and the program on the PIC slave functions. The I2C master always initiates data exchanges.

To exchange data with the slave the master sends a byte containing the slave’s address and whether it is going to send more bytes or wait to receive. When the slave receives that byte it should respond accordingly by sending or receiving.

Only when the master (RPi) puts a byte on the bus following an I2C start condition that contains the slave’s address, will an interrupt be triggered on the slave (PIC).

The interrupt service routine must process the received byte and prepare for the next. The read/write bit determines the response and next action, along with housekeeping to prepare for the next interrupt. The exact steps performed by the slave must match what the master expects and vice-versa.

jolati
  • 700
  • 11
  • 19
  • Yes. That's right. When I connected the i2C sensor to RPi and checked it, I was able to confirm the device address on RPi. So I connected the PIC and checked it, but I couldn't find the address set on the PIC from the RPi side. As described in another comment, PIC implements i2c slave using the interrupt function, but the problem is that the start sequence signal sent from RPi does not reach the PIC. – calm 0815 Dec 27 '19 at 07:20
  • @calm 0815 Looks like `SSP1ADD` gets set to 8 << 1 or 0x10 in i2c1_slave.c so this is the address that the RPi must send to the PIC. – jolati Dec 27 '19 at 16:58