Beispiel #1
0
def main():
    '''
    SPI demo for ece49022 skills assessment

    SCK  => Pin 25 => A1
    CS   => Pin 26 => A0
    MOSI => Pin 13 => 13
    MISO => Pin 12 => 12
    '''

    message = ['a', 'b', 'c']

    spi = SPI(-1,
              sck=Pin(25),
              mosi=Pin(13),
              miso=Pin(12),
              polarity=1,
              phase=0,
              bits=8,
              firstbit=SPI.MSB)

    chip_select = Pin(26, Pin.OUT, 1)

    # baud rate, polarity, phase, bits, firstbit
    spi.init(baudrate=1_000_000)

    sleep(1)

    for char in message:
        print(char)
        chip_select.off()
        spi.write(bytes(char, 'utf-8'))
        chip_select.on()

    sleep(5)
    def get_spi(self):
        spi = None
        spi_id = 1

        spi = SPI(spi_id, baudrate=10000000, polarity=0, phase=0)
        spi.init()
        return spi
Beispiel #3
0
class Lcd:
    """Display control Nokia 5110"""
    def __init__(self, spi=1, cs=2, dc=15, rst=0, bl=12):
        self.spi = SPI(spi)
        self.cs = Pin(cs)
        self.dc = Pin(dc)
        self.rst = Pin(rst)
        self.bl = bl

        self.spi.init(baudrate=2000000, polarity=0, phase=0)
        self.lcd = pcd8544.PCD8544_FRAMEBUF(self.spi, self.cs, self.dc, self.rst)

    def light(self, status):
        if status == 'on':
            # backlight on
            Pin(self.bl, Pin.OUT, value=0)
        elif status == 'off':
            # backlight off
            Pin(self.bl, Pin.OUT, value=1)

    def text(self, line1='', line2='', line3='', line4='', line5=''):
        # Can show five line of text
        # text(string, x, y, color)
        self.clear()
        self.lcd.text(line1, 0, 0, 1)
        self.lcd.text(line2, 0, 10, 1)
        self.lcd.text(line3, 0, 20, 1)
        self.lcd.text(line4, 0, 30, 1)
        self.lcd.text(line5, 0, 40, 1)
        self.lcd.show()

    def clear(self):
        self.lcd.fill(0)
        self.lcd.show()
Beispiel #4
0
    def __init__(self):
        print("Building EPD:")
        # Load modules and set constants
        from display import epd42b as epaper
        from machine import SPI, Pin

        # Initializes SPI
        spi = SPI(1)
        spi.init(baudrate=2000000,
                 polarity=0,
                 phase=0,
                 sck=Pin(pins.SCK),
                 mosi=Pin(pins.MOSI),
                 miso=Pin(pins.MISO))
        cs = Pin(pins.CS)
        dc = Pin(pins.DC)
        rst = Pin(pins.RST)
        busy = Pin(pins.BUSY)
        print("\tSPI - [ OK ]")

        # Create EPD epaper driver
        epd = epaper.EPD(spi, cs, dc, rst, busy)
        self.dim = Vect(epd.width, epd.height)
        self.ofs = Vect(0, 0)
        print("\tEPD - [ OK ]")

        self.fb = (Fb(BLACK, epd), Fb(YELLOW, epd))
Beispiel #5
0
class SPI(Lockable):
    def __init__(self, clock, MOSI=None, MISO=None):
        from machine import SPI

        self._spi = SPI(-1)
        self._pins = (clock, MOSI, MISO)

    def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
        from machine import SPI, Pin

        if self._locked:
            # TODO verify if _spi obj 'caches' sck, mosi, miso to avoid storing in _attributeIds (duplicated in busio)
            # i.e. #init ignores MOSI=None rather than unsetting
            self._spi.init(
                baudrate=baudrate,
                polarity=polarity,
                phase=phase,
                bits=bits,
                firstbit=SPI.MSB,
                sck=Pin(self._pins[0].id),
                mosi=Pin(self._pins[1].id),
                miso=Pin(self._pins[2].id),
            )
        else:
            raise RuntimeError("First call try_lock()")

    def write(self, buf):
        return self._spi.write(buf)

    def readinto(self, buf):
        return self.readinto(buf)

    def write_readinto(self, buffer_out, buffer_in):
        return self.write_readinto(buffer_out, buffer_in)
    def get_spi(self):

        if config.CONFIG.SOFT_SPI:
            spi_id = -1
        else:
            spi_id = 1

        try:
            spi = SPI(spi_id,
                      baudrate=10000000,
                      polarity=0,
                      phase=0,
                      bits=8,
                      firstbit=SPI.MSB,
                      sck=Pin(self.LORA_SCK, Pin.OUT, Pin.PULL_DOWN),
                      mosi=Pin(self.LORA_MOSI, Pin.OUT, Pin.PULL_UP),
                      miso=Pin(self.LORA_MISO, Pin.IN, Pin.PULL_UP))
            spi.init()

        except Exception as e:
            print(e)
            if spi:
                spi.deinit()
            reset()  # in case SPI is already in use, need to reset.
            raise

        return spi
Beispiel #7
0
    def get_spi(self):
        spi = None
        id = 1

        try:
            if config_sensorboard.SOFT_SPI: id = 1  #LoBo id = -1
            #spi = SPI(id, baudrate = 10000000, polarity = 0, phase = 0, bits = 8, firstbit = SPI.MSB,
            # LoBo
            spi = SPI(id,
                      baudrate=10000000,
                      polarity=0,
                      phase=0,
                      bits=8,
                      firstbit=SPI.MSB,
                      sck=Pin(self.PIN_ID_SCK, Pin.OUT, Pin.PULL_DOWN),
                      mosi=Pin(self.PIN_ID_MOSI, Pin.OUT, Pin.PULL_UP),
                      miso=Pin(self.PIN_ID_MISO, Pin.IN, Pin.PULL_UP))
            spi.init()

        except Exception as e:
            print(e)
            if spi:
                spi.deinit()
                spi = None
            reset()  # in case SPI is already in use, need to reset.

        return spi
    def get_spi(self):
        spi = None
        id = 1

        if config_lora.IS_ESP8266:
            spi = SPI(id, baudrate=10000000, polarity=0, phase=0)
            spi.init()

        if config_lora.IS_ESP32:
            try:
                if config_lora.SOFT_SPI: id = -1  #soft spi
                else: id = 1  #hardware spi
                spi = SPI(id,
                          baudrate=10000000,
                          polarity=0,
                          phase=0,
                          bits=8,
                          firstbit=SPI.MSB,
                          sck=Pin(self.PIN_ID_SCK, Pin.OUT, Pin.PULL_DOWN),
                          mosi=Pin(self.PIN_ID_MOSI, Pin.OUT, Pin.PULL_UP),
                          miso=Pin(self.PIN_ID_MISO, Pin.IN, Pin.PULL_UP))
                spi.init()

            except Exception as e:
                print(e)
                if spi:
                    spi.deinit()
                    spi = None
                reset()  # in case SPI is already in use, need to reset.

        return spi
def __init__:
	sckPin = Pin(18)
	mosiPin = Pin(23)
	misoPin = Pin(19)

	spi = SPI(1, baudrate=328125, bits=8, polarity=0, phase=1, sck=sckPin, mosi=mosiPin, miso=misoPin)
	spi.init()

	cs = Pin(2)
	dc = Pin(15)
	rst = Pin(0)

	# backlight on
	bl = Pin(12, Pin.OUT, value=1)

	lcd = pcd8544.PCD8544(spi, cs, dc, rst)
	lcd.contrast(0x3c, pcd8544.BIAS_1_40, pcd8544.TEMP_COEFF_0)
	lcd.reset()
	lcd.init()
	lcd.clear()


	buffer = bytearray((lcd.height // 8) * lcd.width)
	framebuf = framebuf.FrameBuffer1(buffer, lcd.width, lcd.height)

	framebuf.fill(0)
	lcd.data(buffer)
Beispiel #10
0
def init_SD():
    spi = SPI(2, baudrate = 10000000, polarity = 0, phase = 0, bits = 8, firstbit = SPI.MSB,
        sck = Pin(18, Pin.OUT, Pin.PULL_DOWN),
        mosi = Pin(23, Pin.OUT, Pin.PULL_UP),
        miso = Pin(19, Pin.IN, Pin.PULL_UP))

    spi.init()  # Ensure right baudrate
    sd = sdcard.SDCard(spi, Pin(22))  # Compatible with PCB
    return sd
Beispiel #11
0
def setup(hardware_spi=True):
    if hardware_spi:
        spi = SPI(2)
        spi.init(baudrate=2000000, polarity=0, phase=0)
        lcd = HX1230_FB_SPI(spi, cs, rst)
    else:
        mosi = Pin('B15', Pin.OUT)
        sck = Pin('B13', Pin.OUT)
        lcd = HX1230_FB_BBSPI(mosi, sck, cs, rst)
    return lcd
Beispiel #12
0
class Px(object):
    '''init with n pixels, set color'''
    def __init__(self, count=16, clk=14, data=13):  # 14:D5, 13:D7
        self.spi = None
        # NOTE miso not used but still required by SPI(), so watch out when using D6 a.k.a. Pin(12)
        self.spi = SPI(-1,
                       baudrate=100000,
                       polarity=1,
                       phase=0,
                       sck=Pin(clk),
                       mosi=Pin(data),
                       miso=Pin(12))
        self.spi.init()
        self.count = count  # number of LEDs per strip
        self.pixels = [[128, 128, 128]] * count  # list of GRB-lists
        self.latch = (
            count + 31
        ) // 32  # LPD8806 quirk; requires extra latch 0 for every 32 LEDs
        self.show()

    def one(self, n, r, g,
            b):  # Nth led: red, green, and blue 7-bit values (0-127)
        if n >= self.count:
            return
        clr = [128, 128, 128]
        # GRB
        clr[0] |= g & 0xff
        clr[1] |= r & 0xff
        clr[2] |= b & 0xff
        self.pixels[n] = clr
        self.show()

    def all(self, r, g, b):
        self.pixels = [[128 | (g & 0xff), 128 | (r & 0xff), 128 |
                        (b & 0xff)]] * self.count
        self.show()

    def clear(self):
        self.pixels = [[128, 128, 128]] * self.count
        self.show()

    def show(self):  # draw entire strip
        flat = sum(self.pixels, [])
        for _ in range(0, self.latch):
            flat.append(0)
        bts = bytes(flat)
        self.spi.write(bts)  # flatten -> convert to bytes -> write SPI
Beispiel #13
0
def do_write():

    spi = SPI(1, baudrate=2500000, polarity=0, phase=0)
    spi.init()
    rdr = mfrc522.MFRC522(spi=spi, gpioRst=0, gpioCs=2)

    print("")
    print("Place card before reader to write address 0x08")
    print("")

    try:
        while True:

            (stat, tag_type) = rdr.request(rdr.REQIDL)

            if stat == rdr.OK:

                (stat, raw_uid) = rdr.anticoll()

                if stat == rdr.OK:
                    print("New card detected")
                    print("  - tag type: 0x%02x" % tag_type)
                    print("  - uid	 : 0x%02x%02x%02x%02x" %
                          (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]))
                    print("")

                    if rdr.select_tag(raw_uid) == rdr.OK:

                        key = b'\xff\xff\xff\xff\xff\xff'

                        if rdr.auth(rdr.AUTHENT1A, 8, key, raw_uid) == rdr.OK:
                            stat = rdr.write(
                                8,
                                b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
                            )
                            rdr.stop_crypto1()
                            if stat == rdr.OK:
                                print("Data written to card")
                            else:
                                print("Failed to write data to card")
                        else:
                            print("Authentication error")
                    else:
                        print("Failed to select tag")

    except KeyboardInterrupt:
        print("Bye")
Beispiel #14
0
def init():
    global lcd
    global bl
    spi = SPI(1)
    spi.init(baudrate=2000000, polarity=0, phase=0)
    cs = Pin(2)
    dc = Pin(15)
    rst = Pin(0)

    # backlight on
    bl = Pin(12, Pin.OUT, value=1)

    lcd = pcd8544.PCD8544(spi, cs, dc, rst)

    lcd.init()
    print('LCD init')
    lcd.contrast(50)
Beispiel #15
0
def do_read():
    spi = SPI(1, baudrate=2500000, polarity=0, phase=0)
    spi.init()
    rdr = mfrc522.MFRC522(spi=spi, gpioRst=0, gpioCs=2)

    while True:
        print("Place card")

        (stat, tag_type) = rdr.request(rdr.REQIDL)

        if stat == rdr.OK:

            (stat, raw_uid) = rdr.anticoll()

            if stat == rdr.OK:
                print("Detected")
                print("type: 0x%02x" % tag_type)
                print("uid: 0x%02x%02x%02x%02x" %
                      (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]))
                print("")

                if rdr.select_tag(raw_uid) == rdr.OK:

                    key = b'\xff\xff\xff\xff\xff\xff'

                    ms = ticks_ms()

                    blockArray = bytearray(16)
                    for sector in range(1, 64):
                        if rdr.auth(rdr.AUTHENT1A, sector, key,
                                    raw_uid) == rdr.OK:
                            rdr.read(sector, into=blockArray)
                            print("data@%d: %s" % (sector, blockArray))
                        else:
                            print("Auth err")
                    rdr.stop_crypto1()

                    print("Read in " + str(ticks_ms() - ms))  # took 4594 ms

                else:
                    print("Select failed")
Beispiel #16
0
class SPIBus(object):
  """SPI bus access."""

  def __init__(self, freq, sc, mo, mi=None, spidev=2):
    self._spi = SPI(spidev)
    if mi == None:
      self._spi.init(baudrate=freq, sck=Pin(sc), mosi=Pin(mo))
    else:
      self._spi.init(baudrate=freq, sck=Pin(sc), mosi=Pin(mo), miso=Pin(mi))

  def deinit(self):
    self._spi.deinit()

  @property
  def bus(self):
    return self._spi

  def write_readinto(self, wbuf, rbuf):
    self._spi.write_readinto(wbuf, rbuf)

  def write(self, wbuf):
    self._spi.write(wbuf)
Beispiel #17
0
class ST7735R(GFX_):
    """"""

    # ----------------------------------------------------------------------
    def __init__(self,
                 dc,
                 cs,
                 rst,
                 sclk,
                 mosi,
                 miso,
                 size=(128, 128),
                 offset=(0, 3)):
        """"""

        self.spi = SPI(2)
        self.spi.init(mosi=Pin(mosi),
                      sck=Pin(sclk),
                      miso=Pin(miso),
                      baudrate=32000000)
        self.display = ST7735R_(self.spi,
                                dc=Pin(dc),
                                cs=Pin(cs),
                                rst=Pin(rst),
                                width=size[0],
                                height=size[1],
                                ofx=offset[0],
                                ofy=offset[1])

        super().__init__(self.display.pixel, size)

    # ----------------------------------------------------------------------
    def close(self):
        """"""

        self.spi.deinit()
Beispiel #18
0
class LCD5110:
    def __init__(self, spi=0, cs=5, dc=4, rst=8, bl=28):
        self.spi = SPI(spi)
        self.spi.init(baudrate=2000000, polarity=0, phase=0)
        self.cs = Pin(cs)
        self.dc = Pin(dc)
        self.rst = Pin(rst)
        self.bl = Pin(bl, Pin.OUT, value=1)
        self.lcd = pcd8544_fb.PCD8544_FB(self.spi, self.cs, self.dc, self.rst)

        self.buffer = bytearray((pcd8544_fb.HEIGHT // 8) * pcd8544_fb.WIDTH)

        self.framebuf = framebuf.FrameBuffer(self.buffer, pcd8544_fb.WIDTH,
                                             pcd8544_fb.HEIGHT,
                                             framebuf.MONO_VLSB)
        self.HEIGHT = pcd8544_fb.HEIGHT
        self.WIDTH = pcd8544_fb.WIDTH
        self.clear()

    def clear(self):
        # clear
        self.framebuf.fill(0)
        self.update()

    def text(self, string, x, y, color, update=False):
        self.framebuf.text(string, x, y, color)
        if update:
            self.update()

    def fill_rect(self, x, y, w, h, c, update=False):
        self.framebuf.fill_rect(x, y, w, h, c)
        if update:
            self.update()

    def update(self):
        self.lcd.data(self.buffer)
class DotStar:
    """
    A sequence of APA102 (dotstar) LEDs.

    :param ~microcontroller.Pin clock: The pin to output dotstar clock on.
    :param ~microcontroller.Pin data: The pin to output dotstar data on.
    :param int n: The number of dotstars in the chain
    :param float brightness: Brightness of the pixels between 0.0 and 1.0
    :param bool auto_write: True if the dotstars should immediately change when
        set. If False, `show` must be called explicitly.
    :param tuple pixel_order: Set the pixel order on the strip - different
         strips implement this differently. If you send red, and it looks blue
         or green on the strip, modify this! It should be one of the values above


    Example for ESP32:

    .. code-block:: python

        import generic_dotstar
        import time
        from board import *

        RED = 0x100000

        with generic_dotstar.DotStar(APA102_SCK, APA102_MOSI, 1) as pixels:
            pixels[0] = RED
            time.sleep(2)
    """
    def __init__(self,
                 clock,
                 data,
                 n,
                 *,
                 brightness=1.0,
                 auto_write=True,
                 pixel_order=BGR,
                 baudrate=1000000,
                 spi_bus=1,
                 apa102_cmp=False,
                 spip=None):

        self._spi = None
        try:
            if spip:
                self._spi = spip
            else:
                self._spi = SPI(spi_bus)
                self._spi.init(sck=clock, mosi=data, baudrate=baudrate)
        except (NotImplementedError, ValueError):
            if self._spi:
                self._spi.deinit()
            self.dpin = data
            self.cpin = clock
            self.dpin.mode(Pin.OUT)
            self.cpin.mode(Pin.OUT)
            self.cpin.value = False
        self._n = n
        # Supply one extra clock cycle for each two pixels in the strip.
        self.end_header_size = n // 16
        if n % 16 != 0:
            self.end_header_size += 1
        self._buf = bytearray(n * 4 + START_HEADER_SIZE + self.end_header_size)
        self.end_header_index = len(self._buf) - self.end_header_size
        self.pixel_order = pixel_order
        # Four empty bytes to start.
        for i in range(START_HEADER_SIZE):
            self._buf[i] = 0x00
        # Mark the beginnings of each pixel.
        for i in range(START_HEADER_SIZE, self.end_header_index, 4):
            self._buf[i] = 0xff
        # 0xff bytes at the end.
        for i in range(self.end_header_index, len(self._buf)):
            self._buf[i] = 0xff
        self._brightness = 1.0
        # Set auto_write to False temporarily so brightness setter does _not_
        # call show() while in __init__.
        self.auto_write = False
        self.brightness = brightness
        self.auto_write = auto_write
        self.apa102_cmp = apa102_cmp
        if self.apa102_cmp:
            self.auto_write = False

    def deinit(self):
        """Blank out the DotStars and release the resources."""
        self.auto_write = False
        for i in range(START_HEADER_SIZE, self.end_header_index):
            if i % 4 != 0:
                self._buf[i] = 0
        self.show()
        if self._spi:
            self._spi.deinit()
        else:
            self.dpin.deinit()
            self.cpin.deinit()

    def __enter__(self):
        return self

    def __exit__(self, exception_type, exception_value, traceback):
        self.deinit()

    def __repr__(self):
        return "[" + ", ".join([str(x) for x in self]) + "]"

    def _set_item(self, index, value):
        """
        value can be one of three things:
                a (r,g,b) list/tuple
                a (r,g,b, brightness) list/tuple
                a single, longer int that contains RGB values, like 0xFFFFFF
            brightness, if specified should be a float 0-1, or an int 0-31

        Set a pixel value. You can set per-pixel brightness here, if it's not passed it
        will use the max value for pixel brightness value, which is a good default.

        Important notes about the per-pixel brightness - it's accomplished by
        PWMing the entire output of the LED, and that PWM is at a much
        slower clock than the rest of the LEDs. This can cause problems in
        Persistence of Vision Applications
        """

        offset = (index * 4) + START_HEADER_SIZE
        rgb = value
        if isinstance(value, int):
            rgb = (value >> 16, (value >> 8) & 0xff, value & 0xff)

        if len(rgb) == 4:
            brightness = value[3]
            # Ignore value[3] below.
        else:
            brightness = 1.0

        # LED startframe is three "1" bits, followed by 5 brightness bits
        # then 8 bits for each of R, G, and B. The order of those 3 are configurable and
        # vary based on hardware
        # same as math.ceil(brightness * 31) & 0b00011111
        # Idea from https://www.codeproject.com/Tips/700780/Fast-floor-ceiling-functions
        if type(brightness) is float:
            if brightness > 1.0 or brightness < 0.0:
                raise ValueError(
                    "brightness must be float between 0.0 and 1.0")
        elif type(brightness) is int:
            if brightness > 31 or brightness < 0:
                raise ValueError("brightness must be int between 0 and 31")
            brightness = brightness / 31  # convert to float

        brightness_byte = 32 - int(32 - brightness * 31) & 0b00011111
        self._buf[offset] = brightness_byte | LED_START
        self._buf[offset + 1] = rgb[self.pixel_order[0]]
        self._buf[offset + 2] = rgb[self.pixel_order[1]]
        self._buf[offset + 3] = rgb[self.pixel_order[2]]

    @staticmethod
    def _indices_workaound(myslice, myint):
        """Implementation of slice.indices() for workaround"""
        start = 0 if myslice.start is None else myslice.start
        stop = myint if myslice.stop is None else myslice.stop
        step = 1 if myslice.step is None else myslice.step
        start = myint + start if start < 0 else start
        stop = myint + stop if stop < 0 else stop
        start = min(max(start, 0), myint)
        stop = min(max(stop, 0), myint)
        return start, stop, step

    def __setitem__(self, index, val):
        if isinstance(index, slice):
            # The line below should work, but did not for me ESP32 Micropython 1.9.4
            # start, stop, step = index.indices(self._n)
            # Workaround
            start, stop, step = self._indices_workaound(index, self._n)
            # End Workaround
            length = stop - start
            if step != 0:
                # same as math.ceil(length / step)
                # Idea from https://fizzbuzzer.com/implement-a-ceil-function/
                length = (length + step - 1) // step
            if len(val) != length:
                raise ValueError(
                    "Slice {} and input sequence size {} do not match.".format(
                        length, len(val)))
            for val_i, in_i in enumerate(range(start, stop, step)):
                self._set_item(in_i, val[val_i])
        else:
            self._set_item(index, val)

        if self.auto_write:
            self.show()

    def __getitem__(self, index):
        if isinstance(index, slice):
            out = []
            # The line below should work, but did not for me: ESP32 Micropython 1.9.4
            # for in_i in range(*index.indices(self._n)):
            # Workaround
            for in_i in range(*self._indices_workaound(index, self._n)):
                if self.apa102_cmp:
                    offset = in_i * 4
                    out.append(
                        tuple([
                            self._buf[offset + 3 + START_HEADER_SIZE],
                            self._buf[offset + 2 + START_HEADER_SIZE],
                            self._buf[offset + 1 + START_HEADER_SIZE],
                            self._buf[offset + START_HEADER_SIZE] & 0b00011111
                        ]))
                else:
                    out.append(
                        tuple(self._buf[(in_i * 4) + (3 - i) +
                                        START_HEADER_SIZE] for i in range(3)))
            return out
        if index < 0:
            index += len(self)
        if index >= self._n or index < 0:
            raise IndexError
        offset = index * 4
        if self.apa102_cmp:
            return tuple([
                self._buf[offset + 3 + START_HEADER_SIZE],
                self._buf[offset + 2 + START_HEADER_SIZE],
                self._buf[offset + 1 + START_HEADER_SIZE],
                self._buf[offset + START_HEADER_SIZE] & 0b00011111
            ])
        else:
            return tuple(self._buf[offset + (3 - i) + START_HEADER_SIZE]
                         for i in range(3))

    def __len__(self):
        return self._n

    @property
    def brightness(self):
        """Overall brightness of the pixel"""
        return self._brightness

    @brightness.setter
    def brightness(self, brightness):
        self._brightness = min(max(brightness, 0.0), 1.0)
        if self.auto_write:
            self.show()

    def fill(self, color):
        """Colors all pixels the given ***color***."""
        auto_write = self.auto_write
        self.auto_write = False
        for i in range(self._n):
            self[i] = color
        if auto_write:
            self.show()
        self.auto_write = auto_write

    def _ds_writebytes(self, buf):
        for b in buf:
            for _ in range(8):
                self.cpin.value = True
                self.dpin.value = (b & 0x80)
                self.cpin.value = False
                b = b << 1

    def show(self):
        """Shows the new colors on the pixels themselves if they haven't already
        been autowritten.

        The colors may or may not be showing after this function returns because
        it may be done asynchronously."""
        # Create a second output buffer if we need to compute brightness
        buf = self._buf
        if self.brightness < 1.0:
            buf = bytearray(self._buf)
            # Four empty bytes to start.
            for i in range(START_HEADER_SIZE):
                buf[i] = 0x00
            for i in range(START_HEADER_SIZE, self.end_header_index):
                buf[i] = self._buf[i] if i % 4 == 0 else int(self._buf[i] *
                                                             self._brightness)
            # Four 0xff bytes at the end.
            for i in range(self.end_header_index, len(buf)):
                buf[i] = 0xff

        if self._spi:
            self._spi.write(buf)
        else:
            self._ds_writebytes(buf)
            self.cpin.value = False

    # Added for compatibility with esp8266 apa102
    def write(self):
        self.show()
Beispiel #20
0
class RADIO:
    def __init__(
            self,
            mode=LORA,  # 0 - LoRa, 1 - FSK, 2 - OOK
            pars={
                'freq_kHz': 434000,  # kHz
                'freq_Hz': 0,  # Hz
                'power': 10,  # 2...17 dBm
                'crc': True,  # CRC on/off
                # LoRa mode:
                'bw': 125,  # BW: 7.8...500 kHz
                'sf': 10,  # SF: 6..12
                'cr': 5,  # CR: 5...8
                'ldro': None,  # Low Data Rate Optimize (None - automatic)
                'sw': 0x12,  # Sync Word (allways 0x12)
                'preamble': 8,  # 6...65535
                'implicit_header': False,
                # FSK/OOK mode:
                'bitrate': 4800.,  # bit/s
                'fdev': 5000.,  # frequency deviation [Hz]
                'rx_bw': 10.4,  # 2.6...250 kHz
                'afc_bw': 2.6,  # 2.6...250 kHz
                'afc': False,  # AFC on/off
                'fixed': False,  # fixed packet size or variable
                'dcfree': 0
            },  # 0=None, 1=Manchester or 2=Whitening
            gpio={
                'led': 2,  # blue LED GPIO number on board
                'reset': 5,  # reset pin from GPIO5 (or may be None)
                'dio0': 4,  # DIO0 line to GPIO4
                'cs': 15,  # SPI CS
                'sck': 14,  # SPI SCK
                'mosi': 13,  # SPI MOSI
                'miso': 12
            },  # SPI MISO
            spi_hardware=True,
            spi_baudrate=None,
            onReceive=None):  # receive callback

        # init GPIO
        self.pin_led = Pin(gpio['led'], Pin.OUT)
        self.led(0)  # LED off
        if gpio['reset'] != None:
            self.pin_reset = Pin(gpio['reset'], Pin.OUT, Pin.PULL_UP)
            self.pin_reset.value(1)
        else:
            self.pin_reset = None
        self.pin_dio0 = Pin(gpio['dio0'], Pin.IN, Pin.PULL_UP)
        self.pin_cs = Pin(gpio['cs'], Pin.OUT, Pin.PULL_UP)
        self.pin_cs.value(1)

        # init SPI
        if spi_hardware:
            if spi_baudrate == None: spi_baudrate = 5000000  # 5MHz
            if ESP32:
                self.spi = SPI(1,
                               baudrate=spi_baudrate,
                               polarity=0,
                               phase=0,
                               sck=Pin(14),
                               mosi=Pin(13),
                               miso=Pin(12))
            else:
                self.spi = SPI(1, baudrate=spi_baudrate, polarity=0, phase=0)
        else:
            if spi_baudrate == None: spi_baudrate = 500000  # 500kHz
            self.spi = SPI(-1,
                           baudrate=spi_baudrate,
                           polarity=0,
                           phase=0,
                           sck=Pin(gpio['sck']),
                           mosi=Pin(gpio['mosi']),
                           miso=Pin(gpio['miso']))
            #bits=8, firstbit=SPI.MSB, # FIXME
            #sck=Pin(gpio['sck'], Pin.OUT, Pin.PULL_DOWN),
            #mosi=Pin(gpio['mosi'], Pin.OUT, Pin.PULL_UP),
            #miso=Pin(gpio['miso'], Pin.IN, Pin.PULL_UP))
        self.spi.init()
        self.onReceive(onReceive)
        #self._lock = False
        self.reset()
        self._mode = 0  # LoRa mode by default
        self.init(mode, pars)

    def __exit__(self):
        self.pin_dio0.irq(trigger=0, handler=None)
        self.spi.close()

    def spiTransfer(self, address, value=0x00):
        response = bytearray(1)
        self.pin_cs.value(0)
        self.spi.write(bytes([address]))
        self.spi.write_readinto(bytes([value]), response)
        self.pin_cs.value(1)
        return response

    def readReg(self, address, byteorder='big', signed=False):
        """read 8-bit register by SPI"""
        response = self.spiTransfer(address & 0x7F)
        return int.from_bytes(response, byteorder)

    def writeReg(self, address, value):
        """write 8-bit register by SPI"""
        self.spiTransfer(address | 0x80, value)

    def led(self, on=True):
        """on/off LED on GPIO pin"""
        self.pin_led.value(not LED_ON ^ on)

    def blink(self, times=1, on_ms=100, off_ms=20):
        """short blink LED on GPIO pin"""
        for i in range(times):
            self.led(1)
            sleep_ms(on_ms)
            self.led(0)
            sleep_ms(off_ms)

    def reset(self, low_ms=100, high_ms=100, times=1):
        """hard reset SX127x chip"""
        if self.pin_reset:
            for i in range(times):
                self.pin_reset.value(1)
                sleep_ms(high_ms)
                self.pin_reset.value(0)
                sleep_ms(low_ms)
                self.pin_reset.value(1)
                sleep_ms(high_ms)

    def version(self):
        """get SX127x crystal revision"""
        return self.readReg(REG_VERSION)

    def setMode(self, mode):
        """set mode"""
        self.writeReg(REG_OP_MODE,
                      (self.readReg(REG_OP_MODE) & ~MODES_MASK) | mode)

    def getMode(self):
        """get mode"""
        return self.readReg(REG_OP_MODE) & MODES_MASK

    def lora(self, lora=True):
        """switch to LoRa mode"""
        mode = self.readReg(REG_OP_MODE)  # read mode
        sleep = (mode & ~MODES_MASK) | MODE_SLEEP
        self.writeReg(REG_OP_MODE, sleep)  # go to sleep
        if lora:
            sleep |= MODE_LONG_RANGE
            mode |= MODE_LONG_RANGE
        else:
            sleep &= ~MODE_LONG_RANGE
            mode &= ~MODE_LONG_RANGE
        self.writeReg(REG_OP_MODE, sleep)  # write "long range" bit
        self.writeReg(REG_OP_MODE, mode)  # restore old mode

    def isLora(self):
        """check LoRa (or FSK/OOK) mode"""
        mode = self.readReg(REG_OP_MODE)  # read mode
        return True if (mode & MODE_LONG_RANGE) else False

    def fsk(self, fsk=True):
        """switch to FSK mode"""
        self.lora(not fsk)
        if fsk:
            self.writeReg(REG_OP_MODE,
                          (self.readReg(REG_OP_MODE) & ~MODES_MASK2)
                          | MODE_FSK)

    def ook(self, ook=True):
        """switch to OOK mode"""
        self.lora(not ook)
        if ook:
            self.writeReg(REG_OP_MODE,
                          (self.readReg(REG_OP_MODE) & ~MODES_MASK2)
                          | MODE_OOK)

    def sleep(self):
        """switch to Sleep Mode:"""
        self.setMode(MODE_SLEEP)

    def standby(self):
        """switch ro Standby mode"""
        self.setMode(MODE_STDBY)

    def tx(self, on=True):
        """on/off TX mode (off = standby)"""
        if on: self.setMode(MODE_TX)
        else: self.setMode(MODE_STDBY)

    def rx(self, on=True):
        """on/off RX (continuous) mode (off = standby)"""
        if on: self.setMode(MODE_RX_CONTINUOUS)
        else: self.setMode(MODE_STDBY)

    def cad(self, on=True):
        """on/off CAD (LoRa) mode (off = standby)"""
        if self._mode == 0:  # LoRa mode
            if on: self.setMode(MODE_CAD)
            else: self.setMode(MODE_STDBY)

    def init(self, mode=None, pars=None):
        """init chip"""
        if mode is not None: self._mode = mode
        if pars: self._pars = pars

        # check version
        version = self.version()
        print("SX127x selicon revision = 0x%02X" % version)
        if version != 0x12:
            raise Exception('Invalid SX127x selicon revision')

        # switch mode
        if self._mode == 1: self.fsk()  # FSK
        elif self._mode == 2: self.ook()  # OOK
        else: self.lora()  # LoRa

        # set RF frequency
        self.setFrequency(self._pars['freq_kHz'], self._pars['freq_Hz'])

        # set LNA boost: `LnaBoostHf`->3 (Boost on, 150% LNA current)
        self.setLnaBoost(True)

        # set output power level
        self.setPower(self._pars['power'])

        # enable/disable CRC
        self.enableCRC(self._pars["crc"])

        if self._mode == 0:
            # set LoRaTM options
            self.setBW(self._pars['bw'])
            self._implicitHeaderMode = None
            self.setImplicitHeaderMode(self._pars['implicit_header'])
            sf = self._pars['sf']
            self.setSF(sf)
            ldro = self._pars['ldro']
            if ldro == None:
                ldro = True if sf >= 10 else False  # FIXME
            self.setLDRO(ldro)
            self.setCR(self._pars['cr'])
            self.setPreamble(self._pars['preamble'])
            self.setSW(self._pars['sw'])

            # set AGC auto on (internal AGC loop)
            self.writeReg(REG_MODEM_CONFIG_3,
                          self.readReg(REG_MODEM_CONFIG_3)
                          | 0x04)  # `AgcAutoOn`

            # set base addresses
            self.writeReg(REG_FIFO_TX_BASE_ADDR, FIFO_TX_BASE_ADDR)
            self.writeReg(REG_FIFO_RX_BASE_ADDR, FIFO_RX_BASE_ADDR)

            # set DIO0 mapping (`RxDone`)
            self.writeReg(REG_DIO_MAPPING_1, 0x00)
        else:
            # set FSK/OOK options
            self.continuous(False)  # packet mode by default
            self.setBitrate(self._pars["bitrate"])
            self.setFdev(self._pars["fdev"])
            self.setRxBW(self._pars["rx_bw"])
            self.setAfcBW(self._pars["afc_bw"])
            self._fixedLen = None
            self.setFixedLen(self._pars["fixed"])
            self.enableAFC(self._pars["afc"])
            self.setDcFree(self._pars["dcfree"])

            self.writeReg(REG_RSSI_TRESH, 0xFF)  # default
            self.writeReg(REG_PREAMBLE_LSB, 8)  # 3 by default

            self.writeReg(REG_SYNC_VALUE_1, 0x69)  # 0x01 by default
            self.writeReg(REG_SYNC_VALUE_2, 0x81)  # 0x01 by default
            self.writeReg(REG_SYNC_VALUE_3, 0x7E)  # 0x01 by default
            self.writeReg(REG_SYNC_VALUE_4, 0x96)  # 0x01 by default

            # set `DataMode` to Packet (and reset PayloadLength(10:8) to 0)
            self.writeReg(REG_PACKET_CONFIG_2, 0x40)

            # set TX start FIFO condition
            self.writeReg(REG_FIFO_THRESH, TX_START_FIFO_NOEMPTY)

            # set DIO0 mapping (by default):
            #    in RxContin - `SyncAddres`
            #    in TxContin - `TxReady`
            #    in RxPacket - `PayloadReady` <- used signal
            #    in TxPacket - `PacketSent`
            self.writeReg(REG_DIO_MAPPING_1, 0x00)

            # RSSI and IQ callibrate
            self.rxCalibrate()

        self.standby()

    def setFrequency(self, freq_kHz, freq_Hz=0):
        """set RF frequency [kHz * 1000 + Hz]"""
        self._freq = int(freq_kHz) * 1000 + freq_Hz  # kHz + Hz -> Hz
        freq_code = int(round(self._freq / FSTEP))
        self.writeReg(REG_FRF_MSB, (freq_code >> 16) & 0xFF)
        self.writeReg(REG_FRF_MID, (freq_code >> 8) & 0xFF)
        self.writeReg(REG_FRF_LSB, freq_code & 0xFF)
        mode = self.readReg(REG_OP_MODE)
        if self._freq < 600000000:  # LF <= 525 < _600_ < 779 <= HF [MHz]
            mode |= MODE_LOW_FREQ_MODE_ON  # LF
        else:
            mode &= ~MODE_LOW_FREQ_MODE_ON  # HF
        self.writeReg(REG_OP_MODE, mode)

    def setPower(self, level, PA_BOOST=True, MaxPower=7):
        """set TX Power level 2...17 dBm, select PA_BOOST pin"""
        MaxPower = min(max(MaxPower, 0), 7)
        if PA_BOOST:
            # Select PA_BOOST pin: Pout is limited to ~17..20 dBm
            # Pout = 17 - (15 - OutputPower) dBm
            OutputPower = min(max(level - 2, 0), 15)
            self.writeReg(REG_PA_CONFIG, PA_SELECT | OutputPower)
        else:
            # Select RFO pin: Pout is limited to ~14..15 dBm
            # Pmax = 10.8 + 0.6 * MaxPower  [dBm]
            # Pout = Pmax - (15 - OutputPower)) = 0...15 dBm if MaxPower=7
            OutputPower = min(max(level, 0), 15)
            self.writeReg(REG_PA_CONFIG, (MaxPower << 4) | OutputPower)

    def setHighPower(self, on=True):
        """set high power on PA_BOOST up to +20 dBm"""
        if on:  # +3dB
            self.writeReg(REG_PA_DAC,
                          0x87)  # power on PA_BOOST pin up to +20 dBm
        else:
            self.writeReg(REG_PA_DAC, 0x84)  # default mode

    def setOCP(self, trim_mA=100., on=True):
        """set trimming of OCP current (45...240 mA)"""
        if trim_mA <= 120.:
            OcpTrim = round((trim_mA - 45.) / 5.)
        else:
            OcpTrim = round((trim_mA + 30.) / 10.)
        OcpTrim = min(max(OcpTrim, 0), 27)
        if on:
            OcpTrim |= 0x20  # `OcpOn`
        self.writeReg(REG_OCP, OcpTrim)

    def setLnaBoost(self, LnaBoost=True):
        """set LNA boost on/off (only for high frequency band)"""
        reg = self.readReg(REG_LNA)
        if LnaBoost:
            reg |= 0x03  # set `LnaBoostHf` to 3 (boost on, 150% LNA current)
        else:
            reg &= ~0x03  # set `LnaBoostHf` to 0 (default LNA current)
        self.writeReg(REG_LNA, reg)

    def setRamp(self, shaping=0, ramp=0x09):
        """set modulation shaping code 0..3 (FSK/OOK) and PA rise/fall time code 0..15 (FSK/Lora)"""
        shaping = min(max(shaping, 0), 3)
        ramp = min(max(ramp, 0), 15)
        reg = self.readReg(REG_PA_RAMP)
        reg = (reg & 0x90) | (shaping << 5) | ramp
        self.writeReg(REG_PA_RAMP, reg)

    def enableCRC(self, crc=True, crcAutoClearOff=True):
        """enable/disable CRC (and set CrcAutoClearOff in FSK/OOK mode)"""
        self._crc = crc
        if self._mode == 0:  # LoRa mode
            reg = self.readReg(REG_MODEM_CONFIG_2)
            reg = (reg | 0x04) if crc else (reg & ~0x04)  # `RxPayloadCrcOn`
            self.writeReg(REG_MODEM_CONFIG_2, reg)
        else:  # FSK/OOK mode
            reg = self.readReg(REG_PACKET_CONFIG_1) & ~0x18
            if crc: reg |= 0x10  # `CrcOn`
            if crcAutoClearOff: reg |= 0x08  # `CrcAutoClearOff`
            self.writeReg(REG_PACKET_CONFIG_1, reg)

    def getRxGain(self):
        """get current RX gain code [1..6] from `RegLna` (1 - maximum gain)"""
        return (self.readReg(REG_LNA) >> 5) & 0x07  # `LnaGain`

    def getPktRSSI(self):
        """get Packet RSSI [dB] (LoRa)"""
        if self._mode == 0:  # LoRa mode
            return self.readReg(REG_PKT_RSSI_VALUE) - \
                   (164. if self._freq < 600000000 else 157.)
        else:  # FSK/OOK mode
            return -0.5 * self.readReg(REG_RSSI_VALUE)

    def getRSSI(self):
        """get RSSI [dB]"""
        if self._mode == 0:  # LoRa mode
            return self.readReg(REG_LR_RSSI_VALUE) - \
                   (164. if self._freq < 600000000 else 157.)
        else:  # FSK/OOK mode
            return -0.5 * self.readReg(REG_RSSI_VALUE)

    def getSNR(self):
        """get SNR [dB] (LoRa)"""
        if self._mode == 0:  # LoRa mode
            snr = self.readReg(REG_PKT_SNR_VALUE)
            if snr & 0x80:  # sign bit is 1
                snr -= 256
            return snr * 0.25
        else:  # FSK/OOK mode
            return 0.

    def getIrqFlags(self):
        """get IRQ flags for debug"""
        if self._mode == 0:  # LoRa mode
            irqFlags = self.readReg(REG_IRQ_FLAGS)
            self.writeReg(REG_IRQ_FLAGS, irqFlags)
            return irqFlags
        else:  # FSK/OOK mode
            irqFlags1 = self.readReg(REG_IRQ_FLAGS_1)
            irqFlags2 = self.readReg(REG_IRQ_FLAGS_2)
            return (irqFlags2 << 8) | irqFlags1

    def enableRxIrq(self, enable=True):
        """enable/disable interrupt by RX done for debug (LoRa)"""
        if self._mode == 0:  # LoRa mode
            reg = self.readReg(REG_IRQ_FLAGS_MASK)
            if enable: reg &= ~IRQ_RX_DONE_MASK
            else: reg |= IRQ_RX_DONE_MASK
            self.writeReg(REG_IRQ_FLAGS_MASK, reg)

    def invertIQ(self, invert=True):
        """invert IQ channels (LoRa)"""
        if self._mode == 0:
            reg = self.readReg(REG_INVERT_IQ)
            if invert:
                reg |= 0x40  # `InvertIq` = 1
            else:
                reg &= ~0x40  # `InvertIq` = 0
            self.writeReg(REG_INVERT_IQ, reg)

    def setSF(self, sf=10):
        """set Spreading Factor 6...12 (LoRa)"""
        if self._mode == 0:
            sf = min(max(sf, 6), 12)
            self.writeReg(REG_DETECT_OPTIMIZE, 0xC5 if sf == 6 else 0xC3)
            self.writeReg(REG_DETECTION_THRESHOLD, 0x0C if sf == 6 else 0x0A)
            self.writeReg(REG_MODEM_CONFIG_2,
                          (self.readReg(REG_MODEM_CONFIG_2) & 0x0F) |
                          ((sf << 4) & 0xF0))

    def setLDRO(self, ldro):
        """set Low Data Rate Optimisation (LoRa)"""
        if self._mode == 0:
            self.writeReg(
                REG_MODEM_CONFIG_3,  # `LowDataRateOptimize`
                (self.readReg(REG_MODEM_CONFIG_3) & ~0x08)
                | 0x08 if ldro else 0)

    def setBW(self, sbw):
        """set signal Band Width 7.8-500 kHz (LoRa)"""
        if self._mode == 0:
            bw = len(BW_TABLE) - 1
            for i in range(bw + 1):
                if sbw <= BW_TABLE[i]:
                    bw = i
                    break
            self.writeReg(REG_MODEM_CONFIG_1, \
                               (self.readReg(REG_MODEM_CONFIG_1) & 0x0F) | (bw << 4))

    def setCR(self, denominator):
        """set Coding Rate [5..8] (LoRa)"""
        if self._mode == 0:
            denominator = min(max(denominator, 5), 8)
            cr = denominator - 4
            self.writeReg(REG_MODEM_CONFIG_1,
                          (self.readReg(REG_MODEM_CONFIG_1) & 0xF1) |
                          (cr << 1))

    def setPreamble(self, length):
        """set preamble length [6...65535] (LoRa)"""
        if self._mode == 0:
            self.writeReg(REG_PREAMBLE_MSB, (length >> 8) & 0xFF)
            self.writeReg(REG_PREAMBLE_LSB, (length) & 0xFF)

    def setSW(self, sw):  # LoRa mode only
        """set Sync Word (LoRa)"""
        if self._mode == 0:
            self.writeReg(REG_SYNC_WORD, sw)

    def setImplicitHeaderMode(self, implicitHeaderMode=True):
        """set ImplicitHeaderModeOn (LoRa)"""
        if self._mode == 0:
            if self._implicitHeaderMode != implicitHeaderMode:  # set value only if different
                self._implicitHeaderMode = implicitHeaderMode
                modem_config_1 = self.readReg(REG_MODEM_CONFIG_1)
                config = modem_config_1 | 0x01 if implicitHeaderMode else \
                         modem_config_1 & 0xFE
                self.writeReg(REG_MODEM_CONFIG_1, config)

    def setBitrate(self, bitrate=4800.):
        """set bitrate [bit/s] (FSK/OOK)"""
        if self._mode == 1:  # FSK
            code = int(round((FXOSC * 16.) / bitrate))  # bit/s -> code/frac
            self.writeReg(REG_BITRATE_MSB, (code >> 12) & 0xFF)
            self.writeReg(REG_BITRATE_LSB, (code >> 4) & 0xFF)
            self.writeReg(REG_BITRATE_FRAC, code & 0x0F)
        elif self._mode == 2:  # OOK
            code = int(round(FXOSC / bitrate))  # bit/s -> code
            self.writeReg(REG_BITRATE_MSB, (code >> 8) & 0xFF)
            self.writeReg(REG_BITRATE_LSB, code & 0xFF)
            self.writeReg(REG_BITRATE_FRAC, 0)

    def setFdev(self, fdev=5000.):
        """set frequency deviation (FSK)"""
        if self._mode:
            code = int(round(fdev / FSTEP))  # Hz -> code
            code = min(max(code, 0), 0x3FFF)
            self.writeReg(REG_FDEV_MSB, (code >> 8) & 0xFF)
            self.writeReg(REG_FDEV_LSB, code & 0xFF)

    def setRxBW(self, bw=10.4):
        """set RX BW [kHz] (FSK/OOK)"""
        if self._mode:
            m, e = getRxBw(bw)
            self.writeReg(REG_RX_BW, (m << 3) | e)

    def setAfcBW(self, bw=2.6):
        """set AFC BW [kHz] (FSK/OOK)"""
        if self._mode:
            m, e = getRxBw(bw)
            self.writeReg(REG_AFC_BW, (m << 3) | e)

    def enableAFC(self, afc=True):
        """enable/disable AFC (FSK/OOK)"""
        if self._mode:
            reg = self.readReg(REG_RX_CONFIG)
            if afc: reg |= 0x10  # bit 4: AfcAutoOn -> 1
            else: reg &= ~0x10  # bit 4: AfcAutoOn -> 0
            self.writeReg(REG_RX_CONFIG, reg)

    def setFixedLen(self, fixed=True):
        """set Fixed or Variable packet mode (FSK/OOK)"""
        if self._mode:
            if self._fixedLen != fixed:  # set value only if different
                self._fixedLen = fixed
                reg = self.readReg(REG_PACKET_CONFIG_1)
                if fixed: reg &= ~0x80  # bit 7: PacketFormat -> 0 (fixed size)
                else: reg |= 0x80  # bit 7: PacketFormat -> 1 (variable size)
                self.writeReg(REG_PACKET_CONFIG_1, reg)

    def setDcFree(self, mode=0):
        """set DcFree mode: 0=Off, 1=Manchester, 2=Whitening (FSK/OOK)"""
        if self._mode:
            reg = self.readReg(REG_PACKET_CONFIG_1)
            reg = (reg & 0x9F) | ((mode & 3) << 5)  # bit 6-5 `DcFree`
            self.writeReg(REG_PACKET_CONFIG_1, reg)

    def continuous(self, on=True):
        """select Continuous mode, must use DIO2->DATA, DIO1->DCLK (FSK/OOK)"""
        if self._mode:
            reg = self.readReg(REG_PACKET_CONFIG_2)
            if on: reg &= ~0x40  # bit 6: `DataMode` 0 -> Continuous mode
            else: reg |= 0x40  # bit 6: `DataMode` 1 -> Packet mode
            self.writeReg(REG_PACKET_CONFIG_2, reg)

    def rxCalibrate(self):
        """RSSI and IQ callibration (FSK/OOK)"""
        if self._mode:
            reg = self.readReg(REG_IMAGE_CAL)
            reg |= 0x40  # `ImageCalStart` bit
            self.writeReg(REG_IMAGE_CAL, reg)
            while (self.readReg(REG_IMAGE_CAL) & 0x20):  # `ImageCalRunning`
                pass  # FIXME: check timeout

    def setPllBW(self, bw=3):
        """set PLL bandwidth 0=75, 1=150, 2=225, 3=300 kHz (LoRa/FSK/OOK)"""
        bw = min(max(bw, 0), 3)
        reg = self.readReg(REG_PLL)
        reg = (reg & 0x3F) | (bw << 6)
        self.writeReg(REG_PLL, reg)

    def setFastHop(self, on=True):
        """on/off fast frequency PLL hopping (FSK/OOK)"""
        if self._mode:
            reg = self.readReg(REG_PLL_HOP)
            reg = reg | 0x80 if on else reg & 0x7F  # `FastHopOn`
            self.writeReg(REG_PLL_HOP, reg)

    #def aquire_lock(self, lock=False):
    #    if not MICROPYTHON: # MicroPython is single threaded, doesn't need lock.
    #        if lock:
    #            while self._lock: pass
    #            self._lock = True
    #        else:
    #            self._lock = False

    def send(self, string, fixed=False):
        """send packet (LoRa/FSK/OOK)"""
        #self.aquire_lock(True)  # wait until RX_Done, lock and begin writing.
        self.setMode(MODE_STDBY)
        buf = string.encode()
        size = len(buf)

        if self._mode == 0:  # LoRa mode
            self.setImplicitHeaderMode(fixed)

            # set FIFO TX base address
            self.writeReg(REG_FIFO_ADDR_PTR, FIFO_TX_BASE_ADDR)

            # check size
            size = min(size, MAX_PKT_LENGTH)

            # write data
            for i in range(size):
                self.writeReg(REG_FIFO, buf[i])

            # set length
            self.writeReg(REG_PAYLOAD_LENGTH, size)

            # start TX packet
            self.setMode(MODE_TX)  # put in TX mode

            # wait for TX done, standby automatically on TX_DONE
            while (self.readReg(REG_IRQ_FLAGS) & IRQ_TX_DONE) == 0:
                pass  # FIXME: check timeout

            # clear IRQ's
            self.writeReg(REG_IRQ_FLAGS, IRQ_TX_DONE)

        else:  # FSK/OOK mode
            self.setFixedLen(fixed)
            size = min(size, MAX_PKT_LENGTH)  # limit size

            # set TX start FIFO condition
            #self.writeReg(REG_FIFO_THRESH, TX_START_FIFO_NOEMPTY)

            # wait while FIFO is no empty
            while ((self.readReg(REG_IRQ_FLAGS_2) & IRQ2_FIFO_EMPTY) == 0):
                pass  # FIXME: check timeout

            if self._fixedLen:
                self.writeReg(REG_PAYLOAD_LEN, size)  # fixed length
                #add = 0
            else:
                self.writeReg(REG_FIFO, size)  # variable length
                #add = 1

            # set TX start FIFO condition
            #self.writeReg(REG_FIFO_THRESH, TX_START_FIFO_LEVEL | (size + add))

            # write data to FIFO
            for i in range(size):
                self.writeReg(REG_FIFO, buf[i])

            # start TX packet
            self.setMode(MODE_TX)

            # wait `TxRaedy` (bit 5 in `RegIrqFlags1`)
            #while ((self.readReg(REG_IRQ_FLAGS_1) & IRQ1_TX_READY) == 0):
            #    pass # FIXME: check timeout

            # wait `PacketSent` (bit 3 in `RegIrqFlags2`)
            while ((self.readReg(REG_IRQ_FLAGS_2) & IRQ2_PACKET_SENT) == 0):
                pass  # FIXME: check timeout

            # switch to standby mode
            self.setMode(MODE_STDBY)

        self.collect()
        #self.aquire_lock(False) # unlock when done writing

    def onReceive(self, callback):
        """set callback on receive packet (Lora/FSK/OOK)"""
        self._onReceive = callback
        if callback:
            self.pin_dio0.irq(trigger=Pin.IRQ_RISING,
                              handler=self._handleOnReceive)
        else:
            self.pin_dio0.irq(trigger=0, handler=None)

    def receive(self, size=0):
        """go to RX mode; wait callback by interrupt (LoRa/FSK/OOK)"""
        size = min(size, MAX_PKT_LENGTH)
        if self._mode == 0:  # LoRa mode
            self.setImplicitHeaderMode(size > 0)
            if size > 0:
                self.writeReg(REG_PAYLOAD_LENGTH, size)  # implicit header
        else:  # FSK/OOK mode
            self.setFixedLen(size > 0)
            if size > 0:
                self.writeReg(REG_PAYLOAD_LEN, size)  # fixed length
            else:
                self.writeReg(REG_PAYLOAD_LEN,
                              MAX_PKT_LENGTH)  # variable length
        self.setMode(MODE_RX_CONTINUOUS)

    def collect(self):
        """garbage collection"""
        gc.collect()
        #if MICROPYTHON:
        #    print('[Memory - free: {}   allocated: {}]'.format(gc.mem_free(), gc.mem_alloc()))

    def _handleOnReceive(self, event_source):
        #self.aquire_lock(True)
        if self._mode == 0:  # LoRa mode
            irqFlags = self.readReg(REG_IRQ_FLAGS)  # should be 0x50
            self.writeReg(REG_IRQ_FLAGS, irqFlags)

            if (irqFlags & IRQ_RX_DONE) == 0:  # check `RxDone`
                #self.aquire_lock(False)
                return  # `RxDone` is not set

            print(
                "DIO0 interrupt in LoRa mode by `RxDone` (RegIrqFlags=0x%02X)"
                % irqFlags)

            # check `PayloadCrcError` bit
            crcOk = not bool(irqFlags & IRQ_PAYLOAD_CRC_ERROR)

            # set FIFO address to current RX address
            self.writeReg(REG_FIFO_ADDR_PTR,
                          self.readReg(REG_FIFO_RX_CURRENT_ADDR))

            # read packet length
            packetLen = self.readReg(REG_PAYLOAD_LENGTH) if self._implicitHeaderMode else \
                        self.readReg(REG_RX_NB_BYTES)

        else:  # FSK/OOK mode
            irqFlags = self.readReg(REG_IRQ_FLAGS_2)  # should be 0x26/0x24
            if (irqFlags & IRQ2_PAYLOAD_READY) == 0:
                #self.aquire_lock(False)
                return  # `PayloadReady` is not set

            print(
                "DIO0 interrupt in FSK/OOK mode by `PayloadReady` (RegIrqFlags2=0x%02X)"
                % irqFlags)

            # check `CrcOk` bit
            crcOk = bool(irqFlags & IRQ2_CRC_OK)

            # read packet length
            if self.readReg(REG_PACKET_CONFIG_1) & 0x80:  # `PacketFormat`
                packetLen = self.readReg(REG_FIFO)  # variable length
            else:
                packetLen = self.readReg(REG_PAYLOAD_LEN)  # fixed length

        # read FIFO
        payload = bytearray(packetLen)
        for i in range(packetLen):
            payload[i] = self.readReg(REG_FIFO)
        payload = bytes(payload)
        self.collect()

        # run callback
        if self._onReceive:
            self._onReceive(self, payload, crcOk if self._crc else None)
        self.collect()

        #self.aquire_lock(False)

    def dump(self):
        for i in range(128):
            print("Reg[0x%02X] = 0x%02X" % (i, self.readReg(i)))
Beispiel #21
0
class MFRC522:

	OK = 0
	NOTAGERR = 1
	ERR = 2

	REQIDL = 0x26
	REQALL = 0x52
	AUTHENT1A = 0x60
	AUTHENT1B = 0x61

	def __init__(self, sck, mosi, miso, rst, cs):

		self.sck = Pin(sck, Pin.OUT)
		self.mosi = Pin(mosi, Pin.OUT)
		self.miso = Pin(miso)
		self.rst = Pin(rst, Pin.OUT)
		self.cs = Pin(cs, Pin.OUT)

		self.rst.value(0)
		self.cs.value(1)

		if uname()[0] == 'WiPy':
			self.spi = SPI(0)
			self.spi.init(SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso))
		elif uname()[0] == 'esp8266':
			self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
			self.spi.init()
		else:
			raise RuntimeError("Unsupported platform")

		self.rst.value(1)
		self.init()

	def _wreg(self, reg, val):

		self.cs.value(0)
		self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
		self.spi.write(b'%c' % int(0xff & val))
		self.cs.value(1)

	def _rreg(self, reg):

		self.cs.value(0)
		self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
		val = self.spi.read(1)
		self.cs.value(1)

		return val[0]

	def _sflags(self, reg, mask):
		self._wreg(reg, self._rreg(reg) | mask)

	def _cflags(self, reg, mask):
		self._wreg(reg, self._rreg(reg) & (~mask))

	def _tocard(self, cmd, send):

		recv = []
		bits = irq_en = wait_irq = n = 0
		stat = self.ERR

		if cmd == 0x0E:
			irq_en = 0x12
			wait_irq = 0x10
		elif cmd == 0x0C:
			irq_en = 0x77
			wait_irq = 0x30

		self._wreg(0x02, irq_en | 0x80)
		self._cflags(0x04, 0x80)
		self._sflags(0x0A, 0x80)
		self._wreg(0x01, 0x00)

		for c in send:
			self._wreg(0x09, c)
		self._wreg(0x01, cmd)

		if cmd == 0x0C:
			self._sflags(0x0D, 0x80)

		i = 2000
		while True:
			n = self._rreg(0x04)
			i -= 1
			if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
				break

		self._cflags(0x0D, 0x80)

		if i:
			if (self._rreg(0x06) & 0x1B) == 0x00:
				stat = self.OK

				if n & irq_en & 0x01:
					stat = self.NOTAGERR
				elif cmd == 0x0C:
					n = self._rreg(0x0A)
					lbits = self._rreg(0x0C) & 0x07
					if lbits != 0:
						bits = (n - 1) * 8 + lbits
					else:
						bits = n * 8

					if n == 0:
						n = 1
					elif n > 16:
						n = 16

					for _ in range(n):
						recv.append(self._rreg(0x09))
			else:
				stat = self.ERR

		return stat, recv, bits

	def _crc(self, data):

		self._cflags(0x05, 0x04)
		self._sflags(0x0A, 0x80)

		for c in data:
			self._wreg(0x09, c)

		self._wreg(0x01, 0x03)

		i = 0xFF
		while True:
			n = self._rreg(0x05)
			i -= 1
			if not ((i != 0) and not (n & 0x04)):
				break

		return [self._rreg(0x22), self._rreg(0x21)]

	def init(self):

		self.reset()
		self._wreg(0x2A, 0x8D)
		self._wreg(0x2B, 0x3E)
		self._wreg(0x2D, 30)
		self._wreg(0x2C, 0)
		self._wreg(0x15, 0x40)
		self._wreg(0x11, 0x3D)
		self.antenna_on()

	def reset(self):
		self._wreg(0x01, 0x0F)

	def antenna_on(self, on=True):

		if on and ~(self._rreg(0x14) & 0x03):
			self._sflags(0x14, 0x03)
		else:
			self._cflags(0x14, 0x03)

	def request(self, mode):

		self._wreg(0x0D, 0x07)
		(stat, recv, bits) = self._tocard(0x0C, [mode])

		if (stat != self.OK) | (bits != 0x10):
			stat = self.ERR

		return stat, bits

	def anticoll(self):

		ser_chk = 0
		ser = [0x93, 0x20]

		self._wreg(0x0D, 0x00)
		(stat, recv, bits) = self._tocard(0x0C, ser)

		if stat == self.OK:
			if len(recv) == 5:
				for i in range(4):
					ser_chk = ser_chk ^ recv[i]
				if ser_chk != recv[4]:
					stat = self.ERR
			else:
				stat = self.ERR

		return stat, recv

	def select_tag(self, ser):

		buf = [0x93, 0x70] + ser[:5]
		buf += self._crc(buf)
		(stat, recv, bits) = self._tocard(0x0C, buf)
		return self.OK if (stat == self.OK) and (bits == 0x18) else self.ERR

	def auth(self, mode, addr, sect, ser):
		return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]

	def stop_crypto1(self):
		self._cflags(0x08, 0x08)

	def read(self, addr):

		data = [0x30, addr]
		data += self._crc(data)
		(stat, recv, _) = self._tocard(0x0C, data)
		return recv if stat == self.OK else None

	def write(self, addr, data):

		buf = [0xA0, addr]
		buf += self._crc(buf)
		(stat, recv, bits) = self._tocard(0x0C, buf)

		if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
			stat = self.ERR
		else:
			buf = []
			for i in range(16):
				buf.append(data[i])
			buf += self._crc(buf)
			(stat, recv, bits) = self._tocard(0x0C, buf)
			if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
				stat = self.ERR

		return stat
Beispiel #22
0
    def get_time(self):
        now = self.get_localtime()
        return (now[3], now[4], now[5])

    @property
    def uptime(self):
        return time.time() - self._epoch

    def get_uptime_ms(self):
        return int(self.uptime * 1000)


backlight = Backlight()
spi = SPI(0)
spi.init(polarity=1, phase=1, baudrate=8000000)
display = ST7789_SPI(240,
                     240,
                     spi,
                     cs=Pin("DISP_CS", Pin.OUT, quiet=True),
                     dc=Pin("DISP_DC", Pin.OUT, quiet=True),
                     res=Pin("DISP_RST", Pin.OUT, quiet=True))
drawable = draw565.Draw565(display)

accel = Accelerometer()
battery = Battery()
button = Pin('BUTTON', Pin.IN, quiet=True)
rtc = RTC()
touch = CST816S(I2C(0), Pin('TP_INT', Pin.IN, quiet=True),
                Pin('TP_RST', Pin.OUT, quiet=True))
vibrator = Vibrator(Pin('MOTOR', Pin.OUT, value=0), active_low=True)
Beispiel #23
0
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import gc
from machine import Pin, SPI
from codepage import cp437_chr, cp437_pal, cp437_pic
from gd import Gameduino, RAM_CHR, RAM_PAL

# See the Gameduino General test for all MicroPython plateform support
spi = SPI(2)  # MOSI=Y8, MISO=Y7, SCK=Y6, SS=Y5
spi.init(SPI.MASTER, baudrate=2000000, phase=0, polarity=0)
# We must manage the SS signal ourself
ss = Pin(Pin.board.Y5, Pin.OUT)

# Gameduino Lib
gd = Gameduino(spi, ss)
print("Initializing...")
gd.begin()
print("Uncompressing to RAM_CHR")
gd.uncompress(RAM_CHR, cp437_chr)
print("Uncompressing to RAM_PAL")
gd.uncompress(RAM_PAL, cp437_pal)


def atxy(x, y):
    """ Memory offset corresponding to a cursor position """
Beispiel #24
0
from machine import SPI, Pin
from ws2812 import *

spi = SPI(1)
spi.init(baudrate=3200000, mosi=Pin(23))

chain = WS2812(spi, led_count=1)
data = [(255, 0, 0)  #red
        ]
chain.show(data)
Beispiel #25
0
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

from machine import Pin, SPI
from gd import *
import os
import urandom # on recent MicroPython Firmware v1.10+

# Initialize the SPI Bus (on ESP8266-EVB)
# Software SPI
#    spi = SPI(-1, baudrate=4000000, polarity=1, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
# Hardware SPI
spi = SPI(2) # MOSI=Y8, MISO=Y7, SCK=Y6, SS=Y5
spi.init( baudrate=20000000, phase=0, polarity=0 ) # raise @ 20 Mhz
# We must manage the SS signal ourself
ss = Pin( Pin.board.Y5, Pin.OUT )

# Gameduino Lib
gd = Gameduino( spi, ss )
gd.begin()

# === Toolbox ==================================================================
def draw_ball( x, y, pal ):
	global gd
	gd.xsprite(x, y, -40, -56, 0, pal, 0)
	gd.xsprite(x, y, -24, -56, 1, pal, 0)
	gd.xsprite(x, y, -8, -56, 2, pal, 0)
	gd.xsprite(x, y, 8, -56, 3, pal, 0)
	gd.xsprite(x, y, 24, -56, 4, pal, 0)
Beispiel #26
0
class EPD(object):
    MAX_READ = 45
    SW_NORMAL_PROCESSING = 0x9000
    EP_FRAMEBUFFER_SLOT_OVERRUN = 0x6a84 # too much data fed in
    EP_SW_INVALID_LE = 0x6c00 # Wrong expected length
    EP_SW_INSTRUCTION_NOT_SUPPORTED = 0x6d00 # bad instr
    EP_SW_WRONG_PARAMETERS_P1P2 = 0x6a00
    EP_SW_WRONG_LENGTH = 0x6700

    DEFAULT_SLOT=0 # always the *oldest*, should wear-level then I think

    def __init__(self, debug=False, baud=100000):
        # From datasheet
        # Bit rate – up to 12 MHz1
        # ▪ Polarity – CPOL = 1; clock transition high-to-low on the leading edge and low-to-high on the
        #   trailing edge
        # ▪ Phase – CPHA = 1; setup on the leading edge and sample on the trailing edge
        # ▪ Bit order – MSB first
        # ▪ Chip select polarity – active low
        self.spi = SPI(0)
        try:
            self.spi.init(mode=SPI.MASTER, baudrate=baud, bits=8,
                          polarity=1, phase=1, firstbit=SPI.MSB,
                          pins=('GP31', 'GP16', 'GP30')) # CLK, MOSI, MISO
        except AttributeError:
            self.spi.init(baudrate=baud, bits=8,
                          polarity=1, phase=1, firstbit=SPI.MSB,
                          pins=('GP31', 'GP16', 'GP30')) # CLK, MOSI, MISO

        # These are all active low!
        self.tc_en_bar = Pin('GP4', mode=Pin.OUT)

        self.disable()

        self.tc_busy_bar = Pin('GP5', mode=Pin.IN)
        self.tc_busy_bar.irq(trigger=Pin.IRQ_RISING) # Wake up when it changes
        self.tc_cs_bar = Pin('GP17', mode=Pin.ALT, alt=7)

        self.debug = debug

    def enable(self):
        self.tc_en_bar.value(0) # Power up
        time.sleep_ms(5)
        while self.tc_busy_bar() == 0:
            machine.idle() # will it wake up here?
        # /tc_busy goes high during startup, low during init, then high when not busy

    def disable(self):
        self.tc_en_bar.value(1) # Off

    def send_command(self, ins, p1, p2, data=None, expected=None):

        # These command variables are always sent
        cmd = struct.pack('3B', ins, p1, p2)

        # Looks like data is only sent with the length (Lc)
        if data:
            assert len(data) <= 251 # Thus speaks the datasheet
            cmd += struct.pack('B', len(data))
            cmd += data

        # Expected data is either not present at all, 0 for null-terminated, or a number for fixed
        if expected is not None:
            cmd += struct.pack('B', expected)

        if self.debug:
            print("Sending: " + hexlify(cmd).decode())

        self.spi.write(cmd)

        # Wait for a little while
        time.sleep_us(15) # This should take at most 14.5us
        while self.tc_busy_bar() == 0:
            machine.idle()

        # Request a response
        if expected is not None:
            if expected > 0:
                result_bytes = self.spi.read(2 + expected)
            else:
                result_bytes = self.spi.read(EPD.MAX_READ)
                strlen = result_bytes.find(b'\x00')
                result_bytes = result_bytes[:strlen] + result_bytes[strlen+1:strlen+3]
        else:
            result_bytes = self.spi.read(2)

        if self.debug:
            print("Received: " + hexlify(result_bytes).decode())

        (result,) = struct.unpack_from('>H', result_bytes[-2:])

        if result != EPD.SW_NORMAL_PROCESSING:
            raise ValueError("Bad result code: 0x%x" % result)

        return result_bytes[:-2]

    @staticmethod
    def calculate_checksum(data, skip=16):
        """
        Initial checksum value is 0x6363

        :param data:
        :param skip: Skip some data as slices are expensive
        :return:
        """
        acc = 0x6363
        for byte in data:
            if skip > 0:
                skip -= 1
            else:
                acc ^= byte
                acc = ((acc >> 8) | (acc << 8)) & 0xffff
                acc ^= ((acc & 0xff00) << 4) & 0xffff
                acc ^= (acc >> 8) >> 4
                acc ^= (acc & 0xff00) >> 5
        return acc

    def get_sensor_data(self):
        # GetSensorData
        val = self.send_command(0xe5, 1, 0, expected=2)
        (temp,) = struct.unpack(">H", val)
        return temp

    def get_device_id(self):
        return self.send_command(0x30, 2, 1, expected=0x14)

    def get_system_info(self):
        return self.send_command(0x31, 1, 1, expected=0)

    def get_system_version_code(self):
        return self.send_command(0x31, 2, 1, expected=0x10)

    def display_update(self, slot=0, flash=True):
        cmd = 0x86
        if flash:
            cmd = 0x24
        self.send_command(cmd, 1, slot)

    def reset_data_pointer(self):
        self.send_command(0x20, 0xd, 0)

    def image_erase_frame_buffer(self, slot=0):
        self.send_command(0x20, 0xe, slot)

    def get_checksum(self, slot):
        cksum_val = self.send_command(0x2e, 1, slot, expected=2)
        (cksum,) = struct.unpack(">H", cksum_val)
        return cksum

    def upload_image_data(self, data, slot=0, delay_us=1000):
        self.send_command(0x20, 1, slot, data)
        time.sleep_us(delay_us)

    def upload_whole_image(self, img, slot=0):
        """
        Chop up chunks and send it
        :param img: Image to send in EPD format
        :param slot: Slot framebuffer number to use
        :param delay_us: Delay between packets? 450us and the Tbusy line never comes back
        :return:
        """
        total = len(img)
        idx = 0
        try:
            while idx < total - 250:
                chunk = img[idx:idx+250]
                self.upload_image_data(chunk, slot)
                del chunk
                idx += 250
            self.upload_image_data(img[idx:], slot)
        except KeyboardInterrupt:
            print("Stopped at user request at position: %d (%d)" % (idx, (idx // 250)))
        except ValueError as e:
            print("Stopped at position: %d (%d) - %s" % (idx, (idx // 250), e))
Beispiel #27
0
def spi():
    from machine import SPI
    from machine import Pin
    from utime import sleep

    def uart_handle(pin):
        print('irq')

    intr = Pin(2,Pin.IN)
    intr.irq(trigger=Pin.IRQ_RISING, handler=uart_handle)

    cspin = Pin(15,Pin.OUT)
    cspin.value(1)

    cs1pin = Pin(16,Pin.OUT)
    cs1pin.value(1)

    hspi = SPI(1,baudrate=4000000,polarity=0,phase=0)
    hspi.init()
    
    i,r,w,wfifo,rfifo,ruart = sc16is750(hspi,cspin)
    i()

    o = 0

    def wr():
        print('wfifo') 
        ack = wfifo(b'\x00\x01\x02\x03\x04\x05\x06\x07\x10\x11\x12\x13\x14\x15\x16\x17')
        if ack==0:
            print('no room')
        #wfifo(b'\xaa\x66\x55\x99')

    def rd():
        print('readback')

        lsr = r(5)
        print('x{0:x}'.format(int.from_bytes(lsr, 'big')) )
    
        for i in range(8):
            lsr1 = r(5)
            lsr1 = int.from_bytes(lsr1,'big')
            lsr = lsr1 & 0x01
            if lsr==1:
                print( '{:02x}'.format(lsr1) )
                print(r(0))

        lsr = r(5)
        print('x{0:x}'.format(int.from_bytes(lsr, 'big')) )

    def rd1():

        nonlocal o
        n,b = ruart()
        print( '{}:{}: {}'.format(o,n,b) )
        o=o+1

    def rd2():
        nonlocal o
        print('readback2')
        lsr = r(5)
        lsr1 = int.from_bytes(lsr,'big') & 0x01

        if lsr1==0x01:          
          print( '{}: {}'.format(o,rfifo()) )

        print('x{0:02x}'.format(int.from_bytes(lsr, 'big')) )
        o=o+1
        
    def write595(v):
        cs1pin.value(0)
        hspi.write(v.to_bytes(1,'big'))
        cs1pin.value(1)

    
    return write595,wr,rfifo
Beispiel #28
0
"""

from machine import Pin, SPI
from gd import *
import urandom # on recent MicroPython Firmware v1.10+
import os
from math import sqrt
from time import sleep


# Initialize the SPI Bus (on ESP8266-EVB)
# Software SPI
#    spi = SPI(-1, baudrate=4000000, polarity=1, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
# Hardware SPI
spi = SPI(2) # MOSI=Y8, MISO=Y7, SCK=Y6, SS=Y5
spi.init( baudrate=20000000, phase=0, polarity=0 ) # raise @ 20 Mhz
# We must manage the SS signal ourself
ss = Pin( Pin.board.Y5, Pin.OUT )

# Gameduino Lib
gd = Gameduino( spi, ss )
gd.begin()

# os.chdir( '/sd' )

# === Toolbox ==================================================================
# readn() has been added to the gameduino library
# void readn(byte *dst, unsigned int addr, int c)

# Ported from random.h - MicroCode for the VGA controler
random_code = [ 0x81,0x15,
def sdtest():
    print("1")

    #hardware spi

    spi = SPI(2,
              baudrate=10000000,
              polarity=0,
              phase=0,
              bits=8,
              firstbit=SPI.MSB,
              sck=Pin(18, Pin.OUT, Pin.PULL_DOWN),
              mosi=Pin(23, Pin.OUT, Pin.PULL_UP),
              miso=Pin(19, Pin.IN, Pin.PULL_UP))

    spi.init()  # Ensure right baudrate
    sd = sdcard.SDCard(spi, Pin(22))  # Compatible with PCB
    vfs = os.VfsFat(sd)
    os.mount(vfs, "/fc")
    print("Filesystem check")
    print(os.listdir("/fc"))

    print("1")

    line = "abcdefghijklmnopqrstuvwxyz\n"
    lines = line * 200  # 5400 chars
    short = "1234567890\n"

    print("1")

    fn = "/fc/rats.txt"
    print()
    print("Multiple block read/write")
    with open(fn, "w") as f:
        n = f.write(lines)
        print(n, "bytes written")
        n = f.write(short)
        print(n, "bytes written")
        n = f.write(lines)
        print(n, "bytes written")

    with open(fn, "r") as f:
        result1 = f.read()
        print(len(result1), "bytes read")

    fn = "/fc/rats1.txt"
    print()
    print("Single block read/write")
    with open(fn, "w") as f:
        n = f.write(short)  # one block
        print(n, "bytes written")

    with open(fn, "r") as f:
        result2 = f.read()
        print(len(result2), "bytes read")

    os.umount("/fc")

    print()
    print("Verifying data read back")
    success = True
    if result1 == "".join((lines, short, lines)):
        print("Large file Pass")
    else:
        print("Large file Fail")
        success = False
    if result2 == short:
        print("Small file Pass")
    else:
        print("Small file Fail")
        success = False
    print()
    print("Tests", "passed" if success else "failed")
Beispiel #30
0
else:
    raise Exception('Board not supported!')

spi = SPI(0, SPI.MASTER, baudrate=2000000, polarity=0, phase=0, firstbit=SPI.MSB, pins=spi_pins)
print(spi)
spi = SPI(baudrate=5000000)
print(spi)
spi = SPI(0, SPI.MASTER, baudrate=200000, bits=16, polarity=0, phase=0)
print(spi)
spi = SPI(0, SPI.MASTER, baudrate=10000000, polarity=0, phase=1)
print(spi)
spi = SPI(0, SPI.MASTER, baudrate=5000000, bits=32, polarity=1, phase=0)
print(spi)
spi = SPI(0, SPI.MASTER, baudrate=10000000, polarity=1, phase=1)
print(spi)
spi.init(baudrate=20000000, polarity=0, phase=0)
print(spi)
spi=SPI()
print(spi)
SPI(mode=SPI.MASTER)
SPI(mode=SPI.MASTER, pins=spi_pins)
SPI(id=0, mode=SPI.MASTER, polarity=0, phase=0, pins=('GP14', 'GP16', 'GP15'))
SPI(0, SPI.MASTER, polarity=0, phase=0, pins=('GP31', 'GP16', 'GP15'))

spi = SPI(0, SPI.MASTER, baudrate=10000000, polarity=0, phase=0, pins=spi_pins)
print(spi.write('123456') == 6)
buffer_r = bytearray(10)
print(spi.readinto(buffer_r) == 10)
print(spi.readinto(buffer_r, write=0x55) == 10)
read = spi.read(10)
print(len(read) == 10)
Beispiel #31
0
class ILI9341:
    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.pages = self.height // 8
        self.buffer = bytearray(self.pages * self.width)
        self.framebuf = framebuf.FrameBuffer(self.buffer, self.width, self.height, framebuf.MONO_VLSB)

        self.spi = SPI(0)
        # chip select
        self.cs = Pin("P16", mode=Pin.OUT, pull=Pin.PULL_UP)
        # command
        self.dc = Pin("P17", mode=Pin.OUT, pull=Pin.PULL_UP)
        
        # initialize all pins high
        self.cs.high()
        self.dc.high()

        self.spi.init(baudrate=8000000, phase=0, polarity=0)

        self.init_display()
        

    def init_display(self):
        time.sleep_ms(500)
        
        self.write_cmd(0x01)
        
        time.sleep_ms(200)
    
        self.write_cmd(0xCF)
        self.write_data(bytearray([0x00, 0x8B, 0x30]))
    
        self.write_cmd(0xED)
        self.write_data(bytearray([0x67, 0x03, 0x12, 0x81]))

        self.write_cmd(0xE8)
        self.write_data(bytearray([0x85, 0x10, 0x7A]))
    
        self.write_cmd(0xCB)
        self.write_data(bytearray([0x39, 0x2C, 0x00, 0x34, 0x02]))
    
        self.write_cmd(0xF7)
        self.write_data(bytearray([0x20]))

        self.write_cmd(0xEA)
        self.write_data(bytearray([0x00, 0x00]))

        # Power control
        self.write_cmd(0xC0)
        # VRH[5:0]
        self.write_data(bytearray([0x1B]))
        
        # Power control
        self.write_cmd(0xC1)
        # SAP[2:0];BT[3:0]
        self.write_data(bytearray([0x10]))
        
        # VCM control
        self.write_cmd(0xC5)
        self.write_data(bytearray([0x3F, 0x3C]))
    
        # VCM control2
        self.write_cmd(0xC7)
        self.write_data(bytearray([0xB7]))
    
        # Memory Access Control
        self.write_cmd(0x36)
        self.write_data(bytearray([0x08]))
    
        self.write_cmd(0x3A)
        self.write_data(bytearray([0x55]))
    
        self.write_cmd(0xB1)
        self.write_data(bytearray([0x00, 0x1B]))
        
        # Display Function Control
        self.write_cmd(0xB6)
        self.write_data(bytearray([0x0A, 0xA2]))
    
        # 3Gamma Function Disable
        self.write_cmd(0xF2)
        self.write_data(bytearray([0x00]))
        
        # Gamma curve selected
        self.write_cmd(0x26)
        self.write_data(bytearray([0x01]))
    
        # Set Gamma
        self.write_cmd(0xE0)
        self.write_data(bytearray([0x0F, 0x2A, 0x28, 0x08, 0x0E, 0x08, 0x54, 0XA9, 0x43, 0x0A, 0x0F, 0x00, 0x00, 0x00, 0x00]))
    
        # Set Gamma
        self.write_cmd(0XE1)
        self.write_data(bytearray([0x00, 0x15, 0x17, 0x07, 0x11, 0x06, 0x2B, 0x56, 0x3C, 0x05, 0x10, 0x0F, 0x3F, 0x3F, 0x0F]))
        
        # Exit Sleep
        self.write_cmd(0x11)
        time.sleep_ms(120)
        
        # Display on
        self.write_cmd(0x29)
        time.sleep_ms(500)
        self.fill(0)

    def show(self):
        # set col
        self.write_cmd(0x2A)
        self.write_data(bytearray([0x00, 0x00]))
        self.write_data(bytearray([0x00, 0xef]))
        
        # set page 
        self.write_cmd(0x2B)
        self.write_data(bytearray([0x00, 0x00]))
        self.write_data(bytearray([0x01, 0x3f]))

        self.write_cmd(0x2c);

        num_of_pixels = self.height * self.width

        for row in range(0, self.pages):
            for pixel_pos in range(0, 8):
                for col in range(0, self.width):
                    compressed_pixel = self.buffer[row * 240 + col]
                    if ((compressed_pixel >> pixel_pos) & 0x1) == 0:
                        self.write_data(bytearray([0x00, 0x00]))
                    else:
                        self.write_data(bytearray([0xFF, 0xFF]))

    def fill(self, col):
        self.framebuf.fill(col)

    def pixel(self, x, y, col):
        self.framebuf.pixel(x, y, col)

    def scroll(self, dx, dy):
        self.framebuf.scroll(dx, dy)

    def text(self, string, x, y, col=1):
        self.framebuf.text(string, x, y, col)

    def write_cmd(self, cmd):
        self.dc.low()
        self.cs.low()
        self.spi.write(bytearray([cmd]))
        self.cs.high()
        
    def write_data(self, buf):
        self.dc.high()
        self.cs.low()
        self.spi.write(buf)
        self.cs.high()
Beispiel #32
0
class MFRC522:
  RESET = 'GP22'
  CLK = 'GP14'
  MISO = 'GP15'
  MOSI = 'GP16'
  CS = 'GP17'

  MAX_LEN = 16
  
  PCD_IDLE       = 0x00
  PCD_AUTHENT    = 0x0E
  PCD_TRANSCEIVE = 0x0C
  PCD_RESETPHASE = 0x0F
  PCD_CALCCRC    = 0x03

  PICC_REQIDL    = 0x26
  PICC_REQALL    = 0x52
  PICC_ANTICOLL  = 0x93
  PICC_SElECTTAG = 0x93
  PICC_AUTHENT1A = 0x60
  PICC_READ      = 0x30
  PICC_WRITE     = 0xA0
  
  MI_OK       = 0
  MI_NOTAGERR = 1
  MI_ERR      = 2
  MI_AUTH_ERROR_STATUS2REG = 3

  CommandReg     = 0x01
  CommIEnReg     = 0x02
  CommIrqReg     = 0x04
  DivIrqReg      = 0x05
  ErrorReg       = 0x06
  Status2Reg     = 0x08
  FIFODataReg    = 0x09
  FIFOLevelReg   = 0x0A
  WaterLevelReg  = 0x0B
  ControlReg     = 0x0C
  BitFramingReg  = 0x0D
  
  ModeReg        = 0x11
  TxControlReg   = 0x14
  TxAutoReg      = 0x15
  
  CRCResultRegM     = 0x21
  CRCResultRegL     = 0x22
  TModeReg          = 0x2A
  TPrescalerReg     = 0x2B
  TReloadRegH       = 0x2C
  TReloadRegL       = 0x2D
    
  serNum = []

  def __init__(self, spd=1000000):
    # first assign CLK, MISO, MOSI, CS to the correct pins
    self.pin_clk = Pin(self.CLK, mode=Pin.OUT)    # CLK
    self.pin_miso = Pin(self.MISO)    # MISO
    self.pin_mosi = Pin(self.MOSI, mode=Pin.OUT)    # MOSI
    self.pin_cs = Pin(self.CS, mode=Pin.OUT)    # NSS/CS
    self.pin_reset = Pin(self.RESET, mode=Pin.OUT)

    self.pin_reset.value(0)
    self.pin_cs.value(1)

    self.spi = SPI(0)
    self.spi.init(mode=SPI.MASTER, baudrate=spd, pins=(self.CLK, self.MOSI, self.MISO))
    
    self.pin_reset.value(1)

    self.MFRC522_Init()
  
  def MFRC522_Reset(self):
    self.Write_MFRC522(self.CommandReg, self.PCD_RESETPHASE)
  
  def Write_MFRC522(self, addr, val):
    self.pin_cs.value(0)
    # 0(MSB = Write) ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 0(LSB = 0) DATA
    spiBytes = bytearray(2)
    spiBytes[0] = ((addr<<1)&0x7E) 
    spiBytes[1] = val
    self.spi.write(spiBytes)
    self.pin_cs.value(1)
  
  def Read_MFRC522(self, addr):
    self.pin_cs.value(0)
    # 1(MSB = Read) ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 0(LSB = 0)
    self.spi.write((addr<<1)&0x7E|0x80)
    data = self.spi.read(1)
    self.pin_cs.value(1)
    return data[0]
  
  def SetBitMask(self, reg, mask):
    tmp = self.Read_MFRC522(reg)
    self.Write_MFRC522(reg, tmp | mask)
    
  def ClearBitMask(self, reg, mask):
    tmp = self.Read_MFRC522(reg);
    self.Write_MFRC522(reg, tmp & (~mask))
  
  def AntennaOn(self):
    temp = self.Read_MFRC522(self.TxControlReg)
    if(~(temp & 0x03)):
      self.SetBitMask(self.TxControlReg, 0x03)

  
  def AntennaOff(self):
    self.ClearBitMask(self.TxControlReg, 0x03)
  
  def MFRC522_ToCard(self,command,sendData):
    backData = []
    backLen = 0
    status = self.MI_ERR
    irqEn = 0x00
    waitIRq = 0x00
    lastBits = None
    n = 0
    i = 0
    
    if command == self.PCD_AUTHENT:
      irqEn = 0x12
      waitIRq = 0x10
    if command == self.PCD_TRANSCEIVE:
      irqEn = 0x77
      waitIRq = 0x30

    self.Write_MFRC522(self.CommIEnReg, irqEn|0x80)
    self.ClearBitMask(self.CommIrqReg, 0x80)
    self.SetBitMask(self.FIFOLevelReg, 0x80)
    self.Write_MFRC522(self.CommandReg, self.PCD_IDLE);  

    while(i<len(sendData)):
      self.Write_MFRC522(self.FIFODataReg, sendData[i])
      i = i+1
    self.Write_MFRC522(self.CommandReg, command)

    if command == self.PCD_TRANSCEIVE:
      self.SetBitMask(self.BitFramingReg, 0x80)
    
    i = 2000
    while True:
      n = self.Read_MFRC522(self.CommIrqReg)
      i = i - 1
      if ~((i!=0) and ~(n&0x01) and ~(n&waitIRq)):
        break
    
    self.ClearBitMask(self.BitFramingReg, 0x80)
  
    if i != 0:
      st = self.Read_MFRC522(self.ErrorReg)
      if (st & 0x1B)==0x00:
        status = self.MI_OK

        if n & irqEn & 0x01:
          status = self.MI_NOTAGERR
        elif command == self.PCD_TRANSCEIVE:
          n = self.Read_MFRC522(self.FIFOLevelReg)
          lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
          if lastBits != 0:
            backLen = (n-1)*8 + lastBits
          else:
            backLen = n*8
          
          if n == 0:
            n = 1
          if n > self.MAX_LEN:
            n = self.MAX_LEN
    
          i = 0
          while i<n:
            backData.append(self.Read_MFRC522(self.FIFODataReg))
            i = i + 1;
      else:
        status = self.MI_ERR
    return (status,backData,backLen)
  
  
  def MFRC522_Request(self, reqMode):
    status = None
    backBits = None
    TagType = [reqMode]

    self.Write_MFRC522(self.BitFramingReg, 0x07)

    (status,backData,backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, TagType)
    if ((status != self.MI_OK) | (backBits != 0x10)):
      status = self.MI_ERR
      
    return (status,backBits)
  
  
  def MFRC522_Anticoll(self):
    backData = []
    serNumCheck = 0
    
    serNum = [self.PICC_ANTICOLL, 0x20]
  
    self.Write_MFRC522(self.BitFramingReg, 0x00)
    
    (status,backData,backBits) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE,serNum)
    
    if(status == self.MI_OK):
      i = 0
      if len(backData)==5:
        while i<4:
          serNumCheck = serNumCheck ^ backData[i]
          i = i + 1
        if serNumCheck != backData[i]:
          status = self.MI_ERR
      else:
        status = self.MI_ERR
  
    return (status,backData)
  
  def CalulateCRC(self, pIndata):
    self.ClearBitMask(self.DivIrqReg, 0x04)
    self.SetBitMask(self.FIFOLevelReg, 0x80);
    i = 0
    while i<len(pIndata):
      self.Write_MFRC522(self.FIFODataReg, pIndata[i])
      i = i + 1
    self.Write_MFRC522(self.CommandReg, self.PCD_CALCCRC)
    i = 0xFF
    while True:
      n = self.Read_MFRC522(self.DivIrqReg)
      i = i - 1
      if not ((i != 0) and not (n&0x04)):
        break
    pOutData = []
    pOutData.append(self.Read_MFRC522(self.CRCResultRegL))
    pOutData.append(self.Read_MFRC522(self.CRCResultRegM))
    return pOutData
  
  def MFRC522_SelectTag(self, serNum):
    backData = []
    buf = [self.PICC_SElECTTAG, 0x70] + serNum[:5]

    buf += self.CalulateCRC(buf)
    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buf)
    
    if (status == self.MI_OK) and (backLen == 0x18):
      return self.MI_OK
    else:
      return self.MI_ERR
  
  def MFRC522_Auth(self, authMode, BlockAddr, Sectorkey, serNum):
    #First byte should be the authMode (A or B)
    #Second byte is the trailerBlock (usually 7)
    #Now we need to append the authKey which usually is 6 bytes of 0xFF
    #Next we append the first 4 bytes of the UID
    buff = [authMode, BlockAddr] + Sectorkey + serNum[:4]

    # Now we start the authentication itself
    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_AUTHENT,buff)

    # Check if an error occurred


    # Return the status
    return status
  
  def MFRC522_StopCrypto1(self):
    self.ClearBitMask(self.Status2Reg, 0x08)

  def MFRC522_Read(self, blockAddr):
    recvData = [self.PICC_READ, blockAddr]
    recvData += self.CalulateCRC(recvData)

    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, recvData)
    return (status, backData)
  
  def MFRC522_Write(self, blockAddr, writeData):
    buff = [self.PICC_WRITE, blockAddr]
    buff += self.CalulateCRC(buff)
    (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE, buff)
    if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A):
        status = self.MI_ERR
    
    if status == self.MI_OK:
        i = 0
        buf = []
        while i < 16:
            buf.append(writeData[i])
            i = i + 1
        buf += self.CalulateCRC(buf)
        (status, backData, backLen) = self.MFRC522_ToCard(self.PCD_TRANSCEIVE,buf)
        if not(status == self.MI_OK) or not(backLen == 4) or not((backData[0] & 0x0F) == 0x0A):
            status = self.MI_ERR

    return status

  def MFRC522_Init(self):
    self.MFRC522_Reset();
    
    self.Write_MFRC522(self.TModeReg, 0x8D)
    self.Write_MFRC522(self.TPrescalerReg, 0x3E)
    self.Write_MFRC522(self.TReloadRegL, 30)
    self.Write_MFRC522(self.TReloadRegH, 0)
    self.Write_MFRC522(self.TxAutoReg, 0x40)
    self.Write_MFRC522(self.ModeReg, 0x3D)
    self.AntennaOn()
Beispiel #33
0
class MFRC522:
    OK = 0
    NOTAGERR = 1
    ERR = 2

    REQIDL = 0x26
    REQALL = 0x52
    AUTHENT1A = 0x60
    AUTHENT1B = 0x61

    def __init__(self, sck, mosi, miso, rst, cs):
        self.sck = Pin(sck, Pin.OUT)
        self.mosi = Pin(mosi, Pin.OUT)
        self.miso = Pin(miso)
        self.rst = Pin(rst, Pin.OUT)
        self.cs = Pin(cs, Pin.OUT)

        self.rst.value(0)
        self.cs.value(1)

        self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
        self.spi.init()

        self.rst.value(1)
        self.init()

    def _wreg(self, reg, val):

        self.cs.value(0)
        self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
        self.spi.write(b'%c' % int(0xff & val))
        self.cs.value(1)

    def _rreg(self, reg):

        self.cs.value(0)
        self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
        val = self.spi.read(1)
        self.cs.value(1)

        return val[0]

    def _sflags(self, reg, mask):
        self._wreg(reg, self._rreg(reg) | mask)

    def _cflags(self, reg, mask):
        self._wreg(reg, self._rreg(reg) & (~mask))

    def _tocard(self, cmd, send):

        recv = []
        bits = irq_en = wait_irq = n = 0
        stat = self.ERR

        if cmd == 0x0E:
            irq_en = 0x12
            wait_irq = 0x10
        elif cmd == 0x0C:
            irq_en = 0x77
            wait_irq = 0x30

        self._wreg(0x02, irq_en | 0x80)
        self._cflags(0x04, 0x80)
        self._sflags(0x0A, 0x80)
        self._wreg(0x01, 0x00)

        for c in send:
            self._wreg(0x09, c)
        self._wreg(0x01, cmd)

        if cmd == 0x0C:
            self._sflags(0x0D, 0x80)

        i = 200
        while True:
            n = self._rreg(0x04)
            i -= 1
            if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
                break

        self._cflags(0x0D, 0x80)

        if i:
            if (self._rreg(0x06) & 0x1B) == 0x00:
                stat = self.OK

                if n & irq_en & 0x01:
                    stat = self.NOTAGERR
                elif cmd == 0x0C:
                    n = self._rreg(0x0A)
                    lbits = self._rreg(0x0C) & 0x07
                    if lbits != 0:
                        bits = (n - 1) * 8 + lbits
                    else:
                        bits = n * 8

                    if n == 0:
                        n = 1
                    elif n > 16:
                        n = 16

                    for _ in range(n):
                        recv.append(self._rreg(0x09))
            else:
                stat = self.ERR

        return stat, recv, bits

    def _crc(self, data):

        self._cflags(0x05, 0x04)
        self._sflags(0x0A, 0x80)

        for c in data:
            self._wreg(0x09, c)

        self._wreg(0x01, 0x03)

        i = 0xFF
        while True:
            n = self._rreg(0x05)
            i -= 1
            if not ((i != 0) and not (n & 0x04)):
                break

        return [self._rreg(0x22), self._rreg(0x21)]

    def init(self):
        self.reset()
        self._wreg(0x2A, 0x8D)
        self._wreg(0x2B, 0x3E)
        self._wreg(0x2D, 30)
        self._wreg(0x2C, 0)
        self._wreg(0x15, 0x40)
        self._wreg(0x11, 0x3D)
        self.antenna_on()

    def reset(self):
        self._wreg(0x01, 0x0F)

    def antenna_on(self, on=True):
        if on and ~(self._rreg(0x14) & 0x03):
            self._sflags(0x14, 0x03)
        else:
            self._cflags(0x14, 0x03)

    def request(self, mode):
        self._wreg(0x0D, 0x07)
        (stat, recv, bits) = self._tocard(0x0C, [mode])

        if (stat != self.OK) | (bits != 0x10):
            stat = self.ERR

        return stat, bits

    def anticoll(self):
        ser_chk = 0
        ser = [0x93, 0x20]

        self._wreg(0x0D, 0x00)
        (stat, recv, bits) = self._tocard(0x0C, ser)

        if stat == self.OK:
            if len(recv) == 5:
                for i in range(4):
                    ser_chk = ser_chk ^ recv[i]
                if ser_chk != recv[4]:
                    stat = self.ERR
            else:
                stat = self.ERR

        return stat, recv

    def select_tag(self, ser):
        buf = [0x93, 0x70] + ser[:5]
        buf += self._crc(buf)
        (stat, recv, bits) = self._tocard(0x0C, buf)
        return self.OK if (stat == self.OK) and (bits == 0x18) else self.ERR

    def auth(self, mode, addr, sect, ser):
        return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]

    def stop_crypto1(self):
        self._cflags(0x08, 0x08)

    def read(self, addr):
        data = [0x30, addr]
        data += self._crc(data)
        (stat, recv, _) = self._tocard(0x0C, data)
        return recv if stat == self.OK else None

    def write(self, addr, data):
        buf = [0xA0, addr]
        buf += self._crc(buf)
        (stat, recv, bits) = self._tocard(0x0C, buf)

        if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
            stat = self.ERR
        else:
            buf = []
            for i in range(16):
                buf.append(data[i])
            buf += self._crc(buf)
            (stat, recv, bits) = self._tocard(0x0C, buf)
            if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
                stat = self.ERR

        return stat

    def read_data(self, addresses=None):
        """
        Wait for card and read data from 'addresses'
        :param addresses: list of addresses to read from (if you specify empty list, card data will contain only UID)
        :return: CardData instance with card data
        """
        print("Place card before reader to read from addresses {}".format(addresses))
        card = None
        while True:
            (stat, tag_type) = self.request(self.REQIDL)

            if stat != self.OK:
                continue

            (stat, raw_uid) = self.anticoll()

            if stat == self.OK:
                card = CardData(raw_uid, tag_type)

                if self.select_tag(card.uid) == self.OK:
                    key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]

                    addresses = addresses if addresses is not None else range(64)
                    for i in addresses:
                        if self.auth(self.AUTHENT1A, i, key, card.uid) == self.OK:
                            data = bytes(self.read(i))
                            card.set_data(i, data)
                            self.stop_crypto1()
                        else:
                            print("Authentication error for address {}".format(i))
                else:
                    print("Failed to select tag")
                    return None

            return card

    def write_data(self, data):
        """
        Writes specified "data" to card
        :param data: dict with key - address, value - 16 bytes of data in binary string (hex)
        :return: CardData instance
        """
        print("Place card before reader to write to addresses {}".format(data.keys()))
        while True:

            (stat, tag_type) = self.request(self.REQIDL)

            if stat != self.OK:
                continue

            (stat, raw_uid) = self.anticoll()

            if stat == self.OK:
                print("Card detected")
                card = CardData(raw_uid, tag_type)

                if self.select_tag(card.uid) == self.OK:
                    key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]

                    for addr, value in data.items():
                        if self.auth(self.AUTHENT1A, addr, key, card.uid) == self.OK:
                            card.set_data(addr, value)
                            stat = self.write(addr, value)
                            self.stop_crypto1()
                            if stat == self.OK:
                                print("Data written to card for address {}".format(addr))
                            else:
                                print("Failed to write data to card for address {}".format(addr))
                        else:
                            print("Authentication error for address {}".format(addr))
                else:
                    print("Failed to select tag")
Beispiel #34
0
class MFRC522:

	OK = 0
	NOTAGERR = 1
	ERR = 2

	REQIDL = 0x26
	REQALL = 0x52
	AUTHENT1A = 0x60
	AUTHENT1B = 0x61

	def __init__(self, sck, mosi, miso, rst, cs):

		self.sck = Pin(sck, Pin.OUT)
		self.mosi = Pin(mosi, Pin.OUT)
		self.miso = Pin(miso)
		self.rst = Pin(rst, Pin.OUT)
		self.cs = Pin(cs, Pin.OUT)

		self.rst.value(0)
		self.cs.value(1)

		board = uname()[0]

		if board == 'WiPy' or board == 'LoPy' or board == 'FiPy':
			self.spi = SPI(0)
			self.spi.init(SPI.MASTER, baudrate=1000000, pins=(self.sck, self.mosi, self.miso))
		elif board == 'esp8266' or board == 'esp32':
			self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=self.sck, mosi=self.mosi, miso=self.miso)
			self.spi.init()
		else:
			raise RuntimeError("Unsupported platform")

		self.rst.value(1)
		self.init()

	def _wreg(self, reg, val):

		self.cs.value(0)
		self.spi.write(b'%c' % int(0xff & ((reg << 1) & 0x7e)))
		self.spi.write(b'%c' % int(0xff & val))
		self.cs.value(1)

	def _rreg(self, reg):

		self.cs.value(0)
		self.spi.write(b'%c' % int(0xff & (((reg << 1) & 0x7e) | 0x80)))
		val = self.spi.read(1)
		self.cs.value(1)

		return val[0]

	def _sflags(self, reg, mask):
		self._wreg(reg, self._rreg(reg) | mask)

	def _cflags(self, reg, mask):
		self._wreg(reg, self._rreg(reg) & (~mask))

	def _tocard(self, cmd, send):

		recv = []
		bits = irq_en = wait_irq = n = 0
		stat = self.ERR

		if cmd == 0x0E:
			irq_en = 0x12
			wait_irq = 0x10
		elif cmd == 0x0C:
			irq_en = 0x77
			wait_irq = 0x30

		self._wreg(0x02, irq_en | 0x80)
		self._cflags(0x04, 0x80)
		self._sflags(0x0A, 0x80)
		self._wreg(0x01, 0x00)

		for c in send:
			self._wreg(0x09, c)
		self._wreg(0x01, cmd)

		if cmd == 0x0C:
			self._sflags(0x0D, 0x80)

		i = 2000
		while True:
			n = self._rreg(0x04)
			i -= 1
			if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
				break

		self._cflags(0x0D, 0x80)

		if i:
			if (self._rreg(0x06) & 0x1B) == 0x00:
				stat = self.OK

				if n & irq_en & 0x01:
					stat = self.NOTAGERR
				elif cmd == 0x0C:
					n = self._rreg(0x0A)
					lbits = self._rreg(0x0C) & 0x07
					if lbits != 0:
						bits = (n - 1) * 8 + lbits
					else:
						bits = n * 8

					if n == 0:
						n = 1
					elif n > 16:
						n = 16

					for _ in range(n):
						recv.append(self._rreg(0x09))
			else:
				stat = self.ERR

		return stat, recv, bits

	def _crc(self, data):

		self._cflags(0x05, 0x04)
		self._sflags(0x0A, 0x80)

		for c in data:
			self._wreg(0x09, c)

		self._wreg(0x01, 0x03)

		i = 0xFF
		while True:
			n = self._rreg(0x05)
			i -= 1
			if not ((i != 0) and not (n & 0x04)):
				break

		return [self._rreg(0x22), self._rreg(0x21)]

	def init(self):

		self.reset()
		self._wreg(0x2A, 0x8D)
		self._wreg(0x2B, 0x3E)
		self._wreg(0x2D, 30)
		self._wreg(0x2C, 0)
		self._wreg(0x15, 0x40)
		self._wreg(0x11, 0x3D)
		self.antenna_on()

	def reset(self):
		self._wreg(0x01, 0x0F)

	def antenna_on(self, on=True):

		if on and ~(self._rreg(0x14) & 0x03):
			self._sflags(0x14, 0x03)
		else:
			self._cflags(0x14, 0x03)

	def request(self, mode):

		self._wreg(0x0D, 0x07)
		(stat, recv, bits) = self._tocard(0x0C, [mode])

		if (stat != self.OK) | (bits != 0x10):
			stat = self.ERR

		return stat, bits

	def anticoll(self):

		ser_chk = 0
		ser = [0x93, 0x20]

		self._wreg(0x0D, 0x00)
		(stat, recv, bits) = self._tocard(0x0C, ser)

		if stat == self.OK:
			if len(recv) == 5:
				for i in range(4):
					ser_chk = ser_chk ^ recv[i]
				if ser_chk != recv[4]:
					stat = self.ERR
			else:
				stat = self.ERR

		return stat, recv

	def select_tag(self, ser):

		buf = [0x93, 0x70] + ser[:5]
		buf += self._crc(buf)
		(stat, recv, bits) = self._tocard(0x0C, buf)
		return self.OK if (stat == self.OK) and (bits == 0x18) else self.ERR

	def auth(self, mode, addr, sect, ser):
		return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]

	def stop_crypto1(self):
		self._cflags(0x08, 0x08)

	def read(self, addr):

		data = [0x30, addr]
		data += self._crc(data)
		(stat, recv, _) = self._tocard(0x0C, data)
		return recv if stat == self.OK else None

	def write(self, addr, data):

		buf = [0xA0, addr]
		buf += self._crc(buf)
		(stat, recv, bits) = self._tocard(0x0C, buf)

		if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
			stat = self.ERR
		else:
			buf = []
			for i in range(16):
				buf.append(data[i])
			buf += self._crc(buf)
			(stat, recv, bits) = self._tocard(0x0C, buf)
			if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
				stat = self.ERR

		return stat
Beispiel #35
0
loader.loadAll()
import agnostic
from faces.font_5x7 import font
from st7920 import Screen
from mfrc522 import MFRC522
from machine import Pin,SPI
from engines import dictToCard, cardToDict
from engines import Engine
from regimes.console import ConsoleHost
from vault import BankVault
#TODO CH normalise this story module info into one place (e.g. loader, or via milecastles.loadStory)
from stories.corbridge import story
agnostic.collect()

spi = SPI(1, baudrate=1000000, polarity=0, phase=0)
spi.init()
agnostic.collect()

reader = MFRC522(spi=spi, gpioRst=0, gpioCs=2)
agnostic.collect()

vault = BankVault(reader)
agnostic.collect()

screen = Screen(spi=spi, slaveSelectPin=Pin(15))
agnostic.collect()

# TODO CH remove this test function (actual plotter is in avatap engine)
def plotter(x,y):
    screen.plot(x,y)
Beispiel #36
0
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

from machine import Pin, SPI
from gd import *

# Initialize the SPI Bus (on Pyboard)
# Hardware SPI
spi = SPI(2) # MOSI=Y8, MISO=Y7, SCK=Y6, SS=Y5
spi.init( SPI.MASTER, baudrate=2000000, phase=0, polarity=0 )
# We must manage the SS signal ourself
ss = Pin( Pin.board.Y5, Pin.OUT )


# Gameduino Lib
gd = Gameduino( spi, ss )
gd.begin()
gd.ascii()

gd.putstr( 5 ,  0, "  *** DEMOs ***" )
gd.putstr( 5 ,  1, " 04_demo/ascii/scrsize.py " )
gd.putstr( 0,   5, ''.join(["%s         " % i for i in range(6)]) )
gd.putstr( 0,   6, '0123456789'*6 )
for line in range( 38 ):
	gd.putstr( 0,line, "%2s:" % line )
Beispiel #37
0
# Drawing shapes using the Framebuffer

# VCC GND STM32F407ZGT6
from machine import Pin, SPI
spi = SPI(2)
spi.init(baudrate=2000000, polarity=0, phase=0)
cs = Pin('B12', Pin.OUT)
rst = Pin('B11', Pin.OUT)
bl = Pin('B1', Pin.OUT, value=1)  # backlight on

# with framebuffer
import hx1230_fb
lcd = hx1230_fb.HX1230_FB_SPI(spi, cs, rst)

# 8x8 circles, repeated using blit
# ..####..
# .#....#.
# #......#
# #......#
# #......#
# #......#
# .#....#.
# ..####..
import framebuf
lcd.clear()
circle_buf = bytearray(8)
circle_fbuf = framebuf.FrameBuffer(circle_buf, 8, 8, framebuf.MONO_VLSB)
circle_fbuf.hline(2,0,4,1)
circle_fbuf.pixel(1,1,1)
circle_fbuf.pixel(6,1,1)
circle_fbuf.vline(0,2,4,1)
Beispiel #38
0
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import gc
from machine import Pin, SPI
from gd import Gameduino, RAM_CHR, RAM_PAL

# Initialize the SPI Bus (on Pyboard)
spi = SPI(2) # MOSI=Y8, MISO=Y7, SCK=Y6, SS=Y5
spi.init( baudrate=2000000, phase=0, polarity=0 )
# We must manage the SS signal ourself
sel = Pin( Pin.board.Y5, Pin.OUT )

# Gameduino Lib
gd = Gameduino( spi, sel )
print( "Initializing...")
gd.begin()
print( "Initializing ASCII...")
gd.ascii()

# Print a string
gd.putstr( 5 ,  0, "  *** DEMOs ***" )
gd.putstr( 5 ,  1, "04_demo/ascii/dump.py" )
gd.putstr( 10, 10, "MicroPython goes VGA !" )