Hi all,
I am trying to use I2C functionality on HiFive1 Rev B. In order to test it, I use Arduino Due and Arduino Uno as slave devices. I configured the boards like this:
- Arduinos use the slave_receiver template from https://www.arduino.cc/en/Tutorial/MasterWriter. The only difference is the slave address is 0x51. (Wire.begin(0x51);). I used just one Arduino at a time. I DO NOT connect both of them to the I2C bus at the same time.
- HiFive1 Rev B uses 200 MHz coreclock. PRCI pllcfg register has “0x30581” after the clock setup.
- SCL of HiFive1 Rev B is connected to SCL of Arduino and SDA of HiFive1 Rev B is connected to SDA of Arduino using 2 jumper cables.
In order to send a single byte (‘d’, decimal 100) from HiFive1 Rev B to Arduino, I follow the following steps on HiFive1 Rev B:
- Write 0x80 to I2C CTR register to enable I2C.
- Calculate the PRER value as (200 MHz / (5 * 100 kHz)) - 1 = 399. So “143” (PRER & 0xFF) is written to PRERlo and “1” ((PRER & 0xFF00) >> 8) is written to PRERhi.
- Enable the bits in iof_en and clear the bits in iof_sel corresponding to pins 12 and 13 to enable SDA and SCL respectively.
- Write 0xA2 (0x51 << 1) to I2C TX register.
- Write 0x90 (STA | WR) to I2C CR register.
- Loop until TIP bit of SR register is cleared. ( while(SR & 0x02); )
- Check RxACK bit of SR register.
- Write ‘d’ (100) to I2C TX register.
- Write 0x10 (WR) to I2C CR register.
- Loop until TIP bit of SR register is cleared. ( while(SR & 0x02); )
- Check RxACK bit of SR register.
- Write 0x40 (STO) to I2C CR register.
- Wait approximately 100 ms by just polling RTC.
- Loop back to step 4
I realized that sometimes I do not get ACK after the writes to Arduino Due. If I do not stop sending data when I see NACK or if I just repeat the last write if I see NACK the values I read from Arduino Due is mostly garbage. Yes, I read the expected value 100 but I also read bunch of other arbitrary numbers.
I tried to switch to an Arduino Uno. The values I read from Arduino Uno seem stable, however I2C communication just stops between HiFive1 Rev B and Arduino Uno after some arbitrary number of bytes sent. When it stops, I see that HiFive1 Rev B just waits TIP bit to be cleared, but it never gets cleared. Resetting HiFive1 Rev B allows it to continue to communicate with Arduino Uno again until it stops for no apparent reason again.
After this point, I was just wondering if the problem was the Arduino boards I have, so I conducted a similar experiment with them but the transmission between two Arduino boards seem fine. I never get random incorrect values or the transmission never stops.
So at this point I do not have any idea about what I am doing wrong on HiFive1 Rev B. I just wanted to ask if you can see a mistake in my I2C procedure.
Thank you.