terjeio / grblHAL

This repo has moved to a new home https://github.com/grblHAL
232 stars 90 forks source link

MCU hang after toggling "strobe" #265

Closed MaxVandenbussche closed 3 years ago

MaxVandenbussche commented 3 years ago

Hello.

I want to use the i2c keypad plugin. But everytime the strobe-pin is pulled low, the MCU hangs and needs to be reset. There is also no toggling on the i2c SDA and SCL lines. Any ideas?

Br, Max

terjeio commented 3 years ago

Which driver?

MaxVandenbussche commented 3 years ago

IMXRT1062 running on a Teensy 4.1 mounted on a grblHAL Breakout Board Unkit for Teensy 4.1.

phil-barrett commented 3 years ago

Are you using pre-built binaries?

terjeio commented 3 years ago

My test keypad (modified for pulling the strobe pin low) works with this setup. I'll have to revisit the iMXRT1020 I2C code, it is possible it should be "hardened" by adding a timeout if the keypad does not respond in time?

Have you made and written code for the keypad yourself?

MaxVandenbussche commented 3 years ago

I am building my own keypad and writing my own code for a different MCU. Indeed, I used the code for the MSP430 as a reference.

In any case it would be a good idea to have a timeout if the keypad does not respond in time to not have the whole system hang. This was my first thought. But after I pull the strobe low I never even get a falling edge on the SCL line. I assume the master should at least address the slave once. So I think this is not a timeout problem.

terjeio commented 3 years ago

The I2C code is interrupt driven with callback and will hang on the second attempt to address the keypad if the first one never completes. So a plain timeout will not work. I'll have to see how I can work around that.

Since my keypad work something must be amiss with your setup, even a broken MCU?

Is the keypad module reported in the $I report? The correct board is selected? Is SCL, SDA and strobe pins at 3.3V after bootup? What are they after the first strobe?

You may replace while(i2cIsBusy); in the code below with if(i2cIsBusy) return; as a temporary workaround for the hang.

https://github.com/terjeio/grblHAL/blob/f85da79de95db12eff347f146f862bdfbb4f683d/drivers/IMXRT1062/grblHAL_Teensy4/src/i2c.c#L339-L346

A big pity that the Teensy is not debuggable, makes it hard to develop for...

terjeio commented 3 years ago

Try with this code, it resets the bus and the I2C peripheral on a timeout. With this I can disconnect a signal to make the bus hang, after reconnect it starts working again.

void I2C_GetKeycode (uint32_t i2cAddr, keycode_callback_ptr callback)
{
    while(i2cIsBusy) {
        if(port->MSR & LPI2C_MSR_PLTF) {
            if(force_clock(hardware)) {
                port->MCR = LPI2C_MCR_RST;
                setClock(port, 100000);
            } else
                return; // or alarm?
        }
    }

    i2c.keycode_callback = callback;

    I2C_Receive(i2cAddr, NULL, 1, false);
}
terjeio commented 3 years ago

The bus reset code above has been added so I am closing this issue. Open a new at the new repo if still an issue.