chipKIT® Development Platform

Inspired by Arduino™

I2C/Wire Library Problem - No I2C activity on addresses 0-7

Created Mon, 07 Jan 2013 20:44:56 +0000 by alexa


alexa

Mon, 07 Jan 2013 20:44:56 +0000

Hello Everyone,

First, some background. I have a chipKit uC32 with a Basic I/O Shield that I've been playing with. I've successfully talked to the EEProm on the I/O Shield using I2C, by following the EEProm Demo code. Everything works just fine. When I hook up my Logic Analyzer, I can see the I2C lines moving nicely, and everything looks in order.

The problem happens when I try to communicate with my Cypress Capsense Express IC, that I've also hooked into the I2C bus. This IC has a default I2C address of 0x00 (dumb, yes, I know it is the I2C broadcast address).

When I try to talk to this address using I2C, nothing happens on the I2C lines. They lay flat at logic high. It seems like the Wire library is never sending communications when it sees these addresses.

I spent some time trying to debug this, and wrote a quick sketch to troll through every possible address (0-127), and report the ACK/NACK status (attached is my code, a screenshot of the Logic Analyzer Output, along with the serial output debug data).

Results: Address 0-7: returns a 0 (success), but no activity on logic analyzer Addresses 72 and 80: (temp sensor, and EEProm), return success, and the logic analyzer shows activity. Address 124: returns a data NACK. As far as I know, there isn't anything using this address on the I2C bus. It also does not respond to communication using the capsense protocol, so I think this may be a red herring. All other addresses: Return address NACK.

So, long story short, there seems to be some problem with addresses 0-7. Perhaps I'm misunderstanding the Wire library code, or the I2C spec, but from what I an tell, THIS SHOULD WORK.

Thoughts?

(p.s. I can only add three attachments, so let me know if you'd like the raw logic analyzer session data, not that it is very instructive :/)


alexa

Tue, 08 Jan 2013 01:07:53 +0000

Aaaaand, I figured it out.

The PIC doesn't support addresses < 8. Sigh.


les1943

Tue, 08 Jan 2013 11:35:23 +0000

I found this document very useful

NXP Semiconductors UM10204 I2C-bus specification and user manual (extract) 3.1.12 Reserved addresses Two groups of eight addresses (0000 XXX and 1111 XXX) are reserved for the purposes shown in Table 3. [1] The general call address is used for several functions including software reset. [2] No device is allowed to acknowledge at the reception of the START byte. [3] The CBUS address has been reserved to enable the inter-mixing of CBUS compatible and I2C-bus compatible devices in the same system. I2C-bus compatible devices are not allowed to respond on reception of this address. [4] The address reserved for a different bus format is included to enable I2C and other protocols to be mixed. Only I2C-bus compatible devices that can work with such formats and protocols are allowed to respond to this address. Assignment of addresses within a local system is up to the system architect who must take into account the devices being used on the bus and any future interaction with other conventional I2C-buses. For example, a device with seven user-assignable address pins allows all 128 addresses to be assigned. If it is known that the reserved address is never going to be used for its intended purpose, a reserved address can be used for a slave address. 3.1.13 General call address The general call address is for addressing every device connected to the I2C-bus at the same time. However, if a device does not need any of the data supplied within the general call structure, it can ignore this address by not issuing an acknowledgment. If a device does require data from a general call address, it acknowledges this address and behave as a slave-receiver. The master does not actually know how many devices acknowledged if one or more devices respond. The second and following bytes are acknowledged by every slave-receiver capable of handling this data. A slave who cannot process one of these bytes must ignore it by not-acknowledging. Again, if one or more slaves acknowledge, the not-acknowledge will not be seen by the master. The meaning of the general call address is always specified in the second byte . Table 3. Reserved addresses X = don’t care; 1 = HIGH; 0 = LOW. Slave address R/W bit Description 0000 000 0 general call address[1] 0000 000 1 START byte[2] 0000 001 X CBUS address[3] 0000 010 X reserved for different bus format[4] 0000 011 X reserved for future purposes 0000 1XX X Hs-mode master code 1111 1XX 1 device ID 1111 0XX X 10-bit slave addressing


alexa

Thu, 17 Jan 2013 16:07:51 +0000

Thanks for the pointer. However:

3.1.13 General call address The general call address is for addressing every device connected to the I2C-bus at the same time. However, if a device does not need any of the data supplied within the general call structure, it can ignore this address by not issuing an acknowledgment. If a device does require data from a general call address, it acknowledges this address and behave as a slave-receiver. The master does not actually know how many devices acknowledged if one or more devices respond. The second and following bytes are acknowledged by every slave-receiver capable of handling this data. A slave who cannot process one of these bytes must ignore it by not-acknowledging. Again, if one or more slaves acknowledge, the not-acknowledge will not be seen by the master. The meaning of the general call address is always specified in the second byte .

Yeah, those are reserved addresses, but the PIC should be able to talk at them (especially the general call address), instead of refusing to move the lines at all. This is a shortcoming of the PIC platform, not of the I2C standard.


dangeljs

Thu, 17 Jan 2013 16:57:24 +0000

Did you try to remove the lines that exclude the addresses 0-8? In the 'twi.c' file for the PIC32 there is:

uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait)
{
  uint8_t i;
  if(address &lt; 8)
  {
	  return 0;
  }
  // ensure data will fit into buffer
  if (TWI_BUFFER_LENGTH &lt; length)
  {
    return 1;
  }

and

uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length)
{
  unsigned int i;
  if (address &lt; 8)
  {
	  return 0;
  }
  // Ensure data will fit into buffer
  if (TWI_BUFFER_LENGTH &lt; length){
    return 0;
  }

that aren't allowing those addresses through. I haven't tried and don't have the means/need to check it, but you can modify your file and see if it works.

Good luck.