Shop OBEX P1 Docs P2 Docs Learn Events
Any experience with the MAX7313 and Propeller? (AKA I2C help) — Parallax Forums

Any experience with the MAX7313 and Propeller? (AKA I2C help)

WBA ConsultingWBA Consulting Posts: 2,934
edited 2014-08-11 12:12 in Propeller 1
I have a small project in the works that will provide a simple power up test for a PCBA that uses four MAX7313 ICs to drive 56 LEDs (14 each). The project simply needs to supply power and I2C communication to toggle LEDs on and off so that the color patterns of the various LEDs can be easily verified. I have never used an I2C device that didn't already have an object, so my interpretation of the datasheet doesn't help me much in understanding what I need to do to toggle groups of LEDs on this board using an I2C connection from the Propeller.
  1. Any one have experience with the MAX7313 and the Propeller?
  2. What tips can you give me to help me make a program to turn the outputs of the MAX7313 on/off with the Propeller?
  3. Is there a similar chip that has an object in the OBEX that I can use as a starting point to understand the I2C code to make this myself?
thanks in advance!

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-05-28 19:42
    I have a small project in the works that will provide a simple power up test for a PCBA that uses four MAX7313 ICs to drive 56 LEDs (14 each). The project simply needs to supply power and I2C communication to toggle LEDs on and off so that the color patterns of the various LEDs can be easily verified. I have never used an I2C device that didn't already have an object, so my interpretation of the datasheet doesn't help me much in understanding what I need to do to toggle groups of LEDs on this board using an I2C connection from the Propeller.
    1. Any one have experience with the MAX7313 and the Propeller?
    2. What tips can you give me to help me make a program to turn the outputs of the MAX7313 on/off with the Propeller?
    3. Is there a similar chip that has an object in the OBEX that I can use as a starting point to understand the I2C code to make this myself?
    thanks in advance!

    1. None
    2. Send some data to it
    3. Yes, the PCA9535 and PCA9555

    Personally I don't think you need to understand I2C code although the way that I2C is mostly used is a lot simpler than implementing the full standards. You can think of it as a UART of sorts and like a asynch character it has start and stop except it's a condition that starts and stops a sequence of characters or bytes. Of course I2C is synchronous and the clock line plays a part in determining the start and stop conditions. The first byte after a start condition is always an address byte which also tells the addressed chip whether it wants to read or write the next byte(s). But anyway all you need to know is that your part expects a command byte after the write address and then anything after that are considered data bytes which are stored in successive locations or according to the autoincrement address map (smart increment).

    The command byte is really just an address for which register you want to start reading or writing from and of course initially it would be the configuration register $0F which has the bit fields as defined in the datasheet. If I had it hooked-up in one of my Tachyon systems I would just be chatting with it register by register and get to know it, maybe that's an idea if you are Forth right! :)
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2014-05-30 01:21
    Peter, Thanks for the response. That does help a bit. As I said before, I know little of the inner workings of I2C to be able to gather info from the datasheet and talk with the chip, but your explanation makes me think it shouldn't be too difficult if I sit down and try it out. I should have a sample of the board on Monday, so I hope to try it out very soon.

    I took a quick look at the Tachyon Forth page and it does seem pretty straightforward. Not sure about digging into it, but I may try it out for this since it just needs to be a setup to run a loop of I2C commands at the push of a button.
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2014-08-10 14:52
    UPDATE: I will be posting details about the project with the MAX7313 in a separate thread in the projects forum, but I wanted to post a few more comments on this thread regarding i2c since it ended up giving me some trouble. Here are some details from the adventure.
    • There are several i2c objects and demos, but none of them are commented in regards to the inner workings of why certain routines are done in certain ways.
    • i2C addressing can be confusing unless you remember that certain devices have a 7 bit address and then a read/write bit. This means there needs to be an extra bit of code to pass a full address since you need to combine the actual address with the R/W bit.
    • The actual connections for an i2c bus need to be properly setup. One of the i2c objects I was using states that pullups are not needed when the code is set to drive the lines in a different manner. However, this never worked for me. I ended up making a clean i2c bus on two IO pins (2 and 3) with inline 1k protection resistors and 4.7k pullups on both SCL and SDA. This presents flawless results.
    • The i2c object I ended up using, I2C SPIN Object from James Burrows, is mostly straightforward. However, the steps for performing a write on the bus include a few things that didn't make any sense to me until I was pretty much done with the project. The issue came from the strip of code shown below:
      • i2cObject.i2cWrite(dev_addr | 0,8)
        
      • You write 8 bits to the object, but the write command is designed for 32 bits. So, you OR the 8 bits with a 0. Normally, OR'ing with a 0 does nothing, but in this case, I believe it assigns the other 24 bits of the long to 0 as opposed to null? Then the ",8" is telling the command that you only want to use the last 8 bits. Since the i2cObject intends to send a long, the "8" causes the object to shift 24 bits left (32-8) so the 8 bits you want are sent out. That will take a bit to digest as it took me quite a bit to figure out........
    All in all, my LED tester project was completed Thursday. It's already proven effective.
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-08-11 06:02
    Congrats on getting it to work, but your analysis of that instruction isn't quite right. While I2C does use 7-bit device addresses, there doesn't seem to be any sort of agreement among manufacturers as to how to present it. Some datasheets simply show the seven bits, and some show separate 8-bit write and read addresses, which is just the seven bits with a 0 or 1 appended. And that, I feel, is what's responsible for a lot of the confusion in using these I2C objects. The MAX7313 datasheet presents it as 7 bits, and James Burrows wants you to use this 7-bits address with 0 appended, and then use dev_add | 0 for writes, and dev_add | 1 for reads.
    I find the i2cbits parameter confusing, as it is only used to shift i2cData, and after shifting, eight and only eight bits are ever sent. Maybe it's intended to be used by a parent object that writes multiple bytes from a long, with the parent keeping track of which byte to send?

    IMO, I2C busses should always use pullups on SCL and SDA, but for whatever reason Parallax didn't include one for the SCL on the demo board, which leads many people to assume that it isn't required. I've written drivers for pull-up and driven busses, and haven't had any problems with either. Perhaps it's the funky addressing scheme of the MAX7313, which can use SCL and SDA to determine the device address.

    You say you've tried multiple I2C objects from the obex, have you tried my I2C drivers? I tried to write them as simply as I could, just need a seven-bit device address, register address, and data, while the driver appends the 0 or 1 depending on whether a write or a read method is called. The methods handle all of the starts and stops, sending repeated starts for reads, acks for page reads, etc. They've worked fine with everything I've tested, and I'm genuinely interest in knowing if there's some way I could improve them.
  • WBA ConsultingWBA Consulting Posts: 2,934
    edited 2014-08-11 12:12
    ChrisGadd wrote: »
    Congrats on getting it to work, but your analysis of that instruction isn't quite right. While I2C does use 7-bit device addresses, there doesn't seem to be any sort of agreement among manufacturers as to how to present it. Some datasheets simply show the seven bits, and some show separate 8-bit write and read addresses, which is just the seven bits with a 0 or 1 appended. And that, I feel, is what's responsible for a lot of the confusion in using these I2C objects. The MAX7313 datasheet presents it as 7 bits, and James Burrows wants you to use this 7-bits address with 0 appended, and then use dev_add | 0 for writes, and dev_add | 1 for reads.

    Actually, I am expecting the driver to support the I2C specification, more so than individual part datasheets. So, while I agree with your statement about handling the address+R/W, (because I mis-interpreted the OR'ing with a 0) I would expect that I2C drivers would function per spec which defines the address as 7 bits appended with a read or write bit. In datasheets where a different "address" is presented for the read and write commands, it is a way for manufacturers to simplify their datasheet, which in my opinion just adds confusion to the original spec. However, now that I understand the spec better, I;ll ignore the supposed 8 bit address defined by those manufacturers and code appropriately. From section 3.1.10 of NXP's i2c spec:

    After the START condition (S), a slave address is sent. This address is seven bits long followed by an eighth bit which is a data direction bit (R/W) — a ‘zero’ indicates a transmission (WRITE), a ‘one’ indicates a
    request for data (READ)


    I find the i2cbits parameter confusing, as it is only used to shift i2cData, and after shifting, eight and only eight bits are ever sent. Maybe it's intended to be used by a parent object that writes multiple bytes from a long, with the parent keeping track of which byte to send?
    Yes, that was one source of my confusion. After looking at other objects formatted for 8, 16, 24, or 32 bits, it would appear that this code was modeled from a 32 bit version so the extra 24 bits needed to be discarded.
    IMO, I2C busses should always use pullups on SCL and SDA
    ABSOLUTELY DITTO My first mistake was believing that the options in the objects for when pullups don't exist would actually work. In my case they did not, but once pullups were added, it's flawless.
    You say you've tried multiple I2C objects from the obex, have you tried my I2C drivers? I tried to write them as simply as I could, just need a seven-bit device address, register address, and data, while the driver appends the 0 or 1 depending on whether a write or a read method is called. The methods handle all of the starts and stops, sending repeated starts for reads, acks for page reads, etc. They've worked fine with everything I've tested, and I'm genuinely interest in knowing if there's some way I could improve them.
    No, I have not. Somehow I missed yours in my OBEX searching or I may have skipped it when I saw PASM in the title. I was looking for SPIN drivers because I wanted this to be a learning experience for me and I have not delved into PASM yet. I will give them a try because at first glance, they do appear cleaner then any I have used so far in this adventure.

    This has been very enlightening in regards to some new things I have learned with SPIN as well as that I need to take more time upfront to learn about a protocol before just jumping in with an existing object that "should" work. I doubt I will be releasing any sort of MAX7313 object since I am only doing two things that aren't plain and they are just setting two configuration registers.
Sign In or Register to comment.