I use a module that has nrf52833 . this is DWM3001C . My responder software not working with BLE and SD.

Hi, 

ı am using a dwm3001c that has a nrf52833 microprocessor. I want to set communication with initiator and responder . My initiator code that is ss_twr_initiator example in API.My responder code that is ss_twr_responder example in API. My initiator work werll with BLE and SD. ı add dfu and butonless and bluetooth com. to initiator.

But my responder not work with BLE and SD. I add dfu buttonless and bluetooth like initiator but not working. However only my adding code as ble buttonless and bluetooth work well . But this has not API as responder. AND API work well when that has not BLE and buttonless and bluetooth communication.

Please help me.

My responder as like following:

#define DEVICE_NAME "FY/Havelsan/RESPFY" /**< Name of device. Will be included in the advertising data. */
#define APP_BLE_OBSERVER_PRIO 3 /**< Application's BLE observer priority. You shouldn't need to modify this value. */
#define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */
#define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms; this value corresponds to 40 ms). */
#define APP_ADV_DURATION BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising time-out (in units of seconds). When set to 0, we will never time out. */
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(100, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.5 seconds). */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(200, UNIT_1_25_MS) /**< Maximum acceptable connection interval (1 second). */
#define SLAVE_LATENCY 0 /**< Slave latency. */
#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory time-out (4 seconds). */
#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(20000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (15 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (5 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
#define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
#define MAX_TEST_DATA_BYTES (15U)
#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE 256
#define UNIT_TEST 0
#define SAMPLES_IN_BUFFER 5
#define UART_HWFC APP_UART_FLOW_CONTROL_DISABLED

static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Buffer for storing an encoded advertising set. */
static uint8_t m_enc_scan_response_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Buffer for storing an encoded scan data. */
static nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);


static ble_gap_adv_data_t m_adv_data =
{
.adv_data =
{
.p_data = m_enc_advdata,
.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX
},
.scan_rsp_data =
{
.p_data = m_enc_scan_response_data,
.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX

}
};

static nrf_saadc_value_t m_buffer_pool[2][SAMPLES_IN_BUFFER];
static nrf_ppi_channel_t m_ppi_channel;
static uint32_t m_adc_evt_counter;


void wd_event_handler(void);
void wdt_init(void);


nrfx_wdt_channel_id m_channel_id;

NRF_BLE_GATT_DEF(m_gatt);
NRF_BLE_QWR_DEF(m_qwr);
BLE_CUS_DEF(m_cus);
BLE_ESS_DEF(p_ess);

APP_TIMER_DEF(m_notification_timer_id);
APP_TIMER_DEF(m_notification_timer_id_2);
APP_TIMER_DEF(m_app_timer_id);
APP_TIMER_DEF(m_timer);

extern ble_cus_t m_cus;
extern uint32_t ble_rate;
extern ble_ess_t p_ess;


extern example_ptr example_pointer;
extern int unit_test_main(void);
extern void build_examples(void);

void uart_error_handle(app_uart_evt_t * p_event)
{
if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
{
//APP_ERROR_HANDLER(p_event->data.error_communication);
}
else if (p_event->evt_type == APP_UART_FIFO_ERROR)
{
APP_ERROR_HANDLER(p_event->data.error_code);
}

else if (p_event->evt_type == APP_UART_DATA_READY)
{
//app_uart_get(&a);
UNUSED_VARIABLE(app_uart_get(&a));
//printf("%d",a);
err_code=app_uart_put(a);
APP_ERROR_CHECK(err_code);

/*err_code=app_uart_put(a);
APP_ERROR_CHECK(err_code);*/
}

else if (p_event->evt_type == APP_UART_TX_EMPTY)
{
//printf("always_ok...");
}


}

int main(void)
{

bool erase_bonds;

nrf_gpio_cfg_output(red_led);
nrf_gpio_cfg_output(green_led);
nrf_gpio_cfg_output(blue_led);
nrf_gpio_cfg_input(c_type_pin,NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_input(bat_chg_v,NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_input(user_buton, NRF_GPIO_PIN_PULLUP);

//nrf_gpio_cfg_input(ADC,NRF_GPIO_PIN_NOPULL);
nrf_gpio_pin_set(red_led);
nrf_gpio_pin_set(green_led);
nrf_gpio_pin_set(blue_led);


nrf_drv_clock_init();

nrf_drv_clock_lfclk_request(NULL);

wdt_init();


log_init();

// err_code = ble_dfu_buttonless_async_svci_init();
//APP_ERROR_CHECK(err_code);

timers_init();

power_management_init();

saadc_init();

ble_stack_init();

gap_params_init();

gatt_init();

qwr_init();

services_init();

advertising_init();

conn_params_init();

advertising_start();



uint32_t uart_enable;

if(!nrf_gpio_pin_read(bat_chg_v))
{
uart_enable= 15;
}
else
{
uart_enable= UART_PIN_DISCONNECTED;
}

const app_uart_comm_params_t comm_params =
{
RX_PIN_NUMBER,
TX_PIN_NUMBER,
RTS_PIN_NUMBER,
CTS_PIN_NUMBER,
UART_HWFC,
false,
#if defined (UART_PRESENT)
NRF_UART_BAUDRATE_115200
#else
NRF_UARTE_BAUDRATE_115200
#endif
};

APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_error_handle,
APP_IRQ_PRIORITY_LOWEST,
err_code);

APP_ERROR_CHECK(err_code);

build_examples();

gpio_init();

nrf52840_dk_spi_init();

dw_irq_init();


nrf_delay_ms(2);


if (UNIT_TEST)
{
unit_test_main();
}
else
{
example_pointer();
}

}

and my responder code as like following. Note this is same to original of API . I do not changed anything.

#include "deca_probe_interface.h"
#include <deca_device_api.h>
#include <deca_spi.h>
#include <example_selection.h>
#include <port.h>
#include <shared_defines.h>
#include <shared_functions.h>

#if defined(TEST_SS_TWR_RESPONDER)

extern void test_run_info(unsigned char *data);

/* Example application name */
#define APP_NAME "SS TWR RESP v1.0"

/* 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 */
};

/* Default antenna delay values for 64 MHz PRF. See NOTE 2 below. */
#define TX_ANT_DLY 16385
#define RX_ANT_DLY 16385

/* Frames used in the ranging process. See NOTE 3 below. */
static uint8_t rx_poll_msg[] = { 0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0xE0, 0, 0 };
static uint8_t tx_resp_msg[] = { 0x41, 0x88, 0, 0xCA, 0xDE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
/* Length of the common part of the message (up to and including the function code, see NOTE 3 below). */
#define ALL_MSG_COMMON_LEN 10
/* Index to access some of the fields in the frames involved in the process. */
#define ALL_MSG_SN_IDX 2
#define RESP_MSG_POLL_RX_TS_IDX 10
#define RESP_MSG_RESP_TX_TS_IDX 14
#define RESP_MSG_TS_LEN 4
/* Frame sequence number, incremented after each transmission. */
static uint8_t frame_seq_nb = 0;

/* Buffer to store received messages.
* Its size is adjusted to longest frame that this example code is supposed to handle. */
#define RX_BUF_LEN 12 // Must be less than FRAME_LEN_MAX_EX
static uint8_t rx_buffer[RX_BUF_LEN];

/* Hold copy of status register state here for reference so that it can be examined at a debug breakpoint. */
static uint32_t status_reg = 0;

/* Delay between frames, in UWB microseconds. See NOTE 1 below. */
#define POLL_RX_TO_RESP_TX_DLY_UUS 650

/* Timestamps of frames transmission/reception. */
static uint64_t poll_rx_ts;
static uint64_t resp_tx_ts;

/* Values for the PG_DELAY and TX_POWER registers reflect the bandwidth and power of the spectrum at the current
* temperature. These values can be calibrated prior to taking reference measurements. See NOTE 5 below. */
extern dwt_txconfig_t txconfig_options;

/*! ------------------------------------------------------------------------------------------------------------------
* @fn main()
*
* @brief Application entry point.
*
* @param none
*
* @return none
*/
int ss_twr_responder(void)
{
/* Display application name on LCD. */
//test_run_info((unsigned char *)APP_NAME);

/* Configure SPI rate, DW3000 supports up to 36 MHz */
port_set_dw_ic_spi_fastrate();

/* Reset and initialize DW chip. */
reset_DWIC(); /* Target specific drive of RSTn line into DW3000 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)

/* Probe for the correct device driver. */
dwt_probe((struct dwt_probe_s *)&dw3000_probe_interf);

while (!dwt_checkidlerc()) /* Need to make sure DW IC is in IDLE_RC before proceeding */ { };
if (dwt_initialise(DWT_DW_INIT) == DWT_ERROR)
{
//test_run_info((unsigned char *)"INIT FAILED ");
//while (1) { };
}

/* Enabling LEDs here for debug so that for each TX the D1 LED will flash on DW3000 red eval-shield boards. */
dwt_setleds(DWT_LEDS_ENABLE | DWT_LEDS_INIT_BLINK);

/* Configure DW IC. See NOTE 13 below. */
/* if the dwt_configure returns DWT_ERROR either the PLL or RX calibration has failed the host should reset the device */
if (dwt_configure(&config))
{
// test_run_info((unsigned char *)"CONFIG FAILED ");
//while (1) { };
}

/* Configure the TX spectrum parameters (power, PG delay and PG count) */
dwt_configuretxrf(&txconfig_options);

/* Apply default antenna delay value. See NOTE 2 below. */
dwt_setrxantennadelay(RX_ANT_DLY);
dwt_settxantennadelay(TX_ANT_DLY);

/* Next can enable TX/RX states output on GPIOs 5 and 6 to help debug, and also TX/RX LEDs
* Note, in real low power applications the LEDs should not be used. */
dwt_setlnapamode(DWT_LNA_ENABLE | DWT_PA_ENABLE);

/* Loop forever responding to ranging requests. */
while (1)
{
/* Activate reception immediately. */
dwt_rxenable(DWT_START_RX_IMMEDIATE);

/* Poll for reception of a frame or error/timeout. See NOTE 6 below. */
waitforsysstatus(&status_reg, NULL, (DWT_INT_RXFCG_BIT_MASK | SYS_STATUS_ALL_RX_ERR), 0);

if (status_reg & DWT_INT_RXFCG_BIT_MASK)
{
uint16_t frame_len;

/* Clear good RX frame event in the DW IC status register. */
dwt_writesysstatuslo(DWT_INT_RXFCG_BIT_MASK);

/* A frame has been received, read it into the local buffer. */
frame_len = dwt_getframelength();
if (frame_len <= sizeof(rx_buffer))
{
dwt_readrxdata(rx_buffer, frame_len, 0);

/* Check that the frame is a poll sent by "SS TWR initiator" example.
* As the sequence number field of the frame is not relevant, it is cleared to simplify the validation of the frame. */
rx_buffer[ALL_MSG_SN_IDX] = 0;
if (memcmp(rx_buffer, rx_poll_msg, ALL_MSG_COMMON_LEN) == 0)
{
uint32_t resp_tx_time;
int ret;

/* Retrieve poll reception timestamp. */
poll_rx_ts = get_rx_timestamp_u64();

/* Compute response message transmission time. See NOTE 7 below. */
resp_tx_time = (poll_rx_ts + (POLL_RX_TO_RESP_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8;
dwt_setdelayedtrxtime(resp_tx_time);

/* Response TX timestamp is the transmission time we programmed plus the antenna delay. */
resp_tx_ts = (((uint64_t)(resp_tx_time & 0xFFFFFFFEUL)) << 8) + TX_ANT_DLY;

/* Write all timestamps in the final message. See NOTE 8 below. */
resp_msg_set_ts(&tx_resp_msg[RESP_MSG_POLL_RX_TS_IDX], poll_rx_ts);
resp_msg_set_ts(&tx_resp_msg[RESP_MSG_RESP_TX_TS_IDX], resp_tx_ts);

/* Write and send the response message. See NOTE 9 below. */
tx_resp_msg[ALL_MSG_SN_IDX] = frame_seq_nb;
dwt_writetxdata(sizeof(tx_resp_msg), tx_resp_msg, 0); /* Zero offset in TX buffer. */
dwt_writetxfctrl(sizeof(tx_resp_msg), 0, 1); /* Zero offset in TX buffer, ranging. */
ret = dwt_starttx(DWT_START_TX_DELAYED);

/* If dwt_starttx() returns an error, abandon this ranging exchange and proceed to the next one. See NOTE 10 below. */
if (ret == DWT_SUCCESS)
{
/* Poll DW IC until TX frame sent event set. See NOTE 6 below. */
waitforsysstatus(NULL, NULL, DWT_INT_TXFRS_BIT_MASK, 0);

/* Clear TXFRS event. */
dwt_writesysstatuslo(DWT_INT_TXFRS_BIT_MASK);

/* Increment frame sequence number after transmission of the poll message (modulo 256). */
frame_seq_nb++;
}
}
}
}
else
{
/* Clear RX error events in the DW IC status register. */
dwt_writesysstatuslo(SYS_STATUS_ALL_RX_ERR);
}
}
}
#endif

My responder code when I download ,ıt communicate with initiator for 5 times then crash and not communicate.

but only API can full communicate.

Preprocessors definitions:

BL_SETTINGS_ACCESS_ONLY

NRF_DFU_TRANSPORT_BLE=1

BOARD_DWM3001C

CONFIG_GPIO_AS_PINRESET

FLOAT_ABI_HARD

NO_VTOR_CONFIG

INITIALIZE_USER_SECTIONS

NRF52833_XXAA

NRF_SD_BLE_API_VERSION=7

S140

SOFTDEVICE_PRESENT

Parents Reply
  • Hi, 
    The error tells that there was a violation when accessing RAM that occupied by the softdevice. This will cause a reset on the device and it explain why the responder disconnected. 


    Could you try to print the pc info when the error occurs ? 
    Could you check the code to see if it try to access any RAM area that occupied by the softdevice (anything below 0x20002AE8)  ? 
    Or if the code access any peripheral blocked/restricted by the softdevice. You can take a look here.

    Also check if the library use any IRQ handler and if there is any loop that can take a long time in the IRQ handler ? 

Children
  • Hİ, 

    Thanks,

    I contact to nrf on another topic((+) SOFTDEVICE: INVALID MEMORY ACCESS - Nordic Q&A - Nordic DevZone - Nordic DevZone (nordicsemi.com)). then 

    Now statues is;

    but ı change  from *((volatile uint32_t *)0x40000E00) = m_anomaly_198_preserved_value; to *((volatile uint32_t *)0x40002000) = m_anomaly_198_preserved_value; in anomaly_198_disable and enable  now not crash my responder continues advertise but dwm3001c module that has a responder code can not receive frame .

    responder can frame only one time in 15-20 loop.

    but if ı do not use SD AND BLE , my RESPONDER CAN RECEİVE FRAME WELL.

    now how can I fix to receive frame issue?

  • Hi, I can not go to all functions.To access some functions are blocked by qorvo.

    And I can fix violation issue. I search pc,info and id . 

  • Hİ,

    ı found reason to can not receive frame on responder.

    this issue is  that responder wait for long time on  waitforsysstatus(NULL, NULL, DWT_INT_TXFRS_BIT_MASK, 0);

    then 

    responder can not receive.

     this function's define is:

    please help me.

    I can not find reason.I can not debug step by step .Because I have softdevice.

  • Hi Furkan, 
    We are not very familiar with the module/library and not sure how it work. Could you give some description how the nRF52 inside the module communicate with the UWB component, via SPI or I2C ? 
    Does Qorvo provide any example that use both BLE and UWB ? 


    How do you configure the interrupt level of the UWB module ? Note that you need to follow the interrupt priority level guide line here.
    Try to avoid staying in high priority interrupt handler to wait for something. 

  • Hi Huang,

    I'd like to add some comments about this. because I also want to add the BLE to in Qorvo SDK(since Qorvo chose nRF52850 as MCU).

    here is the info on the Qorvo SDK

    - nRF SDK 17.1.0

    - UWB IC chose SPI as the interface to comm MCU nRF52840

    -  Interrupt priority as follows

    // Qorvo Modified:
    
    
    // HAL_SPI 
    #ifdef SOFTDEVICE_PRESENT
        spi_config->irq_priority = (APP_IRQ_PRIORITY_MID - 1);
    #else
        spi_config->irq_priority = (APP_IRQ_PRIORITY_MID - 2);
    #endif
    
    
    // FreeRTOSConfig.h
    /* The highest interrupt priority that can be used by any interrupt service
    routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
    INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
    PRIORITY THAN THIS! (higher priorities are lower numeric values. */
    //#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    _PRIO_APP_HIGH
    #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    _PRIO_APP_LOW_MID
    
    

    in my understanding, interrupt priority configuration is as follows:

    So, Could you help to review the Interrupt priority modified by the Qorvo side?

Related