help with i2c
Mark Mara
Posts: 64
I am having a problem getting i2c to work with XMMC. I am trying to read a DS3231 real time clock. The attached code works fine when compiled using LMM, however, it never returns from the i2cOpen call when compiled using XMMC.
The attached example uses pins 0 and 1 for the i2c bus. I get the same result if I move the DS3231 to pins 28 and 29 and use i2cBootOpen; it works fine using LMM, but never returns from the i2cBootOpen call using XMMC.
Any help would be greatly appreciated.
--markM
The attached example uses pins 0 and 1 for the i2c bus. I get the same result if I move the DS3231 to pins 28 and 29 and use i2cBootOpen; it works fine using LMM, but never returns from the i2cBootOpen call using XMMC.
Any help would be greatly appreciated.
--markM
#include <stdio.h> #include <i2c.h> /* DS3231 pin assignments */ #define _rtcDataPin 0 #define _rtcClockPin 1 /* i2c addresses */ #define DS3231_I2C_WRITE_ADDR 0xd0 #define DS3231_I2C_READ_ADDR 0xd1 /* DS3231 register offsets */ #define DS3231_SECONDS_REG 0 #define DS3231_MINUTES_REG 1 #define DS3231_HOURS_REG 2 #define DS3231_DATE_TIME_BYTE_COUNT 7 // Includes bytes 0-6 #define MAX_I2C_BUS 16 #define TRUE 1 char bcd2bin(char bcd_value) { char temp; temp = bcd_value; temp >>= 1; temp &= 0x78; return(temp + (temp >> 2) + (bcd_value & 0x0f)); } void read_DS3231(I2C *bus) { int hour, minute, second, wday, mday, month, year; uint8_t buffer[DS3231_DATE_TIME_BYTE_COUNT]; printf("data regesters selected\n"); /* read the data registers */ if (i2cRead(bus, DS3231_I2C_READ_ADDR, buffer, DS3231_DATE_TIME_BYTE_COUNT, TRUE) != 0) printf("read failed\n"); else { printf("good read\n"); second = bcd2bin(buffer[DS3231_SECONDS_REG]); minute = bcd2bin(buffer[DS3231_MINUTES_REG]); hour = bcd2bin(buffer[DS3231_HOURS_REG]); printf("\d:d:d\n", hour, minute,second); } return; } int main(void) { I2C *bus; I2C_COGDRIVER dev; /* open i2c bus */ bus = i2cOpen(&dev, _rtcClockPin,_rtcDataPin, 4000); printf("i2cOpen returned x\n",bus); /* select the DS3231 data registers */ if (i2cWrite(bus, DS3231_I2C_WRITE_ADDR, 0, 1, TRUE) != 0) printf("Write failed\n"); else read_DS3231(bus); return 0; }
Comments
If you paste <%02d> into the reply to thread box then switch to advanced mode it is changed to <d> that is why my printf(s) look weird.
--markM
There is some I2C discussion in the Learn forum http://forums.parallax.com/showthread.php/148348-Any-example-code-for-I2C
Should it work in xmm mode? Or, is there a known problem using it that way?
Most likely we will end up with libsimplei2c and other drivers ....
There are some things that I would like to code with this instead of the Spin2Cpp version of my own driver...
BTW: Is there a list somewhere of all the different drivers that come with PropGCC.
I didn't know about i2c.h. I'd guess there's an spi.h around somewhere too, right?
No, there is no spi.h at the moment. Someone was working on a generic SPI driver but I don't think they ever checked it in and I don't recall who it was. Do you have a proposed API for SPI? It wouldn't be too hard to create a driver.
Regarding this code It is writing a 1 byte of zero. I copied it from someone else's code. It seems to work fine. However, from your comment I assume that it is bad technique. I'll change it.
--markM
From C:\propgcc\propeller-elf\include\i2c.h ....
That tells you everything you need to know about how to use the function. To me, it is glorious!
Anyway, you found a real problem with i2cOpen that I am in the process of fixing. Thanks!!!!
Would it be possible to have cognew work in CMM/LMM and XMM?
My guess is that it would be possible to use compile time flags to select the appropriate cognew at compile time. In CMM/LMM the cognew would be the same as it is now. In XMM, it would check out a lock, copy the 2K bytes, use the CMM/LMM cognew, and then release the lock.
Anyway, that's just a suggestion. Otherwise, the onus is each and every developer to provide two methods of starting cog drivers, and that sounds like a hassle.
A side effect of the change is that code that uses i2cBootOpen() gets the following error messages when attempting to compile. This code complies cleanly under the old version of propgcc. This is not a problem for me.
It seems like this is an issue David is working on. He's on vacation right now though.