-
Notifications
You must be signed in to change notification settings - Fork 36
OverflowError small int overflow on QT Py SAMD21 #107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I briefly looked at it, it happens on builds without long ints, because it's trying to unpack a 4 bytes buffer into an int, and small ints in Circuitpython are limited to 30 bits, so the maximum is If we don't want to unconditionally reverse #98 we could add a try/except for |
Since the most prominent product photo/gif of the NeoKey 1x4 QT I2C Breakout shows it connected to QT Py SAMD21, I think it's rather urgent that the standard adafruit_seesaw library works for SAMD21. Getting support for the last 2 bits / 2 pins on builds without long ints can wait until a compromise has been found. Instead of just reversing #98, adding a try/except for the special case where the 2 bits are lost, seems like a good compromise for now. My initial effort is along the lines of changing line 217 of seesaw.py into this try/except: try:
ret = struct.unpack(">I", buf)[0]
except OverflowError:
buf[0] = buf[0] & 0x3F
ret = struct.unpack(">I", buf)[0] It works on QT Py SAMD21 with NeoKey 1x4. I am not near a M4 SAMD51 or RP2040 today to test the successful try clause. I am curious if the user will ever see the error? If a print statement were to be added, the serial console would be filled with warnings. Is there a way to warn the user, without causing too much noise? An unaffected user doesn't want a warning on every boot. To give context to #98, as far as I understand it was added as a special case, to access the SWDCLK / PA30 and SWDIO / PA31 pins as inputs on the ATSAMD09 Breakout with Seesaw and on a third party project with ATSAMD10. With the caveat that the SWDCLK / PA30 needs an external pull-up. |
That sounds like a good compromise. @carlfj can you open a Pull Request with the change? |
.. adding a comment to state that it's for compatibility with boards that don't support arbitrary integers may help prevent it being removed in the future by a well-meaning contributor. |
Thank you for the help. Lovely so see a fix be released quickly, all the way to the CircuitPython bundle. I don't have any real idea about the performance impact with this try/exception error handling of After reading @mkende's comment on Pull request #98, I became aware that the last 2 bits of buf causing the error aren't used anyway, if the bits aren't set in the pins parameter, e.g. when # Only unpack bits 31 and 32 of buf, when they are also set in pins,
# to avoid OverflowError on boards that don't support arbitrary integers
if pins <= 0x3FFFFFFF:
buf[0] = buf[0] & 0x3F
ret = struct.unpack(">I", buf)[0] I have tested this on QT Py SAMD21 with NeoKey 1x4 QT I2C Breakout. I included a comment to make sure it is not removed once again as suggested above, but I am not sure if this is what was meant. This feels like a lot more elegant solution, without the code duplication, and runs the same code on both builds types. A bit like simply walking around the obstacle rather than handling it head on. The performance penalty seems smaller with the |
I'm torn about it, honestly. I agree that this second solution is more elegant in a way, but I also like the "Easier To Ask for Forgiveness Than Permission" (EAFP) approach as more Pythonic. But I'm also not sure what happens behind the scenes. The way it's written now, I'd be surprised if it ever got refactored accidentally by someone with good intentions as @jepler mentioned, and I like that it's clear because of the exception why that code is written that way. But I don't feel strongly either way. Curious what you think, @jepler and @Neradoc. |
When testing QT Py SAMD21 with the NeoKey 1x4 QT I2C Breakout, I got the error
OverflowError: small int overflow
, using the example neokey1x4_simpletest.py from the library / learn.adafruit.com:The program is identical to the linked, but is embedded below for reference. Running the latest bootloader 3.14 and CircuitPython 7.3.2.
I added the line
buf[0] = buf[0] & 0x3F
before line 217 with the error, compiling it with mpy-cross, and the error is gone. I copied the line from theget_temp
function, line 361 with a similar context. That was inspired by a adafruit forum post about the same error, mentioning to keep a value at 8 bits with a bitwise&= 0xff
. In my setup it only works when keeping it at 6 bits as the original code, not 8 bits.It turns out the pull request #98 on 2022-04-04 had removed this exact line to get PA30 and PA31 values:
Do not blank out the value read for pins PA30 and PA31.
The commit: d92217cFor reference the function
digital_read_bulk
looks like this, with the reverted edit to work with QT Py SAMD21:The commit seems to be the catalyst to the
OverflowError: small int overflow
, but my solution just cancels this commit. I haven't read into what theret = struct.unpack(">I", buf)[0]
line does, so I don't know what should be done to keep adafruit_seesaw library compatible with QT Py SAMD21 / M0. Any suggestions?Originally posted on forums.adafruit.com
For reference, the copy of example code
neokey1x4_simpletest.py
that ran on the QT Py SAMD21:The text was updated successfully, but these errors were encountered: