Tried cleaning things up and putting out some new assembly
didn't work
This commit is contained in:
parent
5c28706133
commit
136a1da5b3
22
flake.nix
22
flake.nix
|
@ -284,6 +284,28 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
packages."x86_64-linux"."ws2812_" =
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
||||||
|
avr = pkgs.pkgsCross.avr.buildPackages;
|
||||||
|
in packages."x86_64-linux"."ws2812" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags attiny85; avr = true; };
|
||||||
|
packages."x86_64-linux"."ws2812" =
|
||||||
|
{ gcc, cflags, avr }:
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
||||||
|
in mkProgram {
|
||||||
|
pkgs = pkgs;
|
||||||
|
gcc = gcc;
|
||||||
|
cflags = cflags;
|
||||||
|
pname = "ws2812";
|
||||||
|
psrc = ./ws2812;
|
||||||
|
inherit avr;
|
||||||
|
|
||||||
|
pbuildInputs = [
|
||||||
|
(packages."x86_64-linux"."dio" { inherit gcc cflags; })
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
devShell."x86_64-linux" =
|
devShell."x86_64-linux" =
|
||||||
let
|
let
|
||||||
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
||||||
|
|
|
@ -26,16 +26,26 @@
|
||||||
|
|
||||||
#define write_byte(port, bit, byte) \
|
#define write_byte(port, bit, byte) \
|
||||||
__asm__ __volatile__ ( \
|
__asm__ __volatile__ ( \
|
||||||
"ldi %z, 8" "\n\t" \ // count out eight bits
|
; count out eight bits \
|
||||||
"ld __tmp_reg__, %[byte]" "\n\t" \ // load the current byte into a temporary register
|
"ldi %z, 8" "\n\t" \
|
||||||
"L_%=: " "lsl __tmp_reg__" "\n\t" \ // shift the temporary register left, saving the msb in SREG (1 cycle)
|
; load the current byte into a temporary register \
|
||||||
"brbs I_%=" "\n\t" \ // if SREG is set, branch to I_%= (2 cycles if true, 1 cycle if false)
|
"ld __tmp_reg__, %[byte]" "\n\t" \
|
||||||
write_zero(port, bit) \ // SREG was zero, so write a zero to the port
|
; shift the temporary register left, saving the msb in SREG (1 cycle) \
|
||||||
"rjmp J_%=" "\n\t" \ // Jump to J_%=, the loop cleanup (2 cycles)
|
"L_%=: " "lsl __tmp_reg__" "\n\t" \
|
||||||
"I_%=: " write_one(port, bit) \ // SREG was one, so write a one to the port
|
; if SREG is set, branch to I_%= (2 cycles if true, 1 cycle if false) \
|
||||||
"J_%=: " "dec %z" "\n\t" \ // Decrement the bits counter (1 cycle)
|
"brbs I_%=" "\n\t" \
|
||||||
"cpi %z, 0" "\n\t" \ // are there any bits left to send? (1 cycle)
|
; SREG was zero, so write a zero to the port \
|
||||||
"brne L_%=" "\n\t" \ // there are, so go back to L_%= (2 cycles)
|
write_zero(port, bit) \
|
||||||
|
; Jump to J_%=, the loop cleanup (2 cycles) \
|
||||||
|
"rjmp J_%=" "\n\t" \
|
||||||
|
; SREG was one, so write a one to the port \
|
||||||
|
"I_%=: " write_one(port, bit) \
|
||||||
|
; Decrement the bits counter (1 cycle) \
|
||||||
|
"J_%=: " "dec %z" "\n\t" \
|
||||||
|
; are there any bits left to send? (1 cycle) \
|
||||||
|
"cpi %z, 0" "\n\t" \
|
||||||
|
; there are, so go back to L_%= (2 cycles) \
|
||||||
|
"brne L_%=" "\n\t" \
|
||||||
: /* no outputs */ \
|
: /* no outputs */ \
|
||||||
: [byte] "I" (byte) \
|
: [byte] "I" (byte) \
|
||||||
)
|
)
|
||||||
|
|
163
ws2812/main.c
163
ws2812/main.c
|
@ -1,8 +1,9 @@
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
|
#include <dio.h>
|
||||||
#include "ws2812.h"
|
#include "ws2812.h"
|
||||||
#include "np_common.c"
|
|
||||||
|
|
||||||
|
/*
|
||||||
#include <simavr/avr/avr_mcu_section.h>
|
#include <simavr/avr/avr_mcu_section.h>
|
||||||
AVR_MCU(F_CPU, "attiny85");
|
AVR_MCU(F_CPU, "attiny85");
|
||||||
|
|
||||||
|
@ -10,162 +11,18 @@ const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = {
|
||||||
{ AVR_MCU_VCD_SYMBOL("DDRB"), .what = (void*)&DDRB, },
|
{ AVR_MCU_VCD_SYMBOL("DDRB"), .what = (void*)&DDRB, },
|
||||||
{ AVR_MCU_VCD_SYMBOL("PORTB"), .what = (void*)&PORTB, },
|
{ AVR_MCU_VCD_SYMBOL("PORTB"), .what = (void*)&PORTB, },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PIXEL_COUNT 7
|
|
||||||
/*
|
|
||||||
const uint8_t pixels_0[PIXEL_COUNT * 3] =
|
|
||||||
{ 255, 0, 255,
|
|
||||||
255, 255, 0,
|
|
||||||
255, 255, 255 };
|
|
||||||
*/
|
|
||||||
|
|
||||||
const uint8_t pixels_1[PIXEL_COUNT * 4] =
|
|
||||||
{ 0, 0, 0, 0,
|
|
||||||
32, 0, 0, 0,
|
|
||||||
64, 0, 0, 0,
|
|
||||||
96, 0, 0, 0,
|
|
||||||
128, 0, 0, 0,
|
|
||||||
160, 0, 0, 0,
|
|
||||||
192, 0, 0, 0 };
|
|
||||||
|
|
||||||
const uint8_t pixels_2[PIXEL_COUNT * 4] =
|
|
||||||
{ 0, 0, 0, 0,
|
|
||||||
0, 32, 0, 0,
|
|
||||||
0, 64, 0, 0,
|
|
||||||
0, 96, 0, 0,
|
|
||||||
0, 128, 0, 0,
|
|
||||||
0, 160, 0, 0,
|
|
||||||
0, 192, 0, 0 };
|
|
||||||
|
|
||||||
const uint8_t pixels_3[PIXEL_COUNT * 4] =
|
|
||||||
{ 0, 0, 0, 0,
|
|
||||||
0, 0, 32, 0,
|
|
||||||
0, 0, 64, 0,
|
|
||||||
0, 0, 96, 0,
|
|
||||||
0, 0, 128, 0,
|
|
||||||
0, 0, 160, 0,
|
|
||||||
0, 0, 192, 0 };
|
|
||||||
|
|
||||||
const uint8_t pixels_4[PIXEL_COUNT * 4] =
|
|
||||||
{ 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 32,
|
|
||||||
0, 0, 0, 64,
|
|
||||||
0, 0, 0, 96,
|
|
||||||
0, 0, 0, 128,
|
|
||||||
0, 0, 0, 160,
|
|
||||||
0, 0, 0, 192 };
|
|
||||||
|
|
||||||
void blink(void) {
|
|
||||||
PORTB |= _BV(2);
|
|
||||||
_delay_ms(100);
|
|
||||||
PORTB &= ~(_BV(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void fade_in(const uint8_t *pixels);
|
|
||||||
void fade_out(void);
|
|
||||||
|
|
||||||
void fade_in(const uint8_t *pixels) {
|
|
||||||
uint8_t current[PIXEL_COUNT * 4];
|
|
||||||
for (int i = 0; i < 255; i++) {
|
|
||||||
for (int idx = 0; idx < PIXEL_COUNT * 4; idx++) {
|
|
||||||
if (current[idx] < pixels[idx]) {
|
|
||||||
current[idx] += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write_pixels(current, PIXEL_COUNT * 4);
|
|
||||||
_delay_ms(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fade_out() {
|
|
||||||
uint8_t current[PIXEL_COUNT * 4];
|
|
||||||
for (int i = 0; i < 255; i++) {
|
|
||||||
for (int idx = 0; idx < PIXEL_COUNT * 4; idx++) {
|
|
||||||
if (current[idx] > 0) {
|
|
||||||
current[idx] -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write_pixels(current, PIXEL_COUNT * 4);
|
|
||||||
_delay_ms(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define PIXEL_COUNT 1
|
||||||
|
const rgb_t pixels[PIXEL_COUNT] = {
|
||||||
|
(rgb_t){ .r = 255, .g = 0, .b = 255, },
|
||||||
|
};
|
||||||
|
|
||||||
int main (void) {
|
int main (void) {
|
||||||
PORTB = 0;
|
dio_t pin = (dio_t){ .ddr = &DDRB, .port = &PORTB, .pin = &PINB, .addr = 2 };
|
||||||
DDRB = _BV(0) | _BV(1) | _BV(2) | _BV(3);
|
dio_set_direction(&pin, LINE_OUT);
|
||||||
_delay_ms(50);
|
|
||||||
|
|
||||||
blink();
|
np_write_rgb(&pin, pixels, PIXEL_COUNT);
|
||||||
|
|
||||||
_delay_ms(500);
|
|
||||||
|
|
||||||
/*
|
|
||||||
while (1) {
|
|
||||||
blink();
|
|
||||||
write_pixels(pixels_1, PIXEL_COUNT * 4);
|
|
||||||
_delay_ms(1000);
|
|
||||||
write_pixels(pixels_2, PIXEL_COUNT * 4);
|
|
||||||
_delay_ms(1000);
|
|
||||||
write_pixels(pixels_3, PIXEL_COUNT * 4);
|
|
||||||
_delay_ms(1000);
|
|
||||||
write_pixels(pixels_4, PIXEL_COUNT * 4);
|
|
||||||
_delay_ms(1000);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t pixels[7 * 3];
|
|
||||||
for (uint8_t i = 0; i < 7 * 3; i++) {
|
|
||||||
pixels[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t r_step = 1;
|
|
||||||
int8_t g_step = 0;
|
|
||||||
int8_t b_step = 0;
|
|
||||||
while (1) {
|
|
||||||
pixels[0] += r_step;
|
|
||||||
pixels[3] += r_step;
|
|
||||||
pixels[6] += r_step;
|
|
||||||
pixels[9] += r_step;
|
|
||||||
pixels[12] += r_step;
|
|
||||||
pixels[15] += r_step;
|
|
||||||
pixels[18] += r_step;
|
|
||||||
// pixels[1] += g_step;
|
|
||||||
// pixels[2] += b_step;
|
|
||||||
write_pixels(pixels, 7 * 3);
|
|
||||||
if (pixels[0] == 255) {
|
|
||||||
r_step = -1;
|
|
||||||
} else if (pixels[0] == 0) {
|
|
||||||
r_step = 1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (pixels[0] == 255) {
|
|
||||||
r_step = -1;
|
|
||||||
g_step = 1;
|
|
||||||
} else if (pixels[0] == 0 && r_step == -1) {
|
|
||||||
r_step = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (pixels[1] == 255) {
|
|
||||||
g_step = -1;
|
|
||||||
b_step = 1;
|
|
||||||
} else if (pixels[1] == 0 && g_step == -1) {
|
|
||||||
g_step = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixels[2] == 255) {
|
|
||||||
b_step = -1;
|
|
||||||
r_step = 1;
|
|
||||||
} else if (pixels[2] == 0 && b_step == -1) {
|
|
||||||
b_step = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
_delay_ms(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
#include <avr/io.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "ws2812.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
void latch(io_pin_t *addr) {
|
|
||||||
if (addr->bit >= 8) return;
|
|
||||||
*(addr->port) &= ~(1<<0);
|
|
||||||
_delay_us(50);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define T0_HIGH 4
|
|
||||||
#define T1_HIGH 7
|
|
||||||
#define T_FRAME 11
|
|
||||||
|
|
||||||
#define write_bit(label, bit) \
|
|
||||||
"out %[port], %[hi]" "\n\t" \
|
|
||||||
"nop" "\n\t" \
|
|
||||||
"sbrc %[byte], " #bit "\n\t" \
|
|
||||||
"rjmp .+0" "\n\t" \
|
|
||||||
"out %[port], %[low]" "\n\t" \
|
|
||||||
"rjmp .+0" "\n\t" \
|
|
||||||
"rjmp .+0" "\n\t" \
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define write_bit(label, bit) \
|
|
||||||
"bst %[byte], " #bit "\n\t" \
|
|
||||||
"out %[port], %[hi]" "\n\t" \
|
|
||||||
"nop" "\n\t" \
|
|
||||||
"brtc " label "\n\t" \
|
|
||||||
"rjmp .+0" "\n\t" \
|
|
||||||
label ": " "out %[port], %[low]" "\n\t" \
|
|
||||||
"rjmp .+0" "\n\t" \
|
|
||||||
"rjmp .+0" "\n\t"
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
inline void write_byte(volatile uint8_t *port, uint8_t hi, uint8_t low, uint8_t byte) {
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
write_bit("A_%=", 7)
|
|
||||||
write_bit("B_%=", 6)
|
|
||||||
write_bit("C_%=", 5)
|
|
||||||
write_bit("D_%=", 4)
|
|
||||||
write_bit("E_%=", 3)
|
|
||||||
write_bit("F_%=", 2)
|
|
||||||
write_bit("G_%=", 1)
|
|
||||||
write_bit("H_%=", 0)
|
|
||||||
: /* No outputs */
|
|
||||||
: [port] "I" (_SFR_IO_ADDR(PORTB)),
|
|
||||||
[hi] "r" (hi),
|
|
||||||
[low] "r" (low),
|
|
||||||
[byte] "r" (byte)
|
|
||||||
);
|
|
||||||
|
|
||||||
// __asm__ __volatile__ (
|
|
||||||
/*
|
|
||||||
"ldi r24, 8" "\n\t" // count out eight bits. One higher than normal because I do the final check *after* the counter decrements. I'm effectively 1-based
|
|
||||||
"lsl %[byte]" "\n\t" // output data left, saving the msb in SREG (1 cycle)
|
|
||||||
"bst sreg, 0" "\n\t" // Save hte carry flag to the transfer bit
|
|
||||||
"L_%=: " "out %[port], %[hi]" "\n\t" // enable the port
|
|
||||||
"brtc I_%=" "\n\t" // If we shifted out a 0, if SREG[C] is clear, immediately branch I_%= (2 cycles if true, 1 cycle if false)
|
|
||||||
"nop" "\n\t" // We shifted out a 1, so wait just a touch longer
|
|
||||||
"nop" "\n\t"
|
|
||||||
"nop" "\n\t"
|
|
||||||
"I_%=: " "out %[port], %[low]" "\n\t" // now clear the pin
|
|
||||||
// I now have five ticks before I can re-enable the pin
|
|
||||||
"lsl %[byte]" "\n\t" // Shift out the next bit
|
|
||||||
"bst sreg, 0" "\n\t"
|
|
||||||
"dec r24" "\n\t" // Decrement the bit counter
|
|
||||||
"cpi r24, 0" "\n\t" // Is the bit counter 0?
|
|
||||||
"brne L_%=" "\n\t" // If we haven't reached 0, we have more data to send
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_pixels(const uint8_t *pixels, uint8_t length) {
|
|
||||||
uint8_t hi = PORTB | (1 << 3);
|
|
||||||
uint8_t low = PORTB & ~(1 << 3);
|
|
||||||
cli();
|
|
||||||
for (int idx = 0; idx < length; idx++) {
|
|
||||||
write_byte(&PORTB, hi, low, pixels[idx]);
|
|
||||||
}
|
|
||||||
_delay_us(100);
|
|
||||||
sei();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#include "np_common.c"
|
|
||||||
|
|
||||||
void np_write_rgb(io_pin_t *addr, rgb_t *values, uint8_t length) {
|
|
||||||
write_pixels(addr, values, length * 3);
|
|
||||||
}
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
# include "ws2812.h"
|
||||||
|
|
||||||
|
// inline void write_zero(dio_t *pin, uint8_t hi, uint8_t low) {
|
||||||
|
// uint8_t *val;
|
||||||
|
// uint8_t *hi_reg;
|
||||||
|
// uint8_t *low_reg;
|
||||||
|
// __asm__ __volatile__ (
|
||||||
|
// "ldd %[hi_reg], %[hi]\n"
|
||||||
|
// "ldd %[low_reg], %[low]\n"
|
||||||
|
// "ldd %[val], %[pin]\n"
|
||||||
|
// "or %[val], %[hi_reg]\n"
|
||||||
|
// "std %[pin], %[val]\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "and %[val], %[hi_reg]\n"
|
||||||
|
// "std %[pin], %[val]\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "nop\n"
|
||||||
|
// /* Need another 5 cycles */
|
||||||
|
// : [val] "=r" (val), [hi_reg] "=r" (hi_reg), [low_reg] "=r" (low_reg)
|
||||||
|
// : [pin] "m" (pin->port), [hi] "m" (hi), [low] "m" (low)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// inline void write_one(dio_t *port, uint8_t hi, uint8_t low) {
|
||||||
|
// __asm__ __volatile__ (
|
||||||
|
// "or %0, %1\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "nop\n"
|
||||||
|
// "and %0, %1\n"
|
||||||
|
// /* Need another 5 cycles */
|
||||||
|
// : /* no outputs */
|
||||||
|
// : "m" (port->port),
|
||||||
|
// "m" (hi),
|
||||||
|
// "m" (low)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
inline void write_byte(dio_t *pin, uint8_t hi, uint8_t low, const uint8_t value) {
|
||||||
|
uint8_t *state_r;
|
||||||
|
uint8_t *hi_r;
|
||||||
|
uint8_t *low_r;
|
||||||
|
uint8_t *counter;
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"ldi r16, 8\n"
|
||||||
|
"ldi r17, %[value]\n"
|
||||||
|
"ldd %[hi_r], %[hi]\n"
|
||||||
|
"ldd %[low_r], %[low]\n"
|
||||||
|
"ldd %[state_r], %[pin]\n"
|
||||||
|
|
||||||
|
"L_%=: " "lsl __tmp_reg__\n"
|
||||||
|
"brbs I_%=\n"
|
||||||
|
"or %[state_r], %[hi_r]\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"and %[state_r], %[low_r]\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"rjmp J_%=\n"
|
||||||
|
|
||||||
|
"I_%=: "
|
||||||
|
"brbs I_%=\n"
|
||||||
|
"or %[state_r], %[hi_r]\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"nop\n"
|
||||||
|
"and %[state_r], %[low_r]\n"
|
||||||
|
|
||||||
|
"J_%=: " "dec %[counter]\n"
|
||||||
|
"cpi %[counter], 0\n"
|
||||||
|
"brne L_%="
|
||||||
|
|
||||||
|
: [state_r] "=r" (state_r),
|
||||||
|
[hi_r] "=r" (hi_r),
|
||||||
|
[low_r] "=r" (low_r),
|
||||||
|
[counter] "=r" (counter)
|
||||||
|
|
||||||
|
: [pin] "m" (pin->port),
|
||||||
|
[hi] "m" (hi),
|
||||||
|
[low] "m" (low),
|
||||||
|
[value] "m" (value)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void np_write_rgb(dio_t *pin, const rgb_t *pixels, uint8_t length) {
|
||||||
|
cli();
|
||||||
|
uint8_t hi = 1 << pin->addr;
|
||||||
|
uint8_t low = ~hi;
|
||||||
|
for (int idx = 0; idx < length; idx++) {
|
||||||
|
write_byte(pin, hi, low, pixels[idx].r);
|
||||||
|
write_byte(pin, hi, low, pixels[idx].g);
|
||||||
|
write_byte(pin, hi, low, pixels[idx].b);
|
||||||
|
}
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define __neopixels_h__
|
#define __neopixels_h__
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <base.h>
|
#include <dio.h>
|
||||||
|
|
||||||
typedef struct RGB_s {
|
typedef struct RGB_s {
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
|
@ -18,8 +18,7 @@ typedef struct RGBW_s {
|
||||||
} rgbw_t;
|
} rgbw_t;
|
||||||
|
|
||||||
// void np_initialize();
|
// void np_initialize();
|
||||||
// void np_write_rgb(io_pin_t *addr, rgb_t *values, uint8_t length);
|
void np_write_rgb(dio_t *, const rgb_t *, uint8_t);
|
||||||
void write_pixels(const uint8_t *pixels, uint8_t length);
|
|
||||||
// void np_write_grb(io_pin_t *addr, rgb_t *values, uint8_t length);
|
// void np_write_grb(io_pin_t *addr, rgb_t *values, uint8_t length);
|
||||||
// void np_write_rgbw(io_pin_t *addr, rgbw_t *values, uint8_t length);
|
// void np_write_rgbw(io_pin_t *addr, rgbw_t *values, uint8_t length);
|
||||||
// void np_write_grbw(io_pin_t *addr, rgbw_t *values, uint8_t length);
|
// void np_write_grbw(io_pin_t *addr, rgbw_t *values, uint8_t length);
|
||||||
|
|
Loading…
Reference in New Issue