You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
package I2C
|
|
|
|
// file has general wrappers to interact with i2c-tools
|
|
|
|
import (
|
|
_ "fmt"
|
|
_ "log"
|
|
"os/exec"
|
|
"bytes"
|
|
"strings"
|
|
"sync"
|
|
"strconv"
|
|
"FRMS/internal/pkg/logging"
|
|
)
|
|
|
|
type I2CBus struct {
|
|
int
|
|
sync.Mutex
|
|
}
|
|
|
|
func NewBus(bus int) *I2CBus {
|
|
b := &I2CBus{}
|
|
b.int = bus
|
|
return b
|
|
}
|
|
|
|
func (b *I2CBus) Scan() map[int]bool {
|
|
/*
|
|
Returns all the connected devices
|
|
*/
|
|
b.Lock()
|
|
defer b.Unlock()
|
|
bus := strconv.Itoa(b.int)
|
|
cmd := exec.Command("i2cdetect", "-y", "-r", bus)
|
|
var out bytes.Buffer
|
|
var errs bytes.Buffer
|
|
cmd.Stderr = &errs
|
|
cmd.Stdout = &out
|
|
if err := cmd.Run(); err != nil {
|
|
logging.Debug(logging.DError, "I2C ERROR: %v", errs.String())
|
|
}
|
|
|
|
outString := out.String()
|
|
// could split by \n too
|
|
split := strings.SplitAfter(outString,":")
|
|
// 1st entry is garbage headers and ending is always \n##:
|
|
split = split[1:]
|
|
// create empty slice for all the devices
|
|
//var devices []i2cdev
|
|
devices := map[int]bool{} //maps device addresses to active bool
|
|
for i,v := range split {
|
|
lst := strings.Index(v,"\n")
|
|
trimmed := v[:lst]
|
|
trimmed = strings.Trim(trimmed," ")
|
|
// trimmed now holds just possible sensor addresses
|
|
count := strings.Split(trimmed," ")
|
|
for j,d := range count {
|
|
// the first row has to be offset by 3 but after its just i*16 + j
|
|
offset := 0
|
|
if i == 0 {
|
|
offset = 3
|
|
}
|
|
addr := i*16 + j + offset
|
|
if strings.Contains(d,"--") || strings.Contains(d,"UU") {
|
|
// address is unconnected or reserved
|
|
//devices = append(devices, I2Cdev{Addr:addr,Active:false})
|
|
devices[addr] = false
|
|
} else {
|
|
//devices = append(devices, I2Cdev{Addr:addr,Active:true,LastSeen:now})
|
|
devices[addr] = true
|
|
}
|
|
}
|
|
}
|
|
return devices
|
|
}
|
|
|
|
func (b *I2CBus) GetStatus(addr int) bool {
|
|
b.Lock()
|
|
defer b.Unlock()
|
|
|
|
bus := strconv.Itoa(b.int)
|
|
a := strconv.Itoa(addr)
|
|
cmd := exec.Command("i2cdetect","-y","-r",bus,a,a)
|
|
var out bytes.Buffer
|
|
cmd.Stdout = &out
|
|
if err := cmd.Run(); err != nil {
|
|
logging.Debug(logging.DError,"I2C ERROR: %v", err)
|
|
}
|
|
|
|
outString := out.String()
|
|
split := strings.SplitAfter(outString,":")
|
|
split = split[1:] // remove garbage header
|
|
val := int(addr/16) // if addr = 90 90/16 = int(5.6) = 5 will be in 5th row
|
|
dev := split[val]
|
|
lst := strings.Index(dev,"\n")
|
|
dev = dev[:lst]
|
|
trimmed := strings.Trim(dev," \n")
|
|
if strings.Contains(trimmed,"--") {
|
|
return false
|
|
} else {
|
|
return true
|
|
}
|
|
}
|