These are chat archives for Makuna/NeoPixelBus

20th
Aug 2015
sticilface
@sticilface
Aug 20 2015 06:00
I tried 200us, it lasts a bit longer then reboots. I guess we should get onto esspressif as it used to work but now doesn't!
bbx10
@bbx10
Aug 20 2015 07:12
Using DMA with SPI or I2S controllers should eliminate the need to disable interrupts. If espressif does not fix the problem, DMA might be the only option.
sticilface
@sticilface
Aug 20 2015 20:18
@Makuna @bbx I've got a workaround....it works... it is not too bad... stable as a horse, and no longer reboots with ping -f. But it is not pretty from a coding point of view... I moved the nointurrupts... into the actual send function. there is the occasional glitch. but it is acceptable... at least for now. and it does not crash!!!!
void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixels, uint8_t* end, uint8_t pin)
{
    const uint32_t pinRegister = _BV(pin);
    uint8_t mask;
    uint8_t subpix;
    uint32_t cyclesStart;
    // trigger emediately
    cyclesStart = _getCycleCount() - 800000;
    do
    {
     uint32_t savedPS = xt_rsil(15);  // disable interrupts and save state... 
        subpix = *pixels++;
        for (mask = 0x80; mask != 0; mask >>= 1)
        {
            // do the checks here while we are waiting on time to pass
            uint32_t cyclesBit = ((subpix & mask)) ? CYCLES_800_T1H : CYCLES_800_T0H;
            uint32_t cyclesNext = cyclesStart;
            uint32_t delta;

            // after we have done as much work as needed for this next bit
            // now wait for the HIGH
            do
            {
                // cache and use this count so we don't incur another 
                // instruction before we turn the bit high
                cyclesStart = _getCycleCount();
            } while ((cyclesStart - cyclesNext) < CYCLES_800);


            // set high
            GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinRegister);

            // wait for the LOW
            do
            {
                cyclesNext = _getCycleCount();
            } while ((cyclesNext - cyclesStart) < cyclesBit);

            // set low
            GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
        }

    xt_wsr_ps(savedPS); // restore the state

    } while (pixels < end);

    // while accurate, this isn't needed due to the delays at the 
    // top of Show() to enforce between update timing
    // while ((_getCycleCount() - cyclesStart) < CYCLES_800);
}

i tried to add something, to get the send function to bail out if an interrupt fired during sending! I tried this

 if (_getCycleCount() - Endcyclecount > 13) { break; }

with Endcyclecount being set at the end after interrupts have been re-enabled... but it was actually more glitchy.. this works though, only occasional flashes..

Michael Miller
@Makuna
Aug 20 2015 21:31
@sticilface are you running at 40mhz or 80 mhz clock? Please try to double it with your change and try again. The issue is that the timing in the loop is pretty tight at the default speed, so the extra statements for rsil and wsr may cause an occasional glitch, but double speed would not. If it still glitches then the interrupt is taking more than 0.125us (the pixel error time per bit)
sticilface
@sticilface
Aug 20 2015 21:33
i've always been running at 160mhz, 80mhz for flash... ever since we had the option!
sticilface
@sticilface
Aug 20 2015 21:40
so with interrupts...the pixels are a total mess, completely unusable.. but if they are enabled and disabled per bit, then actually there is only the odd glitch... what i wanted was a way to find out if an interrupt has fired during the sending and then bail out on sending the rest, flag the strip as dirty so on the next show(), it tries again. it would probably not be noticed if the end pixels are not updated in one pass or the next. anyway....
bbx10
@bbx10
Aug 20 2015 22:53
@sticilface I see glitches but no crashes after a few minutes. I was getting crashes but I forgot to remove the calls to noInterrupts()/interrupts(). Running with CPU clock 160 MHz and added xt_rsil and xt_wsr_ps as shown above. Reducing the ping frequency reduces the glitches. sudo ping -i 0.01 <ESP IP> results in 100 pings/sec which is probably closer to real life network activity.