Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(as7262): init driver for new device #592

Open
wants to merge 24 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4b3477e
feat(as7262): init driver for new device
JohnTrunix Aug 23, 2023
f54b488
fix(as7262): export read functions
JohnTrunix Aug 25, 2023
85b6d2a
test(as7262): rename test functions & function calls
JohnTrunix Aug 25, 2023
5192223
test(as7262): add example for as7262
JohnTrunix Aug 26, 2023
1df68f7
test(as7262): add as7262 to smoketest
JohnTrunix Aug 26, 2023
e37293c
test(as7262): fix typo in i2c init
JohnTrunix Aug 26, 2023
d18a337
perf(as7262): remove fmt library from example for arduino uno compati…
JohnTrunix Aug 27, 2023
0376d13
Merge branch 'dev' into as7262
JohnTrunix Aug 27, 2023
608b0df
fix(as7262): rm error code & create virtual registers
JohnTrunix Sep 20, 2023
55ea0ea
fix(as7262): temp fix example code
JohnTrunix Sep 20, 2023
f7a38f6
test(as7262): rm test
JohnTrunix Sep 20, 2023
e3142ef
fix(as7262): fix drivers/internal/legacy dependency
JohnTrunix Sep 20, 2023
f560c70
docs(as7262): add more info context
JohnTrunix Sep 20, 2023
dfd8f1f
refactor(as7262): split Led functionality in new file
JohnTrunix Sep 20, 2023
12f8e2f
feat(as7262): init virtual led register
JohnTrunix Sep 20, 2023
dbf863d
fix(as7262): fix buffer handling
JohnTrunix Sep 20, 2023
b1d3c76
fix(as7262): rmv Led example because of refactoring
JohnTrunix Sep 20, 2023
dd63148
refactor(as7262): move Configure(...) to vControlRegister.go
JohnTrunix Sep 21, 2023
32b7610
fix(as7262): fix integrationTime
JohnTrunix Sep 21, 2023
503beb9
feat(as7262): add led control
JohnTrunix Sep 21, 2023
a83b169
refactor(as7262): move virtual registers to device struct
JohnTrunix Sep 21, 2023
1475046
feat(as7262): add reading colors functionalities
JohnTrunix Sep 26, 2023
1b4e4f3
test(as7262): example main.go changes
JohnTrunix Sep 26, 2023
3173884
fix(as7262): reduce config timeout
JohnTrunix Sep 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions as7262/as7262.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package as7262

import (
"encoding/binary"
"math"
"tinygo.org/x/drivers"
"tinygo.org/x/drivers/internal/legacy"
)

type Error uint8

const (
ErrInvalidID Error = 0x1
TxValid byte = 0x02
RxValid byte = 0x01
)

func (e Error) Error() string {
switch e {
case ErrInvalidID:
return "Invalid chip ID"
default:
return "Unknown error"
}
}

type Device struct {
bus drivers.I2C
buf []byte
Address uint8
vControlReg *vControlReg
vLedControlReg *vLedControlReg
}

// New returns pointer of new as7262 device
func New(i2c drivers.I2C) *Device {
return &Device{
bus: i2c,
buf: []byte{0},
Address: DefaultAddress,
vControlReg: newVControlReg(),
vLedControlReg: newVLedControlReg(),
}
}

// deviceStatus returns StatusReg of as7262
func (d *Device) deviceStatus() byte {
d.buf[0] = 0b00000000
legacy.ReadRegister(d.bus, DefaultAddress, StatusReg, d.buf)
return d.buf[0]
}

// writeReady returns true if as7262 is ready to write write-register
func (d *Device) writeReady() bool {
return d.deviceStatus()&TxValid == 0
}

// readReady return true if as7262 is ready to read read-register
func (d *Device) readReady() bool {
return d.deviceStatus()&RxValid != 0
}

func (d *Device) readByte(reg byte) byte {
d.buf[0] = 0b00000000
for {
if d.writeReady() {
break
}
}

legacy.WriteRegister(d.bus, d.Address, WriteReg, []byte{reg})

for {
if d.readReady() {
break
}
}

legacy.ReadRegister(d.bus, d.Address, ReadReg, d.buf)
return d.buf[0]
}

func (d *Device) writeByte(reg byte, value byte) {
for {
if d.writeReady() {
break
}
}

legacy.WriteRegister(d.bus, d.Address, WriteReg, []byte{reg | 0x80})

for {
if d.writeReady() {
break
}
}

legacy.WriteRegister(d.bus, d.Address, WriteReg, []byte{value})
}

func (d *Device) read32Bit(reg byte) float32 {
var bytes [4]byte

for i := 0; i < 4; i++ {
bytes[3-i] = d.readByte(reg + byte(i))
}
floatValue := math.Float32frombits(binary.BigEndian.Uint32(bytes[:]))
return floatValue
}

// Temperature returns sensor temperature
func (d *Device) Temperature() byte {
return d.readByte(TempRegister)
}

// GetColors set pointer array: V, B, G, Y, O, R
func (d *Device) GetColors(arr *[6]float32) {
arr[0] = d.GetViolet()
arr[1] = d.GetBlue()
arr[2] = d.GetGreen()
arr[3] = d.GetYellow()
arr[4] = d.GetOrange()
arr[5] = d.GetRed()
}

// GetRGB set pointer array: R, G, B
func (d *Device) GetRGB(arr *[3]float32) {
arr[0] = d.GetRed()
arr[1] = d.GetGreen()
arr[2] = d.GetBlue()
}

// GetViolet returns violet value
func (d *Device) GetViolet() float32 {
return d.read32Bit(VCalReg)
}

// GetBlue returns blue value
func (d *Device) GetBlue() float32 {
return d.read32Bit(BCalReg)
}

// GetGreen returns green value
func (d *Device) GetGreen() float32 {
return d.read32Bit(GCalReg)
}

// GetYellow returns yellow value
func (d *Device) GetYellow() float32 {
return d.read32Bit(YCalReg)
}

// GetOrange returns orange value
func (d *Device) GetOrange() float32 {
return d.read32Bit(OCalReg)
}

// GetRed returns red value
func (d *Device) GetRed() float32 {
return d.read32Bit(RCalReg)
}
66 changes: 66 additions & 0 deletions as7262/registers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package as7262

const (
// DefaultAddress Address is default I2C address of AS7262
DefaultAddress = 0x49

// StatusReg
StatusReg = 0x00
// WriteReg
WriteReg = 0x01
// ReadReg
ReadReg = 0x02

// ControlReg
ControlReg = 0x04
// IntegrationTimeReg
IntegrationTimeReg = 0x05
// TempRegister
TempRegister = 0x06
// LedRegister
LedRegister = 0x07

/*
Sensor Raw Data Registers
*/
// VHighRawReg Channel V High Data Byte
VHighRawReg = 0x08
// VLowRawReg Channel V Low Data Byte
VLowRawReg = 0x09
// BHighRawReg Channel B High Data Byte
BHighRawReg = 0x0A
// BLowRawReg Channel B Low Data Byte
BLowRawReg = 0x0B
// GHighRawReg Channel G High Data Byte
GHighRawReg = 0x0C
// GLowRawReg Channel G Low Data Byte
GLowRawReg = 0x0D
// YHighRawReg Channel Y High Data Byte
YHighRawReg = 0x0E
// YLowRawReg Channel Y Low Data Byte
YLowRawReg = 0x0F
// OHighRawReg Channel O High Data Byte
OHighRawReg = 0x10
// OLowRawReg Channel O Low Data Byte
OLowRawReg = 0x11
// RHighRawReg Channel R High Data Byte
RHighRawReg = 0x12
// RLowRawReg Channel R Low Data Byte
RLowRawReg = 0x13

/*
Sensor Calibrated Data Registers
*/
// VCalReg address for Channel V Calibrated Data
VCalReg = 0x14
// BCalReg address for Channel B Calibrated Data
BCalReg = 0x18
// GCalReg address for Channel G Calibrated Data
GCalReg = 0x1C
// YCalReg address for Channel Y Calibrated Data
YCalReg = 0x20
// OCalReg address for Channel O Calibrated Data
OCalReg = 0x24
// RCalReg address for Channel R Calibrated Data
RCalReg = 0x28
)
97 changes: 97 additions & 0 deletions as7262/vControlRegister.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package as7262

import "time"

type vControlReg struct {
reset byte
interrupt byte
gain byte
bank byte
dataReady byte
}

func newVControlReg() *vControlReg {
return &vControlReg{
reset: 0b10000000,
interrupt: 0b01000000,
gain: 0b00110000,
bank: 0b00001100, // measurement mode
dataReady: 0b00000010,
}
}

// encodeCReg register to a complete byte for writing
func (d *Device) encodeCReg() byte {
return d.vControlReg.reset |
d.vControlReg.interrupt |
d.vControlReg.gain |
d.vControlReg.bank |
d.vControlReg.dataReady
}

// decodeCReg register to represent as7262 internal state
func (d *Device) decodeCReg(encoded byte) {
d.vControlReg.reset = encoded & 0b10000000
d.vControlReg.interrupt = encoded & 0b01000000
d.vControlReg.gain = encoded & 0b00110000
d.vControlReg.bank = encoded & 0b00001100
d.vControlReg.dataReady = encoded & 0b00000010
}

// setReset bit which will soft reset the as7262 sensor
func (d *Device) setReset(reset bool) {
if reset {
d.vControlReg.reset |= 0b10000000
} else {
d.vControlReg.reset &= 0b01111111
}
}

// setGain sets bit 4:5 of VControlReg for gain
func (d *Device) setGain(gain float32) {
// set gain (defaults to 64)
// values: 1, 3.7, 16, 64
var g byte
switch gain {
case 1:
g = 0b00
case 3.7:
g = 0b01
case 16:
g = 0b10
default:
g = 0b11
}

// bitwise clear operation & setting bit 4:5
d.vControlReg.gain &= 0b11001111
d.vControlReg.gain |= g << 4
}

// setMode sets bit 2:3 of VControlReg for mode
func (d *Device) setMode(mode int) {
// set mode: 0, 1, 2, 3
m := byte(mode)

// bitwise clear operation & setting bit 4:5
d.vControlReg.bank &= 0b11110011
d.vControlReg.bank |= m << 2
}

// Configure as7262 behaviour
func (d *Device) Configure(reset bool, gain float32, integrationTime float32, mode int) {
d.setReset(reset)
d.setGain(gain)
d.setMode(mode)
crEncoded := d.encodeCReg()

// write ControlReg and read full ControlReg
d.writeByte(ControlReg, crEncoded)
time.Sleep(time.Second)
d.readByte(ControlReg)
d.decodeCReg(d.buf[0])

// set integrationTime: float32 as ms
t := byte(int(integrationTime*2.8) & 0xff)
d.writeByte(IntegrationTimeReg, t)
}
Loading