void memoryTakeReference(void *handle) { INT_Disable(); if(memoryPtrFromHandle(handle) != NULL) { memoryObjs[(uint32_t)handle].refCount++; } INT_Enable(); }
void memoryFree(void *handle) { INT_Disable(); if(memoryPtrFromHandle(handle) != NULL) { memoryObjs[(uint32_t)handle].refCount--; } INT_Enable(); }
/** * Receive packet callback. * * @param[in] rxPacketHandle Contains a handle that points to the memory that * the packet was stored in. This handle will be the same as something * returned by the RAILCb_AllocateMemory() API. To convert this into a receive * packet info struct use the *** function. * * This function is called whenever a packet is received and returns to you the * memory handle for where this received packet and its appended information was * stored. After this callback is done we will release the memory handle so you * must somehow increment a reference count or copy the data out within this * function. */ void RAILCb_RxPacketReceived(void *rxPacketHandle) { RAIL_RxPacketInfo_t* rxPacketInfo = (RAIL_RxPacketInfo_t*) memoryPtrFromHandle(rxPacketHandle); if(rxPacketInfo->appendedInfo.crcStatus) { /* If this is an ACK, deal with it */ if( rxPacketInfo->dataLength == 4 && rxPacketInfo->dataPtr[3] == (current_tx_sequence) && waiting_for_ack) { /* Tell the radio to not ACK an ACK */ RAIL_AutoAckCancelAck(); waiting_for_ack = false; /* Save the pending bit */ last_ack_pending_bit = (rxPacketInfo->dataPtr[1] & (1 << 4)) != 0; /* Tell the stack we got an ACK */ tr_debug("rACK\n"); device_driver.phy_tx_done_cb( rf_radio_driver_id, current_tx_handle, PHY_LINK_TX_DONE, 1, 1); } else { /* Figure out whether we want to not ACK this packet */ /* * dataPtr[0] = length * dataLength = length w/o length byte * dataptr[1:2] = 0x61C9 -> 0b01100001 0b1100 1001 (version 1, dest 3, src 2, ACKreq, type = 1) * [1] => b[0:2] frame type, b[3] = security enabled, b[4] = frame pending, b[5] = ACKreq, b[6] = intrapan * [2] => b[2:3] destmode, b[4:5] version, b[6:7] srcmode */ if( (rxPacketInfo->dataPtr[1] & (1 << 5)) == 0 ) { /* Cancel the ACK if the sender did not request one */ RAIL_AutoAckCancelAck(); } tr_debug("rPKT %d\n", rxPacketInfo->dataLength); /* Feed the received packet into the stack */ device_driver.phy_rx_cb(rxPacketInfo->dataPtr + 1, rxPacketInfo->dataLength - 1, //TODO: take a new RAIL release that exposes LQI, or have LQI as function of RSSI 255, rxPacketInfo->appendedInfo.rssiLatch, rf_radio_driver_id); } } }
static void rf_thread_loop(const void *arg) { SL_DEBUG_PRINT("rf_thread_loop: starting (id: %d)\n", rf_thread_id); for (;;) { osEvent event = osSignalWait(0, osWaitForever); if (event.status != osEventSignal) { continue; } platform_enter_critical(); if (event.value.signals & SL_RX_DONE) { while(rx_queue_tail != rx_queue_head) { void* handle = (void*) rx_queue[rx_queue_tail]; RAIL_RxPacketInfo_t* info = (RAIL_RxPacketInfo_t*) memoryPtrFromHandle(handle); device_driver.phy_rx_cb( info->dataPtr + 1, info->dataLength - 1, info->appendedInfo.lqi, info->appendedInfo.rssiLatch, rf_radio_driver_id); memoryFree(handle); rx_queue[rx_queue_tail] = NULL; rx_queue_tail = (rx_queue_tail + 1) % RF_QUEUE_SIZE; } } else if (event.value.signals & SL_TX_DONE) { device_driver.phy_tx_done_cb(rf_radio_driver_id, current_tx_handle, PHY_LINK_TX_SUCCESS, 1, 1); } else if (event.value.signals & SL_ACK_RECV) { device_driver.phy_tx_done_cb( rf_radio_driver_id, current_tx_handle, (event.value.signals & SL_ACK_PEND) ? PHY_LINK_TX_DONE_PENDING : PHY_LINK_TX_DONE, 1, 1); } else if (event.value.signals & SL_ACK_TIMEOUT) { waiting_for_ack = false; device_driver.phy_tx_done_cb(rf_radio_driver_id, current_tx_handle, PHY_LINK_TX_FAIL, 1, 1); } else if(event.value.signals & SL_TX_ERR) { device_driver.phy_tx_done_cb( rf_radio_driver_id, current_tx_handle, PHY_LINK_CCA_FAIL, 8, 1); } else if(event.value.signals & SL_CAL_REQ) { SL_DEBUG_PRINT("rf_thread_loop: SL_CAL_REQ signal received (unhandled)\n"); } else if(event.value.signals & SL_RXFIFO_ERR) { SL_DEBUG_PRINT("rf_thread_loop: SL_RXFIFO_ERR signal received (unhandled)\n"); } else if(event.value.signals & SL_TXFIFO_ERR) { SL_DEBUG_PRINT("rf_thread_loop: SL_TXFIFO_ERR signal received (unhandled)\n"); } else if(event.value.signals & SL_QUEUE_FULL) { SL_DEBUG_PRINT("rf_thread_loop: SL_QUEUE_FULL signal received (packet dropped)\n"); } else { SL_DEBUG_PRINT("rf_thread_loop unhandled event status: %d value: %d\n", event.status, event.value.signals); } platform_exit_critical(); } }