Skip to content

Commit

Permalink
spi: Add MCP3202, MCP3204, MCP3208, and MCP3304 drivers
Browse files Browse the repository at this point in the history
Signed-off-by: deadprogram <[email protected]>
  • Loading branch information
deadprogram committed Dec 13, 2017
1 parent 6f2921f commit b016010
Show file tree
Hide file tree
Showing 11 changed files with 516 additions and 8 deletions.
6 changes: 3 additions & 3 deletions drivers/spi/mcp3002.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"gobot.io/x/gobot"
)

// MCP3002DriverMaxChannel is the number of channels (plus one) of this A/D converter.
const MCP3002DriverMaxChannel = 1
// MCP3002DriverMaxChannel is the number of channels of this A/D converter.
const MCP3002DriverMaxChannel = 2

// MCP3002Driver is a driver for the MCP3002 A/D converter.
type MCP3002Driver struct {
Expand Down Expand Up @@ -59,7 +59,7 @@ func (d *MCP3002Driver) Halt() (err error) {

// Read reads the current analog data for the desired channel.
func (d *MCP3002Driver) Read(channel int) (result int, err error) {
if channel < 0 || channel > MCP3002DriverMaxChannel {
if channel < 0 || channel > MCP3002DriverMaxChannel-1 {
return 0, errors.New("Invalid channel for read")
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/spi/mcp3004.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"gobot.io/x/gobot"
)

// MCP3004DriverMaxChannel is the number of channels (plus one) of this A/D converter.
// MCP3004DriverMaxChannel is the number of channels of this A/D converter.
const MCP3004DriverMaxChannel = 3

// MCP3004Driver is a driver for the MCP3008 A/D converter.
Expand Down Expand Up @@ -59,7 +59,7 @@ func (d *MCP3004Driver) Halt() (err error) {

// Read reads the current analog data for the desired channel.
func (d *MCP3004Driver) Read(channel int) (result int, err error) {
if channel < 0 || channel > MCP3004DriverMaxChannel {
if channel < 0 || channel > MCP3004DriverMaxChannel-1 {
return 0, errors.New("Invalid channel for read")
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/spi/mcp3008.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"gobot.io/x/gobot"
)

// MCP3008DriverMaxChannel is the number of channels (plus one) of this A/D converter.
const MCP3008DriverMaxChannel = 7
// MCP3008DriverMaxChannel is the number of channels of this A/D converter.
const MCP3008DriverMaxChannel = 8

// MCP3008Driver is a driver for the MCP3008 A/D converter.
type MCP3008Driver struct {
Expand Down Expand Up @@ -59,7 +59,7 @@ func (d *MCP3008Driver) Halt() (err error) {

// Read reads the current analog data for the desired channel.
func (d *MCP3008Driver) Read(channel int) (result int, err error) {
if channel < 0 || channel > MCP3008DriverMaxChannel {
if channel < 0 || channel > MCP3008DriverMaxChannel-1 {
return 0, errors.New("Invalid channel for read")
}

Expand Down
90 changes: 90 additions & 0 deletions drivers/spi/mcp3202.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package spi

import (
"errors"
"strconv"

"gobot.io/x/gobot"
)

// MCP3202DriverMaxChannel is the number of channels of this A/D converter.
const MCP3202DriverMaxChannel = 2

// MCP3202Driver is a driver for the MCP3202 A/D converter.
type MCP3202Driver struct {
name string
connector Connector
connection Connection
}

// NewMCP3202Driver creates a new Gobot Driver for MCP3202Driver A/D converter
//
// Params:
// a *Adaptor - the Adaptor to use with this Driver
//
func NewMCP3202Driver(a Connector) *MCP3202Driver {
d := &MCP3202Driver{
name: gobot.DefaultName("MCP3202"),
connector: a,
}
return d
}

// Name returns the name of the device.
func (d *MCP3202Driver) Name() string { return d.name }

// SetName sets the name of the device.
func (d *MCP3202Driver) SetName(n string) { d.name = n }

// Connection returns the Connection of the device.
func (d *MCP3202Driver) Connection() gobot.Connection { return d.connection.(gobot.Connection) }

// Start initializes the driver.
func (d *MCP3202Driver) Start() (err error) {
bus := d.connector.GetSpiDefaultBus()
mode := d.connector.GetSpiDefaultMode()
maxSpeed := d.connector.GetSpiDefaultMaxSpeed()
d.connection, err = d.connector.GetSpiConnection(bus, mode, maxSpeed)
if err != nil {
return err
}
return nil
}

// Halt stops the driver.
func (d *MCP3202Driver) Halt() (err error) {
d.connection.Close()
return
}

// Read reads the current analog data for the desired channel.
func (d *MCP3202Driver) Read(channel int) (result int, err error) {
if channel < 0 || channel > MCP3202DriverMaxChannel-1 {
return 0, errors.New("Invalid channel for read")
}

tx := make([]byte, 3)
tx[0] = 0x01
tx[1] = 0xa0 + byte(channel)<<6
tx[2] = 0x00

rx := make([]byte, 3)

err = d.connection.Tx(tx, rx)
if err == nil && len(rx) == 3 {
result = int(((rx[1] & 0xf) << 8) + rx[2])
}

return result, err
}

// AnalogRead returns value from analog reading of specified pin, scaled to 0-1023 value.
func (d *MCP3202Driver) AnalogRead(pin string) (value int, err error) {
channel, _ := strconv.Atoi(pin)
value, err = d.Read(channel)
if err != nil {
value = int(gobot.ToScale(gobot.FromScale(float64(value), 0, 4095), 0, 1023))
}

return
}
37 changes: 37 additions & 0 deletions drivers/spi/mcp3202_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package spi

import (
"testing"

"gobot.io/x/gobot"
"gobot.io/x/gobot/drivers/aio"
"gobot.io/x/gobot/gobottest"
)

var _ gobot.Driver = (*MCP3202Driver)(nil)

// must implement the AnalogReader interface
var _ aio.AnalogReader = (*MCP3202Driver)(nil)

func initTestMCP3202Driver() *MCP3202Driver {
d := NewMCP3202Driver(&TestConnector{})
return d
}

func TestMCP3202DriverStart(t *testing.T) {
d := initTestMCP3202Driver()
gobottest.Assert(t, d.Start(), nil)
}

func TestMCP3202DriverHalt(t *testing.T) {
d := initTestMCP3202Driver()
d.Start()
gobottest.Assert(t, d.Halt(), nil)
}

func TestMCP3202DriverRead(t *testing.T) {
d := initTestMCP3202Driver()
d.Start()

// TODO: actual read test
}
90 changes: 90 additions & 0 deletions drivers/spi/mcp3204.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package spi

import (
"errors"
"strconv"

"gobot.io/x/gobot"
)

// MCP3204DriverMaxChannel is the number of channels of this A/D converter.
const MCP3204DriverMaxChannel = 4

// MCP3204Driver is a driver for the MCP3204 A/D converter.
type MCP3204Driver struct {
name string
connector Connector
connection Connection
}

// NewMCP3204Driver creates a new Gobot Driver for MCP3204Driver A/D converter
//
// Params:
// a *Adaptor - the Adaptor to use with this Driver
//
func NewMCP3204Driver(a Connector) *MCP3204Driver {
d := &MCP3204Driver{
name: gobot.DefaultName("MCP3204"),
connector: a,
}
return d
}

// Name returns the name of the device.
func (d *MCP3204Driver) Name() string { return d.name }

// SetName sets the name of the device.
func (d *MCP3204Driver) SetName(n string) { d.name = n }

// Connection returns the Connection of the device.
func (d *MCP3204Driver) Connection() gobot.Connection { return d.connection.(gobot.Connection) }

// Start initializes the driver.
func (d *MCP3204Driver) Start() (err error) {
bus := d.connector.GetSpiDefaultBus()
mode := d.connector.GetSpiDefaultMode()
maxSpeed := d.connector.GetSpiDefaultMaxSpeed()
d.connection, err = d.connector.GetSpiConnection(bus, mode, maxSpeed)
if err != nil {
return err
}
return nil
}

// Halt stops the driver.
func (d *MCP3204Driver) Halt() (err error) {
d.connection.Close()
return
}

// Read reads the current analog data for the desired channel.
func (d *MCP3204Driver) Read(channel int) (result int, err error) {
if channel < 0 || channel > MCP3204DriverMaxChannel-1 {
return 0, errors.New("Invalid channel for read")
}

tx := make([]byte, 3)
tx[0] = 0x06 + (byte(channel) >> 2)
tx[1] = (byte(channel) & 0x03) << 6
tx[2] = 0x00

rx := make([]byte, 3)

err = d.connection.Tx(tx, rx)
if err == nil && len(rx) == 3 {
result = int(((rx[1] & 0xf) << 8) + rx[2])
}

return result, err
}

// AnalogRead returns value from analog reading of specified pin, scaled to 0-1023 value.
func (d *MCP3204Driver) AnalogRead(pin string) (value int, err error) {
channel, _ := strconv.Atoi(pin)
value, err = d.Read(channel)
if err != nil {
value = int(gobot.ToScale(gobot.FromScale(float64(value), 0, 4095), 0, 1023))
}

return
}
37 changes: 37 additions & 0 deletions drivers/spi/mcp3204_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package spi

import (
"testing"

"gobot.io/x/gobot"
"gobot.io/x/gobot/drivers/aio"
"gobot.io/x/gobot/gobottest"
)

var _ gobot.Driver = (*MCP3204Driver)(nil)

// must implement the AnalogReader interface
var _ aio.AnalogReader = (*MCP3204Driver)(nil)

func initTestMCP3204Driver() *MCP3204Driver {
d := NewMCP3204Driver(&TestConnector{})
return d
}

func TestMCP3204DriverStart(t *testing.T) {
d := initTestMCP3204Driver()
gobottest.Assert(t, d.Start(), nil)
}

func TestMCP3204DriverHalt(t *testing.T) {
d := initTestMCP3204Driver()
d.Start()
gobottest.Assert(t, d.Halt(), nil)
}

func TestMCP3204DriverRead(t *testing.T) {
d := initTestMCP3204Driver()
d.Start()

// TODO: actual read test
}
Loading

0 comments on commit b016010

Please sign in to comment.