mirror of
https://github.com/kidoman/embd
synced 2024-12-22 12:50:19 +01:00
mcp3008: added package and samples for mcp3008 10-bit 8-channel adc
This commit is contained in:
parent
42033238e2
commit
59958d7dfc
52
convertors/mcp3008/mcp3008.go
Normal file
52
convertors/mcp3008/mcp3008.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package mcp3008
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"github.com/kidoman/embd"
|
||||||
|
|
||||||
|
_ "github.com/kidoman/embd/host/all"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mcp3008 struct {
|
||||||
|
mode int
|
||||||
|
|
||||||
|
bus embd.SPIBus
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
SingleMode = int(1)
|
||||||
|
DifferenceMode = int(0)
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(mode, spiChan, speed int) (*mcp3008, error) {
|
||||||
|
if err := embd.InitSPI(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
glog.V(3).Infof("mcp3008: getting spiBus with mode: %v, channel: %v, speed: %v", mode, spiChan, speed)
|
||||||
|
spiBus := embd.NewSPIBus(embd.SpiMode0, byte(spiChan), speed, 0, 0)
|
||||||
|
return &mcp3008{mode, spiBus}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mcp3008) AnalogValueAt(chanNum int) (int, error) {
|
||||||
|
data := make([]uint8, 3)
|
||||||
|
data[0] = 1
|
||||||
|
data[1] = uint8(m.mode)<<7 | uint8(chanNum)<<4
|
||||||
|
data[2] = 0
|
||||||
|
|
||||||
|
if err := m.bus.TransferAndRecieveData(data); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(uint16(data[1]&0x03)<<8 | uint16(data[2])), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mcp3008) Close() error {
|
||||||
|
glog.V(2).Infoln("mcp3008: performing cleanup")
|
||||||
|
if err := m.bus.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := embd.CloseSPI(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -15,6 +15,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
"github.com/kidoman/embd/host/generic"
|
"github.com/kidoman/embd/host/generic"
|
||||||
)
|
)
|
||||||
@ -97,6 +99,7 @@ var ledMap = embd.LEDMap{
|
|||||||
var spiDeviceMinor = byte(1)
|
var spiDeviceMinor = byte(1)
|
||||||
|
|
||||||
func ensureFeatureEnabled(id string) error {
|
func ensureFeatureEnabled(id string) error {
|
||||||
|
glog.V(3).Infof("bbb: enabling feature %v", id)
|
||||||
pattern := "/sys/devices/bone_capemgr.*/slots"
|
pattern := "/sys/devices/bone_capemgr.*/slots"
|
||||||
file, err := embd.FindFirstMatchingFile(pattern)
|
file, err := embd.FindFirstMatchingFile(pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -108,6 +111,7 @@ func ensureFeatureEnabled(id string) error {
|
|||||||
}
|
}
|
||||||
str := string(bytes)
|
str := string(bytes)
|
||||||
if strings.Contains(str, id) {
|
if strings.Contains(str, id) {
|
||||||
|
glog.V(3).Infof("bbb: feature %v already enabled", id)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
slots, err := os.OpenFile(file, os.O_WRONLY, os.ModeExclusive)
|
slots, err := os.OpenFile(file, os.O_WRONLY, os.ModeExclusive)
|
||||||
@ -115,6 +119,7 @@ func ensureFeatureEnabled(id string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer slots.Close()
|
defer slots.Close()
|
||||||
|
glog.V(3).Infof("bbb: writing %v to slots file", id)
|
||||||
_, err = slots.WriteString(id)
|
_, err = slots.WriteString(id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,10 @@ func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int, shouldIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *spiBus) init() error {
|
func (b *spiBus) init() error {
|
||||||
|
if b.initialized {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if b.shouldInitialize {
|
if b.shouldInitialize {
|
||||||
if err := b.initializer(); err != nil {
|
if err := b.initializer(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -83,14 +87,11 @@ func (b *spiBus) init() error {
|
|||||||
b.shouldInitialize = false
|
b.shouldInitialize = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.initialized {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if b.file, err = os.OpenFile(fmt.Sprintf("/dev/spidev%v.%v", b.spiDevMinor, b.channel), os.O_RDWR, os.ModeExclusive); err != nil {
|
if b.file, err = os.OpenFile(fmt.Sprintf("/dev/spidev%v.%v", b.spiDevMinor, b.channel), os.O_RDWR, os.ModeExclusive); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(3).Infof("spi: sucessfully opened file /dev/spidev%v.%v", b.spiDevMinor, b.channel)
|
||||||
|
|
||||||
err = b.setMode()
|
err = b.setMode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -112,6 +113,7 @@ func (b *spiBus) init() error {
|
|||||||
b.setDelay()
|
b.setDelay()
|
||||||
|
|
||||||
glog.V(2).Infof("spi: bus %v initialized", b.channel)
|
glog.V(2).Infof("spi: bus %v initialized", b.channel)
|
||||||
|
glog.V(3).Infof("spi: bus %v initialized with spiIocTransfer as %v", b.channel, b.spiTransferData)
|
||||||
|
|
||||||
b.initialized = true
|
b.initialized = true
|
||||||
return nil
|
return nil
|
||||||
@ -187,6 +189,10 @@ func (b *spiBus) setDelay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error {
|
func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error {
|
||||||
|
if err := b.init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
len := len(dataBuffer)
|
len := len(dataBuffer)
|
||||||
dataCarrier := b.spiTransferData
|
dataCarrier := b.spiTransferData
|
||||||
|
|
||||||
@ -194,16 +200,22 @@ func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error {
|
|||||||
dataCarrier.txBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0])))
|
dataCarrier.txBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0])))
|
||||||
dataCarrier.rxBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0])))
|
dataCarrier.rxBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0])))
|
||||||
|
|
||||||
|
glog.V(3).Infof("spi: sending dataBuffer %v with carrier %v", dataBuffer, dataCarrier)
|
||||||
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), uintptr(spiIocMessageN(1)), uintptr(unsafe.Pointer(&dataCarrier)))
|
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), uintptr(spiIocMessageN(1)), uintptr(unsafe.Pointer(&dataCarrier)))
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
err := syscall.Errno(errno)
|
err := syscall.Errno(errno)
|
||||||
glog.V(3).Infof("spi: failed to read due to %v", err.Error())
|
glog.V(3).Infof("spi: failed to read due to %v", err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
glog.V(3).Infof("spi: read into dataBuffer %v", dataBuffer)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *spiBus) ReceiveData(len int) ([]uint8, error) {
|
func (b *spiBus) ReceiveData(len int) ([]uint8, error) {
|
||||||
|
if err := b.init(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
data := make([]uint8, len)
|
data := make([]uint8, len)
|
||||||
var err error
|
var err error
|
||||||
err = b.TransferAndRecieveData(data)
|
err = b.TransferAndRecieveData(data)
|
||||||
@ -214,6 +226,10 @@ func (b *spiBus) ReceiveData(len int) ([]uint8, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) {
|
func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) {
|
||||||
|
if err := b.init(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
d := make([]uint8, 1)
|
d := make([]uint8, 1)
|
||||||
d[0] = uint8(data)
|
d[0] = uint8(data)
|
||||||
err := b.TransferAndRecieveData(d)
|
err := b.TransferAndRecieveData(d)
|
||||||
@ -224,6 +240,10 @@ func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *spiBus) ReceiveByte() (byte, error) {
|
func (b *spiBus) ReceiveByte() (byte, error) {
|
||||||
|
if err := b.init(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
d := make([]uint8, 1)
|
d := make([]uint8, 1)
|
||||||
err := b.TransferAndRecieveData(d)
|
err := b.TransferAndRecieveData(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
2
samples/.gitignore
vendored
2
samples/.gitignore
vendored
@ -24,3 +24,5 @@ universalblinker
|
|||||||
us020
|
us020
|
||||||
watersensor
|
watersensor
|
||||||
spi
|
spi
|
||||||
|
mcp3008
|
||||||
|
spimcp3008
|
||||||
|
33
samples/mcp3008.go
Normal file
33
samples/mcp3008.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/kidoman/embd/convertors/mcp3008"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
fmt.Println("This is a sample code for mcp3008 10bit 8 channel ADC")
|
||||||
|
|
||||||
|
adc, err := mcp3008.New(mcp3008.SingleMode, 0, 1000000)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer adc.Close()
|
||||||
|
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
val, err := adc.AnalogValueAt(0)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Analog value is: %v\n", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
samples/spimcp3008.go
Normal file
46
samples/spimcp3008.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/kidoman/embd"
|
||||||
|
_ "github.com/kidoman/embd/host/all"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
if err := embd.InitSPI(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0)
|
||||||
|
|
||||||
|
defer clean(bus)
|
||||||
|
|
||||||
|
for i := 0; i < 30; i++ {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
val, _ := getSensorValue(bus)
|
||||||
|
fmt.Printf("value is: %v\n", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func clean(bus embd.SPIBus) {
|
||||||
|
bus.Close()
|
||||||
|
embd.CloseSPI()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSensorValue(bus embd.SPIBus) (uint16, error) {
|
||||||
|
data := make([]uint8, 3)
|
||||||
|
data[0] = 1
|
||||||
|
data[1] = 128
|
||||||
|
data[2] = 0
|
||||||
|
var err error
|
||||||
|
err = bus.TransferAndRecieveData(data)
|
||||||
|
if err != nil {
|
||||||
|
return uint16(0), err
|
||||||
|
}
|
||||||
|
return uint16(data[1]&0x03)<<8 | uint16(data[2]), nil
|
||||||
|
}
|
@ -29,6 +29,7 @@ func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus {
|
|||||||
defer s.busMapLock.Unlock()
|
defer s.busMapLock.Unlock()
|
||||||
|
|
||||||
b := s.sbf(s.spiDevMinor, mode, channel, speed, bpw, delay, s.shouldInitialize, s.initializer)
|
b := s.sbf(s.spiDevMinor, mode, channel, speed, bpw, delay, s.shouldInitialize, s.initializer)
|
||||||
|
s.busMap = make(map[byte]SPIBus)
|
||||||
s.busMap[channel] = b
|
s.busMap[channel] = b
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user