Skip to content

Fix 128 Character Max Paste Into REPL#698

Merged
tannewt merged 6 commits into
adafruit:masterfrom
sommersoft:repl_fix
Mar 26, 2018
Merged

Fix 128 Character Max Paste Into REPL#698
tannewt merged 6 commits into
adafruit:masterfrom
sommersoft:repl_fix

Conversation

@sommersoft
Copy link
Copy Markdown

See Issue #417.

After all that digging through the USB read functions and ASF4, turns out we were just reading to often, before clearing the local USB buffer. usb_bytes_available now checks if the local USB buffer 1) has data per usb_rx_count, and 2) if we have space for a new USB read (64 bytes max).

I also commented out the recurring calls to start_read in both usb_read and read_complete. I don't think we need them, since usb_bytes_available and usb_cdc_background will always call it. Makes it easier to debug in the future, and keeps from having too many hands in the cookie jar. If anyone has objections, easy enough to uncomment. Likewise, if we want to delete them...just as easy.

@jerryneedell
Copy link
Copy Markdown
Collaborator

tried this on a metro_mr_express_revb:

Adafruit CircuitPython 3.0.0-alpha.3-23-gccbe557-dirty on 2018-03-23; Metro M4 Express Rev B (Black) with samd51j19
>>> 
>>> 
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== #123456789ABCDEF
=== 
>>> 
>>> 
>>> 
>>> 
>>> #123456789ABCDEF
>>> #123456789ABCDEF
>>> #123456789ABCDEF
>>> #123456789ABCDEF
>>> #123456789ABCDEF
>>> #123456789ABCDEF
>>> #123456789ABCDEF
>>> #12345678EF     TRUNCATED
>>> #123456789ABCDEF
>>> 

so it seems to work in Paste Mode but still truncates in "normal" REPL -- Is this expected?

@sommersoft
Copy link
Copy Markdown
Author

Thanks for testing @jerryneedell!! I'll go sniffing...

@jerryneedell
Copy link
Copy Markdown
Collaborator

Just for fun - here is a nice example of it working in "Paste Mode"

Adafruit CircuitPython 3.0.0-alpha.3-23-gccbe557-dirty on 2018-03-23; Metro M4 Express Rev B (Black) with samd51j19
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import board
=== import digitalio
=== import busio
=== import time
=== import adafruit_bmp280
=== 
=== # Create library object using our Bus I2C port
=== i2c = busio.I2C(board.SCL, board.SDA)
=== bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c)
=== 
=== # OR create library object using our Bus SPI port
=== #spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
=== #bmp_cs = digitalio.DigitalInOut(board.D10)
=== #bmp280 = adafruit_bmp280.Adafruit_BMP280_SPI(spi, bmp_cs)
=== 
=== # change this to match the location's pressure (hPa) at sea level
=== bmp280.seaLevelhPa = 1013.25
=== 
=== while True:
===     print("\nTemperature: %0.1f C" % bmp280.temperature)
===     print("Pressure: %0.1f hPa" % bmp280.pressure)
===     print("Altitude = %0.2f meters" % bmp280.altitude)
===     time.sleep(2)
=== 

Temperature: 23.9 C
Pressure: 1011.1 hPa
Altitude = 17.35 meters

Temperature: 23.9 C
Pressure: 1011.1 hPa
Altitude = 17.37 meters

@sommersoft
Copy link
Copy Markdown
Author

So, my previous testing was only with continuous strings...testing fail on my part.

Using multiple lines would cause the pyexec_xxx_repl functions to trigger usb_cdc_background which was triggering unwanted reads to the USB buffer. This didn't happen in Paste Mode because it stays in it's own loop before exiting the pyexec_xxx_repl function, thereby not triggering usb_cdc_background.

@jerryneedell you are the ULTIMATE tester. Don't know what we'd do without you... Please give this another thorough run-through.

@jerryneedell
Copy link
Copy Markdown
Collaborator

nailed it ! -- almost -- see all three examples

Press any key to enter the REPL. Use CTRL-D to reload.

Adafruit CircuitPython 3.0.0-alpha.3-24-gf237657-dirty on 2018-03-23; Metro M4 Express Rev B (Black) with samd51j19
>>> 
>>> 
>>> 
>>> import board
>>> import digitalio
>>> import busio
>>> import time
>>> import adafruit_bmp280
>>> 
>>> # Create library object using our Bus I2C port
>>> i2c = busio.I2C(board.SCL, board.SDA)
>>> bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c)
>>> 
>>> # OR create library object using our Bus SPI port
>>> #spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
>>> #bmp_cs = digitalio.DigitalInOut(board.D10)
>>> #bmp280 = adafruit_bmp280.Adafruit_BMP280_SPI(spi, bmp_cs)
>>> 
>>> # change this to match the location's pressure (hPa) at sea level
>>> bmp280.seaLevelhPa = 1013.25
>>> 
>>> print("\nTemperature: %0.1f C" % bmp280.temperature)

Temperature: 25.5 C
>>> print("Pressure: %0.1f hPa" % bmp280.pressure)
Pressure: 1010.8 hPa
>>> print("Altitude = %0.2f meters" % bmp280.altitude)
Altitude = 19.94 meters
>>> 
>>> 

also with Paste Mode

Press any key to enter the REPL. Use CTRL-D to reload.

Adafruit CircuitPython 3.0.0-alpha.3-24-gf237657-dirty on 2018-03-23; Metro M4 Express Rev B (Black) with samd51j19
>>> 
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import board
=== import digitalio
=== import busio
=== import time
=== import adafruit_bmp280
=== 
=== # Create library object using our Bus I2C port
=== i2c = busio.I2C(board.SCL, board.SDA)
=== bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c)
=== 
=== # OR create library object using our Bus SPI port
=== #spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
=== #bmp_cs = digitalio.DigitalInOut(board.D10)
=== #bmp280 = adafruit_bmp280.Adafruit_BMP280_SPI(spi, bmp_cs)
=== 
=== # change this to match the location's pressure (hPa) at sea level
=== bmp280.seaLevelhPa = 1013.25
=== 
=== print("\nTemperature: %0.1f C" % bmp280.temperature)
=== print("Pressure: %0.1f hPa" % bmp280.pressure)
=== print("Altitude = %0.2f meters" % bmp280.altitude)
=== 
=== 

Temperature: 25.6 C
Pressure: 1010.8 hPa
Altitude = 19.71 meters
>>> 

but - sometimes paste mode fails with a syntax error -- I'm not sure why.
This is reminiscent of some early issues we had with REPL sometimes giving syntax errors on Line 1.

Adafruit CircuitPython 3.0.0-alpha.3-24-gf237657-dirty on 2018-03-23; Metro M4 Express Rev B (Black) with samd51j19
>>> 
>>> 
>>> 
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import board
=== import digitalio
=== import busio
=== import time
=== import adafruit_bmp280
=== 
=== # Create library object using our Bus I2C port
=== i2c = busio.I2C(board.SCL, board.SDA)
=== bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c)
=== 
=== # OR create library object using our Bus SPI port
=== #spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
=== #bmp_cs = digitalio.DigitalInOut(board.D10)
=== #bmp280 = adafruit_bmp280.Adafruit_BMP280_SPI(spi, bmp_cs)
=== 
=== # change this to match the location's pressure (hPa) at sea level
=== bmp280.seaLevelhPa = 1013.25
=== 
=== print("\nTemperature: %0.1f C" % bmp280.temperature)
=== print("Pressure: %0.1f hPa" % bmp280.pressure)
=== print("Altitude = %0.2f meters" % bmp280.altitude)
=== 
=== 
=== 
Traceback (most recent call last):
  File "<stdin>", line 1
SyntaxError: invalid syntax
>>> 
>>> 

@jerryneedell
Copy link
Copy Markdown
Collaborator

Note - the occasional paste mode failures are not new to the latest commit. They occurred in the previous one as well. I thought it was user error but now it looks like a possible issue.

@jerryneedell
Copy link
Copy Markdown
Collaborator

the syntax errors I was thinking about were from #124
May or may not be relevant...

@tannewt tannewt self-requested a review March 23, 2018 21:25
Copy link
Copy Markdown
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work! Thank you for figuring this out and improving it.

Comment thread ports/atmel-samd/usb.c Outdated
return true;
}
}
}*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go ahead and delete this.

Comment thread ports/atmel-samd/usb.c Outdated
bool usb_bytes_available(void) {
// Check if the buffer has data, but not enough
// space to hold another read.
if (usb_rx_count > 64) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to use USB_RX_BUF_SIZE here so this changes with it?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do. Or, we can use the EP max packet size constant; any future use of USB HS is what would be the determination of going above 64 bytes per EP buffer. Yes?

Comment thread ports/atmel-samd/usb.c Outdated
/*if (!pending_read && usb_rx_count == USB_RX_BUF_SIZE - 1) {
start_read();
}
}*/
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go ahead and delete this too. Git has it in its history.

Comment thread ports/atmel-samd/usb.c Outdated
if (mp_interrupt_char != -1 && cdc_enabled() && !pending_read) {
start_read();
// Make sure we have space in the buffer
if (usb_rx_count < 64) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use USB_RX_BUF_SIZE here too and merge the condition with the outside if statement. No need to have two.

@sommersoft
Copy link
Copy Markdown
Author

The only change I see so far from the fix to #124 is the addition of VFS gc collection. Could have reintroduced the previous problem. Will keep looking, unless wiser minds chime in...

@tannewt
Copy link
Copy Markdown
Member

tannewt commented Mar 23, 2018

Lets get this in and we can chase the syntax error down separately if we want.

@tannewt
Copy link
Copy Markdown
Member

tannewt commented Mar 23, 2018 via email

@jerryneedell
Copy link
Copy Markdown
Collaborator

No objection from me! Great work on this. I think it will be good for others to use it and see how often the syntax error occurs. For me it is about 25% to 50% of the time but there was a lot of flailing around.

@sommersoft
Copy link
Copy Markdown
Author

So, I pulled back on all of the "futurization" I mentioned earlier in discord. The only SAM chips that run High Speed USB are M7s; no real reason to put that in for now.

Copy link
Copy Markdown
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I really appreciate you tackling this.

Comment thread ports/atmel-samd/usb.c Outdated
// Check if the buffer has data, but not enough
// space to hold another read.
if (usb_rx_count > 64) {
if (usb_rx_count > CDC_BULKOUT_SIZE) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've been awesome with feedback so I'll nitpick just a smidge more. This should be USB_RX_BUF_SIZE - usb_rx_count > CDC_BULKOUT_SIZE here and below. This works now because USB_RX_BUF_SIZE is 128. This will break if we make that buffer bigger.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

USB_RX_BUF_SIZE - usb_rx_count > CDC_BULKOUT_SIZE caused REPL to be non-responsive. Puzzled me until I thought about the truth table.

usb_rx_count = 0  # REPL will always start at zero
USB_RX_BUF_SIZE = 128
CDC_BULKOUT_SIZE = 64

if ((128 - 0) > 64) { return > 0;}

All that was needed was flipping the buffer to the other side of the eval. Tests successfully.

Copy link
Copy Markdown
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, good catch on the flip. One more nitpicky thing for clarity. Great work!

Comment thread ports/atmel-samd/usb.c Outdated
// space to hold another read.
if (usb_rx_count > CDC_BULKOUT_SIZE) {
if (usb_rx_count > USB_RX_BUF_SIZE - CDC_BULKOUT_SIZE) {
return usb_rx_count > 0;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last thing. This will always be true because USB_RX_BUF_SIZE - CDC_BULKOUT_SIZE is always more than zero. So, just return true;.

Copy link
Copy Markdown
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

W0000t!!!! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants