hwio

package module
v0.0.0-...-11ea3f4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2018 License: BSD-3-Clause Imports: 14 Imported by: 59

README

hwio

Introduction

hwio is a Go library for interfacing with hardware I/O, particularly on SoC-based boards such as BeagleBone Black, Raspberry Pi and Odroid-C1. It is loosely modelled on the Arduino programming style, but deviating where that doesn't make sense in Go. It makes use of a thin hardware abstraction via an interface so a program written against the library for say a BeagleBone could be easily compiled to run on a Raspberry Pi, maybe only changing pin references.

To use hwio, you just need to import it into your Go project, initialise modules and pins as required, and then use functions that manipulate the pins.

For more information about the library, including pin diagrams for supported boards and tutorials, see http://stuffwemade.net/hwio.

Digital Reads and Writes (GPIO)

Initialising a pin looks like this:

myPin, err := hwio.GetPin("gpio4")
err = hwio.PinMode(myPin, hwio.OUTPUT)

Or the shorter, more convenient form:

myPin, err := GetPinWithMode("gpio4", hwio.OUTPUT)

Unlike Arduino, where the pins are directly numbered and you just use the number, in hwio you get the pin first, by name. This is necessary as different hardware drivers may provide different pins.

The mode constants include:

  • INPUT - set pin to digital input
  • OUTPUT - set pin to digital output

(Pull-ups and pull-downs are not currently supported by the drivers, as this is not apparently exposed to file system.)

Writing a value to a pin looks like this:

hwio.DigitalWrite(myPin, hwio.HIGH)

Reading a value from a digital pin looks like this, returning a HIGH or LOW:

value, err := hwio.DigitalRead(myPin)

Analog

Analog pins are available on BeagleBone Black. Unlike Arduino, before using analog pins you need to enable the module. This is because external programs may have them open.

analog, e := hwio.GetAnalogModule()
if e != nil {
	fmt.Printf("could not get analog module: %s\n", e)
	return
}

analog.Enable()

Reading an analog value looks like this:

value, err := hwio.AnalogRead(somePin)

Analog values (on BeagleBone Black at least) are integers typically between 0-1800, which is the number of millivolts. (Note that you cannot drive analog inputs more than 1.8 volts on the BeagleBone, and you should use the analog voltage references it provides).

(Note: the Raspberry Pi does not have analog inputs onboard, and is not covered by the analog functions of hwio. However it is possible to use i2c to read from a compatible device, such as the MCP4725 or ADS1015. Adafruit has breakout boards for these devices.)

Cleaning Up on Exit

At the end of your application, call CloseAll(). This can be done at the end of the main() function with a defer:

defer hwio.CloseAll()

This will ensure that resources allocated (particularly GPIO pins) will be released, even if there is a panic.

If you want to close an individual GPIO pin, you can use:

hwio.ClosePin(pin)

Utility Functions

To delay a number of milliseconds:

hwio.Delay(500)  // delay 500ms

Or to delay by microseconds:

hwio.DelayMicroseconds(1500)  // delay 1500 usec, or 1.5 milliseconds

The Arduino ShiftOut function is supported in a simplified form for 8 bits:

e := hwio.ShiftOut(dataPin, clockPin, 127, hwio.MSBFIRST)   // write 8 bits, MSB first

or in a bigger variant that supports different sizes:

e := hwio.ShiftOutSize(dataPin, clockPin, someValue, hwio.LSBFIRST, 12)  // write 12 bits LSB first

Sometimes you might want to write an unsigned int to a set of digital pins (e.g. a parallel port). This can be done as follows:

somePins := []hwio.Pin{myPin3, myPin2, myPin1, myPin0}
e := hwio.WriteUIntToPins(myValue, somePins)

This will write out the n lowest bits of myValue, with the most significant bit of that value written to myPin3 etc. It uses DigitalWrite so the outputs are not written instantaneously.

There is an implementation of the Arduino map() function:

// map a value in range 0-1800 to new range 0-1023
i := hwio.Map(value, 0, 1800, 0, 1023)

To pulse a GPIO pin (must have been assigned), you can use the Pulse function:

e := hwio.Pulse(somePin, hwio.HIGH, 1500)

The second parameter is the logic level of the active level of the pulse. First the function sets the pin to the inactive state and then to the active state, before waiting the specified number of microseconds, and setting it inactive again.

On-board LEDs

On-board LEDs can be controlled using the helper function Led:

// Turn on usr0 LED
e := hwio.Led("usr0", true)

For BeagleBone, the LEDs are named "usr0", "usr1", "usr2" and "usr3" (case-insensitive). For Raspberry Pi only one of the LEDs is controllable, which is named "OK".

The Led function is a helper that uses the LED module. This provides more options to control what is displayed on each LED.

I2C

I2C is supported on BeagleBone Black and Raspberry Pi. It is accessible through the "i2c" module (BBB i2c2 pins), as follows:

m, e := hwio.GetModule("i2c")
if e != nil {
	fmt.Printf("could not get i2c module: %s\n", e)
	return
}
i2c := m.(hwio.I2CModule)

// Uncomment on Raspberry pi, which doesn't automatically enable i2c bus. BeagleBone does,
// as the default device tree enables it.

// i2c.Enable()
// defer i2c.Disable()

device := i2c.GetDevice(0x68)

Once you have a device, you can use Write, WriteBytes, Read or ReadBytes to set or get data from the i2c device.

e.g.

device.WriteByte(controlRegister, someValue)

While you can use the i2c types to directly talk to i2c devices, the specific device may already have higher-level support in the hwio/devices package, so check there first, as the hard work may be done already.

PWM

PWM support for BeagleBone Black has been added. To use a PWM pin, you need to fetch the module that the PWM belongs to, enable the PWM module and pin, and then you can manipulate the period and duty cycle. e.g.

// Get the module
m, e := hwio.GetModule("pwm2")
if e != nil {
	fmt.Printf("could not get pwm2 module: %s\n", e)
	return
}

pwm := m.(hwio.PWMModule)

// Enable it.
pwm.Enable()

// Get the PWM pin
pwm8_13, _ := hwio.GetPin("P8.13")
e = pwm.EnablePin(pwm8_13, true)
if e != nil {
	fmt.Printf("Error enabling pin: %s\n", e)
	return
}

// Set the period and duty cycle, in nanoseconds. This is a 1/10th second cycle
pwm.SetPeriod(pwm8_13, 100000000)
pwm.SetDuty(pwm8_13, 90000000)

On BeagleBone Black, there are 3 PWM modules, "pwm0", "pwm1" and "pwm2". I am not sure if "pwm1" pins can be assigned, as they are pre-allocated in the default device tree config, but in theory it should be possible to use them. By default, these pins can be used:

  • pwm0: P9.21 (ehrpwm0B) and P9.22 (ehrpwm0A)
  • pwm2: P8.13 (ehrpwm2A) and P8.19 (ehrpwm2A)

This is a preliminary implementation; only P8.13 (pwm2) has been tested. PWM pins are not present in default device tree. The module will add them dynamically as necessary to bonemgr/slots; this will override defaults.

Servo

There is a servo implementation in the hwio/servo package. See README.md in that package.

Devices

There are sub-packages under 'devices' that have been made to work with hwio. The currently supported devices include:

  • GY-520 gyroscope/accelerometer using I2C.
  • HD-44780 multi-line LCD display. Currently implemented over I2C converter only.
  • MCP23017 16-bit port extender over I2C.
  • Nintendo Nunchuck over I2C.

See README.md files in respective directories.

CPU Info

The helper function CpuInfo can tell you properties about your device. This is based on /proc/cpuinfo.

e.g. model := hwio.CpuInfo(0, "model name")

The properties available from device to device. Processor 0 is always present.

Driver Selection

The intention of the hwio library is to use uname to attempt to detect the platform and select an appropriate driver (see drivers section below), so for some platforms this may auto-detect. However, with the variety of boards around and the variety of operating systems, you may find that autodetection doesn't work. If you need to set the driver automatically, you can do:

hwio.SetDriver(new(BeagleBoneBlackDriver))

This needs to be done before any other hwio calls.

BIG SHINY DISCLAIMER

REALLY IMPORTANT THINGS TO KNOW ABOUT THIS ABOUT THIS LIBRARY:

  • It is under development. If you're lucky, it might work. It should be considered Alpha.
  • If you don't want to risk frying your board, you can still run the unit tests ;-)

Board Support

Currently there are 3 drivers:

  • BeagleBoneBlackDriver - for BeagleBone boards running linux kernel 3.7 or higher, including BeagleBone Black. This is untested on older BeagleBone boards with updated kernels.
  • RaspberryPiDTDriver - for Raspberry Pi modules running linux kernel 3.7 or higher, which includes newer Raspian kernels and some late Occidental kernels.
  • TestDriver - for unit tests.

Old pre-kernel-3.7 drivers for BeagleBone and Raspberry Pi have been deprecated as I have no test beds for these. If you want to use these, you can check out the 'legacy' branch that contains the older drivers, but no new features will be added.

BeagleBoneBlackDriver

This driver accesses hardware via the device interfaces exposed in the file system on linux kernels 3.8 or higher, where device tree is mandated. This should be a robust driver as the hardware access is maintained by device driver authors, but is likely to be not as fast as direct memory I/O to the hardware as there is file system overhead.

Status:

  • In active development.
  • Tested for gpio reads and writes, analog reads and i2c. Test device was BeagleBone Black running rev A5C, running angstrom.
  • Driver automatically blocks out the GPIO pins that are allocated to LCD and MMC on the default BeagleBone Black boards.
  • GPIOs not assigned at boot to other modules are known to read and write.
  • PWM is known to work on erhpwm2A and B ports.
  • GPIO pull-ups is not yet supported.
  • i2c is enabled by default.
  • Has not been tested on BeagleBone Black rev C
RaspberryPiDTDriver

This driver is very similar to the BeagleBone Black driver in that it uses the modules compiled into the kernel and configured using device tree. It uses the same GPIO and i2c implementatons, just with different pins.

Current status:

  • DigitalRead and DigitalWrite (GPIO) have been tested and work correctly on supported GPIO pins. Test platform was Raspberry Pi (revision 1), Raspian 2013-12-20-wheezy-raspbian, kernel 3.10.24+.
  • GPIO pins are gpio4, gpio17, gpio18, gpio21, gpio22, gpio23, gpio24 and gpio25.
  • I2C is working on raspian. You need to enable it on the board first. Follow these instructions
  • It is unlikely to work on a Raspberry Pi B+, as many pins have moved, even on the first 26 legacy pins. Power and I2C appear to be in the same locations, but little else.

GetPin references on this driver return the pin numbers that are on the headers. Pin 0 is unimplemented.

Note: before using this, check your kernel is 3.7 or higher. There are a number of pre-3.7 distributions still in use, and this driver does not support pre-3.7.

OdroidC1Driver

This driver accesses hardware via the device interfaces exposed in the file system on linux kernels 3.8 or higher, where device tree is mandated. This should be a robust driver as the hardware access is maintained by device driver authors, but is likely to be not as fast as direct memory I/O to the hardware as there is file system overhead.

Status:

  • In active development.
  • Analog input is known to work. Device limit is 1.8V on analog input.
  • Autodetection works
  • GPIO not fully tested
  • PWM does not work yet

I2C is not loaded by default on this device. You need to either:

 modprobe aml_i2c

or to enable on each boot:

sudo echo "aml_i2c" >> /etc/modules

This makes the necessary /dev/i2c* files appear.

Implementation Notes

Some general principles the library attempts to adhere to include:

  • Pin references are logical, and are mapped to hardware pins by the driver. The pin numbers you get back from GetPin are, unless otherwise specified, related to the pin numbers on extension headers.
  • Drivers provide pin names, so you can look them up by meaningful names instead of relying on device specific numbers. On boards such as BeagleBone, where pins are multiplexed to internal functions, pins can have multiple names.
  • The library does not implement Arduino functions for their own sake if go's framework naturally supports them better, unless we can provide a simpler interface to those functions and keep close to the Arduino semantics.
  • Drivers are very thin layers; most of the I/O functionality is provided by modules. These aim to be as generic as possible so that different drivers on similar kernels can assemble the modules that are enabled in device tree, with appropriate pin configuration. This also makes it easier to add in new modules to support various SoC functions.
  • Make no assumption about the state of a pin whose mode has not been set. Specifically, pins that don't have mode set may not on a particular hardware configuration even be configured as general purpose I/O. For example, many beaglebone pins have overloaded functions set using a multiplexer, and some are be pre-assigned by the default device tree configuration.
  • Any pin whose mode is set by PinMode can be assumed to be general purpose I/O, and likewise if it is not set, it could have any multiplexed behaviour assigned to it. A consequence is that unlike Arduino, PinMode must be called before a pin is used.
  • The library should be as fast as possible so that applications that require very high speed I/O should achieve maximal throughput, given an appropriate driver.
  • Make simple stuff simple, and harder stuff possible. In particular, while Arduino-like methods have uniform interface and semantics across drivers, we don't hide the driver itself or the modules it uses, so special features of a driver or module can still be used, albeit non-portably.
  • Sub-packages can be added as required that approximately parallel Arduino libaries (e.g. perhaps an SD card package).
Pins

Pins are logical representation of physical pins on the hardware. To provide some abstraction, pins are numbered, much like on an Arduino. Unlike Arduino, there is no single mapping to hardware pins - this is done by the hardware driver. To make it easier to work with, drivers can give one or more names to a pin, and you can use GetPin to get a reference to the pin by one of those names.

Each driver must implement a method that defines the mapping from logical pins to physical pins as understood by that piece of hardware. Additionally, the driver also publishes the modules that the hardware configuration supports, so that hwio can ensure that constraints of the hardware are met. For example, if a pin implements PWM and GPIO in hardware, it is associated with two modules. When the PWM module is enabled, it will assign the pin to itself. Because each pin can have a different set of capabilities, there is no distinction between analog and digital pins as there is in Arduino; there is one set of pins, which may support any number of capabilities including digital and analog.

The caller generally works with logical pin numbers retrieved by GetPin.

Things to be done

  • Interupts (lib, BeagleBone and R-Pi)
  • Serial support for UART pins (lib, BeagleBone and R-Pi)
  • SPI support; consider augmenting ShiftIn and ShiftOut to use hardware pins if appropriate (Beaglebone and R-Pi)
  • Stepper (lib)
  • TLC5940 (lib)

Documentation

Overview

Package hwio implements a simple Arduino-like interface for controlling hardware I/O, with configurable backends depending on the device.

Index

Constants

View Source
const (
	I2C_SMBUS_READ           = 1
	I2C_SMBUS_WRITE          = 0
	I2C_SMBUS_BYTE_DATA      = 2
	I2C_SMBUS_I2C_BLOCK_DATA = 8
	I2C_SMBUS_BLOCK_MAX      = 32

	// Talk to bus
	I2C_SMBUS = 0x0720

	// Set bus slave
	I2C_SLAVE = 0x0703
)

Constants used by ioctl, from i2c-dev.h

View Source
const (
	HIGH = 1
	LOW  = 0
)

Convenience constants for digital pin values.

Variables

This section is empty.

Functions

func AnalogRead

func AnalogRead(pin Pin) (int, error)

Read an analog value from a pin. The range of values is hardware driver dependent.

func AssignPin

func AssignPin(pin Pin, module Module) error

Assign a pin to a module. This is typically called by modules when they allocate pins. If the pin is already assigned, an error is generated. ethod is public in case it is needed to hack around default driver settings.

func AssignPins

func AssignPins(pins PinList, module Module) error

Assign a set of pins. Method is public in case it is needed to hack around default driver settings.

func CloseAll

func CloseAll()

Ensure that any resources external to the program that have been allocated are tidied up.

func ClosePin

func ClosePin(pin Pin) error

Close a specific pin that has been assigned as GPIO by PinMode

func CpuInfo

func CpuInfo(cpu int, property string) string

Look up property for a CPU. CPU's start at 0.

func DebugPinMap

func DebugPinMap()

@todo DebugPinMap: sort

func Delay

func Delay(duration int)

Delay execution by the specified number of milliseconds. This is a helper function for similarity with Arduino. It is implemented using standard go time package.

func DelayMicroseconds

func DelayMicroseconds(duration int)

Delay execution by the specified number of microseconds. This is a helper function for similarity with Arduino. It is implemented using standard go time package

func DigitalRead

func DigitalRead(pin Pin) (result int, e error)

Read a value from a digital pin

func DigitalWrite

func DigitalWrite(pin Pin, value int) (e error)

Write a value to a digital pin

func Led

func Led(name string, on bool) error

Helper to turn an on-board LED on or off. Uses LED module

func Map

func Map(value int, fromLow int, fromHigh int, toLow int, toHigh int) int

func Negate

func Negate(logicLevel int) int

given a logic level of HIGH or LOW, return the opposite. Invalid values returned as LOW.

func PinMode

func PinMode(pin Pin, mode PinIOMode) error

Set the mode of a pin. Analogous to Arduino pin mode.

func PinName

func PinName(pin Pin) string

Given an internal pin number, return the canonical name for the pin, as defined by the driver. If the pin is not to the driver, return "".

func Pulse

func Pulse(pin Pin, active int, durationMicroseconds int) error

Helper function to pulse a pin, which must have been set as GPIO. 'active' is LOW or HIGH. Pulse sets pin to inactive, then active for 'durationMicroseconds' and the back to inactive.

func ReverseBytes16

func ReverseBytes16(value uint16) uint16

func ReverseBytes32

func ReverseBytes32(value uint32) uint32

func SetDriver

func SetDriver(d HardwareDriver)

Set the driver. Also calls Init on the driver, and loads the capabilities of the device.

func SetErrorChecking

func SetErrorChecking(check bool)

Set error checking. This should be called before pin assignments.

func ShiftOut

func ShiftOut(dataPin Pin, clockPin Pin, value uint, order BitShiftOrder) error

The approximate mapping of Arduino shiftOut, this shifts a byte out on the data pin, pulsing the clock pin high and then low.

func ShiftOutSize

func ShiftOutSize(dataPin Pin, clockPin Pin, value uint, order BitShiftOrder, n uint) error

More generic version of ShiftOut which shifts out n of data from value. The value shifted out is always the lowest n bits of the value, but 'order' determines whether the msb or lsb from that value are shifted first

func UInt16FromUInt8

func UInt16FromUInt8(highByte byte, lowByte byte) uint16

Given a high and low byte, combine to form a single 16-bit value

func UnassignPin

func UnassignPin(pin Pin) error

Unassign a pin. Method is public in case it is needed to hack around default driver settings.

func UnassignPins

func UnassignPins(pins PinList) (er error)

Unassign a set of pins. Method is public in case it is needed to hack around default driver settings.

func WriteStringToFile

func WriteStringToFile(filename string, value string) error

Write a string to a file and close it again.

func WriteUIntToPins

func WriteUIntToPins(value uint32, pins []Pin) error

Given an integer and a list of GPIO pins (that must have been set up as outputs), write the integer across the pins. The number of bits is determined by the length of the pins. The most-significant output pin is first. Bits are written MSB first. Maximum number of bits that can be shifted is 32. Note that the bits are not written out instantaneously, although very quickly. If you need instantaneous changing of all pins, you need to consider an output buffer.

Types

type AnalogModule

type AnalogModule interface {
	Module

	AnalogRead(pin Pin) (result int, e error)
}

func GetAnalogModule

func GetAnalogModule() (AnalogModule, error)

Helper function to get GPIO module

type BBAnalogModule

type BBAnalogModule struct {
	// contains filtered or unexported fields
}

BBAnalogModule handles BeagleBone-specific analog.

func NewBBAnalogModule

func NewBBAnalogModule(name string) (result *BBAnalogModule)

func (*BBAnalogModule) AnalogRead

func (module *BBAnalogModule) AnalogRead(pin Pin) (int, error)

func (*BBAnalogModule) Disable

func (module *BBAnalogModule) Disable() error

disables module and release any pins assigned.

func (*BBAnalogModule) Enable

func (module *BBAnalogModule) Enable() error

enable GPIO module. It doesn't allocate any pins immediately.

func (*BBAnalogModule) GetName

func (module *BBAnalogModule) GetName() string

func (*BBAnalogModule) SetOptions

func (module *BBAnalogModule) SetOptions(options map[string]interface{}) error

Set options of the module. Parameters we look for include: - "pins" - an object of type BBAnalogModulePinDefMap

type BBAnalogModuleOpenPin

type BBAnalogModuleOpenPin struct {
	// contains filtered or unexported fields
}

type BBAnalogModulePinDef

type BBAnalogModulePinDef struct {
	// contains filtered or unexported fields
}

Represents the definition of an analog pin, which should contain all the info required to open, close, read and write the pin using FS drivers.

type BBAnalogModulePinDefMap

type BBAnalogModulePinDefMap map[Pin]*BBAnalogModulePinDef

A map of GPIO pin definitions.

type BBPWMModule

type BBPWMModule struct {
	// contains filtered or unexported fields
}

func NewBBPWMModule

func NewBBPWMModule(name string) (result *BBPWMModule)

func (*BBPWMModule) Disable

func (module *BBPWMModule) Disable() error

disables module and release any pins assigned.

func (*BBPWMModule) Enable

func (module *BBPWMModule) Enable() error

enable PWM module. It doesn't allocate any pins immediately. It does check of am33xx_pwm is present in the capemgr slots, and adds it if not. By default, this is not enabled on the BB but can be added easily.

func (*BBPWMModule) EnablePin

func (module *BBPWMModule) EnablePin(pin Pin, enabled bool) error

Enable a specific PWM pin. You need to call this explicitly after enabling the module, as the module will not by default allocate all pins, since there are a few.

func (*BBPWMModule) GetName

func (module *BBPWMModule) GetName() string

func (*BBPWMModule) SetDuty

func (module *BBPWMModule) SetDuty(pin Pin, ns int64) error

Set the duty time, the amount of time during each period that that output is HIGH.

func (*BBPWMModule) SetOptions

func (module *BBPWMModule) SetOptions(options map[string]interface{}) error

Set options of the module. Parameters we look for include: - "pins" - an object of type DTGPIOModulePinDefMap

func (*BBPWMModule) SetPeriod

func (module *BBPWMModule) SetPeriod(pin Pin, ns int64) error

Set the period of this pin, in nanoseconds

type BBPWMModuleOpenPin

type BBPWMModuleOpenPin struct {
	// contains filtered or unexported fields
}

type BBPWMModulePinDef

type BBPWMModulePinDef struct {
	// contains filtered or unexported fields
}

type BBPWMModulePinDefMap

type BBPWMModulePinDefMap map[Pin]*BBPWMModulePinDef

type BeagleBoneBlackDriver

type BeagleBoneBlackDriver struct {
	// contains filtered or unexported fields
}

func NewBeagleboneBlackDTDriver

func NewBeagleboneBlackDTDriver() *BeagleBoneBlackDriver

func (*BeagleBoneBlackDriver) Close

func (d *BeagleBoneBlackDriver) Close()

func (*BeagleBoneBlackDriver) GetModules

func (d *BeagleBoneBlackDriver) GetModules() map[string]Module

func (*BeagleBoneBlackDriver) Init

func (d *BeagleBoneBlackDriver) Init() error

func (*BeagleBoneBlackDriver) MatchesHardwareConfig

func (d *BeagleBoneBlackDriver) MatchesHardwareConfig() bool

Examine the hardware environment and determine if this driver will handle it. Note: this replaces the old detection which mostly used "uname -a" for BeagleBone detection, but this was unreliable with too many edge cases. Now, it looks for specific driver config. This becomes less based on disto etc and more based on capability surfaced via device drivers.

func (*BeagleBoneBlackDriver) PinMap

func (d *BeagleBoneBlackDriver) PinMap() (pinMap HardwarePinMap)

type BeaglePin

type BeaglePin struct {
	// contains filtered or unexported fields
}

type BitShiftOrder

type BitShiftOrder byte
const (
	LSBFIRST BitShiftOrder = iota
	MSBFIRST
)

type DTGPIOModule

type DTGPIOModule struct {
	// contains filtered or unexported fields
}

func NewDTGPIOModule

func NewDTGPIOModule(name string) (result *DTGPIOModule)

func (*DTGPIOModule) ClosePin

func (module *DTGPIOModule) ClosePin(pin Pin) error

func (*DTGPIOModule) DigitalRead

func (module *DTGPIOModule) DigitalRead(pin Pin) (value int, e error)

func (*DTGPIOModule) DigitalWrite

func (module *DTGPIOModule) DigitalWrite(pin Pin, value int) (e error)

func (*DTGPIOModule) Disable

func (module *DTGPIOModule) Disable() error

disables module and release any pins assigned.

func (*DTGPIOModule) Enable

func (module *DTGPIOModule) Enable() error

enable GPIO module. It doesn't allocate any pins immediately.

func (*DTGPIOModule) GetName

func (module *DTGPIOModule) GetName() string

func (*DTGPIOModule) PinMode

func (module *DTGPIOModule) PinMode(pin Pin, mode PinIOMode) error

func (*DTGPIOModule) SetOptions

func (module *DTGPIOModule) SetOptions(options map[string]interface{}) error

Set options of the module. Parameters we look for include: - "pins" - an object of type DTGPIOModulePinDefMap

type DTGPIOModuleOpenPin

type DTGPIOModuleOpenPin struct {
	// contains filtered or unexported fields
}

type DTGPIOModulePinDef

type DTGPIOModulePinDef struct {
	// contains filtered or unexported fields
}

Represents the definition of a GPIO pin, which should contain all the info required to open, close, read and write the pin using FS drivers.

type DTGPIOModulePinDefMap

type DTGPIOModulePinDefMap map[Pin]*DTGPIOModulePinDef

A map of GPIO pin definitions.

type DTI2CDevice

type DTI2CDevice struct {
	// contains filtered or unexported fields
}

func NewDTI2CDevice

func NewDTI2CDevice(module *DTI2CModule, address int) *DTI2CDevice

func (*DTI2CDevice) Read

func (device *DTI2CDevice) Read(command byte, numBytes int) ([]byte, error)

func (*DTI2CDevice) ReadByte

func (device *DTI2CDevice) ReadByte(command byte) (byte, error)

Read 1 byte from the bus

func (*DTI2CDevice) Write

func (device *DTI2CDevice) Write(command byte, data []byte) (e error)

func (*DTI2CDevice) WriteByte

func (device *DTI2CDevice) WriteByte(command byte, value byte) error

type DTI2CModule

type DTI2CModule struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func NewDTI2CModule

func NewDTI2CModule(name string) (result *DTI2CModule)

func (*DTI2CModule) Disable

func (module *DTI2CModule) Disable() error

disables module and release any pins assigned.

func (*DTI2CModule) Enable

func (module *DTI2CModule) Enable() error

enable this I2C module

func (*DTI2CModule) GetDevice

func (module *DTI2CModule) GetDevice(address int) I2CDevice

func (*DTI2CModule) GetName

func (module *DTI2CModule) GetName() string

func (*DTI2CModule) SetOptions

func (module *DTI2CModule) SetOptions(options map[string]interface{}) error

Accept options for the I2C module. Expected options include:

  • "device" - a string that identifies the device file, e.g. "/dev/i2c-1".
  • "pins" - an object of type DTI2CModulePins that identifies the pins that will be assigned when this module is enabled.

type DTI2CModulePins

type DTI2CModulePins []Pin

A list of the pins that are allocated when the bus is enabled. We don't need to know what these mean within the module. We just need them so we can mark them allocated.

type DTLEDModule

type DTLEDModule struct {
	// contains filtered or unexported fields
}

This is a module to support the onboard LED functions. While these are actually attached to GPIO pins that are not exposed on the expansion headers, we can't use GPIO, as a driver is present that provides ways to map what is displayed on the LEDs.

func NewDTLEDModule

func NewDTLEDModule(name string) *DTLEDModule

func (*DTLEDModule) Disable

func (m *DTLEDModule) Disable() error

func (*DTLEDModule) Enable

func (m *DTLEDModule) Enable() error

func (*DTLEDModule) GetLED

func (m *DTLEDModule) GetLED(led string) (LEDModuleLED, error)

Get a LED to manipulate. 'led' must be 0 to 3.

func (*DTLEDModule) GetName

func (m *DTLEDModule) GetName() string

func (*DTLEDModule) SetOptions

func (m *DTLEDModule) SetOptions(options map[string]interface{}) error

type DTLEDModuleLED

type DTLEDModuleLED struct {
	// contains filtered or unexported fields
}

This is a module to support the onboard LED functions. While these are actually attached to GPIO pins that are not exposed on the expansion headers, we can't use GPIO, as a driver is present that provides ways to map what is displayed on the LEDs.

func (*DTLEDModuleLED) SetOn

func (led *DTLEDModuleLED) SetOn(on bool) error

func (*DTLEDModuleLED) SetTrigger

func (led *DTLEDModuleLED) SetTrigger(trigger string) error

Set the trigger for the LED. The values come from /sys/class/leds/*/trigger. This tells the driver what should be displayed on the LED. The useful values include:

  • none The LED can be set up programmatic control. If you want to turn a LED on and off yourself, you want this mode.
  • nand-disk Automatically displays nand disk activity
  • mmc0 Show MMC0 activity.
  • mmc1 Show MMC1 activity. By default, USR3 is configured for mmc1.
  • timer
  • heartbeat Show a heartbeat for system functioning. By default, USR0 is configured for heartbeat.
  • cpu0 Show CPU activity. By default, USR2 is configured for cpu0.

For BeagleBone black system defaults (at least for Angstrom are): - USR0: heartbeat - USR1: mmc0 - USR2: cpu0 - USR3: mmc1 For Raspberry Pi is mmc0.

type DTLEDModulePins

type DTLEDModulePins map[string]string

A map of pin names (e.g. "USR0") to their path e.g. /sys/class/leds/{led}/

type DTPinConfig

type DTPinConfig struct {
	// contains filtered or unexported fields
}

DTPinConfig represents configuration information for a pin used in a device-tree based driver, which typically hold the same details.

type GPIOModule

type GPIOModule interface {
	Module

	PinMode(pin Pin, mode PinIOMode) (e error)
	DigitalWrite(pin Pin, value int) (e error)
	DigitalRead(pin Pin) (result int, e error)
	ClosePin(pin Pin) (e error)
}

func GetGPIOModule

func GetGPIOModule() (GPIOModule, error)

Helper function to get GPIO module

type HardwareDriver

type HardwareDriver interface {
	// Each driver is responsible for evaluating whether it applies to the current hardware
	// configuration or not. If this function returns false, the driver will not be used and Init
	// will not be called. If this function returns true, the driver may be called, in which case
	// Init will then be called
	MatchesHardwareConfig() bool

	// Initialise the driver.
	Init() (e error)

	// Return a module by name, or nil if undefined. The module names can be different between types of boards.
	GetModules() map[string]Module

	// Return the pin map for the driver, listing all supported pins and their capabilities
	PinMap() (pinMap HardwarePinMap)

	// Close the driver before destruction
	Close()
}

This is the interface that hardware drivers implement. Generally all drivers are created but not initialised. If MatchesHardwareConfig() is true and the driver is selected, Init() will be called.

func GetDriver

func GetDriver() HardwareDriver

Retrieve the current hardware driver.

type HardwarePinMap

type HardwarePinMap map[Pin]*PinDef

func GetDefinedPins

func GetDefinedPins() HardwarePinMap

Returns a map of the hardware pins. This will only work once the driver is set.

func (HardwarePinMap) Add

func (m HardwarePinMap) Add(pin Pin, names []string, modules []string)

Add a pin to the map

func (HardwarePinMap) GetPin

func (m HardwarePinMap) GetPin(pin Pin) *PinDef

Given a pin number, return it's PinDef, or nil if that pin is not defined in the map

type I2CDevice

type I2CDevice interface {
	// Read a single byte from a register on the device.
	ReadByte(command byte) (byte, error)

	// Write a single byte to a register on the device.
	WriteByte(command byte, value byte) error

	// Read one or more bytes from the selected slave.
	Read(command byte, numBytes int) ([]byte, error)

	// Write one or more bytes to the selected slave.
	Write(command byte, buffer []byte) (e error)
}

An object that represents a device on a bus. Once an i2c module has been enabled, you can use GetDevice to get an instance of i2c device. You can then talk to the device directly with the supported operations.

type I2CModule

type I2CModule interface {
	Module

	GetDevice(address int) I2CDevice
}

Interface for I2C implementations. Assumes that this device is the only bus master, so initiates all transactions. An I2C module supports exactly one i2c bus, so for systems with multiple i2c busses, the driver will create an instance for each accessible i2c bus.

type LEDModule

type LEDModule interface {
	Module

	GetLED(led string) (LEDModuleLED, error)
}

Interface for controlling on-board LEDs, modelled on /sys/class/leds

type LEDModuleLED

type LEDModuleLED interface {
	SetTrigger(trigger string) error
	SetOn(on bool) error
}

LED from the an LEDModule

type Module

type Module interface {
	// Set parameters require to initialise the module. Generally should be called before Enable() is called,
	// but this may depend on the module.
	SetOptions(map[string]interface{}) error

	// enables the module for use.
	Enable() error

	// disables module and releases pins.
	Disable() error

	// Return the module name so it can be used for error reporting
	GetName() string
}

Generic interface type for all modules.

func GetModule

func GetModule(name string) (Module, error)

Get a module by name. If driver is not set, it will return an error. If the driver does not support that module,

type ODroidC1AnalogModule

type ODroidC1AnalogModule struct {
	// contains filtered or unexported fields
}

ODroidC1AnalogModule is a module for handling the Odroid C1 analog hardware, which is not generic.

func NewODroidC1AnalogModule

func NewODroidC1AnalogModule(name string) (result *ODroidC1AnalogModule)

func (*ODroidC1AnalogModule) AnalogRead

func (module *ODroidC1AnalogModule) AnalogRead(pin Pin) (value int, e error)

func (*ODroidC1AnalogModule) Disable

func (module *ODroidC1AnalogModule) Disable() error

disables module and release any pins assigned.

func (*ODroidC1AnalogModule) Enable

func (module *ODroidC1AnalogModule) Enable() error

enable GPIO module. It doesn't allocate any pins immediately.

func (*ODroidC1AnalogModule) GetName

func (module *ODroidC1AnalogModule) GetName() string

func (*ODroidC1AnalogModule) SetOptions

func (module *ODroidC1AnalogModule) SetOptions(options map[string]interface{}) error

Set options of the module. Parameters we look for include: - "pins" - an object of type ODroidC1AnalogModulePinDefMap

type ODroidC1AnalogModuleOpenPin

type ODroidC1AnalogModuleOpenPin struct {
	// contains filtered or unexported fields
}

type ODroidC1AnalogModulePinDef

type ODroidC1AnalogModulePinDef struct {
	// contains filtered or unexported fields
}

Represents the definition of an analog pin, which should contain all the info required to open, close, read and write the pin using FS drivers.

type ODroidC1AnalogModulePinDefMap

type ODroidC1AnalogModulePinDefMap map[Pin]*ODroidC1AnalogModulePinDef

A map of GPIO pin definitions.

type OdroidC1Driver

type OdroidC1Driver struct {
	// contains filtered or unexported fields
}

func NewOdroidC1Driver

func NewOdroidC1Driver() *OdroidC1Driver

func (*OdroidC1Driver) Close

func (d *OdroidC1Driver) Close()

func (*OdroidC1Driver) GetModules

func (d *OdroidC1Driver) GetModules() map[string]Module

func (*OdroidC1Driver) Init

func (d *OdroidC1Driver) Init() error

func (*OdroidC1Driver) MatchesHardwareConfig

func (d *OdroidC1Driver) MatchesHardwareConfig() bool

Examine the hardware environment and determine if this driver will handle it. For Odroid C1, it's easy: /proc/cpuinfo identifies it.

func (*OdroidC1Driver) PinMap

func (d *OdroidC1Driver) PinMap() (pinMap HardwarePinMap)

type PWMModule

type PWMModule interface {
	Module

	EnablePin(pin Pin, enabled bool) error

	// Set the period of this pin, in nanoseconds
	SetPeriod(pin Pin, ns int64) error

	// Set the duty time, the amount of time during each period that that output is HIGH.
	SetDuty(pin Pin, ns int64) error
}

type Pin

type Pin int

func GetPin

func GetPin(pinName string) (Pin, error)

Returns a Pin given a canonical name for the pin. e.g. to get the pin number of P8.13 on a beaglebone,

pin := hwio.GetPin("P8.13")

Order of search is: - search hwRefs in the pin map in order. This function should not generally be relied on for performance. For max speed, call this for each pin you use once on init, and use the returned Pin values thereafter. Search is case sensitive at the moment @todo GetPin: consider making it case-insensitive on name @todo GetPin: consider allowing an int or int as string to identify logical pin directly

func GetPinWithMode

func GetPinWithMode(cname string, mode PinIOMode) (pin Pin, e error)

Shortcut for calling GetPin and then PinMode.

type PinDef

type PinDef struct {
	// contains filtered or unexported fields
}

func (*PinDef) Names

func (pd *PinDef) Names() string

From the hwPinRefs, construct a string by appending them together. Not brilliantly efficient, but its most for diagnostics anyway.

func (*PinDef) String

func (pd *PinDef) String() string

Provide a string representation of a logic pin and the capabilties it supports.

type PinIOMode

type PinIOMode int

Definitions relating to pins.

const (
	INPUT PinIOMode = iota
	OUTPUT
	INPUT_PULLUP
	INPUT_PULLDOWN
)

The modes for PinMode.

func (PinIOMode) String

func (mode PinIOMode) String() string

String representation of pin IO mode

type PinList

type PinList []Pin

type PreassignedModule

type PreassignedModule struct {
	// contains filtered or unexported fields
}

This is a dummy module for devices that have pins that are pre-assigned, but not to any of the supported modules on the device. It is passed a list of these pre-assigned pins. e.g. on BeagleBone Black, it covers pins that are defined for HDMI, MMC and mcasp0. On the default configuration, these pins are pre-assigned with device tree configuration, so they cannot be assigned for gpio (without custom device tree)

func NewPreassignedModule

func NewPreassignedModule(name string) (result *PreassignedModule)

func (*PreassignedModule) Disable

func (module *PreassignedModule) Disable() error

func (*PreassignedModule) Enable

func (module *PreassignedModule) Enable() error

func (*PreassignedModule) GetName

func (module *PreassignedModule) GetName() string

func (*PreassignedModule) SetOptions

func (module *PreassignedModule) SetOptions(options map[string]interface{}) error

type RaspberryPiDTDriver

type RaspberryPiDTDriver struct {
	// contains filtered or unexported fields
}

func NewRaspPiDTDriver

func NewRaspPiDTDriver() *RaspberryPiDTDriver

func (*RaspberryPiDTDriver) BoardRevision

func (d *RaspberryPiDTDriver) BoardRevision() pinoutRevision

Determine the version of Raspberry Pi. This discussion http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=23989 was used to determine the algorithm, specifically the comment by gordon@drogon.net It will return 1 or 2.

func (*RaspberryPiDTDriver) Close

func (d *RaspberryPiDTDriver) Close()

func (*RaspberryPiDTDriver) GetModules

func (d *RaspberryPiDTDriver) GetModules() map[string]Module

func (*RaspberryPiDTDriver) Init

func (d *RaspberryPiDTDriver) Init() error

func (*RaspberryPiDTDriver) MatchesHardwareConfig

func (d *RaspberryPiDTDriver) MatchesHardwareConfig() bool

func (*RaspberryPiDTDriver) PinMap

func (d *RaspberryPiDTDriver) PinMap() (pinMap HardwarePinMap)

type SPIModule

type SPIModule interface {
	Module

	// Select the device, and send data to it
	Write(slaveSelect int, data []byte) (e error)

	// Select the device, and read data from it
	Read(slaveSelect int, data []byte) (nBytes int, e error)
}

Interface for SPI implementations

type TestDriver

type TestDriver struct {
	// contains filtered or unexported fields
}

func (*TestDriver) Close

func (d *TestDriver) Close()

func (*TestDriver) GetModules

func (d *TestDriver) GetModules() map[string]Module

func (*TestDriver) Init

func (d *TestDriver) Init() error

func (*TestDriver) MatchesHardwareConfig

func (d *TestDriver) MatchesHardwareConfig() bool

func (*TestDriver) PinMap

func (d *TestDriver) PinMap() HardwarePinMap

// Mock has a fixed set of hardcoded pins with different capabilities

Directories

Path Synopsis
devices

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL