Keil Logo Arm Logo

Simulate Multiple I2C devices in Keil known code

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Chris B
Posted
16-Mar-2009 13:08 GMT
Toolset
C51
New! Simulate Multiple I2C devices in Keil known code

I have been using code supplied by Keil to simulate I2C slaves and it works great......only problem.....its one device only. Using the VTREG's it does, I tried to modify the code by +1's on the call names, but that didn't work. I have at least 14 I2C slaves and would like the master to be able to simulate them all.....again it works if I adjust the I2C address for the single device I want to address. I'd like to try them all. Here is the original code:


// Simulation of I2C Memory (Slave)

MAP V:0,V:0xFF READ WRITE                    // Map User Memory region

DEFINE int SADR                              // Slave Address

signal void I2CMEMORY (void) {
  unsigned long adr;

  adr = V:0;
  while (1) {
    wwatch (I2C_OUT);                        // Wait for data from Microcontroller
    while (I2C_OUT == 0x0100) {              // START detected
      wwatch (I2C_OUT);                      // Wait for data from Microcontroller
      if (I2C_OUT > 0xFF) continue;
      if ((I2C_OUT >> 1) != SADR) continue;  // test if Slave is addressed
      I2C_IN = 0xFF00;                       // ACK to Microcontroller
      if (I2C_OUT & 1) {                     // Slave Read
        while (1) {
          I2C_IN = _RBYTE(adr);              // Read Byte from Memory
          adr++;                             // Increment Address
          wwatch (I2C_OUT);                  // Wait for ACK from Microcontroller
          if (I2C_OUT != 0xFF00) break;
        }
      }
      else {                                 // Slave Write
        wwatch (I2C_OUT);                    // Wait for data from Microcontroller
        if (I2C_OUT > 0xFF) continue;
        adr = I2C_OUT | V:0;                 // Set Memory Address
        I2C_IN = 0xFF00;                     // ACK to Microcontroller
        while (1) {
          wwatch (I2C_OUT);                  // Wait for data from Microcontroller
          if (I2C_OUT > 0xFF) break;
          _WBYTE (adr, I2C_OUT);             // Store Byte in Memory
          adr++;                             // Increment Address
          I2C_IN = 0xFF00;                   // ACK to Microcontroller
        }
      }
    }
  }
}


SADR = 0x51
I2CMemory()

I tried:


// Simulation of I2C Memory (Slave)

MAP V:0,V:0xFF READ WRITE                    // Map User Memory region

DEFINE int SADR                              // Slave Address

signal void I2CMEMORY1 (void) {
  unsigned long adr;

  adr = V:0;
  while (1) {
    wwatch (I2C_OUT);                        // Wait for data from Microcontroller
    while (I2C_OUT == 0x0100) {              // START detected
      wwatch (I2C_OUT);                      // Wait for data from Microcontroller
      if (I2C_OUT > 0xFF) continue;
      if ((I2C_OUT >> 1) != SADR) continue;  // test if Slave is addressed
      I2C_IN = 0xFF00;                       // ACK to Microcontroller
      if (I2C_OUT & 1) {                     // Slave Read
        while (1) {
          I2C_IN = _RBYTE(adr);              // Read Byte from Memory
          adr++;                             // Increment Address
          wwatch (I2C_OUT);                  // Wait for ACK from Microcontroller
          if (I2C_OUT != 0xFF00) break;
        }
      }
      else {                                 // Slave Write
        wwatch (I2C_OUT);                    // Wait for data from Microcontroller
        if (I2C_OUT > 0xFF) continue;
        adr = I2C_OUT | V:0;                 // Set Memory Address
        I2C_IN = 0xFF00;                     // ACK to Microcontroller
        while (1) {
          wwatch (I2C_OUT);                  // Wait for data from Microcontroller
          if (I2C_OUT > 0xFF) break;
          _WBYTE (adr, I2C_OUT);             // Store Byte in Memory
          adr++;                             // Increment Address
          I2C_IN = 0xFF00;                   // ACK to Microcontroller
        }
      }
    }
  }
}


SADR = 0x50
I2CMemory1()

// Simulation of I2C Memory (Slave)

signal void I2CMEMORY2 (void) {
  unsigned long adr;

  adr = V:10;
  while (1) {
    wwatch (I2C_OUT);                        // Wait for data from Microcontroller
    while (I2C_OUT == 0x0100) {              // START detected
      wwatch (I2C_OUT);                      // Wait for data from Microcontroller
      if (I2C_OUT > 0xFF) continue;
      if ((I2C_OUT >> 1) != SADR) continue;  // test if Slave is addressed
      I2C_IN = 0xFF00;                       // ACK to Microcontroller
      if (I2C_OUT & 1) {                     // Slave Read
        while (1) {
          I2C_IN = _RBYTE(adr);              // Read Byte from Memory
          adr++;                             // Increment Address
          wwatch (I2C_OUT);                  // Wait for ACK from Microcontroller
          if (I2C_OUT != 0xFF00) break;
        }
      }
      else {                                 // Slave Write
        wwatch (I2C_OUT);                    // Wait for data from Microcontroller
        if (I2C_OUT > 0xFF) continue;
        adr = I2C_OUT | V:0;                 // Set Memory Address
        I2C_IN = 0xFF00;                     // ACK to Microcontroller
        while (1) {
          wwatch (I2C_OUT);                  // Wait for data from Microcontroller
          if (I2C_OUT > 0xFF) break;
          _WBYTE (adr, I2C_OUT);             // Store Byte in Memory
          adr++;                             // Increment Address
          I2C_IN = 0xFF00;                   // ACK to Microcontroller
        }
      }
    }
  }
}


SADR = 0x51
I2CMemory2()

The simulation doesn't crash, but the I2C interface doesn't work the interface properly anymore. Any thoughts on how to address this? I thought this would work since it is two different function in the same memory map space as local functions. I guess I'm missing something.

Read-Only
Author
Chris B
Posted
16-Mar-2009 13:10 GMT
Toolset
C51
New! RE: Simulate Multiple I2C devices in Keil known code

Here is the crossposted link to 8052

http://www.8052.com/forum/thread/163473

Read-Only
Author
Andy Neil
Posted
17-Mar-2009 08:33 GMT
Toolset
C51
New! Just a thought

does the Keil simulation claim to support more than a single device?

ie, does it not work because it isn't supposed to...?

Read-Only
Author
Chris B
Posted
17-Mar-2009 13:02 GMT
Toolset
C51
New! RE: Just a thought

They don't claim either way, so since the memory map is defined, I would expect that having two seperate unique functions would we ok. I have an oscillator running from VTREG's and one I2C slave. There isn't much to go on except the example and the fact that it does work with one.

I think I may have found the issue I mentioned on 8052 and as I mess with it more, I recall your help in the past about no precompilier directives, I think one of my errors is one of my defines are in the wrong location.

I'll give that a try and post up the code if I can get it to work.

Any other thoughts are more than welcome.

Regards,

Read-Only
Author
Chris B
Posted
18-Mar-2009 04:27 GMT
Toolset
C51
New! RE: Just a thought

Issue has been solved, just some added syntax to get it going

Read-Only
Author
Günter Kollmann
Posted
17-Mar-2009 09:55 GMT
Toolset
C51
New! RE: Simulate Multiple I2C devices in Keil known code

You must check the address and data fields inside from ONE service routine.

Depending which chip your tried to access different actions may happen.

For example using 4 IO-chips (PCA9555) the address decided which from this chips is written to or read from.

But the 'action' from processors 'point of view' is evereytime the same! ->i2c-isr.

good luck :)

Read-Only
Author
Chris B
Posted
17-Mar-2009 13:09 GMT
Toolset
C51
New! RE: Simulate Multiple I2C devices in Keil known code

Gunter, all of my code already works and follows what you said, my issue is Keil simulating several devices within the single .ini file. So the example code must be replicated 4 times with unique values and address for each "individual" slave. As it stands now, I have to save SADR = to the value of what is needed for each individual slave. Makes time consuming to test blocks of code, so adding several with w/r capability will make the simulation easy to work with.

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Keil logo

Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.