def exec_ftp_command(self, cl): global datasocket global client_busy global my_ip_addr try: collect() data = cl.readline().decode("utf-8").rstrip("\r\n") if len(data) <= 0: # No data, close # This part is NOT CLEAN; there is still a chance that a # closing data connection will be signalled as closing # command connection log_msg(1, "*** No data, assume QUIT") close_client(cl) return if client_busy: # check if another client is busy cl.sendall("400 Device busy.\r\n") # tell so the remote client return # and quit client_busy = True # now it's my turn # check for log-in state may done here, like # if self.logged_in == False and not command in\ # ("USER", "PASS", "QUIT"): # cl.sendall("530 Not logged in.\r\n") # return command = data.split()[0].upper() payload = data[len(command):].lstrip() # partition is missing path = self.get_absolute_path(self.cwd, payload) log_msg(1, "Command={}, Payload={}".format(command, payload)) if command == "USER": # self.logged_in = True cl.sendall("230 Logged in.\r\n") # If you want to see a password,return # "331 Need password.\r\n" instead # If you want to reject an user, return # "530 Not logged in.\r\n" elif command == "PASS": # you may check here for a valid password and return # "530 Not logged in.\r\n" in case it's wrong # self.logged_in = True cl.sendall("230 Logged in.\r\n") elif command == "SYST": cl.sendall("215 UNIX Type: L8\r\n") elif command in ("TYPE", "NOOP", "ABOR"): # just accept & ignore cl.sendall('200 OK\r\n') elif command == "QUIT": cl.sendall('221 Bye.\r\n') close_client(cl) elif command == "PWD" or command == "XPWD": cl.sendall('257 "{}"\r\n'.format(self.cwd)) elif command == "CWD" or command == "XCWD": try: if (uos.stat(path)[0] & 0o170000) == 0o040000: self.cwd = path cl.sendall('250 OK\r\n') else: cl.sendall('550 Fail\r\n') except: cl.sendall('550 Fail\r\n') elif command == "PASV": cl.sendall('227 Entering Passive Mode ({},{},{}).\r\n'.format( self.pasv_data_addr.replace('.', ','), _DATA_PORT >> 8, _DATA_PORT % 256)) self.active = False elif command == "PORT": items = payload.split(",") if len(items) >= 6: self.act_data_addr = '.'.join(items[:4]) if self.act_data_addr == "127.0.1.1": # replace by command session addr self.act_data_addr = self.remote_addr self.DATA_PORT = int(items[4]) * 256 + int(items[5]) cl.sendall('200 OK\r\n') self.active = True else: cl.sendall('504 Fail\r\n') elif command == "LIST" or command == "NLST": if payload.startswith("-"): option = payload.split()[0].lower() path = self.get_absolute_path( self.cwd, payload[len(option):].lstrip()) else: option = "" try: data_client = self.open_dataclient() cl.sendall("150 Directory listing:\r\n") self.send_list_data(path, data_client, command == "LIST" or 'l' in option) cl.sendall("226 Done.\r\n") data_client.close() except: cl.sendall('550 Fail\r\n') if data_client is not None: data_client.close() elif command == "RETR": try: data_client = self.open_dataclient() cl.sendall("150 Opened data connection.\r\n") self.send_file_data(path, data_client) # if the next statement is reached, # the data_client was closed. data_client = None cl.sendall("226 Done.\r\n") except: cl.sendall('550 Fail\r\n') if data_client is not None: data_client.close() elif command == "STOR" or command == "APPE": result = False try: data_client = self.open_dataclient() cl.sendall("150 Opened data connection.\r\n") if path == "/fpga": import ecp5 ecp5.prog_stream(data_client,_CHUNK_SIZE) result = ecp5.prog_close() data_client.close() elif path.startswith("/flash@"): import ecp5 dummy, addr = path.split("@") addr = int(addr) result = ecp5.flash_stream(data_client,addr) ecp5.flash_close() del addr, dummy data_client.close() elif path.startswith("/sd@"): import sdraw dummy, addr = path.split("@") addr = int(addr) sd_raw = sdraw.sdraw() result = sd_raw.sd_write_stream(data_client,addr) del sd_raw, addr, dummy data_client.close() else: self.save_file_data(path, data_client, "w" if command == "STOR" else "a") result = True # if the next statement is reached, # the data_client was closed. data_client = None except: if data_client is not None: data_client.close() if result: cl.sendall("226 Done.\r\n") else: cl.sendall('550 Fail\r\n') del result elif command == "SIZE": try: cl.sendall('213 {}\r\n'.format(uos.stat(path)[6])) except: cl.sendall('550 Fail\r\n') elif command == "STAT": if payload == "": cl.sendall("211-Connected to ({})\r\n" " Data address ({})\r\n" " TYPE: Binary STRU: File MODE: Stream\r\n" " Session timeout {}\r\n" "211 Client count is {}\r\n".format( self.remote_addr, self.pasv_data_addr, _COMMAND_TIMEOUT, len(client_list))) else: cl.sendall("213-Directory listing:\r\n") self.send_list_data(path, cl, True) cl.sendall("213 Done.\r\n") elif command == "DELE": try: uos.remove(path) cl.sendall('250 OK\r\n') except: cl.sendall('550 Fail\r\n') elif command == "RNFR": try: # just test if the name exists, exception if not uos.stat(path) self.fromname = path cl.sendall("350 Rename from\r\n") except: cl.sendall('550 Fail\r\n') elif command == "RNTO": try: uos.rename(self.fromname, path) cl.sendall('250 OK\r\n') except: cl.sendall('550 Fail\r\n') self.fromname = None elif command == "CDUP" or command == "XCUP": self.cwd = self.get_absolute_path(self.cwd, "..") cl.sendall('250 OK\r\n') elif command == "RMD" or command == "XRMD": try: uos.rmdir(path) cl.sendall('250 OK\r\n') except: cl.sendall('550 Fail\r\n') elif command == "MKD" or command == "XMKD": try: uos.mkdir(path) cl.sendall('250 OK\r\n') except: cl.sendall('550 Fail\r\n') elif command == "SITE": if path == "/mount": if self.mount(): cl.sendall('250 OK\r\n') else: cl.sendall('550 Fail\r\n') elif path == "/umount": if self.umount(): cl.sendall('250 OK\r\n') else: cl.sendall('550 Fail\r\n') elif path == "/passthru": import ecp5 ecp5.passthru() cl.sendall('250 OK passthru\r\n') elif path.endswith(".bit") or path.endswith(".bit.gz"): try: import ecp5 if ecp5.prog(path, close=False): if path.startswith("/sd/"): try: self.umount() cl.sendall('111 umount /sd OK\r\n') except: cl.sendall('411 umount /sd Fail\r\n') if ecp5.prog_close(): cl.sendall('250 OK\r\n') else: cl.sendall('550 Fail\r\n') else: cl.sendall('550 Fail\r\n') except: cl.sendall('550 Fail\r\n') else: if path.startswith("/"): exe=path[1:] else: exe=path try: exec(exe) cl.sendall('250 OK '+exe+'\r\n') except: cl.sendall('550 Fail '+exe+'\r\n') del exe else: cl.sendall("502 Unsupported command.\r\n") # log_msg(2, # "Unsupported command {} with payload {}".format(command, # payload)) # handle unexpected errors except Exception as err: log_msg(1, "Exception in exec_ftp_command: {}".format(err)) # tidy up before leaving client_busy = False
(addr >> 8) & 0xFF, addr & 0xFF ])) self.spi.write(data) self.cs.off() self.ctrl(4) self.ctrl(0) def peek(addr, length=1): return run.peek(addr, length) def poke(addr, data): run.poke(addr, data) #bitstream="/sd/mac/bitstreams/ulx3s_v20_85f_mac128.bit" bitstream = "/xyz.bit" try: freq(240 * 1000 * 1000) # 80/160/240 MHz, faster CPU = faster SD card #os.mount(SDCard(slot=3),"/sd") # 1-bit SD mode os.mount( SDCard(), "/sd" ) # 4-bit SD mode (mac bitstream must be flashed or already loaded) import ecp5 ecp5.prog(bitstream) except: print(bitstream + " file not found") gc.collect() run = osd()
def load_fpga(): fpga_config_file = "/sd/ti99_4a/bitstreams/ti994a_ulx3s.bit" print("FPGA file: {}".format(fpga_config_file)) ecp5.prog(fpga_config_file) # ulx3s_85f_spi_ti99_4a.bit") gc.collect()
from machine import Pin, I2C, SDCard, freq from os import mount import time, ntptime, mcp7940, ecp5 freq(240 * 1000 * 1000) sd = SDCard(slot=3) # 1-bit mode mount(sd, "/sd") ecp5.prog("/sd/rtc/ulx3s_12f_i2c_bridge.bit") i2c = I2C(sda=Pin(16), scl=Pin(17), freq=400000) mcp = mcp7940.MCP7940(i2c) mcp.control = 0 mcp.trim = -29 #mcp.battery=1 #print("battery %s" % ("enabled" if mcp.battery else "disabled")) print("trim %+d ppm" % mcp.trim) print("control 0x%02X" % mcp.control) print("setting time.localtime() to NTP time using ntptime.settime()") ntptime.settime() print("after NTP, time.localtime() reads:") print(time.localtime()) print("setting mcp.time=time.localtime()") mcp.stop() mcp.time = time.localtime() print("after setting:") print("battery %s" % ("enabled" if mcp.battery else "disabled")) print("mcp.time reads:") # Read time after setting it, repeat to see time incrementing for i in range(3): print(mcp.time)
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() os.mount(SDCard(slot=3),"/sd") ecp5.prog("/sd/vic20/bitstreams/ulx3s_vic20_32K_85f.bit") gc.collect() vic20=osd()
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() os.mount(SDCard(slot=3), "/sd") ecp5.prog("/sd/nes/bitstreams/nes12f_esp32_darfon.bit") gc.collect() trs80 = osd()
if stat[0] & 0o170000 == 0o040000: self.direntries.append([fname, 1, 0]) # directory else: self.direntries.append([fname, 0, stat[6]]) # file def osd(self, a): if len(a) > 0: enable = 1 else: enable = 0 self.led.on() self.hwspi.write(bytearray([0, 0xFE, 0, enable])) # enable OSD self.led.off() if enable: self.led.on() self.hwspi.write(bytearray([0, 0xF0, 0])) # write content self.hwspi.write(bytearray(a)) # write content self.led.off() # debug to manually write data and # check them with *C0EC #d.led.on(); d.hwspi.write(bytearray([0xd0,0xb2,0x02,0x59,0x17,0x69,0x91,0x9f]));d.led.off() ecp5.prog("apple2.bit.gz") gc.collect() os.mount(SDCard(slot=3), "/sd") #os.chdir("/sd/apple2") d = disk2("/sd/apple2/snack_attack.nib") #d=disk2("disk2.nib")
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 # 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() os.mount(SDCard(slot=3), "/sd") ecp5.prog("/sd/zxspectrum/bitstreams/zxspectrum12f.bit") gc.collect() spectrum = osdzx()