Chat here about code rewrites, mods, etc... with respect to the github project https://github.com/esp8266/Arduino

Moderator: igrr

User avatar
By Driftmonster
#76423 Hello bjoham,

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:
Code: Select allrsil 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:
Code: Select all__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:
Code: Select all////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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.
Image
Image

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.