DW1000 Simple RX modified to Simple RX on interrupt. Interrupt works, but stops firing after a few transfers. Why?

Hello everyone,

I am using a custom designed PCB for DW1000, and so far I got every part of it working (2WR works) and I am reliably able to receive data on polling. However when I modified example 2a to receive on an interrupt, the interrupt is triggered correctly from DW1000 for one to a couple of times, and then stops, and only works after a hard reset.

Transmitter is example 1a without any modification (transmits a message every second).

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    // Check the status of the DW1000 to determine the cause of the interrupt
    uint32 status = dwt_read32bitreg(SYS_STATUS_ID);

    // If the interrupt was triggered by the receipt of incoming data, read the data from the DW1000
    if (status & SYS_STATUS_RXFCG) {
    	// A frame has been received, copy it to our local buffer.
		frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;
		if (frame_len <= FRAME_LEN_MAX) {
			dwt_readrxdata(rx_buffer, frame_len, 0);
			printf("rx_buffer: %s\n", rx_buffer);
		}

		// Clear good RX frame event in the DW1000 status register.
		dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
    }

    // Clear the interrupt status register
    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_GOOD | SYS_STATUS_ALL_RX_ERR);
    // Using this will prolong the life of how many interrupts I can receive, but doesn't prevent it from dying
    dwt_rxenable(DWT_START_RX_IMMEDIATE);
}

int dw_main(void)
{
    reset_DW1000();
    port_set_dw1000_slowrate();
    if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR) {
        while (1) { };
    }

    port_set_dw1000_fastrate();

    /* Configure DW1000. */
    dwt_configure(&config);

    // Enable the receive interrupt on the DW1000
    dwt_setinterrupt(DWT_INT_RFCG, 1);
    // Enable the receiver on the DW1000
    dwt_rxenable(DWT_START_RX_IMMEDIATE);

    /* Loop forever receiving frames. */
    while (1)
    {
        __WFI();
    }

    return 0;
}

As you see I’m not using dwt_isr to handle the interrupt, but I get the same issue routing the interrupt through dwt_isr.

I am tracing the SPI lines as well as IRQ, RESET, WUP and SYNC. The upper lines are the receiver, the lower lines are the transmitter. As you can see, IRQ goes up right after a good transmission frame.

Is there a problem with implementation? Any help would be greatly appreciated!

Cheers and happy holidays.
Frank

When I’ve seen this in the past it’s been caused by the receive aborting due to some error condition that wasn’t then triggering an interrupt. Have you checked the status register once it gets into this state?

There are a few things that you can try to troubleshoot the issue you are experiencing with the DW1000 interrupt:

  1. Make sure that you are properly handling the interrupts in your code. When the interrupt is triggered, you should clear the interrupt status register by writing to it with the relevant interrupt flags. This can help to prevent further interrupts from being triggered.
  2. Check that your interrupt handler function is not taking too long to execute. If the interrupt handler function takes a long time to execute, it may cause other interrupts to be missed.
  3. Check that you have correctly configured the interrupt pin on the DW1000. Make sure that you have the correct pull-up or pull-down resistors connected to the interrupt pin, and that the interrupt pin is properly connected to your microcontroller.
  4. Check that you are not experiencing any noise or interference on the interrupt pin. This could cause the interrupt to be triggered multiple times or to not trigger at all.
  5. Make sure that you are properly resetting the DW1000 after the interrupt has been triggered. This can help to reset the state of the DW1000 and allow it to continue functioning correctly.

I hope these suggestions help! Let me know if you have any further questions.

Thank you for your swift reply I appreciate it!
I have solved the issue and I’ll just share my solution to it for the records.

So yes, it transitions from 0x2806b03 to 0x6800103, i.e. the preamble is detected successfully, but SFD gets a timeout. It seems to be a timing issue as I am using a custom designed DW1000 setup with a custom TCXO (ATX-13-F-38.400MHz-F05-T ABRACON | Mouser Deutschland). By using a 0 trim instead of FS_XTALT_MIDRANGE

dwt_setxtaltrim(0);

the interrupt has not died yet.