Hi all,
I am in charge of porting an application from DWM1000 to DWM3000.
Frame reception works fine in both polling and interrupt mode on the DWM3000 hardware with no error or timeout.
But a problem arise when I try to use SLEEP capability.
When receive is started in “spi ready” callback and a frame is transmitted by another device the error 0x04000107 is notified in “rx error” callback.
Active bits in cb_data->status are:
RXSTO - Receive SFD timeout
RXPRD - Receive preamble detected status
SPICRCE - Spi CRC error (always set when CRC mode disabled)
CPLOCK - Clock PLL lock
IRQS - Interrupt request status
I am using the following logic to keep most of the time DW3000 in SLEEP and wakeup when requested to check if any frame can be received:
/* Default communication configuration. We use default non-STS DW mode. /
static dwt_config_t config = {
5, / Channel number. /
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. /
1, / 0 to use standard 8 symbol SFD, 1 to use non-standard 8 symbol, 2 for non-standard 16 symbol SFD and 3 for 4z 8 symbol SDF type /
DWT_BR_6M8, / Data rate. /
DWT_PHRMODE_STD, / PHY header mode. /
DWT_PHRRATE_STD, / PHY header rate. /
(129 + 8 - 8), / SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. /
DWT_STS_MODE_OFF, / STS disabled /
DWT_STS_LEN_64, / STS length see allowed values in Enum dwt_sts_lengths_e /
DWT_PDOA_M0 / PDOA mode off */
};
int dw3000intialization()
{
port_set_dw_ic_spi_fastrate(); /* Configure SPI rate, DW IC supports up to 38 MHz */
reset_DWIC(); /* Target specific drive of RSTn line into DW IC low for a period. */
Sleep(2); /* Time needed for DW3000 to start up (transition from INIT_RC to IDLE_RC, or could wait for SPIRDY event) */
while (!dwt_checkidlerc()) /* Need to make sure DW IC is in IDLE_RC before proceeding */
{ };
if (dwt_initialise(DWT_DW_INIT) == DWT_ERROR)
return -1;
if(dwt_configure(&config)) /* Configure DW IC. */
return -2;
dwt_setcallbacks(NULL, rx_ok_cb, rx_to_cb, /* Register RX call-back. */
rx_err_cb, spi_err_cb, spi_ready_cb);
dwt_setinterrupt(SYS_ENABLE_LO_SPIRDY_ENABLE_BIT_MASK | /* Enable wanted interrupts (SPI ready RX good frames and RX errors). */
SYS_ENABLE_LO_RXFCG_ENABLE_BIT_MASK |
SYS_STATUS_ALL_RX_ERR, 0, DWT_ENABLE_INT);
dwt_write32bitreg(SYS_STATUS_ID, /*Clearing the SPI ready interrupt*/
SYS_STATUS_RCINIT_BIT_MASK | SYS_STATUS_SPIRDY_BIT_MASK);
dwt_setrxtimeout (150 * 1000); /* Configure RX timeout */
dwt_configuresleep(DWT_CONFIG, /* Configure DW1000 sleep and wake-up (through wake-up pin) parameters. */
DWT_PRES_SLEEP | DWT_WAKE_WUP | DWT_SLP_EN);
dwt_entersleep (DWT_DW_IDLE); /* Put DW3000 to sleep. */
return 0;
}
static void rx_ok_cb(const dwt_cb_data_t cb_data)
{
GPIO_PinOutToggle(LED_G_PORT, LED_G_PIN); / Toggle GREEN led /
dwt_entersleep (DWT_DW_IDLE); / Put DW3000 to sleep. */
}
static void rx_err_cb(const dwt_cb_data_t cb_data)
{
GPIO_PinOutToggle(LED_B_PORT, LED_B_PIN); / Toggle BLUE led /
dwt_entersleep (DWT_DW_IDLE); / Put DW3000 to sleep. */
static void rx_to_cb(const dwt_cb_data_t *cb_data)
{
GPIO_PinOutToggle(LED_B_PORT, LED_B_PIN); /* Toggle both leds */
GPIO_PinOutToggle(LED_G_PORT, LED_G_PIN);
dwt_entersleep (DWT_DW_IDLE); /* Put DW3000 to sleep. */
}
static void spi_err_cb(const dwt_cb_data_t *cb_data)
{
while (1)
{ };
}
static void spi_ready_cb(const dwt_cb_data_t *cb_data)
{
while (!dwt_checkidlerc()) /* Need to make sure DW IC is in IDLE_RC before proceeding */
{ };
dwt_restoreconfig(); /* Restore the required configurations on wake */
dwt_rxenable(DWT_START_RX_IMMEDIATE); /* Start receive */
}
void externalEventToWakeupDW3000(void)
{
GPIO_PinOutSet(DW1000_WAKEUP_PORT, DW1000_WAKEUP_PIN);
Sleep(2);
GPIO_PinOutClear(DW1000_WAKEUP_PORT, DW1000_WAKEUP_PIN);
}
Any suggestion will be greatly appreciated,
PaoloC