示例#1
0
/*
 * \brief TAL task handling
 *
 * This function
 * - Checks and allocates the receive buffer.
 * - Processes the TAL incoming frame queue.
 * - Implements the TAL state machine.
 */
void tal_task(void)
{
    /* Check if the receiver needs to be switched on. */
    if (tal_rx_on_required && (tal_state == TAL_IDLE))
    {
        /* Check if a receive buffer has not been available before. */
        if (tal_rx_buffer == NULL)
        {
            tal_rx_buffer = bmm_buffer_alloc(LARGE_BUFFER_SIZE);
        }

        /* Check if buffer could be allocated */
        if (NULL != tal_rx_buffer)
        {
            /*
             * Note:
             * This flag needs to be reset BEFORE the received is switched on.
             */
            tal_rx_on_required = false;

#ifdef PROMISCUOUS_MODE
            if (tal_pib.PromiscuousMode)
            {
                set_trx_state(CMD_RX_ON);
            }
            else
            {
                set_trx_state(CMD_RX_AACK_ON);
            }
#else   /* Normal operation */
            set_trx_state(CMD_RX_AACK_ON);
#endif
        }
    }
    else
    {
        /* no free buffer is available; try next time again */
    }

    /*
     * If the transceiver has received a frame and it has been placed
     * into the queue of the TAL, the frame needs to be processed further.
     */
    if (tal_incoming_frame_queue.size > 0)
    {
        buffer_t *rx_frame;

        /* Check if there are any pending data in the incoming_frame_queue. */
        rx_frame = qmm_queue_remove(&tal_incoming_frame_queue, NULL);
        if (NULL != rx_frame)
        {
            process_incoming_frame(rx_frame);
        }
    }

    /* Handle the TAL state machines */
    switch (tal_state)
    {
    case TAL_IDLE:
    /* Do nothing, but fall through... */
    case TAL_TX_AUTO:
        /* Wait until state is changed to TAL_TX_DONE inside tx end ISR */
        break;

#ifdef SW_CONTROLLED_CSMA
    case TAL_BACKOFF:
    /* Do nothing, but fall through... */
    case TAL_CCA:
        /* Do nothing */
        break;

    case TAL_CSMA_CONTINUE:
        csma_continue();
        break;

    case TAL_CCA_DONE:
        cca_done_handling();
        break;
#endif
    case TAL_TX_DONE:
        tx_done_handling();    // see tal_tx.c
        break;

#ifdef BEACON_SUPPORT
    case TAL_SLOTTED_CSMA:
        slotted_csma_state_handling();  // see tal_slotted_csma.c
        break;
#endif  /* BEACON_SUPPORT */

#if (MAC_SCAN_ED_REQUEST_CONFIRM == 1)
    case TAL_ED_RUNNING:
        /* Do nothing here. Wait until ED is completed. */
        break;

    case TAL_ED_DONE:
        ed_scan_done();
        break;
#endif /* (MAC_SCAN_ED_REQUEST_CONFIRM == 1) */
    default:
        Assert("tal_state is not handled" == 0);
        break;
    }
} /* tal_task() */
示例#2
0
文件: tal.c 项目: AndreyMostovov/asf
/*
 * \brief TAL task handling
 *
 * This function
 * - Checks and allocates the receive buffer.
 * - Processes the TAL incoming frame queue.
 * - Implements the TAL state machine.
 */
void tal_task(void)
{
	/* Check if the receiver needs to be switched on. */
	if (tal_rx_on_required && (tal_state == TAL_IDLE)) {
		/* Check if a receive buffer has not been available before. */
		if (tal_rx_buffer == NULL) {
			tal_rx_buffer = bmm_buffer_alloc(LARGE_BUFFER_SIZE);
		}

		/* Check if buffer could be allocated */
		if (NULL != tal_rx_buffer) {
			/*
			 * Note:
			 * This flag needs to be reset BEFORE the received is
			 *switched on.
			 */
			tal_rx_on_required = false;

			/*
			 * Release the protected buffer and set it again for
			 *further protection
			 * since the buffer is available now.
			 */
			trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_DISABLE); /*
			                                                       *Disable
			                                                       *buffer
			                                                       *protection
			                                                       *mode
			                                                       **/
			pal_timer_delay(2); /* Allow pin change to get effective */
			trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE); /*
			                                                      *Enable
			                                                      *buffer
			                                                      *protection
			                                                      *mode
			                                                      **/

			CONF_REG_WRITE();

#ifdef PROMISCUOUS_MODE
			if (tal_pib.PromiscuousMode) {
				set_trx_state(CMD_RX_ON);
			} else {
				set_trx_state(CMD_RX_AACK_ON);
			}

#else   /* Normal operation */
			set_trx_state(CMD_RX_AACK_ON);
#endif
		}
	} else {
		/* no free buffer is available; try next time again */
	}

	/*
	 * If the transceiver has received a frame and it has been placed
	 * into the queue of the TAL, the frame needs to be processed further.
	 */
	if (tal_incoming_frame_queue.size > 0) {
		buffer_t *rx_frame;

		/* Check if there are any pending data in the
		 *incoming_frame_queue. */
		rx_frame = qmm_queue_remove(&tal_incoming_frame_queue, NULL);
		if (NULL != rx_frame) {
			process_incoming_frame(rx_frame);
		}
	}

	/* Handle the TAL state machines */
	switch (tal_state) {
	case TAL_IDLE:
	/* Do nothing, but fall through... */
	case TAL_TX_AUTO:
		/* Wait until state is changed to TAL_TX_DONE inside tx end ISR
		 **/
		break;

	case TAL_TX_DONE:
		tx_done_handling(); /* see tal_tx.c */
		break;

#ifdef BEACON_SUPPORT
	case TAL_SLOTTED_CSMA:
		slotted_csma_state_handling(); /* see tal_slotted_csma.c */
		break;
#endif  /* BEACON_SUPPORT */

#if (MAC_SCAN_ED_REQUEST_CONFIRM == 1)
	case TAL_ED_RUNNING:
		/* Do nothing here. Wait until ED is completed. */
		break;

	case TAL_ED_DONE:
		ed_scan_done();
		break;

#endif /* (MAC_SCAN_ED_REQUEST_CONFIRM == 1) */
	default:
		Assert("tal_state is not handled" == 0);
		break;
	}
} /* tal_task() */
示例#3
0
/**
 * @brief Starts the timer for the backoff period and enables receiver.
 *
 * @param trx_id Transceiver identifier
 */
static void start_backoff(trx_id_t trx_id)
{
	/* Start backoff timer to trigger CCA */
	uint8_t backoff_8;
	backoff_8  = (uint8_t)(rand() & (((uint16_t)1 << BE[trx_id]) - 1));
	if (backoff_8 > 0) {
		uint8_t timer_id;
		uint16_t backoff_16;
		uint32_t backoff_duration_us;
		backoff_16 = backoff_8 * aUnitBackoffPeriod;
		backoff_duration_us
			= (uint32_t)tal_pib[trx_id].SymbolDuration_us *
				(uint32_t)backoff_16;
#ifdef REDUCED_BACKOFF_DURATION
		backoff_duration_us = REDUCED_BACKOFF_DURATION;
#endif
		if (trx_id == RF09) {
			timer_id = TAL_T_0;
		} else {
			timer_id = TAL_T_1;
		}

		retval_t status
			= pal_timer_start(timer_id, backoff_duration_us,
				TIMEOUT_RELATIVE,
				(FUNC_PTR)cca_start,
				(void *)&timer_cb_parameter[trx_id]);
		if (status != MAC_SUCCESS) {
			tx_done_handling(trx_id, status);
			return;
		}

		tx_state[trx_id] = TX_BACKOFF;

#ifdef RX_WHILE_BACKOFF
		/* Keep receiver on during backoff */
		if ((trx_default_state[trx_id] == RF_RX) &&
				(tal_pib[trx_id].NumRxFramesDuringBackoff <
				tal_pib[trx_id].MaxNumRxFramesDuringBackoff)) {
			if (trx_state[trx_id] != RF_RX) {
				if (trx_state[trx_id] == RF_TRXOFF) {
					switch_to_txprep(trx_id);
				}

				switch_to_rx(trx_id);
			}
		} else
#endif
		{
#ifdef USE_TXPREP_DURING_BACKOFF
			/* Switch to TXPREP during backoff */

			if (trx_state[trx_id] != RF_TXPREP) {
				switch_to_txprep(trx_id);
			}

#else
			/* Switch to TRXOFF during backoff */
			if (trx_state[trx_id] != RF_TRXOFF) {
				uint16_t reg_offset = RF_BASE_ADDR_OFFSET *
						trx_id;
				trx_reg_write(reg_offset + RG_RF09_CMD,
						RF_TRXOFF);
				trx_state[trx_id] = RF_TRXOFF;
			}

#endif
		}
	} else { /* no backoff required */
		/* Start CCA immediately - no backoff */
		cca_start((void *)&timer_cb_parameter[trx_id]);
	}
}