sonyhome / FAB_LED

Fast Arduino Bitbang LED library supports programmable LEDs (WS2812B, APA102...), color palettes for Arduino AVR
GNU General Public License v2.0
125 stars 17 forks source link

Question about direct controll #40

Closed Tolomaj closed 1 year ago

Tolomaj commented 1 year ago

I'm working on a project using the sk6812 where I can't use the entire FAB_LED library. I trying to use part of code , specifically sendByte(). For some reason, the LEDs flash, but this is not interference, because when I use the FAB_LED library, they work as they should

Does anyone know what the difference might be between using a function from a library and using a function directly?

Mi code (the definitions are directly from the FAB_LED library) :

#define sbiCycles 2

#define NS_PER_SEC          1000000000ULL
#define CYCLES_PER_SEC      ((uint64_t) (F_CPU))
#define CYCLES(time_ns)     (((CYCLES_PER_SEC * (time_ns)) + NS_PER_SEC - 1ULL) / NS_PER_SEC)

#define SK6812_1H_CY CYCLES(1210) // 500ns 1210ns-1510ns _----------__
#define SK6812_1L_CY CYCLES(200)  // 125ns  200ns-500ns  .    .    .
#define SK6812_0H_CY CYCLES(200)  // 125ns  200ns-500ns  _-----_______
#define SK6812_0L_CY CYCLES(1210) // 500ns 1210ns-1510ns .    .    .
#define SK6812_MS_REFRESH 84      //  84,000ns Minimum wait time to reset LED strip
#define SK6812_NS_RF  833333      // Max refresh rate for all pixels to light up 2msec (LED PWM is 500Hz)

    void sendByte(uint8_t val){
      for(int8_t b=7; b>=0; b--) {
        const bool bit = (val>>b) & 0x1;
        if (bit) { // Send a ONE
          // HIGH with ASM sbi (2 words, 2 cycles)
          PORTB |= (1 << STRIP_PIN); // STRIP_PINgoes high 
          // Wait exact number of cycles specified
          __builtin_avr_delay_cycles(SK6812_1H_CY - sbiCycles);
          //  LOW with ASM cbi (2 words, 2 cycles)
          PORTB &= ~(1 << STRIP_PIN); // STRIP_PINgoes low
          // Wait exact number of cycles specified
          __builtin_avr_delay_cycles(SK6812_1L_CY - sbiCycles );
        } else {  // Send a ZERO
          // HIGH with ASM sbi (2 words, 2 cycles)
          PORTB |= (1 << STRIP_PIN); // STRIP_PIN goes high 
          // Wait exact number of cycles specified
          __builtin_avr_delay_cycles(SK6812_0H_CY - sbiCycles);
          //  LOW with ASM cbi (2 words, 2 cycles)
          PORTB &= ~(1 << STRIP_PIN); // STRIP_PINgoes low
          // Wait exact number of cycles specified
          __builtin_avr_delay_cycles(SK6812_0L_CY - sbiCycles);
        }
      }  
    }

    void sendLed(uint8_t r,uint8_t g,uint8_t b,uint8_t w){ //BRGW
     sendByte(b);
     sendByte(r);
     sendByte(g);
     sendByte(w);
    }

    void endTransmition(){  // automatic ended after 80µs
      PORTB &= ~(1 << STRIP_PIN); // PD0 goes low
      // Wait exact number of cycles specified
      __builtin_avr_delay_cycles(CYCLES(833333)); //80µs
    }

    void fillAllLes(uint8_t r,uint8_t g,uint8_t b,uint8_t w){
      for(int i = 0; i < LED_COUNT; i++ ){
        sendLed(r,g,b,w);
        }
        endTransmition();
    }

Library Code :

avrBitbangLedStrip<FAB_TVAR>::onePortSoftwareSendBytes(const uint16_t count, const uint8_t * array)
{

    for(uint16_t c=0; c < count; c++) {
        const uint8_t val = array[c];
        for(int8_t b=7; b>=0; b--) {
            const bool bit = (val>>b) & 0x1;

            if (bit) {
                // Send a ONE

                // HIGH with ASM sbi (2 words, 2 cycles)
                SET_PORT_HIGH(dataPortId, dataPortPin);
                // Wait exact number of cycles specified
                DELAY_CYCLES(high1 - sbiCycles);
                //  LOW with ASM cbi (2 words, 2 cycles)
                SET_PORT_LOW(dataPortId, dataPortPin);
                // Wait exact number of cycles specified
                DELAY_CYCLES(low1 - cbiCycles);
            } else {
                // Send a ZERO

                // HIGH with ASM sbi (2 words, 2 cycles)
                SET_PORT_HIGH(dataPortId, dataPortPin);
                // Wait exact number of cycles specified
                DELAY_CYCLES(high0 - sbiCycles);
                //  LOW with ASM cbi (2 words, 2 cycles)
                SET_PORT_LOW(dataPortId, dataPortPin);
                // Wait exact number of cycles specified
                DELAY_CYCLES(low0 - cbiCycles);
            }
        }
    }
}

Thanks for the reply.

Tolomaj commented 1 year ago

I solved it. just turn off interrupts