I2C Bus Speed
Andrew Bubble
Posts: 21
Hi all, I have successfully got the propeller chip working with the Adafruit 16 channel 12 Bit PWM board. After testing I need to increase the i2C speed. I am using i2c.h header file in my program and using the following statement PCA9685 = i2cOpen(&Dev, scl, sda, 400000);.
I am aware this i2c library has been tested at higher bus frequency (> 400K). How do I go about increasing this. Every attempt to go past the 400000 results in the i2c to stop working.
Is there a file some where I need to alter to allow me to increase the speed. Looking through some of the files I have found the following statements in the file i2c_interface.c, but I don't know this relates to the i2c.h header file.
I2C *i2cOpen(I2C_COGDRIVER *dev, int scl, int sda, int freq)
{
use_cog_driver(i2c_driver);
I2C_INIT init;
int id;
// only allow speeds up to 400khz for now
if (freq > 400000)
return NULL;
Regards Andrew
I am aware this i2c library has been tested at higher bus frequency (> 400K). How do I go about increasing this. Every attempt to go past the 400000 results in the i2c to stop working.
Is there a file some where I need to alter to allow me to increase the speed. Looking through some of the files I have found the following statements in the file i2c_interface.c, but I don't know this relates to the i2c.h header file.
I2C *i2cOpen(I2C_COGDRIVER *dev, int scl, int sda, int freq)
{
use_cog_driver(i2c_driver);
I2C_INIT init;
int id;
// only allow speeds up to 400khz for now
if (freq > 400000)
return NULL;
Regards Andrew
Comments
Regards Andrew
FWIW, I'm working of a high-speed I2C object for Spin applications. When it's done (probably today), I'll share the code with you -- but I have no idea how to link PASM to C (all of my code is developed in Spin/PASM).
Regards Andrew
I tend to encourage people to learn Spin first, as it was designed for the Propeller and allows one to most easily exploit the Propeller's architecture. If you can program in C, you can line Spin very quickly -- it's a simple language. That said, it has a few powerful features that are not easily duplicated in C.
Regards Andrew
Same for me. I wrote some code that will read a compiled image from a uSD card, move it into the EEPROM, then reboot (this allows my customer to select one of thee apps on start-up [I can't fit the code for all three in one program]). The slowest part of the process is bit-banging I2C in Spin; I'm porting my basic Spin I2C object to PASM which will have the same interface as my Spin variant; this will allow me to validate the new code.
Regards Andrew
Shorter: Yes, Spin is slower than compiled C, especially if the C code is compiled to run in a cog and not use LMM.
I downloaded some material a while ago and there was whole bunch of stuff relating to self modifying code and I got completely lost and didn't want to delve any deeper.
Regards Andrew
Looks like I have a journey ahead of me ???
Regards Andrew
One question about the SimpleIDE, I understand that the Spin is an interpreter and ends up as byte code in the Propeller. How does the C program get compiled to the byte code or is the C program only on the Cog. I have assumed that the Spin is integral to the Propeller and just interested how the SimpleIDE C compiler does not use the Spin interpreter but compiles but compiles to what.
Regards Andrew
Simple IDE compiles your C code to machine code -- how this happens depends on compilation controls. Keep in mind that the cog RAM is only 2K; that's not much for program space. A very clever guy named Bill came up with a system called LMM (large memory model) which allows the Propeller to run machine code from the hub. Now, there is a bit of a speed penalty (for hub access of the assembly code) vis-a-vis running in a cog, but LMM is still faster than Spin. There are other memory models, but I'm not versed enough to explain the differences (you might want to post that in the C section of the forums).
In my experience, Spin is fast enough for the main app "glue" code. For time-critical elements I write PASM objects. At the moment I'm working on a laser-tag controller that uses custom IR in and IR out, allow with my WAV player (takes 4 cogs). My modification of FullDuplexSerial (PASM) takes care of XBee coms.
I understand C well enough to translate programs written in C for the Propeller, but I'm not comfortable writing C code. Spin works for me. It's simple. It's elegant. And it allows me to exploit the Propeller's architecture easier than with any other language.
Regards Andrew
Many objects (e.g., FSRW) do tricks with the counters to create fast SPI code.
Keep in mind that with I2C, you don't want to drive the pins high -- the pull-up takes care of that. Conceptually, it's easy: write 0s to the pin output bits. When you have a data "1" you make the pin an input (write 0 to the corresponding DIRA bit); when you have a data "0" you make the pin an output by writing 1 to the DIRA bit. This is very easy in code by XORing the data byte with $FF and then using the bits to manipulate the DIRA bit of the SDA line.
I've been busy with another project so I haven't finished by PASM I2C code. I'll post it here when I do.
Regards Andrew
Attached are two documents that helped me quite a bit. One by potatohead and one by deSilva. Between the two there's a good start there.
Sandy