The rx examples generally have this initialisation sequence:
- Set SPI rate.
- Power on/reset IC.
dwt_probe()
- Poll
dwt_checkidlerc()
dwt_initialise()
See for example, simple_rx_nlos.c
or rx_diagnostics.c
.
In my experience (stm32) this reliably segfaults due to a read from a NULL pointer. And this seems entirely reasonable, since dwt_checkidlerc()
calls this chain:
dwt_checkidlerc()
indeca_compat.c
ioctl(DWT_CHECKIDLERC)
indw3000_device.c
ull_checkidlerc()
dwt_read16bitoffsetreg()
dwt_readfromdevice()
dwt_xfer3xxx(DW3000_SPI_RD_BIT)
And there, inside the DW3000_SPI_RD_BIT
case, is this line:
if ((LOCAL_DATA(dw)->spicrc == DWT_SPI_CRC_MODE_WRRD) ...
LOCAL_DATA(dw)
expands to dw->priv
and priv
is set to NULL in dwt_probe()
when static_dw
is assigned to dw
. So this bombs out reliably.
The first thing dwt_initialise()
does is malloc()
this field, so calling it before dwt_checkidlerc()
resolves the issue.
This seems pretty fundamental so I’m surprised I can find no discussion or explanation. Is my version of the API hosed? Am I using it wrong? Or is everyone quietly doing this as well?