def __init__(self, i2c_addr=0x45, i2c_dev=None): self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._is_setup = False self.shunt_resistor_value = 0.005 # value in ohms self.shunt_voltage_lsb = 0.00001 # 10 uV per LSB self.bus_voltage_lsb = 0.004 # 4mV per LSB self._ina220 = Device([self._i2c_addr], i2c_dev=self._i2c_dev, bit_width=8, registers=( Register('CONFIG', 0x00, fields=( BitField('reset', 0b1000000000000000), BitField('bus_voltage_range', 0b0010000000000000), BitField('pga_gain', 0b0001100000000000, adapter=LookupAdapter({ '40': 0b00, '80': 0b01, '160': 0b10, '320': 0b11 }), bit_width=16), BitField('bus_adc', 0b0000011110000000, adapter=sadc_badc_adapter, bit_width=16), BitField('shunt_adc', 0b0000000001111000, adapter=sadc_badc_adapter, bit_width=16), BitField('mode', 0b0000000000000111, adapter=LookupAdapter({ 'power_down': 0b000, 'shunt_voltage_triggered': 0b001, 'bus_voltage_triggered': 0b010, 'shunt_and_bus_triggered': 0b011, 'adc_off': 0b100, 'shunt_voltage_continuous': 0b101, 'bus_voltage_continuous': 0b110, 'shunt_and_bus_continuous': 0b111 }), bit_width=16), )), Register('SHUNT_VOLTAGE', 0x01, fields=( BitField('reading', 0xFFFF), ), bit_width=16, read_only=True), Register('BUS_VOLTAGE', 0x02, fields=( BitField('reading', 0b1111111111111000), BitField('conversion_ready', 0b0000000000000010), BitField('math_overflow_flag', 0b0000000000000001) ), bit_width=16, read_only=True), Register('POWER', 0x03, fields=( BitField('reading', 0xFFFF), ), bit_width=16, read_only=True), Register('CURRENT', 0x04, fields=( BitField('reading', 0xFFFF), ), bit_width=16, read_only=True), Register('CALIBARTION', 0x05, fields=( BitField('reading', 0xFFFF), ), bit_width=16, read_only=True), )) self._configuration = self.get_configuration()
def test_lookup_adapter_snap(): adapter = LookupAdapter({0: 0, 1: 1}) assert adapter._encode(0) == 0 assert adapter._encode(1) == 1 assert adapter._encode(0.1) == 0 assert adapter._encode(0.9) == 1 adapter = LookupAdapter({0: 0, 1: 0}, snap=False) with pytest.raises(KeyError): adapter._encode(0.1)
def _decode(self, value): # Mask out the "don't care" bit for anything # that doesn't have the high bit set if value & 0b1000 == 0: value &= 0b0011 # Special case for 0b1000 = 12bit if value == 0b1000: value = 0b0011 return LookupAdapter._decode(self, value)
def test_lookup_adapter(): adapter = LookupAdapter({'Zero': 0, 'One': 1}) assert adapter._decode(0) == 'Zero' assert adapter._decode(1) == 'One' with pytest.raises(ValueError): adapter._decode(2) with pytest.raises(KeyError): adapter._encode('Two')
def test_field_name_in_adapter_error(): bus = MockSMBus(1) device = Device(0x00, i2c_dev=bus, registers=(Register('test', 0x00, fields=(BitField('test', 0xFF00, adapter=LookupAdapter( {'x': 1})), ), bit_width=16), )) with pytest.raises(ValueError) as e: reg = device.get('test') assert 'test' in e del reg
def __init__(self, i2c_addr=I2C_ADDR1, i2c_dev=None): self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._drv8830 = Device( [I2C_ADDR1, I2C_ADDR2, I2C_ADDR3, I2C_ADDR4], i2c_dev=self._i2c_dev, registers=( Register( 'CONTROL', 0x00, fields=( BitField('voltage', 0b11111100, adapter=VoltageAdapter()), # vset BitField('out2', 0b00000010), # in2 BitField('out1', 0b00000001), # in1 BitField( 'direction', 0b00000011, adapter=LookupAdapter({ # both in2 and in1 :D 'coast': 0b00, 'reverse': 0b01, 'forward': 0b10, 'brake': 0b11 })))), Register( 'FAULT', 0x01, fields=( BitField( 'clear', 0b10000000 ), # Clears fault status bits when written to 1 BitField('current_limit', 0b00010000 ), # Fault caused by external current limit BitField( 'over_temperature', 0b00001000 ), # Fault caused by over-temperature condition BitField('under_voltage', 0b00000100 ), # Fault caused by undervoltage lockout BitField( 'over_current', 0b00000010), # Fault caused by overcurrent event BitField('fault', 0b00000001) # Fault condition exists )))) self._drv8830.select_address(self._i2c_addr)
def __init__(self, i2c_addr=DRV2605_ADDR, i2c_dev=None): self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._drv2605 = Device( DRV2605_ADDR, i2c_dev=self._i2c_dev, registers=( Register('STATUS', 0x00, fields=( BitField('device_id', 0b11100000), BitField('diagnostic', 0b00001000), BitField('over_temp', 0b00000010), BitField('over_current', 0b00000001), )), Register( 'MODE', 0x01, fields=( BitField('reset', 0b10000000), BitField('standby', 0b01000000), BitField( 'mode', 0b00000111, adapter=LookupAdapter({ 'Internal Trigger': 0, # Waveforms are fired by setting the GO bit in register 0x0C 'Edge Trigger': 1, # A rising edge on INT/TRIG sets the GO bit, a second rising edge cancels the waveform 'Level Trigger': 2, # A rising edge on INT/TRIG sets the GO bit, a falling edge cancels the waveform 'PWM/Analog In': 3, # A PWM or Analog signal is accepted on INT/TRIG and used as a direct driving source 'Audio In': 4, # An AC-coupled audio signal is accepted on INT/TRIG and turned into meaningful vibration # (AC_COUPLE and N_PWM_ANALOG should also be set) 'Real-time Playback': 5, # The contents of the REALTIME_PLAYBACK register are used as a waveform 'Diagnostics': 6, # Perform a diagnostic test on the actuator- triggered by setting the GO bit 'Auto Calibration': 7 # Perform an auto-calibration- triggered by setting the GO bit })), )), Register('REALTIME_PLAYBACK', 0x02, fields=(BitField('input', 0xFF), )), Register( 'LIBRARY_SELECTION', 0x03, fields=( BitField('high_impedance', 0b00010000), BitField( 'library', 0b00000111, adapter=LookupAdapter({ 'Empty': 0, 'TS2200 A': 1, # Rated 1.3v, Overdrive 3v, 40ms to 60ms rise, 20ms to 40ms brake 'TS2200 B': 2, # Rated 3v, Overdrive 3v, 40ms to 60ms rise, 5ms to 15ms brake 'TS2200 C': 3, # Rated 3v, Overdrive 3v, 60ms to 80ms rise, 10ms to 20ms brake 'TS2200 D': 4, # Rated 3v, Overdrive 3v, 100ms to 140ms rise, 15ms to 25ms brake 'TS2200 E': 5, # Rated 3v, Overdrive 3v, > 140ms rise, > 30ms brake 'LRA': 6, # Linear Resonance 'TS2200 F': 7 # Rated 4.5v, Overdrive 5v, 35ms to 45ms rise, 10ms to 20ms brake })), )), # When the wait bit is set, the value of its corresponding # waveform becomes a timed delay. # Delay time = 10 ms x waveformN Register('WAVEFORM_SEQUENCER', 0x04, fields=( BitField('step1_wait', 0xFF << 56, adapter=WaitTimeAdapter()), BitField('step1_waveform', 0xFF << 56), BitField('step2_wait', 0xFF << 48, adapter=WaitTimeAdapter()), BitField('step2_waveform', 0xFF << 48), BitField('step3_wait', 0xFF << 40, adapter=WaitTimeAdapter()), BitField('step3_waveform', 0xFF << 40), BitField('step4_wait', 0xFF << 32, adapter=WaitTimeAdapter()), BitField('step4_waveform', 0xFF << 32), BitField('step5_wait', 0xFF << 24, adapter=WaitTimeAdapter()), BitField('step5_waveform', 0xFF << 24), BitField('step6_wait', 0xFF << 16, adapter=WaitTimeAdapter()), BitField('step6_waveform', 0xFF << 16), BitField('step7_wait', 0xFF << 8, adapter=WaitTimeAdapter()), BitField('step7_waveform', 0xFF << 8), BitField('step8_wait', 0xFF << 0, adapter=WaitTimeAdapter()), BitField('step8_waveform', 0xFF << 0), ), bit_width=8 * 8), Register('GO', 0x0C, fields=(BitField('go', 0b00000001), )), Register('TIME_OFFSET', 0x0D, fields=(BitField('overdrive', 0xFF000000), BitField('positive_sustain', 0x00FF0000), BitField('negative_sustain', 0x0000FF00), BitField('brake', 0x000000FF)), bit_width=8 * 4), Register('AUDIO_CONTROL', 0x11, fields=(BitField('peak_detection_time_ms', 0b00001100, adapter=LookupAdapter({ 10: 0, 20: 1, 30: 2, 40: 3 })), BitField('low_pass_filter_hz', 0b00000011, adapter=LookupAdapter({ 100: 0, 125: 1, 150: 2, 200: 3 })))), Register( 'AUDIO_INPUT_LEVEL', 0x12, fields=( BitField( 'minimum', 0xFF00 ), # input level v = (minimum * 1.8) / 255 TODO create an adapter BitField( 'maximum', 0x00FF ) # input level v = (maximum * 1.8) / 255 TODO create an adapter ), bit_width=8 * 2), Register( 'AUDIO_OUTPUT_DRIVE', 0x14, fields=( BitField( 'minimum', 0xFF00 ), # max drive % = (maximum / 255) x 100 TODO create an adapter BitField( 'maximum', 0x00FF ) # max drive % = (maximum / 255) x 100 TODO create an adapter ), bit_width=8 * 2), Register('VOLTAGE', 0x16, fields=(BitField('rated', 0xFF00), BitField('overdrive_clamp', 0x00FF)), bit_width=8 * 2), Register( 'AUTO_CALIBRATION_RESULT', 0x18, fields=( BitField('compensation', 0xFF00), # coef = 1 + compensation / 255 BitField( 'back_emf', 0x00FF ), # back-emf v = back_emf / 255 * 1.22 / back_emf_gain ), bit_width=8 * 2), Register( 'FEEDBACK_CONTROL', 0x1A, fields=( BitField('mode', 0b10000000, adapter=LookupAdapter({ 'ERM': 0, 'LRA': 1 })), BitField('feedback_brake_factor', 0b01110000, adapter=LookupAdapter({ 1: 0, 2: 1, 3: 2, 4: 3, 6: 4, 8: 5, 16: 6, 0: 7 })), BitField('loop_gain', 0b00001100, adapter=LookupAdapter({ 'low': 0, 'medium': 1, 'high': 2, 'very high': 3 })), BitField( 'back_emf_gain', 0b00000011, adapter=LookupAdapter({ 0.255: 0, # ERM mode 0.7875: 1, 1.365: 2, 3.0: 3, 3.75: 0, # LRA mode 7.5: 1, 15.0: 2, 22.5: 3 })))), Register('CONTROL1', 0x1B, fields=(BitField('startup_boost', 0b10000000), BitField('ac_couple', 0b00100000), BitField('drive_time', 0b00011111))), Register('CONTROL2', 0x1C, fields=(BitField('bidir_input', 0b10000000), BitField('brake_stabalize', 0b01000000), BitField('sample_time', 0b00110000), BitField('blanking_time', 0b00001100), BitField('idiss_time', 0b00000011))), Register('CONTROL3', 0x1D, fields=(BitField('noise_gate_threshold', 0b11000000, adapter=LookupAdapter({ 'Disabled': 0, '2%': 1, '4%': 2, '8%': 3 })), BitField('erm_open_loop', 0b00100000, adapter=LookupAdapter({ 'Closed Loop': 0, 'Open Loop': 1 })), BitField('supply_compensation_disable', 0b00010000, adapter=LookupAdapter({ 'Enabled': 0, 'Disabled': 1 })), BitField('data_format_rtp', 0b00001000, adapter=LookupAdapter({ 'Signed': 0, 'Unsigned': 1 })), BitField('lra_drive_mode', 0b00000100, adapter=LookupAdapter({ 'Once': 0, 'Twice': 1 })), BitField('pwm_input_mode', 0b00000010, adapter=LookupAdapter({ 'PWM': 0, 'Analog': 1 })), BitField('lra_open_loop', 0b00000001, adapter=LookupAdapter({ 'Auto-resonance': 0, 'Open Loop': 1 })))), Register( 'CONTROL4', 0x1E, fields=( BitField('zero_crossing_detection_time', 0b11000000, adapter=LookupAdapter({ 100: 0, 200: 1, 300: 2, 390: 3 })), BitField( 'auto_calibration_time', 0b00110000, adapter=LookupAdapter({ 150: 0, # 150ms to 350ms 250: 1, # 250ms to 450ms 500: 2, # 500ms to 700ms 1000: 3 # 1000ms to 1200ms })), # BitField('otp_status', 0b00000100), # BitField('otp_program', 0b0000001) )), Register('CONTROL5', 0x1F, fields=(BitField('auto_open_loop_attempts', 0b11000000, adapter=LookupAdapter({ 3: 0, 4: 1, 5: 2, 6: 3 })), BitField('auto_open_loop_transition', 0b00100000), BitField('playback_interval_ms', 0b00010000, adapter=LookupAdapter({ 5: 0, 1: 1 })), BitField('blanking_time', 0b00001100), BitField('idiss_time', 0b00000011))), Register( 'LRA_OPEN_LOOP_PERIOD', 0x20, fields=( BitField('period', 0x7F), # period (us) = period * 98.46 )), Register('VOLTAGE', 0x21, fields=(BitField('vbat', 0xFF), )), Register( 'LRA_RESONANCE', 0x22, fields=( BitField('period', 0xFF), # period (us) = period * 98.46 ))))
def __init__(self, i2c_addr=I2C_ADDRESS_GND, i2c_dev=None): self.calibration = BME280Calibration() self._is_setup = False self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._bme280 = Device( [I2C_ADDRESS_GND, I2C_ADDRESS_VCC], i2c_dev=self._i2c_dev, bit_width=8, registers=( Register('CHIP_ID', 0xD0, fields=(BitField('id', 0xFF), )), Register('RESET', 0xE0, fields=(BitField('reset', 0xFF), )), Register( 'STATUS', 0xF3, fields=( BitField('measuring', 0b00001000), # 1 when conversion is running BitField( 'im_update', 0b00000001), # 1 when NVM data is being copied )), Register( 'CTRL_MEAS', 0xF4, fields=( BitField( 'osrs_t', 0b11100000, # Temperature oversampling adapter=LookupAdapter({ 1: 0b001, 2: 0b010, 4: 0b011, 8: 0b100, 16: 0b101 })), BitField( 'osrs_p', 0b00011100, # Pressure oversampling adapter=LookupAdapter({ 1: 0b001, 2: 0b010, 4: 0b011, 8: 0b100, 16: 0b101 })), BitField( 'mode', 0b00000011, # Power mode adapter=LookupAdapter({ 'sleep': 0b00, 'forced': 0b10, 'normal': 0b11 })), )), Register( 'CTRL_HUM', 0xF2, fields=( BitField( 'osrs_h', 0b00000111, # Humidity oversampling adapter=LookupAdapter({ 1: 0b001, 2: 0b010, 4: 0b011, 8: 0b100, 16: 0b101 })), )), Register( 'CONFIG', 0xF5, fields=( BitField( 't_sb', 0b11100000, # Temp standby duration in normal mode adapter=LookupAdapter({ 0.5: 0b000, 62.5: 0b001, 125: 0b010, 250: 0b011, 500: 0b100, 1000: 0b101, 10: 0b110, 20: 0b111 })), BitField( 'filter', 0b00011100 ), # Controls the time constant of the IIR filter BitField( 'spi3w_en', 0b0000001, read_only=True ), # Enable 3-wire SPI interface when set to 1. IE: Don't set this bit! )), Register('DATA', 0xF7, fields=(BitField('humidity', 0x000000000000FFFF), BitField('temperature', 0x000000FFFFF00000), BitField('pressure', 0xFFFFF00000000000)), bit_width=8 * 8), Register( 'CALIBRATION', 0x88, fields=( BitField('dig_t1', 0xFFFF << 16 * 12, adapter=U16Adapter()), # 0x88 0x89 BitField('dig_t2', 0xFFFF << 16 * 11, adapter=S16Adapter()), # 0x8A 0x8B BitField('dig_t3', 0xFFFF << 16 * 10, adapter=S16Adapter()), # 0x8C 0x8D BitField('dig_p1', 0xFFFF << 16 * 9, adapter=U16Adapter()), # 0x8E 0x8F BitField('dig_p2', 0xFFFF << 16 * 8, adapter=S16Adapter()), # 0x90 0x91 BitField('dig_p3', 0xFFFF << 16 * 7, adapter=S16Adapter()), # 0x92 0x93 BitField('dig_p4', 0xFFFF << 16 * 6, adapter=S16Adapter()), # 0x94 0x95 BitField('dig_p5', 0xFFFF << 16 * 5, adapter=S16Adapter()), # 0x96 0x97 BitField('dig_p6', 0xFFFF << 16 * 4, adapter=S16Adapter()), # 0x98 0x99 BitField('dig_p7', 0xFFFF << 16 * 3, adapter=S16Adapter()), # 0x9A 0x9B BitField('dig_p8', 0xFFFF << 16 * 2, adapter=S16Adapter()), # 0x9C 0x9D BitField('dig_p9', 0xFFFF << 16 * 1, adapter=S16Adapter()), # 0x9E 0x9F BitField('dig_h1', 0x00FF), # 0xA1 uint8 ), bit_width=26 * 8), Register( 'CALIBRATION2', 0xE1, fields=( BitField('dig_h2', 0xFFFF0000000000, adapter=S16Adapter()), # 0xE1 0xE2 BitField('dig_h3', 0x0000FF00000000), # 0xE3 uint8 BitField('dig_h4', 0x000000FFFF0000, adapter=H4Adapter()), # 0xE4 0xE5[3:0] BitField('dig_h5', 0x00000000FFFF00, adapter=H5Adapter()), # 0xE5[7:4] 0xE6 BitField('dig_h6', 0x000000000000FF, adapter=S8Adapter()) # 0xE7 int8 ), bit_width=7 * 8)))
def __init__(self, i2c_addr=0x73, i2c_dev=None): self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._is_setup = False # Device definition self._apds9500 = Device( [0x73], i2c_dev=self._i2c_dev, bit_width=8, bank_select=Register('BANK_SELECT', 0xEF), registers=( Register('BANK_SELECT', 0xEF, fields=(BitField('bank', 0b00000001), )), # BANK 0 Registers Register('ID', 0x00, bank=0, fields=(BitField('part', 0xFFFF00), BitField('version', 0x0000FF)), bit_width=8 * 3), Register('SUSPEND', 0x03, bank=0), # CURSOR MODES Register('CURSOR_MODE', 0x32, bank=0, fields=(BitField('mode', 0xFF, adapter=InterruptLookupAdapter({ 'cursor_use_top': 0b00000001, 'cursor_use_bg_model': 0b00000010, 'cursor_invert_y': 0b00000100, 'cursor_invert_x': 0b00001000, 'cursor_top_ratio': 0b00110000 })), )), Register('POS_FILTER_START_SIZE_LSB', 0x33, bank=0), Register('POS_FILTER_START_SIZE_MSB', 0x34, bank=0), Register('PRO_FILTER_START_SIZE_LSB', 0x35, bank=0), Register('PRO_FILTER_START_SIZE_MSB', 0x36, bank=0), Register('CURSOR_CLAMP_LEFT', 0x37, bank=0), Register('CURSOR_CLAMP_RIGHT', 0x38, bank=0), Register('CURSOR_CLAMP_UP', 0x39, bank=0), Register('CURSOR_CLAMP_DOWN', 0x3A, bank=0), Register('CURSOR_CLAMP_CENTER_X_LSB', 0x3B, bank=0), Register('CURSOR_CLAMP_CENTER_X_MSB', 0x3C, bank=0), Register('CURSOR_CLAMP_CENTER_Y_LSB', 0x3D, bank=0), Register('CURSOR_CLAMP_CENTER_Y_MSB', 0x3E, bank=0), Register('CURSOR_OBJECT_SIZE', 0x8B, bank=0), Register('CURSOR_POSITION_RESOLUTION', 0x8C, bank=0), # Proximity Mode Register('PROX_UPPER_BOUND', 0x69, bank=0), Register('PROX_LOWER_BOUND', 0x6A, bank=0), Register('PROX_S_STATE', 0x6B, bank=0), Register('PROX_AGV_Y', 0x6C, bank=0), # Automatic Gain and Exposure Controls BANK 0 Register('AE_LED_OFF_UB', 0x46, bank=0), Register('AE_LED_OFF_LB', 0x47, bank=0), Register('AE_EXPOSURE_UB_LSB', 0x48, bank=0), Register('AE_EXPOSURE_UB_MSB', 0x49, bank=0), Register('AE_EXPOSURE_LB_LSB', 0x4A, bank=0), Register('AE_EXPOSURE_LB_MSB', 0x4B, bank=0), Register('AG_GAIN_UB', 0x4C, bank=0), Register('AG_GAIN_LB', 0x4D, bank=0), Register('AG_GAIN_CONTROL', 0x4E, bank=0, fields=( BitField('step', 0x0F), BitField('wakeup_ae_mode', 0x10), )), Register('AG_GAIN_DEFAULT', 0x4F, bank=0), Register('AE_EXPOSURE_SELECT', 0x50, bank=0), Register('AEAG_MODE', 0x51, bank=0, fields=( BitField('manual_global_gain', 0b00000001), BitField('manual_exposure', 0b00000010), BitField('maunal_exposure_default', 0b00000100), BitField('auto_exposure_enable', 0b00001000), )), Register('AG_GAIN_ANALOGUE', 0x54, bank=0, read_only=True), Register('AE_EXPOSURE_TIME_LSB', 0x55, bank=0, read_only=True), Register('AE_EXPOSURE_TIME_MSB', 0x56, bank=0, read_only=True), Register('AG_GLOBAL_GAIN', 0x57, bank=0, fields=( BitField('ggn', 0b00000011, read_only=True), BitField('global_gain', 0b11110000, read_only=True), )), Register('LED_OFF_FRAME_AVERAGE_BRIGHTNESS', 0x58, bank=0, read_only=True), Register('AE_DIRECTION', 0x59, bank=0, fields=( BitField('decrease', 0b00000001), BitField('increase', 0b00000010), )), # Automatic Gain and Exposure Controls BANK 1 Register('PGA_GAIN_GLOBAL', 0x42, bank=1, read_only=True), Register('PGA_GAIN_GGH', 0x44, bank=1, read_only=True), # Interupt Controls BANK0 Register('INTERUPT_MODE', 0x40, bank=0, fields=( BitField('auto_clear', 0b00000001), BitField('active_high', 0b00010000), )), Register('INT_ENABLE_1', 0x41, bank=0, fields=(BitField('mode', 0xFF, adapter=InterruptLookupAdapter({ 'event_up': 0b00000001, 'event_down': 0b00000010, 'event_left': 0b00000100, 'event_right': 0b00001000, 'event_forward': 0b00010000, 'event_backward': 0b00100000, 'event_clockwise': 0b01000000, 'event_counterclockwise': 0b10000000 })), )), Register('INT_ENABLE_2', 0x42, bank=0, fields=(BitField('mode', 0xFF, adapter=InterruptLookupAdapter({ 'event_wave': 0b00000001, 'event_proximity': 0b00000010, 'event_has_object': 0b00000100, 'event_wake_up': 0b00001000, 'no_object': 0b10000000 })), )), Register('INT_FLAG_1', 0x43, bank=0, fields=(BitField('mode', 0xFF, read_only=True, adapter=InterruptLookupAdapter({ 'event_up': 0b00000001, 'event_down': 0b00000010, 'event_left': 0b00000100, 'event_right': 0b00001000, 'event_forward': 0b00010000, 'event_backward': 0b00100000, 'event_clockwise': 0b01000000, 'event_counterclockwise': 0b10000000 })), )), Register('INT_FLAG_2', 0x44, bank=0, fields=(BitField('mode', 0xFF, read_only=True, adapter=InterruptLookupAdapter({ 'event_wave': 0b00000001, 'event_proximity': 0b00000010, 'event_has_object': 0b00000100, 'event_wake_up': 0b00001000, 'no_object': 0b10000000 })), )), # Gesture Bank 0 Register('GESTURE_LIGHT_THREASHOLD', 0x83, bank=0), Register('GESTURE_START_THREASHOLD_LSB', 0x84, bank=0), Register('GESTURE_START_THREASHOLD_MSB', 0x85, bank=0), Register('GESTURE_END_THREASHOLD_LSB', 0x86, bank=0), Register('GESTURE_END_THREASHOLD_MSB', 0x87, bank=0), Register('GESTURE_OBJECT_Z_MIN', 0x88, bank=0), Register('GESTURE_OBJECT_Z_MAX', 0x89, bank=0), Register('GESTURE_PROCESS_RESOLUTION', 0x8C, bank=0), Register('GESTURE_DETECTION_DELAY', 0x8D, bank=0), Register('GESTURE_45_DEGREE_DETECTION', 0x8E, bank=0, fields=( BitField('disable', 0b00000001), BitField('ratio', 0xF0), )), Register('GESTURE_X_to_Y_GAIN', 0x8F, bank=0, fields=( BitField('enable', 0b00000001), BitField('ratio', 0xF0), )), Register('GESTURE_NO_MOTION_COUNTER_THRS', 0x90, bank=0), Register('GESTURE_NO_OBJECT_COUNTER_THRS', 0x91, bank=0), Register('GESTURE_NORMALIZED_IMAGE_WIDTH', 0x92, bank=0), Register('GESTURE_DETECTION_HORIZONTAL_THRS', 0x93, bank=0), Register('GESTURE_DETECTION_VERTICAL_THRS', 0x94, bank=0), Register('GESTURE_DETECTION_Z_THRS', 0x95, bank=0), Register('GESTURE_DETECTION_XY_THRS', 0x96, bank=0), Register('GESTURE_DETECTION_Z_ANGLE__THRS', 0x97, bank=0), Register('GESTURE_ROTATE_ANGLE_THRS', 0x98, bank=0), Register('GESTURE_CONTINUOUS_ROTATION', 0x99, bank=0, fields=( BitField('enable', 0b00000001), BitField('threshold', 0b00111110), )), Register('GESTURE_ROTATE_XY_THRS', 0x9A, bank=0), Register('GESTURE_ROTATE_Z_THRS', 0x9B, bank=0), Register('GESTURE_IIR_FILTER', 0x9C, bank=0, fields=( BitField('weight', 0b00000011), BitField('distance_threshold', 0b01111100), )), Register('GESTURE_IIR_FILTER_DISTANCE', 0x9D, bank=0, fields=( BitField('start_distance_threashold', 0b00001111), BitField('end_distance_threshold', 0b01110000), )), Register('GESTURE_DETECTION_ENABLE', 0x9D, bank=0, fields=( BitField('rotate_enable', 0b00010000), BitField('z_enable', 0b00100000), BitField('y_enable', 0b01000000), BitField('x_enable', 0b10000000), )), Register('GESTURE_FILTER_IMAGE', 0xA5, bank=0, fields=( BitField('average_mode_enable', 0b00000001), BitField('average_mode', 0b00001100), BitField('use_light_weight', 0b00010000), )), Register('GESTURE_FRAME_EDGE_ACC_THRS', 0xA9, bank=0), Register('GESTURE_OBJECT_CENTER_X_LSB', 0xAC, bank=0, read_only=True), Register('GESTURE_OBJECT_CENTER_X_MSB', 0xAD, bank=0, read_only=True), Register('GESTURE_OBJECT_CENTER_Y_LSB', 0xAE, bank=0, read_only=True), Register('GESTURE_OBJECT_CENTER_Y_MSB', 0xAF, bank=0, read_only=True), Register('GESTURE_OBJECT_BRIGHTNESS', 0xB0, bank=0, read_only=True), Register('GESTURE_OBJECT_SIZE_LSB', 0xB1, bank=0, read_only=True), Register('GESTURE_OBJECT_SIZE_MSB', 0xB2, bank=0, read_only=True), Register('GESTURE_MOVEMENT_X', 0xB3, bank=0, read_only=True), Register('GESTURE_MOVEMENT_Y', 0xB4, bank=0, read_only=True), Register('GESTURE_MOVEMENT_Z', 0xB5, bank=0, read_only=True), Register('GESTURE_RESULT', 0xB6, bank=0, fields=( BitField('result', 0x0F, read_only=True, adapter=InterruptLookupAdapter({ 'up': 1, 'down': 2, 'left': 3, 'right': 4, 'forward': 5, 'backward': 6, 'clockwise': 7, 'counterclockwise': 8, 'wave': 9, 'n/a': 10 })), BitField('state', 0x30, read_only=True, adapter=InterruptLookupAdapter({ 'inital': 0, 'process': 1, 'end': 2, })), )), Register('GESTURE_WAVE_ABORT_COUNTERS', 0xB7, bank=0, fields=( BitField('wave', 0x0F, read_only=True), BitField('abort', 0x70, read_only=True), )), Register('GESTURE_NO_OBJECT_COUNTER', 0xB8, bank=0, read_only=True), Register('GESTURE_NO_MOTION_COUNTER', 0xB9, bank=0, read_only=True), Register('GESTURE_BRIGHT_OBJECT_COUNTER', 0xBA, bank=0, read_only=True), Register('GESTURE_OBJECT_BIRGHTNESS_ACC_LSB', 0xBB, bank=0, read_only=True), Register('GESTURE_OBJECT_BIRGHTNESS_ACC_MSB', 0xBC, bank=0, read_only=True), Register('GESTURE_TIME_PERIOD_LSB', 0xBD, bank=0, read_only=True), Register('GESTURE_TIME_PERIOD_MSB', 0xBE, bank=0, read_only=True), Register('GESTURE_ANGLE_ACC_LSB', 0xC7, bank=0, read_only=True), Register('GESTURE_ANGLE_ACC_MSB', 0xC8, bank=0, read_only=True), Register('GESTURE_GAIN_VALUE_X', 0xCA, bank=0, read_only=True), Register('GESTURE_GAIN_VALUE_Y', 0xCB, bank=0, read_only=True), Register('GESTURE_Y_TO_Z_SUM', 0xCC, bank=0), Register('GESTURE_Y_TO_Z_FACTOR', 0xCD, bank=0), Register('GESTURE_IIR_FILTER_LENGTH', 0xCE, bank=0, fields=( BitField('cursor_object', 0b00000111), BitField('gesture_object', 0b01110000), )), Register('GESTURE_WAVE_THRES', 0xCF, bank=0, fields=( BitField('count_thres', 0b00001111), BitField('angle_thres', 0b11110000), )), Register('GESTURE_ABORT_THRES', 0xD0, bank=0, fields=( BitField('count_thres', 0b00000111), BitField('angle_thres', 0b11111000), )), Register('GESTURE_ABORT_LENGTH', 0xD1, bank=0), Register( 'GESTURE_ABORT_MODE', 0xD2, bank=0, fields=( BitField('interval', 0b00111111), BitField('confirm_mode', 0b01000000), BitField('wave_detection_enable', 0b10000000), # enabling wave detection mode )), Register('GESTURE_TIME_PERIOD_LSB', 0xD3, bank=0, read_only=True), Register('GESTURE_TIME_PERIOD_MSB', 0xD4, bank=0, read_only=True), Register('GESTURE_ANGLE_ACC_LSB', 0xC7, bank=0, read_only=True), Register('GESTURE_ANGLE_ACC_MSB', 0xC8, bank=0, read_only=True), # Gesture Bank 1 # Image Regs BANK 0 Register('IMAGE_HEIGHT', 0xAA, bank=0), Register('IMAGE_WIDTH', 0xAB, bank=0), # Image Regs BANK 1 Register('IMAGE_H_SCALE', 0x00, bank=1), Register('IMAGE_V_SCALE', 0x01, bank=1), Register('IMAGE_H_START', 0x02, bank=1), Register('IMAGE_V_START', 0x03, bank=1), Register('IMAGE_TRANSLATION', 0x09, bank=1, fields=(BitField('translations', 0xFF, adapter=LookupAdapter({ 'a_skip_v': 0b00100000, 'a_skip_h': 0b00010000, 'd_avg_v': 0b0001000, 'v_flip': 0b00000010, 'h_flip': 0b00000001 })), )), ))
def __init__(self, i2c_addr=I2C_ADDRESS_DEFAULT, i2c_dev=None): self._is_setup = False self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._mcp9600 = Device(I2C_ADDRESSES, i2c_dev=self._i2c_dev, bit_width=8, registers=( Register('HOT_JUNCTION', 0x00, fields=( BitField('temperature', 0xFFFF, adapter=TemperatureAdapter()), ), bit_width=16), Register('DELTA', 0x01, fields=( BitField('value', 0xFFFF, adapter=TemperatureAdapter()), ), bit_width=16), Register('COLD_JUNCTION', 0x02, fields=( BitField('temperature', 0x1FFF, adapter=TemperatureAdapter()), ), bit_width=16), Register('RAW_DATA', 0x03, fields=( BitField('adc', 0xFFFFFF), ), bit_width=24), Register('STATUS', 0x04, fields=( BitField('burst_complete', 0b10000000), BitField('updated', 0b01000000), BitField('input_range', 0b00010000), BitField('alert_4', 0b00001000), BitField('alert_3', 0b00000100), BitField('alert_2', 0b00000010), BitField('alert_1', 0b00000001) )), Register('THERMOCOUPLE_CONFIG', 0x05, fields=( BitField('type_select', 0b01110000, adapter=LookupAdapter({ 'K': 0b000, 'J': 0b001, 'T': 0b010, 'N': 0b011, 'S': 0b100, 'E': 0b101, 'B': 0b110, 'R': 0b111 })), BitField('filter_coefficients', 0b00000111) )), Register('DEVICE_CONFIG', 0x06, fields=( BitField('cold_junction_resolution', 0b10000000, adapter=LookupAdapter({ 0.0625: 0b0, 0.25: 0b1 })), BitField('adc_resolution', 0b01100000, adapter=LookupAdapter({ 18: 0b00, 16: 0b01, 14: 0b10, 12: 0b11 })), BitField('burst_mode_samples', 0b00011100, adapter=LookupAdapter({ 1: 0b000, 2: 0b001, 4: 0b010, 8: 0b011, 16: 0b100, 32: 0b101, 64: 0b110, 128: 0b111 })), BitField('shutdown_modes', 0b00000011, adapter=LookupAdapter({ 'Normal': 0b00, 'Shutdown': 0b01, 'Burst': 0b10 })) )), Register('ALERT1_CONFIG', 0x08, fields=( BitField('clear_interrupt', 0b10000000), BitField('monitor_junction', 0b00010000), # 1 Cold Junction, 0 Thermocouple BitField('rise_fall', 0b00001000), # 1 rising, 0 cooling BitField('state', 0b00000100), # 1 active high, 0 active low BitField('mode', 0b00000010), # 1 interrupt mode, 0 comparator mode BitField('enable', 0b00000001) # 1 enable, 0 disable )), Register('ALERT2_CONFIG', 0x09, fields=( BitField('clear_interrupt', 0b10000000), BitField('monitor_junction', 0b00010000), # 1 Cold Junction, 0 Thermocouple BitField('rise_fall', 0b00001000), # 1 rising, 0 cooling BitField('state', 0b00000100), # 1 active high, 0 active low BitField('mode', 0b00000010), # 1 interrupt mode, 0 comparator mode BitField('enable', 0b00000001) # 1 enable, 0 disable )), Register('ALERT3_CONFIG', 0x0A, fields=( BitField('clear_interrupt', 0b10000000), BitField('monitor_junction', 0b00010000), # 1 Cold Junction, 0 Thermocouple BitField('rise_fall', 0b00001000), # 1 rising, 0 cooling BitField('state', 0b00000100), # 1 active high, 0 active low BitField('mode', 0b00000010), # 1 interrupt mode, 0 comparator mode BitField('enable', 0b00000001) # 1 enable, 0 disable )), Register('ALERT4_CONFIG', 0x0B, fields=( BitField('clear_interrupt', 0b10000000), BitField('monitor_junction', 0b00010000), # 1 Cold Junction, 0 Thermocouple BitField('rise_fall', 0b00001000), # 1 rising, 0 cooling BitField('state', 0b00000100), # 1 active high, 0 active low BitField('mode', 0b00000010), # 1 interrupt mode, 0 comparator mode BitField('enable', 0b00000001) # 1 enable, 0 disable )), Register('ALERT1_HYSTERESIS', 0x0C, fields=( BitField('value', 0xFF), )), Register('ALERT2_HYSTERESIS', 0x0D, fields=( BitField('value', 0xFF), )), Register('ALERT3_HYSTERESIS', 0x0E, fields=( BitField('value', 0xFF), )), Register('ALERT4_HYSTERESIS', 0x0F, fields=( BitField('value', 0xFF), )), Register('ALERT1_LIMIT', 0x10, fields=( BitField('value', 0xFFFF, adapter=AlertLimitAdapter()), ), bit_width=16), Register('ALERT2_LIMIT', 0x11, fields=( BitField('value', 0xFFFF, adapter=AlertLimitAdapter()), ), bit_width=16), Register('ALERT3_LIMIT', 0x12, fields=( BitField('value', 0xFFFF, adapter=AlertLimitAdapter()), ), bit_width=16), Register('ALERT4_LIMIT', 0x13, fields=( BitField('value', 0xFFFF, adapter=AlertLimitAdapter()), ), bit_width=16), Register('CHIP_ID', 0x20, fields=( BitField('id', 0xFF00), BitField('revision', 0x00FF, adapter=RevisionAdapter()) ), bit_width=16) )) self.alert_registers = [ 'ALERT1_CONFIG', 'ALERT2_CONFIG', 'ALERT3_CONFIG', 'ALERT4_CONFIG' ] self.alert_limits = [ 'ALERT1_LIMIT', 'ALERT2_LIMIT', 'ALERT3_LIMIT', 'ALERT4_LIMIT' ] self.alert_hysteresis = [ 'ALERT1_HYSTERESIS', 'ALERT2_HYSTERESIS', 'ALERT3_HYSTERESIS', 'ALERT4_HYSTERESIS' ] self._mcp9600.select_address(self._i2c_addr) try: chip = self._mcp9600.get('CHIP_ID') if chip.id != CHIP_ID: raise RuntimeError("Unable to find mcp9600 on 0x{:02x}, CHIP_ID returned {:02x}".format(self._i2c_addr, chip.id)) except IOError: raise RuntimeError("Unable to find mcp9600 on 0x{:02x}, IOError".format(self._i2c_addr))
return ((value & 0xFF)) << 8 | ((value & 0xF00) >> 8) def _decode(self, value): """ Convert the 12-bit input into the correct format for the registers, the low byte followed by 4 empty bits and the high nibble: 0bHHHHLLLLLLLL -> 0bLLLLLLLLXXXXHHHH """ return ((value & 0xFF00) >> 8) | ((value & 0x000F) << 8) ltr559 = Device(I2C_ADDR, bit_width=8, registers=( Register('ALS_CONTROL', 0x80, fields=( BitField('gain', 0b00011100, adapter=LookupAdapter({1: 0b000, 2: 0b001, 4: 0b011, 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})) )),
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)
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
def __init__(self, i2c_dev=None): self._as7262 = Device( 0x49, i2c_dev=as7262VirtualRegisterBus(i2c_dev=i2c_dev), bit_width=8, registers=( Register('VERSION', 0x00, fields=( BitField('hw_type', 0xFF000000), BitField('hw_version', 0x00FF0000), BitField('fw_version', 0x0000FFFF, adapter=FWVersionAdapter()), ), bit_width=32, read_only=True), Register('CONTROL', 0x04, fields=( BitField('reset', 0b10000000), BitField('interrupt', 0b01000000), BitField('gain_x', 0b00110000, adapter=LookupAdapter({ 1: 0b00, 3.7: 0b01, 16: 0b10, 64: 0b11 })), BitField('measurement_mode', 0b00001100), BitField('data_ready', 0b00000010), )), Register('INTEGRATION_TIME', 0x05, fields=(BitField( 'ms', 0xFF, adapter=IntegrationTimeAdapter()), )), Register('TEMPERATURE', 0x06, fields=(BitField('degrees_c', 0xFF), )), Register('LED_CONTROL', 0x07, fields=( BitField('illumination_current_limit_ma', 0b00110000, adapter=LookupAdapter({ 12.5: 0b00, 25: 0b01, 50: 0b10, 100: 0b11 })), BitField('illumination_enable', 0b00001000), BitField('indicator_current_limit_ma', 0b00000110, adapter=LookupAdapter({ 1: 0b00, 2: 0b01, 4: 0b10, 8: 0b11 })), BitField('indicator_enable', 0b00000001), )), Register('DATA', 0x08, fields=( BitField('v', 0xFFFF00000000000000000000), BitField('b', 0x0000FFFF0000000000000000), BitField('g', 0x00000000FFFF000000000000), BitField('y', 0x000000000000FFFF00000000), BitField('o', 0x0000000000000000FFFF0000), BitField('r', 0x00000000000000000000FFFF), ), bit_width=96), Register('CALIBRATED_DATA', 0x14, fields=( BitField('v', 0xFFFFFFFF << (32 * 5), adapter=FloatAdapter()), BitField('b', 0xFFFFFFFF << (32 * 4), adapter=FloatAdapter()), BitField('g', 0xFFFFFFFF << (32 * 3), adapter=FloatAdapter()), BitField('y', 0xFFFFFFFF << (32 * 2), adapter=FloatAdapter()), BitField('o', 0xFFFFFFFF << (32 * 1), adapter=FloatAdapter()), BitField('r', 0xFFFFFFFF << (32 * 0), adapter=FloatAdapter()), ), bit_width=192), )) # 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._as7262.registers: register = self._as7262.registers[register] for field in register.fields: field = register.fields[field] if isinstance(field.adapter, LookupAdapter): for key in field.adapter.lookup_table: value = field.adapter.lookup_table[key] name = 'AS7262_{register}_{field}_{key}'.format( register=register.name, field=field.name, key=key).upper() locals()[name] = key self.soft_reset()
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)
def __init__(self, i2c_addr=I2C_ADDRESS_DEFAULT, alert_pin=None, i2c_dev=None): self._lock = Lock() self._is_setup = False self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._alert_pin = alert_pin self._deprecated_channels = { 'in0/ref': 'in0/in3', 'in1/ref': 'in1/in3', 'in2/ref': 'in2/in3', 'ref/gnd': 'in3/gnd' } self._is_ads1115 = False self._ads1115 = Device( I2C_ADDRESSES, i2c_dev=self._i2c_dev, bit_width=8, registers=( Register('CONFIG', 0x01, fields=(BitField('data_rate_sps', 0b0000000011100000, adapter=LookupAdapter({ 8: 0b000, 16: 0b001, 32: 0b010, 64: 0b011, 128: 0b100, 475: 0b101, 860: 0b110 })), )), Register('CONV', 0x00, fields=(BitField('value', 0xFFFF, adapter=Conv16Adapter()), ), bit_width=16), )) self._ads1115.select_address(self._i2c_addr) self._ads1015 = Device( I2C_ADDRESSES, i2c_dev=self._i2c_dev, bit_width=8, registers=( Register( 'CONFIG', 0x01, fields=( BitField('operational_status', 0b1000000000000000, adapter=LookupAdapter({ 'active': 0, 'inactive_start': 1 })), BitField( 'multiplexer', 0b0111000000000000, adapter=LookupAdapter({ 'in0/in1': 0b000, # Differential reading between in0 and in1, voltages must not be negative and must not exceed supply voltage 'in0/in3': 0b001, # Differential reading between in0 and in3. pimoroni breakout onboard reference connected to in3 'in1/in3': 0b010, # Differential reading between in1 and in3. pimoroni breakout onboard reference connected to in3 'in2/in3': 0b011, # Differential reading between in2 and in3. pimoroni breakout onboard reference connected to in3 'in0/gnd': 0b100, # Single-ended reading between in0 and GND 'in1/gnd': 0b101, # Single-ended reading between in1 and GND 'in2/gnd': 0b110, # Single-ended reading between in2 and GND 'in3/gnd': 0b111 # Single-ended reading between in3 and GND. Should always read 1.25v (or reference voltage) on pimoroni breakout })), BitField('programmable_gain', 0b0000111000000000, adapter=LookupAdapter({ 6.144: 0b000, 4.096: 0b001, 2.048: 0b010, 1.024: 0b011, 0.512: 0b100, 0.256: 0b101 })), BitField('mode', 0b0000000100000000, adapter=LookupAdapter({ 'continuous': 0, 'single': 1 })), BitField('data_rate_sps', 0b0000000011100000, adapter=LookupAdapter({ 128: 0b000, 250: 0b001, 490: 0b010, 920: 0b011, 1600: 0b100, 2400: 0b101, 3300: 0b110 })), BitField( 'comparator_mode', 0b0000000000010000, adapter=LookupAdapter({ 'traditional': 0b0, # Traditional comparator with hystersis 'window': 0b01 })), BitField('comparator_polarity', 0b0000000000001000, adapter=LookupAdapter({ 'active_low': 0b0, 'active_high': 0b1 })), BitField('comparator_latching', 0b0000000000000100), BitField('comparator_queue', 0b0000000000000011, adapter=LookupAdapter({ 'one': 0b00, 'two': 0b01, 'four': 0b10, 'disabled': 0b11 }))), bit_width=16), Register('CONV', 0x00, fields=(BitField('value', 0xFFF0, adapter=ConvAdapter()), ), bit_width=16), Register('THRESHOLD', 0x02, fields=(BitField('low', 0xFFFF, adapter=S16Adapter()), BitField('high', 0xFFFF, adapter=S16Adapter())), bit_width=32))) self._ads1015.select_address(self._i2c_addr)
def __init__(self, i2c_addr=I2C_ADDRESS, i2c_dev=None): self._is_setup = False self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._active_leds = 0 self._max30105 = Device( I2C_ADDRESS, i2c_dev=self._i2c_dev, bit_width=8, registers=( Register('INT_STATUS_1', 0x00, fields=(BitField('a_full', bit(7)), BitField('data_ready', bit(6)), BitField('alc_overflow', bit(5)), BitField('prox_int', bit(4)), BitField('pwr_ready', bit(0)))), Register('INT_STATUS_2', 0x01, fields=(BitField('die_temp_ready', bit(1)), )), Register('INT_ENABLE_1', 0x02, fields=( BitField('a_full_en', bit(7)), BitField('data_ready_en', bit(6)), BitField('alc_overflow_en', bit(5)), BitField('prox_int_en', bit(4)), )), Register('INT_ENABLE_2', 0x03, fields=(BitField('die_temp_ready_en', bit(1)), )), # Points to MAX30105 write location in FIFO Register('FIFO_WRITE', 0x04, fields=(BitField('pointer', 0b00011111), )), # Counts the number of samples lost up to 0xf Register('FIFO_OVERFLOW', 0x05, fields=(BitField('counter', 0b00011111), )), # Points to read location in FIFO Register('FIFO_READ', 0x06, fields=(BitField('pointer', 0b00011111), )), Register('FIFO_CONFIG', 0x08, fields=(BitField('sample_average', 0b11100000, adapter=LookupAdapter({ 1: 0b000, 2: 0b001, 4: 0b010, 8: 0b011, 16: 0b100, 32: 0b101 })), BitField('fifo_rollover_en', 0b00010000), BitField('fifo_almost_full', 0b00001111))), Register('MODE_CONFIG', 0x09, fields=(BitField('shutdown', 0b10000000), BitField('reset', 0b01000000), BitField('mode', 0b00000111, adapter=LookupAdapter({ 'none': 0b00, 'red_only': 0b010, 'red_ir': 0b011, 'green_red_ir': 0b111 })))), Register( 'SPO2_CONFIG', 0x0A, fields=( BitField('adc_range_nA', 0b01100000, adapter=LookupAdapter({ 2048: 0b00, 4096: 0b01, 8192: 0b10, 16384: 0b11 })), BitField('sample_rate_sps', 0b00011100, adapter=LookupAdapter({ 50: 0b000, 100: 0b001, 200: 0b010, 400: 0b011, 800: 0b100, 1000: 0b101, 1600: 0b110, 3200: 0b111 })), BitField( 'led_pw_us', 0b00000011, adapter=LookupAdapter({ 69: 0b00, # 68.95us 118: 0b01, # 117.78us 215: 0b10, # 215.44us 411: 0b11 # 410.75us })))), Register('LED_PULSE_AMPLITUDE', 0x0C, fields=(BitField('led1_mA', 0xff0000, adapter=PulseAmplitudeAdapter()), BitField('led2_mA', 0x00ff00, adapter=PulseAmplitudeAdapter()), BitField('led3_mA', 0x0000ff, adapter=PulseAmplitudeAdapter())), bit_width=24), Register('LED_PROX_PULSE_AMPLITUDE', 0x10, fields=(BitField('pilot_mA', 0xff, adapter=PulseAmplitudeAdapter()), )), # The below represent 4 timeslots Register('LED_MODE_CONTROL', 0x11, fields=(BitField('slot2', 0x7000, adapter=LEDModeAdapter()), BitField('slot1', 0x0700, adapter=LEDModeAdapter()), BitField('slot4', 0x0070, adapter=LEDModeAdapter()), BitField('slot3', 0x0007, adapter=LEDModeAdapter())), bit_width=16), Register('DIE_TEMP', 0x1f, fields=(BitField('temperature', 0xffff, adapter=TemperatureAdapter()), ), bit_width=16), Register('DIE_TEMP_CONFIG', 0x21, fields=(BitField('temp_en', bit(0)), )), Register('PROX_INT_THRESHOLD', 0x30, fields=(BitField('threshold', 0xff), )), Register('PART_ID', 0xfe, fields=(BitField('revision', 0xff00), BitField('part', 0x00ff)), bit_width=16)))
BitField('monkey', 0b01111100, adapter=x2Adapter()))), Register('measurement_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,
BitField('fw_version', 0x0000FFFF, adapter=FWVersionAdapter()), ), bit_width=32, read_only=True), Register('CONTROL', 0x04, fields=( BitField('reset', 0b10000000), BitField('interrupt', 0b01000000), BitField('gain_x', 0b00110000, adapter=LookupAdapter({ 1: 0b00, 3.7: 0b01, 16: 0b10, 64: 0b11 })), BitField('measurement_mode', 0b00001100), BitField('data_ready', 0b00000010), )), Register('INTEGRATION_TIME', 0x05, fields=(BitField('ms', 0xFF, adapter=IntegrationTimeAdapter()), )), Register('TEMPERATURE', 0x06, fields=(BitField('degrees_c', 0xFF), )), Register('LED_CONTROL', 0x07, fields=( BitField('illumination_current_limit_ma', 0b00110000,
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
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 }
return ((value & 0xFF00) >> 8) | ((value & 0x000F) << 8) ltr559 = Device( I2C_ADDR, i2c_dev=MockSMBus(0, default_registers={0x86: 0x92}), bit_width=8, registers=( Register('ALS_CONTROL', 0x80, fields=(BitField('gain', 0b00011100, adapter=LookupAdapter({ 1: 0b000, 2: 0b001, 4: 0b011, 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,
def __init__(self, i2c_addr=0x26, i2c_dev=None): self._i2c_addr = i2c_addr self._i2c_dev = i2c_dev self._is_setup = False # Device definition self._msa301 = Device([0x26], i2c_dev=self._i2c_dev, bit_width=8, registers=( Register('SOFT_RESET', 0x00, fields=( BitField('soft_reset', 0b00100000), BitField('seft_reset_alt', 0b00000100) )), Register('PARTID', 0x01, fields=(BitField('id', 0xFF),)), Register('ACCEL', 0x02, fields=( BitField('x', 0x00000000FFFF, adapter=SensorDataAdapter()), BitField('y', 0x0000FFFF0000, adapter=SensorDataAdapter()), BitField('z', 0xFFFF00000000, adapter=SensorDataAdapter()), ), bit_width=48, read_only=True), Register('MOTION_INTERRUPT', 0x09, fields=( BitField('interrupts', 0xFF, read_only=True, adapter=InterruptLookupAdapter({ 'orientation_interrupt': 0b01000000, 'single_tap_interrupt': 0b00100000, 'double_tap_interrupt': 0b00010000, 'active_interrupt': 0b00000100, 'freefall_interrupt': 0b00000001 })), )), Register('DATA_INTERRUPT', 0x0A, fields=( BitField('new_data_interrupt', 0b00000001, read_only=True), )), Register('TAP_ACTIVE_STATUS', 0x0B, fields=( BitField('tap_sign', 0b10000000, read_only=True), BitField('tap_triggered_x', 0b01000000, read_only=True), BitField('tap_triggered_y', 0b00100000, read_only=True), BitField('tap_triggered_z', 0b00010000, read_only=True), BitField('active_sign', 0b00001000, read_only=True), BitField('active_triggered_x', 0b00000100, read_only=True), BitField('active_triggered_y', 0b00000010, read_only=True), BitField('active_triggered_z', 0b00000001, read_only=True) )), Register('ORIENTATION_STATUS', 0x0C, fields=( BitField('z_orientation', 0b10000000, read_only=True), BitField('x_y_orientation', 0b01100000, read_only=True, adapter=LookupAdapter({ 'portrait_upright': 0b00, 'portrait_upsidedown': 0b01, 'landscape_left': 0b10, 'landscape_right': 0b11 })) )), Register('RESOLUTION_RANGE', 0x0F, fields=( BitField('resolution', 0b00001100, adapter=LookupAdapter({ 14: 0b00, 12: 0b01, 10: 0b10, 8: 0b11 }, snap=False)), BitField('range', 0b00000011, adapter=LookupAdapter({ 2: 0b00, 4: 0b01, 8: 0b10, 16: 0b11 }, snap=False)) )), Register('DISABLE_AXIS_ODR', 0x10, fields=( BitField('disable_x_axis', 0b10000000), BitField('disable_y_axis', 0b01000000), BitField('disable_z_axis', 0b00100000), BitField('output_data_rate', 0b00001111, adapter=LookupAdapter({ '1Hz': 0b0000, # Not Available in Normal Mode '1.95Hz': 0b0001, # Not Available in Normal Mode '3.9Hz': 0b0010, '7.81Hz': 0b0011, '15.63Hz': 0b0100, '31.25Hz': 0b0101, '62.5Hz': 0b0110, '125Hz': 0b0111, '250Hz': 0b1000, '500Hz': 0b1001, # Not Available in Low Power Mode '1000Hz': 0b1010 # Not Available in Low Power Mode })) )), Register('POWER_MODE_BANDWIDTH', 0x11, fields=( BitField('power_mode', 0b11000000, adapter=LookupAdapter({ 'normal': 0b00, 'low_power': 0b01, 'suspend': 0b10 })), BitField('low_power_bandwidth', 0b00011110, adapter=LookupAdapter({ '1.95Hz': 0b0010, '3.9Hz': 0b0011, '7.81Hz': 0b0100, '15.63Hz': 0b0101, '31.25Hz': 0b0110, '62.5Hz': 0b0111, '125Hz': 0b1000, '250Hz': 0b1001, '500Hz': 0b1010 })) )), Register('SWAP_POLARITY', 0x12, fields=( BitField('x_polariy', 0b00001000), BitField('y_polariy', 0b00000100), BitField('z_polariy', 0b00000010), BitField('x_z_swap', 0b00000001) )), Register('INTERRUPT_ENABLE', 0x16, fields=( BitField('enable', 0xFF), BitField('interrupts', 0xFF, adapter=InterruptLookupAdapter({ 'orientation_interrupt': 0b01000000, 'single_tap_interrupt': 0b00100000, 'double_tap_interrupt': 0b00010000, 'z_active_interrupt': 0b00000100, 'y_active_interrupt': 0b00000010, 'x_active_interrupt': 0b00000001 })), )), Register('INTERRUPT_ENABLE_1', 0x17, fields=( BitField('enable', 0xFF), BitField('interrupts', 0xFF, adapter=InterruptLookupAdapter({ 'data_interrupt': 0b00010000, 'freefall_interrupt': 0b00001000 })), )), Register('INT1_MAPPING_0', 0x19, fields=( BitField('map_orientation_int1', 0b01000000), BitField('map_single_tap_int1', 0b00100000), BitField('map_double_tap_int1', 0b00010000), BitField('map_active_int1', 0b00000100), BitField('map_freefall_int1', 0b00000001) )), Register('INT1_MAPPING_1', 0x1A, fields=( [BitField('map_new_data_int1', 0b00000001)] )), Register('INT1_OUTPUT_MODE', 0x20, fields=( BitField('mode', 0b00000010, adapter=LookupAdapter({ 'push_pull': 0b0, 'open_drain': 0b1 })), BitField('active_level', 0b00000010, adapter=LookupAdapter({ 'low': 0b0, 'high': 0b1 })), )), Register('INT1_LATCH', 0x21, fields=( BitField('latch_reset', 0b10000000), BitField('latch_setting', 0b00001111, adapter=LookupAdapter({ 'non_latched': 0b0000, 'temp_latch_250ms': 0b0001, 'temp_latch_500ms': 0b0010, 'temp_latch_1s': 0b0011, 'temp_latch_2s': 0b0100, 'temp_latch_4s': 0b0101, 'temp_latch_8s': 0b0110, 'latched': 0b0111, 'non_latched_': 0b1000, 'temp_latch_1ms': 0b1001, 'temp_latch_1ms_': 0b1010, # TODO allow LookupAdapter to use list value 'temp_latch_2ms': 0b1011, 'temp_latch_25ms': 0b1100, 'temp_latch_50ms': 0b1101, 'temp_latch_100ms': 0b1110, 'latched_': 0b1111 })) )), Register('FREEFALL_DURATION', 0x22, fields=( BitField('duration', 0xFF), )), Register('FREEFALL_THRESHOLD', 0x23, fields=( BitField('threshold', 0xFF), )), Register('FREEFALL_HYSTERESIS', 0x24, fields=( BitField('mode', 0x00000100, adapter=LookupAdapter({ 'single': 0b0, 'sum': 0b1 })), BitField('hysteresis_time', 0b00000011) )), Register('ACTIVE_DURATION', 0x27, fields=( BitField('duration', 0b00000011), )), Register('ACTIVE_THRESHOLD', 0x21, fields=( BitField('threshold', 0xFF), )), Register('TAP_DURATION', 0x28, fields=( BitField('tap_quiet', 0x10000000, adapter=LookupAdapter({ '30ms': 0b0, '20ms': 0b1 })), BitField('tap_shock', 0x01000000, adapter=LookupAdapter({ '50ms': 0b0, '70ms': 0b1 })), BitField('double_tap_window', 0b00000111, adapter=LookupAdapter({ '50ms': 0b000, '100ms': 0b001, '150ms': 0b010, '200ms': 0b011, '250ms': 0b100, '375ms': 0b101, '500ms': 0b110, '700ms': 0b111 })) )), Register('TAP_THRESHOLD', 0x2B, fields=( [BitField('threshold', 0b00011111)] )), Register('ORIENTATION_HYSTERESIS', 0x2C, fields=( BitField('hysteresis', 0b01110000), # set the hysteresis of the orientation interrupt, 1LSB is 62.5mg BitField('orientation_blocking', 0b00001100, adapter=LookupAdapter({ 'non_blocking': 0b00, 'z_axis_blocking': 0b01, 'z_axis_any_0.2_slope_blocking': 0b10, 'non_blocking_': 0b11 # TODO LookupAdapter needs list value })), BitField('orientation_mode', 0b00000011, adapter=LookupAdapter({ 'symmetrical': 0b00, 'high_asymmetrical': 0b01, 'low_asymmetrical': 0b10, 'symmetrical_': 0b11 # TODO LookupAdapter needs list value })) )), Register('Z_BLOCK', 0x2D, fields=( BitField('setting', 0b00001111), # defines the block acc_z between 0g to 0.9375g )), Register('OFFSET', 0x38, fields=( BitField('x', 0x0000FF), # the offset compensation value for X axis, 1LSB is 3.9mg BitField('y', 0x00FF00), # the offset compensation value for Y axis, 1LSB is 3.9mg BitField('z', 0xFF0000), # the offset compensation value for Z axis, 1LSB is 3.9mg ), bit_width=24) )) res_range = self._msa301.get('RESOLUTION_RANGE') self._resolution = res_range.resolution self._range = res_range.range