This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF51 DK Event/Function on connect/disconnect

Hello community,

I'm facing a problem with nRF51 DK PCA10028 and a function call on connected or disconnected state including NRF_LOG commands. Using SDK 12.3.0

On connected state I want to wakeup a device on SPI and start communication. On disconnect I want to stop device and put it to standby. Both functions (device_start()/device_stop()) are defined in an extra .h and .c file. If I call device_start() in main, everything works fine.

First I tried to call the function from "on_ble_evt" function and case BLE_GAP_EVT_CONNECTED:
Second, I put the device_start() and device_stop function call to ble_evt_dispatch and if (p_ble_evt->header.evt_id == BLE_GAP_EVT_DISCONNECTED) { event checks.

In both cases, the software crashes --> Debugger moves to address 0xFFFFFF80 and I receive SIGTRAP exception at nrf_log_dequeue() at nrf_log_frontend.c:817 and device hangs

If I remove device_start() and device_stop() function calls, everything works fine.

What's the ideal way to react on connected and disconnected events and execute custom functions?

Thx in advance!

Best regards,
Alexander

Parents
  • Hi,

    Could you post the code for the device_start() function? Are you spending alot of time in device_start() ?

    An alternative to moving the device_start()  function to main(), is to start a app_timer when you get the connect event, and when the timer expires some defined numbers of seconds later, you call the device_start() in the app_timer handler.

  • Hi,

    the device_start() function:

    device_start() {
        NRF_LOG_INFO("WAKEUP device\r\n");
        send_command(COM_WAKEUP);
        nrf_delay_us(3); // Need to wait > 4 tclk cycles (> 4 * 514ns = > 2,1us) before continue
        NRF_LOG_INFO("START conversion and RDATAC mode\r\n");
        send_command(COM_START);
        send_command(COM_RDATAC);
        // Enable DRDY interrupt
        nrf_drv_gpiote_in_event_enable(PIN_DRDY, true);
        NRF_LOG_INFO("Gpio nDRDY interrupt started\r\n");
    }

    I made a few tests and it seems, that I get the same error, if I call device_start() after start_application_timers().
    There is one timer for battery service in parallel.

    So you mean it would be better to have a timer to check if a device is connected or not an execute device start inside timer? And in "on_ble_evt" I only set a boolean flag "connected" to true or false?

    UPDATE:
    The function send_command(...) is sending one byte via SPI. The last output on LOG Terminal is "SPI send data".

    void send_command(uint8_t command)
    {
        NRF_LOG_INFO("Send command 0x%02X\r\n", command);
        uint8_t rxBuf[1]
        spi_send_recv(&command, rxBuf, 1);
    }
    
    void spi_event_handler(nrf_drv_spi_evt_t const * p_event)
    {
        spi_xfer_done = true;
    }
    
    void spi_send_recv(uint8_t* txBuf, uint8_t* rxBuf, uint16_t length)
    {
        NRF_LOG_INFO("SPI Send data");
        memset(rxBuf, 0, length);
        spi_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, txBuf, length, rxBuf, length));
        while (!spi_xfer_done) {
            __WFE();
        }
        NRF_LOG_INFO("SPI recevied data");
    }

    Best regards,
    Alexander

  • Lampi87 said:
    So you mean it would be better to have a timer to check if a device is connected or not an execute device start inside timer? And in "on_ble_evt" I only set a boolean flag "connected" to true or false?

    The idea behind the timer in this case would just be to delay initializing the SPI device, to some time after you get the BLE_GAP_EVT_CONNECTED event. 

    But I now see that you are waiting for spi_xfer_done to be set true in spi_send_recv(), but the spi_event_handler() IRQ priority is most likely the same as the ble_evt_dispatch() priority, so you will never exit the spi_send_recv() function. Try to remove the "while (!spi_xfer_done)  { __WFE();} " code.

  • Thank you for clarification, I will give it a try.

    I use the spi_send_recv function inside different functions. And at some places I need to wait for the response. If I remove the while function, rxBuf will stay empty when spi_send_recv is exited. Am I right?

  • I made some changes and now it seems to work. Please correct me if it's the wrong way!

    • SPI0_USE_EASY_DMA set to 1
    • SPI_DEFAULT_CONFIG_IRQ_PRIORITY increased to 1 (initial 3)

    Now I can call device_start() and device_stop() on on_ble_evt function without any changes on spi communication

Reply Children
No Data
Related