govattu

package module
v0.1.0-beta.1 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2022 License: MIT Imports: 11 Imported by: 3

README

govattu

govattu

Golang library (or just simple wrapper) for accessing /dev/mem features on raspberry pi

based on wiringPi (http://wiringpi.com/) and http://www.airspayce.com/mikem/bcm2835/ Butchered go-rpio library and mutilated to this library with added features https://github.com/stianeikeland/go-rpio Feel free to merge hardwarePWM feature to go-rpio if my API design sucks.

Features

  • GPIO input/output
  • GPIO events rise/fall/level/asyncrise/asyncfall -Nice to use with command buttons, can do without aggressive polling
  • HardwarePWM
    • only PWM0 tested

Features to do

  • Raspberry jams with /dev/gpiomem when writing to mempwm[PWMMEM_RNG1] Before solving problem, run this as root (sudo)
  • Multiple pin reads and writes. For parrallel interfacing LCDs etc...

Design principles

  • No c code, no external dependencies
  • This library contains only tricks that are not implemented with drivers like UART or I2C or SPI
  • Only low level functionalities, no lcd functions or software pwm. They are implemented on higher levels
  • API is going to freeze, but not yet

Pin numbering

Govattu uses so called BCM numbering. BCM and GPIO numbers go with same way

How to use

import "github.com/hjkoskel/govattu"

Initialize

hw, err := govattu.Open()

For creating unit tests or mocups there is inteface called Vattu and DoNothingPi example implementation

Basic gpio functions are

hw.PinClear(pin uint8) //for output 0
hw.PinSet(pin uint8) //For output 1
hw.ReadPinLevel(pin uint8) bool  //For input
hw.PullMode(pin uint8, pull PinPull) //Set pin pullup setting  govattu.PULLoff  or govattu.PULLdown or govattu.PULLup

Setting up hardwarePWM. If calculating divisors and ranges is hard. Please check simple example project https://github.com/hjkoskel/pipwm

hw.PinMode(18, govattu.ALT5) //ALT5 function for 18 is PWM0
hw.PwmSetMode(true, true, false, false) // PwmSetMode(en0 bool, ms0 bool, en1 bool, ms1 bool)   enable and set to mark-space mode for pwm0 and pwm1
hw.PwmSetClock(divisor uint32)  //Set clock divisor
hw.Pwm0SetRange(ra uint32) //SET RANGE
hw.Pwm0Set(r uint32) //Set pwm

This library also have function for setting events flags. Very usefull if code monitors button presses. It is handy to detect fall event and later check "did events happend"

hw.ZeroPinEventDetectMask() //At initialization
/*
Possible flags (bitwise or together)
PINE_AFALL
PINE_ARISE
PINE_LOW
PINE_HIGH
PINE_FALL
PINE_RISE

*/
hw.SetPinEventDetectMask(buttonPinNumber, govattu.PINE_FALL|govattu.PINE_RISE) //Set event detection flags for specific pin

//And when polling detected events
if hw.ReadPinEvent(buttonPinNumber) {
  //Process event here
	hw.ResetPinEvent(buttonPinNumber) //This is needed for clearing before next readPinEvent
}

Documentation

Overview

donothingpi Implements vattu interface. Minimal implementation for testing software. Also acts as simple example

Utilities for hardware PWM control

Functions for calculating

Index

Constants

View Source
const (
	CLKLEN  = 0xA8
	GPIOLEN = 0xB4
	PWMLEN  = 0x28
)

Memory map sizes

View Source
const (
	BASEADDRCLK  uint32 = 0x00101000
	BASEADDRGPIO uint32 = 0x00200000
	BASEADDRPWM  uint32 = 0x0020C000
)
View Source
const (
	GPIOMEMOFF_MODE         uint32 = 0
	GPIOMEMOFF_SET          uint32 = 7
	GPIOMEMOFF_CLR          uint32 = 10
	GPIOMEMOFF_LEVEL        uint32 = 13
	GPIOMEMOFF_EVENTDET     uint32 = 16
	GPIOMEMOFF_RISEVENTDET  uint32 = 19
	GPIOMEMOFF_FALLEVENTDET uint32 = 22
	GPIOMEMOFF_HIDET        uint32 = 25
	GPIOMEMOFF_LODET        uint32 = 28
	GPIOMEMOFF_ASYNCRISEDET uint32 = 31
	GPIOMEMOFF_ASYNCFALLDET uint32 = 34
	GPIOMEMOFF_PULL         uint32 = 37
	GPIOMEMOFF_PULLCLK      uint32 = 38
)

0x7E00 0000 is base address on datasheet

View Source
const (
	CM_GP0CTL uint32 = 0
	CM_GP0DIV uint32 = 1
	CM_GP1CTL uint32 = 2
	CM_GP1DIV uint32 = 3
	CM_GP2CTL uint32 = 4
	CM_GP2DIV uint32 = 5
)

Clock memory area register names from datasheet

View Source
const (
	PWMMEM_CTL  uint32 = 0
	PWMMEM_STA  uint32 = 1
	PWMMEM_DMAC uint32 = 2
	PWMMEM_RNG1 uint32 = 4
	PWMMEM_DAT1 uint32 = 5
	PWMMEM_FIF1 uint32 = 6
	PWMMEM_RNG2 uint32 = 8
	PWMMEM_DAT2 uint32 = 9
)
View Source
const (
	PWMCLK_CNTL uint32 = 40
	PWMCLK_DIV  uint32 = 41
)

these come from wiringpi

View Source
const (
	PWM0_ENABLE  uint32 = 0x0001
	PWM1_ENABLE  uint32 = 0x0100
	PWM0_MS_MODE uint32 = 0x0080
	PWM1_MS_MODE uint32 = 0x8000
)

Flages to PWM regs

View Source
const (
	BCMPASSWORD uint32 = 0x5A000000
)
View Source
const (
	HWPWM0PIN = 18
)
View Source
const MAXPWMC uint32 = 4095 //2090
View Source
const MAXPWMR uint32 = 4096
View Source
const MINPWMC uint32 = 2
View Source
const PWMCLOCKNS float64 = 52.0833333333 //=(1000*1000*1000)/19200000  104.1666667 / 2.0 //One "block" takes this long

Variables

This section is empty.

Functions

This section is empty.

Types

type AltSetting

type AltSetting byte

000 = GPIO Pin X is an input 001 = GPIO Pin X is an output 010 = GPIO Pin X takes alternate function 5 011 = GPIO Pin X takes alternate function 4 100 = GPIO Pin X takes alternate function 0 101 = GPIO Pin X takes alternate function 1 110 = GPIO Pin X takes alternate function 2 111 = GPIO Pin X takes alternate function 3

const (
	ALTinput AltSetting = iota
	ALToutput
	ALT5
	ALT4
	ALT0
	ALT1
	ALT2
	ALT3
)

type DoNothingPi

type DoNothingPi struct {
}

func (*DoNothingPi) Close

func (p *DoNothingPi) Close() error

func (*DoNothingPi) PinClear

func (p *DoNothingPi) PinClear(pin uint8)

func (*DoNothingPi) PinMode

func (p *DoNothingPi) PinMode(pin uint8, alt AltSetting)

func (*DoNothingPi) PinSet

func (p *DoNothingPi) PinSet(pin uint8)

func (*DoNothingPi) PullMode

func (p *DoNothingPi) PullMode(pin uint8, pull PinPull)

func (*DoNothingPi) Pwm0Set

func (p *DoNothingPi) Pwm0Set(r uint32)

func (*DoNothingPi) Pwm0SetRange

func (p *DoNothingPi) Pwm0SetRange(ra uint32)

func (*DoNothingPi) Pwm1Set

func (p *DoNothingPi) Pwm1Set(r uint32)

func (*DoNothingPi) Pwm1SetRange

func (p *DoNothingPi) Pwm1SetRange(ra uint32)

func (*DoNothingPi) PwmSetClock

func (p *DoNothingPi) PwmSetClock(divisor uint32)

func (*DoNothingPi) PwmSetMode

func (p *DoNothingPi) PwmSetMode(en0 bool, ms0 bool, en1 bool, ms1 bool)

func (*DoNothingPi) ReadAllPinEvents

func (p *DoNothingPi) ReadAllPinEvents() uint64

func (*DoNothingPi) ReadAllPinLevels

func (p *DoNothingPi) ReadAllPinLevels() uint64

func (*DoNothingPi) ReadPinEvent

func (p *DoNothingPi) ReadPinEvent(pin uint8) bool

func (*DoNothingPi) ReadPinLevel

func (p *DoNothingPi) ReadPinLevel(pin uint8) bool

func (*DoNothingPi) ResetPinEvent

func (p *DoNothingPi) ResetPinEvent(pin uint8)

func (*DoNothingPi) SetPWM0Hi

func (p *DoNothingPi) SetPWM0Hi()

func (*DoNothingPi) SetPWM0Lo

func (p *DoNothingPi) SetPWM0Lo()

func (*DoNothingPi) SetPinEventDetectMask

func (p *DoNothingPi) SetPinEventDetectMask(pin uint8, pine PinEventMask)

func (*DoNothingPi) SetToHwPWM0

func (p *DoNothingPi) SetToHwPWM0(rf *RfSettings)

func (*DoNothingPi) ZeroPinEventDetectMask

func (p *DoNothingPi) ZeroPinEventDetectMask()

type PinConfig

type PinConfig struct {
	Alt byte
}

type PinEventMask

type PinEventMask byte

PINE, Pin Event masks

const (
	PINE_AFALL PinEventMask = 1
	PINE_ARISE PinEventMask = 2
	PINE_LOW   PinEventMask = 4
	PINE_HIGH  PinEventMask = 8
	PINE_FALL  PinEventMask = 16
	PINE_RISE  PinEventMask = 32
)

type PinPull

type PinPull byte
const (
	PULLoff PinPull = iota
	PULLdown
	PULLup
)

Raspberry have pull up and downs

type RaspiHw

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

Just empty struct. Might require some stored state later

func (*RaspiHw) Close

func (p *RaspiHw) Close() error

Close unmaps GPIO memory

func (*RaspiHw) PinClear

func (p *RaspiHw) PinClear(pin uint8)

func (*RaspiHw) PinMode

func (p *RaspiHw) PinMode(pin uint8, alt AltSetting)

func (*RaspiHw) PinSet

func (p *RaspiHw) PinSet(pin uint8)

func (*RaspiHw) PullMode

func (p *RaspiHw) PullMode(pin uint8, pull PinPull)

func (*RaspiHw) Pwm0Set

func (p *RaspiHw) Pwm0Set(r uint32)

func (*RaspiHw) Pwm0SetRange

func (p *RaspiHw) Pwm0SetRange(ra uint32)

func (*RaspiHw) Pwm1Set

func (p *RaspiHw) Pwm1Set(r uint32)

func (*RaspiHw) Pwm1SetRange

func (p *RaspiHw) Pwm1SetRange(ra uint32)

func (*RaspiHw) PwmSetClock

func (p *RaspiHw) PwmSetClock(divisor uint32)

TODO not quite clear why PWMCLK_CNTL uint32 = 40 PWMCLK_DIV uint32 = 41

https://groups.google.com/forum/#!topic/bcm2835/_foWTDSwF8k this code relies on the description given in http://www.scribd.com/doc/127599939/BCM2835-Audio-clocks#scribd TODO: Check fractional part of divisor

func (*RaspiHw) PwmSetMode

func (p *RaspiHw) PwmSetMode(en0 bool, ms0 bool, en1 bool, ms1 bool)

enable and disable. Set to mark-space mode

func (*RaspiHw) ReadAllPinEvents

func (p *RaspiHw) ReadAllPinEvents() uint64

func (*RaspiHw) ReadAllPinLevels

func (p *RaspiHw) ReadAllPinLevels() uint64

func (*RaspiHw) ReadPinEvent

func (p *RaspiHw) ReadPinEvent(pin uint8) bool

func (*RaspiHw) ReadPinLevel

func (p *RaspiHw) ReadPinLevel(pin uint8) bool

func (*RaspiHw) ResetPinEvent

func (p *RaspiHw) ResetPinEvent(pin uint8)

func (*RaspiHw) SetPWM0Hi

func (p *RaspiHw) SetPWM0Hi()

func (*RaspiHw) SetPWM0Lo

func (p *RaspiHw) SetPWM0Lo()

func (*RaspiHw) SetPinEventDetectMask

func (p *RaspiHw) SetPinEventDetectMask(pin uint8, pine PinEventMask)

func (*RaspiHw) SetToHwPWM0

func (p *RaspiHw) SetToHwPWM0(rf *RfSettings)

func (*RaspiHw) ZeroPinEventDetectMask

func (p *RaspiHw) ZeroPinEventDetectMask()

type RfPulseSettings

type RfPulseSettings struct {
	On  time.Duration
	Off time.Duration
}

func (*RfPulseSettings) DeviationPercent

func (p *RfPulseSettings) DeviationPercent(ref RfPulseSettings) (float64, float64)
func (p *RfPulseSettings) IsNear(ref RfPulseSettings, onDeviationPercent float32, offDeviationPercent float32) bool {
	math.Abs(p.Off.Nanoseconds() - ref.Off.Nanoseconds())
	math.Abs
	deltaOnNs := p.On.Nanoseconds() - ref.On.Nanoseconds()
}

func (*RfPulseSettings) Equal

func (p *RfPulseSettings) Equal(a RfPulseSettings) bool

func (*RfPulseSettings) GetFastSettings

func (p *RfPulseSettings) GetFastSettings() RfSettings

Get settings optimized for fast use (fatpuppy)

func (*RfPulseSettings) GetNaiveSettings

func (p *RfPulseSettings) GetNaiveSettings() (RfSettings, error)

Naive solution, rouding errors.... take smallest common deteminator

func (*RfPulseSettings) GetSettings

func (p *RfPulseSettings) GetSettings() (RfSettings, error)

type RfSettings

type RfSettings struct {
	Pwmc uint32 //Range 2-2090
	Pwmr uint32 //TODO range
	Pwm  uint32 //TODO range
}

func (*RfSettings) Equal

func (p *RfSettings) Equal(a RfSettings) bool

func (*RfSettings) EqualNear

func (p *RfSettings) EqualNear(a RfSettings) bool

func (*RfSettings) GetTiming

func (p *RfSettings) GetTiming() RfPulseSettings

func (*RfSettings) IsOffline

func (p *RfSettings) IsOffline() bool

func (*RfSettings) SetFromSettings

func (p *RfSettings) SetFromSettings(newSettings RfPulseSettings) error

type Vattu

type Vattu interface {
	PwmSetMode(en0 bool, ms0 bool, en1 bool, ms1 bool)
	Pwm0SetRange(ra uint32)
	Pwm1SetRange(ra uint32)
	Pwm0Set(r uint32)
	Pwm1Set(r uint32)

	SetPWM0Hi()
	SetPWM0Lo()
	SetToHwPWM0(rf *RfSettings)

	PwmSetClock(divisor uint32)
	Close() error

	PinClear(pin uint8)
	PinSet(pin uint8)
	PinMode(pin uint8, alt AltSetting)
	ReadPinLevel(pin uint8) bool
	ReadAllPinLevels() uint64
	ReadPinEvent(pin uint8) bool
	ReadAllPinEvents() uint64
	ResetPinEvent(pin uint8)
	ZeroPinEventDetectMask()
	SetPinEventDetectMask(pin uint8, pine PinEventMask)
	PullMode(pin uint8, pull PinPull)
}

Vattu is interface for interfacing real hardware or fake

func Open

func Open() (Vattu, error)

Jump to

Keyboard shortcuts

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