static int nrf_driver_send(void* p, int len) { /** * Air time is 1 byte preamble, 5 byte address, 2 byte CRC and 9 bits at the end. * We add 25 just to make sure we satisfy air time requirement. * The slots is the number of slots we allocate for someone to send their data, * and we pick one of them to avoid data collision when nodes repeat a packet. */ static const uint32_t s_pkt_air_time_us = 25 + (((8 * (MESH_PAYLOAD + 1 + 5 + 3)) * 1000) / WIRELESS_AIR_DATARATE_KBPS); const uint32_t slots = MESH_MAX_NODES; int packetWasSent = 1; /** * If we are not the source of this packet, that means we are repeating the packet. * If we are repeating the packet to discover the route (mac.dst == MESH_ZERO_ADDR) * then we need to randomly pick one air-time slot otherwise if all nodes send at * the same time, then their data will collide and packet won't go through. */ const mesh_packet_t *pkt = (mesh_packet_t*)p; if (mesh_get_node_address() != pkt->nwk.src) { if (MESH_ZERO_ADDR == pkt->mac.dst) { const uint32_t timeSlotDelayUs = ((rand() % slots) + 1) * s_pkt_air_time_us; delay_us(timeSlotDelayUs); /**< Maximize mesh nodes to repeat the packet and not collide */ } } // Bring from RX mode to TX mode nordic_rx_to_Stanby1(); nordic_standby1_to_tx_mode1(); // Send the packet : nordic_mode1_send_single_packet(p, len); nordic_clear_packet_sent_flag(); // Switch back to receive mode nordic_standby1_to_rx(); /* If FreeRTOS is running, we are probably blocked indefinitely on the activity semaphore. * So we will give the semaphore here, to give the mesh network task to unblock and * carry out retry logic. We use FromISR() API such that mesh_send() will not be * restricted to be called from a FreeRTOS task alone. */ if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState()) { xSemaphoreGiveFromISR(g_nrf_activity_sem, NULL); } return packetWasSent; }
// TO DO: void nordic_finishTxMode2_transitionToStandby1(char* data, unsigned short length) { // Wait until any previous Tx Packets are sent such that Nordic will be in Standby-1 mode. while(!nordic_is_tx_fifo_empty()); // From Standby-1 or Standby-2, filling FIFO goes to "Tx Settling" State. // Set CE to low while Nordic is in "Tx Setting" state. nordic_mode1_send_single_packet(data, length); // After packet is sent, Nordic will enter STANDBY-1 since CE is low while(NORDIC_INT_SIGNAL()); //while(!nordic_isTxFifoEmpty()); nordic_clear_packet_sent_flag(); }