We have an application where the host MCU sends a 4k page of data to the DA14585 via SPI interface every ~6.3 seconds. The DA14585 then relays this data to the radio via notifications. Between pages, we go into extended sleep mode, and the master MCU wakes the DA14585 using the Wakeup Timer. The SPI data is received via DMA, and the DMA finished IRQ handler then posts a custom message to the kernel to initiate the nofications and go back to extended sleep. All this appears to be working well, except as follows:
看起来核心消息只是在DMA IRQ处理程序(实际回调)执行和消息发送时BLE核心激活。读取SW平台参考的第7.1.2节表明消息需要与BLE核心同步。我推断这是on_ble_powered()回调的目的。我修改了代码以在DMA IRQ处理程序中设置标志,然后在on_ble_powered()回调函数中检查标志。如果设置标志,则发送消息以启动通知/特征值更新并清除标志。
However, with this code in place, the DA14585 fails to even advertise anymore. Why would adding an on_ble_powered() callback break the code? Is there a better way to "synchronize with the BLE core" when an async event requires sending a message?
以下是相关功能:
The DMA finished callback function:
static void epilog_spi_dma_done(void *userdata, uint16_t len)
{
/ *蓝牙的准备数据* /
eeg_rt.data = rteeg_buffer;
memcpy(&eeg_rt.pageaddr, spi.parmbuf, BTSPI_PARM_LEN);
/* Reset SPI state */
spi_reset_state();
spi_int_bit_clear();
NVIC_ClearPendingIRQ(SPI_IRQn);
spi_enable_irq();
RTPageReady = true;
//epilog_spi_send_page_done_msg(&eeg_rt, rteeg_buffer + EEG_PAGE_SIZE);
}
The on_ble_powered() callback:
arch_main_loop_callback_ret_t send_page_on_ble_powered(void)
{
if (RTPageReady) {
epilog_spi_send_page_done_msg(&eeg_rt, rteeg_buffer + EEG_PAGE_SIZE);
RTPageReady = false;
}
return KEEP_POWERED;
}
The page send function:
静态孔隙epilog_spi_send_page_done_msg (struct eegdata *eeg, uint8_t *evt)
{
struct msg_page_done *msg_param;
msg_param = ke_msg_alloc(appmsg_page_received,task_app,task_app,
msg_page_done);
msg_param->eeg = eeg;
msg_param->evt = evt;
ke_msg_send(msg_param);
}
Finally, a snip from the user_catch_rest_hndl() function to handle the APPMSG_PAGE_RECEIVED msg:
case APPMSG_PAGE_RECEIVED:
{
struct msg_page_done * msg_param =(struct msg_page_done *)param;
uint8_t state = ke_state_get(TASK_APP);
if (state == APP_CONNECTED) {
eegdata_start_notify(msg_param->eeg);
eegevent_start_notify(msg_param->eeg, msg_param->evt);
}
/* Re-enable sleep mode */
app_enable_wakeup(); /* Sets up wkupct */
arch_set_extended_sleep(false);
}
break;
Thanks in advance for any advice you can offer.

Hi mkelwood,
You are correct about the scheduling of the messages and the device only schedules while the BLE core is active and when the rwip_schedule() function executes. Messages can be send asychornously towards the stack but they will be served synchronously when the rwip_schedule gets executed. I dont see anything wrong with the code that you have posted, it seems ok. The fact that you are not able to advertise though should be something else, i mean as far as i can tell from the code as soon as the device starts advertising the code will go through the on_ble_powered, the flag should be false so no extra code will run during the advertising procedure. So i dont think that the code in the on_ble_powered() is affecting the functionallity of the advertising, something else should be going on. Check what the device does. Check if the advertising completion callback is getting invoked and check the reason of the advertising cancellation, in case the advertising is cancelled. Also as far far as i can tell you always return KEEP_POWER and not only if you have data available, this will keep your device active all the time and wont allow it to go to sleep.
Thanks MT_dialog
在调试器中运行此功能,很明显NMI处理程序正在绊倒,表明看门狗定时器已过期。将WatchDog_Reload()添加到on_ble_powered()处理程序恢复的BLE函数的开头。显然,即使是一个琐碎的短语on_ble_powered()处理程序对于看门狗来说太长了。
Thank you for clarifying that messages can be sent to the kernel asynchronously, although they won't be handled until the BLE core is on. This will be fine for our application - so I don't need the on_ble_powered() handler after all; I can just send the message to the kernel at the tail end of my dma complete handler. I wish the documentation was more clear on this subject - it implies that you can't even send messages when then BLE core is down.
It appears that my real problem is in the SPI communications handler. I'll start another thread if I need answers on that one. Thanks again.
Hi mkelwood,
Glad it helped.
最好的问候mt_dialog.