<commit_before># upower.py Enables access to functions useful in low power Pyboard projects
# Copyright 2016 <NAME>
# This code is released under the MIT licence

# V0.4 10th October 2016
# why() function adapted: old version broken by firmware change


# http://www.st.com/web/en/resource/technical/document/application_note/DM00025071.pdf
import pyb, stm, os, utime, uctypes, machine

# CODE RUNS ON IMPORT **** START ****

def buildcheck(tupTarget):
    fail = True
    if 'uname' in dir(os):
        datestring = os.uname()[3]
        date = datestring.split(' on')[1]
        idate = tuple([int(x) for x in date.split('-')])
        fail = idate < tupTarget
    if fail:
        raise OSError('This driver requires a firmware build dated {:4d}-{:02d}-{:02d} or later'.format(*tupTarget))

buildcheck((2016, 10, 1))                       # y,m,d

usb_connected = False
if pyb.usb_mode() is not None:                  # User has enabled CDC in boot.py
    usb_connected = pyb.Pin.board.USB_VBUS.value() == 1
    if not usb_connected:
        pyb.usb_mode(None)                      # Save power

# CODE RUNS ON IMPORT **** END ****

def bounds(val, minval, maxval, msg):           # Bounds check
    if not (val >= minval and val <= maxval):
        raise ValueError(msg)

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

class RTCError(OSError):
    pass

def cprint(*args, **kwargs):                    # Conditional print: USB fails if low power modes are used
    global usb_connected
    if not usb_connected:                       # assume a UART has been specified in boot.py
        print(*args, **kwargs)

# Count the trailing zeros in an integer
def ctz(n):
    if not n:
        return 32
    count = 0
    while not n & 1:
        n >>= 1
        count += 1
    return count

# ***** BACKUP RAM SUPPORT *****

@singleton
class BkpRAM(object):
    BKPSRAM = 0x40024000
    def __init__(self):
        stm.mem32[stm.RCC + stm.RCC_APB1ENR] |= 0x10000000 # PWREN bit
        stm.mem32[stm.PWR + stm.PWR_CR] |= 0x100  # Set the DBP bit in the PWR power control register
        stm.mem32[stm.RCC + stm.RCC_AHB1ENR] |= 0x40000 # enable BKPSRAMEN
        stm.mem32[stm.PWR + stm.PWR_CSR] |= 0x200 # BRE backup register enable bit
        self._ba = uctypes.bytearray_at(self.BKPSRAM, 4096)
    def idxcheck(self, idx):
        bounds(idx, 0, 0x3ff, 'RTC backup RAM index out of range')
    def __getitem__(self, idx):
        self.idxcheck(idx)
        return stm.mem32[self.BKPSRAM + idx * 4]
    def __setitem__(self, idx, val):
        self.idxcheck(idx)
        stm.mem32[self.BKPSRAM + idx * 4] = val
    @property
    def ba(self):
        return self._ba                         # Access as bytearray

# ***** RTC REGISTERS *****

@singleton
class RTCRegs(object):
    def idxcheck(self, idx):
        bounds(idx, 0, 19, 'RTC register index out of range')
    def __getitem__(self, idx):
        self.idxcheck(idx)
        return stm.mem32[stm.RTC + stm.RTC_BKP0R+ idx * 4]
    def __setitem__(self, idx, val):
        self.idxcheck(idx)
        stm.mem32[stm.RTC + stm.RTC_BKP0R + idx * 4] = val


# ***** LOW POWER pyb.delay() ALTERNATIVE *****
def lpdelay(ms):                                # Low power delay. Note stop() kills USB
    global usb_connected
    rtc = pyb.RTC()
    if usb_connected:
        pyb.delay(ms)
        return
    rtc.wakeup(ms)
    pyb.stop()
    rtc.wakeup(None)

# ***** TAMPER (X18) PIN SUPPORT *****

@singleton
class Tamper(object):
    def __init__(self):
        self.edge_triggered = False
        self.triggerlevel = 0
        self.tampmask = 0
        self.disable()                          # Ensure no events occur until we're ready
        self.pin = pyb.Pin.board.X18
        self.pin_configured = False             # Conserve power: enable pullup only if needed
        self.setup()

    def setup(self, level = 0, *, freq = 16, samples = 2, edge = False):
        self.tampmask = 0
        if level == 1:
            self.tampmask |= 2
            self.triggerlevel = 1
        elif level == 0:
            self.triggerlevel = 0
        else:
            raise ValueError("level must be 0 or 1")
        if type(edge) == bool:
            self.edge_triggered = edge
        else:
            raise ValueError("edge must be True or False")
        if not self.edge_triggered:
            if freq in (1,2,4,8,16,32,64,128):
                self.tampmask |= ctz(freq) << 8
            else:
                raise ValueError("Frequency must be 1, 2, 4, 8, 16, 32, 64 or 128Hz")
            if samples in (2, 4, 8):
                self.tampmask |= ctz(samples) << 11
            else:
                raise ValueError("Number of samples must be 2, 4, or 8")

    def _pinconfig(self):
        if not self.pin_configured:
            self.pin.init(mode = pyb.Pin.IN, pull = pyb.Pin.PULL_UP)
            self.pin_configured = True

    def disable(self):
        stm.mem32[stm.RTC + stm.RTC_TAFCR] = self.tampmask

    def wait_inactive(self):
        self._pinconfig()
        while self.pin.value() == self.triggerlevel: # Wait for pin to go logically off
            lpdelay(50)

    @property
    def pinvalue(self):
        self._pinconfig()
        return self.pin.value()

    def enable(self):
        BIT21 = 1 << 21                                 # Tamper mask bit
        self.disable()
        stm.mem32[stm.EXTI + stm.EXTI_IMR] |= BIT21     # Set up ext interrupt
        stm.mem32[stm.EXTI + stm.EXTI_RTSR] |= BIT21    # Rising edge
        stm.mem32[stm.EXTI + stm.EXTI_PR] |= BIT21      # Clear pending bit

        stm.mem32[stm.RTC + stm.RTC_ISR] &= 0xdfff      # Clear tamp1f flag
        stm.mem32[stm.PWR + stm.PWR_CR] |= 4            # Clear power wakeup flag WUF
        stm.mem32[stm.RTC + stm.RTC_TAFCR] = self.tampmask | 5 # Tamper interrupt enable and tamper1 enable

# ***** WKUP PIN (X1) SUPPORT *****

@singleton
class wakeup_X1(object):                                # Support wakeup on low-high edge on pin X1
    def __init__(self):
        self.disable()
        self.pin = pyb.Pin.board.X1                     # Don't configure pin unless user accesses wkup
        self.pin_configured = False

    def _pinconfig(self):
        if not self.pin_configured:
            self.pin.init(mode = pyb.Pin.IN, pull = pyb.Pin.PULL_DOWN)
            self.pin_configured = True

    def enable(self):                                   # In this mode pin has pulldown enabled
        stm.mem32[stm.PWR + stm.PWR_CR] |= 4            # set CWUF to clear WUF in PWR_CSR
        stm.mem32[stm.PWR + stm.PWR_CSR] |= 0x100       # Enable wakeup

    def disable(self):<commit_msg>upower.py add comment about pin X1 on Espruino Pico<commit_after># upower.py Enables access to functions useful in low power Pyboard projects
# Copyright 2016 <NAME>
# This code is released under the MIT licence

# V0.4 10th October 2016
# why() function adapted: old version broken by firmware change


# http://www.st.com/web/en/resource/technical/document/application_note/DM00025071.pdf
import pyb, stm, os, utime, uctypes, machine

# CODE RUNS ON IMPORT **** START ****

def buildcheck(tupTarget):
    fail = True
    if 'uname' in dir(os):
        datestring = os.uname()[3]
        date = datestring.split(' on')[1]
        idate = tuple([int(x) for x in date.split('-')])
        fail = idate < tupTarget
    if fail:
        raise OSError('This driver requires a firmware build dated {:4d}-{:02d}-{:02d} or later'.format(*tupTarget))

buildcheck((2016, 10, 1))                       # y,m,d

usb_connected = False
if pyb.usb_mode() is not None:                  # User has enabled CDC in boot.py
    usb_connected = pyb.Pin.board.USB_VBUS.value() == 1
    if not usb_connected:
        pyb.usb_mode(None)                      # Save power

# CODE RUNS ON IMPORT **** END ****

def bounds(val, minval, maxval, msg):           # Bounds check
    if not (val >= minval and val <= maxval):
        raise ValueError(msg)

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

class RTCError(OSError):
    pass

def cprint(*args, **kwargs):                    # Conditional print: USB fails if low power modes are used
    global usb_connected
    if not usb_connected:                       # assume a UART has been specified in boot.py
        print(*args, **kwargs)

# Count the trailing zeros in an integer
def ctz(n):
    if not n:
        return 32
    count = 0
    while not n & 1:
        n >>= 1
        count += 1
    return count

# ***** BACKUP RAM SUPPORT *****

@singleton
class BkpRAM(object):
    BKPSRAM = 0x40024000
    def __init__(self):
        stm.mem32[stm.RCC + stm.RCC_APB1ENR] |= 0x10000000 # PWREN bit
        stm.mem32[stm.PWR + stm.PWR_CR] |= 0x100  # Set the DBP bit in the PWR power control register
        stm.mem32[stm.RCC + stm.RCC_AHB1ENR] |= 0x40000 # enable BKPSRAMEN
        stm.mem32[stm.PWR + stm.PWR_CSR] |= 0x200 # BRE backup register enable bit
        self._ba = uctypes.bytearray_at(self.BKPSRAM, 4096)
    def idxcheck(self, idx):
        bounds(idx, 0, 0x3ff, 'RTC backup RAM index out of range')
    def __getitem__(self, idx):
        self.idxcheck(idx)
        return stm.mem32[self.BKPSRAM + idx * 4]
    def __setitem__(self, idx, val):
        self.idxcheck(idx)
        stm.mem32[self.BKPSRAM + idx * 4] = val
    @property
    def ba(self):
        return self._ba                         # Access as bytearray

# ***** RTC REGISTERS *****

@singleton
class RTCRegs(object):
    def idxcheck(self, idx):
        bounds(idx, 0, 19, 'RTC register index out of range')
    def __getitem__(self, idx):
        self.idxcheck(idx)
        return stm.mem32[stm.RTC + stm.RTC_BKP0R+ idx * 4]
    def __setitem__(self, idx, val):
        self.idxcheck(idx)
        stm.mem32[stm.RTC + stm.RTC_BKP0R + idx * 4] = val


# ***** LOW POWER pyb.delay() ALTERNATIVE *****
def lpdelay(ms):                                # Low power delay. Note stop() kills USB
    global usb_connected
    rtc = pyb.RTC()
    if usb_connected:
        pyb.delay(ms)
        return
    rtc.wakeup(ms)
    pyb.stop()
    rtc.wakeup(None)

# ***** TAMPER (X18) PIN SUPPORT *****

@singleton
class Tamper(object):
    def __init__(self):
        self.edge_triggered = False
        self.triggerlevel = 0
        self.tampmask = 0
        self.disable()                          # Ensure no events occur until we're ready
        self.pin = pyb.Pin.board.X18
        self.pin_configured = False             # Conserve power: enable pullup only if needed
        self.setup()

    def setup(self, level = 0, *, freq = 16, samples = 2, edge = False):
        self.tampmask = 0
        if level == 1:
            self.tampmask |= 2
            self.triggerlevel = 1
        elif level == 0:
            self.triggerlevel = 0
        else:
            raise ValueError("level must be 0 or 1")
        if type(edge) == bool:
            self.edge_triggered = edge
        else:
            raise ValueError("edge must be True or False")
        if not self.edge_triggered:
            if freq in (1,2,4,8,16,32,64,128):
                self.tampmask |= ctz(freq) << 8
            else:
                raise ValueError("Frequency must be 1, 2, 4, 8, 16, 32, 64 or 128Hz")
            if samples in (2, 4, 8):
                self.tampmask |= ctz(samples) << 11
            else:
                raise ValueError("Number of samples must be 2, 4, or 8")

    def _pinconfig(self):
        if not self.pin_configured:
            self.pin.init(mode = pyb.Pin.IN, pull = pyb.Pin.PULL_UP)
            self.pin_configured = True

    def disable(self):
        stm.mem32[stm.RTC + stm.RTC_TAFCR] = self.tampmask

    def wait_inactive(self):
        self._pinconfig()
        while self.pin.value() == self.triggerlevel: # Wait for pin to go logically off
            lpdelay(50)

    @property
    def pinvalue(self):
        self._pinconfig()
        return self.pin.value()

    def enable(self):
        BIT21 = 1 << 21                                 # Tamper mask bit
        self.disable()
        stm.mem32[stm.EXTI + stm.EXTI_IMR] |= BIT21     # Set up ext interrupt
        stm.mem32[stm.EXTI + stm.EXTI_RTSR] |= BIT21    # Rising edge
        stm.mem32[stm.EXTI + stm.EXTI_PR] |= BIT21      # Clear pending bit

        stm.mem32[stm.RTC + stm.RTC_ISR] &= 0xdfff      # Clear tamp1f flag
        stm.mem32[stm.PWR + stm.PWR_CR] |= 4            # Clear power wakeup flag WUF
        stm.mem32[stm.RTC + stm.RTC_TAFCR] = self.tampmask | 5 # Tamper interrupt enable and tamper1 enable

# ***** WKUP PIN (X1) SUPPORT *****

@singleton
class wakeup_X1(object):                                # Support wakeup on low-high edge on pin X1
    def __init__(self):
        self.disable()
        self.pin = pyb.Pin.board.X1                     # Don't configure pin unless user accesses wkup
                                                        # On the Espruino Pico change X1 to A0 (issue #1)
        self.pin_configured = False

    def _pinconfig(self):
        if not self.pin_configured:
            self.pin.init(mode = pyb.Pin.IN, pull = pyb.Pin.PULL_DOWN)
            self.pin_configured = True

    def enable(self):                                   # In this mode pin has pulldown enabled
        stm.mem32[stm.PWR + stm.PWR_CR] |= 4            # set CWUF to clear WUF in PWR_CSR
        stm.mem32[stm.PWR + stm.PWR_CSR] |= 0x100       # Enable wakeup

    def disable(self):
{'fraction_non_alphanumeric': 0.10907898571844943, 'fraction_numerical': 0.030166132322937918, 'mean_word_length': 1.9817510319356941, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2513436', 'n_tokens_mistral': 4928, 'n_tokens_neox': 4463, 'n_words': 1263}