Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Getting data from a rtc device through I2C

Hi all,

I would like to retrieve information from a RTC device which is directly connected to a GPIO, using the i2c protocol. So, the first step was to load the i2c-gpio driver with this piece of code:

# define GPIO_RTC_SDA		100# define GPIO_RTC_SCL		99
MODULE_DESCRIPTION("i2c via gpio module");
MODULE_LICENSE("GPL");
static struct i2c_gpio_platform_data rtc_device_data = {
	.sda_pin = GPIO_RTC_SDA,
	.scl_pin = GPIO_RTC_SCL,
	.udelay  = 25
};
static struct platform_device i2c_gpio_bus_rtc = {
	.name 	= "i2c-gpio",
	.id		= 0,
	.dev	= {
		.platform_data = &rtc_device_data,
	}
};
static int __init i2c_gpio_bus_init(void)
{
	int ret;
	return platform_device_register(&i2c_gpio_bus_rtc);
}
static void __exit i2c_gpio_bus_exit(void)
{
	platform_device_unregister(&i2c_gpio_bus_rtc);
}
module_init(i2c_gpio_bus_init);
module_exit(i2c_gpio_bus_exit);

Once loaded, I get a new device in the /sys/bus/i2c/devices directory. For testing purpose I then use i2cdetect utility to scan the i2c bus to see if I could find my rtc device. But, I could not find it. So, I added manually a device at address 0x68 on the i2c bus with the following command:

echo m41t83 0x68 > /sys/devices/platform/i2c-gpio.0/i2c-0 (m41t83 is my rtc device) as it is explained in the Documentation/i2c/instantiating-devices file. However, it is still not working.

Does somebody understand what’s going on?

Info : I work with a nios II processor under linux (uClinux distrib). I use a device tree to setup board devices.

15 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    --- Quote Start ---

    Everything is okay, I checked all timing specifications at pp.53. However, the SCL's frequency is never higher than 12kHz, even if I set the struct i2c_gpio_platform_data's udelay field (in the linux module) to 2 for example. Normally, the SCL's frequency should be 500kHz when setting udelay to 2. Anyway, even at 12kHz, the RTC device should acknowledged to I2C frames.

    --- Quote End ---

    Please note that the SLC's frequency is not so important, but its tf and tr are important because SLC is used as the clock of Flip-Flops. If you observe the same 'half voltage' phenomenon at the 9th clock rising edge, please change the pull-up resistors value high if possible. If you can lower the voltage, this is the problem of m41t83's output abilities, though it means some malfunction. And of course, you connect X'tal etc. and the internal circuit of your m41t83 is working correctly?

    Kazu
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I'm coming back after a while ;-)

    So I eventually succeed in detecting my i2c device (RTC) despite I still get some half-amplitude i2c signals. Actually it was not a software issue but rather a FPGA configuration problem. To explain it simple:

    https://www.alteraforum.com/forum/attachment.php?attachmentid=7811

    On figure 1, you can see that we used intermediate signals between the GPIO and the SDA and SCL hardware pins to adapt the 2-bit-wide bus. However it seems that it was not a proper solution because when by-passing these signals I could be able to scan successfully the rtc, using the i2cdetect utility.

    But, as I described below, I still get some weird i2c frames... Anyway, I can now get data from my rtc device so my problem is solved!

    Thanks to both of you ;-)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    --- Quote Start ---

    So I eventually succeed in detecting my i2c device (RTC) despite I still get some half-amplitude i2c signals. Actually it was not a software issue but rather a FPGA configuration problem. To explain it simple:

    --- Quote End ---

    If you still observe the half-amplitude i2c signals on your SDA, I strongly recommend you to check again whether your SDA pin is open-drain or not. The half voltage at the ACK phase means that someone is driving your SDA line high despite your rtc is driving it low. In normal case, only the pull-up resistor can make the SDA line high and it's force is not so strong because you are using 4k7.

    Kazu
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    For what it's worth, I just finished debugging an I2C interface that had very similar issues and found this knowledge base item from Altera was the cause. I did some digging in the Chip Planner (Arria 10 w/ Q16.0) and found that my tristate buffer in SDA and SCL was always driving (!OE = GND) and control signal was wired to the BUF_IN port. This is exactly the opposite of what I was expecting (!OE = control and BUF_IN = GND). Therefore, we were always driving the bus and the half-voltage on the SDA pin was a function of the two ends fighting each other.

    https://www.altera.com/support/support-resources/knowledge-base/solutions/rd01262015_264.html

    The solution is to create a psuedo-ground signal and set an attribute to keep it in the synthesizer. Confirmed that this fix resulted in a working I2C bus and the Chip Planner also confirmed that they were utilized properly in the IO buffer.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In the i2c-gpio method, SCL and SDA signals are generated directly by your Nios CPU, and this is the reason why the SLC clock period is not constant. If you have any doubt, there is another way to use an 'opencore's i2c core'.