diff --git a/devices/apa102/apa102.go b/devices/apa102/apa102.go index 2771721..54bc70a 100644 --- a/devices/apa102/apa102.go +++ b/devices/apa102/apa102.go @@ -11,6 +11,7 @@ import ( "image/color" "periph.io/x/periph/conn" + "periph.io/x/periph/conn/physic" "periph.io/x/periph/conn/spi" "periph.io/x/periph/devices" ) @@ -58,7 +59,7 @@ type Opts struct { // https://en.wikipedia.org/wiki/Flicker_fusion_threshold is a recommended // reading. func New(p spi.Port, o *Opts) (*Dev, error) { - c, err := p.Connect(20000000, spi.Mode3, 8) + c, err := p.Connect(20*physic.MegaHertz, spi.Mode3, 8) if err != nil { return nil, err } diff --git a/devices/apa102/apa102_test.go b/devices/apa102/apa102_test.go index 19cdd8b..9b79c49 100644 --- a/devices/apa102/apa102_test.go +++ b/devices/apa102/apa102_test.go @@ -14,6 +14,7 @@ import ( "testing" "periph.io/x/periph/conn/conntest" + "periph.io/x/periph/conn/physic" "periph.io/x/periph/conn/spi" "periph.io/x/periph/conn/spi/spitest" ) @@ -755,7 +756,7 @@ type configFail struct { spitest.Record } -func (c *configFail) Connect(maxHz int64, mode spi.Mode, bits int) (spi.Conn, error) { +func (c *configFail) Connect(f physic.Frequency, mode spi.Mode, bits int) (spi.Conn, error) { return nil, errors.New("injected error") } diff --git a/devices/bmxx80/bmx280_test.go b/devices/bmxx80/bmx280_test.go index b7ca131..63e2752 100644 --- a/devices/bmxx80/bmx280_test.go +++ b/devices/bmxx80/bmx280_test.go @@ -1024,6 +1024,6 @@ type spiFail struct { spitest.Playback } -func (s *spiFail) Connect(maxHz int64, mode spi.Mode, bits int) (spi.Conn, error) { +func (s *spiFail) Connect(f physic.Frequency, mode spi.Mode, bits int) (spi.Conn, error) { return nil, errors.New("failing") } diff --git a/devices/bmxx80/bmxx80.go b/devices/bmxx80/bmxx80.go index eaf1031..0e04587 100644 --- a/devices/bmxx80/bmxx80.go +++ b/devices/bmxx80/bmxx80.go @@ -214,7 +214,7 @@ func NewI2C(b i2c.Bus, addr uint16, opts *Opts) (*Dev, error) { // When using SPI, the CS line must be used. func NewSPI(p spi.Port, opts *Opts) (*Dev, error) { // It works both in Mode0 and Mode3. - c, err := p.Connect(10000000, spi.Mode3, 8) + c, err := p.Connect(10*physic.MegaHertz, spi.Mode3, 8) if err != nil { return nil, fmt.Errorf("bmxx80: %v", err) } diff --git a/devices/lepton/lepton.go b/devices/lepton/lepton.go index 35b6abf..daa4be8 100644 --- a/devices/lepton/lepton.go +++ b/devices/lepton/lepton.go @@ -74,7 +74,7 @@ type Frame struct { func New(p spi.Port, i i2c.Bus) (*Dev, error) { // TODO(maruel): Switch to 16 bits per word, so that big endian 16 bits word // decoding is done by the SPI driver. - s, err := p.Connect(20000000, spi.Mode3, 8) + s, err := p.Connect(20*physic.MegaHertz, spi.Mode3, 8) if err != nil { return nil, err } diff --git a/devices/lepton/lepton_test.go b/devices/lepton/lepton_test.go index 7cf4b86..4c4b50c 100644 --- a/devices/lepton/lepton_test.go +++ b/devices/lepton/lepton_test.go @@ -392,9 +392,9 @@ func (s *spiStream) String() string { return "spi" } -func (s *spiStream) Connect(maxHz int64, mode spi.Mode, bits int) (spi.Conn, error) { - if maxHz != 20000000 { - s.t.Fatal(maxHz) +func (s *spiStream) Connect(f physic.Frequency, mode spi.Mode, bits int) (spi.Conn, error) { + if f != 20*physic.MegaHertz { + s.t.Fatal(f) } if mode != spi.Mode3 { s.t.Fatal(mode) diff --git a/devices/ssd1306/ssd1306.go b/devices/ssd1306/ssd1306.go index cfc3167..d7ba8da 100644 --- a/devices/ssd1306/ssd1306.go +++ b/devices/ssd1306/ssd1306.go @@ -45,6 +45,7 @@ import ( "periph.io/x/periph/conn" "periph.io/x/periph/conn/gpio" "periph.io/x/periph/conn/i2c" + "periph.io/x/periph/conn/physic" "periph.io/x/periph/conn/spi" "periph.io/x/periph/devices" "periph.io/x/periph/devices/ssd1306/image1bit" @@ -119,7 +120,7 @@ func NewSPI(p spi.Port, dc gpio.PinOut, opts *Opts) (*Dev, error) { } else if err := dc.Out(gpio.Low); err != nil { return nil, err } - c, err := p.Connect(3300000, spi.Mode0, bits) + c, err := p.Connect(3300*physic.KiloHertz, spi.Mode0, bits) if err != nil { return nil, err } diff --git a/devices/ssd1306/ssd1306_test.go b/devices/ssd1306/ssd1306_test.go index dbdc2db..52f061c 100644 --- a/devices/ssd1306/ssd1306_test.go +++ b/devices/ssd1306/ssd1306_test.go @@ -14,6 +14,7 @@ import ( "periph.io/x/periph/conn/gpio" "periph.io/x/periph/conn/gpio/gpiotest" "periph.io/x/periph/conn/i2c/i2ctest" + "periph.io/x/periph/conn/physic" "periph.io/x/periph/conn/spi" "periph.io/x/periph/conn/spi/spitest" "periph.io/x/periph/devices/ssd1306/image1bit" @@ -540,7 +541,7 @@ type configFail struct { spitest.Record } -func (c *configFail) Connect(maxHz int64, mode spi.Mode, bits int) (spi.Conn, error) { +func (c *configFail) Connect(f physic.Frequency, mode spi.Mode, bits int) (spi.Conn, error) { return nil, errors.New("injected error") } diff --git a/experimental/devices/bitbang/i2c.go b/experimental/devices/bitbang/i2c.go index 0a2a8ea..84629a1 100644 --- a/experimental/devices/bitbang/i2c.go +++ b/experimental/devices/bitbang/i2c.go @@ -17,6 +17,7 @@ import ( "periph.io/x/periph/conn/gpio" "periph.io/x/periph/conn/i2c" + "periph.io/x/periph/conn/physic" "periph.io/x/periph/host/cpu" ) @@ -122,10 +123,10 @@ func (i *I2C) Tx(addr uint16, w, r []byte) error { } // SetSpeed implements i2c.Bus. -func (i *I2C) SetSpeed(hz int64) error { +func (i *I2C) SetSpeed(f physic.Frequency) error { i.mu.Lock() defer i.mu.Unlock() - i.halfCycle = time.Second / time.Duration(hz) / time.Duration(2) + i.halfCycle = f.Duration() / 2 return nil } diff --git a/experimental/devices/bitbang/spi.go b/experimental/devices/bitbang/spi.go index 35d88b4..90b21b7 100644 --- a/experimental/devices/bitbang/spi.go +++ b/experimental/devices/bitbang/spi.go @@ -19,6 +19,7 @@ import ( "periph.io/x/periph/conn" "periph.io/x/periph/conn/gpio" + "periph.io/x/periph/conn/physic" "periph.io/x/periph/conn/spi" "periph.io/x/periph/host/cpu" ) @@ -66,8 +67,8 @@ type SPI struct { csn gpio.PinOut // CS mu sync.Mutex - maxHzPort int64 - maxHzDev int64 + freqPort physic.Frequency + freqDev physic.Frequency mode spi.Mode bits int halfCycle time.Duration @@ -89,32 +90,32 @@ func (s *SPI) Duplex() conn.Duplex { } // LimitSpeed implements spi.ConnCloser. -func (s *SPI) LimitSpeed(maxHz int64) error { - if maxHz <= 0 { - return errors.New("bitbang-spi: invalid maxHz") +func (s *SPI) LimitSpeed(f physic.Frequency) error { + if f <= 0 { + return errors.New("bitbang-spi: invalid frequency") } s.mu.Lock() defer s.mu.Unlock() - s.maxHzPort = maxHz - if s.maxHzDev == 0 || s.maxHzPort < s.maxHzDev { - s.halfCycle = time.Second / time.Duration(maxHz) / time.Duration(2) + s.freqPort = f + if s.freqDev == 0 || s.freqPort < s.freqDev { + s.halfCycle = f.Duration() / 2 } return nil } // Connect implements spi.Conn. -func (s *SPI) Connect(maxHz int64, mode spi.Mode, bits int) error { - if maxHz < 0 { - return errors.New("bitbang-spi: invalid maxHz") +func (s *SPI) Connect(f physic.Frequency, mode spi.Mode, bits int) error { + if f < 0 { + return errors.New("bitbang-spi: invalid frequency") } if mode != spi.Mode3 { return fmt.Errorf("bitbang-spi: mode %v is not implemented", mode) } s.mu.Lock() defer s.mu.Unlock() - s.maxHzDev = maxHz - if s.maxHzDev != 0 && (s.maxHzPort == 0 || s.maxHzDev < s.maxHzPort) { - s.halfCycle = time.Second / time.Duration(maxHz) / time.Duration(2) + s.freqDev = f + if s.freqDev != 0 && (s.freqPort == 0 || s.freqDev < s.freqPort) { + s.halfCycle = f.Duration() / 2 } s.mode = mode s.bits = bits diff --git a/experimental/devices/mfrc522/mfrc522.go b/experimental/devices/mfrc522/mfrc522.go index a5ff1c2..eb48838 100644 --- a/experimental/devices/mfrc522/mfrc522.go +++ b/experimental/devices/mfrc522/mfrc522.go @@ -15,6 +15,7 @@ import ( "periph.io/x/periph/conn" "periph.io/x/periph/conn/gpio" + "periph.io/x/periph/conn/physic" "periph.io/x/periph/conn/spi" "periph.io/x/periph/experimental/devices/mfrc522/commands" ) @@ -103,7 +104,7 @@ func NewSPI(spiPort spi.Port, resetPin gpio.PinOut, irqPin gpio.PinIn) (*Dev, er if irqPin == nil { return nil, wrapf("IRQ pin is not set") } - spiDev, err := spiPort.Connect(10000000, spi.Mode0, 8) + spiDev, err := spiPort.Connect(10*physic.MegaHertz, spi.Mode0, 8) if err != nil { return nil, err } diff --git a/experimental/devices/nrzled/nrzled.go b/experimental/devices/nrzled/nrzled.go index da7ec06..0bd9ecb 100644 --- a/experimental/devices/nrzled/nrzled.go +++ b/experimental/devices/nrzled/nrzled.go @@ -9,10 +9,10 @@ import ( "fmt" "image" "image/color" - "time" "periph.io/x/periph/conn" "periph.io/x/periph/conn/gpio/gpiostream" + "periph.io/x/periph/conn/physic" "periph.io/x/periph/devices" ) @@ -43,14 +43,15 @@ func NRZ(b byte) uint32 { // New opens a handle to a compatible LED strip. // -// The speed (hz) should either be 800000 for fast ICs and 400000 for the slow -// ones. +// 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, hz int, channels int) (*Dev, error) { - if hz <= 0 || hz > 1000000000 { - return nil, errors.New("nrzled: specify valid speed in hz") +func New(p gpiostream.PinOut, numPixels int, f physic.Frequency, channels int) (*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 { + return nil, errors.New("nrzled: specify valid frequency") } if channels != 3 && channels != 4 { return nil, errors.New("nrzled: specify valid number of channels (3 or 4)") @@ -60,7 +61,7 @@ func New(p gpiostream.PinOut, numPixels, hz int, channels int) (*Dev, error) { numPixels: numPixels, channels: channels, b: gpiostream.BitStream{ - Res: time.Second / time.Duration(hz), + Res: f.Duration(), // Each bit is encoded on 3 bits. Bits: make([]byte, numPixels*3*channels), LSBF: false, diff --git a/experimental/devices/nrzled/nrzled_test.go b/experimental/devices/nrzled/nrzled_test.go index 04cf5b3..44643ba 100644 --- a/experimental/devices/nrzled/nrzled_test.go +++ b/experimental/devices/nrzled/nrzled_test.go @@ -14,6 +14,7 @@ import ( "periph.io/x/periph/conn/gpio/gpiostream" "periph.io/x/periph/conn/gpio/gpiostream/gpiostreamtest" + "periph.io/x/periph/conn/physic" ) func TestNRZ(t *testing.T) { @@ -61,7 +62,7 @@ func TestNew_3(t *testing.T) { }, }, } - d, err := New(&g, 10, 400000, 3) + d, err := New(&g, 10, 400*physic.KiloHertz, 3) if err != nil { t.Fatal(err) } @@ -87,7 +88,7 @@ func TestNew_fail(t *testing.T) { if _, err := New(&g, 1, 0, 3); err == nil { t.Fatal("hz == 0") } - if _, err := New(&g, 1, 400000, 2); err == nil { + if _, err := New(&g, 1, 400*physic.KiloHertz, 2); err == nil { t.Fatal("channels == 2") } } @@ -109,7 +110,7 @@ func TestDraw_NRGBA_3(t *testing.T) { }, }, } - d, _ := New(&g, 10, 400000, 3) + d, _ := New(&g, 10, 400*physic.KiloHertz, 3) img := image.NewNRGBA(d.Bounds()) copy(img.Pix, getRGBW()) d.Draw(d.Bounds(), img, image.Point{}) @@ -135,7 +136,7 @@ func TestDraw_RGBA_3(t *testing.T) { }, }, } - d, _ := New(&g, 10, 400000, 3) + d, _ := New(&g, 10, 400*physic.KiloHertz, 3) img := image.NewRGBA(d.Bounds()) copy(img.Pix, getRGBW()) d.Draw(d.Bounds(), img, image.Point{}) @@ -163,7 +164,7 @@ func TestDraw_RGBA_4(t *testing.T) { }, }, } - d, _ := New(&g, 10, 400000, 4) + d, _ := New(&g, 10, 400*physic.KiloHertz, 4) img := image.NewRGBA(d.Bounds()) copy(img.Pix, getRGBW()) d.Draw(d.Bounds(), img, image.Point{}) @@ -189,7 +190,7 @@ func TestDraw_Limits(t *testing.T) { }, }, } - d, _ := New(&g, 10, 400000, 3) + d, _ := New(&g, 10, 400*physic.KiloHertz, 3) img := image.NewRGBA(image.Rect(-1, -1, 20, 20)) copy(img.Pix, getRGBW()) d.Draw(d.Bounds(), img, image.Point{}) @@ -215,7 +216,7 @@ func TestWrite_3(t *testing.T) { }, }, } - d, _ := New(&g, 10, 400000, 3) + d, _ := New(&g, 10, 400*physic.KiloHertz, 3) if n, err := d.Write(getRGB()); n != 30 || err != nil { t.Fatal(n, err) } @@ -226,7 +227,7 @@ func TestWrite_3(t *testing.T) { func TestWrite_fail(t *testing.T) { g := gpiostreamtest.PinOutPlayback{DontPanic: true} - d, _ := New(&g, 10, 400000, 3) + d, _ := New(&g, 10, 400*physic.KiloHertz, 3) if n, err := d.Write([]byte{1}); n != 0 || err == nil { t.Fatal(n, err) } @@ -240,7 +241,7 @@ func TestWrite_fail(t *testing.T) { func TestHalt_fail(t *testing.T) { g := gpiostreamtest.PinOutPlayback{DontPanic: true} - d, _ := New(&g, 10, 400000, 3) + d, _ := New(&g, 10, 400*physic.KiloHertz, 3) if d.Halt() == nil { t.Fatal("expected failure") }