Skip to content

Commit

Permalink
gpiostream: Add BitStream.LSBF
Browse files Browse the repository at this point in the history
Remove Bits.

Fixes google#189
  • Loading branch information
maruel committed May 27, 2018
1 parent ae21564 commit 25fcbaa
Show file tree
Hide file tree
Showing 18 changed files with 275 additions and 478 deletions.
39 changes: 24 additions & 15 deletions conn/gpio/gpiostream/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ import (
"periph.io/x/periph/host"
)

func ExampleBitsLSB() {
// Format is LSB; least significant bit first.
stream := gpiostream.Bits{0x80, 0x01, 0xAA, 0x55}
for _, l := range stream {
func ExampleBitStream() {
fmt.Printf("Format is LSB-first; least significant bit first:\n")
stream := gpiostream.BitStream{
Bits: []byte{0x80, 0x01, 0xAA, 0x55},
Res: time.Microsecond,
LSBF: true,
}
for _, l := range stream.Bits {
fmt.Printf("0x%02X: ", l)
for j := 0; j < 8; j++ {
mask := byte(1) << uint(j)
Expand All @@ -29,17 +33,15 @@ func ExampleBitsLSB() {
}
fmt.Printf("\n")
}
// Output:
// 0x80: Low, Low, Low, Low, Low, Low, Low, High,
// 0x01: High, Low, Low, Low, Low, Low, Low, Low,
// 0xAA: Low, High, Low, High, Low, High, Low, High,
// 0x55: High, Low, High, Low, High, Low, High, Low,
}
fmt.Printf("\n")

func ExampleBitsMSB() {
// Format is MSB; most significant bit first.
stream := gpiostream.Bits{0x80, 0x01, 0xAA, 0x55}
for _, l := range stream {
fmt.Printf("Format is MSB-first; most significant bit first:\n")
stream = gpiostream.BitStream{
Bits: []byte{0x80, 0x01, 0xAA, 0x55},
Res: time.Microsecond,
LSBF: false,
}
for _, l := range stream.Bits {
fmt.Printf("0x%02X: ", l)
for j := 7; j >= 0; j-- {
mask := byte(1) << uint(j)
Expand All @@ -51,6 +53,13 @@ func ExampleBitsMSB() {
fmt.Printf("\n")
}
// Output:
// Format is LSB-first; least significant bit first:
// 0x80: Low, Low, Low, Low, Low, Low, Low, High,
// 0x01: High, Low, Low, Low, Low, Low, Low, Low,
// 0xAA: Low, High, Low, High, Low, High, Low, High,
// 0x55: High, Low, High, Low, High, Low, High, Low,
//
// Format is MSB-first; most significant bit first:
// 0x80: High, Low, Low, Low, Low, Low, Low, Low,
// 0x01: Low, Low, Low, Low, Low, Low, Low, High,
// 0xAA: High, Low, High, Low, High, Low, High, Low,
Expand All @@ -69,7 +78,7 @@ func ExamplePinIn() {
if !ok {
log.Fatalf("pin streaming is not supported on pin %s", p)
}
b := gpiostream.BitStream{Res: time.Millisecond, Bits: make(gpiostream.Bits, 1000/8)}
b := gpiostream.BitStream{Res: time.Millisecond, Bits: make([]byte, 1000/8)}
if err := r.StreamIn(gpio.PullNoChange, &b); err != nil {
log.Fatal(err)
}
Expand Down
100 changes: 19 additions & 81 deletions conn/gpio/gpiostream/gpiostream.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,86 +25,26 @@ type Stream interface {
Duration() time.Duration
}

// BitsLSB is a densely packed LSB-first bitstream.
//
// The format is LSB-first, the first bit processed is the least significant
// one (0x01).
//
// For example, Ethernet uses LSB-first at the byte level and MSB-first at the
// word level.
//
// The stream is required to be a multiple of 8 samples.
type BitsLSB []byte

// BitsMSB is a densely packed MSB-first bitstream.
//
// The format is MSB-first, the first bit processed is the most significant one
// (0x80).
//
// For example, I²C, I2S PCM and SPI use MSB-first at the word level. This
// requires to pack words correctly.
//
// The stream is required to be a multiple of 8 samples.
type BitsMSB []byte

// BitStreamLSB is a stream of BitsLSB to be written or read.
type BitStreamLSB struct {
Bits BitsLSB
// The duration each bit represents.
Res time.Duration
}

// Resolution implement Stream.
func (b *BitStreamLSB) Resolution() time.Duration {
if len(b.Bits) == 0 {
return 0
}
return b.Res
}

// Duration implement Stream.
func (b *BitStreamLSB) Duration() time.Duration {
return b.Res * time.Duration(len(b.Bits)*8)
}

// BitStreamMSB is a stream of Bits.MSB to be written or read.
type BitStreamMSB struct {
Bits BitsMSB
// The duration each bit represents.
Res time.Duration
}

// Resolution implement Stream.
func (b *BitStreamMSB) Resolution() time.Duration {
if len(b.Bits) == 0 {
return 0
}
return b.Res
}

// Duration implement Stream.
func (b *BitStreamMSB) Duration() time.Duration {
return b.Res * time.Duration(len(b.Bits)*8)
}

//

// Bits is a densely packed LSB-first bitstream.
//
// Warning
//
// This type will be removed in the next major version.
type Bits []byte

// BitStream is a stream of Bits to be written or read.
//
// Warning
//
// This struct will be removed in the next major version.
// BitStream is a stream of bits to be written or read.
type BitStream struct {
Bits Bits
// The duration each bit represents.
// Bits is a densely packed bitstream.
//
// The stream is required to be a multiple of 8 samples.
Bits []byte
// The duration each bit represents. Not to be confused by the duration of
// each byte.
Res time.Duration
// LSBF when true means than Bits is in LSB-first. When false, the data is
// MSB-first.
//
// With MSBF, the first bit processed is the most significant one (0x80). For
// example, I²C, I2S PCM and SPI use MSB-first at the word level. This
// requires to pack words correctly.
//
// With LSBF, the first bit processed is the least significant one (0x01).
// For example, Ethernet uses LSB-first at the byte level and MSB-first at
// the word level.
LSBF bool
}

// Resolution implement Stream.
Expand All @@ -117,7 +57,7 @@ func (b *BitStream) Resolution() time.Duration {

// Duration implement Stream.
func (b *BitStream) Duration() time.Duration {
return b.Res * time.Duration(len(b.Bits))
return b.Res * time.Duration(len(b.Bits)*8)
}

//
Expand Down Expand Up @@ -265,8 +205,6 @@ func search(n int, f func(int) bool) int {
return lo
}

var _ Stream = &BitStreamLSB{}
var _ Stream = &BitStreamMSB{}
var _ Stream = &BitStream{}
var _ Stream = &EdgeStream{}
var _ Stream = &Program{}
42 changes: 7 additions & 35 deletions conn/gpio/gpiostream/gpiostream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,15 @@ import (
"time"
)

func TestBitStreamLSB(t *testing.T) {
s := BitStreamLSB{Res: time.Second, Bits: make(BitsLSB, 100)}
if r := s.Resolution(); r != time.Second {
t.Fatal(r)
}
if d := s.Duration(); d != 100*8*time.Second {
t.Fatal(d)
}
s = BitStreamLSB{Res: time.Second}
if r := s.Resolution(); r != 0 {
t.Fatal(r)
}
}

func TestBitStreamMSB(t *testing.T) {
s := BitStreamMSB{Res: time.Second, Bits: make(BitsMSB, 100)}
if r := s.Resolution(); r != time.Second {
t.Fatal(r)
}
if d := s.Duration(); d != 100*8*time.Second {
t.Fatal(d)
}
s = BitStreamMSB{Res: time.Second}
if r := s.Resolution(); r != 0 {
t.Fatal(r)
}
}

func TestBitStream(t *testing.T) {
s := BitStream{Res: time.Second, Bits: make(Bits, 100)}
s := BitStream{Res: time.Second, Bits: make([]byte, 100), LSBF: true}
if r := s.Resolution(); r != time.Second {
t.Fatal(r)
}
if d := s.Duration(); d != 100*time.Second {
if d := s.Duration(); d != 100*8*time.Second {
t.Fatal(d)
}
s = BitStream{Res: time.Second}
s = BitStream{Res: time.Second, LSBF: true}
if r := s.Resolution(); r != 0 {
t.Fatal(r)
}
Expand Down Expand Up @@ -73,7 +45,7 @@ func TestProgram(t *testing.T) {
s := Program{
Parts: []Stream{
&EdgeStream{Res: time.Second, Edges: []time.Duration{time.Second, time.Millisecond}},
&BitStreamLSB{Res: time.Second, Bits: make(BitsLSB, 100)},
&BitStream{Res: time.Second, Bits: make([]byte, 100)},
},
Loops: 2,
}
Expand Down Expand Up @@ -102,9 +74,9 @@ func TestProgram(t *testing.T) {
func TestProgram_Nyquist(t *testing.T) {
s := Program{
Parts: []Stream{
&BitStreamLSB{Res: time.Second + 2*time.Millisecond, Bits: make(BitsLSB, 1)},
&BitStreamLSB{Res: time.Second, Bits: make(BitsLSB, 1)},
&BitStreamLSB{Res: 5 * time.Second, Bits: make(BitsLSB, 1)},
&BitStream{Res: time.Second + 2*time.Millisecond, Bits: make([]byte, 1)},
&BitStream{Res: time.Second, Bits: make([]byte, 1)},
&BitStream{Res: 5 * time.Second, Bits: make([]byte, 1)},
},
Loops: 1,
}
Expand Down
Loading

0 comments on commit 25fcbaa

Please sign in to comment.