mirror of
https://github.com/kidoman/embd
synced 2025-03-12 11:13:15 +01:00
Merge pull request #69 from kidoman/update
Add support for CHIP; merge piled-up PRs
This commit is contained in:
commit
adc3d47305
@ -5,11 +5,10 @@ branches:
|
|||||||
- go-rpi
|
- go-rpi
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.2.2
|
- 1.6
|
||||||
- 1.3.3
|
- 1.7
|
||||||
- 1.4
|
|
||||||
- tip
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- go test -bench=. -v ./... | grep -v 'no test files' ; test ${PIPESTATUS[0]} -eq 0
|
- go test -bench=. -v ./... | grep -v 'no test files' ; test ${PIPESTATUS[0]} -eq 0
|
||||||
- cd samples; find . -name "*.go" -print0 | xargs -0 -n1 go build
|
- cd samples; find . -name "*.go" -print0 | xargs -0 -n1 go build
|
||||||
|
- cd ../embd; go build .
|
||||||
|
15
CONTRIBUTORS
15
CONTRIBUTORS
@ -1,8 +1,17 @@
|
|||||||
Karan Misra <kidoman@gmail.com>
|
adeschamps <anthony.j.deschamps@gmail.com>
|
||||||
|
alsm <asm@rndm.io>
|
||||||
|
Al S-M <asm@rndm.io>
|
||||||
|
Ben Delarre <ben@delarre.net>
|
||||||
|
Ben Schwartz <benschw@gmail.com>
|
||||||
|
Gavin Cabbage <gavincabbage@gmail.com>
|
||||||
|
gotang <gotang@foxmail.com>
|
||||||
Kashyap Kopparam <kashyapkopparam@gmail.com>
|
Kashyap Kopparam <kashyapkopparam@gmail.com>
|
||||||
Kunal Powar <kunalpowar1203@gmail.com>
|
Kunal Powar <kunalpowar1203@gmail.com>
|
||||||
Marco P. Monteiro <marco_monteiro@sv.comcast.com>
|
Marco P. Monteiro <marco_monteiro@sv.comcast.com>
|
||||||
|
Matthew Dale <matthew@matthewrdale.com>
|
||||||
Nikesh Vora <nikesh.voratp@gmail.com>
|
Nikesh Vora <nikesh.voratp@gmail.com>
|
||||||
|
SjB <steve@sagacity.ca>
|
||||||
Steve Beaulac <steve@beaulac.me>
|
Steve Beaulac <steve@beaulac.me>
|
||||||
Al S-M <asm@rndm.io>
|
Thorsten von Eicken <tve@rightscale.com>
|
||||||
Ben Delarre <ben@delarre.net>
|
wiless <wiless.bytes@gmail.com>
|
||||||
|
Wu Jiang <wu@morediff.info>
|
||||||
|
61
README.md
61
README.md
@ -2,9 +2,24 @@
|
|||||||
|
|
||||||
**embd** is a hardware abstraction layer (HAL) for embedded systems.
|
**embd** is a hardware abstraction layer (HAL) for embedded systems.
|
||||||
|
|
||||||
It allows you to start your hardware hack on easily available hobby boards (like the Raspberry Pi, BeagleBone Black, etc.) by giving you staight forward access to the board's capabilities as well as a plethora of **sensors** (like accelerometers, gyroscopes, thermometers, etc.) and **controllers** (PWM generators, digital-to-analog convertors) for which we have written drivers. And when things get serious, you dont have to throw away the code. You carry forward the effort onto more custom designed boards where the HAL abstraction of EMBD will save you precious time.
|
It allows you to start your hardware hack on easily available hobby boards
|
||||||
|
(like the Raspberry Pi, BeagleBone Black, C.H.I.P., etc.) by giving you
|
||||||
|
straight-forward access to the board's capabilities as well as a plethora of
|
||||||
|
**sensors** (like accelerometers, gyroscopes, thermometers, etc.) and
|
||||||
|
**controllers** (PWM generators, digital-to-analog convertors) for
|
||||||
|
which it includes drivers. If you move to custom designed boards
|
||||||
|
you have to throw away your code: you carry forward the effort
|
||||||
|
where the HAL abstraction of EMBD will save you precious time.
|
||||||
|
|
||||||
Development supported and sponsored by [**SoStronk**](https://www.sostronk.com) and [**ThoughtWorks**](http://www.thoughtworks.com/)
|
The overall strategy used in embd is to use Linux device drivers to access gpio pins,
|
||||||
|
SPI and I2C buses, as well as interrupts. This makes it easy to port from one platform
|
||||||
|
to another and it enables kernel code to handle the devices as efficiently as possible.
|
||||||
|
What embd then adds is first a Golang library interface on top of the various Linux
|
||||||
|
devices and then another layer of user-level drivers for specific sensors and controllers
|
||||||
|
that are connected to gpio pins or one of the buses.
|
||||||
|
|
||||||
|
Development supported and sponsored by [**SoStronk**](https://www.sostronk.com) and
|
||||||
|
[**ThoughtWorks**](http://www.thoughtworks.com/).
|
||||||
|
|
||||||
Also, you might be interested in: [Why Golang?](https://github.com/kidoman/embd/wiki/Why-Go)
|
Also, you might be interested in: [Why Golang?](https://github.com/kidoman/embd/wiki/Why-Go)
|
||||||
|
|
||||||
@ -12,7 +27,9 @@ Also, you might be interested in: [Why Golang?](https://github.com/kidoman/embd/
|
|||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
After installing Go* and setting up your [GOPATH](http://golang.org/doc/code.html#GOPATH), create your first .go file. We'll call it ```simpleblinker.go```.
|
Install Go version 1.6 or later to make compiling for ARM easy.
|
||||||
|
The set up your [GOPATH](http://golang.org/doc/code.html#GOPATH),
|
||||||
|
and create your first .go file. We'll call it `simpleblinker.go`.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@ -32,11 +49,11 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Then install the EMBD package (go1.2 and greater is required):
|
Then install the EMBD package:
|
||||||
|
|
||||||
$ go get github.com/kidoman/embd
|
$ go get github.com/kidoman/embd
|
||||||
|
|
||||||
Build the binary*:
|
Build the binary for linux/ARM:
|
||||||
|
|
||||||
$ export GOOS=linux
|
$ export GOOS=linux
|
||||||
$ export GOARCH=arm
|
$ export GOARCH=arm
|
||||||
@ -46,7 +63,7 @@ Copy the cross-compiled binary to your RaspberryPi*:
|
|||||||
|
|
||||||
$ scp simpleblinker pi@192.168.2.2:~
|
$ scp simpleblinker pi@192.168.2.2:~
|
||||||
|
|
||||||
Then run the program with ```sudo```*:
|
Then on the rPi run the program with ```sudo```*:
|
||||||
|
|
||||||
$ sudo ./simpleblinker
|
$ sudo ./simpleblinker
|
||||||
|
|
||||||
@ -54,25 +71,21 @@ Then run the program with ```sudo```*:
|
|||||||
|
|
||||||
**<nowiki>*</nowiki> Notes**
|
**<nowiki>*</nowiki> Notes**
|
||||||
|
|
||||||
* Please install the cross compilers. Mac users: ```brew install go --cross-compile-common```. [goxc](https://github.com/laher/goxc) can be a big help as well
|
|
||||||
* We are instructing the ```go``` compiler to create a binary which will run on the RaspberryPi processor
|
|
||||||
* Assuming your RaspberryPi has an IP address of ```192.168.2.2```. Substitute as necessary
|
* Assuming your RaspberryPi has an IP address of ```192.168.2.2```. Substitute as necessary
|
||||||
* ```sudo``` (root) permission is required as we are controlling the hardware by writing to special files
|
* `sudo` (root) permission is required as we are controlling the hardware by writing to special files
|
||||||
* This sample program is optimized for brevity and does not clean up after itself. Click here to see the [full version](https://github.com/kidoman/embd/blob/master/samples/fullblinker.go)
|
* This sample program is optimized for brevity and does not clean up after itself. Click here to
|
||||||
|
see the [full version](https://github.com/kidoman/embd/blob/master/samples/fullblinker.go)
|
||||||
|
|
||||||
## Getting Help
|
## Getting Help
|
||||||
|
|
||||||
Join the [mailing list](https://groups.google.com/forum/#!forum/go-embd)
|
Join the [slack channel](https://gophers.slack.com/archives/embd)
|
||||||
|
|
||||||
## Platforms Supported
|
## Platforms Supported
|
||||||
|
|
||||||
* [RaspberryPi](http://www.raspberrypi.org/) (including [A+](http://www.raspberrypi.org/products/model-a-plus/) and [B+](http://www.raspberrypi.org/products/model-b-plus/))
|
* [RaspberryPi](http://www.raspberrypi.org/) (including [A+](http://www.raspberrypi.org/products/model-a-plus/) and [B+](http://www.raspberrypi.org/products/model-b-plus/))
|
||||||
* [RaspberryPi 2](http://www.raspberrypi.org/)
|
* [RaspberryPi 2](http://www.raspberrypi.org/)
|
||||||
|
* [NextThing C.H.I.P](https://www.nextthing.co/pages/chip)
|
||||||
* [BeagleBone Black](http://beagleboard.org/Products/BeagleBone%20Black)
|
* [BeagleBone Black](http://beagleboard.org/Products/BeagleBone%20Black)
|
||||||
* [Intel Edison](http://www.intel.com/content/www/us/en/do-it-yourself/galileo-maker-quark-board.html) **coming soon**
|
|
||||||
* [Radxa](http://radxa.com/) **coming soon**
|
|
||||||
* [Cubietruck](http://www.cubietruck.com/) **coming soon**
|
|
||||||
* Bring Your Own **coming soon**
|
|
||||||
|
|
||||||
## The command line tool
|
## The command line tool
|
||||||
|
|
||||||
@ -80,8 +93,6 @@ Join the [mailing list](https://groups.google.com/forum/#!forum/go-embd)
|
|||||||
|
|
||||||
will install a command line utility ```embd``` which will allow you to quickly get started with prototyping. The binary should be available in your ```$GOPATH/bin```. However, to be able to run this on a ARM based device, you will need to build it with ```GOOS=linux``` and ```GOARCH=arm``` environment variables set.
|
will install a command line utility ```embd``` which will allow you to quickly get started with prototyping. The binary should be available in your ```$GOPATH/bin```. However, to be able to run this on a ARM based device, you will need to build it with ```GOOS=linux``` and ```GOARCH=arm``` environment variables set.
|
||||||
|
|
||||||
But, since I am feeling so generous, a prebuilt/tested version is available for direct download and deployment [here](https://dl.dropboxusercontent.com/u/6727135/Binaries/embd/linux-arm/embd).
|
|
||||||
|
|
||||||
For example, if you run ```embd detect``` on a **BeagleBone Black**:
|
For example, if you run ```embd detect``` on a **BeagleBone Black**:
|
||||||
|
|
||||||
root@beaglebone:~# embd detect
|
root@beaglebone:~# embd detect
|
||||||
@ -214,17 +225,11 @@ platforms.
|
|||||||
## Sensors Supported
|
## Sensors Supported
|
||||||
|
|
||||||
* **TMP006** Thermopile sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/tmp006), [Datasheet](http://www.adafruit.com/datasheets/tmp006.pdf), [Userguide](http://www.adafruit.com/datasheets/tmp006ug.pdf)
|
* **TMP006** Thermopile sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/tmp006), [Datasheet](http://www.adafruit.com/datasheets/tmp006.pdf), [Userguide](http://www.adafruit.com/datasheets/tmp006ug.pdf)
|
||||||
|
|
||||||
* **BMP085** Barometric pressure sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/bmp085), [Datasheet](https://www.sparkfun.com/datasheets/Components/General/BST-BMP085-DS000-05.pdf)
|
* **BMP085** Barometric pressure sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/bmp085), [Datasheet](https://www.sparkfun.com/datasheets/Components/General/BST-BMP085-DS000-05.pdf)
|
||||||
|
|
||||||
* **BMP180** Barometric pressure sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/bmp180), [Datasheet](http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf)
|
* **BMP180** Barometric pressure sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/bmp180), [Datasheet](http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf)
|
||||||
|
|
||||||
* **LSM303** Accelerometer and magnetometer [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/lsm303), [Datasheet](https://www.sparkfun.com/datasheets/Sensors/Magneto/LSM303%20Datasheet.pdf)
|
* **LSM303** Accelerometer and magnetometer [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/lsm303), [Datasheet](https://www.sparkfun.com/datasheets/Sensors/Magneto/LSM303%20Datasheet.pdf)
|
||||||
|
|
||||||
* **L3GD20** Gyroscope [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/l3gd20), [Datasheet](http://www.adafruit.com/datasheets/L3GD20.pdf)
|
* **L3GD20** Gyroscope [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/l3gd20), [Datasheet](http://www.adafruit.com/datasheets/L3GD20.pdf)
|
||||||
|
|
||||||
* **US020** Ultrasonic proximity sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/us020), [Product Page](http://www.digibay.in/sensor/object-detection-and-proximity?product_id=239)
|
* **US020** Ultrasonic proximity sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/us020), [Product Page](http://www.digibay.in/sensor/object-detection-and-proximity?product_id=239)
|
||||||
|
|
||||||
* **BH1750FVI** Luminosity sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/bh1750fvi), [Datasheet](http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf)
|
* **BH1750FVI** Luminosity sensor [Documentation](http://godoc.org/github.com/kidoman/embd/sensor/bh1750fvi), [Datasheet](http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf)
|
||||||
|
|
||||||
## Interfaces
|
## Interfaces
|
||||||
@ -234,9 +239,7 @@ platforms.
|
|||||||
## Controllers
|
## Controllers
|
||||||
|
|
||||||
* **PCA9685** 16-channel, 12-bit PWM Controller with I2C protocol [Documentation](http://godoc.org/github.com/kidoman/embd/controller/pca9685), [Datasheet](http://www.adafruit.com/datasheets/PCA9685.pdf), [Product Page](http://www.adafruit.com/products/815)
|
* **PCA9685** 16-channel, 12-bit PWM Controller with I2C protocol [Documentation](http://godoc.org/github.com/kidoman/embd/controller/pca9685), [Datasheet](http://www.adafruit.com/datasheets/PCA9685.pdf), [Product Page](http://www.adafruit.com/products/815)
|
||||||
|
|
||||||
* **MCP4725** 12-bit DAC [Documentation](http://godoc.org/github.com/kidoman/embd/controller/mcp4725), [Datasheet](http://www.adafruit.com/datasheets/mcp4725.pdf), [Product Page](http://www.adafruit.com/products/935)
|
* **MCP4725** 12-bit DAC [Documentation](http://godoc.org/github.com/kidoman/embd/controller/mcp4725), [Datasheet](http://www.adafruit.com/datasheets/mcp4725.pdf), [Product Page](http://www.adafruit.com/products/935)
|
||||||
|
|
||||||
* **ServoBlaster** RPi PWM/PCM based PWM controller [Documentation](http://godoc.org/github.com/kidoman/embd/controller/servoblaster), [Product Page](https://github.com/richardghirst/PiBits/tree/master/ServoBlaster)
|
* **ServoBlaster** RPi PWM/PCM based PWM controller [Documentation](http://godoc.org/github.com/kidoman/embd/controller/servoblaster), [Product Page](https://github.com/richardghirst/PiBits/tree/master/ServoBlaster)
|
||||||
|
|
||||||
## Convertors
|
## Convertors
|
||||||
@ -245,9 +248,11 @@ platforms.
|
|||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We look forward to your pull requests, but contributions which abide by the [guidelines](https://github.com/kidoman/embd/blob/master/CONTRIBUTING.md) will get a free beer!
|
[Pull requests](https://github.com/kidoman/embd/pulls) that follow the
|
||||||
|
[guidelines](https://github.com/kidoman/embd/blob/master/CONTRIBUTING.md) are very appreciated.
|
||||||
File an [issue](https://github.com/kidoman/embd/issues), open a [pull request](https://github.com/kidoman/embd/pulls). We are waiting.
|
If you find a problem but are not up to coding a fix please file an
|
||||||
|
[issue](https://github.com/kidoman/embd/issues).
|
||||||
|
Thank you!
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
|
2
controller/doc.go
Normal file
2
controller/doc.go
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// Package controller is a container for the various device controllers supported by EMBD.
|
||||||
|
package controller
|
@ -131,6 +131,7 @@ type mockI2CBus struct {
|
|||||||
closed bool
|
closed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bus *mockI2CBus) ReadBytes(addr byte, num int) ([]byte, error) { return []byte{0x00}, nil }
|
||||||
func (bus *mockI2CBus) ReadByte(addr byte) (byte, error) { return 0x00, nil }
|
func (bus *mockI2CBus) ReadByte(addr byte) (byte, error) { return 0x00, nil }
|
||||||
func (bus *mockI2CBus) WriteBytes(addr byte, value []byte) error { return nil }
|
func (bus *mockI2CBus) WriteBytes(addr byte, value []byte) error { return nil }
|
||||||
func (bus *mockI2CBus) ReadFromReg(addr, reg byte, value []byte) error { return nil }
|
func (bus *mockI2CBus) ReadFromReg(addr, reg byte, value []byte) error { return nil }
|
||||||
|
16
detect.go
16
detect.go
@ -31,6 +31,9 @@ const (
|
|||||||
|
|
||||||
// HostRadxa represents the Radxa board.
|
// HostRadxa represents the Radxa board.
|
||||||
HostRadxa = "Radxa"
|
HostRadxa = "Radxa"
|
||||||
|
|
||||||
|
// HostCHIP represents the NextThing C.H.I.P.
|
||||||
|
HostCHIP = "CHIP"
|
||||||
)
|
)
|
||||||
|
|
||||||
func execOutput(name string, arg ...string) (output string, err error) {
|
func execOutput(name string, arg ...string) (output string, err error) {
|
||||||
@ -92,7 +95,7 @@ func cpuInfo() (model, hardware string, revision int, err error) {
|
|||||||
}
|
}
|
||||||
revision = int(rev)
|
revision = int(rev)
|
||||||
case strings.HasPrefix(fields[0], "Hardware"):
|
case strings.HasPrefix(fields[0], "Hardware"):
|
||||||
hardware = fields[1]
|
hardware = strings.TrimSpace(fields[1])
|
||||||
case strings.HasPrefix(fields[0], "model name"):
|
case strings.HasPrefix(fields[0], "model name"):
|
||||||
model = fields[1]
|
model = fields[1]
|
||||||
}
|
}
|
||||||
@ -108,7 +111,9 @@ func DetectHost() (host Host, rev int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if major < 3 || (major == 3 && minor < 8) {
|
if major < 3 || (major == 3 && minor < 8) {
|
||||||
return HostNull, 0, fmt.Errorf("embd: linux kernel versions lower than 3.8 are not supported. you have %v.%v.%v", major, minor, patch)
|
return HostNull, 0, fmt.Errorf(
|
||||||
|
"embd: linux kernel versions lower than 3.8 are not supported, "+
|
||||||
|
"you have %v.%v.%v", major, minor, patch)
|
||||||
}
|
}
|
||||||
|
|
||||||
model, hardware, rev, err := cpuInfo()
|
model, hardware, rev, err := cpuInfo()
|
||||||
@ -121,6 +126,13 @@ func DetectHost() (host Host, rev int, err error) {
|
|||||||
return HostBBB, rev, nil
|
return HostBBB, rev, nil
|
||||||
case strings.Contains(hardware, "BCM2708") || strings.Contains(hardware, "BCM2709"):
|
case strings.Contains(hardware, "BCM2708") || strings.Contains(hardware, "BCM2709"):
|
||||||
return HostRPi, rev, nil
|
return HostRPi, rev, nil
|
||||||
|
case hardware == "Allwinner sun4i/sun5i Families":
|
||||||
|
if major < 4 || (major == 4 && minor < 4) {
|
||||||
|
return HostNull, 0, fmt.Errorf(
|
||||||
|
"embd: linux kernel version 4.4+ required, you have %v.%v",
|
||||||
|
major, minor)
|
||||||
|
}
|
||||||
|
return HostCHIP, rev, nil
|
||||||
default:
|
default:
|
||||||
return HostNull, 0, fmt.Errorf(`embd: your host "%v:%v" is not supported at this moment. request support at https://github.com/kidoman/embd/issues`, host, model)
|
return HostNull, 0, fmt.Errorf(`embd: your host "%v:%v" is not supported at this moment. request support at https://github.com/kidoman/embd/issues`, host, model)
|
||||||
}
|
}
|
||||||
|
169
doc.go
169
doc.go
@ -1,88 +1,119 @@
|
|||||||
/*
|
/*
|
||||||
Package embd provides a hardware abstraction layer for doing embedded programming
|
Package embd provides a hardware abstraction layer for doing embedded programming
|
||||||
on supported platforms like the Raspberry Pi and BeagleBone Black. Most of the examples below
|
on supported platforms like the Raspberry Pi, BeagleBone Black and CHIP. Most of the examples below
|
||||||
will work without change (i.e. the same binary) on all supported platforms. How cool is that?
|
will work without change (i.e. the same binary) on all supported platforms.
|
||||||
|
|
||||||
Although samples are all present in the samples folder, we will show a few choice examples here.
|
== Overall structure
|
||||||
|
|
||||||
Use the LED driver to toggle LEDs on the BBB:
|
It's best to think of the top-level embd package as a switchboard that doesn't implement anything
|
||||||
|
on its own but rather relies on sub-packages for hosts drivers and devices and stitches them
|
||||||
|
together. The exports in the top-level package serve a number of different purposes,
|
||||||
|
which can be confusing at first:
|
||||||
|
- it defines a number of driver interfaces, such as the GPIODriver, this is the interface that
|
||||||
|
the driver for each specific platform must implement and is not something of concern to the
|
||||||
|
typical user.
|
||||||
|
- it defines the main low-level hardware interface types: analog pins, digital pins,
|
||||||
|
interrupt pins, I2Cbuses, SPI buses, PWM pins and LEDs. Each type has a New function to
|
||||||
|
instantiate one of these pins or buses.
|
||||||
|
- it defines a number of InitXXX functions that initialize the various drivers, however, these
|
||||||
|
are called by the coresponding NewXXX functions, so can be ignored.
|
||||||
|
- it defines a number of top-level convenience functions, such as DigitalWrite, that can be
|
||||||
|
called as 1-liners instead of first instantiating a DigitalPin and then writing to it
|
||||||
|
|
||||||
import "github.com/kidoman/embd"
|
To get started a host driver needs to be registered with the top-level embd package. This is
|
||||||
...
|
most easily accomplished by doing an "underscore import" on of the sub-packages of embd/host,
|
||||||
embd.InitLED()
|
e.g., `import _ "github.com/kidoman/embd/host/chip"`. An `Init()` function in the host driver
|
||||||
defer embd.CloseLED()
|
registers all the individual drivers with embd.
|
||||||
...
|
|
||||||
led, err := embd.NewLED("USR3")
|
|
||||||
...
|
|
||||||
led.Toggle()
|
|
||||||
|
|
||||||
Even shorter while prototyping:
|
After getting the host driver the next step might be to instantiate a GPIO pin using
|
||||||
|
`NewDigitalPin` or an I2CBus using `NewI2CBus`. Such a pin or bus can be used directly but
|
||||||
|
often it is passed into the initializer of a sensor, controller or other user-level driver
|
||||||
|
which provides a high-level interface to some device. For example, the New function
|
||||||
|
for the BMP180 type in the `embd/sensor/bmp180` package takes an I2CBus as argument, which
|
||||||
|
it will use to reach the sensor.
|
||||||
|
|
||||||
import "github.com/kidoman/embd"
|
== Samples
|
||||||
...
|
|
||||||
embd.InitLED()
|
|
||||||
defer embd.CloseLED()
|
|
||||||
...
|
|
||||||
embd.ToggleLED(3)
|
|
||||||
|
|
||||||
BBB + PWM:
|
This section shows a few choice samples, more are available in the samples folder.
|
||||||
|
|
||||||
import "github.com/kidoman/embd"
|
Use the LED driver to toggle LEDs on the BBB:
|
||||||
...
|
|
||||||
embd.InitGPIO()
|
|
||||||
defer embd.CloseGPIO()
|
|
||||||
...
|
|
||||||
pwm, _ := embd.NewPWMPin("P9_14")
|
|
||||||
defer pwm.Close()
|
|
||||||
...
|
|
||||||
pwm.SetDuty(1000)
|
|
||||||
|
|
||||||
Control GPIO pins on the RaspberryPi / BeagleBone Black:
|
import "github.com/kidoman/embd"
|
||||||
|
...
|
||||||
|
embd.InitLED()
|
||||||
|
defer embd.CloseLED()
|
||||||
|
...
|
||||||
|
led, err := embd.NewLED("USR3")
|
||||||
|
...
|
||||||
|
led.Toggle()
|
||||||
|
|
||||||
import "github.com/kidoman/embd"
|
Even shorter while prototyping:
|
||||||
...
|
|
||||||
embd.InitGPIO()
|
|
||||||
defer embd.CloseGPIO()
|
|
||||||
...
|
|
||||||
embd.SetDirection(10, embd.Out)
|
|
||||||
embd.DigitalWrite(10, embd.High)
|
|
||||||
|
|
||||||
Could also do:
|
import "github.com/kidoman/embd"
|
||||||
|
...
|
||||||
|
embd.InitLED()
|
||||||
|
defer embd.CloseLED()
|
||||||
|
...
|
||||||
|
embd.ToggleLED(3)
|
||||||
|
|
||||||
import "github.com/kidoman/embd"
|
BBB + PWM:
|
||||||
...
|
|
||||||
embd.InitGPIO()
|
|
||||||
defer embd.CloseGPIO()
|
|
||||||
...
|
|
||||||
pin, err := embd.NewDigitalPin(10)
|
|
||||||
...
|
|
||||||
pin.SetDirection(embd.Out)
|
|
||||||
pin.Write(embd.High)
|
|
||||||
|
|
||||||
Or read data from the Bosch BMP085 barometric sensor:
|
import "github.com/kidoman/embd"
|
||||||
|
...
|
||||||
|
embd.InitGPIO()
|
||||||
|
defer embd.CloseGPIO()
|
||||||
|
...
|
||||||
|
pwm, _ := embd.NewPWMPin("P9_14")
|
||||||
|
defer pwm.Close()
|
||||||
|
...
|
||||||
|
pwm.SetDuty(1000)
|
||||||
|
|
||||||
import "github.com/kidoman/embd"
|
Control GPIO pins on the RaspberryPi / BeagleBone Black:
|
||||||
import "github.com/kidoman/embd/sensor/bmp085"
|
|
||||||
...
|
|
||||||
bus := embd.NewI2CBus(1)
|
|
||||||
...
|
|
||||||
baro := bmp085.New(bus)
|
|
||||||
...
|
|
||||||
temp, err := baro.Temperature()
|
|
||||||
altitude, err := baro.Altitude()
|
|
||||||
|
|
||||||
Even find out the heading from the LSM303 magnetometer:
|
import "github.com/kidoman/embd"
|
||||||
|
...
|
||||||
|
embd.InitGPIO()
|
||||||
|
defer embd.CloseGPIO()
|
||||||
|
...
|
||||||
|
embd.SetDirection(10, embd.Out)
|
||||||
|
embd.DigitalWrite(10, embd.High)
|
||||||
|
|
||||||
import "github.com/kidoman/embd"
|
Could also do:
|
||||||
import "github.com/kidoman/embd/sensor/lsm303"
|
|
||||||
...
|
|
||||||
bus := embd.NewI2CBus(1)
|
|
||||||
...
|
|
||||||
mag := lsm303.New(bus)
|
|
||||||
...
|
|
||||||
heading, err := mag.Heading()
|
|
||||||
|
|
||||||
The above two examples depend on I2C and therefore will work without change on almost all
|
import "github.com/kidoman/embd"
|
||||||
platforms.
|
...
|
||||||
|
embd.InitGPIO()
|
||||||
|
defer embd.CloseGPIO()
|
||||||
|
...
|
||||||
|
pin, err := embd.NewDigitalPin(10)
|
||||||
|
...
|
||||||
|
pin.SetDirection(embd.Out)
|
||||||
|
pin.Write(embd.High)
|
||||||
|
|
||||||
|
Or read data from the Bosch BMP085 barometric sensor:
|
||||||
|
|
||||||
|
import "github.com/kidoman/embd"
|
||||||
|
import "github.com/kidoman/embd/sensor/bmp085"
|
||||||
|
...
|
||||||
|
bus := embd.NewI2CBus(1)
|
||||||
|
...
|
||||||
|
baro := bmp085.New(bus)
|
||||||
|
...
|
||||||
|
temp, err := baro.Temperature()
|
||||||
|
altitude, err := baro.Altitude()
|
||||||
|
|
||||||
|
Even find out the heading from the LSM303 magnetometer:
|
||||||
|
|
||||||
|
import "github.com/kidoman/embd"
|
||||||
|
import "github.com/kidoman/embd/sensor/lsm303"
|
||||||
|
...
|
||||||
|
bus := embd.NewI2CBus(1)
|
||||||
|
...
|
||||||
|
mag := lsm303.New(bus)
|
||||||
|
...
|
||||||
|
heading, err := mag.Heading()
|
||||||
|
|
||||||
|
The above two examples depend on I2C and therefore will work without change on almost all
|
||||||
|
platforms.
|
||||||
*/
|
*/
|
||||||
package embd
|
package embd
|
||||||
|
6
gpio.go
6
gpio.go
@ -33,7 +33,11 @@ const (
|
|||||||
EdgeBoth Edge = "both"
|
EdgeBoth Edge = "both"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InterruptPin implements access to a Interruptable capable GPIO pin.
|
// InterruptPin implements access to an interrupt capable GPIO pin.
|
||||||
|
// The basic capability provided is to watch for a transition on the pin and
|
||||||
|
// generate a callback to a handler when a transition occurs.
|
||||||
|
// On Linux the underlying implementation generally uses epoll to receive the
|
||||||
|
// interrupts at user-level.
|
||||||
type InterruptPin interface {
|
type InterruptPin interface {
|
||||||
|
|
||||||
// Start watching this pin for interrupt
|
// Start watching this pin for interrupt
|
||||||
|
@ -95,7 +95,7 @@ var ledMap = embd.LEDMap{
|
|||||||
"beaglebone:green:usr3": []string{"3", "USR3", "usr3"},
|
"beaglebone:green:usr3": []string{"3", "USR3", "usr3"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var spiDeviceMinor byte = 1
|
var spiDeviceMinor int = 1
|
||||||
|
|
||||||
func ensureFeatureEnabled(id string) error {
|
func ensureFeatureEnabled(id string) error {
|
||||||
glog.V(3).Infof("bbb: enabling feature %v", id)
|
glog.V(3).Infof("bbb: enabling feature %v", id)
|
||||||
|
34
host/chip/README.md
Normal file
34
host/chip/README.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Using embd on CHIP
|
||||||
|
|
||||||
|
The CHIP drivers support gpio, I2C, SPI, and pin interrupts. Not supported are PWM or LED.
|
||||||
|
The names of the pins on chip have multiple aliases. The official CHIP pin names are supported,
|
||||||
|
for example XIO-P1 or LCD-D2 and the pin number are also supported, such as U14-14 (same as XIO-P1)
|
||||||
|
or U13-17. Some of the alternate function names are also supported, like "SPI2_MOSI", and the
|
||||||
|
linux 4.4 kernel gpio pin numbers as well, e.g., 1017 for XIO-P1. Finally, the official GPIO pins
|
||||||
|
(XIO-P0 thru XIO-P7) can be addressed as gpio0-gpio7.
|
||||||
|
|
||||||
|
A simple demo to blink an LED connected with a small resistor between XIO-P6 and 3.3V is
|
||||||
|
|
||||||
|
```
|
||||||
|
package main
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"github.com/kidoman/embd"
|
||||||
|
_ "github.com/kidoman/embd/host/chip"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
embd.InitGPIO()
|
||||||
|
defer embd.CloseGPIO()
|
||||||
|
|
||||||
|
embd.SetDirection("gpio6", embd.Out)
|
||||||
|
on := 0
|
||||||
|
for {
|
||||||
|
embd.DigitalWrite("gpio6", on)
|
||||||
|
on = 1 - on
|
||||||
|
time.Sleep(250 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Run it as root: `sudo ./blinky`
|
||||||
|
|
99
host/chip/chip.go
Normal file
99
host/chip/chip.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// Copyright 2016 by Thorsten von Eicken, see LICENSE file
|
||||||
|
|
||||||
|
// Package chip provides NextThing C.H.I.P. support.
|
||||||
|
// References:
|
||||||
|
// http://docs.getchip.com/chip.html#chip-hardware
|
||||||
|
// http://www.chip-community.org/index.php/Hardware_Information
|
||||||
|
//
|
||||||
|
// The following features are supported on Linux kernel 4.4+
|
||||||
|
// GPIO (digital (rw))
|
||||||
|
// I²C
|
||||||
|
// SPI
|
||||||
|
// Could add LED support by following https://bbs.nextthing.co/t/pwr-and-stat-leds/748/5
|
||||||
|
|
||||||
|
package chip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kidoman/embd"
|
||||||
|
"github.com/kidoman/embd/host/generic"
|
||||||
|
)
|
||||||
|
|
||||||
|
var spiDeviceMinor = 32766
|
||||||
|
|
||||||
|
var chipPins = embd.PinMap{
|
||||||
|
// official GPIO pins (U14 connector) using the pcf8574a
|
||||||
|
&embd.PinDesc{"XIO-P0", []string{"1016", "0", "U14-13", "gpio0"}, embd.CapDigital, 1016, 0},
|
||||||
|
&embd.PinDesc{"XIO-P1", []string{"1017", "1", "U14-14", "gpio1"}, embd.CapDigital, 1017, 0},
|
||||||
|
&embd.PinDesc{"XIO-P2", []string{"1018", "2", "U14-15", "gpio2"}, embd.CapDigital, 1018, 0},
|
||||||
|
&embd.PinDesc{"XIO-P3", []string{"1019", "3", "U14-16", "gpio3"}, embd.CapDigital, 1019, 0},
|
||||||
|
&embd.PinDesc{"XIO-P4", []string{"1020", "4", "U14-17", "gpio4"}, embd.CapDigital, 1020, 0},
|
||||||
|
&embd.PinDesc{"XIO-P5", []string{"1021", "5", "U14-18", "gpio5"}, embd.CapDigital, 1021, 0},
|
||||||
|
&embd.PinDesc{"XIO-P6", []string{"1022", "6", "U14-19", "gpio6"}, embd.CapDigital, 1022, 0},
|
||||||
|
&embd.PinDesc{"XIO-P7", []string{"1023", "7", "U14-20", "gpio7"}, embd.CapDigital, 1023, 0},
|
||||||
|
|
||||||
|
// pins usable on the U13 connector
|
||||||
|
&embd.PinDesc{"TWI1-SDA", []string{"48", "U13-9", "I2C0_SDA"}, embd.CapDigital | embd.CapI2C, 48, 0},
|
||||||
|
&embd.PinDesc{"TWI1-SCK", []string{"47", "U13-11", "I2C0_SCK"}, embd.CapDigital | embd.CapI2C, 47, 0},
|
||||||
|
&embd.PinDesc{"PWM0", []string{"34", "U13-18"}, embd.CapDigital | embd.CapPWM, 34, 0},
|
||||||
|
&embd.PinDesc{"LCD-D2", []string{"98", "U13-17"}, embd.CapDigital, 98, 0},
|
||||||
|
&embd.PinDesc{"LCD-D3", []string{"99", "U13-20"}, embd.CapDigital, 99, 0},
|
||||||
|
&embd.PinDesc{"LCD-D4", []string{"100", "U13-19"}, embd.CapDigital, 100, 0},
|
||||||
|
&embd.PinDesc{"LCD-D5", []string{"101", "U13-22"}, embd.CapDigital, 101, 0},
|
||||||
|
&embd.PinDesc{"LCD-D6", []string{"102", "U13-21"}, embd.CapDigital, 102, 0},
|
||||||
|
&embd.PinDesc{"LCD-D7", []string{"103", "U13-24"}, embd.CapDigital, 103, 0},
|
||||||
|
&embd.PinDesc{"LCD-D10", []string{"106", "U13-23"}, embd.CapDigital, 106, 0},
|
||||||
|
&embd.PinDesc{"LCD-D11", []string{"107", "U13-26"}, embd.CapDigital, 107, 0},
|
||||||
|
&embd.PinDesc{"LCD-D12", []string{"108", "U13-25"}, embd.CapDigital, 108, 0},
|
||||||
|
&embd.PinDesc{"LCD-D13", []string{"109", "U13-28"}, embd.CapDigital, 109, 0},
|
||||||
|
&embd.PinDesc{"LCD-D14", []string{"110", "U13-27"}, embd.CapDigital, 110, 0},
|
||||||
|
&embd.PinDesc{"LCD-D15", []string{"111", "U13-30"}, embd.CapDigital, 111, 0},
|
||||||
|
&embd.PinDesc{"LCD-D18", []string{"114", "U13-29"}, embd.CapDigital, 114, 0},
|
||||||
|
&embd.PinDesc{"LCD-D19", []string{"115", "U13-32"}, embd.CapDigital, 115, 0},
|
||||||
|
&embd.PinDesc{"LCD-D20", []string{"116", "U13-31"}, embd.CapDigital, 116, 0},
|
||||||
|
&embd.PinDesc{"LCD-D21", []string{"117", "U13-34"}, embd.CapDigital, 117, 0},
|
||||||
|
&embd.PinDesc{"LCD-D22", []string{"118", "U13-33"}, embd.CapDigital, 118, 0},
|
||||||
|
&embd.PinDesc{"LCD-D23", []string{"119", "U13-36"}, embd.CapDigital, 119, 0},
|
||||||
|
&embd.PinDesc{"LCD-CLK", []string{"120", "U13-35"}, embd.CapDigital, 120, 0},
|
||||||
|
&embd.PinDesc{"LCD-VSYNC", []string{"123", "U13-37"}, embd.CapDigital, 123, 0},
|
||||||
|
&embd.PinDesc{"LCD-HSYNC", []string{"122", "U13-38"}, embd.CapDigital, 122, 0},
|
||||||
|
&embd.PinDesc{"LCD-DE", []string{"121", "U13-40"}, embd.CapDigital, 121, 0},
|
||||||
|
|
||||||
|
// pins usable on the U14 connector
|
||||||
|
&embd.PinDesc{"UART1-TX", []string{"195", "U14-3", "EINT3"}, embd.CapDigital | embd.CapUART, 195, 0},
|
||||||
|
&embd.PinDesc{"UART1-RX", []string{"196", "U14-5", "EINT4"}, embd.CapDigital | embd.CapUART, 196, 0},
|
||||||
|
&embd.PinDesc{"AP-EINT1", []string{"193", "U14-23", "EINT1"}, embd.CapDigital, 193, 0},
|
||||||
|
&embd.PinDesc{"AP-EINT3", []string{"35", "U14-24", "EINT3"}, embd.CapDigital, 35, 0},
|
||||||
|
&embd.PinDesc{"TWI2-SDA", []string{"50", "U14-25", "I2C2_SDA"}, embd.CapDigital | embd.CapI2C, 50, 0},
|
||||||
|
&embd.PinDesc{"TWI2-SCK", []string{"49", "U14-26", "I2C2_SCK"}, embd.CapDigital | embd.CapI2C, 49, 0},
|
||||||
|
&embd.PinDesc{"CSIPCK", []string{"128", "U14-27", "SPI2_SCO", "SPI2_CS0"}, embd.CapDigital | embd.CapSPI, 128, 0},
|
||||||
|
&embd.PinDesc{"CSICK", []string{"129", "U14-28", "SPI2_CLK"}, embd.CapDigital | embd.CapSPI, 129, 0},
|
||||||
|
&embd.PinDesc{"CSIHSYNC", []string{"130", "U14-29", "SPI2_MOSI"}, embd.CapDigital | embd.CapSPI, 130, 0},
|
||||||
|
&embd.PinDesc{"CSIVSYNC", []string{"131", "U14-30", "SPI2_MISO"}, embd.CapDigital | embd.CapSPI, 131, 0},
|
||||||
|
&embd.PinDesc{"CSID0", []string{"132", "U14-31"}, embd.CapDigital, 132, 0},
|
||||||
|
&embd.PinDesc{"CSID1", []string{"133", "U14-32"}, embd.CapDigital, 133, 0},
|
||||||
|
&embd.PinDesc{"CSID2", []string{"134", "U14-33"}, embd.CapDigital, 134, 0},
|
||||||
|
&embd.PinDesc{"CSID3", []string{"135", "U14-34"}, embd.CapDigital, 135, 0},
|
||||||
|
&embd.PinDesc{"CSID4", []string{"136", "U14-35"}, embd.CapDigital, 136, 0},
|
||||||
|
&embd.PinDesc{"CSID5", []string{"137", "U14-36"}, embd.CapDigital, 137, 0},
|
||||||
|
&embd.PinDesc{"CSID6", []string{"138", "U14-37", "UART1_TX"}, embd.CapDigital | embd.CapUART, 138, 0},
|
||||||
|
&embd.PinDesc{"CSID7", []string{"139", "U14-38", "UART1_RX"}, embd.CapDigital | embd.CapUART, 139, 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
embd.Register(embd.HostCHIP, func(rev int) *embd.Descriptor {
|
||||||
|
return &embd.Descriptor{
|
||||||
|
GPIODriver: func() embd.GPIODriver {
|
||||||
|
return embd.NewGPIODriver(chipPins, generic.NewDigitalPin, nil, nil)
|
||||||
|
},
|
||||||
|
I2CDriver: func() embd.I2CDriver {
|
||||||
|
return embd.NewI2CDriver(generic.NewI2CBus)
|
||||||
|
},
|
||||||
|
//LEDDriver: func() embd.LEDDriver {
|
||||||
|
// return embd.NewLEDDriver(ledMap, generic.NewLED)
|
||||||
|
//},
|
||||||
|
SPIDriver: func() embd.SPIDriver {
|
||||||
|
return embd.NewSPIDriver(spiDeviceMinor, generic.NewSPIBus, nil)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -10,6 +10,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kidoman/embd"
|
"github.com/kidoman/embd"
|
||||||
@ -69,6 +70,9 @@ func (p *digitalPin) export() error {
|
|||||||
}
|
}
|
||||||
defer exporter.Close()
|
defer exporter.Close()
|
||||||
_, err = exporter.WriteString(strconv.Itoa(p.n))
|
_, err = exporter.WriteString(strconv.Itoa(p.n))
|
||||||
|
if e, ok := err.(*os.PathError); ok && e.Err == syscall.EBUSY {
|
||||||
|
return nil // EBUSY -> the pin has already been exported
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +101,28 @@ func (b *i2cBus) ReadByte(addr byte) (byte, error) {
|
|||||||
return bytes[0], nil
|
return bytes[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *i2cBus) ReadBytes(addr byte, num int) ([]byte, error) {
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
|
||||||
|
if err := b.init(); err != nil {
|
||||||
|
return []byte{0}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := b.setAddress(addr); err != nil {
|
||||||
|
return []byte{0}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes := make([]byte, num)
|
||||||
|
n, _ := b.file.Read(bytes)
|
||||||
|
|
||||||
|
if n != num {
|
||||||
|
return []byte{0}, fmt.Errorf("i2c: Unexpected number (%v) of bytes read", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (b *i2cBus) WriteByte(addr, value byte) error {
|
func (b *i2cBus) WriteByte(addr, value byte) error {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
@ -223,7 +245,7 @@ func (b *i2cBus) WriteToReg(addr, reg byte, value []byte) error {
|
|||||||
message.addr = uint16(addr)
|
message.addr = uint16(addr)
|
||||||
message.flags = 0
|
message.flags = 0
|
||||||
message.len = uint16(len(outbuf))
|
message.len = uint16(len(outbuf))
|
||||||
message.buf = uintptr(unsafe.Pointer(&hdrp.Data))
|
message.buf = uintptr(unsafe.Pointer(hdrp.Data))
|
||||||
|
|
||||||
var packets i2c_rdwr_ioctl_data
|
var packets i2c_rdwr_ioctl_data
|
||||||
|
|
||||||
|
@ -61,11 +61,13 @@ func initEpollListener() *epollListener {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("EpollWait error: %v", err))
|
panic(fmt.Sprintf("EpollWait error: %v", err))
|
||||||
}
|
}
|
||||||
|
listener.mu.Lock()
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
if irq, ok := listener.interruptablePins[int(epollEvents[i].Fd)]; ok {
|
if irq, ok := listener.interruptablePins[int(epollEvents[i].Fd)]; ok {
|
||||||
irq.Signal()
|
irq.Signal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
listener.mu.Unlock()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return listener
|
return listener
|
||||||
|
@ -36,12 +36,14 @@ type spiIOCTransfer struct {
|
|||||||
speedHz uint32
|
speedHz uint32
|
||||||
delayus uint16
|
delayus uint16
|
||||||
bitsPerWord uint8
|
bitsPerWord uint8
|
||||||
|
csChange uint8
|
||||||
|
pad uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type spiBus struct {
|
type spiBus struct {
|
||||||
file *os.File
|
file *os.File
|
||||||
|
|
||||||
spiDevMinor byte
|
spiDevMinor int
|
||||||
|
|
||||||
channel byte
|
channel byte
|
||||||
mode byte
|
mode byte
|
||||||
@ -61,7 +63,7 @@ func spiIOCMessageN(n uint32) uint32 {
|
|||||||
return (spiIOCMessage0 + (n * spiIOCIncrementor))
|
return (spiIOCMessage0 + (n * spiIOCIncrementor))
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSPIBus(spiDevMinor, mode, channel byte, speed, bpw, delay int, i func() error) embd.SPIBus {
|
func NewSPIBus(spiDevMinor int, mode, channel byte, speed, bpw, delay int, i func() error) embd.SPIBus {
|
||||||
return &spiBus{
|
return &spiBus{
|
||||||
spiDevMinor: spiDevMinor,
|
spiDevMinor: spiDevMinor,
|
||||||
mode: mode,
|
mode: mode,
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"github.com/kidoman/embd/host/generic"
|
"github.com/kidoman/embd/host/generic"
|
||||||
)
|
)
|
||||||
|
|
||||||
var spiDeviceMinor = byte(0)
|
var spiDeviceMinor = 0
|
||||||
|
|
||||||
var rev1Pins = embd.PinMap{
|
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_3", Aliases: []string{"0", "GPIO_0", "SDA", "I2C0_SDA"}, Caps: embd.CapDigital | embd.CapI2C, DigitalLogical: 0},
|
||||||
|
2
i2c.go
2
i2c.go
@ -6,6 +6,8 @@ package embd
|
|||||||
type I2CBus interface {
|
type I2CBus interface {
|
||||||
// ReadByte reads a byte from the given address.
|
// ReadByte reads a byte from the given address.
|
||||||
ReadByte(addr byte) (value byte, err error)
|
ReadByte(addr byte) (value byte, err error)
|
||||||
|
// ReadBytes reads a slice of bytes from the given address.
|
||||||
|
ReadBytes(addr byte, num int) (value []byte, err error)
|
||||||
// WriteByte writes a byte to the given address.
|
// WriteByte writes a byte to the given address.
|
||||||
WriteByte(addr, value byte) error
|
WriteByte(addr, value byte) error
|
||||||
// WriteBytes writes a slice bytes to the given address.
|
// WriteBytes writes a slice bytes to the given address.
|
||||||
|
@ -24,25 +24,25 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("received data is: %v", dataBuf)
|
fmt.Println("received data is:", dataBuf)
|
||||||
|
|
||||||
dataReceived, err := spiBus.ReceiveData(3)
|
dataReceived, err := spiBus.ReceiveData(3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("received data is: %v", dataReceived)
|
fmt.Println("received data is:", dataReceived)
|
||||||
|
|
||||||
dataByte := byte(1)
|
dataByte := byte(1)
|
||||||
receivedByte, err := spiBus.TransferAndReceiveByte(dataByte)
|
receivedByte, err := spiBus.TransferAndReceiveByte(dataByte)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Println("received byte is: %v", receivedByte)
|
fmt.Println("received byte is:", receivedByte)
|
||||||
|
|
||||||
receivedByte, err = spiBus.ReceiveByte()
|
receivedByte, err = spiBus.ReceiveByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Println("received byte is: %v", receivedByte)
|
fmt.Println("received byte is:", receivedByte)
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@ package embd
|
|||||||
|
|
||||||
import "sync"
|
import "sync"
|
||||||
|
|
||||||
type spiBusFactory func(byte, byte, byte, int, int, int, func() error) SPIBus
|
type spiBusFactory func(int, byte, byte, int, int, int, func() error) SPIBus
|
||||||
|
|
||||||
type spiDriver struct {
|
type spiDriver struct {
|
||||||
spiDevMinor byte
|
spiDevMinor int
|
||||||
initializer func() error
|
initializer func() error
|
||||||
|
|
||||||
busMap map[byte]SPIBus
|
busMap map[byte]SPIBus
|
||||||
@ -16,7 +16,7 @@ type spiDriver struct {
|
|||||||
|
|
||||||
// NewSPIDriver returns a SPIDriver interface which allows control
|
// NewSPIDriver returns a SPIDriver interface which allows control
|
||||||
// over the SPI bus.
|
// over the SPI bus.
|
||||||
func NewSPIDriver(spiDevMinor byte, sbf spiBusFactory, i func() error) SPIDriver {
|
func NewSPIDriver(spiDevMinor int, sbf spiBusFactory, i func() error) SPIDriver {
|
||||||
return &spiDriver{
|
return &spiDriver{
|
||||||
spiDevMinor: spiDevMinor,
|
spiDevMinor: spiDevMinor,
|
||||||
sbf: sbf,
|
sbf: sbf,
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
git log --all --format='%cN <%cE>' | sort -u | grep -v karan.misra@gmail.com > CONTRIBUTORS
|
|
5
update_contributors.sh
Executable file
5
update_contributors.sh
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
git log --all --format='%cN <%cE>' | sort -u | grep -v karan.misra@gmail.com |\
|
||||||
|
grep -v noreply@ | cat CONTRIBUTORS - | sort | uniq > CONTRIBUTORS.new
|
||||||
|
mv CONTRIBUTORS.new CONTRIBUTORS
|
Loading…
x
Reference in New Issue
Block a user