Skip to content
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

rp2040: Added rp2040 support. #45

Merged
merged 9 commits into from
Oct 31, 2022
Merged

rp2040: Added rp2040 support. #45

merged 9 commits into from
Oct 31, 2022

Conversation

sh83
Copy link
Contributor

@sh83 sh83 commented Oct 20, 2022

This PR add support for the rp2040 mcu. All of USB, CAN and UART communication interfaces are supported, but only USB was tested well. The most of the code was taken from klipper, pico sdk and canboot. The folder lib/ was taken from klipper as is, without modifications.
The existing code mostly was not unchanged, so no regress on other mcu is expected.
The companion PR Klipper3d/klipper#5844
I have added online comments to the non-trivial places.

Signed-off-by: Alex Malishev malishev@gmail.com

@@ -9,10 +9,16 @@
#include "board/irq.h" // irq_disable
#include "board/misc.h" // try_request_canboot

#if CONFIG_MACH_RP2040
#define BOOTLOADER_START (CONFIG_RP2040_BOOTLOADER_START)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

User bootloader should be placed just after boot2 block at START_FLASH+256 address. Simple CONFIG_FLASH_START & 0xFF000000 do not work here.

****************************************************************/

void
timer_setup(void)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

timer from generic/timer.c do not work on cortex-m0+

_bss_end = .;
} > ram

_stack_start = CONFIG_RAM_START + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE - 1024;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Magical "-1024" is really magical. _stack_start is used to place request key what should be preserved after reset. But rp2040 bootrom uses and of the ram to copy boot2(256 bytes) from flash and boot2 uses some stack on top of what. so ~300 bytes around CONFIG_RAM_START + CONFIG_RAM_SIZE are damaged by the boot process of the rp2040. That is why we shift stack by 1024 bytes.

default 0x10000000

config APPLICATION_START
default 0x10004000
Copy link
Contributor Author

Choose a reason for hiding this comment

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

16kb is reserved for the bootloader. The current bootloader size is 5kb for usb, 7 kb for can.

@Arksine
Copy link
Owner

Arksine commented Oct 21, 2022

Looks like a good addition to CanBoot. Can you break this up into separate commits? Preferably, there would be separate a commits for:

  1. Importing the source from Klipper
  2. Modifications to the Klipper Source (its fine if this includes the addition of flash.h/flash.c)
  3. Modifications to Canboot Source

I can be confident that Klipper's source is solid, so I just need to review the changes. This is much easier when I can review the diffs in each commit. Thanks.

@sh83
Copy link
Contributor Author

sh83 commented Oct 21, 2022

Thank you. You suggestions make sense. I will split pr into multiple commits.

Signed-off-by: Alex Malishev <malishev@gmail.com>
Signed-off-by: Alex Malishev <malishev@gmail.com>
Implemented canboot timer interface.
Simplified chipid.c to use common flash interface.

Signed-off-by: Alex Malishev <malishev@gmail.com>
Modified linker script and loader to load whole bootloader to the RAM.
Removed whatchdog.
Fixed gpio.c compilation.

Signed-off-by: Alex Malishev <malishev@gmail.com>
Signed-off-by: Alex Malishev <malishev@gmail.com>
@sh83
Copy link
Contributor Author

sh83 commented Oct 21, 2022

I did cleanup of the pr as suggested.
The first and second commits contain direct imports from klipper and pico-sdk.
The last and before last commits contain modification of the common canboot code.

Please note what rp2040 flash do not support concurrent read end erase/program. So interrupt handlers are suspended during erase operation. It is not good for the software can driver we use. So I have changed linker script and startup file armcm_canboot.c to load whole bootloader to the RAM. This way we do NOT disable interrupts during flash erase and write.

} > rom

. = ALIGN(4);
_data_flash = .;

.data : AT (_data_flash)
{
. = ALIGN(4);
. = ALIGN(128);
Copy link
Contributor Author

@sh83 sh83 Oct 21, 2022

Choose a reason for hiding this comment

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

Actually ALIGN do not do anything, cause we are at the start of the ram anyway :)
Leaved it for the documentation purpose, cause vector_table should be 128 byte aligned.

_text_vectortable_end = .;
*(.text .text.*)
*(.rodata .rodata*)
KEEP(*(.vector_table_flash))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only VectorTableFlash , ResetHandler and reset_handler_stage_two are executed from flash. reset_handler_stage_two moves everything to the ram.

_data_start = .;
KEEP(*(.vector_table))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We copy vector_table to the RAM and update VTOR, so core could use it.

uint32_t count = (&_data_end - &_data_start);
for(int i = 0; i < count; i++) {
(&_data_start)[i] = (&_data_flash)[i];
barrier();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

At this point it is not safe to call anything, cause we did not copied code yet. So barrier() here to prevent compiler from use memcpy and memset.

Signed-off-by: Alex Malishev <malishev@gmail.com>
@sh83
Copy link
Contributor Author

sh83 commented Oct 24, 2022

Added global CONFIG_BOOTLOADER_START to avoid idefs in the code. This is the same change as in klipper PR.

@jtrmal
Copy link

jtrmal commented Oct 28, 2022

I tried this and I get the following error during make flash:

make flash FLASH_DEVICE=2e8a:0003
  Building rp2040_flash
gcc -c -Wall -ggdb -I../rp2040/ `pkg-config libusb-1.0 --cflags` main.c -o main.o
main.c: In function ‘main’:
main.c:177:46: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=]
  177 |     fprintf(stderr, "Loaded UF2 image with %lu pages\n", image->num_blocks);
      |                                            ~~^           ~~~~~~~~~~~~~~~~~
      |                                              |                |
      |                                              |                size_t {aka unsigned int}
      |                                              long unsigned int
      |                                            %u
gcc -c -Wall -ggdb -I../rp2040/ `pkg-config libusb-1.0 --cflags` picoboot_connection.c -o picoboot_connection.o
gcc  main.o picoboot_connection.o `pkg-config libusb-1.0 --libs` -o rp2040_flash
  Flashing out/canboot.uf2
Loaded UF2 image with 21 pages
No rp2040 in BOOTSEL mode was found

I do however have the rpi connected:

pi@tri:~/CanBoot $ lsusb
Bus 002 Device 002: ID 090c:1000 Silicon Motion, Inc. - Taiwan (formerly Feiya Technology Corp.) Flash Drive
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 1d50:614e OpenMoko, Inc. stm32f446xx
Bus 001 Device 003: ID 1d50:606f OpenMoko, Inc. Geschwister Schneider CAN adapter
Bus 001 Device 005: ID 2e8a:0003 Raspberry Pi RP2 Boot
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

@jtrmal
Copy link

jtrmal commented Oct 28, 2022

OK, resolved... I just have to flash via root/sudo. SORRY!

@sh83
Copy link
Contributor Author

sh83 commented Oct 28, 2022

@jtrmal Thanks for testing it.
I think instructions should be updated. One thing to note is sudo usage. Also flash should be erased before if no bootloader entry mode is defined(double reset or button). Will do it later.

Do it work well after all? What board do you use?

@jtrmal
Copy link

jtrmal commented Oct 28, 2022

yeah, it looks like its working. I do have some issues that do not most probably correlate with the canboot but I tried to resolved them by using canboot (unsuccessfully). My board behaves ok after soft restart (i.e. staying on power but being restarted after flashing), but when I unplug and plug again, it is dead. I tried both CAN and USB and it still behaves the same. But I'm sure it's not can boot, was happening even before it. This is all just to explain why I'm not able to confirm with 100% certainty
I'm using SB2040

@jtrmal
Copy link

jtrmal commented Oct 28, 2022

Things that were confusing for me:

  • not specifying the bootloader offset and related stuff
  • If I should flash the uf2 file

@sh83
Copy link
Contributor Author

sh83 commented Oct 28, 2022

Well, most low level parameters should be ok by default.
Recommended install procedure is following:

  1. Boot into buildin bootloader mode - apply power with mode button pressed
  2. Flash binary flash_nuke.uf2 (https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython/circuitpython) via mass storage method or via rp2040_flash
  3. Wait a minute or two. Dyring this flash_nuke.uf2 will erase all flash
  4. Boot into buildin bootloader mode again
  5. Build canboot.uf2 and flash canboot.uf2 by the same method
  6. Check usb or can bus - canboot should be up running and connected
  7. Now it is possible to flash klipper.bin from my klipper pr. Bootloader option should be enabled in klipper menuconfig.
    This should work given hardware is ok.

@jtrmal
Copy link

jtrmal commented Oct 28, 2022 via email

Signed-off-by: Alex Malishev <malishev@gmail.com>
@sh83
Copy link
Contributor Author

sh83 commented Oct 28, 2022

I have added option (enabled by default after make menucofig) to force bootloader entry before new application flashed. nuke_flash.uf2 (i.e. steps 2,3,4 above) is no longer needed.

@jtrmal
Copy link

jtrmal commented Oct 29, 2022

Hi, I just went through the hoops and updated klipper and the canboot to @sh83's repo. Everything seems to work flawlessly. Update via CAN even without triggering the canboot via button also works. Didn't find smallest issue.
And the last commit ("flash-nuke") is super-useful.

@sh83
Copy link
Contributor Author

sh83 commented Oct 29, 2022

@jtrmal thank you for your feedback and testing. Really good news.

@Arksine
Copy link
Owner

Arksine commented Oct 30, 2022

Thanks. I have begun my review and overall it looks solid. I do have a few observations:

  • bootrom.c, hw_flash.c, and hw_flash.h look like library files, so I suspect they should be placed in lib/rp2040 somewhere rather than src/rp2040.

  • The deployer should have a build option rather than default to the application address.

  • With the 256 byte bootloader offset, we probably need to change the following block in deployer.c to use CONFIG_BOOTLOADER_START:

    // Check if flash has already been written
    void *fstart = (void*)CONFIG_FLASH_START;
    uint32_t cbsize = deployer_canboot_binary_size;
    if (memcmp(fstart, deployer_canboot_binary, cbsize) == 0) {
        try_request_canboot();
        halt();
    }
  • Assuming we set fstart to `CONFIG_BOOTLOADER_START' we might have an issue erasing the first page when using the deployer with the rp2040.

I'm going to try to test this on real hardware today to see how the deployer works. Hopefully it something we can get working but it isn't a huge issue if we can't, we just need to disable it and document it.

@sh83
Copy link
Contributor Author

sh83 commented Oct 30, 2022

Deployer work fine in my setup as is . No fixup is required afaik.
It is a bit confusing: canboot binary contains boot2 ( first 256 bytes) as it should. But canboot itself(i.e. interrupt table) start at 0x10000100. So klipper should look at this to find canboot presence .
Answer other questions later.

 - moved external files to lib folder
 - fixed typos
 - added optional "sudo" to flash command
 - fixed redundant file close in script
 - fixed compilation warning
@sh83
Copy link
Contributor Author

sh83 commented Oct 30, 2022

Added misc fixes:

@sh83
Copy link
Contributor Author

sh83 commented Oct 30, 2022

@Arksine, thanks for review. Answers to your notes:

  • I moved files as suggested
  • I think I did not touch deployer build, it should not be different from other targets. It do not harm to build it anyway )
  • deployer.c should not be changed. Although canboot itself (vector table) starts at 0x10000100, we append boot2 before (see magic with stage2.o in rp2040/Makefile). CONFIG_BOOTLOADER_START only used to locate canboot vector table in deployer and klipper.
  • no problem here, see above

@Arksine Arksine merged commit 2990480 into Arksine:master Oct 31, 2022
@Arksine
Copy link
Owner

Arksine commented Oct 31, 2022

Thanks for the explanation, makes sense. Everything looks good and tests well on my end, so I merged.

@tnap1979
Copy link

hey guys, i have a question.
im running the mellow SB2040 v1 canbus printhead...
on manta m4p/cb1 combo running the latest btt cb1 full image with klipperscreen and a UtoC-3
im able to get a succesful UUID from the sb2040
but klipper still seems unable to connect to the sb2040 mcu via can
the can network is obviously up and running if im able to get the uuid no ?
what gives ? why wont klipper connect to the mcu?
i have a proper .cfg setup with mcu id and cnabus uuid

@nvrprfct
Copy link

nvrprfct commented Nov 2, 2022

hey guys, i have a question. im running the mellow SB2040 v1 canbus printhead... on manta m4p/cb1 combo running the latest btt cb1 full image with klipperscreen and a UtoC-3 im able to get a succesful UUID from the sb2040 but klipper still seems unable to connect to the sb2040 mcu via can the can network is obviously up and running if im able to get the uuid no ? what gives ? why wont klipper connect to the mcu? i have a proper .cfg setup with mcu id and cnabus uuid

Well, most low level parameters should be ok by default. Recommended install procedure is following:
1. Boot into buildin bootloader mode - apply power with mode button pressed
2. Flash binary flash_nuke.uf2 (https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython/circuitpython) via mass storage method or via rp2040_flash
3. Wait a minute or two. Dyring this flash_nuke.uf2 will erase all flash
4. Boot into buildin bootloader mode again
5. Build canboot.uf2 and flash canboot.uf2 by the same method
6. Check usb or can bus - canboot should be up running and connected
7. Now it is possible to flash klipper.bin from my klipper pr. Bootloader option should be enabled in klipper menuconfig.
This should work given hardware is ok.

once canboot is flashed, you need to flash klipper from sh83s klipper fork, at least until his pull request is merged.

@Flob74
Copy link

Flob74 commented Nov 6, 2022

Hi guys,

Thank you for your work for integrating RP2040 to canboot.

I'm also trying to install the SB2040 with the Octopus board. But I'm not able to complete :

  • I flashed Canboot firmware on both mcu octopus and SB2040 (STM32Cube method & storage flash method)
  • I flashed the octopus with klipper as USB to CAN bus bridge
  • I setup can0 on my Raspberry Pi
  • I found my two UUID and updated the printer.cfg file.
  • I flashed klipper to the SB2040

Then I got the klipper error mcu "'SB2040': Unable to connect" and when I restart the printer, the SB2040's blue light for "flash successfull" turn off. The wiring seems fine as I flashed Klipper throught CanBoot CAN command. I think that I missed something in the canboot's menuconfig.

image

Please, can anyone explain me simply which option did I missed ? Thank you

@sh83
Copy link
Contributor Author

sh83 commented Nov 6, 2022

@Flob74 The klipper pull request is not merged yet. I expect it will be done in a few days. For now you could use klipper from pull request branch https://github.com/Klipper3d/klipper/tree/work-rp2040canboot-20221103 , or just wait a bit until klipper is ready. Also in klipper menuconfig bootloader support(16kib) should be enabled.
By the way what is gpio24 on sb2040?

@tnap1979
Copy link

tnap1979 commented Nov 6, 2022

hey guys, i have a question. im running the mellow SB2040 v1 canbus printhead... on manta m4p/cb1 combo running the latest btt cb1 full image with klipperscreen and a UtoC-3 im able to get a succesful UUID from the sb2040 but klipper still seems unable to connect to the sb2040 mcu via can the can network is obviously up and running if im able to get the uuid no ? what gives ? why wont klipper connect to the mcu? i have a proper .cfg setup with mcu id and cnabus uuid

Well, most low level parameters should be ok by default. Recommended install procedure is following:

  1. Boot into buildin bootloader mode - apply power with mode button pressed
  2. Flash binary flash_nuke.uf2 (https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython/circuitpython) via mass storage method or via rp2040_flash
  3. Wait a minute or two. Dyring this flash_nuke.uf2 will erase all flash
  4. Boot into buildin bootloader mode again
  5. Build canboot.uf2 and flash canboot.uf2 by the same method
  6. Check usb or can bus - canboot should be up running and connected
    7. Now it is possible to flash klipper.bin from my klipper pr. Bootloader option should be enabled in klipper menuconfig.
    This should work given hardware is ok.

once canboot is flashed, you need to flash klipper from sh83s klipper fork, at least until his pull request is merged.

Yea, I'll admit.. I had a total brain dump when I realized I STILL had to flash klipper after canboot... considering I've done canboot on the btt stuff a few times .. thanks for the response..
After all said and done, the system IS running very stable and so far hasn't presented any issues.. and has now made about 5 consecutive prints in a row

@tnap1979
Copy link

tnap1979 commented Nov 6, 2022

@Flob74 The klipper pull request is not merged yet. I expect it will be done in a few days. For now you could use klipper from pull request branch https://github.com/Klipper3d/klipper/tree/work-rp2040canboot-20221103 , or just wait a bit until klipper is ready. Also in klipper menuconfig bootloader support(16kib) should be enabled. By the way what is gpio24 on sb2040?

This is a led indicator on the side of the board to basically let you know if it flashed or not.. or status?? I'm not sure.. but I used my gpio24 enabling and disabling to make sure canboot flashed ok

@jtrmal
Copy link

jtrmal commented Nov 6, 2022 via email

@tnap1979
Copy link

tnap1979 commented Nov 6, 2022

Hi, gpio24 is a status led -- Mellow does not explain in their docs what does it do, so people just keep copying it from their example config (https://mellow.klipper.cn/#/board/fly_sb2040/flash) But generally I've found it's better to treat it as a status led in the canboot, so that I can distinguish between canboot active (blinking) and klipper active (solid) y.

On Sun, Nov 6, 2022 at 10:45 AM tnap1979 @.> wrote: hey guys, i have a question. im running the mellow SB2040 v1 canbus printhead... on manta m4p/cb1 combo running the latest btt cb1 full image with klipperscreen and a UtoC-3 im able to get a succesful UUID from the sb2040 but klipper still seems unable to connect to the sb2040 mcu via can the can network is obviously up and running if im able to get the uuid no ? what gives ? why wont klipper connect to the mcu? i have a proper .cfg setup with mcu id and cnabus uuid Well, most low level parameters should be ok by default. Recommended install procedure is following: 1. Boot into buildin bootloader mode - apply power with mode button pressed 2. Flash binary flash_nuke.uf2 ( https://learn.adafruit.com/getting-started-with-raspberry-pi-pico-circuitpython/circuitpython) via mass storage method or via rp2040_flash 3. Wait a minute or two. Dyring this flash_nuke.uf2 will erase all flash 4. Boot into buildin bootloader mode again 5. Build canboot.uf2 and flash canboot.uf2 by the same method 6. Check usb or can bus - canboot should be up running and connected 7. Now it is possible to flash klipper.bin from my klipper pr. Bootloader option should be enabled in klipper menuconfig. This should work given hardware is ok. once canboot is flashed, you need to flash klipper from sh83s klipper fork, at least until his pull request is merged. Yea, I'll admit.. I had a total brain dump when I realized I STILL had to flash klipper after canboot... considering I've done canboot on the btt stuff a few times .. thanks for the response.. After all said and done, the system IS running very stable and so far hasn't presented any issues.. and has now made about 5 consecutive prints in a row — Reply to this email directly, view it on GitHub <#45 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUKYX3TF6MOPAKG5CEKPOLWG7ACLANCNFSM6AAAAAARKRKOPU . You are receiving this because you were mentioned.Message ID: @.>

Nice.. did not know it could be used for status...
Ya.. mellow docs aren't the best... they need work.
Well now I know I'll be setting up status led on my voron tridex build

@jtrmal
Copy link

jtrmal commented Nov 6, 2022 via email

@Flob74
Copy link

Flob74 commented Nov 6, 2022

Thank you for your quick answers. I think that I will wait a couple of days that klipper merge the branch.

For the GPIO24, jtrmal was true, I just copied it from the Mellow Fly documentation.

jtrmal : Mellow does not explain in their docs what
does it do, so people just keep copying it from their example config

Also, please jtrmal, as the message was posted from an email my navigators can't launch the image : [image: Screenshot 2022-11-06 at 10.53.41 AM.png]. It seems very interesting.

@jtrmal
Copy link

jtrmal commented Nov 6, 2022

Screenshot 2022-11-06 at 11 38 55 AM

ok, I uploaded it again, didn't know that github won't add the pic. I actually didn't figure out if the "doublick" option does something for SB-2040, as it does have only boot button. Also, it's not super-important to have the endstop as "button" enabled, as flash_can can trigger canboot on its own.

@tnap1979
Copy link

tnap1979 commented Nov 6, 2022

Thank you for your quick answers. I think that I will wait a couple of days that klipper merge the branch.

For the GPIO24, jtrmal was true, I just copied it from the Mellow Fly documentation.

jtrmal : Mellow does not explain in their docs what
does it do, so people just keep copying it from their example config

Also, please jtrmal, as the message was posted from an email my navigators can't launch the image : [image: Screenshot 2022-11-06 at 10.53.41 AM.png]. It seems very interesting.

@Flob74 if you use the latest Kiauh klipper helper.. you can install @sh83 version of klipper directly thru kiauh, that's how I did mine

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.

6 participants