Chat here about code rewrites, mods, etc... with respect to the github project

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 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 };

void setup()
    // Open Serial Port for Debug

    // Print Chip Information
    // 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

    // 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)

    // Set I2C Slave Address to listen to

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.
User avatar
By rajhlinux
#89664 Hello all, I need some help in making a WeMos D1 Mini (ESP8622) into slave mode for I2C.

So everyone says you can not make the ESP8622 into slave mode, but here I'm seeing you guys making your ESP8622 into slave mode, I am puzzled...

So what do I need to make my ESP8622 into I2C slave mode?

Is there some kind of implementation I can download, such as a library and compile the code using Arduino?

User avatar
By StanJ
#89763 There are slave examples in the Wire library: slave_receiver and slave_sender. In order for them to work, you should compile with 160MHz CPU clock and only run the slave at 50KHz or slower. The slow speed is due to the SDK interrupt processing latency, which is insanely high compared to other micros I've used.

The slave code in the Wire library is horribly buggy. I started re-writing it from scratch and then got distracted by COVID, trying to keep all of our employees alive. It's much harder for me since some of the Wire core is now in C++, and I don't understand it any longer. I can code assembly with ease, but C++ just completely stumps me.