Using frame filtering with data AND beacon frames

Hi,

We are having troubles with our project where we use DWM1000 modules in an embedded system (ESP32 based architecture). The problem is briefly: we want to use the frame filtering, but we also use data and beacon frames in our project. I can receive data frames with enabled frame filtering but I cannot receive beacon frames, I get only errors.

On the transmitter side I’m sending frames in a cycle: 4 data frames then 4 beacon frames. The destination addresses are always the same: 1 real address (the address of the other device) and 3 dummy addresses. For data I use 0x8841 frame control and for the beacon I use 0x8840 (only the frame type is different).

This is the data frame:

/*    This sequence frame is a 11-byte frame composed of the following fields:
 *     - byte 0/1: frame control (0x8841 to indicate a DATA frame using 16-bit addressing, without ACK).
 *     - byte 2: sequence number, incremented for each new frame.
 *     - byte 3/4: broadcast PAN ID (0xFFFF).
 *     - byte 5/6: 16-bit destination address (0x0000, later set by the switch case).
 *     - byte 7/8: 16-bit source address, 0xAAAA.
 *     - byte 9/10: frame check-sum, automatically set by DW1000.  */
uint8_t tx_msg[] = {0x41, 0x88, 00, 0xFF, 0xFF, 00, 00, 0xAA, 0xAA, 00, 00};

This is the beacon frame:

/*    This sequence frame is a 11-byte frame composed of the following fields:
 *     - byte 0/1: frame control (0x8840 to indicate a BEACON frame using 16-bit addressing, without ACK).
 *     - byte 2: sequence number, incremented for each new frame.
 *     - byte 3/4: broadcast PAN ID (0xFFFF).
 *     - byte 5/6: 16-bit destination address (0x0000, later set by the switch case).
 *     - byte 7/8: 16-bit source address, 0xAAAA.
 *     - byte 9/10: frame check-sum, automatically set by DW1000.  */
uint8_t tx_beacon[] = {0x40, 0x88, 00, 0xFF, 0xFF, 00, 00, 0xAA, 0xAA, 00, 00};

I send these with the recommended order (dwt_writetxdata, dwt_writetxfctrl and then dwt_starttx).

On the receiver side these are my callback functions:

// OK
static void fn_cbRxOk(const dwt_cb_data_t *cb_data)
{
	ets_printf("CALLBACK, cbRxOk  ->\t");
    ets_printf("Status: %08Xh\tLen: %d\tFCTRL: %02X%02Xh\tflag: %02Xh -> ",
                cb_data->status, cb_data->datalength, cb_data->fctrl[0], cb_data->fctrl[1], cb_data->rx_flags);

	uint8_t buffer[11];
	for (int i = 0; i < 11; i++)    buffer[i] = 0;
	dwt_readrxdata(buffer, sizeof(buffer), 0);

	ets_printf("DATA: ");
	for (int i = 0; i < sizeof(buffer); i++)
	    ets_printf("%02X", buffer[i]);
	ets_printf("\n");
}

// TIMEOUT ERROR
static void fn_cbRxTo(const dwt_cb_data_t *cb_data)
{
	ets_printf("CALLBACK, cbRxTo (timeout)!!!\n");
}

// ERROR
static void fn_cbRxErr(const dwt_cb_data_t *cb_data)
{
	ets_printf("CALLBACK, cbRxErr ->\t");
    ets_printf("Status: %08Xh\tLen: %d\tFCTRL: %02X%02Xh\tflag: %02Xh\n",
                cb_data->status, cb_data->datalength, cb_data->fctrl[0], cb_data->fctrl[1], cb_data->rx_flags);
}

Please don’t mind the not-so-pretty, hard coded buffer size and so on, I only use these with the mentioned dummy frames above.

A typical log is something like this:

CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 0	FCTRL: 0000h	flag: 00h
CALLBACK, cbRxErr ->	Status: 06800103h	Len: 0	FCTRL: 0000h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 0	FCTRL: 0000h	flag: 00h
CALLBACK, cbRxOk  ->	Status: 02806F03h	Len: 11	FCTRL: 8841h	flag: 00h -> DATA: 418800FFFFAADAAAAA899F
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 06800103h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 06800103h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxOk  ->	Status: 02806F03h	Len: 11	FCTRL: 8841h	flag: 00h -> DATA: 418800FFFFAADAAAAA899F
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h
CALLBACK, cbRxErr ->	Status: 22800F03h	Len: 11	FCTRL: 8841h	flag: 00h

(and so on...)

If I’m correct, the 02… status code messages are the sent DATA frames, the 06… status code refers to the faulty BEACON frame and every other case is the 22… status. I guess the callback data is only updated at good received frames, since it shows “4188” frame control at the faulty beacon frame as well (although it should be 4088 there…).

According to the manual the only issue with the data frames are the PLL clock (02 means CLKPLL_LL is set which means the PLL clock is losing lock - though at the end the CPLOCK bit is also set…).
What’s really interesting (and confusing to me) is the status at the beacon frames: SFD timeout occurs (RXSFDTO), no proper good frames are received (no RXCFG), no PHY header detected (no RXPHD), no edge detection (no LDEDONE), no correct SFD (no RXSFDD) but it DOES get somehow a correct frame preamble (RXPRD)

I’m a bit confused because: since the data frames are mostly correct, I don’t know the reason for the SFD, PHY header and edge detection fault at the beacon. Also I don’t know why CLKPLL_LL is set since the clock is set as locked (CPLOCK).

I see that faulty settings could cause timing issues that could cause the SFD and PLL clock issues (though I’m using the example code settings in a hardware that’s been working fine for more than a year) but since these errors not really occur at the data frames, I don’t really know why it does occur at the beacon frames…

If anyone has some good suggestions, please feel free to write it :wink:

Has anyone any idea about this?