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();
}
Exemple #3
0
/**
 * 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();
    }
}