Example #1
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
Example #2
0
def main():
    '''
    Decode and draw the jpg on the display
    '''
    try:
        # Turn display power
        axp = axp202c.PMU(address=0x34)
        axp.enablePower(axp202c.AXP192_LDO2)
        # Set backlight voltage
        axp.setDC3Voltage(3000)

        spi = SPI(2, baudrate=60000000, sck=Pin(18), mosi=Pin(23))

        # initialize display
        tft = ili9342c.ILI9342C(spi,
                                320,
                                240,
                                reset=Pin(33, Pin.OUT),
                                cs=Pin(5, Pin.OUT),
                                dc=Pin(15, Pin.OUT),
                                rotation=0)

        # enable display and clear screen
        tft.init()

        # display jpg
        tft.jpg("bigbuckbunny.jpg", 0, 0, ili9342c.SLOW)

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Example #3
0
def main():

    try:

        spi = SPI(2, baudrate=30000000, sck=Pin(18), mosi=Pin(19))

        tft = st7789.ST7789(spi,
                            135,
                            240,
                            reset=Pin(23, Pin.OUT),
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(16, Pin.OUT),
                            backlight=Pin(4, Pin.OUT),
                            rotation=3)

        # enable display and clear screen
        tft.init()
        tft.fill(st7789.BLACK)

        row = 0
        tft.write(font_16, "abcdefghijklmnopqrst", 0, row)
        row += font_16.HEIGHT

        tft.write(font_32, "abcdefghij", 0, row)
        row += font_32.HEIGHT

        tft.write(font_64, "abcd", 0, row)
        row += font_64.HEIGHT

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Example #4
0
def main():
    '''
    Decode and draw jpg on display
    '''
    try:
        spi = SPI(2, baudrate=30000000, sck=Pin(18), mosi=Pin(19))

        tft = st7789.ST7789(spi,
                            135,
                            240,
                            reset=Pin(23, Pin.OUT),
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(16, Pin.OUT),
                            backlight=Pin(4, Pin.OUT),
                            rotation=3)

        # enable display and clear screen
        tft.init()

        # display jpg
        tft.jpg("bigbuckbunny.jpg", 0, 0, st7789.SLOW)

    finally:
        # shutdown spi
        spi.deinit()
Example #5
0
def main():
    '''
    Decode and draw jpg on display
    '''
    try:
        # Turn on display backlight
        axp = axp202c.PMU()
        axp.enablePower(axp202c.AXP202_LDO2)

        # initialize display spi port
        spi = SPI(
            2,
            baudrate=32000000,
            sck=Pin(18, Pin.OUT),
            mosi=Pin(19, Pin.OUT))

        # configure display
        tft = st7789.ST7789(
            spi,
            240,
            240,
            cs=Pin(5, Pin.OUT),
            dc=Pin(27, Pin.OUT),
            backlight=Pin(12, Pin.OUT),
            rotation=2)

        # enable display and clear screen
        tft.init()

        # display jpg
        tft.jpg("bigbuckbunny.jpg", 0, 0, st7789.SLOW)

    finally:
        # shutdown spi
        spi.deinit()
    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
Example #7
0
class MAX6675:
    def __init__(self, sck, mosi, miso, cs):
        '''
        self.spi = SPI(1, baudrate=200000, polarity=0, phase=0)
        self.spi.init(baudrate=200000) # set the baudrate
        # (SPI(0) 仅用于内部的 FlashROM。)
        '''
        self.cs = cs
        self.cs.on()  # 使能引脚拉高self.cs = cs
        self.spi = SPI(1, baudrate=100000, polarity=1, phase=0)
        # self.spi = SPI(-1, baudrate=1000000, polarity=1,
        #        phase=0, sck=sck, mosi=mosi, miso=miso)
        self.connect = False

    def read_temperature(self, ):
        """
        读取一次温度(摄氏度),读取错误或者热电偶异常均返回4095
        """
        self.cs.off()  # CS引脚检测到下降沿后停止转换。随后在sck时钟控制下输出16位数据
        value = self.spi.read(2)  # 读取两个字节
        self.cs.on()

        temp = value[0] << 8 | value[1]
        self.connect = True if (temp & MAX6675_CONNECT) == 0 else False
        gc.collect()
        if self.connect == True:  # 没检测到电热偶
            return ((temp & 0x7FFF) >> 3) >> 2  # 测得的温度单位是0.25,所以要乘以0.25(即除以4)
        else:
            return 4095

    def __del__(self, ):
        self.spi.deinit()   # 关闭spi
Example #8
0
def main():
    '''
    Decode and draw jpg on display
    '''
    try:
        spi = SPI(2, baudrate=30000000, sck=Pin(18), mosi=Pin(19))

        tft = st7789.ST7789(spi,
                            135,
                            240,
                            reset=Pin(23, Pin.OUT),
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(16, Pin.OUT),
                            backlight=Pin(4, Pin.OUT),
                            rotation=3,
                            buffer_size=30 * 30 * 2)

        # enable display and clear screen
        tft.init()

        # display jpg in random locations
        while True:
            tft.rotation(random.randint(0, 4))
            tft.jpg("alien.jpg", random.randint(0,
                                                tft.width() - 30),
                    random.randint(0,
                                   tft.height() - 30), st7789.FAST)

    finally:
        # shutdown spi
        spi.deinit()
def load_bitstream(bitstream):
    filestream = None
    if type(bitstream) == str:
        filestream = open(bitstream, "rb")
    elif type(bitstream) == FileIO:
        filestream = bitstream
    else:
        raise ValueError("bitstream must be filename name or file handle")

    spi = SPI(hwice40.SPI_ID, TRANSFER_RATE)

    hwice40.chip_select(False)
    hwice40.reset(True)
    sleep(0.1)
    hwice40.reset(False)
    hwice40.chip_select(True)
    spi.write(b"\x00")
    hwice40.chip_select(False)
    sleep(0.1)
    if hwice40.done_state():
        print("Error resetting fpga")
        return False
    while True:
        bitstreampart = filestream.read(
            TRANSFER_SIZE)  #TODO: change to readinto to resuse single buffer
        if not bitstreampart:
            break
        spi.write(bitstreampart)
    hwice40.chip_select(True)
    spi.write(bytes(10 * [0]))
    spi.deinit()
    del (spi)
    return hwice40.done_state()
    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
Example #11
0
def main():
    '''
    Draw and move sprite
    '''
    try:

        spi = SPI(1, baudrate=30000000, sck=Pin(18), mosi=Pin(19))

        # initialize display
        tft = st7789.ST7789(
            spi,
            135,
            240,
            reset=Pin(23, Pin.OUT),
            cs=Pin(5, Pin.OUT),
            dc=Pin(16, Pin.OUT),
            backlight=Pin(4, Pin.OUT),
            rotation=0,
            buffer_size=64*64*2)

        # enable display and clear screen
        tft.init()
        tft.fill(st7789.BLACK)

        # create toast spites in random positions
        sprites = [
            toast(TOASTERS, 135-64, 0),
            toast(TOAST, 135-64*2, 80),
            toast(TOASTERS, 135-64*4, 160)
        ]

        # move and draw sprites
        while True:
            for man in sprites:
                bitmap = man.sprites[man.step]
                tft.fill_rect(
                    man.x+bitmap.WIDTH-man.speed,
                    man.y,
                    man.speed,
                    bitmap.HEIGHT,
                    st7789.BLACK)

                man.move()

                if man.x > 0:
                    tft.bitmap(bitmap, man.x, man.y)
                else:
                    tft.fill_rect(
                        0,
                        man.y,
                        bitmap.WIDTH,
                        bitmap.HEIGHT,
                        st7789.BLACK)

            time.sleep(0.05)

    finally:
        # shutdown spi
        spi.deinit()
Example #12
0
class MicroPython:

    # Pin definition
    RST_PIN_NO = 26
    DC_PIN_NO = 27
    CS_PIN_NO = 15
    BUSY_PIN_NO = 25

    SCK_PIN_NO = 13
    MOSI_PIN_NO = 14

    def __init__(self):
        # preimport utime
        import utime  # pylint: disable=C0415, W0611
        from machine import Pin  # pylint: disable=C0415
        self.DC_PIN = Pin(self.DC_PIN_NO, Pin.OUT)
        self.CS_PIN = Pin(self.CS_PIN_NO, Pin.OUT, Pin.PULL_UP)
        self.RST_PIN = Pin(self.RST_PIN_NO, Pin.OUT)
        self.BUSY_PIN = Pin(self.BUSY_PIN_NO, Pin.IN)

        self.spi = None

    def digital_write(self, pin, value):
        pin.value(value)

    def digital_read(self, pin):
        return pin.value()

    def spi_writebyte(self, data):
        self.spi.write(data)

    def delay_ms(self, delaytime):
        import utime  # pylint: disable=C0415
        utime.sleep_ms(delaytime)

    def module_init(self):
        if self.spi is None:
            from machine import Pin, SPI  # pylint: disable=C0415
            sck = Pin(self.SCK_PIN_NO, Pin.OUT)
            mosi = Pin(self.MOSI_PIN_NO, Pin.OUT)
            self.spi = SPI(2,
                           baudrate=32000000,
                           polarity=0,
                           phase=0,
                           sck=sck,
                           mosi=mosi)

        return 0

    def module_exit(self):
        self.spi.deinit()
        self.spi = None

        logger.debug("close 5V, Module enters 0 power consumption ...")
        self.RST_PIN.value(0)
        self.DC_PIN.value(0)
Example #13
0
def main():
    try:
        # Turn on display backlight
        axp = axp202c.PMU()
        axp.enablePower(axp202c.AXP202_LDO2)

        # initialize display spi port
        spi = SPI(
            2,
            baudrate=32000000,
            polarity=1,
            phase=0,
            bits=8,
            firstbit=0,
            sck=Pin(18),
            mosi=Pin(19))

        # configure display
        tft = st7789.ST7789(
            spi,
            240,
            240,
            cs=Pin(5, Pin.OUT),
            dc=Pin(27, Pin.OUT),
            backlight=Pin(12, Pin.OUT),
            rotation=2)

        tft.init()

        while True:
            for font in (font1, font2, font3, font4):
                tft.fill(st7789.BLUE)
                line = 0
                col = 0
                for char in range(font.FIRST, font.LAST):
                    tft.text(font, chr(char), col, line, st7789.WHITE, st7789.BLUE)
                    col += font.WIDTH
                    if col > tft.width() - font.WIDTH:
                        col = 0
                        line += font.HEIGHT

                        if line > tft.height()-font.HEIGHT:
                            utime.sleep(3)
                            tft.fill(st7789.BLUE)
                            line = 0
                            col = 0

                utime.sleep(3)

    finally:
        # shutdown spi
        spi.deinit()

        # turn off display backlight
        axp.disablePower(axp202c.AXP202_LDO2)
Example #14
0
def main():
    fast = False

    def display_font(font):
        tft.fill(st7789.BLUE)
        column = 0
        row = 0
        for char in font.MAP:
            tft.bitmap(font, column, row, font.MAP.index(char))
            column += font.WIDTH
            if column >= tft.width() - font.WIDTH:
                row += font.HEIGHT
                column = 0

                if row > tft.height() - font.HEIGHT:
                    row = 0

            if not fast:
                time.sleep(0.05)

    try:
        # Turn power on display power
        axp = axp202c.PMU()
        axp.enablePower(axp202c.AXP202_LDO2)

        # initialize spi port
        spi = SPI(1,
                  baudrate=32000000,
                  sck=Pin(18, Pin.OUT),
                  mosi=Pin(19, Pin.OUT))

        # configure display
        tft = st7789.ST7789(spi,
                            240,
                            240,
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(27, Pin.OUT),
                            backlight=Pin(12, Pin.OUT),
                            rotation=2,
                            buffer_size=66 * 32 * 2)

        tft.init()

        while True:
            for font in [font_16, font_32, font_64]:
                display_font(font)

            fast = not fast

    finally:
        # shutdown spi
        spi.deinit()
        # turn off display power
        axp.disablePower(axp202c.AXP202_LDO2)
Example #15
0
def main():
    '''
    Draw and move sprite
    '''
    try:
        # Turn display power
        axp = axp202c.PMU(address=0x34)
        axp.enablePower(axp202c.AXP192_LDO2)
        # Set backlight voltage
        axp.setDC3Voltage(3000)

        spi = SPI(2, baudrate=60000000, sck=Pin(18), mosi=Pin(23))

        # initialize display

        tft = ili9342c.ILI9342C(spi,
                                320,
                                240,
                                reset=Pin(33, Pin.OUT),
                                cs=Pin(5, Pin.OUT),
                                dc=Pin(15, Pin.OUT),
                                rotation=0)

        # enable display and clear screen
        tft.init()
        tft.fill(ili9342c.BLACK)

        # create toast spites in random positions
        sprites = [
            toast(TOASTERS, 320 - 64, 0),
            toast(TOAST, 320 - 64 * 2, 80),
            toast(TOASTERS, 320 - 64 * 4, 160)
        ]

        # move and draw sprites
        while True:
            for man in sprites:
                bitmap = man.sprites[man.step]
                tft.fill_rect(man.x + bitmap.WIDTH - man.speed, man.y,
                              man.speed, bitmap.HEIGHT, ili9342c.BLACK)

                man.move()

                if man.x > 0:
                    tft.bitmap(bitmap, man.x, man.y)
                else:
                    tft.fill_rect(0, man.y, bitmap.WIDTH, bitmap.HEIGHT,
                                  ili9342c.BLACK)

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Example #16
0
def main():
    def center(font, s, row, color=st7789.WHITE):
        screen = tft.width()  # get screen width
        width = tft.write_len(font, s)  # get the width of the string
        if width and width < screen:  # if the string < display
            col = tft.width() // 2 - width // 2  # find the column to center
        else:  # otherwise
            col = 0  # left justify

        tft.write(font, s, col, row, color)  # and write the string

    try:
        # Turn power on display power
        axp = axp202c.PMU()
        axp.enablePower(axp202c.AXP202_LDO2)

        # initialize spi port
        spi = SPI(1,
                  baudrate=32000000,
                  sck=Pin(18, Pin.OUT),
                  mosi=Pin(19, Pin.OUT))

        # configure display
        tft = st7789.ST7789(spi,
                            240,
                            240,
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(27, Pin.OUT),
                            backlight=Pin(12, Pin.OUT),
                            rotation=2,
                            buffer_size=16 * 32 * 2)

        # enable display
        tft.init()
        tft.fill(st7789.BLACK)

        # center the name of the first font, using the font
        row = 16
        center(noto_sans, "NotoSans", row, st7789.RED)
        row += noto_sans.HEIGHT

        # center the name of the second font, using the font
        center(noto_serif, "NotoSerif", row, st7789.GREEN)
        row += noto_serif.HEIGHT

        # center the name of the third font, using the font
        center(noto_mono, "NotoSansMono", row, st7789.BLUE)
        row += noto_mono.HEIGHT

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Example #17
0
def initSD():
    counter = 0
    vext_pin = Pin(21, Pin.OUT, value=0)
    cs_lora = Pin(18, Pin.OUT, value=1)  #para desactivar LoRa
    while counter < 3:
        spi = SPI(sck=Pin(5), mosi=Pin(27), miso=Pin(19))
        try:
            sd = sdcard.SDCard(spi, Pin(2, Pin.OUT))
            return sd
        except Exception as e:
            print("Error al montar sd, intento " + str(counter) +
                  " excepcion: " + str(e))
            spi.deinit()
        counter += 1
    return None
Example #18
0
def main():
    '''
    Draw greetings on display cycling thru hershey fonts and colors
    '''
    try:
        # Turn power on display power
        axp = axp202c.PMU()
        axp.enablePower(axp202c.AXP202_LDO2)
        axp.enablePower(axp202c.AXP202_DCDC3)

        # initialize spi port
        spi = SPI(2,
                  baudrate=32000000,
                  polarity=1,
                  phase=0,
                  bits=8,
                  firstbit=0,
                  sck=Pin(18, Pin.OUT),
                  mosi=Pin(19, Pin.OUT))

        # configure display
        tft = st7789.ST7789(spi,
                            240,
                            240,
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(27, Pin.OUT),
                            backlight=Pin(12, Pin.OUT),
                            rotation=2)

        tft.init()
        tft.fill(st7789.BLACK)
        width = tft.width()
        row = 0

        while True:
            row += 32
            color = next(COLORS)
            tft.fill_rect(0, row - 16, width, 32, st7789.BLACK)
            tft.draw(next(FONTS), next(GREETINGS), 0, row, color)

            if row > 192:
                row = 0

            utime.sleep(0.25)

    finally:
        # shutdown spi
        spi.deinit()
Example #19
0
def main():
    def center(font, s, row, color=st7789.WHITE):
        screen = tft.width()  # get screen width
        width = tft.write_len(font, s)  # get the width of the string
        if width and width < screen:  # if the string < display
            col = tft.width() // 2 - width // 2  # find the column to center
        else:  # otherwise
            col = 0  # left justify

        tft.write(font, s, col, row, color)  # and write the string

    try:
        # initialize the SPI
        spi = SPI(1, baudrate=30000000, sck=Pin(18), mosi=Pin(19))

        # confgure the display
        tft = st7789.ST7789(spi,
                            135,
                            240,
                            reset=Pin(23, Pin.OUT),
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(16, Pin.OUT),
                            backlight=Pin(4, Pin.OUT),
                            rotation=3)

        # enable display and clear screen
        tft.init()
        tft.fill(st7789.BLACK)

        # center the name of the first font, using the font
        row = 16
        center(noto_sans, "NotoSans", row, st7789.RED)
        row += noto_sans.HEIGHT

        # center the name of the second font, using the font
        center(noto_serif, "NotoSerif", row, st7789.GREEN)
        row += noto_serif.HEIGHT

        # center the name of the third font, using the font
        center(noto_mono, "NotoSansMono", row, st7789.BLUE)
        row += noto_mono.HEIGHT

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Example #20
0
def test_max7219():
    from machine import Pin, SPI
    import time
    spi = SPI(baudrate=100000,
              polarity=1,
              phase=0,
              mosi=Pin(27),
              sck=Pin(25),
              miso=Pin(33))
    display = Matrix8x8(spi, Pin(26), 1)
    letters = 'abcdefghijklmnopqrstuvwxyz'
    for c in letters + letters.upper():
        display.fill(0)
        display.text(c, 0, 0, 1)
        display.show()
        time.sleep(1)
    spi.deinit()
Example #21
0
class MicroPython:
    def __init__(self):
        # preimport utime
        import utime  # pylint: disable=C0415, W0611
        from machine import Pin  # pylint: disable=C0415
        self.DC_PIN = self.dc = Pin('P20')
        self.dc.mode(Pin.OUT)

        self.CS_PIN = self.cs = Pin('P4')
        self.cs.mode(Pin.OUT)
        self.cs.pull(Pin.PULL_UP)

        self.RST_PIN = self.rst = Pin('P19')
        self.rst.mode(Pin.OUT)

        self.BUSY_PIN = self.busy = Pin('P18')
        self.busy.mode(Pin.IN)

    def digital_write(self, pin, value):
        pin.value(value)

    def digital_read(self, pin):
        return pin.value()

    def spi_writebyte(self, data):
        self.spi.write(bytes(c & 0xff for c in data))

    def delay_ms(self, delaytime):
        import utime  # pylint: disable=C0415
        utime.sleep_ms(delaytime)

    def module_init(self):
        from machine import Pin, SPI  # pylint: disable=C0415
        clk = Pin('P21')
        mosi = Pin('P22')
        self.spi = SPI(0,
                       mode=SPI.MASTER,
                       baudrate=20000000,
                       polarity=0,
                       phase=0,
                       pins=(clk, mosi, None))
        return 0

    def module_exit(self):
        self.spi.deinit()
Example #22
0
    def get_spi(self):
        spi = None

        try:
            spi = SPI(baudrate = 5000000, 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
Example #23
0
def main():
    try:
        # Turn power on display power
        axp = axp202c.PMU()
        axp.enablePower(axp202c.AXP202_LDO2)

        # initialize spi port
        spi = SPI(1,
                  baudrate=32000000,
                  sck=Pin(18, Pin.OUT),
                  mosi=Pin(19, Pin.OUT))

        # configure display
        tft = st7789.ST7789(spi,
                            240,
                            240,
                            cs=Pin(5, Pin.OUT),
                            dc=Pin(27, Pin.OUT),
                            backlight=Pin(12, Pin.OUT),
                            rotation=2)

        tft.init()
        tft.fill(st7789.BLUE)
        row = font_16.HEIGHT

        tft.write(font_16, "abcdefghijklmnopqrst", 0, row, st7789.WHITE,
                  st7789.BLUE)
        row += font_16.HEIGHT

        tft.write(font_32, "abcdefghij", 0, row, st7789.WHITE, st7789.BLUE)
        row += font_32.HEIGHT

        tft.write(font_32, "klmnopqrs", 0, row, st7789.WHITE, st7789.BLUE)
        row += font_32.HEIGHT

        tft.write(font_32, "tuvwxyz", 0, row, st7789.WHITE, st7789.BLUE)
        row += font_32.HEIGHT

        tft.write(font_64, "abcd", 0, row, st7789.WHITE, st7789.BLUE)
        row += font_64.HEIGHT

    finally:
        # shutdown spi
        spi.deinit()
Example #24
0
def main():
    '''
    Draw greetings on display cycling thru hershey fonts and colors
    '''
    try:
        # Turn display power
        axp = axp202c.PMU(address=0x34)
        axp.enablePower(axp202c.AXP192_LDO2)
        # Set backlight voltage
        axp.setDC3Voltage(3000)

        spi = SPI(2, baudrate=60000000, sck=Pin(18), mosi=Pin(23))

        # Configure display
        tft = ili9342c.ILI9342C(spi,
                                320,
                                240,
                                reset=Pin(33, Pin.OUT),
                                cs=Pin(5, Pin.OUT),
                                dc=Pin(15, Pin.OUT),
                                rotation=0)

        tft.init()
        tft.fill(ili9342c.BLACK)
        height = tft.height()
        width = tft.width()
        row = 0

        while True:
            row += 32
            tft.fill_rect(0, row - 16, width, 32, ili9342c.BLACK)
            tft.draw(next(FONTS), next(GREETINGS), 0, row, next(COLORS))

            if row > 192:
                row = 0

            utime.sleep(0.25)

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Example #25
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)
Example #26
0
def main():

    try:
        # Turn display power
        axp = axp202c.PMU(address=0x34)
        axp.enablePower(axp202c.AXP192_LDO2)
        # Set backlight voltage
        axp.setDC3Voltage(3000)

        spi = SPI(2,
                  baudrate=20000000,
                  sck=Pin(18),
                  miso=Pin(38),
                  mosi=Pin(23))

        # initialize and mount the sdcard
        sd_device = sdcard.SDCard(spi, cs=Pin(4), baudrate=20000000)
        uos.mount(sd_device, '/sd')

        # initialize display

        tft = ili9342c.ILI9342C(spi,
                                320,
                                240,
                                cs=Pin(5, Pin.OUT),
                                dc=Pin(15, Pin.OUT),
                                rotation=0,
                                buffer_size=38400)

        tft.init()

        for i in range(1, 2387):
            frame = "/sd/160x120/{:04d}.jpg".format(i)
            tft.jpg(frame, 80, 60, ili9342c.FAST)

    finally:
        # shutdown spi
        if 'spi' in locals():
            spi.deinit()
Example #27
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()
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()
Example #29
0
class osd:
    def __init__(self):
        self.screen_x = const(64)
        self.screen_y = const(20)
        self.cwd = "/"
        self.init_fb()
        self.exp_names = " KMGTE"
        self.mark = bytearray([32, 16, 42])  # space, right triangle, asterisk
        self.read_dir()
        self.spi_read_irq = bytearray([1, 0xF1, 0, 0, 0, 0, 0])
        self.spi_read_btn = bytearray([1, 0xFB, 0, 0, 0, 0, 0])
        self.spi_result = bytearray(7)
        self.spi_enable_osd = bytearray([0, 0xFE, 0, 0, 0, 1])
        self.spi_write_osd = bytearray([0, 0xFD, 0, 0, 0])
        self.spi_channel = const(2)
        self.spi_freq = const(3000000)
        self.init_pinout_sd()
        #self.spi=SPI(self.spi_channel, baudrate=self.spi_freq, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=Pin(self.gpio_sck), mosi=Pin(self.gpio_mosi), miso=Pin(self.gpio_miso))
        self.init_spi()
        alloc_emergency_exception_buf(100)
        self.enable = bytearray(1)
        self.timer = Timer(3)
        self.irq_handler(0)
        self.irq_handler_ref = self.irq_handler  # allocation happens here
        self.spi_request = Pin(0, Pin.IN, Pin.PULL_UP)
        self.spi_request.irq(trigger=Pin.IRQ_FALLING,
                             handler=self.irq_handler_ref)

    def init_spi(self):
        self.spi = SPI(self.spi_channel,
                       baudrate=self.spi_freq,
                       polarity=0,
                       phase=0,
                       bits=8,
                       firstbit=SPI.MSB,
                       sck=Pin(self.gpio_sck),
                       mosi=Pin(self.gpio_mosi),
                       miso=Pin(self.gpio_miso))
        self.cs = Pin(self.gpio_cs, Pin.OUT)
        self.cs.off()

    def get_spi_result(self):
        return self.spi_result

    def get_spi_result2(self):
        self.cs.on()
        self.spi.write_readinto(self.spi_read_btn, self.spi_result)
        self.cs.off()
        return self.spi_result

# A couple of shortcut functions to change directories, useful for TI-99/4A core development.
# After running "import osd", these can be accessed with osd.run.ti_cart() for example.

    def change_dir(self, dir):
        os.chdir(dir)
        print("Current directory changed to {}".format(dir))

    def ti_cart(self):
        self.change_dir("/sd/ti99_4a/cart")

    def ti_grom(self):
        self.change_dir("/sd/ti99_4a/grom")

    def ti_bit(self):
        self.change_dir("/sd/ti99_4a/bitstreams")

# init file browser

    def init_fb(self):
        self.fb_topitem = 0
        self.fb_cursor = 0
        self.fb_selected = -1

    @micropython.viper
    def init_pinout_sd(self):
        self.gpio_cs = const(5)
        self.gpio_sck = const(16)
        self.gpio_mosi = const(4)
        self.gpio_miso = const(12)

    @micropython.viper
    def irq_handler(self, pin):
        p8result = ptr8(addressof(self.spi_result))
        self.cs.on()
        self.spi.write_readinto(self.spi_read_irq, self.spi_result)
        self.cs.off()
        btn_irq = p8result[6]
        if btn_irq & 0x80:  # btn event IRQ flag
            self.cs.on()
            self.spi.write_readinto(self.spi_read_btn, self.spi_result)
            self.cs.off()
            btn = p8result[6]
            p8enable = ptr8(addressof(self.enable))
            if p8enable[0] & 2:  # wait to release all BTNs
                if btn == 1:
                    p8enable[
                        0] &= 1  # clear bit that waits for all BTNs released
            else:  # all BTNs released
                if (btn & 0x78
                    ) == 0x78:  # all cursor BTNs pressed at the same time
                    self.show_dir()  # refresh directory
                    p8enable[0] = (p8enable[0] ^ 1) | 2
                    self.osd_enable(p8enable[0] & 1)
                if p8enable[0] == 1:
                    if btn == 9:  # btn3 cursor up
                        self.start_autorepeat(-1)
                    if btn == 17:  # btn4 cursor down
                        self.start_autorepeat(1)
                    if btn == 1:
                        self.timer.deinit()  # stop autorepeat
                    if btn == 33:  # btn6 cursor left
                        self.updir()
                    if btn == 65:  # btn6 cursor right
                        self.select_entry()

    def start_autorepeat(self, i: int):
        self.autorepeat_direction = i
        self.move_dir_cursor(i)
        self.timer_slow = 1
        self.timer.init(mode=Timer.PERIODIC,
                        period=500,
                        callback=self.autorepeat)

    def autorepeat(self, timer):
        if self.timer_slow:
            self.timer_slow = 0
            self.timer.init(mode=Timer.PERIODIC,
                            period=30,
                            callback=self.autorepeat)
        self.move_dir_cursor(self.autorepeat_direction)
        self.irq_handler(0)  # catch stale IRQ

    def select_entry(self):
        if self.direntries[self.fb_cursor][1]:  # is it directory
            oldselected = self.fb_selected - self.fb_topitem
            self.fb_selected = self.fb_cursor
            try:
                self.cwd = self.fullpath(self.direntries[self.fb_cursor][0])
            except:
                self.fb_selected = -1
            self.show_dir_line(oldselected)
            self.show_dir_line(self.fb_cursor - self.fb_topitem)
            self.init_fb()
            self.read_dir()
            self.show_dir()
        else:
            self.change_file()

    def updir(self):
        if len(self.cwd) < 2:
            self.cwd = "/"
        else:
            s = self.cwd.split("/")[:-1]
            self.cwd = ""
            for name in s:
                if len(name) > 0:
                    self.cwd += "/" + name
        self.init_fb()
        self.read_dir()
        self.show_dir()

    def fullpath(self, fname):
        if self.cwd.endswith("/"):
            return self.cwd + fname
        else:
            return self.cwd + "/" + fname

    def change_file(self):
        oldselected = self.fb_selected - self.fb_topitem
        self.fb_selected = self.fb_cursor
        try:
            filename = self.fullpath(self.direntries[self.fb_cursor][0])
        except:
            filename = False
            self.fb_selected = -1
        self.show_dir_line(oldselected)
        self.show_dir_line(self.fb_cursor - self.fb_topitem)
        if filename:
            if filename.endswith(".bit"):
                self.spi_request.irq(handler=None)
                self.timer.deinit()
                self.enable[0] = 0
                self.osd_enable(0)
                self.spi.deinit()
                tap = ecp5.ecp5()
                tap.prog_stream(open(filename, "rb"), blocksize=1024)
                if filename.endswith("_sd.bit"):
                    os.umount("/sd")
                    for i in bytearray([2, 4, 12, 13, 14, 15]):
                        p = Pin(i, Pin.IN)
                        a = p.value()
                        del p, a
                result = tap.prog_close()
                del tap
                gc.collect()
                #os.mount(SDCard(slot=3),"/sd") # BUG, won't work
                self.init_spi()  # because of ecp5.prog() spi.deinit()
                self.spi_request.irq(trigger=Pin.IRQ_FALLING,
                                     handler=self.irq_handler_ref)
                self.irq_handler(0)  # handle stuck IRQ
            if filename.endswith(".nes") \
            or filename.endswith(".snes") \
            or filename.endswith(".smc") \
            or filename.endswith(".sfc"):
                import ld_nes
                s = ld_nes.ld_nes(self.spi, self.cs)
                s.ctrl(1)
                s.ctrl(0)
                s.load_stream(open(filename, "rb"), addr=0, maxlen=0x101000)
                del s
                gc.collect()
                self.enable[0] = 0
                self.osd_enable(0)
            if filename.startswith(
                    "/sd/ti99_4a/") and filename.lower().endswith(".bin"):
                import ld_ti99_4a
                s = ld_ti99_4a.ld_ti99_4a(self.spi, self.cs)
                s.load_rom_auto(open(filename, "rb"), filename)
                del s
                gc.collect()
                self.enable[0] = 0
                self.osd_enable(0)
            if (filename.startswith("/sd/msx") and filename.endswith(".rom")) \
            or filename.endswith(".mx1"):
                import ld_msx
                s = ld_msx.ld_msx(self.spi, self.cs)
                s.load_msx_rom(open(filename, "rb"))
                del s
                gc.collect()
                self.enable[0] = 0
                self.osd_enable(0)
            if filename.endswith(".z80"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_zxspectrum
                s = ld_zxspectrum.ld_zxspectrum(self.spi, self.cs)
                s.loadz80(filename)
                del s
                gc.collect()
            if filename.endswith(".ora") or filename.endswith(".orao"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_orao
                s = ld_orao.ld_orao(self.spi, self.cs)
                s.loadorao(filename)
                del s
                gc.collect()
            if filename.endswith(".vsf"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_vic20
                s = ld_vic20.ld_vic20(self.spi, self.cs)
                s.loadvsf(filename)
                del s
                gc.collect()
            if filename.endswith(".prg"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_vic20
                s = ld_vic20.ld_vic20(self.spi, self.cs)
                s.loadprg(filename)
                del s
                gc.collect()
            if filename.endswith(".cas"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_trs80
                s = ld_trs80.ld_trs80(self.spi, self.cs)
                s.loadcas(filename)
                del s
                gc.collect()
            if filename.endswith(".cmd"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_trs80
                s = ld_trs80.ld_trs80(self.spi, self.cs)
                s.loadcmd(filename)
                del s
                gc.collect()

    @micropython.viper
    def osd_enable(self, en: int):
        pena = ptr8(addressof(self.spi_enable_osd))
        pena[5] = en & 1
        self.cs.on()
        self.spi.write(self.spi_enable_osd)
        self.cs.off()

    @micropython.viper
    def osd_print(self, x: int, y: int, i: int, text):
        p8msg = ptr8(addressof(self.spi_write_osd))
        a = 0xF000 + (x & 63) + ((y & 31) << 6)
        p8msg[2] = i
        p8msg[3] = a >> 8
        p8msg[4] = a
        self.cs.on()
        self.spi.write(self.spi_write_osd)
        self.spi.write(text)
        self.cs.off()

    @micropython.viper
    def osd_cls(self):
        p8msg = ptr8(addressof(self.spi_write_osd))
        p8msg[3] = 0xF0
        p8msg[4] = 0
        self.cs.on()
        self.spi.write(self.spi_write_osd)
        self.spi.read(1280, 32)
        self.cs.off()

    # y is actual line on the screen
    def show_dir_line(self, y):
        if y < 0 or y >= self.screen_y:
            return
        mark = 0
        invert = 0
        if y == self.fb_cursor - self.fb_topitem:
            mark = 1
            invert = 1
        if y == self.fb_selected - self.fb_topitem:
            mark = 2
        i = y + self.fb_topitem
        if i >= len(self.direntries):
            self.osd_print(0, y, 0, "%64s" % "")
            return
        if self.direntries[i][1]:  # directory
            self.osd_print(
                0, y, invert,
                "%c%-57s     D" % (self.mark[mark], self.direntries[i][0]))
        else:  # file
            mantissa = self.direntries[i][2]
            exponent = 0
            while mantissa >= 1024:
                mantissa >>= 10
                exponent += 1
            self.osd_print(
                0, y, invert,
                "%c%-57s %4d%c" % (self.mark[mark], self.direntries[i][0],
                                   mantissa, self.exp_names[exponent]))

    def show_dir(self):
        for i in range(self.screen_y):
            self.show_dir_line(i)

    def move_dir_cursor(self, step):
        oldcursor = self.fb_cursor
        if step == 1:
            if self.fb_cursor < len(self.direntries) - 1:
                self.fb_cursor += 1
        if step == -1:
            if self.fb_cursor > 0:
                self.fb_cursor -= 1
        if oldcursor != self.fb_cursor:
            screen_line = self.fb_cursor - self.fb_topitem
            if screen_line >= 0 and screen_line < self.screen_y:  # move cursor inside screen, no scroll
                self.show_dir_line(oldcursor - self.fb_topitem)  # no highlight
                self.show_dir_line(screen_line)  # highlight
            else:  # scroll
                if screen_line < 0:  # cursor going up
                    screen_line = 0
                    if self.fb_topitem > 0:
                        self.fb_topitem -= 1
                        self.show_dir()
                else:  # cursor going down
                    screen_line = self.screen_y - 1
                    if self.fb_topitem + self.screen_y < len(self.direntries):
                        self.fb_topitem += 1
                        self.show_dir()

    def read_dir(self):
        self.direntries = []
        ls = sorted(os.listdir(self.cwd))
        for fname in ls:
            stat = os.stat(self.fullpath(fname))
            if stat[0] & 0o170000 == 0o040000:
                self.direntries.append([fname, 1, 0])  # directory
            else:
                self.direntries.append([fname, 0, stat[6]])  # file
            gc.collect()

    # NOTE: this can be used for debugging
    #def osd(self, a):
    #  if len(a) > 0:
    #    enable = 1
    #  else:
    #    enable = 0
    #  self.cs.on()
    #  self.spi.write(bytearray([0,0xFE,0,0,0,enable])) # enable OSD
    #  self.cs.off()
    #  if enable:
    #    self.cs.on()
    #    self.spi.write(bytearray([0,0xFD,0,0,0])) # write content
    #    self.spi.write(bytearray(a)) # write content
    #    self.cs.off()

    def load_console_grom(self):
        gromfile = "/sd/ti99_4a/grom/994AGROM.Bin"
        import ld_ti99_4a
        s = ld_ti99_4a.ld_ti99_4a(self.spi, self.cs)
        s.reset_on()
        print("GROM file: {}".format(gromfile))
        bytes = s.load_stream(open(gromfile, "rb"), 0x10000)
        print("Loaded {} bytes".format(bytes))
        s.reset_off()
        del s
        gc.collect()

    def load_console_rom(self):
        romfile = "/sd/ti99_4a/rom/994AROM.Bin"
        import ld_ti99_4a
        s = ld_ti99_4a.ld_ti99_4a(self.spi, self.cs)
        s.reset_on()
        print("System ROM file: {}".format(romfile))
        bytes = s.load_stream(open(romfile, "rb"), 0)
        print("Loaded {} bytes".format(bytes))
        s.reset_off()
        del s
        gc.collect()

    def load_roms(self):
        romfile = "/sd/ti99_4a/rom/994AROM.Bin"
        gromfile = "/sd/ti99_4a/grom/994AGROM.Bin"
        import ld_ti99_4a
        s = ld_ti99_4a.ld_ti99_4a(self.spi, self.cs)
        s.reset_on()
        # Load ROM
        print("System ROM file: {}".format(romfile))
        bytes = s.load_stream(open(romfile, "rb"), 0)
        print("Loaded {} bytes".format(bytes))
        # Load GROM
        print("GROM file: {}".format(gromfile))
        bytes = s.load_stream(open(gromfile, "rb"), 0x10000)
        print("Loaded {} bytes".format(bytes))
        # remove reset
        s.reset_off()
        del s
        gc.collect()

    def save_mem(self, filename, addr, length):
        import ld_ti99_4a
        old_freq = self.spi_freq
        self.spi_freq = const(100000)
        self.init_spi()
        s = ld_ti99_4a.ld_ti99_4a(self.spi, self.cs)
        print("Saving memory from {} length {} file: {}".format(
            addr, length, filename))
        s.save_stream(open(filename, "wb"), addr, length)
        del s
        self.spi_freq = old_freq
        self.init_spi()
        gc.collect()
Example #30
0
class osd:
    def __init__(self):
        self.screen_x = const(64)
        self.screen_y = const(20)
        self.cwd = "/"
        self.init_fb()
        self.exp_names = " KMGTE"
        self.mark = bytearray([32, 16, 42])  # space, right triangle, asterisk
        self.diskfile = [open("main.py", "rb"),
                         open("main.py", "rb")]  # any dummy file that can open
        self.imgtype = bytearray(
            2)  # [0]=0:.mac/.bin 1638400 bytes, [0]=1:.dsk 819200 bytes
        self.drive = bytearray(1)  # [0]=0:1st drive, [0]=1:2nd drive
        self.conv_dataIn12K = bytearray(12 * 1024)
        # memoryview for each track//16
        datainmv = memoryview(self.conv_dataIn12K)
        self.conv_dataIn = []
        for i in range(5):
            self.conv_dataIn.append(memoryview(datainmv[0:(12 - i) * 1024]))
        self.conv_nibsOut = bytearray(1024)
        dsk2mac.init_nibsOut(self.conv_nibsOut)
        self.track2sector = bytearray(81 * 2)
        self.init_track2sector()
        self.read_dir()
        self.spi_read_irq = bytearray([1, 0xF1, 0, 0, 0, 0, 0])
        self.spi_read_btn = bytearray([1, 0xFB, 0, 0, 0, 0, 0])
        self.spi_read_trackno = bytearray([1, 0xD0, 0, 0, 0, 0, 0])
        self.spi_result = bytearray(7)
        self.spi_enable_osd = bytearray([0, 0xFE, 0, 0, 0, 1])
        self.spi_write_osd = bytearray([0, 0xFD, 0, 0, 0])
        self.spi_write_track = [
            bytearray([0, 0xD1, 0, 0, 0]),
            bytearray([0, 0xD1, 0, 0x60, 0])
        ]
        self.spi_channel = const(2)
        self.spi_freq = const(3000000)
        self.init_pinout_sd()
        self.init_spi()
        alloc_emergency_exception_buf(100)
        self.enable = bytearray(1)
        self.timer = Timer(3)
        self.irq_handler(0)
        self.irq_handler_ref = self.irq_handler  # allocation happens here
        self.spi_request = Pin(0, Pin.IN, Pin.PULL_UP)
        self.spi_request.irq(trigger=Pin.IRQ_FALLING,
                             handler=self.irq_handler_ref)

    def init_spi(self):
        self.spi = SPI(self.spi_channel,
                       baudrate=self.spi_freq,
                       polarity=0,
                       phase=0,
                       bits=8,
                       firstbit=SPI.MSB,
                       sck=Pin(self.gpio_sck),
                       mosi=Pin(self.gpio_mosi),
                       miso=Pin(self.gpio_miso))
        self.cs = Pin(self.gpio_cs, Pin.OUT)
        self.cs.off()
        self.led = Pin(self.gpio_led, Pin.OUT)
        self.led.off()


# init file browser

    def init_fb(self):
        self.fb_topitem = 0
        self.fb_cursor = 0
        self.fb_selected = -1

    @micropython.viper
    def init_track2sector(self):
        p16t2s = ptr16(addressof(self.track2sector))
        offset = 0
        for i in range(0, 81):
            p16t2s[i] = offset
            offset += 12 - i // 16

    @micropython.viper
    def init_pinout_sd(self):
        self.gpio_cs = const(17)
        self.gpio_sck = const(16)
        #self.gpio_mosi = const(4)
        #self.gpio_miso = const(12)
        self.gpio_mosi = const(25)
        self.gpio_miso = const(26)
        self.gpio_led = const(5)

    @micropython.viper
    def update_track(self):
        p8result = ptr8(addressof(self.spi_result))
        p16t2s = ptr16(addressof(self.track2sector))
        p8it = ptr8(addressof(self.imgtype))
        # ask FPGA for current track number
        self.ctrl(4)  # stop cpu
        self.cs.on()
        self.spi.write_readinto(self.spi_read_trackno, self.spi_result)
        self.cs.off()
        drive = 0
        if p8result[6] & 0x80:
            drive = 1
        track = p8result[6] & 0x7F
        if track > 79:
            track = 79
        trackdiv16 = track // 16
        #print("Fetching drive " + str(drive) + " track " + str(track))
        sectors = 12 - trackdiv16
        self.diskfile[drive].seek((2 - p8it[drive]) * p16t2s[track] * 1024)
        # upload data
        self.cs.on()
        self.spi.write(self.spi_write_track[drive])
        if p8it[drive]:  # .dsk
            self.diskfile[drive].readinto(self.conv_dataIn[trackdiv16])
            offset = 0
            for side in range(2):
                for sector in range(sectors):
                    dsk2mac.convert_sector(self.conv_dataIn12K, offset,
                                           self.conv_nibsOut, track, side,
                                           sector)
                    offset += 512
                    self.spi.write(self.conv_nibsOut)
        else:  # .mac
            for side in range(2):
                self.diskfile[drive].readinto(self.conv_dataIn[trackdiv16])
                self.spi.write(self.conv_dataIn[trackdiv16])
        self.cs.off()
        self.ctrl(0)  # resume cpu

    @micropython.viper
    def irq_handler(self, pin):
        p8result = ptr8(addressof(self.spi_result))
        p8drive = ptr8(addressof(self.drive))
        self.cs.on()
        self.spi.write_readinto(self.spi_read_irq, self.spi_result)
        self.cs.off()
        btn_irq = p8result[6]
        if btn_irq & 1:  # drive 1 request
            self.update_track()
        if btn_irq & 0x80:  # btn event IRQ flag
            self.cs.on()
            self.spi.write_readinto(self.spi_read_btn, self.spi_result)
            self.cs.off()
            btn = p8result[6]
            p8enable = ptr8(addressof(self.enable))
            if p8enable[0] & 2:  # wait to release all BTNs
                if btn == 1:
                    p8enable[
                        0] &= 1  # clear bit that waits for all BTNs released
            else:  # all BTNs released
                if (btn & 0x78
                    ) == 0x78:  # all cursor BTNs pressed at the same time
                    self.show_dir()  # refresh directory
                    p8enable[0] = (p8enable[0] ^ 1) | 2
                    self.osd_enable(p8enable[0] & 1)
                if p8enable[0] == 1:
                    if btn == 9:  # btn3 cursor up
                        self.start_autorepeat(-1)
                    if btn == 17:  # btn4 cursor down
                        self.start_autorepeat(1)
                    if btn == 1:
                        self.timer.deinit()  # stop autorepeat
                    if btn == 33:  # btn5 cursor left
                        self.updir()
                    if btn == 65:  # btn6 cursor right 1st drive
                        p8drive[0] = 0
                        self.select_entry()
                    if btn == 3:  # btn1 2nd drive
                        p8drive[0] = 1
                        self.select_entry()

    def start_autorepeat(self, i: int):
        self.autorepeat_direction = i
        self.move_dir_cursor(i)
        self.timer_slow = 1
        self.timer.init(mode=Timer.PERIODIC,
                        period=500,
                        callback=self.autorepeat)

    def autorepeat(self, timer):
        if self.timer_slow:
            self.timer_slow = 0
            self.timer.init(mode=Timer.PERIODIC,
                            period=30,
                            callback=self.autorepeat)
        self.move_dir_cursor(self.autorepeat_direction)
        self.irq_handler(0)  # catch stale IRQ

    def select_entry(self):
        if self.direntries[self.fb_cursor][1]:  # is it directory
            oldselected = self.fb_selected - self.fb_topitem
            self.fb_selected = self.fb_cursor
            try:
                self.cwd = self.fullpath(self.direntries[self.fb_cursor][0])
            except:
                self.fb_selected = -1
            self.show_dir_line(oldselected)
            self.show_dir_line(self.fb_cursor - self.fb_topitem)
            self.init_fb()
            self.read_dir()
            self.show_dir()
        else:
            self.change_file()

    def updir(self):
        if len(self.cwd) < 2:
            self.cwd = "/"
        else:
            s = self.cwd.split("/")[:-1]
            self.cwd = ""
            for name in s:
                if len(name) > 0:
                    self.cwd += "/" + name
        self.init_fb()
        self.read_dir()
        self.show_dir()

    def fullpath(self, fname):
        if self.cwd.endswith("/"):
            return self.cwd + fname
        else:
            return self.cwd + "/" + fname

    def change_file(self):
        oldselected = self.fb_selected - self.fb_topitem
        self.fb_selected = self.fb_cursor
        try:
            filename = self.fullpath(self.direntries[self.fb_cursor][0])
        except:
            filename = False
            self.fb_selected = -1
        self.show_dir_line(oldselected)
        self.show_dir_line(self.fb_cursor - self.fb_topitem)
        if filename:
            if filename.endswith(".mac") or filename.endswith(
                    ".MAC") or filename.endswith(".dsk") or filename.endswith(
                        ".DSK"):
                self.diskfile[self.drive[0]] = open(filename, "rb")
                self.imgtype[self.drive[0]] = 0
                if filename.endswith(".dsk") or filename.endswith(".DSK"):
                    self.imgtype[self.drive[0]] = 1
                #self.update_track()
                self.ctrl(16 << self.drive[0])  # set insert_disk
                self.enable[0] = 0
                self.osd_enable(0)
            if filename.endswith(".bit"):
                self.spi_request.irq(handler=None)
                self.timer.deinit()
                self.enable[0] = 0
                self.osd_enable(0)
                self.spi.deinit()
                import ecp5
                ecp5.prog_stream(open(filename, "rb"), blocksize=1024)
                if filename.endswith("_sd.bit"):
                    os.umount("/sd")
                    for i in bytearray([2, 4, 12, 13, 14, 15]):
                        p = Pin(i, Pin.IN)
                        a = p.value()
                        del p, a
                result = ecp5.prog_close()
                del tap
                gc.collect()
                #os.mount(SDCard(slot=3),"/sd") # BUG, won't work
                self.init_spi()  # because of ecp5.prog() spi.deinit()
                self.spi_request.irq(trigger=Pin.IRQ_FALLING,
                                     handler=self.irq_handler_ref)
                self.irq_handler(0)  # handle stuck IRQ
            if filename.endswith(".nes") \
            or filename.endswith(".snes") \
            or filename.endswith(".smc") \
            or filename.endswith(".sfc"):
                import ld_nes
                s = ld_nes.ld_nes(self.spi, self.cs)
                s.ctrl(1)
                s.ctrl(0)
                s.load_stream(open(filename, "rb"))
                del s
                gc.collect()
                self.enable[0] = 0
                self.osd_enable(0)
            if filename.startswith("/sd/ti99_4a/") and filename.endswith(
                    ".bin"):
                import ld_ti99_4a
                s = ld_ti99_4a.ld_ti99_4a(self.spi, self.cs)
                s.load_rom_auto(open(filename, "rb"), filename)
                del s
                gc.collect()
                self.enable[0] = 0
                self.osd_enable(0)
            if (filename.startswith("/sd/msx") and filename.endswith(".rom")) \
            or filename.endswith(".mx1"):
                import ld_msx
                s = ld_msx.ld_msx(self.spi, self.cs)
                s.load_msx_rom(open(filename, "rb"))
                del s
                gc.collect()
                self.enable[0] = 0
                self.osd_enable(0)
            if filename.endswith(".z80"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_zxspectrum
                s = ld_zxspectrum.ld_zxspectrum(self.spi, self.cs)
                s.loadz80(filename)
                del s
                gc.collect()
            if filename.endswith(".ora") or filename.endswith(".orao"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_orao
                s = ld_orao.ld_orao(self.spi, self.cs)
                s.loadorao(filename)
                del s
                gc.collect()
            if filename.endswith(".vsf"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_vic20
                s = ld_vic20.ld_vic20(self.spi, self.cs)
                s.loadvsf(filename)
                del s
                gc.collect()
            if filename.endswith(".prg"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_vic20
                s = ld_vic20.ld_vic20(self.spi, self.cs)
                s.loadprg(filename)
                del s
                gc.collect()
            if filename.endswith(".cas"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_trs80
                s = ld_trs80.ld_trs80(self.spi, self.cs)
                s.loadcas(filename)
                del s
                gc.collect()
            if filename.endswith(".cmd"):
                self.enable[0] = 0
                self.osd_enable(0)
                import ld_trs80
                s = ld_trs80.ld_trs80(self.spi, self.cs)
                s.loadcmd(filename)
                del s
                gc.collect()

    @micropython.viper
    def osd_enable(self, en: int):
        pena = ptr8(addressof(self.spi_enable_osd))
        pena[5] = en & 1
        self.cs.on()
        self.spi.write(self.spi_enable_osd)
        self.cs.off()

    @micropython.viper
    def osd_print(self, x: int, y: int, i: int, text):
        p8msg = ptr8(addressof(self.spi_write_osd))
        a = 0xF000 + (x & 63) + ((y & 31) << 6)
        p8msg[2] = i
        p8msg[3] = a >> 8
        p8msg[4] = a
        self.cs.on()
        self.spi.write(self.spi_write_osd)
        self.spi.write(text)
        self.cs.off()

    @micropython.viper
    def osd_cls(self):
        p8msg = ptr8(addressof(self.spi_write_osd))
        p8msg[3] = 0xF0
        p8msg[4] = 0
        self.cs.on()
        self.spi.write(self.spi_write_osd)
        self.spi.read(1280, 32)
        self.cs.off()

    # y is actual line on the screen
    def show_dir_line(self, y):
        if y < 0 or y >= self.screen_y:
            return
        mark = 0
        invert = 0
        if y == self.fb_cursor - self.fb_topitem:
            mark = 1
            invert = 1
        if y == self.fb_selected - self.fb_topitem:
            mark = 2
        i = y + self.fb_topitem
        if i >= len(self.direntries):
            self.osd_print(0, y, 0, "%64s" % "")
            return
        if self.direntries[i][1]:  # directory
            self.osd_print(
                0, y, invert,
                "%c%-57s     D" % (self.mark[mark], self.direntries[i][0]))
        else:  # file
            mantissa = self.direntries[i][2]
            exponent = 0
            while mantissa >= 1024:
                mantissa >>= 10
                exponent += 1
            self.osd_print(
                0, y, invert,
                "%c%-57s %4d%c" % (self.mark[mark], self.direntries[i][0],
                                   mantissa, self.exp_names[exponent]))

    def show_dir(self):
        for i in range(self.screen_y):
            self.show_dir_line(i)

    def move_dir_cursor(self, step):
        oldcursor = self.fb_cursor
        if step == 1:
            if self.fb_cursor < len(self.direntries) - 1:
                self.fb_cursor += 1
        if step == -1:
            if self.fb_cursor > 0:
                self.fb_cursor -= 1
        if oldcursor != self.fb_cursor:
            screen_line = self.fb_cursor - self.fb_topitem
            if screen_line >= 0 and screen_line < self.screen_y:  # move cursor inside screen, no scroll
                self.show_dir_line(oldcursor - self.fb_topitem)  # no highlight
                self.show_dir_line(screen_line)  # highlight
            else:  # scroll
                if screen_line < 0:  # cursor going up
                    screen_line = 0
                    if self.fb_topitem > 0:
                        self.fb_topitem -= 1
                        self.show_dir()
                else:  # cursor going down
                    screen_line = self.screen_y - 1
                    if self.fb_topitem + self.screen_y < len(self.direntries):
                        self.fb_topitem += 1
                        self.show_dir()

    def read_dir(self):
        self.direntries = []
        ls = sorted(os.listdir(self.cwd))
        for fname in ls:
            stat = os.stat(self.fullpath(fname))
            if stat[0] & 0o170000 == 0o040000:
                self.direntries.append([fname, 1, 0])  # directory
        for fname in ls:
            stat = os.stat(self.fullpath(fname))
            if stat[0] & 0o170000 != 0o040000:
                self.direntries.append([fname, 0, stat[6]])  # file

    # NOTE: this can be used for debugging
    #def osd(self, a):
    #  if len(a) > 0:
    #    enable = 1
    #  else:
    #    enable = 0
    #  self.cs.on()
    #  self.spi.write(bytearray([0,0xFE,0,0,0,enable])) # enable OSD
    #  self.cs.off()
    #  if enable:
    #    self.cs.on()
    #    self.spi.write(bytearray([0,0xFD,0,0,0])) # write content
    #    self.spi.write(bytearray(a)) # write content
    #    self.cs.off()

    def ctrl(self, i):
        self.cs.on()
        self.spi.write(bytearray([0, 0xFF, 0xFF, 0xFF, 0xFF, i]))
        self.cs.off()

    def peek(self, addr, length):
        self.ctrl(4)
        self.ctrl(6)
        self.cs.on()
        self.spi.write(
            bytearray([
                1, (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
                (addr >> 8) & 0xFF, addr & 0xFF, 0
            ]))
        b = bytearray(length)
        self.spi.readinto(b)
        self.cs.off()
        self.ctrl(4)
        self.ctrl(0)
        return b

    def poke(self, addr, data):
        self.ctrl(4)
        self.ctrl(6)
        self.cs.on()
        self.spi.write(
            bytearray([
                0, (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
                (addr >> 8) & 0xFF, addr & 0xFF
            ]))
        self.spi.write(data)
        self.cs.off()
        self.ctrl(4)
        self.ctrl(0)
Example #31
0
spi.init(SPI.MASTER, baudrate=10000000, bits=16, polarity=0, phase=0, pins=None)
print(spi.write_readinto(buffer_w, buffer_r) == 12)
print(buffer_w == buffer_r)

buffer_r = bytearray(12)
spi.init(SPI.MASTER, baudrate=10000000, bits=32, polarity=0, phase=0, pins=None)
print(spi.write_readinto(buffer_w, buffer_r) == 12)
print(buffer_w == buffer_r)

# check for memory leaks...
for i in range (0, 1000):
    spi = SPI(0, SPI.MASTER, baudrate=1000000)

# test deinit
spi = SPI(0, SPI.MASTER, baudrate=1000000)
spi.deinit()
print(spi)

spi = SPI(0, SPI.MASTER, baudrate=1000000)
# next ones must fail
try:
    spi = SPI(0, 10, baudrate=10000000, polarity=0, phase=0)
except:
    print("Exception")

try:
    spi = SPI(0, mode=SPI.MASTER, baudrate=10000000, polarity=1, phase=2)
except:
    print("Exception")

try: