Problem sending 6 bytes to multiple services using sd_ble_gatts_hvx

Renix gravatar image

asked 2017-04-21 04:24:47 +0200

Petter gravatar image

updated 2017-04-21 10:57:51 +0200

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]);


// 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

edit retag flag offensive close delete report spam

2 answers

Sort by » oldest newest most voted
Renix gravatar image

answered 2017-04-21 14:20:39 +0200

Petter gravatar image

updated 2017-04-24 14:18:00 +0200


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.


edit flag offensive delete publish link more


I guess either stop the SPI, or only call nrf_drv_spi_transfer to update the rx_Buffer, and then update the characteristics. Thanks

Renix ( 2017-04-21 14:23:32 +0200 )editconvert to answer

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 ...(more)

Renix ( 2017-04-25 05:23:19 +0200 )editconvert to answer

I'm not exactly sure what is going on here, and even if you shared your code it would be a bit difficult to test it. Can't you just have a 2, 3 or 5 second timer and start the SPI transfer from the timer? And when the SPI transaction is complete you update the characteristics?

Petter Myhre ( 2017-04-25 08:50:09 +0200 )editconvert to answer


I think the while (!spi_xfer_done) { __WFE(); } is causing problems. I removed the __WFE(); inside of the timer update, but still no go.

The only way I could get SPI to function correctly, was to leave it in the main loop, and place an if() around it, so set a flag inside the timer event, so the main() loop will the do the SPI transfer.

It works, so all I can say is unless the SPI was stopped, the asynchronous SPI reads with the Timer 1sec interrupt, does not work.


Renix ( 2017-04-25 15:26:44 +0200 )editconvert to answer
Petter gravatar image

answered 2017-04-21 11:05:38 +0200

Renix gravatar image

updated 2017-04-25 15:27:34 +0200

So you have made 3 services with one characteristic in each? What exactly fails? Do you get any error inside our_temperature_characteristic_update()? Have you tried to use the debugger to see what happens? Does the chip reset? The last code piece you included seems to me incomplete, is this on purpose?

edit flag offensive delete publish link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer. Do not ask a new question or reply to an answer here.

[hide preview]

User menu

    or sign up

Recent questions

Question Tools

1 follower


Asked: 2017-04-21 04:24:47 +0200

Seen: 39 times

Last updated: Apr 21