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

Problem sending 6 bytes to multiple services using sd_ble_gatts_hvx

I would like to confirm my understanding of Problem sending 6 bytes to multiple services using sd_ble_gatts_hvx

I use nrf52832 sdk13.0.0

BLE SPI is master. I dropped the SCK to 1 Mhz I send x18 bytes of data to slave, just to generate the SPI clock.

I receive all x18 bytes on MISO. I can view it with analyzer. I also see the correct data in m_rx_buf, in IAR watch window.

I have x3 BLE services. I update characteristic with this

our_termperature_characteristic_update(&m_our_service, &testchar[0]);

sr2_termperature_characteristic_update(&m_sr2_service, &testchar[6]);

sr3_termperature_characteristic_update(&m_sr3_service, &testchar[12]);

So the plan is to update service 1 with data[0] to [5] Service 2 with data[6] to [11], and service 3 with data[12] to [17]

I made all the changes in xxx_service.c

// OUR_JOB: Step 2.H, Set characteristic length in number of bytes

attr_char_value.max_len     = 6;
attr_char_value.init_len    = 6;
uint8_t value[6]            = {0x16, 0x15, 0x14, 0x13, 0x12, 0x11};

I changed characteristic to int8_t

// ALREADY_DONE_FOR_YOU: Function to be called when updating characteristic value

void our_termperature_characteristic_update(ble_os_t *p_our_service, int8_t *temperature_value)

If I pass the pointer to the first 6x bytes of the 18-byte array, all is fine. Charateristics of ALL three services are updated correctly.

our_termperature_characteristic_update(&m_our_service, &testchar[0]);

When I try to update a service with next six bytes, ALL three services fail.

So services update with &testchar[0]); but fail with &testchar[6]);

our_termperature_characteristic_update(&m_our_service, &testchar[6]);

So

// ALREADY_DONE_FOR_YOU: Function to be called when updating characteristic value

void our_termperature_characteristic_update(ble_os_t *p_our_service, int8_t *temperature_value)
{
    // OUR_JOB: Step 3.E, Update characteristic value
    if (p_our_service->conn_handle != BLE_CONN_HANDLE_INVALID)
    {
        uint16_t               len = 6;

Perhaps I do not understand the sending mechanism correctly, but at least the first 6-bytes of the array are sent correctly, without fail.

Passing the pointer to the next six bytes is where all fails.

Any help appreciated

Parents
  • Petter,

    I believe I found the issue.

    I was calling the characteristic updates from inside the 1sec timer routine.

    So I think the SPI is free running, (in the main while loop) so it updates all the time.

    During the time the 1sec timer interrupts, the SPI may have updated. So I moved the characteristic update calls to right after the nrf_drv_spi_transfer

    FIXED!! A hack a day keeps the doctor away.

    Regards

  • I still have problems with updating characteristics to quickly. If I call the three (3) characteristic updates in the main() loop, it works.

    our_termperature_characteristic_update(&m_our_service, &testchar[12]);
    sr2_termperature_characteristic_update(&m_sr2_service, &testchar[6]);
    sr3_termperature_characteristic_update(&m_sr3_service, &testchar[0]);
    

    If I call it from the static void timer_timeout_handler(void * p_context)

    then the SPI info is out of sync. So it seems because SPI is updated through an interrupt, (not DMA it seems), SPI info is correct right after while (!spi_xfer_done)

    But if I call my service characteristic updates from timer_timeout_handler(void * p_context) Since it is asynchronous with SPI events, I get shifted SPI info. So by the time the timer happens, SPI has updated some values, but not all.

    It is still correct information, it is just shifted in the buffer, so say val[1] holds val[5] info.

    The problem is that I place a nrf_delay_ms(500); in the main loop, so the updates happens very quickly. I've seen on a iPhone 4s that after a while, the screen starts flickering as updates happen.

    So I need to slow the updates down, 1sec or even 5 second update rate is fine.

    I saw a suggestion to uninit the SPI, but that did not seem to work.

    I need a way to update every say 2 or 3 or 5 seconds, but know when SPI has the correct info.

    Any help appreciated

Reply
  • I still have problems with updating characteristics to quickly. If I call the three (3) characteristic updates in the main() loop, it works.

    our_termperature_characteristic_update(&m_our_service, &testchar[12]);
    sr2_termperature_characteristic_update(&m_sr2_service, &testchar[6]);
    sr3_termperature_characteristic_update(&m_sr3_service, &testchar[0]);
    

    If I call it from the static void timer_timeout_handler(void * p_context)

    then the SPI info is out of sync. So it seems because SPI is updated through an interrupt, (not DMA it seems), SPI info is correct right after while (!spi_xfer_done)

    But if I call my service characteristic updates from timer_timeout_handler(void * p_context) Since it is asynchronous with SPI events, I get shifted SPI info. So by the time the timer happens, SPI has updated some values, but not all.

    It is still correct information, it is just shifted in the buffer, so say val[1] holds val[5] info.

    The problem is that I place a nrf_delay_ms(500); in the main loop, so the updates happens very quickly. I've seen on a iPhone 4s that after a while, the screen starts flickering as updates happen.

    So I need to slow the updates down, 1sec or even 5 second update rate is fine.

    I saw a suggestion to uninit the SPI, but that did not seem to work.

    I need a way to update every say 2 or 3 or 5 seconds, but know when SPI has the correct info.

    Any help appreciated

Children
No Data
Related