Shop OBEX P1 Docs P2 Docs Learn Events
Simple IDE I2C Bus Speed how to change — Parallax Forums

Simple IDE I2C Bus Speed how to change

Andrew BubbleAndrew Bubble Posts: 21
edited 2014-11-29 12:16 in General Discussion
Hi I am developing some LED lamps using the Propeller chip, I am using the Adafruit 16 channel Servo / LED driver board
http://www.adafruit.com/products/815 This uses the PCA9685 LED driver chip. I originally used an Arduino board but I have infrared, the LED board together with an radio link and the interrupts were getting complicated so I chose to use the propeller chip instead.

The project is going ok but I have a problem to do with the SimpleIDE I2C bus speed, I can't find anywhere to adjust the I2C clock speed. I assume this set to 100K but I would like to increase up to 400K or higher if possible.

Is this possible and can anyone give any advice on how to achieve this.

Regards Andrew

Comments

  • edited 2014-11-26 14:02
    Propeller GCC has a built-in I2C with faster clock options. I think I still have some examples, will be back in a while...
  • edited 2014-11-26 15:49
    Here is an example that demonstrates clocking the Propeller's EEPROM at 400 kHz:

    EEPROM sample code
    https://code.google.com/p/propgcc/source/browse/demos/eeprom/eepromdemo.c?name=release_1_0

    EEPROM Library with fast I2C function calls
    https://code.google.com/p/propgcc/source/browse/lib/sys/propeller/eeprom.c?name=release_1_0

    The actual I2C code is in the propeller folder
    https://code.google.com/p/propgcc/source/browse/lib/sys/propeller/?name=release_1_0
  • Andrew BubbleAndrew Bubble Posts: 21
    edited 2014-11-27 09:24
    Hi Andy

    Thank you for the quick response. As a generic question can the eeprom examples be used with any I2C device or are they specific to an eeprom. Below is an the two routines I use in my program the first initializes the PCA9685 device the second is used to update the device when any of the led's data changes.

    void Setup_PCA9685()
    {
    i2c_open(PCA9685,7,6,0);
    i2c_start(PCA9685);
    i2c_writeByte(PCA9685,0x80);
    i2c_writeByte(PCA9685,0x00);
    i2c_writeByte(PCA9685,0x00);
    i2c_stop(PCA9685);
    //pause(200);

    i2c_start(PCA9685);
    i2c_writeByte(PCA9685,0x80);
    i2c_writeByte(PCA9685,0x01);
    i2c_writeByte(PCA9685,0x10);
    i2c_stop(PCA9685);
    //pause(200);

    i2c_start(PCA9685);
    i2c_writeByte(PCA9685,0x80);
    i2c_writeByte(PCA9685,0xFE);
    i2c_writeByte(PCA9685,0x0B);
    i2c_stop(PCA9685);
    //pause(200);
    }

    void Update_PCA9685()
    {
    int i = 0;
    int pwm;
    short int address = 0x08;

    for(i=0; i <=14; i++)
    {
    i2c_start(PCA9685);
    i2c_writeByte(PCA9685,0x80);
    i2c_writeByte(PCA9685,address);
    pwm = PWMData;
    i2c_writeByte(PCA9685,pwm);
    i2c_stop(PCA9685);

    address++;
    i2c_start(PCA9685);
    i2c_writeByte(PCA9685,0x80);
    i2c_writeByte(PCA9685,address);
    pwm = PWMData>>8;
    i2c_writeByte(PCA9685,pwm);
    i2c_stop(PCA9685);
    address = address + 3;
    }
    }

    Regards Andrew
  • Andrew BubbleAndrew Bubble Posts: 21
    edited 2014-11-27 13:06
    Hi Andy

    I think I have answered my question but before I try something I need some clarification, I have read through some of the .c files indicated in the last link of your reply.

    In my examples listed above the I2C library had the form of i2c_open, i2c_start, byte, byte, byte then i2c_stop. I am assuming that using examples in the links you have provided I simply use the i2cWrite and define the three bytes I wish to send and the function will
    put the required start at the beginning and the stop at the end.

    I am off work over the weekend so I am planning on having a play.

    Regards Andrew
  • jazzedjazzed Posts: 11,803
    edited 2014-11-27 15:18
    PropellerGCC's i2c API's are described here: https://code.google.com/p/propgcc/source/browse/lib/include/i2c.h?name=release_1_0

    It's very confusing to me about what causes a start sequence. The stop sequence control is pretty clear though.
  • Andrew BubbleAndrew Bubble Posts: 21
    edited 2014-11-27 15:57
    Hi Yes I agree I have assumed that the i2cWrite will send a start sequence first followed by the number of requested bytes and in all of my PCA9685 device cases this is two bytes. In the initialise of the device I send three i2cWrite sequences to set the registers of the device and this seems to work as soon as the initialise routine is run all the LED's which where previously on go out. I have left the stop bit to true as in all cases I want to send a stop sequence after a i2cWrite.

    The problem comes when I try to set the LED's afterwards using the update routine, this uses the same i2cWrite commands but there is a for next loop setting each of the brightness registers to a value from 0 to 4095 (full brightness), for all sixteen LED's.

    Regards Andrew
  • Andrew BubbleAndrew Bubble Posts: 21
    edited 2014-11-27 17:10
    Hi All

    Thanks for all your help, all working now. I have got the PCA9685 chip talking and I can control all the led's. I am using the I2cOpen, i2cRead and i2cWrite which runs at 400khz.

    Regards Andrew
  • DomanikDomanik Posts: 233
    edited 2014-11-27 20:49
    ...to adjust the I2C clock speed. I assume this set to 100K but I would like to increase up to 400K or higher if possible.

    I measured the SCL frequency on a Quickstart and an AB. Both are running at 16.6KHz, 19us high and 38us low.
    Seems like when functioning normally both ought to be clocking at 100KHz, 10us period.
    Maybe it's a quirk of the SimpleIDE or something else?? The pulse out of P0 is 1us, if that means anything.
    /*
      SCL high is 19us, low is 38us.
      Should be 5us & 5us
    */
    
    #include "simpletools.h"
    #include "simplei2c.h" 
    
    i2c *eeProm, *imuBus;
    
    int main()
    {
      imuBus = i2c_newbus( 9, 10,   0);
      eeProm = i2c_newbus(28, 29,   0);
      while(1)
      {
        pause(1);
        pulse_out(0, 1);
        i2c_busy(imuBus, 0x5A);
      }    
    }
    
    Dom..
  • jazzedjazzed Posts: 11,803
    edited 2014-11-27 21:10
    Simple Library I2C functions are optimized for simplicity, not speed.
  • DomanikDomanik Posts: 233
    edited 2014-11-28 10:32
    jazzed wrote: »
    Simple Library I2C functions are optimized for simplicity, not speed.
    Since discovering Parallax 2 months ago I was under the impression that Simple IDE is the only SW tool available from Parallax for programming in C. So if I need I2C to run at 400KHz (or 100KHz) how is that done? "Prop GCC" shuffles me back to SimpleIDE. Or are there other development environments available somewhere? Running at 16KHz instead of 100KHz because of the IDE is a surprise; it shouldn't affect the clock rate or at least there should be a way to get the speed back up to spec.
    Dom..
  • edited 2014-11-28 11:57
    The particular library's I2C functions you tested are part of the Learn folder, an open source project for helping beginners get started with C language, the Propeller, and multicore. As Jazzed said earlier, execution speed was not the goal there, but he was referring to that particular set of libraries.

    Keep in mind that they are not your only I2C library choices for SimpleIDE. For example, you can also use #include <i2c.h> to add the I2C functions built into Propeller GCC. They have a 400 kHz clock speed option running in Propeller Assembly Language (PASM) in another cog, and Jazzed posted a link to its API for it in post #6.

    [Correction, the 400 kHz I2C option was written in C in an optimized way that can be executed directly by another cog. The C library could also have utilized a PASM driver, but did not in this case.]

    You have many other software and language options. The Parallax Propeller Tool and PropellerIDE are two software examples that support the Spin + PASM languages. You will also encounter libraries that execute at different speeds in the Spin libraries. For example, there are I2C libraries that execute in the higher level and interpreted (lower speed) Spin language in the same cog, and others that run in the assembled PASM language (higher speed) in another cog.

    P.S. Parallax provides/supports the SimpleIDE and Propeller Tool software packages for Spin, Propeller C and PASM. There are also lots of options contributed by community members listed here: ULTIMATE-List-of-Propeller-Languages. Keep in mind that these community developed languages and software packages will be at various levels of completeness, and have varying levels of support.
  • DomanikDomanik Posts: 233
    edited 2014-11-28 16:07
    Thanks Andy, Looks like I've got a lot of studying ahead.
    Dom..
  • DomanikDomanik Posts: 233
    edited 2014-11-29 12:16
    Thanks everyone, (including David Betz) my program works now. It goes up to 400KHz in Simple IDE.
    Found the thread: Sawmill helpful. The code started with something simple that worked and
    allowed me to whittle away until mine worked too.

    Didn't see a "i2c_busy" replacement so used this instead and it seems to do the job:
    status = i2cRead(busID, i2cAddr, 0x00, 0, 1);
    
  • ercoerco Posts: 20,256
    I just nabbed this PCA9685 breakout board for $2: http://www.ebay.com/itm/PCA9685-16-Channel-12-bit-PWM-Servo-motor-Driver-I2C-Module-For-Arduino-Robot/272557014281

    That's a lot of fun for $2.
  • erco wrote: »
    I just nabbed this PCA9685 breakout board for $2: http://www.ebay.com/itm/PCA9685-16-Channel-12-bit-PWM-Servo-motor-Driver-I2C-Module-For-Arduino-Robot/272557014281

    That's a lot of fun for $2.




    Pretty cool, do you have a line on those CC male headers?
  • ercoerco Posts: 20,256
    edited 2017-03-05 23:28
    CC meaning color-coded? No, never seen those before. Sure makes for a colorful board. Looks like four German flags, mein herr!
Sign In or Register to comment.