mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-22 07:29:01 +00:00
Add support for CEVA BNO08x 9DoF sensor (#809)
* Add support for CEVA BNO08x 9DoF sensor. Also includes implementation of CEVA SH-2 and SHTP protocols.
* Replace machine.I2C with drivers.I2C interface to remove dependency on machine package
* Replace Pin functionality with that provided by tinygo.org/x/drivers/internal/pin
* Unexport fields on SensorValue and replace with accessor methods. Add check for correct SensorID validation
* Add example to smoketest.sh
* Change build target for smoketest to match development environment.. Probably not important, but matches reality.
* Fix decoding of some sensor data: Step Counter, Tap Detector, Flip Detector. These are experimental.
* Refactor to allow SPI/UART etc. SPI is currently under development, but is omitted from this commit.
Example code has been moved to i2c subdirectory.
This commit introduces some major refactoring changes. It introduces a "Buser" interface and tries to remove any I2C specific code from the core. It still retains a couple of I2C specific fields in the "Config" struct ("Address" and "ReadChunk") but they are ignored in the as yet uncommited SPI code.
* Fix CRLF -> LF for gofmt
* Update smoketest to point to new example file
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
// SHTP specification found at https://www.ceva-ip.com/wp-content/uploads/SH-2-SHTP-Reference-Manual.pdf
|
||||
|
||||
package bno08x
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// shtpHandler is a callback for handling SHTP channel data.
|
||||
type shtpHandler func(payload []byte, timestamp uint32)
|
||||
|
||||
// shtp implements the Sensor Hub Transport Protocol layer.
|
||||
type shtp struct {
|
||||
hal *hal
|
||||
handlers map[uint8]shtpHandler
|
||||
seq [8]uint8
|
||||
rx [maxTransferIn]byte // Reusable receive buffer
|
||||
tx [maxTransferOut]byte // Reusable transmit buffer
|
||||
}
|
||||
|
||||
func newSHTP(hal *hal) *shtp {
|
||||
return &shtp{
|
||||
hal: hal,
|
||||
handlers: make(map[uint8]shtpHandler),
|
||||
}
|
||||
}
|
||||
|
||||
// register registers a handler for a specific SHTP channel.
|
||||
func (s *shtp) register(channel uint8, handler shtpHandler) {
|
||||
if handler == nil {
|
||||
delete(s.handlers, channel)
|
||||
return
|
||||
}
|
||||
s.handlers[channel] = handler
|
||||
}
|
||||
|
||||
// send transmits a payload on the specified channel.
|
||||
func (s *shtp) send(channel uint8, payload []byte) error {
|
||||
total := len(payload) + shtpHeaderLength
|
||||
if total > maxTransferOut {
|
||||
return errFrameTooLarge
|
||||
}
|
||||
|
||||
// Use pre-allocated transmit buffer to avoid allocations
|
||||
frame := s.tx[:total]
|
||||
binary.LittleEndian.PutUint16(frame[0:2], uint16(total))
|
||||
frame[2] = channel
|
||||
frame[3] = s.seq[channel]
|
||||
s.seq[channel]++
|
||||
copy(frame[shtpHeaderLength:], payload)
|
||||
|
||||
_, err := s.hal.write(frame)
|
||||
return err
|
||||
}
|
||||
|
||||
// poll checks for and processes incoming SHTP packets.
|
||||
// Returns true if a packet was processed, false if no data available.
|
||||
func (s *shtp) poll() (bool, error) {
|
||||
n, timestamp, err := s.hal.read(s.rx[:])
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if n == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
packet := s.rx[:n]
|
||||
length := int(binary.LittleEndian.Uint16(packet[0:2]) & ^uint16(continueMask))
|
||||
if length > n {
|
||||
length = n
|
||||
}
|
||||
if length < shtpHeaderLength {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
channel := packet[2]
|
||||
// seq := packet[3] // sequence number, not currently validated
|
||||
payload := packet[shtpHeaderLength:length]
|
||||
|
||||
if handler := s.handlers[channel]; handler != nil {
|
||||
handler(payload, timestamp)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
Reference in New Issue
Block a user