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  }