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.
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,
Issue has been solved, just some added syntax to get it going