mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-03 22:47:47 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ca37c1c461 | |||
| 5dfacc3c73 |
+224
-145
@@ -8,15 +8,16 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
"tinygo.org/x/drivers/internal/legacy"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Device wraps an I2C connection to a APDS-9960 device.
|
// Device wraps an I2C connection to a APDS-9960 device.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.I2C
|
bus drivers.I2C
|
||||||
|
_txerr error
|
||||||
|
gesture gestureData
|
||||||
|
buf [8]byte
|
||||||
Address uint8
|
Address uint8
|
||||||
mode uint8
|
mode uint8
|
||||||
gesture gestureData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration for APDS-9960 device.
|
// Configuration for APDS-9960 device.
|
||||||
@@ -46,15 +47,24 @@ type gestureData struct {
|
|||||||
received bool
|
received bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// for enabling various device function
|
// for enabling various device functions.
|
||||||
type enableConfig struct {
|
type encfg uint8
|
||||||
GEN bool
|
|
||||||
PIEN bool
|
// data := []byte{gen<<6 | pien<<5 | aien<<4 | wen<<3 | pen<<2 | aen<<1 | pon}
|
||||||
AIEN bool
|
const (
|
||||||
WEN bool
|
enPON encfg = 1 << iota
|
||||||
PEN bool
|
enAEN
|
||||||
AEN bool
|
enPEN
|
||||||
PON bool
|
enWEN
|
||||||
|
enAIEN
|
||||||
|
enPIEN
|
||||||
|
enGEN
|
||||||
|
)
|
||||||
|
|
||||||
|
func (e encfg) write7bits(b []byte) {
|
||||||
|
for i := uint8(0); i < 7; i++ {
|
||||||
|
b[i] = byte(e>>(6-i)) & 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new APDS-9960 connection. The I2C bus must already be
|
// New creates a new APDS-9960 connection. The I2C bus must already be
|
||||||
@@ -68,9 +78,8 @@ func New(bus drivers.I2C) Device {
|
|||||||
// Connected returns whether APDS-9960 has been found.
|
// Connected returns whether APDS-9960 has been found.
|
||||||
// It does a "who am I" request and checks the response.
|
// It does a "who am I" request and checks the response.
|
||||||
func (d *Device) Connected() bool {
|
func (d *Device) Connected() bool {
|
||||||
data := []byte{0}
|
d.txNew()
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_ID_REG, data)
|
return d.txRead8(APDS9960_ID_REG) == 0xAB && d.txErr() == nil
|
||||||
return data[0] == 0xAB
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMode returns current engine mode
|
// GetMode returns current engine mode
|
||||||
@@ -79,65 +88,82 @@ func (d *Device) GetMode() uint8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DisableAll turns off the device and all functions
|
// DisableAll turns off the device and all functions
|
||||||
func (d *Device) DisableAll() {
|
func (d *Device) DisableAll() error {
|
||||||
d.enable(enableConfig{})
|
err := d.enable(0)
|
||||||
legacy.WriteRegister(d.bus, d.Address, APDS9960_GCONF4_REG, []byte{0x00})
|
if err != nil {
|
||||||
d.mode = MODE_NONE
|
return err
|
||||||
d.gesture.detected = GESTURE_NONE
|
}
|
||||||
|
d.txWrite8(APDS9960_GCONF4_REG, 0)
|
||||||
|
err = d.txErr()
|
||||||
|
if err == nil {
|
||||||
|
d.mode = MODE_NONE
|
||||||
|
d.gesture.detected = GESTURE_NONE
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetProximityPulse sets proximity pulse length (4, 8, 16, 32) and count (1~64)
|
// SetProximityPulse sets proximity pulse length (4, 8, 16, 32) and count (1..64)
|
||||||
// default: 16, 64
|
// default: 16, 64
|
||||||
func (d *Device) SetProximityPulse(length, count uint8) {
|
func (d *Device) SetProximityPulse(length, count uint8) error {
|
||||||
legacy.WriteRegister(d.bus, d.Address, APDS9960_PPULSE_REG, []byte{getPulseLength(length)<<6 | getPulseCount(count)})
|
d.txNew()
|
||||||
|
d.txWrite8(APDS9960_PPULSE_REG, getPulseLength(length)<<6|getPulseCount(count))
|
||||||
|
return d.txErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGesturePulse sets gesture pulse length (4, 8, 16, 32) and count (1~64)
|
// SetGesturePulse sets gesture pulse length (4, 8, 16, 32) and count (1..64)
|
||||||
// default: 16, 64
|
// default: 16, 64
|
||||||
func (d *Device) SetGesturePulse(length, count uint8) {
|
func (d *Device) SetGesturePulse(length, count uint8) error {
|
||||||
legacy.WriteRegister(d.bus, d.Address, APDS9960_GPULSE_REG, []byte{getPulseLength(length)<<6 | getPulseCount(count)})
|
d.txNew()
|
||||||
|
d.txWrite8(APDS9960_GPULSE_REG, getPulseLength(length)<<6|getPulseCount(count))
|
||||||
|
return d.txErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetADCIntegrationCycles sets ALS/color ADC internal integration cycles (1~256, 1 cycle = 2.78 ms)
|
// SetADCIntegrationCycles sets ALS/color ADC internal integration cycles (1..256, 1 cycle = 2.78 ms)
|
||||||
// default: 4 (~10 ms)
|
// default: 4 (approx. 10 ms)
|
||||||
func (d *Device) SetADCIntegrationCycles(cycles uint16) {
|
func (d *Device) SetADCIntegrationCycles(cycles uint16) error {
|
||||||
if cycles > 256 {
|
if cycles > 256 {
|
||||||
cycles = 256
|
cycles = 256
|
||||||
}
|
}
|
||||||
legacy.WriteRegister(d.bus, d.Address, APDS9960_ATIME_REG, []byte{uint8(256 - cycles)})
|
d.txNew()
|
||||||
|
d.txWrite8(APDS9960_ATIME_REG, uint8(256-cycles))
|
||||||
|
return d.txErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGains sets proximity/gesture gain (1, 2, 4, 8x) and ALS/color gain (1, 4, 16, 64x)
|
// SetGains sets proximity/gesture gain (1, 2, 4, 8x) and ALS/color gain (1, 4, 16, 64x)
|
||||||
// default: 1, 1, 4
|
// default: 1, 1, 4
|
||||||
func (d *Device) SetGains(proximityGain, gestureGain, colorGain uint8) {
|
func (d *Device) SetGains(proximityGain, gestureGain, colorGain uint8) error {
|
||||||
legacy.WriteRegister(d.bus, d.Address, APDS9960_CONTROL_REG, []byte{getProximityGain(proximityGain)<<2 | getALSGain(colorGain)})
|
d.txNew()
|
||||||
legacy.WriteRegister(d.bus, d.Address, APDS9960_GCONF2_REG, []byte{getProximityGain(gestureGain) << 5})
|
d.txWrite8(APDS9960_CONTROL_REG, getProximityGain(proximityGain)<<2|getALSGain(colorGain))
|
||||||
|
d.txWrite8(APDS9960_GCONF2_REG, getProximityGain(gestureGain)<<5)
|
||||||
|
return d.txErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LEDBoost sets proximity and gesture LED current level (100, 150, 200, 300 (%))
|
// LEDBoost sets proximity and gesture LED current level (100, 150, 200, 300 (%))
|
||||||
// default: 100
|
// default: 100
|
||||||
func (d *Device) LEDBoost(percent uint16) {
|
func (d *Device) LEDBoost(percent uint16) error {
|
||||||
var v uint8
|
var v uint8
|
||||||
switch percent {
|
switch {
|
||||||
case 100:
|
case percent < 125:
|
||||||
v = 0
|
v = 0
|
||||||
case 150:
|
case percent < 175:
|
||||||
v = 1
|
v = 1
|
||||||
case 200:
|
case percent < 250:
|
||||||
v = 2
|
v = 2
|
||||||
case 300:
|
default:
|
||||||
v = 3
|
v = 3 // Maximum case.
|
||||||
}
|
}
|
||||||
legacy.WriteRegister(d.bus, d.Address, APDS9960_CONFIG2_REG, []byte{0x01 | v<<4})
|
d.txNew()
|
||||||
|
d.txWrite8(APDS9960_CONFIG2_REG, 0x01|(v<<4))
|
||||||
|
return d.txErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setthreshold sets threshold (0~255) for detecting gestures
|
// Setthreshold sets threshold (0..255) for detecting gestures
|
||||||
// default: 30
|
// default: 30
|
||||||
func (d *Device) Setthreshold(t uint8) {
|
func (d *Device) Setthreshold(t uint8) {
|
||||||
d.gesture.threshold = t
|
d.gesture.threshold = t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setsensitivity sets sensivity (0~100) for detecting gestures
|
// Setsensitivity sets sensivity (0..100) for detecting gestures
|
||||||
// default: 20
|
// default: 20
|
||||||
func (d *Device) Setsensitivity(s uint8) {
|
func (d *Device) Setsensitivity(s uint8) {
|
||||||
if s > 100 {
|
if s > 100 {
|
||||||
@@ -147,47 +173,69 @@ func (d *Device) Setsensitivity(s uint8) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EnableProximity starts the proximity engine
|
// EnableProximity starts the proximity engine
|
||||||
func (d *Device) EnableProximity() {
|
func (d *Device) EnableProximity() error {
|
||||||
if d.mode != MODE_NONE {
|
if d.mode != MODE_NONE {
|
||||||
d.DisableAll()
|
err := d.DisableAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
d.enable(enableConfig{PON: true, PEN: true, WEN: true})
|
err := d.enable(enPON | enPEN | enWEN)
|
||||||
d.mode = MODE_PROXIMITY
|
if err == nil {
|
||||||
|
d.mode = MODE_PROXIMITY
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err returns the current error state of the device if encountered during I2C communication.
|
||||||
|
// After a call to Err the error is cleared.
|
||||||
|
func (d *Device) Err() error {
|
||||||
|
err := d.txErr()
|
||||||
|
d.txNew()
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProximityAvailable reports if proximity data is available
|
// ProximityAvailable reports if proximity data is available
|
||||||
func (d *Device) ProximityAvailable() bool {
|
func (d *Device) ProximityAvailable() bool {
|
||||||
if d.mode == MODE_PROXIMITY && d.readStatus("PVALID") {
|
if d.mode != MODE_PROXIMITY {
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
return false
|
status, err := d.ReadStatus()
|
||||||
|
return err == nil && status.PVALID()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadProximity reads proximity data (0~255)
|
// ReadProximity reads proximity data (0..255)
|
||||||
func (d *Device) ReadProximity() (proximity int32) {
|
func (d *Device) ReadProximity() (proximity int32) {
|
||||||
if d.mode != MODE_PROXIMITY {
|
if d.mode != MODE_PROXIMITY {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
data := []byte{0}
|
d.txNew()
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_PDATA_REG, data)
|
val := d.txRead8(APDS9960_PDATA_REG)
|
||||||
return 255 - int32(data[0])
|
return 255 - int32(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableColor starts the color engine
|
// EnableColor starts the color engine
|
||||||
func (d *Device) EnableColor() {
|
func (d *Device) EnableColor() (err error) {
|
||||||
if d.mode != MODE_NONE {
|
if d.mode != MODE_NONE {
|
||||||
d.DisableAll()
|
err = d.DisableAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
d.enable(enableConfig{PON: true, AEN: true, WEN: true})
|
err = d.enable(enPON | enAEN | enWEN)
|
||||||
d.mode = MODE_COLOR
|
if err == nil {
|
||||||
|
d.mode = MODE_COLOR
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColorAvailable reports if color data is available
|
// ColorAvailable reports if color data is available
|
||||||
func (d *Device) ColorAvailable() bool {
|
func (d *Device) ColorAvailable() bool {
|
||||||
if d.mode == MODE_COLOR && d.readStatus("AVALID") {
|
if d.mode != MODE_COLOR {
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
return false
|
status, err := d.ReadStatus()
|
||||||
|
return err == nil && status.AVALID()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadColor reads color data (red, green, blue, clear color/brightness)
|
// ReadColor reads color data (red, green, blue, clear color/brightness)
|
||||||
@@ -195,28 +243,36 @@ func (d *Device) ReadColor() (r int32, g int32, b int32, clear int32) {
|
|||||||
if d.mode != MODE_COLOR {
|
if d.mode != MODE_COLOR {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data := []byte{0, 0, 0, 0, 0, 0, 0, 0}
|
d.txNew()
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_CDATAL_REG, data[:1])
|
data := d.buf[:8]
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_CDATAH_REG, data[1:2])
|
const numLowRegs = APDS9960_GDATAH_REG - APDS9960_CDATAL_REG + 1
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_RDATAL_REG, data[2:3])
|
for i := uint8(0); i < numLowRegs; i++ {
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_RDATAH_REG, data[3:4])
|
data[i] = d.txRead8(i + APDS9960_CDATAL_REG)
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_GDATAL_REG, data[4:5])
|
}
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_GDATAH_REG, data[5:6])
|
data[numLowRegs] = d.txRead8(APDS9960_BDATAL_REG)
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_BDATAL_REG, data[6:7])
|
data[numLowRegs+1] = d.txRead8(APDS9960_BDATAH_REG)
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_BDATAH_REG, data[7:])
|
if d.txErr() != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
clear = int32(uint16(data[1])<<8 | uint16(data[0]))
|
clear = int32(uint16(data[1])<<8 | uint16(data[0]))
|
||||||
r = int32(uint16(data[3])<<8 | uint16(data[2]))
|
r = int32(uint16(data[3])<<8 | uint16(data[2]))
|
||||||
g = int32(uint16(data[5])<<8 | uint16(data[4]))
|
g = int32(uint16(data[5])<<8 | uint16(data[4]))
|
||||||
b = int32(uint16(data[7])<<8 | uint16(data[6]))
|
b = int32(uint16(data[7])<<8 | uint16(data[6]))
|
||||||
return
|
return r, g, b, clear
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableGesture starts the gesture engine
|
// EnableGesture starts the gesture engine
|
||||||
func (d *Device) EnableGesture() {
|
func (d *Device) EnableGesture() error {
|
||||||
if d.mode != MODE_NONE {
|
if d.mode != MODE_NONE {
|
||||||
d.DisableAll()
|
err := d.DisableAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := d.enable(enPON | enPEN | enGEN | enWEN)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
d.enable(enableConfig{PON: true, PEN: true, GEN: true, WEN: true})
|
|
||||||
d.mode = MODE_GESTURE
|
d.mode = MODE_GESTURE
|
||||||
d.gesture.detected = GESTURE_NONE
|
d.gesture.detected = GESTURE_NONE
|
||||||
d.gesture.gXDelta = 0
|
d.gesture.gXDelta = 0
|
||||||
@@ -224,6 +280,7 @@ func (d *Device) EnableGesture() {
|
|||||||
d.gesture.gXPrevDelta = 0
|
d.gesture.gXPrevDelta = 0
|
||||||
d.gesture.gYPrevDelta = 0
|
d.gesture.gYPrevDelta = 0
|
||||||
d.gesture.received = false
|
d.gesture.received = false
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GestureAvailable reports if gesture data is available
|
// GestureAvailable reports if gesture data is available
|
||||||
@@ -231,29 +288,26 @@ func (d *Device) GestureAvailable() bool {
|
|||||||
if d.mode != MODE_GESTURE {
|
if d.mode != MODE_GESTURE {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
d.txNew()
|
||||||
data := []byte{0, 0, 0, 0}
|
gstatus := d.txRead8(APDS9960_GSTATUS_REG)
|
||||||
|
if gstatus&1 == 0 {
|
||||||
// check GVALID
|
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_GSTATUS_REG, data[:1])
|
|
||||||
if data[0]&0x01 == 0 {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
availableDataSets := d.txRead8(APDS9960_GFLVL_REG)
|
||||||
// get number of data sets available in FIFO
|
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_GFLVL_REG, data[:1])
|
|
||||||
availableDataSets := data[0]
|
|
||||||
if availableDataSets == 0 {
|
if availableDataSets == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
data := d.buf[:]
|
||||||
// read up, down, left and right proximity data from FIFO
|
// read up, down, left and right proximity data from FIFO
|
||||||
var dataSets [32][4]uint8
|
var dataSets [32][4]uint8
|
||||||
|
const numAddrs = APDS9960_GFIFO_R_REG - APDS9960_GFIFO_U_REG + 1
|
||||||
for i := uint8(0); i < availableDataSets; i++ {
|
for i := uint8(0); i < availableDataSets; i++ {
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_GFIFO_U_REG, data[:1])
|
for j := uint8(0); j < numAddrs; j++ {
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_GFIFO_D_REG, data[1:2])
|
data[j] = d.txRead8(j + APDS9960_GFIFO_U_REG)
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_GFIFO_L_REG, data[2:3])
|
}
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_GFIFO_R_REG, data[3:4])
|
if d.txErr() != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
for j := uint8(0); j < 4; j++ {
|
for j := uint8(0); j < 4; j++ {
|
||||||
dataSets[i][j] = data[j]
|
dataSets[i][j] = data[j]
|
||||||
}
|
}
|
||||||
@@ -315,9 +369,11 @@ func (d *Device) ReadGesture() (gesture int32) {
|
|||||||
|
|
||||||
// private functions
|
// private functions
|
||||||
|
|
||||||
func (d *Device) configureDevice(cfg Configuration) {
|
func (d *Device) configureDevice(cfg Configuration) error {
|
||||||
d.DisableAll() // turn off everything
|
err := d.DisableAll() // turn off everything
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// "default" settings
|
// "default" settings
|
||||||
if cfg.ProximityPulseLength == 0 {
|
if cfg.ProximityPulseLength == 0 {
|
||||||
cfg.ProximityPulseLength = 16
|
cfg.ProximityPulseLength = 16
|
||||||
@@ -350,69 +406,92 @@ func (d *Device) configureDevice(cfg Configuration) {
|
|||||||
d.gesture.sensitivity = 20
|
d.gesture.sensitivity = 20
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetProximityPulse(cfg.ProximityPulseLength, cfg.ProximityPulseCount)
|
err = d.SetProximityPulse(cfg.ProximityPulseLength, cfg.ProximityPulseCount)
|
||||||
d.SetGesturePulse(cfg.GesturePulseLength, cfg.GesturePulseCount)
|
if err != nil {
|
||||||
d.SetGains(cfg.ProximityGain, cfg.GestureGain, cfg.ColorGain)
|
return err
|
||||||
d.SetADCIntegrationCycles(cfg.ADCIntegrationCycles)
|
|
||||||
|
|
||||||
if cfg.LEDBoost > 0 {
|
|
||||||
d.LEDBoost(cfg.LEDBoost)
|
|
||||||
}
|
}
|
||||||
|
err = d.SetGesturePulse(cfg.GesturePulseLength, cfg.GesturePulseCount)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = d.SetGains(cfg.ProximityGain, cfg.GestureGain, cfg.ColorGain)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = d.SetADCIntegrationCycles(cfg.ADCIntegrationCycles)
|
||||||
|
if err == nil && cfg.LEDBoost > 0 {
|
||||||
|
err = d.LEDBoost(cfg.LEDBoost)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) enable(cfg enableConfig) {
|
func (d *Device) enable(cfg encfg) error {
|
||||||
var gen, pien, aien, wen, pen, aen, pon uint8
|
d.txNew()
|
||||||
|
cfg.write7bits(d.buf[:7])
|
||||||
if cfg.GEN {
|
d.txWrite(APDS9960_ENABLE_REG, d.buf[:7])
|
||||||
gen = 1
|
err := d.txErr()
|
||||||
}
|
if err == nil && cfg&enPON != 0 {
|
||||||
if cfg.PIEN {
|
|
||||||
pien = 1
|
|
||||||
}
|
|
||||||
if cfg.AIEN {
|
|
||||||
aien = 1
|
|
||||||
}
|
|
||||||
if cfg.WEN {
|
|
||||||
wen = 1
|
|
||||||
}
|
|
||||||
if cfg.PEN {
|
|
||||||
pen = 1
|
|
||||||
}
|
|
||||||
if cfg.AEN {
|
|
||||||
aen = 1
|
|
||||||
}
|
|
||||||
if cfg.PON {
|
|
||||||
pon = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
data := []byte{gen<<6 | pien<<5 | aien<<4 | wen<<3 | pen<<2 | aen<<1 | pon}
|
|
||||||
legacy.WriteRegister(d.bus, d.Address, APDS9960_ENABLE_REG, data)
|
|
||||||
|
|
||||||
if cfg.PON {
|
|
||||||
time.Sleep(time.Millisecond * 10)
|
time.Sleep(time.Millisecond * 10)
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) readStatus(param string) bool {
|
func (d *Device) txErr() error { return d._txerr }
|
||||||
data := []byte{0}
|
|
||||||
legacy.ReadRegister(d.bus, d.Address, APDS9960_STATUS_REG, data)
|
|
||||||
|
|
||||||
switch param {
|
func (d *Device) txNew() { d._txerr = nil }
|
||||||
case "CPSAT":
|
|
||||||
return data[0]>>7&0x01 == 1
|
func (d *Device) txRead8(addr uint8) uint8 {
|
||||||
case "PGSAT":
|
if d._txerr != nil {
|
||||||
return data[0]>>6&0x01 == 1
|
return 0
|
||||||
case "PINT":
|
|
||||||
return data[0]>>5&0x01 == 1
|
|
||||||
case "AINT":
|
|
||||||
return data[0]>>4&0x01 == 1
|
|
||||||
case "PVALID":
|
|
||||||
return data[0]>>1&0x01 == 1
|
|
||||||
case "AVALID":
|
|
||||||
return data[0]&0x01 == 1
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
d.buf[0] = addr
|
||||||
|
d._txerr = d.bus.Tx(uint16(d.Address), d.buf[:1], d.buf[1:2])
|
||||||
|
return d.buf[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) txWrite8(addr uint8, val uint8) {
|
||||||
|
if d._txerr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.buf[0] = addr
|
||||||
|
d.buf[1] = val
|
||||||
|
d._txerr = d.bus.Tx(uint16(d.Address), d.buf[:2], nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) txWrite(addr uint8, data []byte) {
|
||||||
|
if d._txerr != nil {
|
||||||
|
return
|
||||||
|
} else if len(data) > len(d.buf)-1 {
|
||||||
|
panic("txWrite: data too long")
|
||||||
|
}
|
||||||
|
d.buf[0] = addr
|
||||||
|
copy(d.buf[1:], data)
|
||||||
|
d._txerr = d.bus.Tx(uint16(d.Address), d.buf[:len(data)+1], nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type status uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
statusAVALID status = 1 << iota
|
||||||
|
statusPVALID
|
||||||
|
_
|
||||||
|
_
|
||||||
|
statusAINT
|
||||||
|
statusPINT
|
||||||
|
statusPGSAT
|
||||||
|
statusCPSAT
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s status) CPSAT() bool { return s&statusCPSAT != 0 }
|
||||||
|
func (s status) PGSAT() bool { return s&statusPGSAT != 0 }
|
||||||
|
func (s status) PINT() bool { return s&statusPINT != 0 }
|
||||||
|
func (s status) AINT() bool { return s&statusAINT != 0 }
|
||||||
|
func (s status) PVALID() bool { return s&statusPVALID != 0 }
|
||||||
|
func (s status) AVALID() bool { return s&statusAVALID != 0 }
|
||||||
|
|
||||||
|
func (d *Device) ReadStatus() (status, error) {
|
||||||
|
d.txNew()
|
||||||
|
return status(d.txRead8(APDS9960_STATUS_REG)), d.txErr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPulseLength(l uint8) uint8 {
|
func getPulseLength(l uint8) uint8 {
|
||||||
|
|||||||
@@ -8,33 +8,42 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
// Sleep to catch any errors through the serial monitor.
|
||||||
|
time.Sleep(1000 * time.Millisecond)
|
||||||
|
bus := machine.I2C0
|
||||||
// use Nano 33 BLE Sense's internal I2C bus
|
// use Nano 33 BLE Sense's internal I2C bus
|
||||||
machine.I2C1.Configure(machine.I2CConfig{
|
err := bus.Configure(machine.I2CConfig{
|
||||||
SCL: machine.SCL1_PIN,
|
SCL: machine.GP1,
|
||||||
SDA: machine.SDA1_PIN,
|
SDA: machine.GP0,
|
||||||
Frequency: machine.TWI_FREQ_400KHZ,
|
Frequency: 400 * machine.KHz,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
sensor := apds9960.New(machine.I2C1)
|
sensor := apds9960.New(bus)
|
||||||
|
|
||||||
// use default settings
|
// use default settings
|
||||||
sensor.Configure(apds9960.Configuration{})
|
sensor.Configure(apds9960.Configuration{})
|
||||||
|
|
||||||
if !sensor.Connected() {
|
if !sensor.Connected() {
|
||||||
println("APDS-9960 not connected!")
|
println("APDS-9960 not connected!")
|
||||||
|
println("err:", sensor.Err())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
println("APDS connected!")
|
||||||
sensor.EnableProximity() // enable proximity engine
|
err = sensor.EnableProximity() // enable proximity engine
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
|
|
||||||
if sensor.ProximityAvailable() {
|
if sensor.ProximityAvailable() {
|
||||||
p := sensor.ReadProximity()
|
p := sensor.ReadProximity()
|
||||||
println("Proximity:", p)
|
println("Proximity:", p)
|
||||||
}
|
}
|
||||||
|
if err := sensor.Err(); err != nil {
|
||||||
|
println(err.Error())
|
||||||
|
}
|
||||||
time.Sleep(time.Millisecond * 100)
|
time.Sleep(time.Millisecond * 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user