
たまたまその上でMicroPythonやっていたというだけで「ソフトウエア制御DMAC」のシーケンサと化していたM5Stackです。折角のM5Stackを単なるシーケンサに使うのはモッタイナイ。そこで今回「シーケンサ」ホストを台数に余裕のあるRaspberry Pi Pico機に変更。M5Stackはお役目から解放。
※「MicroPython的午睡」投稿順 Indexはこちら
こういうホストを挿げ替えるような荒業を行うとき、C言語などで制御ソフトを書いていたらと思うと呆然としたでありましょうが、MicroPythonなら恐れるもなにもありません。ちょこちょこと端子名を書き変えたくらいで動作してしまいます。こういうときはMicroPythonサイコー。
でもまターゲットの回路は同じなので信号品質が悪い問題はまったく解決していないんだけれども。
前回と比べ、どこが変わったの?という感じ。
MicroPythonスクリプトが以下に。これまた前回との変更点は、ファイルコンペアでもかけないと差には気づきずらいっす(前回はコードを貼り付けてなかったけど。)
# softDMA_REWRtest.py RpiPico
from machine import SoftI2C, Pin
import sys
import time
IOEX0 = 0x20
IOEX1 = 0x21
IOCONA = 0x0A
IOCONB = 0x0B
IODIRA = 0x00
IODIRB = 0x01
GPIOA = 0x12
GPIOB = 0x13
OLATA = 0x14
OLATB = 0x15
recount = 0
wecount = 0
i2c = SoftI2C(scl=Pin(1), sda=Pin(0), freq=100000)
def isIOEXavailable():
global i2c
lis = i2c.scan()
if (IOEX0 in lis) and (IOEX1 in lis):
return True
return False
def readByte(i2cADR, regADR):
global i2c, recount
bufW = bytes([regADR])
try:
lim = 0
while lim < 5:
if i2c.writeto(i2cADR, bufW) != 1:
lim += 1
time.sleep_us(10) #$$$
else:
break
if lim >= 5:
return -2
bufR = bytearray(1)
ackR = i2c.readfrom_into(i2cADR, bufR)
except OSError:
recount += 1
return -1
return int.from_bytes(bufR, 'little')
def writeByte(i2cADR, regADR, dat):
global i2c, wecount
bufW = bytes([regADR, dat])
try:
lim = 0
ackW = 0
while (lim < 5) and (ackW < 2):
ackW = i2c.writeto(i2cADR, bufW)
lim += 1
time.sleep_us(10) #$$$
if lim >= 5:
return -2
except OSError:
wecount += 1
return -1
return ackW
def letPortsHz():
writeByte(IOEX0, IODIRA, 0xFF)
writeByte(IOEX0, IODIRB, 0xFF)
writeByte(IOEX1, IODIRA, 0xFF)
writeByte(IOEX1, IODIRB, 0xFF)
def letADRbusOutput():
writeByte(IOEX1, OLATA, 0xFF) # initial value, A15-A8
writeByte(IOEX1, OLATB, 0xFF) # initial value, A7-A0
writeByte(IOEX1, IODIRA, 0x00) # DIR=ouput A15-A8
writeByte(IOEX1, IODIRB, 0x00) # DIR=ouput AD7-AD0
def letADRbusInput():
writeByte(IOEX1, IODIRA, 0xFF) # DIR=input A15-A8
writeByte(IOEX1, IODIRB, 0xFF) # DIR=input AD7-AD0
def outputADRbus(adr):
adrH = (adr >> 8) & 0xFF
adrL = adr & 0xFF
writeByte(IOEX1, OLATA, adrH) # output A15-A8
writeByte(IOEX1, OLATB, adrL) # output AD7-AD0
def letDATAbusInput():
writeByte(IOEX1, IODIRB, 0xFF) # AD7-AD0 input
def letDATAbusOutput():
writeByte(IOEX1, OLATB, 0xFF) # initial value, AD7-AD0
writeByte(IOEX1, IODIRB, 0x00) # DIR=ouput AD7-AD0
def outputDATAbus(dat):
dat &= 0xFF
writeByte(IOEX1, OLATB, dat) # output AD7-AD0
def inputDATAbus():
return readByte(IOEX1, GPIOB) # input AD7-AD0
# B0: ALE, B1: IO/M#, B2:RD#, B3:WR#
# B4: RESET#, B5:HOLD, B6:HLDA, B7:---
def enableCONTSIG():
writeByte(IOEX0, OLATB, 0x3E) # NO RESET, HOLD
writeByte(IOEX0, IODIRB, 0xC0) # HLDA, B7: input
def disableCONTSIG(opt):
if opt:
writeByte(IOEX0, OLATB, 0x3E) # NO RESET, HOLD
else:
writeByte(IOEX0, OLATB, 0x1E) # NO RESET, NO HOLD
writeByte(IOEX0, IODIRB, 0xCF) # RESET# HOLD : output
def assertALE():
# NO RESET, HOLD, ALE
while writeByte(IOEX0, OLATB, 0x3F) < 0:
print("ALE")
def assertMEMRD():
# NO RESET, HOLD, IO/M#, RD#
while writeByte(IOEX0, OLATB, 0x38) < 0:
print("MEMRD")
def assertMEMWR():
# NO RESET, HOLD, IO/M#, WR#
while writeByte(IOEX0, OLATB, 0x34) < 0:
print("MEMWR")
def assertRST():
writeByte(IOEX0, OLATB, 0x0E)
def negateCNT(dbg):
# NO RESET, HOLD
while writeByte(IOEX0, OLATB, 0x3E) < 0:
print("NEGCNT ", dbg)
return -1
return 0
def assertM():
writeByte(IOEX0, OLATB, 0x3C) # NO RESET, HOLD, IO/M#=MEM
def isHLDA():
temp = readByte(IOEX0, GPIOB)
return (temp >> 6) & 1
def initDevices():
writeByte(IOEX0, IOCONA, 0x20)
writeByte(IOEX0, IODIRA, 0xFF)
writeByte(IOEX0, IODIRB, 0xCF)
writeByte(IOEX0, OLATA, 0xFF)
writeByte(IOEX0, OLATB, 0x1E)
writeByte(IOEX1, IOCONA, 0x20)
writeByte(IOEX1, IODIRA, 0xFF)
writeByte(IOEX1, IODIRB, 0xFF)
writeByte(IOEX1, OLATA, 0xFF)
writeByte(IOEX1, OLATB, 0xFF)
def wrMEM(adr, dat, opt):
enableCONTSIG()
while isHLDA() == 0:
pass
letADRbusOutput()
outputADRbus(adr)
assertALE()
negateCNT("W1")
outputDATAbus(dat)
assertMEMWR()
negateCNT("W2")
letADRbusInput()
disableCONTSIG(opt)
def rdMEM(adr, opt):
enableCONTSIG()
while isHLDA() == 0:
pass
letADRbusOutput()
outputADRbus(adr)
assertALE()
negateCNT("R1")
letDATAbusInput()
assertMEMRD()
#time.sleep_us(100)
dat = inputDATAbus()
if negateCNT("R2") < 0:
return -1
disableCONTSIG(opt)
return dat
def WrRdTest(startADDR, endADDR):
global wecount, recount
addr = startADDR
dat = 0
while addr < endADDR:
wrMEM(addr, dat, True)
rddat = rdMEM(addr, True)
if rddat < 0:
print("EXIT")
sys.exit(999)
if rddat == dat:
if (addr % 0x100) == 0:
print("VERIFIED ADDRESS: 0x{0:04x}".format(addr))
else:
wecount += 1
#print("ERROR ADDRESS: 0x{0:04x} WR=0x{1:02x} RD=0x{2:02x} {3} {4}".format(addr, dat, rddat, type(dat), type(rddat)))
continue
addr += 1
dat += 1
if dat > 0xFF:
dat = 0
rddat = rdMEM(addr, False)
print("recount:{0} wecount:{1}".format(recount, wecount))
def main():
global i2c
print("SRAM RD/WR test")
print("IO Expander is ", end="")
if not isIOEXavailable():
print("not available.")
else:
print("available.")
initDevices()
WrRdTest(0x0, 0x1000)
if __name__ == "__main__":
main()
まあお引越しできたので、次回こそ真のホスト8085との接続だな。MicroPythonじゃない、別シリーズでな。
MicroPython的午睡(142)M5Stack、SoftI2Cで無理やりSRAM初期化 へ戻る
MicroPython的午睡(144)RP2350-GEEK版MicroPythonの例題 へ進む
