From 12db8443b05e8be34c02d388c3462b952ddb4487 Mon Sep 17 00:00:00 2001 From: Kunal Powar Date: Mon, 28 Apr 2014 01:18:14 +0530 Subject: [PATCH 01/17] spi: added spi feature for all bbb and rpi --- descriptor.go | 1 + host/bbb/bbb.go | 5 + host/generic/spibus.go | 233 +++++++++++++++++++++++++++++++++++++++++ host/rpi/rpi.go | 5 + samples/spisample.go | 53 ++++++++++ spi.go | 64 +++++++++++ spidriver.go | 38 +++++++ 7 files changed, 399 insertions(+) create mode 100644 host/generic/spibus.go create mode 100644 samples/spisample.go create mode 100644 spi.go create mode 100644 spidriver.go diff --git a/descriptor.go b/descriptor.go index 78208f3..b891008 100644 --- a/descriptor.go +++ b/descriptor.go @@ -14,6 +14,7 @@ type Descriptor struct { GPIODriver func() GPIODriver I2CDriver func() I2CDriver LEDDriver func() LEDDriver + SPIDriver func() SPIDriver } // The Describer type is a Descriptor provider. diff --git a/host/bbb/bbb.go b/host/bbb/bbb.go index c52f8a8..5a2e8ce 100644 --- a/host/bbb/bbb.go +++ b/host/bbb/bbb.go @@ -94,6 +94,8 @@ var ledMap = embd.LEDMap{ "beaglebone:green:usr3": []string{"3", "USR3", "usr3"}, } +var spiDeviceMinor = byte(1) + func ensureFeatureEnabled(id string) error { pattern := "/sys/devices/bone_capemgr.*/slots" file, err := embd.FindFirstMatchingFile(pattern) @@ -165,6 +167,9 @@ func init() { LEDDriver: func() embd.LEDDriver { return embd.NewLEDDriver(ledMap, generic.NewLED) }, + SPIDriver: func() embd.SPIDriver { + return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus) + }, } }) } diff --git a/host/generic/spibus.go b/host/generic/spibus.go new file mode 100644 index 0000000..d2d96ae --- /dev/null +++ b/host/generic/spibus.go @@ -0,0 +1,233 @@ +package generic + +import ( + "fmt" + "os" + "sync" + "syscall" + "unsafe" + + "github.com/golang/glog" + "github.com/kidoman/embd" +) + +const ( + SPI_IOC_WR_MODE = 0x40016B01 + SPI_IOC_WR_BITS_PER_WORD = 0x40016B03 + SPI_IOC_WR_MAX_SPEED_HZ = 0x40046B04 + + SPI_IOC_RD_MODE = 0x80016B01 + SPI_IOC_RD_BITS_PER_WORD = 0x80016B03 + SPI_IOC_RD_MAX_SPEED_HZ = 0x80046B04 + + SPI_IOC_MESSAGE_0 = 1073769216 //0x40006B00 + SPI_IOC_INCREMENTER = 2097152 //0x200000 + + DEFAULT_DELAYMS = uint16(0) + DEFAULT_SPI_BPW = uint8(8) + DEFAULT_SPI_SPEED = uint32(1000000) +) + +type spiIocTransfer struct { + tx_buf uint64 + rx_buf uint64 + + length uint32 + speed_hz uint32 + delay_usecs uint16 + bits_per_word uint8 +} + +type spiBus struct { + file *os.File + + spiDevMinor byte + + channel byte + mode byte + speed int + bpw int + delayms int + + mu sync.Mutex + + spiTransferData spiIocTransfer + initialized bool +} + +func spi_ioc_message_n(n uint32) uint32 { + return (SPI_IOC_MESSAGE_0 + (n * SPI_IOC_INCREMENTER)) +} + +func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int) embd.SPIBus { + return &spiBus{ + spiDevMinor: spiDevMinor, + mode: mode, + channel: channel, + speed: speed, + bpw: bpw, + delayms: delay, + } +} + +func (b *spiBus) init() error { + if b.initialized { + return nil + } + + 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 { + return err + } + + err = b.setMode() + if err != nil { + return err + } + + b.spiTransferData = spiIocTransfer{} + + err = b.setSpeed() + if err != nil { + return err + } + + err = b.setBpw() + if err != nil { + return err + } + + b.setDelay() + + glog.V(2).Infof("spi: bus %v initialized", b.channel) + + b.initialized = true + return nil + +} + +func (b *spiBus) setMode() error { + var mode = uint8(b.mode) + var err error + glog.V(3).Infof("spi: setting spi mode to %v", mode) + + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), SPI_IOC_WR_MODE, uintptr(unsafe.Pointer(&mode))) + if errno != 0 { + err = syscall.Errno(errno) + glog.V(3).Infof("spi: failed to set mode due to %v", err.Error()) + return err + } + glog.V(3).Infof("spi: mode set to %v", mode) + return nil +} + +func (b *spiBus) setSpeed() error { + var speed uint32 + if b.speed > 0 { + speed = uint32(b.speed) + } else { + speed = DEFAULT_SPI_SPEED + } + + glog.V(3).Infof("spi: setting spi speed_max to %v", speed) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), SPI_IOC_WR_MAX_SPEED_HZ, uintptr(unsafe.Pointer(&speed))) + if errno != 0 { + err := syscall.Errno(errno) + glog.V(3).Infof("spi: failed to set speed_max due to %v", err.Error()) + return err + } + glog.V(3).Infof("spi: speed_max set to %v", speed) + b.spiTransferData.speed_hz = speed + + return nil +} + +func (b *spiBus) setBpw() error { + var bpw uint8 + + if b.bpw > 0 { + bpw = uint8(b.bpw) + } else { + bpw = DEFAULT_SPI_BPW + } + + glog.V(3).Infof("spi: setting spi bpw to %v", bpw) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), SPI_IOC_WR_BITS_PER_WORD, uintptr(unsafe.Pointer(&bpw))) + if errno != 0 { + err := syscall.Errno(errno) + glog.V(3).Infof("spi: failed to set bpw due to %v", err.Error()) + return err + } + glog.V(3).Infof("spi: bpw set to %v", bpw) + b.spiTransferData.bits_per_word = uint8(bpw) + return nil +} + +func (b *spiBus) setDelay() { + var delay uint16 + + if b.delayms > 0 { + delay = uint16(b.delayms) + } else { + delay = DEFAULT_DELAYMS + } + glog.V(3).Infof("spi: delay_ms set to %v", delay) + b.spiTransferData.delay_usecs = delay +} + +func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error { + len := len(dataBuffer) + dataCarrier := b.spiTransferData + + dataCarrier.length = uint32(len) + dataCarrier.tx_buf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0]))) + dataCarrier.rx_buf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0]))) + + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), uintptr(spi_ioc_message_n(1)), uintptr(unsafe.Pointer(&dataCarrier))) + if errno != 0 { + err := syscall.Errno(errno) + glog.V(3).Infof("spi: failed to read due to %v", err.Error()) + return err + } + return nil +} + +func (b *spiBus) ReceiveData(len int) ([]uint8, error) { + data := make([]uint8, len) + var err error + err = b.TransferAndRecieveData(data) + if err != nil { + return nil, err + } + return data, nil +} + +func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) { + d := make([]uint8, 1) + d[0] = uint8(data) + err := b.TransferAndRecieveData(d) + if err != nil { + return 0, err + } + return d[0], nil +} + +func (b *spiBus) ReceiveByte() (byte, error) { + d := make([]uint8, 1) + err := b.TransferAndRecieveData(d) + if err != nil { + return 0, err + } + return byte(d[0]), nil +} + +func (b *spiBus) Close() error { + b.mu.Lock() + defer b.mu.Unlock() + + if !b.initialized { + return nil + } + + return b.file.Close() +} diff --git a/host/rpi/rpi.go b/host/rpi/rpi.go index 36a9905..7814843 100644 --- a/host/rpi/rpi.go +++ b/host/rpi/rpi.go @@ -13,6 +13,8 @@ import ( "github.com/kidoman/embd/host/generic" ) +var spiDeviceMinor = byte(0) + var rev1Pins = embd.PinMap{ &embd.PinDesc{ID: "P1_3", Aliases: []string{"0", "GPIO_0", "SDA", "I2C0_SDA"}, Caps: embd.CapDigital | embd.CapI2C, DigitalLogical: 0}, &embd.PinDesc{ID: "P1_5", Aliases: []string{"1", "GPIO_1", "SCL", "I2C0_SCL"}, Caps: embd.CapDigital | embd.CapI2C, DigitalLogical: 1}, @@ -74,6 +76,9 @@ func init() { LEDDriver: func() embd.LEDDriver { return embd.NewLEDDriver(ledMap, generic.NewLED) }, + SPIDriver: func() embd.SPIDriver { + return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus) + }, } }) } diff --git a/samples/spisample.go b/samples/spisample.go new file mode 100644 index 0000000..647c649 --- /dev/null +++ b/samples/spisample.go @@ -0,0 +1,53 @@ +package main + +import ( + "fmt" + + "github.com/kidoman/embd" + + _ "github.com/kidoman/embd/host/all" +) + +func main() { + var err error + err = embd.InitSPI() + if err != nil { + panic(err) + } + defer embd.CloseSPI() + + spiBus := embd.NewSPIBus(embd.SPI_MODE_0, 0, 1000000, 8, 0) + defer spiBus.Close() + + dataBuf := make([]uint8, 3) + dataBuf[0] = uint8(1) + dataBuf[1] = uint8(2) + dataBuf[2] = uint8(3) + + err = spiBus.TransferAndRecieveData(dataBuf) + if err != nil { + panic(err) + } + + fmt.Println("Recived data is: %v", dataBuf) + + dataReceived, err := spiBus.ReceiveData(3) + if err != nil { + panic(err) + } + + fmt.Println("Recived data is: %v", dataReceived) + + dataByte := byte(1) + receivedByte, err := spiBus.TransferAndReceiveByte(dataByte) + if err != nil { + panic(err) + } + fmt.Println("Recived byte is: %v", receivedByte) + + receivedByte, err = spiBus.ReceiveByte() + if err != nil { + panic(err) + } + fmt.Println("Recived byte is: %v", receivedByte) +} diff --git a/spi.go b/spi.go new file mode 100644 index 0000000..e903084 --- /dev/null +++ b/spi.go @@ -0,0 +1,64 @@ +package embd + +const ( + spi_cpha = 0x01 + spi_cpol = 0x02 + + SPI_MODE_0 = (0 | 0) + SPI_MODE_1 = (0 | spi_cpha) + SPI_MODE_2 = (spi_cpol | 0) + SPI_MODE_3 = (spi_cpol | spi_cpha) +) + +type SPIBus interface { + TransferAndRecieveData(dataBuffer []uint8) error + + ReceiveData(len int) ([]uint8, error) + + TransferAndReceiveByte(data byte) (byte, error) + + ReceiveByte() (byte, error) + + Close() error +} + +type SPIDriver interface { + Bus(byte, byte, int, int, int) SPIBus + + Close() error +} + +var spiDriverInitialized bool +var spiDriverInstance SPIDriver + +func InitSPI() error { + if spiDriverInitialized { + return nil + } + + desc, err := DescribeHost() + if err != nil { + return err + } + + if desc.SPIDriver == nil { + return ErrFeatureNotSupported + } + + spiDriverInstance = desc.SPIDriver() + spiDriverInitialized = true + + return nil +} + +func CloseSPI() error { + return spiDriverInstance.Close() +} + +func NewSPIBus(mode, channel byte, speed, bpw, delay int) SPIBus { + if err := InitSPI(); err != nil { + panic(err) + } + + return spiDriverInstance.Bus(mode, channel, speed, bpw, delay) +} diff --git a/spidriver.go b/spidriver.go new file mode 100644 index 0000000..c2f21f6 --- /dev/null +++ b/spidriver.go @@ -0,0 +1,38 @@ +package embd + +import "sync" + +type spiBusFactory func(byte, byte, byte, int, int, int) SPIBus + +type spiDriver struct { + spiDevMinor byte + + busMap map[byte]SPIBus + busMapLock sync.Mutex + + spf spiBusFactory +} + +func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory) SPIDriver { + return &spiDriver{ + spiDevMinor: spiDevMinor, + spf: sbf, + } +} + +func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus { + s.busMapLock.Lock() + defer s.busMapLock.Unlock() + + b := s.spf(s.spiDevMinor, mode, channel, speed, bpw, delay) + s.busMap[channel] = b + return b +} + +func (s *spiDriver) Close() error { + for _, b := range s.busMap { + b.Close() + } + + return nil +} From faa686f01c9e50199e82c6cf9dcc35015b7fff34 Mon Sep 17 00:00:00 2001 From: Kunal Powar Date: Mon, 28 Apr 2014 03:13:57 +0530 Subject: [PATCH 02/17] spi: changes in fields/symbols to follow idiomatic go --- host/generic/spibus.go | 71 ++++++++++++++++---------------- samples/.gitignore | 1 + samples/{spisample.go => spi.go} | 7 +--- spi.go | 12 +++--- spidriver.go | 6 +-- 5 files changed, 47 insertions(+), 50 deletions(-) rename samples/{spisample.go => spi.go} (83%) diff --git a/host/generic/spibus.go b/host/generic/spibus.go index d2d96ae..9c1cb6b 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -12,30 +12,30 @@ import ( ) const ( - SPI_IOC_WR_MODE = 0x40016B01 - SPI_IOC_WR_BITS_PER_WORD = 0x40016B03 - SPI_IOC_WR_MAX_SPEED_HZ = 0x40046B04 + spiIocWrMode = 0x40016B01 + spiIocWrBitsPerWord = 0x40016B03 + spiIocWrMaxSpeedHz = 0x40046B04 - SPI_IOC_RD_MODE = 0x80016B01 - SPI_IOC_RD_BITS_PER_WORD = 0x80016B03 - SPI_IOC_RD_MAX_SPEED_HZ = 0x80046B04 + spiIocRdMode = 0x80016B01 + spiIocRdBitsPerWord = 0x80016B03 + spiIocRdMaxSpeedHz = 0x80046B04 - SPI_IOC_MESSAGE_0 = 1073769216 //0x40006B00 - SPI_IOC_INCREMENTER = 2097152 //0x200000 + spiIocMessage0 = 1073769216 //0x40006B00 + spiIocIncrementor = 2097152 //0x200000 - DEFAULT_DELAYMS = uint16(0) - DEFAULT_SPI_BPW = uint8(8) - DEFAULT_SPI_SPEED = uint32(1000000) + defaultDelayms = uint16(0) + defaultSpiBpw = uint8(8) + defaultSpiSpeed = uint32(1000000) ) type spiIocTransfer struct { - tx_buf uint64 - rx_buf uint64 + txBuf uint64 + rxBuf uint64 - length uint32 - speed_hz uint32 - delay_usecs uint16 - bits_per_word uint8 + length uint32 + speedHz uint32 + delayus uint16 + bitsPerWord uint8 } type spiBus struct { @@ -55,8 +55,8 @@ type spiBus struct { initialized bool } -func spi_ioc_message_n(n uint32) uint32 { - return (SPI_IOC_MESSAGE_0 + (n * SPI_IOC_INCREMENTER)) +func spiIocMessageN(n uint32) uint32 { + return (spiIocMessage0 + (n * spiIocIncrementor)) } func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int) embd.SPIBus { @@ -103,7 +103,6 @@ func (b *spiBus) init() error { b.initialized = true return nil - } func (b *spiBus) setMode() error { @@ -111,7 +110,7 @@ func (b *spiBus) setMode() error { var err error glog.V(3).Infof("spi: setting spi mode to %v", mode) - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), SPI_IOC_WR_MODE, uintptr(unsafe.Pointer(&mode))) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIocWrMode, uintptr(unsafe.Pointer(&mode))) if errno != 0 { err = syscall.Errno(errno) glog.V(3).Infof("spi: failed to set mode due to %v", err.Error()) @@ -126,18 +125,18 @@ func (b *spiBus) setSpeed() error { if b.speed > 0 { speed = uint32(b.speed) } else { - speed = DEFAULT_SPI_SPEED + speed = defaultSpiSpeed } - glog.V(3).Infof("spi: setting spi speed_max to %v", speed) - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), SPI_IOC_WR_MAX_SPEED_HZ, uintptr(unsafe.Pointer(&speed))) + glog.V(3).Infof("spi: setting spi speedMax to %v", speed) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIocWrMaxSpeedHz, uintptr(unsafe.Pointer(&speed))) if errno != 0 { err := syscall.Errno(errno) - glog.V(3).Infof("spi: failed to set speed_max due to %v", err.Error()) + glog.V(3).Infof("spi: failed to set speedMax due to %v", err.Error()) return err } - glog.V(3).Infof("spi: speed_max set to %v", speed) - b.spiTransferData.speed_hz = speed + glog.V(3).Infof("spi: speedMax set to %v", speed) + b.spiTransferData.speedHz = speed return nil } @@ -148,18 +147,18 @@ func (b *spiBus) setBpw() error { if b.bpw > 0 { bpw = uint8(b.bpw) } else { - bpw = DEFAULT_SPI_BPW + bpw = defaultSpiBpw } glog.V(3).Infof("spi: setting spi bpw to %v", bpw) - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), SPI_IOC_WR_BITS_PER_WORD, uintptr(unsafe.Pointer(&bpw))) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIocWrBitsPerWord, uintptr(unsafe.Pointer(&bpw))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to set bpw due to %v", err.Error()) return err } glog.V(3).Infof("spi: bpw set to %v", bpw) - b.spiTransferData.bits_per_word = uint8(bpw) + b.spiTransferData.bitsPerWord = uint8(bpw) return nil } @@ -169,10 +168,10 @@ func (b *spiBus) setDelay() { if b.delayms > 0 { delay = uint16(b.delayms) } else { - delay = DEFAULT_DELAYMS + delay = defaultDelayms } - glog.V(3).Infof("spi: delay_ms set to %v", delay) - b.spiTransferData.delay_usecs = delay + glog.V(3).Infof("spi: delayms set to %v", delay) + b.spiTransferData.delayus = delay } func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error { @@ -180,10 +179,10 @@ func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error { dataCarrier := b.spiTransferData dataCarrier.length = uint32(len) - dataCarrier.tx_buf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0]))) - dataCarrier.rx_buf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0]))) + dataCarrier.txBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0]))) + dataCarrier.rxBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0]))) - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), uintptr(spi_ioc_message_n(1)), uintptr(unsafe.Pointer(&dataCarrier))) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), uintptr(spiIocMessageN(1)), uintptr(unsafe.Pointer(&dataCarrier))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to read due to %v", err.Error()) diff --git a/samples/.gitignore b/samples/.gitignore index 836f1c7..f48626d 100644 --- a/samples/.gitignore +++ b/samples/.gitignore @@ -23,3 +23,4 @@ tmp006 universalblinker us020 watersensor +spi diff --git a/samples/spisample.go b/samples/spi.go similarity index 83% rename from samples/spisample.go rename to samples/spi.go index 647c649..f23fb0d 100644 --- a/samples/spisample.go +++ b/samples/spi.go @@ -16,13 +16,10 @@ func main() { } defer embd.CloseSPI() - spiBus := embd.NewSPIBus(embd.SPI_MODE_0, 0, 1000000, 8, 0) + spiBus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0) defer spiBus.Close() - dataBuf := make([]uint8, 3) - dataBuf[0] = uint8(1) - dataBuf[1] = uint8(2) - dataBuf[2] = uint8(3) + dataBuf := []uint8{1, 2, 3} err = spiBus.TransferAndRecieveData(dataBuf) if err != nil { diff --git a/spi.go b/spi.go index e903084..1bcb918 100644 --- a/spi.go +++ b/spi.go @@ -1,13 +1,13 @@ package embd const ( - spi_cpha = 0x01 - spi_cpol = 0x02 + spiCpha = 0x01 + spiCpol = 0x02 - SPI_MODE_0 = (0 | 0) - SPI_MODE_1 = (0 | spi_cpha) - SPI_MODE_2 = (spi_cpol | 0) - SPI_MODE_3 = (spi_cpol | spi_cpha) + SpiMode0 = (0 | 0) + SpiMode1 = (0 | spiCpha) + SpiMode2 = (spiCpol | 0) + SpiMode3 = (spiCpol | spiCpha) ) type SPIBus interface { diff --git a/spidriver.go b/spidriver.go index c2f21f6..e354ff9 100644 --- a/spidriver.go +++ b/spidriver.go @@ -10,13 +10,13 @@ type spiDriver struct { busMap map[byte]SPIBus busMapLock sync.Mutex - spf spiBusFactory + sbf spiBusFactory } func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory) SPIDriver { return &spiDriver{ spiDevMinor: spiDevMinor, - spf: sbf, + sbf: sbf, } } @@ -24,7 +24,7 @@ func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus { s.busMapLock.Lock() defer s.busMapLock.Unlock() - b := s.spf(s.spiDevMinor, mode, channel, speed, bpw, delay) + b := s.sbf(s.spiDevMinor, mode, channel, speed, bpw, delay) s.busMap[channel] = b return b } From 42033238e2e51e7e2b55712b8dcc0dd2dd46a3b6 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 1 May 2014 22:44:41 +0530 Subject: [PATCH 03/17] spi: use a initializer if required by any host --- host/bbb/bbb.go | 9 ++++++++- host/generic/spibus.go | 26 +++++++++++++++++++------- host/rpi/rpi.go | 2 +- spidriver.go | 16 ++++++++++------ 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/host/bbb/bbb.go b/host/bbb/bbb.go index 5a2e8ce..2088b69 100644 --- a/host/bbb/bbb.go +++ b/host/bbb/bbb.go @@ -155,6 +155,13 @@ func ensureFeatureDisabled(id string) error { return fmt.Errorf("embd: could not disable feature %q", id) } +func spiInitializer() error { + if err := ensureFeatureEnabled("BB-SPIDEV0"); err != nil { + return err + } + return nil +} + func init() { embd.Register(embd.HostBBB, func(rev int) *embd.Descriptor { return &embd.Descriptor{ @@ -168,7 +175,7 @@ func init() { return embd.NewLEDDriver(ledMap, generic.NewLED) }, SPIDriver: func() embd.SPIDriver { - return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus) + return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus, true, spiInitializer) }, } }) diff --git a/host/generic/spibus.go b/host/generic/spibus.go index 9c1cb6b..661ec3a 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -53,24 +53,36 @@ type spiBus struct { spiTransferData spiIocTransfer initialized bool + + shouldInitialize bool + initializer func() error } func spiIocMessageN(n uint32) uint32 { return (spiIocMessage0 + (n * spiIocIncrementor)) } -func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int) embd.SPIBus { +func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int, shouldInitialize bool, i func() error) embd.SPIBus { return &spiBus{ - spiDevMinor: spiDevMinor, - mode: mode, - channel: channel, - speed: speed, - bpw: bpw, - delayms: delay, + spiDevMinor: spiDevMinor, + mode: mode, + channel: channel, + speed: speed, + bpw: bpw, + delayms: delay, + shouldInitialize: shouldInitialize, + initializer: i, } } func (b *spiBus) init() error { + if b.shouldInitialize { + if err := b.initializer(); err != nil { + return err + } + b.shouldInitialize = false + } + if b.initialized { return nil } diff --git a/host/rpi/rpi.go b/host/rpi/rpi.go index 7814843..ddb0a6c 100644 --- a/host/rpi/rpi.go +++ b/host/rpi/rpi.go @@ -77,7 +77,7 @@ func init() { return embd.NewLEDDriver(ledMap, generic.NewLED) }, SPIDriver: func() embd.SPIDriver { - return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus) + return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus, false, nil) }, } }) diff --git a/spidriver.go b/spidriver.go index e354ff9..f12c86c 100644 --- a/spidriver.go +++ b/spidriver.go @@ -2,10 +2,12 @@ package embd import "sync" -type spiBusFactory func(byte, byte, byte, int, int, int) SPIBus +type spiBusFactory func(byte, byte, byte, int, int, int, bool, func() error) SPIBus type spiDriver struct { - spiDevMinor byte + spiDevMinor byte + shouldInitialize bool + initializer func() error busMap map[byte]SPIBus busMapLock sync.Mutex @@ -13,10 +15,12 @@ type spiDriver struct { sbf spiBusFactory } -func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory) SPIDriver { +func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory, shouldInitialize bool, i func() error) SPIDriver { return &spiDriver{ - spiDevMinor: spiDevMinor, - sbf: sbf, + spiDevMinor: spiDevMinor, + sbf: sbf, + shouldInitialize: shouldInitialize, + initializer: i, } } @@ -24,7 +28,7 @@ func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus { s.busMapLock.Lock() defer s.busMapLock.Unlock() - b := s.sbf(s.spiDevMinor, mode, channel, speed, bpw, delay) + b := s.sbf(s.spiDevMinor, mode, channel, speed, bpw, delay, s.shouldInitialize, s.initializer) s.busMap[channel] = b return b } From 59958d7dfc6093df5a288fcb483a0767b4a26825 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Sat, 3 May 2014 21:35:09 +0530 Subject: [PATCH 04/17] mcp3008: added package and samples for mcp3008 10-bit 8-channel adc --- convertors/mcp3008/mcp3008.go | 52 +++++++++++++++++++++++++++++++++++ host/bbb/bbb.go | 5 ++++ host/generic/spibus.go | 28 ++++++++++++++++--- samples/.gitignore | 2 ++ samples/mcp3008.go | 33 ++++++++++++++++++++++ samples/spimcp3008.go | 46 +++++++++++++++++++++++++++++++ spidriver.go | 1 + 7 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 convertors/mcp3008/mcp3008.go create mode 100644 samples/mcp3008.go create mode 100644 samples/spimcp3008.go diff --git a/convertors/mcp3008/mcp3008.go b/convertors/mcp3008/mcp3008.go new file mode 100644 index 0000000..2684c4c --- /dev/null +++ b/convertors/mcp3008/mcp3008.go @@ -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 +} diff --git a/host/bbb/bbb.go b/host/bbb/bbb.go index 2088b69..118cf7d 100644 --- a/host/bbb/bbb.go +++ b/host/bbb/bbb.go @@ -15,6 +15,8 @@ import ( "os" "strings" + "github.com/golang/glog" + "github.com/kidoman/embd" "github.com/kidoman/embd/host/generic" ) @@ -97,6 +99,7 @@ var ledMap = embd.LEDMap{ var spiDeviceMinor = byte(1) func ensureFeatureEnabled(id string) error { + glog.V(3).Infof("bbb: enabling feature %v", id) pattern := "/sys/devices/bone_capemgr.*/slots" file, err := embd.FindFirstMatchingFile(pattern) if err != nil { @@ -108,6 +111,7 @@ func ensureFeatureEnabled(id string) error { } str := string(bytes) if strings.Contains(str, id) { + glog.V(3).Infof("bbb: feature %v already enabled", id) return nil } slots, err := os.OpenFile(file, os.O_WRONLY, os.ModeExclusive) @@ -115,6 +119,7 @@ func ensureFeatureEnabled(id string) error { return err } defer slots.Close() + glog.V(3).Infof("bbb: writing %v to slots file", id) _, err = slots.WriteString(id) return err } diff --git a/host/generic/spibus.go b/host/generic/spibus.go index 661ec3a..9d2d114 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -76,6 +76,10 @@ func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int, shouldIni } func (b *spiBus) init() error { + if b.initialized { + return nil + } + if b.shouldInitialize { if err := b.initializer(); err != nil { return err @@ -83,14 +87,11 @@ func (b *spiBus) init() error { b.shouldInitialize = false } - if b.initialized { - return nil - } - 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 { return err } + glog.V(3).Infof("spi: sucessfully opened file /dev/spidev%v.%v", b.spiDevMinor, b.channel) err = b.setMode() if err != nil { @@ -112,6 +113,7 @@ func (b *spiBus) init() error { b.setDelay() 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 return nil @@ -187,6 +189,10 @@ func (b *spiBus) setDelay() { } func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error { + if err := b.init(); err != nil { + return err + } + len := len(dataBuffer) dataCarrier := b.spiTransferData @@ -194,16 +200,22 @@ func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error { dataCarrier.txBuf = 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))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to read due to %v", err.Error()) return err } + glog.V(3).Infof("spi: read into dataBuffer %v", dataBuffer) return nil } func (b *spiBus) ReceiveData(len int) ([]uint8, error) { + if err := b.init(); err != nil { + return nil, err + } + data := make([]uint8, len) var err error err = b.TransferAndRecieveData(data) @@ -214,6 +226,10 @@ func (b *spiBus) ReceiveData(len int) ([]uint8, error) { } func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) { + if err := b.init(); err != nil { + return 0, err + } + d := make([]uint8, 1) d[0] = uint8(data) err := b.TransferAndRecieveData(d) @@ -224,6 +240,10 @@ func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) { } func (b *spiBus) ReceiveByte() (byte, error) { + if err := b.init(); err != nil { + return 0, err + } + d := make([]uint8, 1) err := b.TransferAndRecieveData(d) if err != nil { diff --git a/samples/.gitignore b/samples/.gitignore index f48626d..af9b180 100644 --- a/samples/.gitignore +++ b/samples/.gitignore @@ -24,3 +24,5 @@ universalblinker us020 watersensor spi +mcp3008 +spimcp3008 diff --git a/samples/mcp3008.go b/samples/mcp3008.go new file mode 100644 index 0000000..252f2d1 --- /dev/null +++ b/samples/mcp3008.go @@ -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) + } + +} diff --git a/samples/spimcp3008.go b/samples/spimcp3008.go new file mode 100644 index 0000000..12b60d8 --- /dev/null +++ b/samples/spimcp3008.go @@ -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 +} diff --git a/spidriver.go b/spidriver.go index f12c86c..bd7ec9d 100644 --- a/spidriver.go +++ b/spidriver.go @@ -29,6 +29,7 @@ func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus { defer s.busMapLock.Unlock() b := s.sbf(s.spiDevMinor, mode, channel, speed, bpw, delay, s.shouldInitialize, s.initializer) + s.busMap = make(map[byte]SPIBus) s.busMap[channel] = b return b } From 41913276327ce67047fb4a7de07057b3d56be148 Mon Sep 17 00:00:00 2001 From: Kunal Powar Date: Wed, 7 May 2014 23:23:29 +0530 Subject: [PATCH 05/17] spi: ignore build for sample codes --- samples/spi.go | 2 ++ samples/spimcp3008.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/samples/spi.go b/samples/spi.go index f23fb0d..0d7b397 100644 --- a/samples/spi.go +++ b/samples/spi.go @@ -1,3 +1,5 @@ +// +build ignore + package main import ( diff --git a/samples/spimcp3008.go b/samples/spimcp3008.go index 12b60d8..4648c80 100644 --- a/samples/spimcp3008.go +++ b/samples/spimcp3008.go @@ -1,3 +1,5 @@ +// +build ignore + package main import ( From 1bb2bac8f1ab3b05c9a9c6e49e0e275b445477b8 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 8 May 2014 23:09:31 +0530 Subject: [PATCH 06/17] spi: variables/method name, err handling changes to follow idiomatic go --- convertors/mcp3008/mcp3008.go | 12 ++++---- host/bbb/bbb.go | 2 +- host/generic/spibus.go | 52 +++++++++++++++++------------------ samples/spi.go | 15 ++++------ samples/spimcp3008.go | 1 - 5 files changed, 37 insertions(+), 45 deletions(-) diff --git a/convertors/mcp3008/mcp3008.go b/convertors/mcp3008/mcp3008.go index 2684c4c..f074a4e 100644 --- a/convertors/mcp3008/mcp3008.go +++ b/convertors/mcp3008/mcp3008.go @@ -8,17 +8,15 @@ import ( ) type mcp3008 struct { - mode int + mode byte bus embd.SPIBus } -const ( - SingleMode = int(1) - DifferenceMode = int(0) -) +var SingleMode byte = 1 +var DifferenceMode byte = 0 -func New(mode, spiChan, speed int) (*mcp3008, error) { +func New(mode byte, spiChan, speed int) (*mcp3008, error) { if err := embd.InitSPI(); err != nil { return nil, err } @@ -28,7 +26,7 @@ func New(mode, spiChan, speed int) (*mcp3008, error) { } func (m *mcp3008) AnalogValueAt(chanNum int) (int, error) { - data := make([]uint8, 3) + var data [3]uint8 data[0] = 1 data[1] = uint8(m.mode)<<7 | uint8(chanNum)<<4 data[2] = 0 diff --git a/host/bbb/bbb.go b/host/bbb/bbb.go index 118cf7d..9c3a6e9 100644 --- a/host/bbb/bbb.go +++ b/host/bbb/bbb.go @@ -96,7 +96,7 @@ var ledMap = embd.LEDMap{ "beaglebone:green:usr3": []string{"3", "USR3", "usr3"}, } -var spiDeviceMinor = byte(1) +var spiDeviceMinor byte = 1 func ensureFeatureEnabled(id string) error { glog.V(3).Infof("bbb: enabling feature %v", id) diff --git a/host/generic/spibus.go b/host/generic/spibus.go index 9d2d114..a41d0e4 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -12,23 +12,23 @@ import ( ) const ( - spiIocWrMode = 0x40016B01 - spiIocWrBitsPerWord = 0x40016B03 - spiIocWrMaxSpeedHz = 0x40046B04 + spiIOCWrMode = 0x40016B01 + spiIOCWrBitsPerWord = 0x40016B03 + spiIOCWrMaxSpeedHz = 0x40046B04 - spiIocRdMode = 0x80016B01 - spiIocRdBitsPerWord = 0x80016B03 - spiIocRdMaxSpeedHz = 0x80046B04 + spiIOCRdMode = 0x80016B01 + spiIOCRdBitsPerWord = 0x80016B03 + spiIOCRdMaxSpeedHz = 0x80046B04 - spiIocMessage0 = 1073769216 //0x40006B00 - spiIocIncrementor = 2097152 //0x200000 + spiIOCMessage0 = 1073769216 //0x40006B00 + spiIOCIncrementor = 2097152 //0x200000 defaultDelayms = uint16(0) - defaultSpiBpw = uint8(8) - defaultSpiSpeed = uint32(1000000) + defaultSPIBPW = uint8(8) + defaultSPISpeed = uint32(1000000) ) -type spiIocTransfer struct { +type spiIOCTransfer struct { txBuf uint64 rxBuf uint64 @@ -51,15 +51,15 @@ type spiBus struct { mu sync.Mutex - spiTransferData spiIocTransfer + spiTransferData spiIOCTransfer initialized bool shouldInitialize bool initializer func() error } -func spiIocMessageN(n uint32) uint32 { - return (spiIocMessage0 + (n * spiIocIncrementor)) +func spiIOCMessageN(n uint32) uint32 { + return (spiIOCMessage0 + (n * spiIOCIncrementor)) } func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int, shouldInitialize bool, i func() error) embd.SPIBus { @@ -98,14 +98,14 @@ func (b *spiBus) init() error { return err } - b.spiTransferData = spiIocTransfer{} + b.spiTransferData = spiIOCTransfer{} err = b.setSpeed() if err != nil { return err } - err = b.setBpw() + err = b.setBPW() if err != nil { return err } @@ -113,7 +113,7 @@ func (b *spiBus) init() error { b.setDelay() 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) + glog.V(3).Infof("spi: bus %v initialized with spiIOCTransfer as %v", b.channel, b.spiTransferData) b.initialized = true return nil @@ -124,7 +124,7 @@ func (b *spiBus) setMode() error { var err error glog.V(3).Infof("spi: setting spi mode to %v", mode) - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIocWrMode, uintptr(unsafe.Pointer(&mode))) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIOCWrMode, uintptr(unsafe.Pointer(&mode))) if errno != 0 { err = syscall.Errno(errno) glog.V(3).Infof("spi: failed to set mode due to %v", err.Error()) @@ -139,11 +139,11 @@ func (b *spiBus) setSpeed() error { if b.speed > 0 { speed = uint32(b.speed) } else { - speed = defaultSpiSpeed + speed = defaultSPISpeed } glog.V(3).Infof("spi: setting spi speedMax to %v", speed) - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIocWrMaxSpeedHz, uintptr(unsafe.Pointer(&speed))) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIOCWrMaxSpeedHz, uintptr(unsafe.Pointer(&speed))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to set speedMax due to %v", err.Error()) @@ -155,17 +155,17 @@ func (b *spiBus) setSpeed() error { return nil } -func (b *spiBus) setBpw() error { +func (b *spiBus) setBPW() error { var bpw uint8 if b.bpw > 0 { bpw = uint8(b.bpw) } else { - bpw = defaultSpiBpw + bpw = defaultSPIBPW } glog.V(3).Infof("spi: setting spi bpw to %v", bpw) - _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIocWrBitsPerWord, uintptr(unsafe.Pointer(&bpw))) + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIOCWrBitsPerWord, uintptr(unsafe.Pointer(&bpw))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to set bpw due to %v", err.Error()) @@ -201,7 +201,7 @@ func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error { 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 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to read due to %v", err.Error()) @@ -217,9 +217,7 @@ func (b *spiBus) ReceiveData(len int) ([]uint8, error) { } data := make([]uint8, len) - var err error - err = b.TransferAndRecieveData(data) - if err != nil { + if err := b.TransferAndRecieveData(data); err != nil { return nil, err } return data, nil diff --git a/samples/spi.go b/samples/spi.go index 0d7b397..8ed81f2 100644 --- a/samples/spi.go +++ b/samples/spi.go @@ -11,9 +11,7 @@ import ( ) func main() { - var err error - err = embd.InitSPI() - if err != nil { + if err := embd.InitSPI(); err != nil { panic(err) } defer embd.CloseSPI() @@ -23,30 +21,29 @@ func main() { dataBuf := []uint8{1, 2, 3} - err = spiBus.TransferAndRecieveData(dataBuf) - if err != nil { + if err := spiBus.TransferAndRecieveData(dataBuf); err != nil { panic(err) } - fmt.Println("Recived data is: %v", dataBuf) + fmt.Println("received data is: %v", dataBuf) dataReceived, err := spiBus.ReceiveData(3) if err != nil { panic(err) } - fmt.Println("Recived data is: %v", dataReceived) + fmt.Println("received data is: %v", dataReceived) dataByte := byte(1) receivedByte, err := spiBus.TransferAndReceiveByte(dataByte) if err != nil { panic(err) } - fmt.Println("Recived byte is: %v", receivedByte) + fmt.Println("received byte is: %v", receivedByte) receivedByte, err = spiBus.ReceiveByte() if err != nil { panic(err) } - fmt.Println("Recived byte is: %v", receivedByte) + fmt.Println("received byte is: %v", receivedByte) } diff --git a/samples/spimcp3008.go b/samples/spimcp3008.go index 4648c80..0f2419b 100644 --- a/samples/spimcp3008.go +++ b/samples/spimcp3008.go @@ -18,7 +18,6 @@ func main() { } bus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0) - defer clean(bus) for i := 0; i < 30; i++ { From dbc97bd15cf0b640e467d958a1ff62ffc7e54953 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 8 May 2014 23:28:29 +0530 Subject: [PATCH 07/17] mcp3008: changes to use external spiBus --- convertors/mcp3008/mcp3008.go | 23 ++++------------------- samples/mcp3008.go | 16 +++++++++++----- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/convertors/mcp3008/mcp3008.go b/convertors/mcp3008/mcp3008.go index f074a4e..7636e29 100644 --- a/convertors/mcp3008/mcp3008.go +++ b/convertors/mcp3008/mcp3008.go @@ -16,35 +16,20 @@ type mcp3008 struct { var SingleMode byte = 1 var DifferenceMode byte = 0 -func New(mode byte, 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 New(mode byte, bus embd.SPIBus) *mcp3008 { + return &mcp3008{mode, bus} } func (m *mcp3008) AnalogValueAt(chanNum int) (int, error) { - var data [3]uint8 + data := make([]uint8, 3) data[0] = 1 data[1] = uint8(m.mode)<<7 | uint8(chanNum)<<4 data[2] = 0 + glog.V(2).Infof("mcp3008: sendingdata buffer %v", data) 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 -} diff --git a/samples/mcp3008.go b/samples/mcp3008.go index 252f2d1..ff2f09f 100644 --- a/samples/mcp3008.go +++ b/samples/mcp3008.go @@ -8,17 +8,23 @@ import ( "time" "github.com/kidoman/embd/convertors/mcp3008" + + "github.com/kidoman/embd" ) func main() { flag.Parse() - fmt.Println("This is a sample code for mcp3008 10bit 8 channel ADC") + fmt.Println("this is a sample code for mcp3008 10bit 8 channel ADC") - adc, err := mcp3008.New(mcp3008.SingleMode, 0, 1000000) - if err != nil { + if err := embd.InitSPI(); err != nil { panic(err) } - defer adc.Close() + defer embd.CloseSPI() + + spiBus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0) + defer spiBus.Close() + + adc := mcp3008.New(mcp3008.SingleMode, spiBus) for i := 0; i < 20; i++ { time.Sleep(1 * time.Second) @@ -27,7 +33,7 @@ func main() { panic(err) } - fmt.Printf("Analog value is: %v\n", val) + fmt.Printf("analog value is: %v\n", val) } } From c42a345a6030a1b7483c818ba24995a70c425ced Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 8 May 2014 23:46:09 +0530 Subject: [PATCH 08/17] spi: added godoc --- spi.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/spi.go b/spi.go index 1bcb918..63ad89e 100644 --- a/spi.go +++ b/spi.go @@ -1,27 +1,44 @@ +// SPI support. + package embd const ( spiCpha = 0x01 spiCpol = 0x02 + // SpiMode0 represents the mode0 operation (CPOL=0 CPHA=0) of spi. SpiMode0 = (0 | 0) + + // SpiMode0 represents the mode0 operation (CPOL=0 CPHA=1) of spi. SpiMode1 = (0 | spiCpha) + + // SpiMode0 represents the mode0 operation (CPOL=1 CPHA=0) of spi. SpiMode2 = (spiCpol | 0) + + // SpiMode0 represents the mode0 operation (CPOL=1 CPHA=1) of spi. SpiMode3 = (spiCpol | spiCpha) ) +// SPI interface allows interaction with the SPI bus. type SPIBus interface { + // TransferAndRecieveData transmits data in a buffer(slice) and receives into it. TransferAndRecieveData(dataBuffer []uint8) error + // ReceiveData receives data of length len into a slice. ReceiveData(len int) ([]uint8, error) + // TransferAndReceiveByte transmits a byte data and receives a byte. TransferAndReceiveByte(data byte) (byte, error) + // ReceiveByte receives a byte data. ReceiveByte() (byte, error) + // Close releases the resources associated with the bus. Close() error } +// SPIDriver interface interacts with the host descriptors to allow us +// control of SPI communication. type SPIDriver interface { Bus(byte, byte, int, int, int) SPIBus @@ -31,6 +48,7 @@ type SPIDriver interface { var spiDriverInitialized bool var spiDriverInstance SPIDriver +// InitSPI initializes the SPI driver. func InitSPI() error { if spiDriverInitialized { return nil @@ -51,10 +69,12 @@ func InitSPI() error { return nil } +// CloseSPI releases resources associated with the SPI driver. func CloseSPI() error { return spiDriverInstance.Close() } +// NewSPIBus returns a SPIBus. func NewSPIBus(mode, channel byte, speed, bpw, delay int) SPIBus { if err := InitSPI(); err != nil { panic(err) From 9206358abe52fa7b2eaaad56a6de3bf7eaceb8ef Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 01:11:14 +0530 Subject: [PATCH 09/17] spi: refactoring for err handling --- host/generic/spibus.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/host/generic/spibus.go b/host/generic/spibus.go index a41d0e4..3b7e6a2 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -230,8 +230,7 @@ func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) { d := make([]uint8, 1) d[0] = uint8(data) - err := b.TransferAndRecieveData(d) - if err != nil { + if err := b.TransferAndRecieveData(d); err != nil { return 0, err } return d[0], nil From f80e6f624d74f6d0ffa5da06c86aa6390a9801c0 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 01:11:45 +0530 Subject: [PATCH 10/17] spi: using defer for cleanup --- samples/spimcp3008.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/samples/spimcp3008.go b/samples/spimcp3008.go index 0f2419b..e35b09d 100644 --- a/samples/spimcp3008.go +++ b/samples/spimcp3008.go @@ -16,9 +16,10 @@ func main() { if err := embd.InitSPI(); err != nil { panic(err) } + defer embd.CloseSPI() bus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0) - defer clean(bus) + defer bus.Close() for i := 0; i < 30; i++ { time.Sleep(1 * time.Second) @@ -28,11 +29,6 @@ func main() { } -func clean(bus embd.SPIBus) { - bus.Close() - embd.CloseSPI() -} - func getSensorValue(bus embd.SPIBus) (uint16, error) { data := make([]uint8, 3) data[0] = 1 From 454eca42d0e6b48738cc49538080a354d048eec7 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 01:21:09 +0530 Subject: [PATCH 11/17] spi: got rid of shouldInitialize arg in spibus (redundant). --- host/bbb/bbb.go | 2 +- host/generic/spibus.go | 32 +++++++++++++------------------- host/rpi/rpi.go | 2 +- spidriver.go | 18 ++++++++---------- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/host/bbb/bbb.go b/host/bbb/bbb.go index 9c3a6e9..4564c72 100644 --- a/host/bbb/bbb.go +++ b/host/bbb/bbb.go @@ -180,7 +180,7 @@ func init() { return embd.NewLEDDriver(ledMap, generic.NewLED) }, SPIDriver: func() embd.SPIDriver { - return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus, true, spiInitializer) + return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus, spiInitializer) }, } }) diff --git a/host/generic/spibus.go b/host/generic/spibus.go index 3b7e6a2..35b3472 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -54,24 +54,22 @@ type spiBus struct { spiTransferData spiIOCTransfer initialized bool - shouldInitialize bool - initializer func() error + initializer func() error } func spiIOCMessageN(n uint32) uint32 { return (spiIOCMessage0 + (n * spiIOCIncrementor)) } -func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int, shouldInitialize bool, i func() error) embd.SPIBus { +func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int, i func() error) embd.SPIBus { return &spiBus{ - spiDevMinor: spiDevMinor, - mode: mode, - channel: channel, - speed: speed, - bpw: bpw, - delayms: delay, - shouldInitialize: shouldInitialize, - initializer: i, + spiDevMinor: spiDevMinor, + mode: mode, + channel: channel, + speed: speed, + bpw: bpw, + delayms: delay, + initializer: i, } } @@ -80,11 +78,10 @@ func (b *spiBus) init() error { return nil } - if b.shouldInitialize { + if b.initializer != nil { if err := b.initializer(); err != nil { return err } - b.shouldInitialize = false } var err error @@ -93,20 +90,17 @@ func (b *spiBus) init() error { } glog.V(3).Infof("spi: sucessfully opened file /dev/spidev%v.%v", b.spiDevMinor, b.channel) - err = b.setMode() - if err != nil { + if err = b.setMode(); err != nil { return err } b.spiTransferData = spiIOCTransfer{} - err = b.setSpeed() - if err != nil { + if err = b.setSpeed(); err != nil { return err } - err = b.setBPW() - if err != nil { + if err = b.setBPW(); err != nil { return err } diff --git a/host/rpi/rpi.go b/host/rpi/rpi.go index ddb0a6c..41db588 100644 --- a/host/rpi/rpi.go +++ b/host/rpi/rpi.go @@ -77,7 +77,7 @@ func init() { return embd.NewLEDDriver(ledMap, generic.NewLED) }, SPIDriver: func() embd.SPIDriver { - return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus, false, nil) + return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus, nil) }, } }) diff --git a/spidriver.go b/spidriver.go index bd7ec9d..91766dd 100644 --- a/spidriver.go +++ b/spidriver.go @@ -2,12 +2,11 @@ package embd import "sync" -type spiBusFactory func(byte, byte, byte, int, int, int, bool, func() error) SPIBus +type spiBusFactory func(byte, byte, byte, int, int, int, func() error) SPIBus type spiDriver struct { - spiDevMinor byte - shouldInitialize bool - initializer func() error + spiDevMinor byte + initializer func() error busMap map[byte]SPIBus busMapLock sync.Mutex @@ -15,12 +14,11 @@ type spiDriver struct { sbf spiBusFactory } -func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory, shouldInitialize bool, i func() error) SPIDriver { +func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory, i func() error) SPIDriver { return &spiDriver{ - spiDevMinor: spiDevMinor, - sbf: sbf, - shouldInitialize: shouldInitialize, - initializer: i, + spiDevMinor: spiDevMinor, + sbf: sbf, + initializer: i, } } @@ -28,7 +26,7 @@ func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus { s.busMapLock.Lock() 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.initializer) s.busMap = make(map[byte]SPIBus) s.busMap[channel] = b return b From 0f231503743be4ce1b8b892a798e3c5c555bda5e Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 01:34:39 +0530 Subject: [PATCH 12/17] spi: removing blank line --- samples/spimcp3008.go | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/spimcp3008.go b/samples/spimcp3008.go index e35b09d..48405e1 100644 --- a/samples/spimcp3008.go +++ b/samples/spimcp3008.go @@ -26,7 +26,6 @@ func main() { val, _ := getSensorValue(bus) fmt.Printf("value is: %v\n", val) } - } func getSensorValue(bus embd.SPIBus) (uint16, error) { From 67d316851a372fc1b2ebea4f04a4c79fe56fff1a Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 02:19:01 +0530 Subject: [PATCH 13/17] spi: finishing touches --- convertors/mcp3008/mcp3008.go | 21 ++++++++++++--------- host/bbb/bbb.go | 1 - host/generic/spibus.go | 31 +++++++++++-------------------- samples/mcp3008.go | 11 ++++++++--- samples/spi.go | 3 +-- samples/spimcp3008.go | 11 +++++++++-- spi.go | 16 ++++++++-------- 7 files changed, 49 insertions(+), 45 deletions(-) diff --git a/convertors/mcp3008/mcp3008.go b/convertors/mcp3008/mcp3008.go index 7636e29..64f6106 100644 --- a/convertors/mcp3008/mcp3008.go +++ b/convertors/mcp3008/mcp3008.go @@ -3,11 +3,10 @@ package mcp3008 import ( "github.com/golang/glog" "github.com/kidoman/embd" - - _ "github.com/kidoman/embd/host/all" ) -type mcp3008 struct { +// MCP3008 represents a mcp3008 8bit DAC +type MCP3008 struct { mode byte bus embd.SPIBus @@ -16,18 +15,22 @@ type mcp3008 struct { var SingleMode byte = 1 var DifferenceMode byte = 0 -func New(mode byte, bus embd.SPIBus) *mcp3008 { - return &mcp3008{mode, bus} +func New(mode byte, bus embd.SPIBus) *MCP3008 { + return &MCP3008{mode, bus} } -func (m *mcp3008) AnalogValueAt(chanNum int) (int, error) { - data := make([]uint8, 3) - data[0] = 1 +const ( + startBit = 1 +) + +func (m *MCP3008) AnalogValueAt(chanNum int) (int, error) { + var data [3]uint8 + data[0] = startBit data[1] = uint8(m.mode)<<7 | uint8(chanNum)<<4 data[2] = 0 glog.V(2).Infof("mcp3008: sendingdata buffer %v", data) - if err := m.bus.TransferAndRecieveData(data); err != nil { + if err := m.bus.TransferAndRecieveData(data[:]); err != nil { return 0, err } diff --git a/host/bbb/bbb.go b/host/bbb/bbb.go index 4564c72..f909627 100644 --- a/host/bbb/bbb.go +++ b/host/bbb/bbb.go @@ -16,7 +16,6 @@ import ( "strings" "github.com/golang/glog" - "github.com/kidoman/embd" "github.com/kidoman/embd/host/generic" ) diff --git a/host/generic/spibus.go b/host/generic/spibus.go index 35b3472..9857a38 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -129,11 +129,9 @@ func (b *spiBus) setMode() error { } func (b *spiBus) setSpeed() error { - var speed uint32 + speed := defaultSPISpeed if b.speed > 0 { speed = uint32(b.speed) - } else { - speed = defaultSPISpeed } glog.V(3).Infof("spi: setting spi speedMax to %v", speed) @@ -150,12 +148,9 @@ func (b *spiBus) setSpeed() error { } func (b *spiBus) setBPW() error { - var bpw uint8 - + bpw := defaultSPIBPW if b.bpw > 0 { bpw = uint8(b.bpw) - } else { - bpw = defaultSPIBPW } glog.V(3).Infof("spi: setting spi bpw to %v", bpw) @@ -171,13 +166,11 @@ func (b *spiBus) setBPW() error { } func (b *spiBus) setDelay() { - var delay uint16 - + delay := defaultDelayms if b.delayms > 0 { delay = uint16(b.delayms) - } else { - delay = defaultDelayms } + glog.V(3).Infof("spi: delayms set to %v", delay) b.spiTransferData.delayus = delay } @@ -210,11 +203,11 @@ func (b *spiBus) ReceiveData(len int) ([]uint8, error) { return nil, err } - data := make([]uint8, len) - if err := b.TransferAndRecieveData(data); err != nil { + var data [len]uint8 + if err := b.TransferAndRecieveData(data[:]); err != nil { return nil, err } - return data, nil + return data[:], nil } func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) { @@ -222,9 +215,8 @@ func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) { return 0, err } - d := make([]uint8, 1) - d[0] = uint8(data) - if err := b.TransferAndRecieveData(d); err != nil { + d := [1]uint8{uint8(data)} + if err := b.TransferAndRecieveData(d[:]); err != nil { return 0, err } return d[0], nil @@ -235,9 +227,8 @@ func (b *spiBus) ReceiveByte() (byte, error) { return 0, err } - d := make([]uint8, 1) - err := b.TransferAndRecieveData(d) - if err != nil { + var d [1]uint8 + if err := b.TransferAndRecieveData(d[:]); err != nil { return 0, err } return byte(d[0]), nil diff --git a/samples/mcp3008.go b/samples/mcp3008.go index ff2f09f..28c8ff6 100644 --- a/samples/mcp3008.go +++ b/samples/mcp3008.go @@ -1,5 +1,6 @@ // +build ignore +// this sample uses the mcp3008 package to interface with the 8-bit ADC and works without code change on bbb and rpi package main import ( @@ -7,9 +8,9 @@ import ( "fmt" "time" - "github.com/kidoman/embd/convertors/mcp3008" - "github.com/kidoman/embd" + "github.com/kidoman/embd/convertors/mcp3008" + _ "github.com/kidoman/embd/host/all" ) func main() { @@ -21,7 +22,11 @@ func main() { } defer embd.CloseSPI() - spiBus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0) + channel := 0 + speed := 1000000 + bpw := 8 + delay := 0 + spiBus := embd.NewSPIBus(embd.SPIMode0, channel, speed, bpw, delay) defer spiBus.Close() adc := mcp3008.New(mcp3008.SingleMode, spiBus) diff --git a/samples/spi.go b/samples/spi.go index 8ed81f2..72ef4f2 100644 --- a/samples/spi.go +++ b/samples/spi.go @@ -6,7 +6,6 @@ import ( "fmt" "github.com/kidoman/embd" - _ "github.com/kidoman/embd/host/all" ) @@ -16,7 +15,7 @@ func main() { } defer embd.CloseSPI() - spiBus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0) + spiBus := embd.NewSPIBus(embd.SPIMode0, 0, 1000000, 8, 0) defer spiBus.Close() dataBuf := []uint8{1, 2, 3} diff --git a/samples/spimcp3008.go b/samples/spimcp3008.go index 48405e1..e862cc6 100644 --- a/samples/spimcp3008.go +++ b/samples/spimcp3008.go @@ -18,12 +18,19 @@ func main() { } defer embd.CloseSPI() - bus := embd.NewSPIBus(embd.SpiMode0, 0, 1000000, 8, 0) + channel := 0 + speed := 1000000 + bpw := 8 + delay := 0 + bus := embd.NewSPIBus(embd.SPIMode0, channel, speed, bpw, delay) defer bus.Close() for i := 0; i < 30; i++ { time.Sleep(1 * time.Second) - val, _ := getSensorValue(bus) + val, err := getSensorValue(bus) + if err != nil { + panic(err) + } fmt.Printf("value is: %v\n", val) } } diff --git a/spi.go b/spi.go index 63ad89e..1568f2d 100644 --- a/spi.go +++ b/spi.go @@ -6,17 +6,17 @@ const ( spiCpha = 0x01 spiCpol = 0x02 - // SpiMode0 represents the mode0 operation (CPOL=0 CPHA=0) of spi. - SpiMode0 = (0 | 0) + // SPIMode0 represents the mode0 operation (CPOL=0 CPHA=0) of spi. + SPIMode0 = (0 | 0) - // SpiMode0 represents the mode0 operation (CPOL=0 CPHA=1) of spi. - SpiMode1 = (0 | spiCpha) + // SPIMode1 represents the mode0 operation (CPOL=0 CPHA=1) of spi. + SPIMode1 = (0 | spiCpha) - // SpiMode0 represents the mode0 operation (CPOL=1 CPHA=0) of spi. - SpiMode2 = (spiCpol | 0) + // SPIMode2 represents the mode0 operation (CPOL=1 CPHA=0) of spi. + SPIMode2 = (spiCpol | 0) - // SpiMode0 represents the mode0 operation (CPOL=1 CPHA=1) of spi. - SpiMode3 = (spiCpol | spiCpha) + // SPIMode3 represents the mode0 operation (CPOL=1 CPHA=1) of spi. + SPIMode3 = (spiCpol | spiCpha) ) // SPI interface allows interaction with the SPI bus. From 2d3dee87645a5b25e6c1a1a6378c49f08adee6c7 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 02:31:42 +0530 Subject: [PATCH 14/17] spi: more refactoring --- samples/mcp3008.go | 2 -- samples/spi.go | 4 ++-- samples/spimcp3008.go | 8 +++----- spi.go | 2 ++ spidriver.go | 4 ++++ 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/samples/mcp3008.go b/samples/mcp3008.go index 28c8ff6..368d9ee 100644 --- a/samples/mcp3008.go +++ b/samples/mcp3008.go @@ -37,8 +37,6 @@ func main() { if err != nil { panic(err) } - fmt.Printf("analog value is: %v\n", val) } - } diff --git a/samples/spi.go b/samples/spi.go index 72ef4f2..1f702b2 100644 --- a/samples/spi.go +++ b/samples/spi.go @@ -18,9 +18,9 @@ func main() { spiBus := embd.NewSPIBus(embd.SPIMode0, 0, 1000000, 8, 0) defer spiBus.Close() - dataBuf := []uint8{1, 2, 3} + dataBuf := [3]uint8{1, 2, 3} - if err := spiBus.TransferAndRecieveData(dataBuf); err != nil { + if err := spiBus.TransferAndRecieveData(dataBuf[:]); err != nil { panic(err) } diff --git a/samples/spimcp3008.go b/samples/spimcp3008.go index e862cc6..045106c 100644 --- a/samples/spimcp3008.go +++ b/samples/spimcp3008.go @@ -36,12 +36,10 @@ func main() { } func getSensorValue(bus embd.SPIBus) (uint16, error) { - data := make([]uint8, 3) - data[0] = 1 - data[1] = 128 - data[2] = 0 + data := [3]uint8{1, 128, 0} + var err error - err = bus.TransferAndRecieveData(data) + err = bus.TransferAndRecieveData(data[:]) if err != nil { return uint16(0), err } diff --git a/spi.go b/spi.go index 1568f2d..1cc50e0 100644 --- a/spi.go +++ b/spi.go @@ -40,8 +40,10 @@ type SPIBus interface { // SPIDriver interface interacts with the host descriptors to allow us // control of SPI communication. type SPIDriver interface { + // Bus returns a SPIBus interface which allows us to use spi functionalities Bus(byte, byte, int, int, int) SPIBus + // Close cleans up all the initialized SPIbus Close() error } diff --git a/spidriver.go b/spidriver.go index 91766dd..cecc19d 100644 --- a/spidriver.go +++ b/spidriver.go @@ -14,6 +14,8 @@ type spiDriver struct { sbf spiBusFactory } +// NewSPIDriver returns a SPIDriver interface which allows control +// over the SPI bus. func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory, i func() error) SPIDriver { return &spiDriver{ spiDevMinor: spiDevMinor, @@ -22,6 +24,7 @@ func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory, i func() error) SPIDriver } } +// Bus returns a SPIBus interface which allows us to use spi functionalities func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus { s.busMapLock.Lock() defer s.busMapLock.Unlock() @@ -32,6 +35,7 @@ func (s *spiDriver) Bus(mode, channel byte, speed, bpw, delay int) SPIBus { return b } +// Close cleans up all the initialized SPIbus func (s *spiDriver) Close() error { for _, b := range s.busMap { b.Close() From 32c9a96af5c47387597c8334c417c71f4a122318 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 02:58:15 +0530 Subject: [PATCH 15/17] spi: remove types from const declarations and added few more go docs --- convertors/mcp3008/mcp3008.go | 21 ++++++++++++++------- host/generic/spibus.go | 15 +++++++-------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/convertors/mcp3008/mcp3008.go b/convertors/mcp3008/mcp3008.go index 64f6106..716d437 100644 --- a/convertors/mcp3008/mcp3008.go +++ b/convertors/mcp3008/mcp3008.go @@ -5,16 +5,22 @@ import ( "github.com/kidoman/embd" ) -// MCP3008 represents a mcp3008 8bit DAC +// MCP3008 represents a mcp3008 8bit DAC. type MCP3008 struct { - mode byte + Mode byte - bus embd.SPIBus + Bus embd.SPIBus } -var SingleMode byte = 1 -var DifferenceMode byte = 0 +const ( + // SingleMode represents the single-ended mode for the mcp3008. + SingleMode = 1 + // DifferenceMode represents the diffenrential mode for the mcp3008. + DifferenceMode = 0 +) + +// New creates a representation of the mcp3008 convertor func New(mode byte, bus embd.SPIBus) *MCP3008 { return &MCP3008{mode, bus} } @@ -23,14 +29,15 @@ const ( startBit = 1 ) +// AnalogValueAt returns the analog value at the given channel of the convertor. func (m *MCP3008) AnalogValueAt(chanNum int) (int, error) { var data [3]uint8 data[0] = startBit - data[1] = uint8(m.mode)<<7 | uint8(chanNum)<<4 + data[1] = uint8(m.Mode)<<7 | uint8(chanNum)<<4 data[2] = 0 glog.V(2).Infof("mcp3008: sendingdata buffer %v", data) - if err := m.bus.TransferAndRecieveData(data[:]); err != nil { + if err := m.Bus.TransferAndRecieveData(data[:]); err != nil { return 0, err } diff --git a/host/generic/spibus.go b/host/generic/spibus.go index 9857a38..a90fb0c 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -23,9 +23,9 @@ const ( spiIOCMessage0 = 1073769216 //0x40006B00 spiIOCIncrementor = 2097152 //0x200000 - defaultDelayms = uint16(0) - defaultSPIBPW = uint8(8) - defaultSPISpeed = uint32(1000000) + defaultDelayms = 0 + defaultSPIBPW = 8 + defaultSPISpeed = 1000000 ) type spiIOCTransfer struct { @@ -115,12 +115,11 @@ func (b *spiBus) init() error { func (b *spiBus) setMode() error { var mode = uint8(b.mode) - var err error glog.V(3).Infof("spi: setting spi mode to %v", mode) _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIOCWrMode, uintptr(unsafe.Pointer(&mode))) if errno != 0 { - err = syscall.Errno(errno) + err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to set mode due to %v", err.Error()) return err } @@ -129,7 +128,7 @@ func (b *spiBus) setMode() error { } func (b *spiBus) setSpeed() error { - speed := defaultSPISpeed + var speed uint32 = defaultSPISpeed if b.speed > 0 { speed = uint32(b.speed) } @@ -148,7 +147,7 @@ func (b *spiBus) setSpeed() error { } func (b *spiBus) setBPW() error { - bpw := defaultSPIBPW + var bpw uint8 = defaultSPIBPW if b.bpw > 0 { bpw = uint8(b.bpw) } @@ -166,7 +165,7 @@ func (b *spiBus) setBPW() error { } func (b *spiBus) setDelay() { - delay := defaultDelayms + var delay uint16 = defaultDelayms if b.delayms > 0 { delay = uint16(b.delayms) } From 5965ddf789c2bef85977ebe53cc8a53ec652a341 Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 03:03:22 +0530 Subject: [PATCH 16/17] spi: fix for breaking build --- host/generic/spibus.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/host/generic/spibus.go b/host/generic/spibus.go index a90fb0c..e00150c 100644 --- a/host/generic/spibus.go +++ b/host/generic/spibus.go @@ -202,11 +202,11 @@ func (b *spiBus) ReceiveData(len int) ([]uint8, error) { return nil, err } - var data [len]uint8 - if err := b.TransferAndRecieveData(data[:]); err != nil { + data := make([]uint8, len) + if err := b.TransferAndRecieveData(data); err != nil { return nil, err } - return data[:], nil + return data, nil } func (b *spiBus) TransferAndReceiveByte(data byte) (byte, error) { From bb82613c6464897802d04f74ca92cad94d9466ad Mon Sep 17 00:00:00 2001 From: kunalpowar Date: Thu, 22 May 2014 03:14:33 +0530 Subject: [PATCH 17/17] spi: code fixes in samples --- samples/mcp3008.go | 11 +++++++---- samples/spimcp3008.go | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/samples/mcp3008.go b/samples/mcp3008.go index 368d9ee..791d56a 100644 --- a/samples/mcp3008.go +++ b/samples/mcp3008.go @@ -13,6 +13,13 @@ import ( _ "github.com/kidoman/embd/host/all" ) +const ( + channel = 0 + speed = 1000000 + bpw = 8 + delay = 0 +) + func main() { flag.Parse() fmt.Println("this is a sample code for mcp3008 10bit 8 channel ADC") @@ -22,10 +29,6 @@ func main() { } defer embd.CloseSPI() - channel := 0 - speed := 1000000 - bpw := 8 - delay := 0 spiBus := embd.NewSPIBus(embd.SPIMode0, channel, speed, bpw, delay) defer spiBus.Close() diff --git a/samples/spimcp3008.go b/samples/spimcp3008.go index 045106c..efff661 100644 --- a/samples/spimcp3008.go +++ b/samples/spimcp3008.go @@ -11,6 +11,13 @@ import ( _ "github.com/kidoman/embd/host/all" ) +const ( + channel = 0 + speed = 1000000 + bpw = 8 + delay = 0 +) + func main() { flag.Parse() if err := embd.InitSPI(); err != nil { @@ -18,10 +25,6 @@ func main() { } defer embd.CloseSPI() - channel := 0 - speed := 1000000 - bpw := 8 - delay := 0 bus := embd.NewSPIBus(embd.SPIMode0, channel, speed, bpw, delay) defer bus.Close()