Skip to content

Enable protomatter on RP2040 builds #4186

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

Merged
merged 4 commits into from
Mar 3, 2021

Conversation

jepler
Copy link

@jepler jepler commented Feb 11, 2021

Testing performed: ran on a 32x32 display

Other testing performed:

  • created a 128x64 display, 3 bits resolution (didn't drive anything)
  • checked across soft resets
  • checked recreating display

Also found a race condition between timer_disable and redraw, which would happen if I debugger-paused inside common_hal_rgbmatrix_timer_disable or put a delay or print inside it. That's what pausing inside reconstruct
fixes.

So that the "right timer" can be chosen, timer_allocate now gets the self pointer. It's guaranteed at this point that the pin information is accurate,so you can e.g., find a PWM unit related to the pins themselves. This required touching each port to add the parameter even though it's unused everywhere but raspberrypi.

Here's my testing code, with a 32x32 matrix:

import rgbmatrix
import board
import framebufferio
import displayio

displayio.release_displays()

MATRIX = rgbmatrix.RGBMatrix(
    width=32, height=32, bit_depth=3, tile=1,
    rgb_pins=[board.GP0,
              board.GP1,
              board.GP2,
              board.GP3,
              board.GP4,
              board.GP5],
    addr_pins=[board.GP9,
               board.GP10,
               board.GP11,
               board.GP12],
    clock_pin=board.GP6, latch_pin=board.GP7,
    output_enable_pin=board.GP8)

DISPLAY = framebufferio.FramebufferDisplay(MATRIX, auto_refresh=True,
                                           rotation=0)

Also found a race condition between timer_disable and redraw, which
would happen if I debugger-paused inside common_hal_rgbmatrix_timer_disable
or put a delay or print inside it.  That's what pausing inside reconstruct
fixes.

So that the "right timer" can be chosen, `timer_allocate` now gets the `self`
pointer.  It's guaranteed at this point that the pin information is accurate,
so you can e.g., find a PWM unit related to the pins themselves.
This required touching each port to add the parameter even though it's
unused everywhere but raspberrypi.
@jepler jepler force-pushed the update-protomatter-rp2 branch from 763f7ac to ff1942c Compare February 12, 2021 14:28
jepler added a commit to jepler/Adafruit_Protomatter that referenced this pull request Feb 12, 2021
These changes are tested along with adafruit/circuitpython#4186 and work on a 32x32 matrix.
@tannewt tannewt self-requested a review February 12, 2021 19:13
Copy link
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.

I don't see any issues. Thanks! (Not approving because it's a draft.)n

@jepler jepler marked this pull request as ready for review February 12, 2021 19:55
@jepler
Copy link
Author

jepler commented Feb 12, 2021

Thanks! We should probably wait for the pull request up at protomatter to be accepted first, but I marked this ready for review anyhow.

jepler added a commit to jepler/Adafruit_Protomatter that referenced this pull request Feb 12, 2021
These changes are tested along with adafruit/circuitpython#4186 and work on a 32x32 matrix.
@jepler jepler requested a review from tannewt February 12, 2021 22:07
@jepler
Copy link
Author

jepler commented Feb 12, 2021

I was confused about the "red X" failed CI notes, but those are for the Protomatter CI running in my fork, on a commit that refers to this PR. Click over to the "checks" tab to see a green board.

@ladyada
Copy link
Member

ladyada commented Feb 14, 2021

ok so... technically yes this does work.
but it seems like when it tries to get into REPL-on-display mode it crashes, and if thats during a file save sometimes so hard that the USB filesys gets corrupted and i have to nuke it to get it back.

@jepler
Copy link
Author

jepler commented Feb 14, 2021

Uh oh, it worked better than that for me. I'll test further on Monday. I know I tested being in the REPL, soft restarting, but mmmmaybe not writing to CIRCUITPY.

@jepler
Copy link
Author

jepler commented Feb 26, 2021

I tested by loading an adapted version of the fruit demo from https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/master/CircuitPython_RGBMatrix/fruit.py and causing heavy CIRCUITPY filesystem activity by running cat emoji.bmp{,,,} > bigmoji.bin; sync but didn't reproduce a crash.

I also re-tested entering and using the REPL and didn't encounter problems.

While writing to CIRCUITPY, the display will temporarily glitch. I believe this is because code can only execute from SRAM during flash erase (and write?) operations. Since protomatter (like most of the rest of circuitpython) resides in the flash it can't be executed during this time.

Anyhow, as a merge conflict had arisen I've merged main into this PR and with any luck there will be fresh artifacts shortly.

@jepler
Copy link
Author

jepler commented Feb 26, 2021

We figured out why @ladyada and I were having ahem varying levels of success. Limor was testing the prototype Feather, while I was testing the pico. Feather has a status LED.

At the time everything goes south, GDB says...

#0  0x1006926c in _PM_swapbuffer_maybe ()
#1  0x10050986 in common_hal_rgbmatrix_rgbmatrix_refresh ()
#2  0x1004606e in rgbmatrix_rgbmatrix_swapbuffers ()
#3  0x1004e5b4 in _refresh_display ()
#4  0x1004eb04 in framebufferio_framebufferdisplay_background ()
#5  0x1004d5ec in displayio_background ()
#6  0x10027aaa in supervisor_background_tasks ()
#7  0x10026780 in background_callback_run_all ()
#8  0x10027b46 in supervisor_run_background_tasks_if_tick ()
#9  0x100325f8 in common_hal_rp2pio_statemachine_write ()
#10 0x1003ef9c in common_hal_neopixel_write ()
#11 0x10026ed6 in rgb_led_status_init ()
#12 0x1003ec24 in reset_all_pins ()
#13 0x1002652e in reset_port ()
#14 0x1002623a in main ()

I can now investigate this properly.

@jepler
Copy link
Author

jepler commented Feb 26, 2021

I got another hung backtrace, again using the feather uf2 but not obviously related to neopixel:

#0  0x10069088 in _PM_row_handler (core=0x20000994 <displays+20>)
    at ../../lib/protomatter/src/core.c:534
#1  0x10069238 in _PM_PWM_ISR () at ../../lib/protomatter/src/arch/rp2040.h:148
#2  <signal handler called>
#3  0x10068698 in _PM_init (core=core@entry=0x20000994 <displays+20>, 
    bitWidth=bitWidth@entry=64, bitDepth=bitDepth@entry=4 '\004', 
    rgbCount=<optimized out>, rgbCount@entry=1 '\001', 
    rgbList=rgbList@entry=0x20000a0c <displays+140> "\006\005\t\v\n\f", 
    addrCount=<optimized out>, 
    addrList=addrList@entry=0x20000a2a <displays+170> "\031\030\035\034", 
    clockPin=13 '\r', latchPin=latchPin@entry=1 '\001', 
    oePin=oePin@entry=0 '\000', doubleBuffer=doubleBuffer@entry=true, 
    tile=-1 '\377', timer=0x10003) at ../../lib/protomatter/src/core.c:119
#4  0x1005071a in common_hal_rgbmatrix_rgbmatrix_reconstruct (
    self=self@entry=0x20000980 <displays>, framebuffer=framebuffer@entry=0x0)
    at ../../shared-module/rgbmatrix/RGBMatrix.c:97
#5  0x1002fad6 in supervisor_display_move_memory ()
    at ../../supervisor/shared/display.c:144
#6  0x10039e2e in supervisor_move_memory ()
    at ../../supervisor/shared/memory.c:316
#7  0x1002621a in cleanup_after_vm (heap=0x200033b8 <allocations+8>)
    at ../../main.c:233
#8  run_repl () at ../../main.c:528
#9  main () at ../../main.c:593

@jepler
Copy link
Author

jepler commented Mar 1, 2021

@ladyada I re-tested the slot machine demo from Adafruit_Learning_System_Guides/CircuitPython_RGBMatrix using the Feather RP2040 build and my Pico pinout on a Pico, but with R and B pin swapped to trigger the bug I was able to reproduce.

During the testing process, I ten times hit ctrl-c, ctrl-d to re-load the program, and caused filesystem activity with cat emoji.bmp{,,,} > large.bin; sync; rm large.bin; sync also 10 times with 5-second sleeps between. (of course, large.bin is only about 115kB big)

I did not observe any hard-faults or lockups, only the expected screen flickering while writing to CIRCUITPY. I did the same test with your Feather pinout, and while I couldn't see the display I also didn't have any lockups or hard-faults.

@jepler
Copy link
Author

jepler commented Mar 1, 2021

See adafruit/Adafruit_Protomatter#36 for the PWM slice number fix, already merged in yay

@dhalbert
Copy link
Collaborator

dhalbert commented Mar 2, 2021

@jepler is this all fixed and ready to merge? Did @ladyada test?

@ladyada
Copy link
Member

ladyada commented Mar 3, 2021

i did test, i had a wierd hardfault once but couldnt repro it, and i think it had more to do with USB so this is ok to merge!

Copy link
Member

@ladyada ladyada left a comment

Choose a reason for hiding this comment

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

tested with feather + matrix featherwing!

@jepler jepler merged commit efc2667 into adafruit:main Mar 3, 2021
@jepler jepler deleted the update-protomatter-rp2 branch November 3, 2021 21:11
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.

4 participants