scientifichackers/ampy

ampy commands are pending on windows 10

youngsu999 opened this issue · 2 comments

I want to share my experience how I (may be temporary) solve the ampy command pending issue.

Here is my problem and temporary solution for ampy command pending issue.

My environment

SW:

  • windows 10 professional
  • python 3.6.5
    • ampy 1.0.8
  • CP210x driver v10.1.4

HW:

  • esp32-devkitc_v4
    • firmware: esp32-20180511-v1.9.4.bin

Problem

  • Pending amp commands such as ls, put, get. Sometimes it success (only ls) but most of execution Fails.

Finding the issue

I checkout the source and add the print on library and searched for the point where code was pending.
I Found that the code is pending at the line 189 of pyboard.py. The code is data = self.read_until(1, b'raw REPL; CTRL-B to exit\r\n>').

    def enter_raw_repl(self):
        # Brief delay before sending RAW MODE char if requests
        if _rawdelay > 0:
            time.sleep(_rawdelay)

        self.serial.write(b'\r\x03\x03') # ctrl-C twice: interrupt any running program

        # flush input (without relying on serial.flushInput())
        n = self.serial.inWaiting()
        while n > 0:
            self.serial.read(n)
            n = self.serial.inWaiting()

        self.serial.write(b'\r\x01') # ctrl-A: enter raw REPL
        data = self.read_until(1, b'raw REPL; CTRL-B to exit\r\n>')  # line 189
        if not data.endswith(b'raw REPL; CTRL-B to exit\r\n>'):
            print(data)
            raise PyboardError('could not enter raw repl')

        self.serial.write(b'\x04') # ctrl-D: soft reset
        data = self.read_until(1, b'soft reboot\r\n')
        if not data.endswith(b'soft reboot\r\n'):
            print(data)
            raise PyboardError('could not enter raw repl')
        # By splitting this into 2 reads, it allows boot.py to print stuff,
        # which will show up after the soft reboot and before the raw REPL.
        # Modification from original pyboard.py below:
        #   Add a small delay and send Ctrl-C twice after soft reboot to ensure
        #   any main program loop in main.py is interrupted.
        time.sleep(0.5)
        self.serial.write(b'\x03')
        time.sleep(0.1)           # (slight delay before second interrupt
        self.serial.write(b'\x03')
        # End modification above.
        data = self.read_until(1, b'raw REPL; CTRL-B to exit\r\n')
        if not data.endswith(b'raw REPL; CTRL-B to exit\r\n'):
            print(data)
            raise PyboardError('could not enter raw repl')

I also inspected the inside of self.read_util function but the most suspicious line was a line before. (self.serial.write(b'\r\x01') # ctrl-A: enter raw REPL).
I think For some reason, The develop board missed Ctl-A character and it may fail to enter raw repl mode.

So I modified the function as follows:

    def enter_raw_repl(self):
        # Brief delay before sending RAW MODE char if requests
        if _rawdelay > 0:
            time.sleep(_rawdelay)
        self.serial.write(b'\r\x03\x03') # ctrl-C twice: interrupt any running program
        # flush input (without relying on serial.flushInput())
        n = self.serial.inWaiting()
        while n > 0:
            self.serial.read(n)
            n = self.serial.inWaiting()
->      time.sleep(0.5)
        self.serial.write(b'\r\x01') # ctrl-A: enter raw REPL
->      for i in range(4):
->          time.sleep(0.1)
->          self.serial.write(b'\x01') # send ctl-A for several times
->      self.serial.flushOutput()
        data = self.read_until(1, b'raw REPL; CTRL-B to exit\r\n>')
        # data = self.read_until(1, b'raw REPL; CTRL-B to exit\n>')
        if not data.endswith(b'raw REPL; CTRL-B to exit\r\n>'):
            print(data)
            raise PyboardError('could not enter raw repl')
->      self.serial.flushInput()
        self.serial.write(b'\x04') # ctrl-D: soft reset
        data = self.read_until(1, b'soft reboot\r\n')
   
        if not data.endswith(b'soft reboot\r\n'):
            print(data)
            raise PyboardError('could not enter raw repl')
   
        # By splitting this into 2 reads, it allows boot.py to print stuff,
        # which will show up after the soft reboot and before the raw REPL.
        # Modification from original pyboard.py below:
        #   Add a small delay and send Ctrl-C twice after soft reboot to ensure
        #   any main program loop in main.py is interrupted.
        time.sleep(0.5)
        self.serial.write(b'\x03')
        time.sleep(0.1)           # (slight delay before second interrupt
        self.serial.write(b'\x03')
        # End modification above.
        data = self.read_until(1, b'raw REPL; CTRL-B to exit\r\n')
        if not data.endswith(b'raw REPL; CTRL-B to exit\r\n'):
            print(data)
            raise PyboardError('could not enter raw repl')

And the commands works well.
My opinion is that many pending issues are came from failing to enter the raw_repl mode.

It is just temporal patch and until now i have no idea more proper way to solve it.

I found issues such as #19 #41 #43 and #69 seems to be related. Especially for #19, it is same issue except board model.

Hiya! We are discontinuing support for ampy, and will no longer be maintaining it. We are leaving this repository available for continued use. If you would like to take over supporting it, please contact us on the Adafruit Discord server and we can transfer the repository to you.
If you wish to continue developing it on your own, please fork the repository.