tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/tester/device16.go (about)

     1  package tester
     2  
     3  // I2CDevice represents a mock I2C device on a mock I2C bus with 16-bit registers.
     4  type I2CDevice16 struct {
     5  	c Failer
     6  	// addr is the i2c device address.
     7  	addr uint8
     8  	// Registers holds the device registers. It can be inspected
     9  	// or changed as desired for testing.
    10  	Registers map[uint8]uint16
    11  	// If Err is non-nil, it will be returned as the error from the
    12  	// I2C methods.
    13  	Err error
    14  }
    15  
    16  // NewI2CDevice returns a new mock I2C device.
    17  //
    18  // To use this mock, populate the Registers map with known / expected
    19  // registers.  Attempts by the code under test to write to a register
    20  // that has not been populated into the map will be treated as an
    21  // error.
    22  func NewI2CDevice16(c Failer, addr uint8) *I2CDevice16 {
    23  	return &I2CDevice16{
    24  		c:         c,
    25  		addr:      addr,
    26  		Registers: map[uint8]uint16{},
    27  	}
    28  }
    29  
    30  // Addr returns the Device address.
    31  func (d *I2CDevice16) Addr() uint8 {
    32  	return d.addr
    33  }
    34  
    35  // ReadRegister implements I2C.ReadRegister.
    36  func (d *I2CDevice16) readRegister(r uint8, buf []byte) error {
    37  	if d.Err != nil {
    38  		return d.Err
    39  	}
    40  
    41  	if len(buf) > 2 {
    42  		d.c.Fatalf("register read [%#x, %#x] oversized buffer", r, len(buf))
    43  	}
    44  
    45  	val, ok := d.Registers[r]
    46  	if !ok {
    47  		d.c.Fatalf("register read [%#x] unknown register", r)
    48  	}
    49  
    50  	buf[0] = byte(val >> 8)
    51  	buf[1] = byte(val & 0xff)
    52  
    53  	return nil
    54  }
    55  
    56  // WriteRegister implements I2C.WriteRegister.
    57  func (d *I2CDevice16) writeRegister(r uint8, buf []byte) error {
    58  	if d.Err != nil {
    59  		return d.Err
    60  	}
    61  
    62  	if len(buf) != 2 {
    63  		d.c.Fatalf("register write [%#x, %#x] mis-sized write", r, len(buf))
    64  	}
    65  
    66  	_, ok := d.Registers[r]
    67  	if !ok {
    68  		d.c.Fatalf("register write [%#x] unknown register", r)
    69  	}
    70  
    71  	d.Registers[r] = uint16(buf[0])<<8 | uint16(buf[1])
    72  
    73  	return nil
    74  }
    75  
    76  // Tx implements I2C.Tx.
    77  func (bus *I2CDevice16) Tx(w, r []byte) error {
    78  	switch len(w) {
    79  	case 0:
    80  		bus.c.Fatalf("i2c mock: need a write byte")
    81  		return nil
    82  	case 1:
    83  		return bus.readRegister(w[0], r)
    84  	default:
    85  		if len(r) > 0 || len(w) == 1 {
    86  			bus.c.Fatalf("i2c mock: unsupported lengths in Tx(%d, %d)", len(w), len(r))
    87  		}
    88  		return bus.writeRegister(w[0], w[1:])
    89  	}
    90  }