the trickiest part is when i have received the register address from the Master and have to enable interrupts on both, SCL and SDA, lines. Sometimes the ESP8266 cant keep up, if SDA changes to quickly after SCL becomes high.
I then stumbled accross Xtensa® Instruction Set Architecture (ISA) Reference Manual. In Chapter 4.4.4.4 is an explanation on how to use a single ASM instruction to change the current intterupt level, which means dis-/enabling all interupts is very very fast, because the controller doesnt have to deal with a C-Function:
rsil a2, *newlevel*
*newlevel* can have the values from 0 to 3. This has got me a good boost of around 0.5 to 0.75 µs from the entry point of my ISR to reenabling the interrupts. Since i am using Arduino IDE to keep things simple, you can use it like this:
__asm__("rsil a2, *newlevel*");
I am not allowed to post any specific source from my library, but i can show you, how my setup routine looks in my testing program:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
volatile uint8_t I2C_Slave_RxBuffer[256] = { 0x00 };
volatile uint8_t I2C_Slave_TxBuffer[256] = { 0x00 };
volatile uint8_t I2C_Slave_RegAddresses[10] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xFE };
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SETUP ROUTINE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
// Open Serial Port for Debug
Serial.begin(115200);
Serial.setDebugOutput(true);
delay(250);
// Print Chip Information
printChipInformation();
// Fill TxBuffer with Random Values
uint16_t i = 0;
for ( i ; i<sizeof(I2C_Slave_TxBuffer) ; i++) {
I2C_Slave_TxBuffer[i] = RANDOM_REG32 & 0xff;
}
// Set GPIOs for SCL and SDA
I2C_SLAVE_setGPIOs(5,4);
// Set allowed Register Addresses
I2C_SLAVE_setRegisters( I2C_Slave_RegAddresses );
// Pass Rx and Tx Buffers (It is possible to use the same Buffer for Rx and Tx)
I2C_SLAVE_setRxBuf(I2C_Slave_RxBuffer);
I2C_SLAVE_setTxBuf(I2C_Slave_TxBuffer);
// Set I2C Slave Address to listen to
I2C_SLAVE_init(0x69);
}
Here are two screenshots for reading and writing with 2 ESP8266 at 100 kHz. Master ESP8266 runs at 80 MHz, Slave ESP8266 still runs at 160 MHz.
I hope it helps you improving your code
// Edit: I recently implemented Clock Stretching, that is why there are pauses in the pictures. Also fixed some typos.