def test_adapters():
    bus = MockSMBus(1)
    device = Device(0x00,
                    i2c_dev=bus,
                    registers=(Register(
                        'adapter',
                        0x01,
                        fields=(BitField('test',
                                         0xFFFF,
                                         adapter=U16ByteSwapAdapter()), )), ))

    device.adapter.set_test(0xFF00)

    assert device.adapter.get_test() == 0xFF00

    assert bus.regs[0:2] == [0x00, 0xFF]
Exemple #2
0
            volatile=False),
        Register(
            'MANUFACTURER_ID',
            0x87,
            fields=(
                BitField('manufacturer_id', 0b11111111),  # Should be 0x05H
            ),
            read_only=True),

        # This will address 0x88, 0x89, 0x8A and 0x8B as a continuous 32bit register
        Register('ALS_DATA',
                 0x88,
                 fields=(BitField('ch1',
                                  0xFFFF0000,
                                  bit_width=16,
                                  adapter=U16ByteSwapAdapter()),
                         BitField('ch0',
                                  0x0000FFFF,
                                  bit_width=16,
                                  adapter=U16ByteSwapAdapter())),
                 read_only=True,
                 bit_width=32),
        Register(
            'ALS_PS_STATUS',
            0x8C,
            fields=(
                BitField('als_data_valid', 0b10000000),
                BitField('als_gain',
                         0b01110000,
                         adapter=LookupAdapter({
                             1: 0b000,
Exemple #3
0
    def __init__(self, i2c_addr=0x38, i2c_dev=None):
        """Initialise sensor.

        :param i2c_addr: i2c address of sensor
        :param i2c_dev: SMBus-compatible instance

        """
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._is_setup = False
        # Device definition
        self._bh1745 = Device(I2C_ADDRESSES, i2c_dev=self._i2c_dev, bit_width=8, registers=(
            # Part ID should be 0b001011 or 0x0B
            Register('SYSTEM_CONTROL', 0x40, fields=(
                BitField('sw_reset', 0b10000000),
                BitField('int_reset', 0b01000000),
                BitField('part_id', 0b00111111, read_only=True)
            )),

            Register('MODE_CONTROL1', 0x41, fields=(
                BitField('measurement_time_ms', 0b00000111, adapter=LookupAdapter({
                    160: 0b000,
                    320: 0b001,
                    640: 0b010,
                    1280: 0b011,
                    2560: 0b100,
                    5120: 0b101
                })),
            )),

            Register('MODE_CONTROL2', 0x42, fields=(
                BitField('valid', 0b10000000, read_only=True),
                BitField('rgbc_en', 0b00010000),
                BitField('adc_gain_x', 0b00000011, adapter=LookupAdapter({
                    1: 0b00, 2: 0b01, 16: 0b10}))
            )),

            Register('MODE_CONTROL3', 0x44, fields=(
                BitField('on', 0b11111111, adapter=LookupAdapter({True: 2, False: 0})),
            )),

            Register('COLOUR_DATA', 0x50, fields=(
                BitField('red', 0xFFFF000000000000, adapter=U16ByteSwapAdapter()),
                BitField('green', 0x0000FFFF00000000, adapter=U16ByteSwapAdapter()),
                BitField('blue', 0x00000000FFFF0000, adapter=U16ByteSwapAdapter()),
                BitField('clear', 0x000000000000FFFF, adapter=U16ByteSwapAdapter())
            ), bit_width=64, read_only=True),

            Register('DINT_DATA', 0x58, fields=(
                BitField('data', 0xFFFF, adapter=U16ByteSwapAdapter()),
            ), bit_width=16),

            Register('INTERRUPT', 0x60, fields=(
                BitField('status', 0b10000000, read_only=True),
                BitField('latch', 0b00010000, adapter=LookupAdapter({0: 1, 1: 0})),
                BitField('source', 0b00001100, read_only=True, adapter=LookupAdapter({
                    'red': 0b00,
                    'green': 0b01,
                    'blue': 0b10,
                    'clear': 0b11
                })),
                BitField('enable', 0b00000001)
            )),

            # 00: Interrupt status is toggled at each measurement end
            # 01: Interrupt status is updated at each measurement end
            # 10: Interrupt status is updated if 4 consecutive threshold judgements are the same
            # 11: Blah blah ditto above except for 8 consecutive judgements
            Register('PERSISTENCE', 0x61, fields=(
                BitField('mode', 0b00000011, adapter=LookupAdapter({
                    'toggle': 0b00,
                    'update': 0b01,
                    'update_on_4': 0b10,
                    'update_on_8': 0b11
                })),
            )),

            # High threshold defaults to 0xFFFF
            # Low threshold defaults to 0x0000
            Register('THRESHOLD', 0x62, fields=(
                BitField('high', 0xFFFF0000, adapter=U16ByteSwapAdapter()),
                BitField('low', 0x0000FFFF, adapter=U16ByteSwapAdapter())
            ), bit_width=32),

            # Default MANUFACTURER ID is 0xE0h
            Register('MANUFACTURER', 0x92, fields=(
                BitField('id', 0xFF),
            ), read_only=True, volatile=False)
        ))

        self._bh1745.select_address(self._i2c_addr)

        # TODO : Integrate into i2cdevice so that LookupAdapter fields can always be exported to constants
        # Iterate through all register fields and export their lookup tables to constants
        for register in self._bh1745.registers:
            register = self._bh1745.registers[register]
            for field in register.fields:
                field = register.fields[field]
                if isinstance(field.adapter, LookupAdapter):
                    for key in field.adapter.lookup_table:
                        name = 'BH1745_{register}_{field}_{key}'.format(
                            register=register.name,
                            field=field.name,
                            key=key
                        ).upper()
                        globals()[name] = key

        """
        Approximate compensation for the spectral response performance curves
        """
        self._channel_compensation = (2.2, 1.0, 1.8, 10.0)
        self._enable_channel_compensation = True
Exemple #4
0
    def __init__(self, i2c_addr=0x1D, i2c_dev=None):
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._lsm303d = Device(
            [0x1D, 0x1E],
            i2c_dev=self._i2c_dev,
            bit_width=8,
            registers=(
                Register('TEMPERATURE',
                         0x05 | 0x80,
                         fields=(BitField('temperature',
                                          0xFFFF,
                                          adapter=TemperatureAdapter()), ),
                         bit_width=16),

                # Magnetometer interrupt status
                Register('MAGNETOMETER_STATUS',
                         0x07,
                         fields=(
                             BitField('xdata', 0b00000001),
                             BitField('ydata', 0b00000010),
                             BitField('zdata', 0b00000100),
                             BitField('data', 0b00001000),
                             BitField('xoverrun', 0b00010000),
                             BitField('yoverrun', 0b00100000),
                             BitField('zoverrun', 0b01000000),
                             BitField('overrun', 0b10000000),
                         )),
                Register('MAGNETOMETER',
                         0x08 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),
                Register('WHOAMI', 0x0F, fields=(BitField('id', 0xFF), )),
                Register(
                    'MAGNETOMETER_INTERRUPT',
                    0x12,
                    fields=(
                        BitField('enable', 0b00000001),
                        BitField('4d', 0b00000010),
                        BitField('latch', 0b00000100),
                        BitField(
                            'polarity',
                            0b00001000),  # 0 = active-low, 1 = active-high
                        BitField('pin_config',
                                 0b00010000),  # 0 = push-pull, 1 = open-drain
                        BitField('z_enable', 0b00100000),
                        BitField('y_enable', 0b01000000),
                        BitField('x_enable', 0b10000000),
                    )),
                Register('MAGNETOMETER_INTERRUPT_SOURCE',
                         0x13,
                         fields=(
                             BitField('event', 0b00000001),
                             BitField('overflow', 0b00000010),
                             BitField('z_negative', 0b00000100),
                             BitField('y_negative', 0b00001000),
                             BitField('x_negative', 0b00010000),
                             BitField('z_positive', 0b00100000),
                             BitField('y_positive', 0b01000000),
                             BitField('x_positive', 0b10000000),
                         )),
                Register('MAGNETOMETER_INTERRUPT_THRESHOLD',
                         0x14 | 0x80,
                         fields=(BitField('threshold',
                                          0xFFFF,
                                          adapter=U16ByteSwapAdapter()), ),
                         bit_width=16),
                Register('MAGNETOMETER_OFFSET',
                         0x16 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),
                Register('HP_ACCELEROMETER_REFERENCE',
                         0x1c | 0x80,
                         fields=(
                             BitField('x', 0xFF0000),
                             BitField('y', 0x00FF00),
                             BitField('z', 0x0000FF),
                         ),
                         bit_width=8 * 3),
                Register('CONTROL0',
                         0x1f,
                         fields=(
                             BitField('int2_high_pass', 0b00000001),
                             BitField('int1_high_pass', 0b00000010),
                             BitField('click_high_pass', 0b00000100),
                             BitField('fifo_threshold', 0b00100000),
                             BitField('fifo_enable', 0b01000000),
                             BitField('reboot_memory', 0b10000000),
                         )),
                Register('CONTROL1',
                         0x20,
                         fields=(
                             BitField('accel_x_enable', 0b00000001),
                             BitField('accel_y_enable', 0b00000010),
                             BitField('accel_z_enable', 0b00000100),
                             BitField('block_data_update', 0b00001000),
                             BitField('accel_data_rate_hz',
                                      0b11110000,
                                      adapter=LookupAdapter({
                                          0: 0,
                                          3.125: 0b0001,
                                          6.25: 0b0010,
                                          12.5: 0b0011,
                                          25: 0b0100,
                                          50: 0b0101,
                                          100: 0b0110,
                                          200: 0b0111,
                                          400: 0b1000,
                                          800: 0b1001,
                                          1600: 0b1010
                                      })),
                         )),
                Register('CONTROL2',
                         0x21,
                         fields=(
                             BitField('serial_interface_mode', 0b00000001),
                             BitField('accel_self_test', 0b00000010),
                             BitField('accel_full_scale_g',
                                      0b00111000,
                                      adapter=LookupAdapter({
                                          2: 0b000,
                                          4: 0b001,
                                          6: 0b010,
                                          8: 0b011,
                                          16: 0b100
                                      })),
                             BitField('accel_antialias_bw_hz',
                                      0b11000000,
                                      adapter=LookupAdapter({
                                          50: 0b11,
                                          362: 0b10,
                                          194: 0b01,
                                          773: 0b00
                                      })),
                         )),

                # Known in the datasheet as CTRL3
                Register('INTERRUPT1',
                         0x22,
                         fields=(
                             BitField('enable_fifo_empty', 0b00000001),
                             BitField('enable_accel_dataready', 0b00000010),
                             BitField('enable_accelerometer', 0b00000100),
                             BitField('enable_magnetometer', 0b00001000),
                             BitField('enable_ig2', 0b00010000),
                             BitField('enable_ig1', 0b00100000),
                             BitField('enable_click', 0b01000000),
                             BitField('enable_boot', 0b10000000),
                         )),

                # Known in the datasheet as CTRL4
                Register('INTERRUPT2',
                         0x23,
                         fields=(
                             BitField('enable_fifo', 0b00000001),
                             BitField('enable_fifo_overrun', 0b00000010),
                             BitField('enable_mag_dataready', 0b00000100),
                             BitField('enable_accel_dataready', 0b00001000),
                             BitField('enable_magnetometer', 0b00010000),
                             BitField('enable_ig2', 0b00100000),
                             BitField('enable_ig1', 0b01000000),
                             BitField('enable_click', 0b10000000),
                         )),
                Register('CONTROL5',
                         0x24,
                         fields=(
                             BitField('latch_int1', 0b00000001),
                             BitField('latch_int2', 0b00000010),
                             BitField('mag_data_rate_hz',
                                      0b00011100,
                                      adapter=LookupAdapter({
                                          3.125: 0b000,
                                          6.25: 0b001,
                                          12.5: 0b010,
                                          25: 0b011,
                                          50: 0b100,
                                          100: 0b101,
                                      })),
                             BitField('mag_resolution', 0b01100000),
                             BitField('enable_temperature', 0b10000000),
                         )),
                Register('CONTROL6',
                         0x25,
                         fields=(BitField('mag_full_scale_gauss',
                                          0b01100000,
                                          adapter=LookupAdapter({
                                              2: 0b00,
                                              4: 0b01,
                                              8: 0b10,
                                              12: 0b11
                                          })), )),
                Register(
                    'CONTROL7',
                    0x26,
                    fields=(
                        BitField('mag_mode',
                                 0b00000011,
                                 adapter=LookupAdapter({
                                     'continuous': 0b00,
                                     'single': 0b01,
                                     'off': 0b10
                                 })),
                        BitField('mag_lowpowermode', 0b00000100),
                        BitField('temperature_only', 0b00010000),
                        BitField('filter_accel', 0b00100000),
                        BitField('high_pass_mode_accel',
                                 0b11000000),  # See page 39 of lsm303d.pdf
                    )),

                # Accelerometer interrupt status register
                Register('ACCELEROMETER_STATUS',
                         0x27,
                         fields=(BitField('xdata', 0b00000001),
                                 BitField('ydata', 0b00000010),
                                 BitField('zdata', 0b00000100),
                                 BitField('data', 0b00001000),
                                 BitField('xoverrun', 0b00010000),
                                 BitField('yoverrun', 0b00100000),
                                 BitField('zoverrun', 0b01000000),
                                 BitField('overrun', 0b10000000))),

                # X/Y/Z values from accelerometer
                Register('ACCELEROMETER',
                         0x28 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),

                # FIFO control register
                Register('FIFO_CONTROL',
                         0x2e,
                         fields=(
                             BitField('mode', 0b11100000),
                             BitField('threshold', 0b00011111),
                         )),

                # FIFO status register
                Register(
                    'FIFO_STATUS',
                    0x2f,
                    fields=(
                        BitField('threshold_exceeded', 1 << 7),
                        BitField('overrun', 1 << 6),
                        BitField('empty', 1 << 5),
                        BitField('unread_levels', 0b00011111
                                 ),  # Current number of unread FIFO levels
                    )),

                # 0x30: Internal interrupt generator 1: configuration register
                # 0x31: Internal interrupt generator 1: status register
                # 0x32: Internal interrupt generator 1: threshold register
                # 0x33: Internal interrupt generator 1: duration register
                Register(
                    'IG_CONFIG1',
                    0x30 | 0x80,
                    fields=(
                        # 0x30
                        BitField('and_or_combination', 1 << 31),
                        BitField('6d_enable', 1 << 30),
                        BitField('z_high_enable', 1 << 29),
                        BitField('z_low_enable', 1 << 28),
                        BitField('y_high_enable', 1 << 27),
                        BitField('y_low_enable', 1 << 26),
                        BitField('x_high_enable', 1 << 25),
                        BitField('x_low_enble', 1 << 24),
                        # 0x31
                        BitField('interrupt_status', 1 << 23),
                        BitField('z_high', 1 << 22),
                        BitField('z_low', 1 << 21),
                        BitField('y_high', 1 << 20),
                        BitField('y_low', 1 << 19),
                        BitField('x_high', 1 << 18),
                        BitField('x_low', 1 << 17),
                        BitField('status', 1 << 16),
                        # 0x32
                        BitField('threshold', 0xff << 8),
                        # 0x33
                        BitField('duration', 0xff),
                    ),
                    bit_width=32),

                # 0x34: Internal interrupt generator 2: configuration register
                # 0x35: Internal interrupt generator 2: status register
                # 0x36: Internal interrupt generator 2: threshold register
                # 0x37: Internal interrupt generator 2: duration register
                Register(
                    'IG_CONFIG1',
                    0x30 | 0x80,
                    fields=(
                        # 0x34
                        BitField('and_or_combination', 1 << 31),
                        BitField('6d_enable', 1 << 30),
                        BitField('z_high_enable', 1 << 29),
                        BitField('z_low_enable', 1 << 28),
                        BitField('y_high_enable', 1 << 27),
                        BitField('y_low_enable', 1 << 26),
                        BitField('x_high_enable', 1 << 25),
                        BitField('x_low_enble', 1 << 24),
                        # 0x35
                        BitField('interrupt_status', 1 << 23),
                        BitField('z_high', 1 << 22),
                        BitField('z_low', 1 << 21),
                        BitField('y_high', 1 << 20),
                        BitField('y_low', 1 << 19),
                        BitField('x_high', 1 << 18),
                        BitField('x_low', 1 << 17),
                        BitField('status', 1 << 16),
                        # 0x36
                        BitField('threshold', 0xff << 8),
                        # 0x37
                        BitField('duration', 0xff),
                    ),
                    bit_width=32),

                # 0x38: Click: configuration register
                # 0x39: Click: status register
                # 0x3A: Click: threshold register
                # 0x3B: Click: time limit register
                # 0x3C: Click: time latency register
                # 0x3D: Click: time window register
                Register(
                    'CLICK',
                    0x38 | 0x80,
                    fields=(
                        # 0x38
                        # bits 1 << 47 and 1 << 46 are unimplemented
                        BitField('z_doubleclick_enable', 1 << 45),
                        BitField('z_click_enable', 1 << 44),
                        BitField('y_doubleclick_enable', 1 << 43),
                        BitField('y_click_enable', 1 << 42),
                        BitField('x_doubleclick_enable', 1 << 41),
                        BitField('x_click_enable', 1 << 40),
                        # 0x39
                        # bit 1 << 39 is unimplemented
                        BitField('interrupt_enable', 1 << 38),
                        BitField('doubleclick_enable', 1 << 37),
                        BitField('click_enable', 1 << 36),
                        BitField(
                            'sign', 1 <<
                            35),  # 0 positive detection, 1 negative detection
                        BitField('z', 1 << 34),
                        BitField('y', 1 << 33),
                        BitField('x', 1 << 32),
                        # 0x3A
                        BitField('threshod', 0xFF << 24),
                        # 0x3B
                        BitField('time_limit', 0xFF << 16),
                        # 0x3C
                        BitField('time_latency', 0xFF << 8),
                        # 0x3D
                        BitField('time_window', 0xFF),
                    ),
                    bit_width=8 * 6),

                # Controls the threshold and duration of returning to sleep mode
                Register(
                    'ACT',
                    0x3e | 0x80,
                    fields=(
                        BitField('threshold', 0xFF00),  # 1 LSb = 16mg
                        BitField('duration',
                                 0x00FF)  # (duration + 1) * 8/output_data_rate
                    ),
                    bit_width=16)))

        self._is_setup = False

        self._accel_full_scale_g = 2
        self._mag_full_scale_guass = 2
Exemple #5
0
    def __init__(self, i2c_dev=None, enable_interrupts=False, interrupt_pin_polarity=1, timeout=5.0):
        """Initialise the LTR559.

        This sets up the LTR559 and checks that the Part Number ID matches 0x09 and
        that the Revision Number ID matches 0x02. If you come across an unsupported
        revision you should raise an Issue at https://github.com/pimoroni/ltr559-python

        Several known-good default values are picked during setup, and the interrupt
        thresholds are reset to the full range so that interrupts will not fire unless
        configured manually using `set_light_threshold` and `set_proximity_threshold`.

        Interrupts are always enabled, since this must be done before the sensor is active.

        """
        self._als0 = 0
        self._als1 = 0
        self._ps0 = 0
        self._lux = 0
        self._ratio = 100

        # Non default
        self._gain = 4  # 4x gain = 0.25 to 16k lux
        self._integration_time = 50

        self._ch0_c = (17743, 42785, 5926, 0)
        self._ch1_c = (-11059, 19548, -1185, 0)

        self._ltr559 = Device(I2C_ADDR, i2c_dev=i2c_dev, bit_width=8, registers=(
            Register('ALS_CONTROL', 0x80, fields=(
                BitField('gain', 0b00011100, adapter=LookupAdapter({
                    1: 0b000,
                    2: 0b001,
                    4: 0b010,
                    8: 0b011,
                    48: 0b110,
                    96: 0b111})),
                BitField('sw_reset', 0b00000010),
                BitField('mode', 0b00000001)
            )),

            Register('PS_CONTROL', 0x81, fields=(
                BitField('saturation_indicator_enable', 0b00100000),
                BitField('active', 0b00000011, adapter=LookupAdapter({
                    False: 0b00,
                    True: 0b11}))
            )),

            Register('PS_LED', 0x82, fields=(
                BitField('pulse_freq_khz', 0b11100000, adapter=LookupAdapter({
                    30: 0b000,
                    40: 0b001,
                    50: 0b010,
                    60: 0b011,
                    70: 0b100,
                    80: 0b101,
                    90: 0b110,
                    100: 0b111})),
                BitField('duty_cycle', 0b00011000, adapter=LookupAdapter({
                    0.25: 0b00,
                    0.5: 0b01,
                    0.75: 0b10,
                    1.0: 0b11})),
                BitField('current_ma', 0b00000111, adapter=LookupAdapter({
                    5: 0b000,
                    10: 0b001,
                    20: 0b010,
                    50: 0b011,
                    100: 0b100}))
            )),

            Register('PS_N_PULSES', 0x83, fields=(
                BitField('count', 0b00001111),
            )),

            Register('PS_MEAS_RATE', 0x84, fields=(
                BitField('rate_ms', 0b00001111, adapter=LookupAdapter({
                    10: 0b1000,
                    50: 0b0000,
                    70: 0b0001,
                    100: 0b0010,
                    200: 0b0011,
                    500: 0b0100,
                    1000: 0b0101,
                    2000: 0b0110})),
            )),

            Register('ALS_MEAS_RATE', 0x85, fields=(
                BitField('integration_time_ms', 0b00111000, adapter=LookupAdapter({
                    100: 0b000,
                    50: 0b001,
                    200: 0b010,
                    400: 0b011,
                    150: 0b100,
                    250: 0b101,
                    300: 0b110,
                    350: 0b111})),
                BitField('repeat_rate_ms', 0b00000111, adapter=LookupAdapter({
                    50: 0b000,
                    100: 0b001,
                    200: 0b010,
                    500: 0b011,
                    1000: 0b100,
                    2000: 0b101}))
            )),

            Register('PART_ID', 0x86, fields=(
                BitField('part_number', 0b11110000),  # Should be 0x09H
                BitField('revision', 0b00001111)      # Should be 0x02H
            ), read_only=True, volatile=False),

            Register('MANUFACTURER_ID', 0x87, fields=(
                BitField('manufacturer_id', 0b11111111),  # Should be 0x05H
            ), read_only=True),

            # This will address 0x88, 0x89, 0x8A and 0x8B as a continuous 32bit register
            Register('ALS_DATA', 0x88, fields=(
                BitField('ch1', 0xFFFF0000, bit_width=16, adapter=U16ByteSwapAdapter()),
                BitField('ch0', 0x0000FFFF, bit_width=16, adapter=U16ByteSwapAdapter())
            ), read_only=True, bit_width=32),

            Register('ALS_PS_STATUS', 0x8C, fields=(
                BitField('als_data_valid', 0b10000000),
                BitField('als_gain', 0b01110000, adapter=LookupAdapter({
                    1: 0b000,
                    2: 0b001,
                    4: 0b010,
                    8: 0b011,
                    48: 0b110,
                    96: 0b111})),
                BitField('als_interrupt', 0b00001000),  # True = Interrupt is active
                BitField('als_data', 0b00000100),       # True = New data available
                BitField('ps_interrupt', 0b00000010),   # True = Interrupt is active
                BitField('ps_data', 0b00000001)         # True = New data available
            ), read_only=True),

            # The PS data is actually an 11bit value but since B3 is reserved it'll (probably) read as 0
            # We could mask the result if necessary
            Register('PS_DATA', 0x8D, fields=(
                BitField('ch0', 0xFF0F, adapter=Bit12Adapter()),
                BitField('saturation', 0x0080)
            ), bit_width=16, read_only=True),

            # INTERRUPT allows the interrupt pin and function behaviour to be configured.
            Register('INTERRUPT', 0x8F, fields=(
                BitField('polarity', 0b00000100),
                BitField('mode', 0b00000011, adapter=LookupAdapter({
                    'off': 0b00,
                    'ps': 0b01,
                    'als': 0b10,
                    'als+ps': 0b11}))
            )),

            Register('PS_THRESHOLD', 0x90, fields=(
                BitField('upper', 0xFF0F0000, adapter=Bit12Adapter()),
                BitField('lower', 0x0000FF0F, adapter=Bit12Adapter())
            ), bit_width=32),

            # PS_OFFSET defines the measurement offset value to correct for proximity
            # offsets caused by device variations, crosstalk and other environmental factors.
            Register('PS_OFFSET', 0x94, fields=(
                BitField('offset', 0x03FF),  # Last two bits of 0x94, full 8 bits of 0x95
            ), bit_width=16),

            # Defines the upper and lower limits of the ALS reading.
            # An interrupt is triggered if values fall outside of this range.
            # See also INTERRUPT_PERSIST.
            Register('ALS_THRESHOLD', 0x97, fields=(
                BitField('upper', 0xFFFF0000, adapter=U16ByteSwapAdapter(), bit_width=16),
                BitField('lower', 0x0000FFFF, adapter=U16ByteSwapAdapter(), bit_width=16)
            ), bit_width=32),

            # This register controls how many values must fall outside of the range defined
            # by upper and lower threshold limits before the interrupt is asserted.

            # In the case of both PS and ALS, a 0 value indicates that every value outside
            # the threshold range should be counted.
            # Values therein map to n+1 , ie: 0b0001 requires two consecutive values.
            Register('INTERRUPT_PERSIST', 0x9E, fields=(
                BitField('PS', 0xF0),
                BitField('ALS', 0x0F)
            ))

        ))

        """Set up the LTR559 sensor"""
        self.part_id = self._ltr559.get('PART_ID')
        if self.part_id.part_number != PART_ID or self.part_id.revision != REVISION_ID:
            raise RuntimeError("LTR559 not found")

        self._ltr559.set('ALS_CONTROL', sw_reset=1)

        t_start = time.time()
        while time.time() - t_start < timeout:
            status = self._ltr559.get('ALS_CONTROL').sw_reset
            if status == 0:
                break
            time.sleep(0.05)

        if self._ltr559.get('ALS_CONTROL').sw_reset:
            raise RuntimeError("Timeout waiting for software reset.")

        # Interrupt register must be set before device is switched to active mode
        # see datasheet page 12/40, note #2.
        if enable_interrupts:
            self._ltr559.set('INTERRUPT',
                             mode='als+ps',
                             polarity=interrupt_pin_polarity)

        # FIXME use datasheet defaults or document
        # No need to run the proximity LED at 100mA, so we pick 50 instead.
        # Tests suggest this works pretty well.
        self._ltr559.set('PS_LED',
                         current_ma=50,
                         duty_cycle=1.0,
                         pulse_freq_khz=30)

        # 1 pulse is the default value
        self._ltr559.set('PS_N_PULSES', count=1)

        self._ltr559.set('ALS_CONTROL',
                         mode=1,
                         gain=self._gain)

        self._ltr559.set('PS_CONTROL',
                         active=True,
                         saturation_indicator_enable=1)

        self._ltr559.set('PS_MEAS_RATE', rate_ms=100)

        self._ltr559.set('ALS_MEAS_RATE',
                         integration_time_ms=self._integration_time,
                         repeat_rate_ms=50)

        self._ltr559.set('ALS_THRESHOLD',
                         lower=0x0000,
                         upper=0xFFFF)

        self._ltr559.set('PS_THRESHOLD',
                         lower=0x0000,
                         upper=0xFFFF)

        self._ltr559.set('PS_OFFSET', offset=0)
        BitField('integration_time_ms', 0b00111000, adapter=LookupAdapter({100: 0b000, 50: 0b001, 200: 0b010, 400: 0b011, 150: 0b100, 250: 0b101, 300: 0b110, 350: 0b111})),
        BitField('repeat_rate_ms', 0b00000111, adapter=LookupAdapter({50: 0b000, 100: 0b001, 200: 0b010, 500: 0b011, 1000: 0b100, 2000: 0b101}))
    )),

    Register('PART_ID', 0x86, fields=(
        BitField('part_number', 0b11110000),  # Should be 0x09H
        BitField('revision', 0b00001111)  # Should be 0x02H
    ), read_only=True, volatile=False),

    Register('MANUFACTURER_ID', 0x87, fields=(
        BitField('manufacturer_id', 0b11111111),  # Should be 0x05H
    ), read_only=True),

    # This will address 0x88, 0x89, 0x8A and 0x8B as a continuous 32bit register
    Register('ALS_DATA', 0x88, fields=(
        BitField('ch1', 0xFFFF0000, bit_width=16, adapter=U16ByteSwapAdapter()),
        BitField('ch0', 0x0000FFFF, bit_width=16, adapter=U16ByteSwapAdapter())
    ), read_only=True, bit_width=32),

    Register('ALS_PS_STATUS', 0x8C, fields=(
        BitField('als_data_valid', 0b10000000),
        BitField('als_gain', 0b01110000, adapter=LookupAdapter({1: 0b000, 2: 0b001, 4: 0b010, 8: 0b011, 48: 0b110, 96: 0b111})),
        BitField('als_interrupt', 0b00001000),  # True = Interrupt is active
        BitField('als_data', 0b00000100),  # True = New data available
        BitField('ps_interrupt', 0b00000010),  # True = Interrupt is active
        BitField('ps_data', 0b00000001)  # True = New data available
    ), read_only=True),

    # The PS data is actually an 11bit value but since B3 is reserved it'll (probably) read as 0
    # We could mask the result if necessary
    Register('PS_DATA', 0x8D, fields=(
Exemple #7
0
    def __init__(self, i2c_addr=0x26, i2c_dev=None):
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._is_setup = False

        self._rv3028 = Device([0x52], i2c_dev=self._i2c_dev, bit_width=8, registers=(
            Register('SECONDS', 0x00, fields=(
                BitField('seconds', 0x7F, adapter=BCDAdapter()),
            )),
            Register('MINUTES', 0x01, fields=(
                BitField('minutes', 0x7F, adapter=BCDAdapter()),
            )),
            Register('HOURS', 0x02, fields=(
                BitField('t24hours', 0b00111111, adapter=BCDAdapter()),
                BitField('t12hours', 0b00011111, adapter=BCDAdapter()),
                BitField('am_pm', 0b00100000),
            )),
            Register('WEEKDAY', 0x03, fields=(
                BitField('weekday', 0b00000111),
            )),
            Register('DATE', 0x04, fields=(
                BitField('date', 0b00111111, adapter=BCDAdapter()),
            )),
            Register('MONTH', 0x05, fields=(
                BitField('month', 0b00011111, adapter=BCDAdapter()),
            )),
            Register('YEAR', 0x06, fields=(
                BitField('year', 0xFF, adapter=BCDAdapter()),
            )),
            Register('ALARM_MINUTES', 0x07, fields=(
                BitField('minutes_alarm_enable', 0b10000000),
                BitField('minutes', 0x7F, adapter=BCDAdapter()),
            )),
            Register('ALARM_HOURS', 0x08, fields=(
                BitField('hours_alarm_enable', 0b10000000, adapter=BCDAdapter()),
                BitField('t24hours', 0b00111111, adapter=BCDAdapter()),
                BitField('t12hours', 0b00011111, adapter=BCDAdapter()),
                BitField('am_pm', 0b00100000),
            )),
            Register('ALARM_WEEKDAY', 0x09, fields=(
                BitField('weekday_alarm_enable', 0b10000000, adapter=BCDAdapter()),
                BitField('weekday', 0b00000111),
                BitField('date', 0b00111111)
            )),
            Register('TIMER_VALUE', 0x0A, fields=(
                BitField('value', 0xFF0F, adapter=U16ByteSwapAdapter()),
            ), bit_width=16),
            Register('TIMER_STATUS', 0x0C, fields=(
                BitField('value', 0xFF0F, adapter=U16ByteSwapAdapter()),
            ), bit_width=16),
            Register('STATUS', 0x0E, fields=(
                BitField('value', 0xFF),
                BitField('eeprom_busy_flag', 0b10000000),
                BitField('clock_output_interrupt_flag', 0b01000000),
                BitField('backup_switch_flag', 0b00100000),
                BitField('periodic_time_update_flag', 0b00010000),
                BitField('periodic_countdown_timer_flag', 0b00001000),
                BitField('alarm_flag', 0b00000100),
                BitField('external_event_flag', 0b00000010),
                BitField('power_on_reset_flag', 0b00000001),
            )),
            Register('CONTROL_1', 0x0F, fields=(
                BitField('value', 0xFF),
                BitField('timer_repeat', 0b10000000),
                BitField('weekday_date_alarm', 0b00100000),
                BitField('update_interrupt', 0b00010000),
                BitField('eeprom_memory_refresh_disable', 0b00001000),
                BitField('periodic_countdown_timer_enable', 0b00000100),
                BitField('timer_frequency_selection', 0b00000011, adapter=LookupAdapter({
                    '4036Hz': 0b00,  # 214.14us
                    '63Hz': 0b01,    # 15.625ms
                    '1Hz': 0b10,     # 1s
                    '0.016Hz': 0b11  # 60s
                })),
            )),
            Register('CONTROL_2', 0x10, fields=(
                BitField('value', 0xFF),
                BitField('timestamp_enable', 0b10000000),
                BitField('interrupt_controlled_output_enable', 0b01000000),
                BitField('periodic_time_update_interupt_enable', 0b00100000),
                BitField('periodic_countdown_timer_interupt_enable', 0b00010000),
                BitField('alarm_interupt_enable', 0b00001000),
                BitField('external_event_interrupt_enable', 0b00000100),
                BitField('select_24_12_hours', 0b00000010),
                BitField('reset', 0b00000001),
            )),
            Register('GENERAL_PURPOSE_STORAGE_REGISTER', 0x11, fields=(
                BitField('value', 0b01111111),
            )),
            Register('CLOCK_INTERRUPT_MASK', 0x12, fields=(
                BitField('value', 0x0F),
                BitField('clock_output_when_event_interrupt', 0b00001000),
                BitField('clock_output_when_alarm_interrupt', 0b00000100),
                BitField('clock_output_when_countdown_interrupt', 0b00000010),
                BitField('clock_output_when_periodic_interrupt', 0b00000001),
            )),
            Register('EVENT_CONTROL', 0x13, fields=(
                BitField('value', 0xFF),
                BitField('event_high_low_detection', 0b01000000),
                BitField('event_filtering_time', 0b00110000, adapter=LookupAdapter({
                    'no_filtering': 0b00,
                    '3.9ms': 0b01,
                    '15.6ms': 0b10,
                    '125ms': 0b11
                })),
                BitField('timestamp_reset', 0b00000100),
                BitField('timestamp_overwrite', 0b00000010),
                BitField('timestamp_source', 0b00000001),
            )),
            Register('TIMESTAMP_COUNT', 0x14, fields=(
                BitField('value', 0xFF),
            )),
            Register('TIMESTAMP_SECONDS', 0x15, fields=(
                BitField('seconds', 0x7F),
            )),
            Register('TIMESTAMP_MINUTES', 0x16, fields=(
                BitField('minutes', 0x7F),
            )),
            Register('TIMESTAMP_HOURS', 0x17, fields=(
                BitField('t24hours', 0b00111111),
                BitField('t12hours', 0b00001111),
                BitField('am_pm', 0x00010000),
            )),
            Register('TIMESTAMP_DATE', 0x18, fields=(
                BitField('date', 0b00011111),
            )),
            Register('TIMESTAMP_MONTH', 0x19, fields=(
                BitField('month', 0b00001111),
            )),
            Register('TIMESTAMP_YEAR', 0x1A, fields=(
                BitField('year', 0xFF),
            )),
            Register('UNIX_TIME', 0x1B, fields=(
                BitField('value', 0xFFFFFFFF, adapter=ReverseBytesAdapter(4)),
            ), bit_width=32),
            Register('USER_RAM', 0x1F, fields=(
                BitField('one', 0x00FF),
                BitField('two', 0xFF00),
            ), bit_width=16),
            Register('PASSWORD', 0x21, fields=(
                BitField('value', 0xFFFFFFFF),
            ), bit_width=32),
            Register('EEPROM_ADDRESS', 0x25, fields=(
                BitField('value', 0xFF),
            )),
            Register('EEPROM_DATA', 0x26, fields=(
                BitField('value', 0xFF),
            )),
            Register('EEPROM_COMMAND', 0x27, fields=(
                BitField('command', 0xFF, adapter=LookupAdapter({
                    'first_command': 0x00,
                    'write_all_configuration_to_eeprom': 0x11,
                    'read_all_configuration_from_eeprom': 0x12,
                    'write_one_byte_to_eeprom_address': 0x21,
                    'read_one_byte_from_eeprom_address': 0x22
                })),
            )),
            Register('PART', 0x28, fields=(
                BitField('id', 0xF0),
                BitField('version', 0x0F)
            )),
            Register('EEPROM_PASSWORD_ENABLE', 0x30, fields=(
                BitField('value', 0xFF),  # Write 0xFF to this register to enable EEPROM password
            )),
            Register('EEPROM_PASSWORD', 0x31, fields=(
                BitField('value', 0xFFFFFFFF),
            ), bit_width=32),
            Register('EEPROM_CLKOUT', 0x35, fields=(
                BitField('value', 0xFF),
                BitField('clkout_output', 0b10000000),
                BitField('clkout_synchronized', 0b01000000),
                BitField('power_on_reset_interrupt_enable', 0b00001000),
                BitField('clkout_frequency_selection', 0b00000111, adapter=LookupAdapter({
                    '32.768kHz': 0b000,
                    '8192Hz': 0b001,
                    '1024Hz': 0b010,
                    '64Hz': 0b011,
                    '32Hz': 0b100,
                    '1Hz': 0b101,
                    'periodic_countdown_timer_interrupt': 0b110,
                    'clkout_low': 0b111,
                })),
            )),
            Register('EEPROM_OFFSET', 0x36, fields=(
                BitField('value', 0xFF),
            )),
            Register('EEPROM_BACKUP', 0x37, fields=(
                BitField('value', 0xFF),
                BitField('ee_offset', 0b10000000),
                BitField('backup_switchover_interrupt_enable', 0b01000000),
                BitField('trickle_charger_enable', 0b00100000),
                BitField('fast_edge_detection', 0b00010000),
                BitField('automatic_battery_switchover', 0b00001100, adapter=LookupAdapter({
                    'switchover_disabled': 0b00,
                    'direct_switching_mode': 0b01,
                    'standby_mode': 0b10,
                    'level_switching_mode': 0b11
                })),
                BitField('trickle_charger_series_resistance', 0b00000011, adapter=LookupAdapter({
                    '1kOhm': 0b00,
                    '3kOhm': 0b01,
                    '6kOhm': 0b10,
                    '11kOhm': 0b11
                })),
            ))


        ))
        self.enable_12hours = self._rv3028.get('CONTROL_2').select_24_12_hours
        self.alarm_frequency = {
            'disabled_weekly': 0b0111,
            'disabled_monthly': 0b1111,
            'hourly_on_minute': 0b110,
            'daily_on_hour': 0b101,
            'daily_on_hour_and_minute': 0b011,
            'weekly': 0b0011,
            'weekly_on_minute': 0b0010,
            'weekly_on_hour': 0b0001,
            'weekly_on_hour_and_minute': 0b0000,
            'monthly': 0b1011,
            'monthly_on_minute': 0b1010,
            'monthly_on_hour': 0b1001,
            'monthly_on_hour_and_minute': 0b1000
        }
Exemple #8
0
def test_byteswap_adapter():
    adapter = U16ByteSwapAdapter()
    assert adapter._encode(0xFF00) == 0x00FF
    assert adapter._decode(0x00FF) == 0xFF00
Exemple #9
0
    def __init__(self, i2c_dev=None):
        """Initialise the TCS3472."""

        self._max_count = 0
        self._integration_time_ms = 0
        self._rgbc_tuple = namedtuple('Colour', (
            'time',
            'red',
            'green',
            'blue',
            'raw_red',
            'raw_green',
            'raw_blue',
            'raw_clear'
        ))

        self._tcs3472 = Device(I2C_ADDR, i2c_dev=i2c_dev, bit_width=8, registers=(
            Register('ENABLE', I2C_COMMAND | 0x00, fields=(
                BitField('power_on', 0b00000001),
                BitField('enable', 0b00000010),
                BitField('wait_enable', 0b00001000),
                BitField('int_enable', 0b00010000)
            )),
            # Actual integration time is (256 - INTEGRATION_TIME) * 2.4
            # Integration time affects the max ADC count, with the max count
            # being (256 - INTEGRATION_TIME) * 1024 up to a limit of 65535.
            # IE: An integration time of 0xF6 (24ms) would limit readings to 0-10240.
            Register('INTEGRATION_TIME', I2C_COMMAND | 0x01, fields=(
                BitField('time_ms', 0xff, adapter=IntegrationTimeAdapter()),  
            )),
            # Actual wait time is (256 - WAIT_TIME) * 2.4
            # if the WLONG bit is set, this value is multiplied by 12
            Register('WAIT_TIME', I2C_COMMAND | 0x03, fields=(
                BitField('time_ms', 0xff, adapter=WaitTimeAdapter()),
            )),
            Register('INTERRUPT_THRESHOLD', I2C_COMMAND | I2C_AUTOINC | 0x04, fields=(
                BitField('low', 0x0000ffff),
                BitField('high', 0xffff0000)
            ), bit_width=8 * 4),
            Register('PERSISTENCE', I2C_COMMAND | 0x0c, fields=(
                BitField('count', 0x0f, adapter=LookupAdapter({
                    0: 0b0000,
                    1: 0b0001,
                    2: 0b0010,
                    3: 0b0011,
                    5: 0b0100,
                    10: 0b0101,
                    15: 0b0110,
                    20: 0b0111,
                    25: 0b1000,
                    30: 0b1001,
                    35: 0b1010,
                    40: 0b1011,
                    45: 0b1100,
                    50: 0b1101,
                    55: 0b1110,
                    60: 0b1111
                })),
            )),
            # wlong multiplies the wait time by 12
            Register('CONFIGURATION', I2C_COMMAND | 0x0d, fields=(
                BitField('wlong', 0b00000010),    
            )),
            Register('CONTROL', I2C_COMMAND | 0x0f, fields=(
                BitField('gain', 0b00000011, adapter=LookupAdapter({
                    1: 0b00,
                    4: 0b01,
                    16: 0b10,
                    60: 0b11
                })),   
            )),
            # Should be either 0x44 (TCS34725) or 0x4D (TCS34727)
            Register('ID', I2C_COMMAND | 0x12, fields=(
                BitField('id', 0xff),    
            )),
            Register('STATUS', I2C_COMMAND | 0x13, fields=(
                BitField('aint', 0b00010000),
                BitField('avalid', 0b00000001)
            )),
            Register('RGBC', I2C_COMMAND | I2C_AUTOINC | 0x14, fields=(
                BitField('clear', 0xffff, adapter=U16ByteSwapAdapter()),
                BitField('red', 0xffff << 16, adapter=U16ByteSwapAdapter()),
                BitField('green', 0xffff << 32, adapter=U16ByteSwapAdapter()),
                BitField('blue', 0xffff << 48, adapter=U16ByteSwapAdapter())
            ), bit_width=8 * 8)
        ))

        chip = self._tcs3472.get('ID')

        if chip.id not in CHIP_ID:
            raise RuntimeError("TCS3472 not found! Chip ID {} not in {}".format(chip.id, CHIP_ID))

        # Enable the sensor and RGBC interface by default
        self._tcs3472.set('ENABLE', power_on=True, enable=True)

        # Aim for 100ms integration time, or 10 readings / second
        # This should give a saturation of ~41984 counts: (256 - 0xd7) * 1024
        # During testing it reached saturation at 41984
        self.set_integration_time_ms(100)