spi: Update spi.Conn to separate app and device configuration. (#123)

- Allow both app and device drive set max bus speed.
- Make DevParams callable only exactly once.
- sysfs-spi: make SPI implement io.Reader.
- sysfs-spi: Fix Tx() with write only or read only.
pull/1/head
M-A 9 years ago committed by GitHub
parent fd7cbfd4bf
commit 7faec2c2d3

@ -283,7 +283,7 @@ func (d *Dev) Write(pixels []byte) (int, error) {
// https://en.wikipedia.org/wiki/Flicker_fusion_threshold is a recommended // https://en.wikipedia.org/wiki/Flicker_fusion_threshold is a recommended
// reading. // reading.
func New(s spi.Conn, numLights int, intensity uint8, temperature uint16) (*Dev, error) { func New(s spi.Conn, numLights int, intensity uint8, temperature uint16) (*Dev, error) {
if err := s.Configure(spi.Mode3, 8); err != nil { if err := s.DevParams(20000000, spi.Mode3, 8); err != nil {
return nil, err return nil, err
} }
// End frames are needed to be able to push enough SPI clock signals due to // End frames are needed to be able to push enough SPI clock signals due to

@ -336,9 +336,9 @@ func TestDevEmpty(t *testing.T) {
} }
} }
func TestConfigureFail(t *testing.T) { func TestDevParamsFail(t *testing.T) {
if d, err := New(&configFail{}, 150, 255, 6500); d != nil || err == nil { if d, err := New(&configFail{}, 150, 255, 6500); d != nil || err == nil {
t.Fatal("Configure() call have failed") t.Fatal("DevParams() call have failed")
} }
} }
@ -682,7 +682,7 @@ type configFail struct {
spitest.Record spitest.Record
} }
func (c *configFail) Configure(mode spi.Mode, bits int) error { func (c *configFail) DevParams(maxHz int64, mode spi.Mode, bits int) error {
return errors.New("injected error") return errors.New("injected error")
} }

@ -6,7 +6,7 @@
// //
// Datasheet // Datasheet
// //
// https://cdn-shop.adafruit.com/datasheets/BST-BME280_DS001-10.pdf // https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-11.pdf
package bme280 package bme280
import ( import (
@ -172,7 +172,7 @@ func NewI2C(b i2c.Bus, opts *Opts) (*Dev, error) {
// device in the mail. // device in the mail.
func NewSPI(s spi.Conn, opts *Opts) (*Dev, error) { func NewSPI(s spi.Conn, opts *Opts) (*Dev, error) {
// It works both in Mode0 and Mode3. // It works both in Mode0 and Mode3.
if err := s.Configure(spi.Mode3, 8); err != nil { if err := s.DevParams(10000000, spi.Mode3, 8); err != nil {
return nil, err return nil, err
} }
d := &Dev{d: s, isSPI: true} d := &Dev{d: s, isSPI: true}

@ -89,9 +89,8 @@ type Dev struct {
// connection is to connect RES and DC to ground, CS to 3.3v, SDA to MOSI, SCK // connection is to connect RES and DC to ground, CS to 3.3v, SDA to MOSI, SCK
// to SCLK. // to SCLK.
// //
// As per datasheet, maximum clock speed is 1/100ns = 10MHz.
func NewSPI(s spi.Conn, w, h int, rotated bool) (*Dev, error) { func NewSPI(s spi.Conn, w, h int, rotated bool) (*Dev, error) {
if err := s.Configure(spi.Mode3, 8); err != nil { if err := s.DevParams(3300000, spi.Mode3, 8); err != nil {
return nil, err return nil, err
} }
return newDev(s, w, h, rotated) return newDev(s, w, h, rotated)
@ -101,10 +100,8 @@ func NewSPI(s spi.Conn, w, h int, rotated bool) (*Dev, error) {
// controler. // controler.
// //
// If rotated, turns the display by 180° // If rotated, turns the display by 180°
//
// As per datasheet, maximum clock speed is 1/2.5µs = 400KHz. It's worth
// bumping up from default bus speed of 100KHz if possible.
func NewI2C(i i2c.Bus, w, h int, rotated bool) (*Dev, error) { func NewI2C(i i2c.Bus, w, h int, rotated bool) (*Dev, error) {
// Maximum clock speed is 1/2.5µs = 400KHz.
return newDev(&i2c.Dev{Bus: i, Addr: 0x3C}, w, h, rotated) return newDev(&i2c.Dev{Bus: i, Addr: 0x3C}, w, h, rotated)
} }

@ -31,6 +31,8 @@ type SPI struct {
csn gpio.PinOut // CS csn gpio.PinOut // CS
mu sync.Mutex mu sync.Mutex
maxHzBus int64
maxHzDev int64
mode spi.Mode mode spi.Mode
bits int bits int
halfCycle time.Duration halfCycle time.Duration
@ -51,21 +53,34 @@ func (s *SPI) Duplex() conn.Duplex {
return conn.Full return conn.Full
} }
// Speed implements spi.Conn. // Speed implements spi.ConnCloser.
func (s *SPI) Speed(hz int64) error { func (s *SPI) Speed(maxHz int64) error {
if maxHz <= 0 {
return errors.New("bitbang-spi: invalid maxHz")
}
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
s.halfCycle = time.Second / time.Duration(hz) / time.Duration(2) s.maxHzBus = maxHz
if s.maxHzDev == 0 || s.maxHzBus < s.maxHzDev {
s.halfCycle = time.Second / time.Duration(maxHz) / time.Duration(2)
}
return nil return nil
} }
// Configure implements spi.Conn. // DevParams implements spi.Conn.
func (s *SPI) Configure(mode spi.Mode, bits int) error { func (s *SPI) DevParams(maxHz int64, mode spi.Mode, bits int) error {
s.mu.Lock() if maxHz < 0 {
defer s.mu.Unlock() return errors.New("bitbang-spi: invalid maxHz")
}
if mode != spi.Mode3 { if mode != spi.Mode3 {
return errors.New("bitbang-spi: not implemented") return errors.New("bitbang-spi: not implemented")
} }
s.mu.Lock()
defer s.mu.Unlock()
s.maxHzDev = maxHz
if s.maxHzDev != 0 && (s.maxHzBus == 0 || s.maxHzDev < s.maxHzBus) {
s.halfCycle = time.Second / time.Duration(maxHz) / time.Duration(2)
}
s.mode = mode s.mode = mode
s.bits = bits s.bits = bits
return nil return nil

Loading…
Cancel
Save