func (d *L3GD20) calibrate(a *axis) (axisCalibration, error) { glog.V(1).Infof("l3gd20: calibrating %v axis", a) values := make(values, 0) for i := 0; i < 20; i++ { again: available, err := d.axisStatus(a) if err != nil { return axisCalibration{}, err } if !available { time.Sleep(100 * time.Microsecond) goto again } value, err := d.readOrientationDelta(a) if err != nil { return axisCalibration{}, err } values = append(values, value) } ac := axisCalibration{min: values.min(), max: values.max(), mean: values.mean()} glog.V(1).Infof("l3gd20: %v axis calibration (%v)", a, ac) return ac, nil }
func (d *TMP006) measureObjTemp() (float64, error) { if err := d.setup(); err != nil { return 0, err } tDie, err := d.measureRawDieTemp() if err != nil { return 0, err } glog.V(2).Infof("tmp006: tdie = %.2f C", tDie) tDie += 273.15 // Convert to K vo, err := d.measureRawVoltage() if err != nil { return 0, err } vObj := float64(vo) vObj *= 156.25 // 156.25 nV per LSB vObj /= 1000 // nV -> uV glog.V(2).Infof("tmp006: vObj = %.5f uV", vObj) vObj /= 1000 // uV -> mV vObj /= 1000 // mV -> V tdie_tref := tDie - tref s := 1 + a1*tdie_tref + a2*tdie_tref*tdie_tref s *= s0 s /= 10000000 s /= 10000000 Vos := b0 + b1*tdie_tref + b2*tdie_tref*tdie_tref fVobj := (vObj - Vos) + c2*(vObj-Vos)*(vObj-Vos) temp := math.Sqrt(math.Sqrt(tDie*tDie*tDie*tDie + fVobj/s)) temp -= 273.15 return temp, nil }
func (d *TMP006) setup() error { d.mu.RLock() if d.initialized { d.mu.RUnlock() return nil } d.mu.RUnlock() d.mu.Lock() defer d.mu.Unlock() if err := d.validate(); err != nil { return err } if d.SampleRate == nil { glog.V(1).Infof("tmp006: sample rate = nil, using SR16") d.SampleRate = SR16 } glog.V(1).Infof("tmp006: configuring with %#04x", configRegDefault|d.SampleRate.enabler) if err := d.Bus.WriteWordToReg(d.Addr, configReg, configRegDefault|d.SampleRate.enabler); err != nil { return err } d.initialized = true return nil }
func (d *PCA9685) wake() error { glog.V(1).Infoln("pca9685: wake request received") mode1Reg, err := d.mode1Reg() if err != nil { return err } wakeMode := mode1Reg & 0xEF if (mode1Reg & 0x80) == 0x80 { if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, wakeMode); err != nil { return err } glog.V(1).Infof("pca9685: wake mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", wakeMode, mode1RegAddr) time.Sleep(500 * time.Microsecond) } restartOpCode := wakeMode | 0x80 if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, restartOpCode); err != nil { return err } glog.V(1).Infof("pca9685: restart mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", restartOpCode, mode1RegAddr) return nil }
// Close stops the controller and resets mode and pwm controller registers. func (d *PCA9685) Close() error { if err := d.setup(); err != nil { return err } if err := d.sleep(); err != nil { return err } glog.V(1).Infof("pca9685: reset request received") if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, 0x00); err != nil { return err } glog.V(1).Infof("pca9685: cleaning up all PWM control registers") for regAddr := 0x06; regAddr <= 0x45; regAddr++ { if err := d.Bus.WriteByteToReg(d.Addr, byte(regAddr), 0x00); err != nil { return err } } if glog.V(1) { glog.Infof("pca9685: done Cleaning up all PWM control registers") glog.Infof("pca9685: controller reset") } return nil }
func ensureFeatureEnabled(id string) error { glog.V(3).Infof("bbb: enabling feature %v", id) pattern := "/sys/devices/bone_capemgr.*/slots" file, err := embd.FindFirstMatchingFile(pattern) if err != nil { return err } bytes, err := ioutil.ReadFile(file) if err != nil { return err } str := string(bytes) if strings.Contains(str, id) { glog.V(3).Infof("bbb: feature %v already enabled", id) return nil } slots, err := os.OpenFile(file, os.O_WRONLY, os.ModeExclusive) if err != nil { return err } defer slots.Close() glog.V(3).Infof("bbb: writing %v to slots file", id) _, err = slots.WriteString(id) return err }
func (controller *HD44780) lcdInit() error { glog.V(2).Info("hd44780: initializing display") err := controller.WriteInstruction(lcdInit) if err != nil { return err } glog.V(2).Info("hd44780: initializing display in 4-bit mode") return controller.WriteInstruction(lcdInit4bit) }
func (b *spiBus) setMode() error { var mode = uint8(b.mode) glog.V(3).Infof("spi: setting spi mode to %v", mode) _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIOCWrMode, uintptr(unsafe.Pointer(&mode))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to set mode due to %v", err.Error()) return err } glog.V(3).Infof("spi: mode set to %v", mode) return nil }
func (d *BMP085) measureTemp() (uint16, error) { if err := d.calibrate(); err != nil { return 0, err } utemp, err := d.readUncompensatedTemp() if err != nil { return 0, err } glog.V(1).Infof("bcm085: uncompensated temp: %v", utemp) temp := d.calcTemp(utemp) glog.V(1).Infof("bcm085: compensated temp %v", temp) return temp, nil }
func (d *PCA9685) setup() error { d.mu.RLock() if d.initialized { d.mu.RUnlock() return nil } d.mu.RUnlock() d.mu.Lock() defer d.mu.Unlock() mode1Reg, err := d.mode1Reg() if err != nil { return err } glog.V(1).Infof("pca9685: read MODE1 Reg [regAddr: %#02x] Value: [%v]", mode1RegAddr, mode1Reg) if err := d.sleep(); err != nil { return err } if d.Freq == 0 { d.Freq = defaultFreq } preScaleValue := byte(math.Floor(float64(clockFreq/(pwmControlPoints*d.Freq))+float64(0.5)) - 1) glog.V(1).Infof("pca9685: calculated prescale value = %#02x", preScaleValue) if err := d.Bus.WriteByteToReg(d.Addr, preScaleRegAddr, byte(preScaleValue)); err != nil { return err } glog.V(1).Infof("pca9685: prescale value [%#02x] written to PRE_SCALE Reg [regAddr: %#02x]", preScaleValue, preScaleRegAddr) if err := d.wake(); err != nil { return err } newmode := ((mode1Reg | 0x01) & 0xDF) if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, newmode); err != nil { return err } glog.V(1).Infof("pca9685: new mode [%#02x] [disabling register auto increment] written to MODE1 Reg [regAddr: %#02x]", newmode, mode1RegAddr) d.initialized = true glog.V(1).Infof("pca9685: driver initialized with pwm freq: %v", d.Freq) return nil }
func (d *BMP085) measurePressureAndAltitude() (int32, float64, error) { if err := d.calibrate(); err != nil { return 0, 0, err } upressure, err := d.readUncompensatedPressure() if err != nil { return 0, 0, err } glog.V(1).Infof("bcm085: uncompensated pressure: %v", upressure) pressure := d.calcPressure(upressure) glog.V(1).Infof("bcm085: compensated pressure %v", pressure) altitude := d.calcAltitude(pressure) glog.V(1).Infof("bcm085: calculated altitude %v", altitude) return pressure, altitude, nil }
// SetAngle sets the servo angle. func (s *Servo) SetAngle(angle int) error { us := util.Map(int64(angle), 0, 180, int64(s.Minus), int64(s.Maxus)) glog.V(1).Infof("servo: given angle %v calculated %v us", angle, us) return s.PWM.SetMicroseconds(int(us)) }
// Write writes a register select flag and byte to the I²C connection. func (conn *I2CConnection) Write(rs bool, data byte) error { var instructionHigh byte = 0x00 instructionHigh |= ((data >> 4) & 0x01) << conn.PinMap.D4 instructionHigh |= ((data >> 5) & 0x01) << conn.PinMap.D5 instructionHigh |= ((data >> 6) & 0x01) << conn.PinMap.D6 instructionHigh |= ((data >> 7) & 0x01) << conn.PinMap.D7 var instructionLow byte = 0x00 instructionLow |= (data & 0x01) << conn.PinMap.D4 instructionLow |= ((data >> 1) & 0x01) << conn.PinMap.D5 instructionLow |= ((data >> 2) & 0x01) << conn.PinMap.D6 instructionLow |= ((data >> 3) & 0x01) << conn.PinMap.D7 instructions := []byte{instructionHigh, instructionLow} for _, ins := range instructions { if rs { ins |= 0x01 << conn.PinMap.RS } if conn.Backlight == bool(conn.PinMap.BLPolarity) { ins |= 0x01 << conn.PinMap.Backlight } glog.V(3).Infof("hd44780: writing to I2C: %#x", ins) err := conn.pulseEnable(ins) if err != nil { return err } } time.Sleep(writeDelay) return nil }
// Write writes a register select flag and byte to the 4-bit GPIO connection. func (conn *GPIOConnection) Write(rs bool, data byte) error { glog.V(3).Infof("hd44780: writing to GPIO RS: %t, data: %#x", rs, data) rsInt := embd.Low if rs { rsInt = embd.High } functions := []func() error{ func() error { return conn.RS.Write(rsInt) }, func() error { return conn.D4.Write(int((data >> 4) & 0x01)) }, func() error { return conn.D5.Write(int((data >> 5) & 0x01)) }, func() error { return conn.D6.Write(int((data >> 6) & 0x01)) }, func() error { return conn.D7.Write(int((data >> 7) & 0x01)) }, func() error { return conn.pulseEnable() }, func() error { return conn.D4.Write(int(data & 0x01)) }, func() error { return conn.D5.Write(int((data >> 1) & 0x01)) }, func() error { return conn.D6.Write(int((data >> 2) & 0x01)) }, func() error { return conn.D7.Write(int((data >> 3) & 0x01)) }, func() error { return conn.pulseEnable() }, } for _, f := range functions { err := f() if err != nil { return err } } time.Sleep(writeDelay) return nil }
func (d *US020) setup() error { d.mu.RLock() if d.initialized { d.mu.RUnlock() return nil } d.mu.RUnlock() d.mu.Lock() defer d.mu.Unlock() d.TriggerPin.SetDirection(embd.Out) d.EchoPin.SetDirection(embd.In) if d.Thermometer == nil { d.Thermometer = NullThermometer } if temp, err := d.Thermometer.Temperature(); err == nil { d.speedSound = 331.3 + 0.606*temp glog.V(1).Infof("us020: read a temperature of %v, so speed of sound = %v", temp, d.speedSound) } else { d.speedSound = 340 } d.initialized = true return nil }
// Close puts the DAC into power down mode. func (d *MCP4725) Close() error { glog.V(1).Infof("mcp4725: powering down") if err := d.Bus.WriteWordToReg(d.Addr, powerDown, 0); err != nil { return err } return nil }
func (b *spiBus) setBPW() error { var bpw uint8 = defaultSPIBPW if b.bpw > 0 { bpw = uint8(b.bpw) } glog.V(3).Infof("spi: setting spi bpw to %v", bpw) _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIOCWrBitsPerWord, uintptr(unsafe.Pointer(&bpw))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to set bpw due to %v", err.Error()) return err } glog.V(3).Infof("spi: bpw set to %v", bpw) b.spiTransferData.bitsPerWord = uint8(bpw) return nil }
// Heading returns the current heading [0, 360). func (d *LSM303) Heading() (float64, error) { select { case heading := <-d.headings: return heading, nil default: glog.V(2).Infof("lsm303: no headings available... measuring") return d.measureHeading() } }
func (d *PCA9685) sleep() error { glog.V(1).Infof("pca9685: sleep request received") mode1Reg, err := d.mode1Reg() if err != nil { return err } sleepmode := (mode1Reg & 0x7F) | 0x10 if err := d.Bus.WriteByteToReg(d.Addr, mode1RegAddr, sleepmode); err != nil { return err } if glog.V(1) { glog.Infof("pca9685: sleep mode [%#02x] written to MODE1 Reg [regAddr: %#02x]", sleepmode, mode1RegAddr) glog.Infoln("pca9685: controller set to Sleep mode") } return nil }
func (b *spiBus) setSpeed() error { var speed uint32 = defaultSPISpeed if b.speed > 0 { speed = uint32(b.speed) } glog.V(3).Infof("spi: setting spi speedMax to %v", speed) _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), spiIOCWrMaxSpeedHz, uintptr(unsafe.Pointer(&speed))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to set speedMax due to %v", err.Error()) return err } glog.V(3).Infof("spi: speedMax set to %v", speed) b.spiTransferData.speedHz = speed return nil }
// SetMicroseconds sends a command to the PWM driver to generate a us wide pulse. func (d *ServoBlaster) setMicroseconds(channel, us int) error { if err := d.setup(); err != nil { return err } cmd := fmt.Sprintf("%v=%vus\n", channel, us) glog.V(1).Infof("servoblaster: sending command %q", cmd) _, err := d.fd.WriteString(cmd) return err }
func (b *spiBus) setDelay() { var delay uint16 = defaultDelayms if b.delayms > 0 { delay = uint16(b.delayms) } glog.V(3).Infof("spi: delayms set to %v", delay) b.spiTransferData.delayus = delay }
func (d *BMP085) calcPressure(upressure uint32) int32 { var x1, x2, x3 int32 l := func(s string, v interface{}) { glog.V(1).Infof("bcm085: %v = %v", s, v) } b6 := d.b5 - 4000 l("b6", b6) // Calculate b3 x1 = (int32(d.b2) * int32(b6*b6) >> 12) >> 11 x2 = (int32(d.ac2) * b6) >> 11 x3 = x1 + x2 b3 := (((int32(d.ac1)*4 + x3) << d.oss) + 2) >> 2 l("x1", x1) l("x2", x2) l("x3", x3) l("b3", b3) // Calculate b4 x1 = (int32(d.ac3) * b6) >> 13 x2 = (int32(d.b1) * ((b6 * b6) >> 12)) >> 16 x3 = ((x1 + x2) + 2) >> 2 b4 := (uint32(d.ac4) * uint32(x3+32768)) >> 15 l("x1", x1) l("x2", x2) l("x3", x3) l("b4", b4) var p int32 b7 := (uint32(upressure-uint32(b3)) * (50000 >> d.oss)) if b7 < 0x80000000 { p = int32((b7 << 1) / b4) } else { p = int32((b7 / b4) << 1) } l("b7", b7) l("p", p) x1 = (p >> 8) * (p >> 8) x1 = (x1 * 3038) >> 16 x2 = (-7357 * p) >> 16 p += (x1 + x2 + 3791) >> 4 l("x1", x1) l("x2", x2) l("x3", x3) l("p", p) return p }
// Register makes a host describer available by the provided host key. // If Register is called twice with the same host or if describer is nil, // it panics. func Register(host Host, describer Describer) { if describer == nil { panic("embd: describer is nil") } if _, dup := describers[host]; dup { panic("embd: describer already registered") } describers[host] = describer glog.V(1).Infof("embd: host %v is registered", host) }
func (d *TMP006) measureRawVoltage() (int16, error) { if err := d.setup(); err != nil { return 0, err } vlt, err := d.Bus.ReadWordFromReg(d.Addr, vObjReg) if err != nil { return 0, err } volt := int16(vlt) glog.V(2).Infof("tmp006: raw voltage %#04x", volt) return volt, nil }
func (b *i2cBus) setAddress(addr byte) error { if addr != b.addr { glog.V(2).Infof("i2c: setting bus %v address to %#02x", b.l, addr) if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), slaveCmd, uintptr(addr)); errno != 0 { return syscall.Errno(errno) } b.addr = addr } return nil }
// AnalogValueAt returns the analog value at the given channel of the convertor. func (m *MCP3008) AnalogValueAt(chanNum int) (int, error) { var data [3]uint8 data[0] = startBit data[1] = uint8(m.Mode)<<7 | uint8(chanNum)<<4 data[2] = 0 glog.V(2).Infof("mcp3008: sendingdata buffer %v", data) if err := m.Bus.TransferAndRecieveData(data[:]); err != nil { return 0, err } return int(uint16(data[1]&0x03)<<8 | uint16(data[2])), nil }
func (b *spiBus) TransferAndRecieveData(dataBuffer []uint8) error { if err := b.init(); err != nil { return err } len := len(dataBuffer) dataCarrier := b.spiTransferData dataCarrier.length = uint32(len) dataCarrier.txBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0]))) dataCarrier.rxBuf = uint64(uintptr(unsafe.Pointer(&dataBuffer[0]))) glog.V(3).Infof("spi: sending dataBuffer %v with carrier %v", dataBuffer, dataCarrier) _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, b.file.Fd(), uintptr(spiIOCMessageN(1)), uintptr(unsafe.Pointer(&dataCarrier))) if errno != 0 { err := syscall.Errno(errno) glog.V(3).Infof("spi: failed to read due to %v", err.Error()) return err } glog.V(3).Infof("spi: read into dataBuffer %v", dataBuffer) return nil }
func (b *spiBus) init() error { if b.initialized { return nil } if b.initializer != nil { if err := b.initializer(); err != nil { return err } } var err error if b.file, err = os.OpenFile(fmt.Sprintf("/dev/spidev%v.%v", b.spiDevMinor, b.channel), os.O_RDWR, os.ModeExclusive); err != nil { return err } glog.V(3).Infof("spi: sucessfully opened file /dev/spidev%v.%v", b.spiDevMinor, b.channel) if err = b.setMode(); err != nil { return err } b.spiTransferData = spiIOCTransfer{} if err = b.setSpeed(); err != nil { return err } if err = b.setBPW(); err != nil { return err } b.setDelay() glog.V(2).Infof("spi: bus %v initialized", b.channel) glog.V(3).Infof("spi: bus %v initialized with spiIOCTransfer as %v", b.channel, b.spiTransferData) b.initialized = true return nil }
// SetPwm sets the ON and OFF time registers for pwm signal shaping. // channel: 0-15 // onTime/offTime: 0-4095 func (d *PCA9685) SetPwm(channel, onTime, offTime int) error { if err := d.setup(); err != nil { return err } onTimeLowReg := byte(pwm0OnLowReg + (4 * channel)) onTimeLow := byte(onTime & 0xFF) onTimeHigh := byte(onTime >> 8) offTimeLow := byte(offTime & 0xFF) offTimeHigh := byte(offTime >> 8) if err := d.Bus.WriteByteToReg(d.Addr, onTimeLowReg, onTimeLow); err != nil { return err } glog.V(2).Infof("pca9685: writing on-time low [%#02x] to CHAN%v_ON_L reg [reg: %#02x]", onTimeLow, channel, onTimeLowReg) onTimeHighReg := onTimeLowReg + 1 if err := d.Bus.WriteByteToReg(d.Addr, onTimeHighReg, onTimeHigh); err != nil { return err } glog.V(2).Infof("pca9685: writing on-time high [%#02x] to CHAN%v_ON_H reg [reg: %#02x]", onTimeHigh, channel, onTimeHighReg) offTimeLowReg := onTimeHighReg + 1 if err := d.Bus.WriteByteToReg(d.Addr, offTimeLowReg, offTimeLow); err != nil { return err } glog.V(2).Infof("pca9685: writing off-time low [%#02x] to CHAN%v_OFF_L reg [reg: %#02x]", offTimeLow, channel, offTimeLowReg) offTimeHighReg := offTimeLowReg + 1 if err := d.Bus.WriteByteToReg(d.Addr, offTimeHighReg, offTimeHigh); err != nil { return err } glog.V(2).Infof("pca9685: writing off-time high [%#02x] to CHAN%v_OFF_H reg [reg: %#02x]", offTimeHigh, channel, offTimeHighReg) return nil }