Hello!
I am developing a project based on STM32F4 + DWM 1000.
The system consists of one anchor and two tags:
- The Anchor performs TOF measurements for each Tag;
- The Anchor transmits an appropriate TOF measurements to each tag;
- The Anchor sends a synchro message to synchronize the local time of the Tags STM32;
TOF measurement and transmission works perfectly, but to synchronize the STM32 timers on the tag side, I want also use the SFDLED signal.
The problem is in follows: the DWM1000 SFDLED signals of both of my tags have a sufficiently large delay between them:
Although as I understand it, if the Tags are nearby, this signal should be generated simultaneously.
Tag and Anchor applications are based on dw1000_api_rev2p14_stsw API. Firmware for both tags is identical.
There is no SFDLED pin configuration function in the API, so I had to write it separately:
#define GPIO_PIN1_SFD 0x00000100UL /* The pin operates as SFD LED output */
void dwt_setSFDgpio1(void)
{
// Set GPIO Mode
uint32 gpio_mode = dwt_read32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET);
gpio_mode &= ~(GPIO_MSGP1_MASK);
gpio_mode |= GPIO_PIN1_SFD;
dwt_write32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET, gpio_mode);
gpio_mode = dwt_read32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET);
// Enable LP Oscillator to run from counter and turn on de-bounce clock.
uint32 reg;
reg = dwt_read32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET);
reg |= (PMSC_CTRL0_GPDCE | PMSC_CTRL0_KHZCLEN);
dwt_write32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, reg);
// Enable LEDs to blink and set default blink time.
reg = PMSC_LEDC_BLNKEN | 0x01;
dwt_write32bitoffsetreg(PMSC_ID, PMSC_LEDC_OFFSET, reg);
}
Initial DW1000 setup:
static dwt_config_t config = {
2, /* Channel number. */
DWT_PRF_64M, /* Pulse repetition frequency. */
DWT_PLEN_128, /* Preamble length. Used in TX only. */
DWT_PAC8, /* Preamble acquisition chunk size. Used in RX only. */
9, /* TX preamble code. Used in TX only. */
9, /* RX preamble code. Used in RX only. */
0, /* 0 to use standard SFD, 1 to use non-standard SFD. */
DWT_BR_6M8, /* Data rate. */
DWT_PHRMODE_STD, /* PHY header mode. */
(129 + 8 - 8) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
};
static dwt_txconfig_t txconfig = {
0xC2, /* PG delay. */
0x67676767, /* TX power. */
};
reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */
port_set_dw1000_slowrate();
HAL_Delay(1000);
if (dwt_initialise(DWT_LOADUCODE) == DWT_ERROR)
{
while (1)
;
}
port_set_dw1000_fastrate();
dwt_configure(&config);
dwt_configuretxrf(&txconfig);
dwt_enablegpioclocks();
dwt_setSFDgpio1();
Non-blocking RX handler (called as often as possible):
case DWM_RX:
if (handler->dwm.pocessing == 0)
{
dwt_rxenable(DWT_START_RX_IMMEDIATE);
handler->dwm.pocessing = 1;
}
else
{
statusReg = dwt_read32bitreg(SYS_STATUS_ID);
if (statusReg & SYS_STATUS_RXFCG)
{
uint16_t rxPacketSize = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;
if (rxPacketSize <= 0xFF + 4)
{
dwt_readrxdata((uint8_t *)&handler->rxPacketBuffer.packet, rxPacketSize - UWB_PROTOCOL_HW_CRC_LENGTH, 0);
handler->rxPacketBuffer.rxTimestamp = dwt_readrxtimestamplo32() + (((uint64_t)dwt_readrxtimestamphi32() & 0xFF000000) << 8);
Fifo_pushBack(handler->rxFifo, &handler->rxPacketBuffer);
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR);
dwt_rxenable(DWT_START_RX_IMMEDIATE);
break;
}
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR);
handler->dwm.pocessing = 0;
}
else if (statusReg & SYS_STATUS_ALL_RX_ERR)
{
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
handler->dwm.pocessing = 0;
}
}