nrzled: change to Opts pattern

This makes it coherent with other drivers.
pull/1/head
Marc-Antoine Ruel 8 years ago
parent 8fa8a276a6
commit 0a22d3193e

@ -41,29 +41,45 @@ func NRZ(b byte) uint32 {
return out
}
// DefaultOpts is the recommended default options.
var DefaultOpts = Opts{
NumPixels: 150, // 150 LEDs is a common strip length.
Channels: 3, // RGB.
Freq: 800 * physic.KiloHertz, // Fast LEDs, most common.
}
// Opts defines the options for the device.
type Opts struct {
// NumPixels is the number of pixels to control. If too short, the following
// pixels will be corrupted. If too long, the pixels will be drawn
// unnecessarily but not visible issue will occur.
NumPixels int
// Channels is 1 for single color LEDs, 3 for RGB LEDs and 4 for RGBW (white)
// LEDs.
Channels int
// Freq is the frequency to use to drive the LEDs. It should be either 800kHz
// for fast ICs and 400kHz for the slow ones.
Freq physic.Frequency
}
// New opens a handle to a compatible LED strip.
//
// f should either be 800kHz for fast ICs and 400kHz for the slow ones.
//
// channels should be either 1 (White only), 3 (RGB) or 4 (RGBW). For RGB and
// RGBW, the encoding is respectively GRB and GRBW.
func New(p gpiostream.PinOut, numPixels int, f physic.Frequency, channels int) (*Dev, error) {
func New(p gpiostream.PinOut, opts *Opts) (*Dev, error) {
// Allow a wider range in case there's new devices with higher supported
// frequency.
if f < 10*physic.KiloHertz || f > 100*physic.MegaHertz {
if opts.Freq < 10*physic.KiloHertz || opts.Freq > 100*physic.MegaHertz {
return nil, errors.New("nrzled: specify valid frequency")
}
if channels != 3 && channels != 4 {
if opts.Channels != 3 && opts.Channels != 4 {
return nil, errors.New("nrzled: specify valid number of channels (3 or 4)")
}
return &Dev{
p: p,
numPixels: numPixels,
channels: channels,
numPixels: opts.NumPixels,
channels: opts.Channels,
b: gpiostream.BitStream{
Freq: f,
Freq: opts.Freq,
// Each bit is encoded on 3 bits.
Bits: make([]byte, numPixels*3*channels),
Bits: make([]byte, opts.NumPixels*3*opts.Channels),
LSBF: false,
},
}, nil

@ -56,12 +56,14 @@ func TestNew_3(t *testing.T) {
0x49, 0x24, 0x92, 0x49, 0x24, 0x92, 0x49, 0x24, 0x92, 0x49, 0x24, 0x92, 0x49, 0x24, 0x92, 0x49,
0x24, 0x92, 0x49, 0x24, 0x92, 0x49, 0x24, 0x92, 0x49, 0x24,
},
Freq: 400 * physic.KiloHertz,
Freq: 800 * physic.KiloHertz,
LSBF: false,
},
},
}
d, err := New(&g, 10, 400*physic.KiloHertz, 3)
opts := DefaultOpts
opts.NumPixels = 10
d, err := New(&g, &opts)
if err != nil {
t.Fatal(err)
}
@ -84,10 +86,14 @@ func TestNew_3(t *testing.T) {
func TestNew_fail(t *testing.T) {
g := gpiostreamtest.PinOutPlayback{}
if _, err := New(&g, 1, 0, 3); err == nil {
opts := DefaultOpts
opts.Freq = 0
if _, err := New(&g, &opts); err == nil {
t.Fatal("hz == 0")
}
if _, err := New(&g, 1, 400*physic.KiloHertz, 2); err == nil {
opts = DefaultOpts
opts.Channels = 2
if _, err := New(&g, &opts); err == nil {
t.Fatal("channels == 2")
}
}
@ -104,12 +110,14 @@ func TestDraw_NRGBA_3(t *testing.T) {
0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d,
0xb6, 0x92, 0x49, 0xb6, 0x92, 0x49, 0xb4, 0x92, 0x4d, 0x24,
},
Freq: 400 * physic.KiloHertz,
Freq: 800 * physic.KiloHertz,
LSBF: false,
},
},
}
d, _ := New(&g, 10, 400*physic.KiloHertz, 3)
opts := DefaultOpts
opts.NumPixels = 10
d, _ := New(&g, &opts)
img := image.NewNRGBA(d.Bounds())
copy(img.Pix, getRGBW())
d.Draw(d.Bounds(), img, image.Point{})
@ -130,12 +138,14 @@ func TestDraw_RGBA_3(t *testing.T) {
0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xa6, 0xdb, 0x6d, 0xa6, 0xdb, 0x6d,
0xa6, 0xda, 0x49, 0xb6, 0xd3, 0x4d, 0x34, 0xdb, 0x49, 0x36,
},
Freq: 400 * physic.KiloHertz,
Freq: 800 * physic.KiloHertz,
LSBF: false,
},
},
}
d, _ := New(&g, 10, 400*physic.KiloHertz, 3)
opts := DefaultOpts
opts.NumPixels = 10
d, _ := New(&g, &opts)
img := image.NewRGBA(d.Bounds())
copy(img.Pix, getRGBW())
d.Draw(d.Bounds(), img, image.Point{})
@ -158,12 +168,15 @@ func TestDraw_RGBA_4(t *testing.T) {
0xdb, 0x6d, 0xa6, 0xdb, 0x6d, 0xa6, 0xdb, 0x6d, 0xa6, 0xd2, 0x49, 0x24, 0xda, 0x49, 0xb6, 0xd3,
0x4d, 0x34, 0xdb, 0x49, 0x36, 0x92, 0x4d, 0x26,
},
Freq: 400 * physic.KiloHertz,
Freq: 800 * physic.KiloHertz,
LSBF: false,
},
},
}
d, _ := New(&g, 10, 400*physic.KiloHertz, 4)
opts := DefaultOpts
opts.NumPixels = 10
opts.Channels = 4
d, _ := New(&g, &opts)
img := image.NewRGBA(d.Bounds())
copy(img.Pix, getRGBW())
d.Draw(d.Bounds(), img, image.Point{})
@ -184,12 +197,14 @@ func TestDraw_Limits(t *testing.T) {
0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xa6, 0xdb, 0x6d, 0xa6, 0xdb, 0x6d,
0xa6, 0xda, 0x49, 0xb6, 0xd3, 0x4d, 0x34, 0xdb, 0x49, 0x36,
},
Freq: 400 * physic.KiloHertz,
Freq: 800 * physic.KiloHertz,
LSBF: false,
},
},
}
d, _ := New(&g, 10, 400*physic.KiloHertz, 3)
opts := DefaultOpts
opts.NumPixels = 10
d, _ := New(&g, &opts)
img := image.NewRGBA(image.Rect(-1, -1, 20, 20))
copy(img.Pix, getRGBW())
d.Draw(d.Bounds(), img, image.Point{})
@ -210,12 +225,14 @@ func TestWrite_3(t *testing.T) {
0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0x92, 0x49, 0xa4, 0x92, 0x49, 0x36, 0x92, 0x49,
0xa6, 0x92, 0x49, 0xb6, 0x92, 0x49, 0xb4, 0x92, 0x4d, 0x24,
},
Freq: 400 * physic.KiloHertz,
Freq: 800 * physic.KiloHertz,
LSBF: false,
},
},
}
d, _ := New(&g, 10, 400*physic.KiloHertz, 3)
opts := DefaultOpts
opts.NumPixels = 10
d, _ := New(&g, &opts)
if n, err := d.Write(getRGB()); n != 30 || err != nil {
t.Fatal(n, err)
}
@ -226,7 +243,9 @@ func TestWrite_3(t *testing.T) {
func TestWrite_fail(t *testing.T) {
g := gpiostreamtest.PinOutPlayback{DontPanic: true}
d, _ := New(&g, 10, 400*physic.KiloHertz, 3)
opts := DefaultOpts
opts.NumPixels = 10
d, _ := New(&g, &opts)
if n, err := d.Write([]byte{1}); n != 0 || err == nil {
t.Fatal(n, err)
}
@ -240,7 +259,9 @@ func TestWrite_fail(t *testing.T) {
func TestHalt_fail(t *testing.T) {
g := gpiostreamtest.PinOutPlayback{DontPanic: true}
d, _ := New(&g, 10, 400*physic.KiloHertz, 3)
opts := DefaultOpts
opts.NumPixels = 10
d, _ := New(&g, &opts)
if d.Halt() == nil {
t.Fatal("expected failure")
}

Loading…
Cancel
Save