from machine import Pin
from utime import sleep_ms, ticks_us
import rp2
import struct
import uctypes
from myDMA import myDMA
LCD_RD = 8
LCD_WR = 9
LCD_RS = 10
LCD_CS = 11
LCD_RST = 12
BMP_WIDTH = 240
BMP_HEIGHT = 320
BUF_LINE = 32
BUF_SIZE = BMP_WIDTH * BUF_LINE * 3
PIO0_BASE = 0x50200000
PIO1_BASE = 0x50300000
TXF0 = 0x010
TXF1 = 0x014
@rp2.asm_pio(out_init=(rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW),
sideset_init=rp2.PIO.OUT_HIGH,
out_shiftdir=rp2.PIO.SHIFT_RIGHT,
pull_thresh=8,
autopull=True)
def lcd_write_bus1():
out(pins, 8).side(0)
nop().side(1)
@rp2.asm_pio(out_init=(rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW,
rp2.PIO.OUT_LOW),
sideset_init=rp2.PIO.OUT_HIGH,
out_shiftdir=rp2.PIO.SHIFT_LEFT,
in_shiftdir=rp2.PIO.SHIFT_LEFT)
def lcd_write_bus2():
pull().side(0)
out(x, 29).side(0)
pull().side(0)
out(y, 27).side(0)
out(isr, 3).side(0)
in_(x, 5).side(0)
mov(x, isr).side(0)
pull().side(0)
out(isr, 29).side(0)
in_(y, 3).side(0)
mov(pins, isr).side(0)
nop().side(1)
mov(pins, x).side(0)
nop().side(1)
def bmp_load(file_name):
with open(file_name, 'rb') as bmp_file:
offset = read_bmp_header(bmp_file)
if offset != False:
bmp_draw(bmp_file, offset)
def bmp_draw(bmp_file, offset):
address_set(0, 0, BMP_WIDTH, BMP_HEIGHT)
lcd_cs.value(0)
lcd_rs.value(1)
sm1.active(0)
sm2.active(1)
bmp_file.seek(offset)
start = ticks_us()
dma = myDMA(0, timer=0,clock_MUL=1, clock_DIV=5)
dma.setCtrl(dst_inc=False, data_size=1)
for i in range(BMP_HEIGHT / BUF_LINE):
bmp = bmp_file.read(BUF_SIZE)
dma.move(uctypes.addressof(bmp), PIO0_BASE+TXF1, BUF_SIZE, start=True)
while dma.isBusy():
pass
end = ticks_us()
sm2.active(0)
sm1.active(1)
length_us = end - start
print('{} s'.format(length_us/1000000))
def read_bmp_header(bmp_file):
file_type = struct.unpack('<h', bmp_file.read(2))[0]
print('file type = ', hex(file_type))
if file_type != 0x4d42:
return False
file_size = struct.unpack('<i', bmp_file.read(4))[0]
print('file size(kbyte) = ', file_size / 1024)
reserved = bmp_file.read(4)
offset = struct.unpack('<i', bmp_file.read(4))[0]
print('offset = ', offset)
header_size = struct.unpack('<i', bmp_file.read(4))[0]
print('header size = ', header_size)
if header_size != 40:
return False
bmp_width = struct.unpack('<i', bmp_file.read(4))[0]
print('bmp width = ', bmp_width)
if bmp_width != BMP_WIDTH:
return False
bmp_height = struct.unpack('<i', bmp_file.read(4))[0]
print('bmp height = ', bmp_height)
if bmp_height != BMP_HEIGHT:
return False
planes = struct.unpack('<h', bmp_file.read(2))[0]
print('planes = ', planes)
if planes != 1:
return False
bmp_depth = struct.unpack('<h', bmp_file.read(2))[0]
print('bmp depth = ', bmp_depth)
compression = struct.unpack('<i', bmp_file.read(4))[0]
print('compression = ', compression)
if compression != 0:
return False
return offset
def lcd_write_com(d):
lcd_rs.value(0)
sm1.put(d)
def lcd_write_data(d):
lcd_rs.value(1)
sm1.put(d)
def address_set(x1, y1, x2, y2):
lcd_write_com(0x2a)
lcd_write_data(x1 >> 8)
lcd_write_data(x1 & 0xFF)
lcd_write_data(x2 >> 8)
lcd_write_data(x2 & 0xFF)
lcd_write_com(0x2b)
lcd_write_data(y1 >> 8)
lcd_write_data(y1 & 0xFF)
lcd_write_data(y2 >> 8)
lcd_write_data(y2 & 0xFF)
lcd_write_com(0x2c)
def lcd_init():
lcd_rst.value(1)
sleep_ms(5)
lcd_rst.value(0)
sleep_ms(15)
lcd_rst.value(1)
sleep_ms(15)
lcd_cs.value(1)
lcd_wr.value(1)
lcd_cs.value(0)
lcd_write_com(0xcb)
lcd_write_data(0x39)
lcd_write_data(0x2c)
lcd_write_data(0x00)
lcd_write_data(0x34)
lcd_write_data(0x02)
lcd_write_com(0xcf)
lcd_write_data(0x00)
lcd_write_data(0xc1)
lcd_write_data(0x30)
lcd_write_com(0xe8)
lcd_write_data(0x85)
lcd_write_data(0x00)
lcd_write_data(0x78)
lcd_write_com(0xea)
lcd_write_data(0x00)
lcd_write_data(0x00)
lcd_write_com(0xed)
lcd_write_data(0x64)
lcd_write_data(0x03)
lcd_write_data(0x12)
lcd_write_data(0x81)
lcd_write_com(0xf7)
lcd_write_data(0x20)
lcd_write_com(0xc0)
lcd_write_data(0x23)
lcd_write_com(0xc1)
lcd_write_data(0x10)
lcd_write_com(0xc5)
lcd_write_data(0x3e)
lcd_write_data(0x28)
lcd_write_com(0xc7)
lcd_write_data(0x86)
lcd_write_com(0x36)
lcd_write_data(0x48)
lcd_write_com(0x3a)
lcd_write_data(0x55)
lcd_write_com(0xb1)
lcd_write_data(0x00)
lcd_write_data(0x18)
lcd_write_com(0xb6)
lcd_write_data(0x08)
lcd_write_data(0x82)
lcd_write_data(0x27)
lcd_write_com(0x11)
sleep_ms(120)
lcd_write_com(0x29)
lcd_write_com(0x2c)
lcd_rd = Pin(LCD_RD, Pin.OUT, value = 1)
lcd_wr = Pin(LCD_WR, Pin.OUT, value = 1)
lcd_rs = Pin(LCD_RS, Pin.OUT, value = 1)
lcd_cs = Pin(LCD_CS, Pin.OUT, value = 1)
lcd_rst = Pin(LCD_RST, Pin.OUT, value = 1)
for i in range(9):
Pin(i, Pin.OUT, value = 1)
sm1 = rp2.StateMachine(0, lcd_write_bus1, out_base=Pin(0), sideset_base=Pin(9))
sm2 = rp2.StateMachine(1, lcd_write_bus2, out_base=Pin(0), sideset_base=Pin(9))
sm1.active(1)
lcd_init()
bmp_load('sample.bmp')