たまたまその上で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じゃない、別シリーズでな。