2017-04-21 15:41:11 +08:00
|
|
|
package sysfs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
|
|
|
// PWMPin is the interface for sysfs PWM interactions
|
2017-04-22 01:50:17 +08:00
|
|
|
type PWMPinner interface {
|
2017-04-21 15:41:11 +08:00
|
|
|
// Export exports the pin for use by the operating system
|
|
|
|
Export() error
|
2017-04-21 18:55:00 +08:00
|
|
|
// Unexport unexports the pin and releases the pin from the operating system
|
|
|
|
Unexport() error
|
|
|
|
// Enable enables/disables the PWM pin
|
2017-04-21 15:41:11 +08:00
|
|
|
Enable(val string) (err error)
|
|
|
|
// Period returns the current PWM period for pin
|
|
|
|
Period() (period string, err error)
|
|
|
|
// WriteDuty writes the duty cycle to the pin
|
|
|
|
WriteDuty(duty string) (err error)
|
|
|
|
}
|
|
|
|
|
2017-04-22 01:50:17 +08:00
|
|
|
type PWMPin struct {
|
2017-04-21 15:41:11 +08:00
|
|
|
pin string
|
2017-04-22 01:29:55 +08:00
|
|
|
Chip string
|
2017-04-21 15:41:11 +08:00
|
|
|
write func(path string, data []byte) (i int, err error)
|
|
|
|
read func(path string) ([]byte, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewPwmPin returns a new pwmPin
|
2017-04-22 01:50:17 +08:00
|
|
|
func NewPWMPin(pin int) *PWMPin {
|
|
|
|
return &PWMPin{
|
2017-04-22 01:29:55 +08:00
|
|
|
pin: strconv.Itoa(pin),
|
|
|
|
Chip: "0",
|
|
|
|
read: readPwmFile,
|
|
|
|
write: writePwmFile}
|
2017-04-21 15:41:11 +08:00
|
|
|
}
|
|
|
|
|
2017-04-21 18:55:00 +08:00
|
|
|
// Export writes pin to pwm export path
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) Export() (err error) {
|
2017-04-22 01:29:55 +08:00
|
|
|
_, err = p.write(p.pwmExportPath(), []byte(p.pin))
|
2017-04-21 18:55:00 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unexport writes pin to pwm unexport path
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) Unexport() (err error) {
|
2017-04-22 01:29:55 +08:00
|
|
|
_, err = p.write(p.pwmUnexportPath(), []byte(p.pin))
|
2017-04-21 18:55:00 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-04-21 15:41:11 +08:00
|
|
|
// Enable writes value to pwm enable path
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) Enable(val string) (err error) {
|
2017-04-22 01:29:55 +08:00
|
|
|
_, err = p.write(p.pwmEnablePath(), []byte(val))
|
2017-04-21 15:41:11 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Period reads from pwm period path and returns value
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) Period() (period string, err error) {
|
2017-04-22 01:29:55 +08:00
|
|
|
buf, err := p.read(p.pwmPeriodPath())
|
2017-04-21 15:41:11 +08:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return string(buf), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// WriteDuty writes value to pwm duty cycle path
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) WriteDuty(duty string) (err error) {
|
2017-04-22 01:29:55 +08:00
|
|
|
_, err = p.write(p.pwmDutyCyclePath(), []byte(duty))
|
2017-04-21 15:41:11 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// pwmPath returns pwm base path
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) pwmPath() string {
|
2017-04-22 01:29:55 +08:00
|
|
|
return "/sys/class/pwm/pwmchip" + p.Chip
|
2017-04-21 15:41:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// pwmExportPath returns export path
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) pwmExportPath() string {
|
2017-04-22 01:29:55 +08:00
|
|
|
return p.pwmPath() + "/export"
|
2017-04-21 15:41:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// pwmUnexportPath returns unexport path
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) pwmUnexportPath() string {
|
2017-04-22 01:29:55 +08:00
|
|
|
return p.pwmPath() + "/unexport"
|
2017-04-21 15:41:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// pwmDutyCyclePath returns duty_cycle path for specified pin
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) pwmDutyCyclePath() string {
|
2017-04-22 01:29:55 +08:00
|
|
|
return p.pwmPath() + "/pwm" + p.pin + "/duty_cycle"
|
2017-04-21 15:41:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// pwmPeriodPath returns period path for specified pin
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) pwmPeriodPath() string {
|
2017-04-22 01:29:55 +08:00
|
|
|
return p.pwmPath() + "/pwm" + p.pin + "/period"
|
2017-04-21 15:41:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// pwmEnablePath returns enable path for specified pin
|
2017-04-22 01:50:17 +08:00
|
|
|
func (p *PWMPin) pwmEnablePath() string {
|
2017-04-22 01:29:55 +08:00
|
|
|
return p.pwmPath() + "/pwm" + p.pin + "/enable"
|
2017-04-21 15:41:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func writePwmFile(path string, data []byte) (i int, err error) {
|
|
|
|
file, err := OpenFile(path, os.O_WRONLY, 0644)
|
|
|
|
defer file.Close()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return file.Write(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
func readPwmFile(path string) ([]byte, error) {
|
|
|
|
file, err := OpenFile(path, os.O_RDONLY, 0644)
|
|
|
|
defer file.Close()
|
|
|
|
if err != nil {
|
|
|
|
return make([]byte, 0), err
|
|
|
|
}
|
|
|
|
|
|
|
|
buf := make([]byte, 200)
|
|
|
|
var i int
|
|
|
|
i, err = file.Read(buf)
|
|
|
|
if i == 0 {
|
|
|
|
return buf, err
|
|
|
|
}
|
|
|
|
return buf[:i], err
|
|
|
|
}
|