Exemplo n.º 1
0
 def psleep(self):
     '''
     Sleeps longer and longer to save power the more time in between updates.
     '''
     if check_deadline(ticks_ms(), self._powersave_start) <= 60000:
         sleep(8 / 1000)
     elif check_deadline(ticks_ms(), self._powersave_start) >= 240000:
         sleep(180 / 1000)
     return
def check_timeout(flag, limit):
    """test for timeout waiting for specified flag"""
    timed_out = False
    if HAS_SUPERVISOR:
        start = supervisor.ticks_ms()
        while not timed_out and not flag():
            if ticks_diff(supervisor.ticks_ms(), start) >= limit * 1000:
                timed_out = True
    else:
        start = time.monotonic()
        while not timed_out and not flag():
            if time.monotonic() - start >= limit:
                timed_out = True
    return timed_out
Exemplo n.º 3
0
    def before_matrix_scan(self, keyboard):
        '''
        Return value will be injected as an extra matrix update
        '''
        now = ticks_ms()
        if now - self.last_tick < self.polling_interval:
            return
        self.last_tick = now

        x, y = self._read_raw_state()

        # I'm a shit coder, so offset is handled in software side
        s_x = self.getSignedNumber(x, 8) - self.x_offset
        s_y = self.getSignedNumber(y, 8) - self.y_offset

        # Evaluate Deadzone
        if s_x in range(-self.dead_x, self.dead_x) and s_y in range(
            -self.dead_y, self.dead_y
        ):
            # Within bounds, just die
            return
        else:
            # Set the X/Y from easypoint
            self.pointing_device.report_x[0] = x
            self.pointing_device.report_y[0] = y

            self.pointing_device.hid_pending = x != 0 or y != 0

        return
Exemplo n.º 4
0
 def tick(self):
     now = ticks_ms()
     if ticks_diff(now, self.last_tick) >= self.period:
         self.last_tick = now
         return True
     else:
         return False
 def operation_mode(self, val):
     assert 0 <= val <= 4
     # Set the mode bits inside the operation mode register.
     op_mode = self._read_u8(_REG_OP_MODE)
     op_mode &= 0b11100011
     op_mode |= val << 2
     self._write_u8(_REG_OP_MODE, op_mode)
     # Wait for mode to change by polling interrupt bit.
     if HAS_SUPERVISOR:
         start = supervisor.ticks_ms()
         while not self.mode_ready:
             if ticks_diff(supervisor.ticks_ms(), start) >= 1000:
                 raise TimeoutError("Operation Mode failed to set.")
     else:
         start = time.monotonic()
         while not self.mode_ready:
             if time.monotonic() - start >= 1:
                 raise TimeoutError("Operation Mode failed to set.")
Exemplo n.º 6
0
    def __init__(self, powersave_pin=None):
        self.enable = False
        self.powersave_pin = powersave_pin  # Powersave pin board object
        self._powersave_start = ticks_ms()
        self._usb_last_scan = ticks_ms() - 5000
        self._psp = None  # Powersave pin object
        self._i2c = 0
        self._loopcounter = 0

        make_key(names=('PS_TOG', ),
                 on_press=self._ps_tog,
                 on_release=handler_passthrough)
        make_key(names=('PS_ON', ),
                 on_press=self._ps_enable,
                 on_release=handler_passthrough)
        make_key(names=('PS_OFF', ),
                 on_press=self._ps_disable,
                 on_release=handler_passthrough)
Exemplo n.º 7
0
    def __init__(
        self,
        split_flip=True,
        split_side=None,
        split_type=SplitType.UART,
        split_target_left=True,
        uart_interval=20,
        data_pin=None,
        data_pin2=None,
        target_left=True,
        uart_flip=True,
        use_pio=False,
        debug_enabled=False,
    ):
        self._is_target = True
        self._uart_buffer = []
        self.split_flip = split_flip
        self.split_side = split_side
        self.split_type = split_type
        self.split_target_left = split_target_left
        self.split_offset = None
        self.data_pin = data_pin
        self.data_pin2 = data_pin2
        self.target_left = target_left
        self.uart_flip = uart_flip
        self._use_pio = use_pio
        self._uart = None
        self._uart_interval = uart_interval
        self._debug_enabled = debug_enabled
        self.uart_header = bytearray([0xB2])  # Any non-zero byte should work

        if self.split_type == SplitType.BLE:
            try:
                from adafruit_ble import BLERadio
                from adafruit_ble.advertising.standard import (
                    ProvideServicesAdvertisement, )
                from adafruit_ble.services.nordic import UARTService

                self.BLERadio = BLERadio
                self.ProvideServicesAdvertisement = ProvideServicesAdvertisement
                self.UARTService = UARTService
            except ImportError:
                print('BLE Import error')
                return  # BLE isn't supported on this platform
            self._ble_last_scan = ticks_ms() - 5000
            self._connection_count = 0
            self._split_connected = False
            self._uart_connection = None
            self._advertisment = None  # Seems to not be used anywhere
            self._advertising = False
            self._psave_enable = False

        if self._use_pio:
            from kmk.transports.pio_uart import PIO_UART

            self.PIO_UART = PIO_UART
Exemplo n.º 8
0
 def after_matrix_scan(self, keyboard):
     if self._nav_key_activated:
         if self._next_interval <= ticks_ms():
             # print("hello: ")
             # print(ticks_ms())
             self._next_interval = ticks_ms() + self.ac_interval
             # print(self._next_interval)
             if self.move_step < self.max_speed:
                 self.move_step = self.move_step + 1
                 if self._right_activated:
                     self.pointing_device.report_x[0] = self.move_step
                 if self._left_activated:
                     self.pointing_device.report_x[0] = 0xFF & (
                         0 - self.move_step)
                 if self._up_activated:
                     self.pointing_device.report_y[0] = 0xFF & (
                         0 - self.move_step)
                 if self._down_activated:
                     self.pointing_device.report_y[0] = self.move_step
                 # self.pointing_device.hid_pending = True
     return
Exemplo n.º 9
0
    def __init__(self, is_inverted=False):

        self.is_inverted = is_inverted

        self._state = None
        self._direction = None
        self._pos = 0
        self._button_state = True
        self._button_held = None
        self._velocity = 0

        self._movement = 0
        self._timestamp = ticks_ms()

        # callback functions on events. Need to be defined externally
        self.on_move_do = None
        self.on_button_do = None
Exemplo n.º 10
0
    def set_timeout(self, after_ticks, callback):
        # We allow passing False as an implicit "run this on the next process timeouts cycle"
        if after_ticks is False:
            after_ticks = 0

        if after_ticks == 0 and self._processing_timeouts:
            after_ticks += 1

        timeout_key = ticks_add(ticks_ms(), after_ticks)

        if timeout_key not in self._timeouts:
            self._timeouts[timeout_key] = []

        idx = len(self._timeouts[timeout_key])
        self._timeouts[timeout_key].append(callback)

        return (timeout_key, idx)
Exemplo n.º 11
0
    def __init__(
        self,
        i2c,
        address=I2C_ADDRESS,
        y_offset=Y_OFFSET,
        x_offset=X_OFFSET,
        dead_x=DEAD_X,
        dead_y=DEAD_Y,
    ):
        self._i2c_address = address
        self._i2c_bus = i2c

        # HID parameters
        self.pointing_device = PointingDevice()
        self.polling_interval = 20
        self.last_tick = ticks_ms()

        # Offsets for poor soldering
        self.y_offset = y_offset
        self.x_offset = x_offset

        # Deadzone
        self.dead_x = DEAD_X
        self.dead_y = DEAD_Y
Exemplo n.º 12
0
    def _process_timeouts(self):
        if not self._timeouts:
            return self

        # Copy timeout keys to a temporary list to allow sorting.
        # Prevent net timeouts set during handling from running on the current
        # cycle by setting a flag `_processing_timeouts`.
        current_time = ticks_ms()
        timeout_keys = []
        self._processing_timeouts = True

        for k in self._timeouts.keys():
            if ticks_diff(k, current_time) <= 0:
                timeout_keys.append(k)

        for k in sorted(timeout_keys):
            for callback in self._timeouts[k]:
                if callback:
                    callback()
            del self._timeouts[k]

        self._processing_timeouts = False

        return self
Exemplo n.º 13
0
 def _reset_next_interval(self):
     if self._nav_key_activated == 1:
         self._next_interval = ticks_ms() + self.ac_interval
         self.move_step = 1
Exemplo n.º 14
0
 def psave_time_reset(self):
     self._powersave_start = ticks_ms()
    def receive(self,
                *,
                keep_listening: bool = True,
                with_header: bool = False,
                with_ack: bool = False,
                timeout: Optional[float] = None) -> Optional[bytearray]:
        """Wait to receive a packet from the receiver. If a packet is found the payload bytes
        are returned, otherwise None is returned (which indicates the timeout elapsed with no
        reception).
        If keep_listening is True (the default) the chip will immediately enter listening mode
        after reception of a packet, otherwise it will fall back to idle mode and ignore any
        future reception.
        All packets must have a 4-byte header for compatibility with the
        RadioHead library.
        The header consists of 4 bytes (To,From,ID,Flags). The default setting will  strip
        the header before returning the packet to the caller.
        If with_header is True then the 4 byte header will be returned with the packet.
        The payload then begins at packet[4].
        If with_ack is True, send an ACK after receipt (Reliable Datagram mode)
        """
        timed_out = False
        if timeout is None:
            timeout = self.receive_timeout
        if timeout is not None:
            # Wait for the payload_ready signal.  This is not ideal and will
            # surely miss or overflow the FIFO when packets aren't read fast
            # enough, however it's the best that can be done from Python without
            # interrupt supports.
            # Make sure we are listening for packets.
            self.listen()
            timed_out = False
            if HAS_SUPERVISOR:
                start = supervisor.ticks_ms()
                while not timed_out and not self.rx_done():
                    if ticks_diff(supervisor.ticks_ms(),
                                  start) >= timeout * 1000:
                        timed_out = True
            else:
                start = time.monotonic()
                while not timed_out and not self.rx_done():
                    if time.monotonic() - start >= timeout:
                        timed_out = True
        # Payload ready is set, a packet is in the FIFO.
        packet = None
        # save last RSSI reading
        self.last_rssi = self.rssi

        # save the last SNR reading
        self.last_snr = self.snr

        # Enter idle mode to stop receiving other packets.
        self.idle()
        if not timed_out:
            if self.enable_crc and self.crc_error():
                self.crc_error_count += 1
            else:
                # Read the data from the FIFO.
                # Read the length of the FIFO.
                fifo_length = self._read_u8(_RH_RF95_REG_13_RX_NB_BYTES)
                # Handle if the received packet is too small to include the 4 byte
                # RadioHead header and at least one byte of data --reject this packet and ignore it.
                if fifo_length > 0:  # read and clear the FIFO if anything in it
                    current_addr = self._read_u8(
                        _RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR)
                    self._write_u8(_RH_RF95_REG_0D_FIFO_ADDR_PTR, current_addr)
                    packet = bytearray(fifo_length)
                    # Read the packet.
                    self._read_into(_RH_RF95_REG_00_FIFO, packet)
                # Clear interrupt.
                self._write_u8(_RH_RF95_REG_12_IRQ_FLAGS, 0xFF)
                if fifo_length < 5:
                    packet = None
                else:
                    if (self.node != _RH_BROADCAST_ADDRESS
                            and packet[0] != _RH_BROADCAST_ADDRESS
                            and packet[0] != self.node):
                        packet = None
                    # send ACK unless this was an ACK or a broadcast
                    elif (with_ack and ((packet[3] & _RH_FLAGS_ACK) == 0)
                          and (packet[0] != _RH_BROADCAST_ADDRESS)):
                        # delay before sending Ack to give receiver a chance to get ready
                        if self.ack_delay is not None:
                            time.sleep(self.ack_delay)
                        # send ACK packet to sender (data is b'!')
                        self.send(
                            b"!",
                            destination=packet[1],
                            node=packet[0],
                            identifier=packet[2],
                            flags=(packet[3] | _RH_FLAGS_ACK),
                        )
                        # reject Retries if we have seen this idetifier from this source before
                        if (self.seen_ids[packet[1]] == packet[2]) and (
                                packet[3] & _RH_FLAGS_RETRY):
                            packet = None
                        else:  # save the packet identifier for this source
                            self.seen_ids[packet[1]] = packet[2]
                    if (not with_header and packet
                            is not None):  # skip the header if not wanted
                        packet = packet[4:]
        # Listen again if necessary and return the result packet.
        if keep_listening:
            self.listen()
        else:
            # Enter idle mode to stop receiving other packets.
            self.idle()
        # Clear interrupt.
        self._write_u8(_RH_RF95_REG_12_IRQ_FLAGS, 0xFF)
        return packet
    def send(self,
             data: ReadableBuffer,
             *,
             keep_listening: bool = False,
             destination: Optional[int] = None,
             node: Optional[int] = None,
             identifier: Optional[int] = None,
             flags: Optional[int] = None) -> bool:
        """Send a string of data using the transmitter.
        You can only send 252 bytes at a time
        (limited by chip's FIFO size and appended headers).
        This appends a 4 byte header to be compatible with the RadioHead library.
        The header defaults to using the initialized attributes:
        (destination,node,identifier,flags)
        It may be temporarily overidden via the kwargs - destination,node,identifier,flags.
        Values passed via kwargs do not alter the attribute settings.
        The keep_listening argument should be set to True if you want to start listening
        automatically after the packet is sent. The default setting is False.

        Returns: True if success or False if the send timed out.
        """
        # Disable pylint warning to not use length as a check for zero.
        # This is a puzzling warning as the below code is clearly the most
        # efficient and proper way to ensure a precondition that the provided
        # buffer be within an expected range of bounds. Disable this check.
        # pylint: disable=len-as-condition
        assert 0 < len(data) <= 252
        # pylint: enable=len-as-condition
        self.idle()  # Stop receiving to clear FIFO and keep it clear.
        # Fill the FIFO with a packet to send.
        self._write_u8(_RH_RF95_REG_0D_FIFO_ADDR_PTR,
                       0x00)  # FIFO starts at 0.
        # Combine header and data to form payload
        payload = bytearray(4)
        if destination is None:  # use attribute
            payload[0] = self.destination
        else:  # use kwarg
            payload[0] = destination
        if node is None:  # use attribute
            payload[1] = self.node
        else:  # use kwarg
            payload[1] = node
        if identifier is None:  # use attribute
            payload[2] = self.identifier
        else:  # use kwarg
            payload[2] = identifier
        if flags is None:  # use attribute
            payload[3] = self.flags
        else:  # use kwarg
            payload[3] = flags
        payload = payload + data
        # Write payload.
        self._write_from(_RH_RF95_REG_00_FIFO, payload)
        # Write payload and header length.
        self._write_u8(_RH_RF95_REG_22_PAYLOAD_LENGTH, len(payload))
        # Turn on transmit mode to send out the packet.
        self.transmit()
        # Wait for tx done interrupt with explicit polling (not ideal but
        # best that can be done right now without interrupts).
        timed_out = False
        if HAS_SUPERVISOR:
            start = supervisor.ticks_ms()
            while not timed_out and not self.tx_done():
                if ticks_diff(supervisor.ticks_ms(),
                              start) >= self.xmit_timeout * 1000:
                    timed_out = True
        else:
            start = time.monotonic()
            while not timed_out and not self.tx_done():
                if time.monotonic() - start >= self.xmit_timeout:
                    timed_out = True
        # Listen again if necessary and return the result packet.
        if keep_listening:
            self.listen()
        else:
            # Enter idle mode to stop receiving other packets.
            self.idle()
        # Clear interrupt.
        self._write_u8(_RH_RF95_REG_12_IRQ_FLAGS, 0xFF)
        return not timed_out
Exemplo n.º 17
0
 def ble_time_reset(self):
     '''Resets the rescan timer'''
     self._ble_last_scan = ticks_ms()
Exemplo n.º 18
0
 def ble_rescan_timer(self):
     '''If true, the rescan timer is up'''
     return not bool(check_deadline(ticks_ms(), self._ble_last_scan, 5000))
Exemplo n.º 19
0
 def usb_rescan_timer(self):
     return bool(check_deadline(ticks_ms(), self._usb_last_scan) > 5000)
Exemplo n.º 20
0
        mapped = in_delta
    else:
        mapped = 0.5
    mapped *= out_max - out_min
    mapped += out_min
    if out_min <= out_max:
        return max(min(mapped, out_max), out_min)
    return min(max(mapped, out_max), out_min)


# we're doing "analog" reading of touchA, so get our own baseline
touchA_min = touchA.raw_value
# because of long traces to touchB, we need to adjust threshold up a bit
touchB.threshold += 500

last_press_time = ticks_ms()
last_gate_time = ticks_ms()
interval = 500  # milliseconds between
gate_duration = 100  # milliseconds gate is high in tap tempo mode
do_tap_tempo = False

while True:
    switch.update()
    now = ticks_ms()

    # r = 0-255 mapped analog touch value on A output
    # g = tap-tempo beat, if any, on B output
    # b = on/off touch value on B output
    r = map_range(touchA.raw_value, touchA_min, touchA_min * 2, 0, 255)
    g = 0
    b = 0
Exemplo n.º 21
0
 def usb_time_reset(self):
     self._usb_last_scan = ticks_ms()
     return
Exemplo n.º 22
0
 def velocity_event(self):
     if self.VELOCITY_MODE:
         new_timestamp = ticks_ms()
         self._velocity = new_timestamp - self._timestamp
         self._timestamp = new_timestamp
Exemplo n.º 23
0
 def __init__(self, period):
     self.period = period
     self.last_tick = ticks_ms()