Browse Source

Initial Commit

master
Tim Schuster 2 years ago
commit
db7ec98d2b
Signed by: Tim Schuster <mail@timschuster.info> GPG Key ID: F9E27097EFB77F61

+ 34
- 0
consts.go View File

@@ -0,0 +1,34 @@
1
+package adafruitPCA9685
2
+
3
+import (
4
+	"os"
5
+	"fmt"
6
+	"syscall"
7
+)
8
+
9
+/* https://github.com/adafruit/Adafruit_Python_PCA9685/blob/master/Adafruit_PCA9685/PCA9685.py */
10
+
11
+const (
12
+	c_I2C_SLAVE = 0x0703
13
+	c_PCA9685_ADDRESS = 0x40
14
+	c_MODE1 = 0x00
15
+	c_MODE2 = 0x01
16
+	c_SUBADR1 = 0x02
17
+	c_SUBADR2 = 0x03
18
+	c_SUBADR3 = 0x04
19
+	c_PRESCALE = 0xFE
20
+	c_LED0_ON_L = 0x06
21
+	c_LED0_ON_H = 0x07
22
+	c_LED0_OFF_L = 0x08
23
+	c_LED0_OFF_H = 0x09
24
+	c_ALL_LED_ON_L = 0xFA
25
+	c_ALL_LED_ON_H = 0xFB
26
+	c_ALL_LED_OFF_L = 0xFC
27
+	c_ALL_LED_OFF_H = 0xFD
28
+
29
+	c_RESTART = 0x80
30
+	c_SLEEP = 0x10
31
+	c_ALLCALL = 0x01
32
+	c_INVRT = 0x10
33
+	c_OUTDRV = 0x04
34
+)

+ 28
- 0
helper.go View File

@@ -0,0 +1,28 @@
1
+package adafruitPCA9685
2
+
3
+import (
4
+	"time"
5
+)
6
+
7
+func (p *PCA9685) WaitForOscillator() {
8
+	time.Sleep(200 * time.Millisecond)
9
+}
10
+
11
+func (p *PCA9685) logDebug(msg ...interface{}) {
12
+	if p.debugger == nil {
13
+		return
14
+	}
15
+	p.debugger.Print(msg...)
16
+}
17
+func (p *PCA9685) writeBReg(register, data byte) error {
18
+	return p.dev.WriteReg(register, []byte{data})
19
+}
20
+
21
+func (p *PCA9685) readBReg(register byte) (byte, error) {
22
+	var b = make([]byte, 1)
23
+	err := p.dev.ReadReg(register, b)
24
+	if err != nil {
25
+		return 0, err
26
+	}
27
+	return b[0], nil
28
+}

+ 122
- 0
pca9685.go View File

@@ -0,0 +1,122 @@
1
+package adafruitPCA9685
2
+
3
+import (
4
+	"fmt"
5
+	"golang.org/x/exp/io/i2c"
6
+	"log"
7
+	"math"
8
+)
9
+
10
+type PCA9685 struct {
11
+	dev      *i2c.Device
12
+	mode1    byte
13
+	debugger *log.Logger
14
+}
15
+
16
+func NewPCA9685(address int, bus byte, debug *log.Logger) (*PCA9685, error) {
17
+	i2cDev := fmt.Sprintf("/dev/i2c-%d", i2c)
18
+	d, err := i2c.Open(&i2c.Devfs{Dev: i2cDev}, address)
19
+	if err != nil {
20
+		return nil, err
21
+	}
22
+	pca := &PCA9685{dev: d, debugger: debug}
23
+	pca.logDebug("Setting up Controller")
24
+	err = pca.writeBReg(c_MODE2, c_OUTDRV)
25
+	if err != nil {
26
+		pca.logDebug("Error on write MODE2 OUTDRV : ", err)
27
+		return nil, err
28
+	}
29
+	err = pca.writeBReg(c_MODE2, c_ALLCALL)
30
+	if err != nil {
31
+		pca.logDebug("Error on write MODE2 ALLCALL : ", err)
32
+		return nil, err
33
+	}
34
+	pca.WaitForOscillator()
35
+	pca.mode1, err = pca.readBReg(c_MODE1)
36
+	if err != nil {
37
+		pca.logDebug("Error on read MODE1 : ", err)
38
+		return nil, err
39
+	}
40
+	pca.mode1 = pca.mode1 & (^c_SLEEP)
41
+	if err = pca.writeBReg(c_MODE1, pca.mode1); err != nil {
42
+		pca.logDebug("Error on write MODE1 ", pca.mode1, " : ", err)
43
+	}
44
+	pca.WaitForOscillator()
45
+	pca.logDebug("Controller has finished setup")
46
+	return pca, nil
47
+}
48
+
49
+func (p *PCA9685) SetPWMFreq(freq_hz uint64) error {
50
+	var prescaleval float64 = 25000000.0 // 25 MHz
51
+	prescaleval /= 4096.0                // 12-bit
52
+	prescaleval /= float64(freq_hz)
53
+	prescaleval -= 1.0
54
+	p.logDebug("Setting PWM Frequency to ", freq_hz, " Hz")
55
+	p.logDebug("Estimated pre-scale: ", prescaleval)
56
+	prescale := byte(math.Floor(prescaleval + 0.5))
57
+	p.logDebug("Final pre-scale: ", prescale)
58
+	oldmode, err := p.readBReg(c_MODE1)
59
+	if err != nil {
60
+		p.logDebug("Error on read MODE1: ", err)
61
+		return err
62
+	}
63
+	newmode := (oldmode & 0x7F) | 0x10 // sleep
64
+	if err := p.writeBReg(c_MODE1, newmode); err != nil {
65
+		p.logDebug("Error on write MODE1 ", newmode, " : ", err)
66
+		return err
67
+	}
68
+	if err := p.writeBReg(c_PRESCALE, prescale); err != nil {
69
+		p.logDebug("Error on write PRESCALE ", prescale, " : ", err)
70
+		return err
71
+	}
72
+	if err := p.writeBReg(c_MODE1, oldmode); err != nil {
73
+		p.logDebug("Error on write MODE1 ", oldmode, " : ", err)
74
+		return err
75
+	}
76
+	p.WaitForOscillator()
77
+	if err := p.writeBReg(c_MODE1, oldmode|0x80); err != nil {
78
+		p.logDebug("Error on write MODE1 ", oldmode, " : ", err)
79
+		return err
80
+	}
81
+	return nil
82
+}
83
+
84
+func (p *PCA9685) SetPWM(channel, on, off byte) error {
85
+	if err := p.writeBReg(c_LED0_ON_L+4*channel, on&0xFF); err != nil {
86
+		p.logDebug("Error on write LED0_ON_L : ", err)
87
+		return err
88
+	}
89
+	if err := p.writeBReg(c_LED0_ON_H+4*channel, on>>8); err != nil {
90
+		p.logDebug("Error on write LED0_ON_H : ", err)
91
+		return err
92
+	}
93
+	if err := p.writeBReg(c_LED0_OFF_L+4*channel, off&0xFF); err != nil {
94
+		p.logDebug("Error on write LED0_OFF_ON_L : ", err)
95
+		return err
96
+	}
97
+	if err := p.writeBReg(c_LED0_OFF_H+4*channel, off>>8); err != nil {
98
+		p.logDebug("Error on write LED0_OFF_ON_H : ", err)
99
+		return err
100
+	}
101
+	return nil
102
+}
103
+
104
+func (p *PCA9685) SetAllPWM(on, off byte) error {
105
+	if err := p.writeBReg(c_ALL_LED_ON_L, on&0xFF); err != nil {
106
+		p.logDebug("Error on write LED0_ON_L : ", err)
107
+		return err
108
+	}
109
+	if err := p.writeBReg(c_ALL_LED_ON_H, on>>8); err != nil {
110
+		p.logDebug("Error on write LED0_ON_H : ", err)
111
+		return err
112
+	}
113
+	if err := p.writeBReg(c_ALL_LED_OFF_L, off&0xFF); err != nil {
114
+		p.logDebug("Error on write LED0_OFF_ON_L : ", err)
115
+		return err
116
+	}
117
+	if err := p.writeBReg(c_ALL_LED_OFF_H, off>>8); err != nil {
118
+		p.logDebug("Error on write LED0_OFF_ON_H : ", err)
119
+		return err
120
+	}
121
+	return nil
122
+}

+ 27
- 0
vendor/golang.org/x/exp/LICENSE View File

@@ -0,0 +1,27 @@
1
+Copyright (c) 2009 The Go Authors. All rights reserved.
2
+
3
+Redistribution and use in source and binary forms, with or without
4
+modification, are permitted provided that the following conditions are
5
+met:
6
+
7
+   * Redistributions of source code must retain the above copyright
8
+notice, this list of conditions and the following disclaimer.
9
+   * Redistributions in binary form must reproduce the above
10
+copyright notice, this list of conditions and the following disclaimer
11
+in the documentation and/or other materials provided with the
12
+distribution.
13
+   * Neither the name of Google Inc. nor the names of its
14
+contributors may be used to endorse or promote products derived from
15
+this software without specific prior written permission.
16
+
17
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 22
- 0
vendor/golang.org/x/exp/PATENTS View File

@@ -0,0 +1,22 @@
1
+Additional IP Rights Grant (Patents)
2
+
3
+"This implementation" means the copyrightable works distributed by
4
+Google as part of the Go project.
5
+
6
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
7
+no-charge, royalty-free, irrevocable (except as stated in this section)
8
+patent license to make, have made, use, offer to sell, sell, import,
9
+transfer and otherwise run, modify and propagate the contents of this
10
+implementation of Go, where such license applies only to those patent
11
+claims, both currently owned or controlled by Google and acquired in
12
+the future, licensable by Google that are necessarily infringed by this
13
+implementation of Go.  This grant does not include claims that would be
14
+infringed only as a consequence of further modification of this
15
+implementation.  If you or your agent or exclusive licensee institute or
16
+order or agree to the institution of patent litigation against any
17
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
18
+that this implementation of Go or any code incorporated within this
19
+implementation of Go constitutes direct or contributory patent
20
+infringement, or inducement of patent infringement, then any patent
21
+rights granted to you under this License for this implementation of Go
22
+shall terminate as of the date such litigation is filed.

+ 79
- 0
vendor/golang.org/x/exp/io/i2c/devfs.go View File

@@ -0,0 +1,79 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// +build linux
6
+
7
+package i2c
8
+
9
+import (
10
+	"fmt"
11
+	"io"
12
+	"os"
13
+	"syscall"
14
+
15
+	"golang.org/x/exp/io/i2c/driver"
16
+)
17
+
18
+// Devfs is an I2C driver that works against the devfs.
19
+// You need to load the "i2c-dev" kernel module to use this driver.
20
+type Devfs struct {
21
+	// Dev is the I2C bus device, e.g. /dev/i2c-1. Required.
22
+	Dev string
23
+}
24
+
25
+const (
26
+	i2c_SLAVE  = 0x0703 // TODO(jbd): Allow users to use I2C_SLAVE_FORCE?
27
+	i2c_TENBIT = 0x0704
28
+)
29
+
30
+// TODO(jbd): Support I2C_RETRIES and I2C_TIMEOUT at the driver and implementation level.
31
+
32
+func (d *Devfs) Open(addr int, tenbit bool) (driver.Conn, error) {
33
+	f, err := os.OpenFile(d.Dev, os.O_RDWR, os.ModeDevice)
34
+	if err != nil {
35
+		return nil, err
36
+	}
37
+	conn := &devfsConn{f: f}
38
+	if tenbit {
39
+		if err := conn.ioctl(i2c_TENBIT, uintptr(1)); err != nil {
40
+			conn.Close()
41
+			return nil, fmt.Errorf("cannot enable the 10-bit address mode on bus %v: %v", d.Dev, err)
42
+		}
43
+	}
44
+	if err := conn.ioctl(i2c_SLAVE, uintptr(addr)); err != nil {
45
+		conn.Close()
46
+		return nil, fmt.Errorf("error opening the address (%v) on the bus (%v): %v", addr, d.Dev, err)
47
+	}
48
+	return conn, nil
49
+}
50
+
51
+type devfsConn struct {
52
+	f *os.File
53
+}
54
+
55
+func (c *devfsConn) Tx(w, r []byte) error {
56
+	if w != nil {
57
+		if _, err := c.f.Write(w); err != nil {
58
+			return err
59
+		}
60
+		c.f.Sync()
61
+	}
62
+	if r != nil {
63
+		if _, err := io.ReadFull(c.f, r); err != nil {
64
+			return err
65
+		}
66
+	}
67
+	return nil
68
+}
69
+
70
+func (c *devfsConn) Close() error {
71
+	return c.f.Close()
72
+}
73
+
74
+func (c *devfsConn) ioctl(arg1, arg2 uintptr) error {
75
+	if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, c.f.Fd(), arg1, arg2); errno != 0 {
76
+		return syscall.Errno(errno)
77
+	}
78
+	return nil
79
+}

+ 24
- 0
vendor/golang.org/x/exp/io/i2c/devfs_nonlinux.go View File

@@ -0,0 +1,24 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// +build !linux
6
+
7
+package i2c
8
+
9
+import (
10
+	"errors"
11
+
12
+	"golang.org/x/exp/io/i2c/driver"
13
+)
14
+
15
+// Devfs is no-implementation so developers using cross compilation
16
+// can rely on local tools even though the real implementation isn't
17
+// available on their platform.
18
+type Devfs struct {
19
+	Dev string
20
+}
21
+
22
+func (d *Devfs) Open(addr int, tenbit bool) (driver.Conn, error) {
23
+	return nil, errors.New("not implemented on this platform")
24
+}

+ 24
- 0
vendor/golang.org/x/exp/io/i2c/driver/driver.go View File

@@ -0,0 +1,24 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// Package driver contains interfaces to be implemented by various I2C implementations.
6
+package driver // import "golang.org/x/exp/io/i2c/driver"
7
+
8
+// Opener opens a connection to an I2C device to communicate with
9
+// the I2C address given. If the address is an 10-bit I2C address,
10
+// tenbit is true.
11
+type Opener interface {
12
+	Open(addr int, tenbit bool) (Conn, error)
13
+}
14
+
15
+// Conn represents an active connection to an I2C device.
16
+type Conn interface {
17
+	// Tx first writes w (if not nil), then reads len(r)
18
+	// bytes from device into r (if not nil) in a single
19
+	// I2C transaction.
20
+	Tx(w, r []byte) error
21
+
22
+	// Close closes the connection.
23
+	Close() error
24
+}

+ 70
- 0
vendor/golang.org/x/exp/io/i2c/i2c.go View File

@@ -0,0 +1,70 @@
1
+// Copyright 2016 The Go Authors. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// Package i2c allows users to read from and write to a slave I2C device.
6
+package i2c // import "golang.org/x/exp/io/i2c"
7
+
8
+import (
9
+	"golang.org/x/exp/io/i2c/driver"
10
+)
11
+
12
+const tenbitMask = 1 << 12
13
+
14
+// Device represents an I2C device. Devices must be closed once
15
+// they are no longer in use.
16
+type Device struct {
17
+	conn driver.Conn
18
+}
19
+
20
+// TenBit marks an I2C address as a 10-bit address.
21
+func TenBit(addr int) int {
22
+	return addr | tenbitMask
23
+}
24
+
25
+// Read reads len(buf) bytes from the device.
26
+func (d *Device) Read(buf []byte) error {
27
+	return d.conn.Tx(nil, buf)
28
+}
29
+
30
+// ReadReg is similar to Read but it reads from a register.
31
+func (d *Device) ReadReg(reg byte, buf []byte) error {
32
+	return d.conn.Tx([]byte{reg}, buf)
33
+}
34
+
35
+// Write writes the buffer to the device. If it is required to write to a
36
+// specific register, the register should be passed as the first byte in the
37
+// given buffer.
38
+func (d *Device) Write(buf []byte) (err error) {
39
+	return d.conn.Tx(buf, nil)
40
+}
41
+
42
+// WriteReg is similar to Write but writes to a register.
43
+func (d *Device) WriteReg(reg byte, buf []byte) (err error) {
44
+	// TODO(jbd): Do not allocate, not optimal.
45
+	return d.conn.Tx(append([]byte{reg}, buf...), nil)
46
+}
47
+
48
+// Close closes the device and releases the underlying sources.
49
+func (d *Device) Close() error {
50
+	return d.conn.Close()
51
+}
52
+
53
+// Open opens a connection to an I2C device.
54
+// All devices must be closed once they are no longer in use.
55
+// For devices that use 10-bit I2C addresses, addr can be marked
56
+// as a 10-bit address with TenBit.
57
+func Open(o driver.Opener, addr int) (*Device, error) {
58
+	unmasked, tenbit := resolveAddr(addr)
59
+	conn, err := o.Open(unmasked, tenbit)
60
+	if err != nil {
61
+		return nil, err
62
+	}
63
+	return &Device{conn: conn}, nil
64
+}
65
+
66
+// resolveAddr returns whether the addr is 10-bit masked or not.
67
+// It also returns the unmasked address.
68
+func resolveAddr(addr int) (unmasked int, tenbit bool) {
69
+	return addr & (tenbitMask - 1), addr&tenbitMask == tenbitMask
70
+}

+ 19
- 0
vendor/vendor.json View File

@@ -0,0 +1,19 @@
1
+{
2
+	"comment": "",
3
+	"ignore": "test",
4
+	"package": [
5
+		{
6
+			"checksumSHA1": "cdQmT5TaSM6NcsOZ3kqQ+K32KYY=",
7
+			"path": "golang.org/x/exp/io/i2c",
8
+			"revision": "e9c3453fc79c16b175ff7b8bf36b1507d0295079",
9
+			"revisionTime": "2017-03-31T05:31:32Z"
10
+		},
11
+		{
12
+			"checksumSHA1": "dJnnn8GW7JBnsCMTia/EsCWM7sE=",
13
+			"path": "golang.org/x/exp/io/i2c/driver",
14
+			"revision": "e9c3453fc79c16b175ff7b8bf36b1507d0295079",
15
+			"revisionTime": "2017-03-31T05:31:32Z"
16
+		}
17
+	],
18
+	"rootPath": "go.rls.moe/misc/adafruitPCA9685"
19
+}

Loading…
Cancel
Save