/** * @brief Order the radio_control module to do a RX, and report back to * search_callback(). */ static void order_search(void) { radio_event_t search_event; search_event.access_address = 1; /* RX: treat as bitfield */ search_event.callback.rx = search_callback; rbc_mesh_channel_get(&search_event.channel); search_event.event_type = RADIO_EVENT_TYPE_RX; search_event.start_time = 0; radio_order(&search_event); }
static void order_search(void) { radio_event_t evt; evt.event_type = RADIO_EVENT_TYPE_RX_PREEMPTABLE; evt.start_time = 0; evt.access_address = 1; evt.channel = g_state.channel; evt.callback.rx = rx_cb; if (!mesh_packet_acquire((mesh_packet_t**) &evt.packet_ptr)) { return; /* something is hogging all the packets */ } if (!radio_order(&evt)) { /* couldn't queue the packet for reception, immediately free its only ref */ mesh_packet_ref_count_dec((mesh_packet_t*) evt.packet_ptr); } }
uint32_t tc_tx(mesh_packet_t* p_packet) { TICK_PIN(PIN_MESH_TX); /* queue the packet for transmission */ radio_event_t event; memset(&event, 0, sizeof(radio_event_t)); event.start_time = 0; mesh_packet_ref_count_inc(p_packet); /* queue will have a reference until tx_cb */ event.packet_ptr = (uint8_t*) p_packet; event.access_address = 0; event.channel = g_state.channel; event.callback.tx = tx_cb; event.event_type = RADIO_EVENT_TYPE_TX; if (!radio_order(&event)) { mesh_packet_ref_count_dec(p_packet); /* queue couldn't hold the ref */ return NRF_ERROR_NO_MEM; } return NRF_SUCCESS; }
/** * @brief Handle trickle timing events */ static void trickle_step_callback(void) { TICK_PIN(6); /* check if timeslot is about to end */ if (timeslot_get_remaining_time() < RADIO_SAFETY_TIMING_US) return; uint64_t time_now = global_time + timer_get_timestamp(); trickle_time_update(time_now); packet_t packet; bool has_anything_to_send = false; mesh_srv_packet_assemble(&packet, PACKET_DATA_MAX_LEN * PACKET_MAX_CHAIN_LEN, &has_anything_to_send); if (has_anything_to_send) { TICK_PIN(PIN_MESH_TX); radio_disable(); uint8_t packet_and_addr_type = PACKET_TYPE_ADV_NONCONN | ((packet.sender.addr_type == BLE_GAP_ADDR_TYPE_PUBLIC)? 0 : PACKET_ADDR_TYPE_MASK); uint8_t* temp_data_ptr = &packet.data[0]; uint8_t* tx_data_ptr = &tx_data[0]; tx_data_ptr[PACKET_TYPE_POS] = packet_and_addr_type; /* Code structured for packet chaining, although this is yet to be implemented. */ do { uint8_t min_len = ((packet.length > PACKET_DATA_MAX_LEN)? PACKET_DATA_MAX_LEN : packet.length); tx_data_ptr[PACKET_PADDING_POS] = 0; tx_data_ptr[PACKET_LENGTH_POS] = (min_len + PACKET_ADDR_LEN); tx_data_ptr[PACKET_TYPE_POS] = packet_and_addr_type; memcpy(&tx_data_ptr[PACKET_ADDR_POS], packet.sender.addr, PACKET_ADDR_LEN); memcpy(&tx_data_ptr[PACKET_DATA_POS], &temp_data_ptr[0], min_len); radio_event_t tx_event; tx_event.access_address = 0; rbc_mesh_channel_get(&tx_event.channel); tx_event.event_type = RADIO_EVENT_TYPE_TX; tx_event.packet_ptr = &tx_data_ptr[0]; tx_event.start_time = 0; tx_event.callback.tx = NULL; radio_order(&tx_event); TICK_PIN(0); } while (0); order_search(); /* search for the rest of the timeslot */ } /* order next processing */ uint64_t next_time; uint64_t end_time = timeslot_get_end_time(); uint32_t error_code = mesh_srv_get_next_processing_time(&next_time); if (error_code == NRF_SUCCESS && next_time < global_time + end_time) { timer_abort(step_timer_index); step_timer_index = timer_order_cb(next_time - global_time, trickle_step_callback); } }