You are reading a single comment by @maze1980 and its replies. Click here to read the full conversation.
  • I'd propose the fix the code like this, however I didn't touch C for ages.

    Line 1: set start = 0 for the first run (cache loading)
    Line 23: wait if ccount>(0xFFFFFFFF-1000)
    Line 24: set start = ccount, in the range [0 .. (0xFFFFFFFF-1000)]

    I selected the number 1000 just to show the case, in reality it should correspond to the number of ticks needed to transfer a single bit (tOne + tLow (incl. program overhead)). Maybe 300 is more reasonable.

    
      start =  0;                     //fast pre-roll
      tZero = 63;                  //T0H = 400ns for WS2812B
      tOne = 121;                  //T1H = 800ns for WS2812B
      tLow =  181;                //PERIOD = 1200ns for WS2812B
      
      ets_intr_lock();                // disable most interrupts
      while(1) {
        GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinMask);  // Set high
        uint32_t t;
        if (pix & mask) t = tOne;
        else            t = tZero;
        while (_getCycleCount()-start < t) ;             // busy-wait (high)
        GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinMask);  // Set low
        start = _getCycleCount();
        while (_getCycleCount()-start < tLow) ;          // busy-wait (low)
        mask = mask>>1;                                  // Next bit
        if (mask == 0) {                                 // Next byte
          if (p >= end) break;                           // at end, we're done
          pix = *p++;
          mask = 0x80;
        }
        pinMask = _BV(pin);                              // correct pinMask after pre-roll
        while (_getCycleCount() > 0xFFFFFC17) ;          // ccount overflow handler
        start = _getCycleCount();                        // get start time of this bit
      }
      ets_intr_unlock();
    
About

Avatar for maze1980 @maze1980 started