123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- //需要使用的头文件
- #include <stdint.h>
- #include <stdbool.h>
- #include "nrf.h"
- #include "app_error.h"
- #include "nrf_gpio.h"
- #include "boards.h"
- #include "nrf_nvic.h"
- #include "ble_comm.h"
- // 定义一个timeSlot的变量,该变量用来设置 请求的timeSlot的特性。
- static nrf_radio_request_t m_timeslot_request;
- // 请求的timeSlot的时间间隙长度
- static uint32_t m_slot_length;
- // 信号处理函数的返回值。
- static nrf_radio_signal_callback_return_param_t signal_callback_return_param;
- //请求一个earliest possible 类型的timeSlot,第一次请求timeSLot的时候总是以该类型发起
- // timeSlot时间长度为 5000 us
- // timeSlot的请求优先级为正常优先级
- // 这里设置了在timeSlot运行过程中会打开外部高频晶振时钟源,不过其实不是必须的。
- // timeout_us表示请求timeSlot发出后,系统接收这个请求的最大延迟。
- // timeSLot的时间长度为5000us
- uint32_t request_next_event_earliest(void)
- {
- m_slot_length = 5000;
- m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
- m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
- m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
- m_timeslot_request.params.earliest.length_us = m_slot_length;
- m_timeslot_request.params.earliest.timeout_us = 1000000;
- return sd_radio_request(&m_timeslot_request);
- }
- // 配置 earliest possible的类型的 timeSlot
- void configure_next_event_earliest(void)
- {
- m_slot_length = 5000;
- m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
- m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
- m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
- m_timeslot_request.params.earliest.length_us = m_slot_length;
- m_timeslot_request.params.earliest.timeout_us = 1000000;
- }
- // 配置normal类型的timeSlot
- void configure_next_event_normal(void)
- {
- m_slot_length = 5000;
- m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_NORMAL;
- m_timeslot_request.params.normal.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
- m_timeslot_request.params.normal.priority = NRF_RADIO_PRIORITY_HIGH;
- // norma类型的timeSlot 的开始时间为距离上一个 timeSlot的开始时间 distance_us后
- m_timeslot_request.params.normal.distance_us = 100000;
- m_timeslot_request.params.normal.length_us = m_slot_length;
- }
- // timeSlot 会话相关的 一些事件的处理
- // 这里的主要处理是,在收到 IDLE事件,即申请的这段会话中没有 timeSlot需要处理后会
- // 产生这个事件,那么就可以 通过sd_radio_session_close 函数关闭这个 会话了
- // 另外请求的timeSlot可能因为和协议栈运行产生冲突,那么就可以被阻塞或去掉,所以
- // NRF_EVT_RADIO_BLOCKED 和 NRF_EVT_RADIO_CANCELED 事件的处理都是重新发起请求
- void nrf_evt_signal_handler(uint32_t evt_id)
- {
- uint32_t err_code;
- switch (evt_id)
- {
- case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
- BLE_PRINT("NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN\r\n");
- break;
- case NRF_EVT_RADIO_SESSION_IDLE:
- BLE_PRINT("NRF_EVT_RADIO_SESSION_IDLE\r\n");
- sd_radio_session_close();
- break;
- case NRF_EVT_RADIO_SESSION_CLOSED:
- BLE_PRINT("NRF_EVT_RADIO_SESSION_CLOSED\r\n");
- break;
- case NRF_EVT_RADIO_BLOCKED:
- BLE_PRINT("NRF_EVT_RADIO_BLOCKED\r\n");
- //注意这里没有break,所以 这两个事件的处理都是重新发起请求
- case NRF_EVT_RADIO_CANCELED:
- BLE_PRINT("NRF_EVT_RADIO_CANCELED\r\n");
- err_code = request_next_event_earliest();
- APP_ERROR_CHECK(err_code);
- break;
- default:
- break;
- }
- }
- // timeSlot相关的信号处理函数。
- // 当请求的timeSlot 被安排开始后,就会收到 START信号,在这个信号处理里面实现
- // 实现翻转 LED灯同时设置 Timer0的超时时间,time0在timeSLot开始后会被自动重置为
- // 1MH运行从0 计数,所以这里设置time0的超时时间比 timeSlot的时间长度短1000us,//这样在timeSLot
- // 结束之前就可以收到 NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0信号,然后在这信号处
- // 理里做一些收尾工作,在这里我们实现的是请求下一个timeSlot
- // NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO信号不需要处理,因为我们没有在timeSLot
- // 中使用Radio,所以不会有这个信号。
- nrf_radio_signal_callback_return_param_t * radio_callback(uint8_t signal_type)
- {
- static uint8_t start_count = 0;
- static uint8_t timer0_count = 0;
- switch(signal_type)
- {
- case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
- signal_callback_return_param.params.request.p_next = NULL;
- signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
- NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
- NRF_TIMER0->CC[0] = m_slot_length - 1000;
- NVIC_EnableIRQ(TIMER0_IRQn);
- nrf_gpio_pin_toggle(16);
- //避免打印太快
- if(start_count++ >10 ){
- BLE_PRINT("NRF_RADIO_CALLBACK_SIGNAL_TYPE_START\r\n");
- start_count = 0;
- }
- break;
- case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
- signal_callback_return_param.params.request.p_next = NULL;
- signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
- break;
- case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
- configure_next_event_normal();
- signal_callback_return_param.params.request.p_next = &m_timeslot_request;
- signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
- if(timer0_count++ >10 ){
- BLE_PRINT("NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0\r\n");
- timer0_count = 0;
- }
- break;
- case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
- BLE_PRINT("NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED\r\n");
- break;
- case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:
- BLE_PRINT("NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED\r\n");
- configure_next_event_earliest();
- signal_callback_return_param.params.request.p_next = &m_timeslot_request;
- signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
- break;
- default:
- //No implementation needed
- break;
- }
- return (&signal_callback_return_param);
- }
- // timeSlot初始化函数。
- uint32_t timeslot_sd_init(void)
- {
- uint32_t err_code;
- err_code = sd_radio_session_open(radio_callback);
- if (err_code != NRF_SUCCESS)
- {
- return err_code;
- }
- err_code = request_next_event_earliest();
- if (err_code != NRF_SUCCESS)
- {
- (void)sd_radio_session_close();
- return err_code;
- }
- nrf_gpio_cfg_output(16);
- return NRF_SUCCESS;
- }
|