CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

MCP45HVX1 I2C Addressing

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

MCP45HVX1 I2C Addressing
PostPosted: Tue Dec 12, 2017 10:13 am     Reply with quote

Hi There,

I'm using a pair of MCP45HVX1 digi-pots on my board, each one works fine if I use the address byte as 0x00. Neither work if I set it to what the datasheet says, 0x78 for A1=0:A0 = 0 or 0x7A for A1=0:A0=1 (yes I'm changing the hardware pins to match!).

There's an: MCP45HVX1 Rev. A1 Silicon/Data Sheet Errata which predates my revision as my date code is YMM = 725

I've included my code as a reference:

Code:


In header file:

#use i2c(MASTER, I2C2, SLOW)

In Source:

void mcp45HVx1_setWiper(int16 val, int ch)
{
    fprintf(USB, "Set wiper to: %d\n\r",val);
    i2c_start();
    delay_us(10);
    /*if (ch = 0)                  This bit doesn't work
        i2c_write(0x78);   
    else
        i2c_write(0x7A);*/
    i2c_write(0x00);           This does
    delay_us(10);
    i2c_write(0x80);
    delay_us(10);
    i2c_write(val);
    delay_us(10);
    i2c_stop();
}


Has anybody else encountered this, or can spot something wrong please?[/code]
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Dec 12, 2017 10:26 am     Reply with quote

comments
1)_ have you got pullup resistors on the address lines ?

2) use PCM P 'I2C scanner ' program ( in code library ) to see if it finds the I2C devices. It may find them at another address, possibly due to PCB etch error,short, etc.

I always test using the scanner as it's too easy for my half dead finger to mistype code....

Jay
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

PostPosted: Tue Dec 12, 2017 10:38 am     Reply with quote

Hi Temtronic,

Thanks for reply.
Yes I have 4K7 pullups.
Haven't heard of this scanner before, so will check that out!

Regards
James
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Tue Dec 12, 2017 1:14 pm     Reply with quote

There are different address versions of the chip. The low voltage variant (without the H), uses 5 instead of 7. Double check what you have.
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Dec 12, 2017 3:01 pm     Reply with quote

yeesh THAT is just plain silly !!! let alone a pain !!! Imagine,you decide to 'upgrade' to an all low voltage version of your product and you HAVE to change code !!! arrgh
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 7:24 am     Reply with quote

I use the I2C Scanner and found both my chips at address 0x78 & 0x7A as expected, but I still cannot get communicate to them successfully yet.

Mine is the H version so uses the 7.

So my code now uses the scanner inside to check I can see it:

Code:

void mcp45HVx1_setWiper(int8 ch, int16 val)
{
    bool status0, status1, status2;
    int16 address;
   
    if (ch == 0)
        address = 0x78;
    else if(ch == 1)
        address = 0x7A;
    else if(ch == 2)
        address = 0x00;
   
    i2c_start();
    delay_us(2);
    status0 = i2c_write(address);             // Address of IC
    delay_us(2);
    status1 = i2c_write(0x80);
    delay_us(2);
    status2 = i2c_write(val);
    delay_us(2);
    i2c_stop();
   
    if(status0 || status1 || status2)
        fprintf(USB, "error %d, %d, %d\n\r", status0, status1, status2);
    else
        fprintf(USB, "Set ch: %d, add: %X to pos: %d\n\r", ch, address, val);
       
}

// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK".   This function returns TRUE if an
// ACK was found.  Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
    int8 status;

    i2c_start();
    status = i2c_write(address); // Status = 0 if got an ACK
    i2c_stop();

    if(status == 0)
        return(TRUE);
    else
        return(FALSE);
}


void main()
{
    unsigned int8 i,x;
    unsigned int8 status;
    unsigned int8 count = 0;
   
    delay_ms(1000);     
    setup_uart(921600, USB);
   
    setAD9833Frequency(25);

    delay_ms(1000);
   
    fprintf(USB, "\n\rSet 0x78 \n\r");
    mcp45HVx1_setWiper(0,254);  // smallest o/p
   
    delay_ms(1000);
    fprintf(USB, "\n\rSet 0x7A \n\r");
    mcp45HVx1_setWiper(1,254);

    delay_ms(1000);
    fprintf(USB, "\n\rSet 0x00 \n\r");
    mcp45HVx1_setWiper(2,254);
   
    fprintf(USB, "\n\rStart: Discover IC's\n\r");

    // Try all slave addresses from 0x10 to 0xEF.
    // See if we get a response from any slaves
    // that may be on the i2c bus.
   
    for(i=0x10; i < 0xF0; i+=2)
    {
        status = get_ack_status(i);
        if(status == TRUE)
        {
            fprintf(USB, "ACK addr: %X\n\r", i);
            count++;
            delay_ms(2000);
        }
    }

    if(count == 0)
        fprintf(USB, "\n\rNothing Found");
    else
        fprintf(USB, "\n\rNumber of i2c chips found: %u\n\r", count);
       
    while(1);
}


I only have one chip connected (scl & sda pins lifted on other) and set A1 = low & A0 = high, my printf is now:


Set 0x78
error 1, 1, 1

Set 0x7A
error 0, 1, 1

Set 0x00
Set ch: 2, add: 0 to pos: 254

Start: Discover IC's
ACK addr: 7A

Number of i2c chips found: 1

* So from that the first write to 0x78 has errors for wrong address, no change in wiper postion
* Second call is the correct address, so we get 0 back ack, but next two bytes don't get ack'ed, so it doesn't like them. No change in wiper postion.
* Third call to 0x00, to wrong address, no errors and works fine!

From datasheet the only !A reasons are:
-Slave address not valid
-Device memory address and specified command (AD3:AD0 and C1:C0) are invalid combination

But I've double checked my memory and command as 0x80 being fine to set wiper in volatile.

I really can't see what can be causing this, shortly I'm going to have to take a scalpel to the board and use the second I2C for the second IC!
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 9:18 am     Reply with quote

You keep referring to the 'X1'. Do you have the 51?. The 31 only supports 0 to 127 as the position.
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 9:27 am     Reply with quote

Yes sorry I have the MCP45HV51
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 9:40 am     Reply with quote

What voltage are you working?.
Describe your bus. How long is it?. How many devices in total?. What sort of connections?.
What clock rate are you setting the bus up for?.
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 9:43 am     Reply with quote

this...
status1 = i2c_write(0x80);

.. I think is wrong.

If I read the datasheet correct, it's the 'command' byte, where the high nibble ( 8 or 0b1000 in this case) refers to the chips memory map. I think it should be 0b0000 to select wiper #0

Maybe I'm wrong.... but worth rechecking .

Jay
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 10:04 am     Reply with quote

Thanks,
My dspic33fj256mc710a is on 3V3.
The MCP45HV51's VL is on 5v, V+ is +15V, V- is -15V
I2C bus is approx. 4" long with only two digipots on there. 4K7 pullups to 5V at digipot end, SCL2 & SDA2 are switching nicely between 5V and 0V, no connectors just several vias. Pins 58 (SCL2) & 59 (SDA2) are 5V tolerant.
SPI bus runs parallel for short duration, but not active after setAD9833Frequency(25);

Code:
#use i2c(MASTER, I2C2, SLOW, FORCE_HW)


I have been using my prototype board with one of these digi-pots hanging off on kynar and breakout board for a few months without issue (all be it using the wrong address) and have re-spun the board with the second one added on. Our proto board supplier was bought out by someone else and this is in the first batch from them, if it wasn't working so well with the wrong address, I'd be looking for fractured barrels etc.

I'm baffled it seems as it the errata is applying to me pic, even though my manufacture date is 2 years later!
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

MCP45HVX1 Rev. A1 Silicon/Data Sheet Errata
PostPosted: Wed Dec 13, 2017 10:16 am     Reply with quote

Module: I2C™ Interface The MCP45HVX1 interface will accept the serial data that was intended for other devices on the I2C™ bus. This occurs when the other device on the same I2C bus Acknowledges the I2C Control Byte (contains the I2C Slave Address). This causes the MCP45HVX1 to accept the subsequent serial data until either a Stop or Restart condition occurs. The MCP45HVX1 will interpret this received data per the defined command definitions.
Work around Each MCP45HVX1 device would need to be on a unique I2C bus with no other I2C devices.
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 11:39 am     Reply with quote

Temtronic's comment is right.

An invalid register address will make the chip not acknowledge.

The reason it works on zero, is that this is a Microchip 'overload' to the GCA operation, and this only looks at bits 3 & 3 of the next byte to automatically select a 'write register 0' operation.

He has the A2 revision CCSFred.
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

You guys are awesome!
PostPosted: Thu Dec 14, 2017 4:55 am     Reply with quote

Thanks so much Ttelmah & temtronic, you are quite correct! It now works perfectly, saving me from a "work around" and hacking my new board. Very Happy Very Happy Very Happy
Thanks again!
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Dec 14, 2017 5:52 am     Reply with quote

I happy you're happy it works !!
One comment about this line..
status1 = i2c_write(0x80);

I've found it best to put a name to numbers like 0x80. At the very least toss a comment on the end of the line, so 3 months from now or even 2 days from now you'll KNOW what 0x80 means. It's especially important when the value is actually a combination of bits. Perhaps not a big deal for this PIC project but sooner or later you'll spend a couple long nights wondering why something doesn't work only to find out that 0x10 is supposed to be 0x01 and WHEN did the 'fat fingers' change THAT !

up and running is always nice
Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group