tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/pca9685/pca9685_buffered.go (about) 1 package pca9685 2 3 import ( 4 "encoding/binary" 5 6 "tinygo.org/x/drivers" 7 ) 8 9 // 16 PWM channels, 2 2 byte values each (on, off 16bits) 10 const buffLen = 16 * 2 * 2 11 12 // DevBuffered provides a way of performing one-shot writes 13 // on all PWM signals. This is useful when working with systems 14 // which require as little as possible I/O overhead. 15 type DevBuffered struct { 16 Dev 17 // LED buffer, first value is address, following values correspond to LED registers. 18 // [0]: LEDSTART register address 19 // [1:5]: LED0 corresponding to PWM channel 0 20 // [5:9]: LED1 PWM channel 1 21 // ... 22 // [1 + N*4 : 1 + N*4 + 4] : channnel N up to channel 15 23 ledBuf [buffLen + 1]byte 24 } 25 26 // New creates a new instance of a PCA9685 device. It performs 27 // no IO on the i2c bus. 28 func NewBuffered(bus drivers.I2C, addr uint8) *DevBuffered { 29 db := &DevBuffered{ 30 Dev: New(bus, addr), 31 } 32 db.ledBuf[0] = LEDSTART 33 return db 34 } 35 36 // PrepSet prepares a value to be written to the 37 // channel's PWM register on Update() call. 38 func (b *DevBuffered) PrepSet(channel uint8, on uint32) { 39 b.PrepPhasedSet(channel, on, 0) 40 } 41 42 // PrepPhasedSet prepares a phased PWM value to be written to the 43 // channel's register on Update() call. 44 func (b *DevBuffered) PrepPhasedSet(channel uint8, on, off uint32) { 45 onLReg := 1 + channel*4 46 binary.LittleEndian.PutUint16(b.ledBuf[onLReg:], uint16(on)&maxtop) 47 binary.LittleEndian.PutUint16(b.ledBuf[onLReg+2:], uint16(off)&maxtop) 48 } 49 50 // Update writes the prepared values to the PWM device registers in one shot. 51 func (b *DevBuffered) Update() error { 52 return b.bus.Tx(uint16(b.addr), b.ledBuf[:], nil) 53 }