Hello ultrawideband friends,
The DW3000 User Manual includes the following section in 9.4.1 “Delayed TX Notes”:
Due to an errata in the DW3000, there is a case when neither the HPDWARN event gets set nor does the packet get transmitted. This happens when the time at which the transmitter needs to be enabled to send occurs within the analog front-end power up time preceding the current time. To avoid this bug reliably, the delayed send time must be set far enough in advance; it should be at least equal or more than the current time + preamble length + SFD length + 20 µs, or the time should be passed which will give rise to HPDWARN.
The host can check for this issue by reading the PMSC_STATE. When this bug occurs, the PMSC_STATE will be “TX” but TX_STATE will be “IDLE”, the TXFRS event will never be set, see state descriptions in 8.2.14.19 Sub-register 0x0F:30 – System state. The host should abort the transmission in this case. This check and recovery is implemented in the published DW3000 dwt-starttx() API.
I’m implementing to the registers (my target controller is not supported by your API) and alas your API is a “binary blob” so I can’t see the implementation of dwt_starrtx()
. So, I’m just going by the text, but having some trouble:
First of all, PMSC_STATE apparently lives in SYS_STATE, but the SYS_STATE register is inconsistently documented. The bitfield diagram lists TX_STATE (bits 0-3), RX_STATE (bits 8-13) and TSE_STATE (bits 16-20). However, the text description lists TX_STATE (bits 0-3), RX_STATE (bits 8-11!), and PMSC_STATE (bits 16-23), with no TSE_STATE. Which is to be believed?
Following the text description (since the diagram has no PMSC_STATE at all!), I attempt to implement this with logic something like this:
auto const state = dw3k_read<uint32_t>(DW3K_SYS_STATE);
auto const pmsc = (state >> 16) & 0xFF;
if ((state & 0xF) == 0 && pmsc >= 0x08 && pmsc <= 0x0F) {
last_status = DW3KStatus::ChipError;
error_text = "Chip: Scheduled too late*";
}
However, this generates many false positives on (what would otherwise be) successful transmissions, where PMSC_STATE becomes 0xA (described as indicating the TX WAIT state) and TX_STATE is 0 (idle) but that’s perfectly normal during TX WAIT. So, I added a carve-out:
if ((state & 0xF) == 0 && pmsc >= 0x08 && pmsc <= 0x0F && pmsc != 0x0A) ...
Even that doesn’t work reliably, though – again, it produces false positives. I’d really like to know what the API dwt_starttx()
actually does! If someone with access could just look that up and tell me what the logic is (or tell me where I can find the source code, if it is in fact available). Or, at least clarify the inconsistent manual text and confirm the field definitions?
Thank you kindly!
– egnor