Support for rp2350 micro-controllers

That’s odd.

You could try picotool directly using the klipper.elf file as described in the link above.

The ctr_run_initfuncs() is an auto-generated function - you can find the implementation in out/compile_time_requests.c. One would typically not add debugging code to the function, but instead add debugging to the code that function calls. (You’ll find the generated code is very simple and just calls the functions that were marked with DECL_INIT() .)

The Klipper code is based on the pico-sdk v2.0.0 as described in lib/README. However, Klipper uses very little code from the sdk. I guess it’s possible that you have one of the newer A4 steppings of the chip and that changed something subtle from the A2 stepping. I guess you could try disabling USB serial number from CHIPID in make menuconfig under USB IDs when Enable extra low-level configuration options is set (to possibly rule out its the pico-sdk chip id code).

I think you also mentioned this is a custom board. Does it have the standard 12Mhz crystal and is that crystal known to be working?

I’m just throwing out “guesses” as I’m not sure what the issue is.
-Kevin

Oh, nice, yesterday it was started to be late, I saw that initfuncs were dynamic, but didn’t see the .c file for it, just compiled code.

Guesses is all I need as I’m running out of ideas :smiley:

You’re right, there is 0A4 on the chip, so erratum 9 is apparently fixed in this one. I’m using Abracon ABM8-272-T3 for xtal, the one that hardware design guide recommends. Generally I think I followed the hardware design guide strictly. But it is from LCSC, not from Abracon directly. With hello world usb I think the comm was stable, I didn’t see any disconnections though.

Disabling USB serial number from CHIPID didn’t help.

Ok, I’ve got something I guess, because I’ve made it running. It will take some time still to go deeper, but want to share something now, and maybe get some help further.

I went back to your idea about the CHIP ID, it bothered me somehow. Of course it was my fault, instead of deselecting the USB serial number from CHIPID I just disabled extra low-level configuration - don’t kill me please, that’s what happens when I read your instructions before morning coffee :smiley: . But that got me to following that path and trying to fix getting that chip id :smiley:

So, debugging further got me that it probably gets stuck on:

    rom_get_sys_info_fn func = rom_func_lookup(ROM_FUNC_GET_SYS_INFO);

    uint8_t data[9 * 4];

    func(data, 9, SYS_INFO_CHIP_INFO);

I’ve made a lot of changes now:

the *out_buffer was uint8_t, I adjusted this function to use it exactly as in the SDK 2.2

void
bootrom_read_unique_id(uint8_t *out, uint32_t maxlen)
{
typedef int (*rom_get_sys_info_fn)(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t flags);
rom_get_sys_info_fn func = rom_func_lookup(ROM_FUNC_GET_SYS_INFO);
union {
uint32_t words[9];
uint8_t bytes[9 * 4];
} data;
__unused int rc = func(data.words, 9, SYS_INFO_CHIP_INFO);

int i;
for (i = 0; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES; i++)
    out[i] = data.bytes[PICO_UNIQUE_BOARD_ID_SIZE_BYTES - 1 + 2 * 4 - i];

}

I also changed the rom_func_lookup slightly, I added the pico_processor_state_is_nonsecure, from SDK, and used it in the rom_func_lookup. Probably unnecessary, but I was doing step by step adjustments to the SDK, so I thought that maybe in some situations this may be important.

static bool pico_processor_state_is_nonsecure(void) {
#ifndef __riscv
// todo add a define to disable NS checking at all?
// IDAU-Exempt addresses return S=1 when tested in the Secure state,
// whereas executing a tt in the NonSecure state will always return S=0.
uint32_t tt;
pico_default_asm_volatile (
“movs %0, #0\n”
“tt %0, %0\n”
: “=r” (tt) : : “cc”
);
return !(tt & (1u << 22));
#else
// NonSecure is an Arm concept, there is nothing meaningful to return
// here. Note it’s not possible in general to detect whether you are
// executing in U-mode as, for example, M-mode is classically
// virtualisable in U-mode.
return false;
#endif
}

static void *
rom_func_lookup(uint32_t code)
{
typedef void (rom_table_lookup_fn)(uint32_t code, uint32_t mask);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored “-Warray-bounds”
rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn)
(uintptr_t)(uint16_t)(BOOTROM_TABLE_LOOKUP_OFFSET);
#pragma GCC diagnostic pop
if (pico_processor_state_is_nonsecure()) {
return rom_table_lookup(code, RT_FLAG_FUNC_ARM_NONSEC);
} else {
return rom_table_lookup(code, RT_FLAG_FUNC_ARM_SEC);
}
}

And in bootrom_constants.h we have:

// todo remove this (or #ifdef it for A1/A2)
#define BOOTROM_IS_A2() ((*(volatile uint8_t *)0x13) == 2)
#define BOOTROM_WELL_KNOWN_PTR_SIZE (BOOTROM_IS_A2() ? 2 : 4)

Which I changed to simply

#define BOOTROM_WELL_KNOWN_PTR_SIZE 2

Also I updated all the hardware/regs to SDK2.2 for RP2350.

As a result. my usb-devices now beautifully contain:

T: Bus=01 Lev=02 Prnt=03 Port=01 Cnt=01 Dev#= 32 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=02(commc) Sub=00 Prot=00 MxPS=16 #Cfgs= 1
P: Vendor=1d50 ProdID=614e Rev=01.00
S: Manufacturer=Hello
S: Product=rp2350
S: SerialNumber=C7CA988AA511E8A8
C: #Ifs= 2 Cfg#= 1 Atr=c0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=02 Prot=01 Driver=cdc_acm
E: Ad=83(I) Atr=03(Int.) MxPS= 8 Ivl=255ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_acm
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms

//EDIT, now I made a fresh repo clone, and changed ONLY BOOTROM_WELL_KNOWN_PTR_SIZEand it works!

1 Like

Okay, thanks for reporting and tracking this down. I have created a github PR to update Klipper to pico-sdk v2.2.0 . Hopefully that fixes the issue.

-Kevin

Thanks!
As you’ve said, klipper is not using much from that SDK, from what I could see they’ve changed some default values, but some of them are set in the code anyway. They had changes in the .c codes, also when I was playing with their examples, I saw that they are building downloadable uf2 files.

Very interesting chips I must say. I managed to overclock it to something in range of 550MHz and it didn’t even warm up (but I’ think I’ll stay in a range of 300MHz). I still have some things to test if it works reliably, mainly PWM, SPI and ADC, but so far so good. In my projects drawer I’ve got RP2354B based board for tileable heatbed (8ADCs help there), but that is the topic for undefined future:D

FYI, the latest mainline Klipper code now uses the pico-sdk v2.2.0 . This should make it possible to use the latest rp235x chips with the “A4” revision.

I also updated the code to support rp235xB additional GPIO pins and ADC ( Add support for rp2350b chips by KevinOConnor · Pull Request #7146 · Klipper3d/klipper · GitHub ).

-Kevin

2 Likes