DWM1000 behaving weird on custom board

So I’ve made my custom pcb with esp32 s3 and dwm1000 module and connected esp to dwm the exact way they are connected on makerfabs dw1000 (just with different spi pins for esp32 s3).
I’m using my board for the tag and makerfabs one (with bu01 and esp32) for the anchor and the problem is that ranging just won’t work most of the time. I get completely random values for range and short address, ranging is really slow and randomly disconnects from the anchors, but sometimes (maybe once in 10 attempts) it works completely fine: I get correct range and short addresses of anchors at normal refresh rate. If I try using another makerfabs board for the tag everything works fine every time.
I’m pretty clueless right now. Is maybe something wrong with my pcb or esp32 s3 spi works differently than on the normal esp32? I assume that bu01 and dwm1000 are completely the same and should work with same code.

SPI not working correctly will normally result in a more catastrophic failure than intermittent operation. How fast are you running the SPI? How’s the board layout in terms of signal integrity and antenna placement?
How good is your power supply, do you have enough capacitors on the power rails?

Is the ESP running wifi/bluetooth? If so can you do a build with that disabled and see if it works better? Turning that off would significantly reduce the ESP power usage and prevent potential interference between the two antennas. If that improves the UWB performance then that gives you a clue as to where to look.

SPI freq is the default one (16MHz) I tried lowering it to 2MHz but there’s no difference. SPI lines are going trough middle layer of 4 layer PCB and they are about 4cm long. There’s no copper underneath the antenna and 1cm on both sides of antenna. Power supply is ap2112k ldo with guaranteed constant current of 600mA and there are 10uF and 100nF caps just by dwm VDD pins. Esp in not using radio and is running at 80MHz. It is N16R2 module so it uses Quad SPI for flash and PSRAM but that uses SPI 0 and 1 and I don’t think that should be a problem or interfere with SPI 2 and 3.

On the anchor output I get a bunch of “delete inactive device” messages, or just some random values for range (-250m or 300m). On tag serial monitor I just get device address:xx:xx… and ### TAG ###. Sometimes I got “Interrupt wdt timeout on CPU1” after that. If I keep resetting tag after some time it starts normally and immediately starts ranging. It works fine until I reset it again.
I think that the tag sends a package, anchor receives it and send it back to tag but then tag fails to receive it or respond back to anchor. By “delete inactive device” it’s obvious that anchor receives something and that tag is trying to communicate, just I’m not sure what goes wrong then.

I guess it has something to do with initialization because once it started ranging it works great until I restart or power off tag.

I’d agree, it does sound like a startup related issue. Which seems odd, if the system was trying to configure the DW1000 before it was ready I’d expect some sort of error during the configuration process. You are running at a lower SPI speed initially until the PLL is locked right? And then verifying that it is locked before switching rather than just assuming it is done within a certain amount of time. I’d expect the drivers you’re using to take care of this but may be worth checking.

Have you tried slowing the startup process down?
Reset the DWM1000 once power is up and stable (so once your processor is running). Wait plenty of time between releasing the reset line and first talking to the device. Make sure you allow plenty of time after telling the DWM1000 to switch to the PLL.

Unless startup speed is critical it’s often simpler to add a second or two to the boot time rather than trying to figure out exactly where you’re not always allowing enough time to be ready.

I am in the same boat, custom board with ESP32-S3 and DWM1000 behaving weird. Did you ever manage to determine a cause/fix?

Seemingly managed to fix it, sharing for future people:
I am using the DW1000 library by thotro. In DW1000.cpp, I changed the _fastSPI to be 20000000L instead of 16000000L. That’s it!