Esempio n. 1
0
/**
 * @brief Handles incoming frame from transceiver
 *
 * @param trx_id Transceiver identifier
 */
static void handle_incoming_frame(trx_id_t trx_id)
{
	uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id;

	if (is_frame_an_ack(trx_id)) {
		if (tx_state[trx_id] == TX_WAITING_FOR_ACK) {
			if (is_ack_valid(trx_id)) {
				/* Stop ACK timeout timer */
				stop_tal_timer(trx_id);
				/* Re-store frame filter to pass "normal" frames
				 **/
				/* Configure frame filter to receive all allowed
				 *frame types */
#ifdef SUPPORT_FRAME_FILTER_CONFIGURATION
				trx_reg_write(reg_offset + RG_BBC0_AFFTM,
						tal_pib[trx_id].frame_types);
#else
				trx_reg_write(reg_offset + RG_BBC0_AFFTM,
						DEFAULT_FRAME_TYPES);
#endif
				tx_done_handling(trx_id, MAC_SUCCESS);
			} else {
				/* Continue waiting for incoming ACK */
				switch_to_rx(trx_id);
			}
		} else {
			/* No interest in ACKs */
			switch_to_rx(trx_id);
		}

		return; /* no further processing of ACK frames */
	}

	/* Check if ACK transmission is done by transceiver */
	bool ack_transmitting = trx_bit_read(reg_offset + SR_BBC0_AMCS_AACKFT);
	if (ack_transmitting) {
	} else {
		complete_rx_transaction(trx_id);
#ifdef RX_WHILE_BACKOFF
		if (tx_state[trx_id] == TX_DEFER) {
			csma_start(trx_id);
		}

#endif
	}
}
Esempio n. 2
0
void tx_msg_char(void)
{
    UDR0 = tx_buffer.buffer[tx_idx];
    tx_idx++;
    if (tx_idx == tx_len)
    {
        rx_state = RX_IDLE;
        tx_state = TX_IDLE;
        transport_state = RX;
        switch_to_rx();
    }
}
Esempio n. 3
0
/**
 * @brief Switches receiver on or off
 *
 * This function switches the receiver on (PHY_RX_ON) or off (PHY_TRX_OFF).
 *
 * @param trx_id Transceiver identifier
 * @param state New state of receiver
 *
 * @return
 *      - @ref TAL_BUSY if the TAL state machine cannot switch receiver on or
 *off,
 *      - @ref PHY_TRX_OFF if receiver has been switched off, or
 *      - @ref PHY_RX_ON otherwise.
 *
 * @ingroup apiTalApi
 */
uint8_t tal_rx_enable(trx_id_t trx_id, uint8_t state)
{
	uint8_t ret_val;

	if (tal_state[trx_id] == TAL_SLEEP) {
		return TAL_TRX_ASLEEP;
	}

	/*
	 * Trx can only be enabled if TAL is not busy;
	 * i.e. if TAL is IDLE.
	 */
	if (tal_state[trx_id] != TAL_IDLE) {
		return TAL_BUSY;
	}

	if (state == PHY_TRX_OFF) {
		/*
		 * If the rx needs to be switched off,
		 * we are not interested in a frame that is currently being
		 *received.
		 */
		uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id;
		trx_reg_write(reg_offset + RG_RF09_CMD, RF_TRXOFF);
#ifdef IQ_RADIO
		pal_dev_reg_write(RF215_RF, GET_REG_ADDR(RG_RF09_CMD),
				RF_TRXOFF);
#endif
#if (defined RF215V1) && ((defined SUPPORT_FSK) || (defined SUPPORT_OQPSK))
		stop_rpc(trx_id);
#endif
		trx_state[trx_id] = RF_TRXOFF;
		tal_buf_shortage[trx_id] = false;
		ret_val = PHY_TRX_OFF;
#ifdef ENABLE_FTN_PLL_CALIBRATION
		stop_ftn_timer(trx_id);
#endif  /* ENABLE_FTN_PLL_CALIBRATION */
		trx_default_state[trx_id] = RF_TRXOFF;
	} else {
		switch_to_txprep(trx_id);
		switch_to_rx(trx_id);
		ret_val = PHY_RX_ON;
#ifdef ENABLE_FTN_PLL_CALIBRATION
		start_ftn_timer(trx_id);
#endif  /* ENABLE_FTN_PLL_CALIBRATION */
		trx_default_state[trx_id] = RF_RX;
	}

	return ret_val;
}
Esempio n. 4
0
/**
 * @brief Completes Rx transaction
 *
 * @param trx_id Transceiver identifier
 */
void complete_rx_transaction(trx_id_t trx_id)
{
	/* Get energy of received frame */
	uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id;
	uint8_t ed = trx_reg_read(reg_offset + RG_RF09_EDV);
	uint16_t ed_pos = rx_frm_info[trx_id]->len_no_crc + 1 +
			tal_pib[trx_id].FCSLen;
	rx_frm_info[trx_id]->mpdu[ed_pos] = ed; /* PSDU, LQI, ED */

	/* Append received frame to incoming_frame_queue and get new rx buffer.
	 **/
	qmm_queue_append(&tal_incoming_frame_queue[trx_id],
			tal_rx_buffer[trx_id]);
	/* The previous buffer is eaten up and a new buffer is not assigned yet.
	 **/
	tal_rx_buffer[trx_id] = bmm_buffer_alloc(LARGE_BUFFER_SIZE);
	/* Switch to rx again to handle buffer shortage */
	switch_to_rx(trx_id);
}
Esempio n. 5
0
/**
 * @brief Stops CW transmission
 *
 * @param trx_id Identifier of the transceiver
 */
void tfa_continuous_tx_stop(trx_id_t trx_id)
{
	uint16_t reg_offset = BB_BASE_ADDR_OFFSET * trx_id;
	/* Stop continuous transmission */
	trx_bit_write(reg_offset + SR_BBC0_PC_CTX, 0);
#ifdef IQ_RADIO
	/* Allow command via SPI */
	pal_dev_bit_write(RF215_RF, SR_RF_IQIFC0_EEC, 0);
#endif
	switch_to_txprep(trx_id);

	/* Disable carrier transmission - even if it has not been used. */
	uint8_t dac_config[2] = {0x00, 0x00};
	uint16_t rft_reg_offset = RFT_TST_ADDR_OFFSET * trx_id;
#ifdef IQ_RADIO
	pal_dev_write(RF215_RF, rft_reg_offset + RG_RF09_TXDACI, dac_config, 2);
	/* Enable embedded TX control again */
	pal_dev_bit_write(RF215_RF, SR_RF_IQIFC0_EEC, 1);
#else
	trx_write(rft_reg_offset + RG_RF09_TXDACI, dac_config, 2);
	/* Disable baseband bypass */
	trx_bit_write( SR_RF_IQIFC1_CHPM, 0);
#endif

	/* Restore previous settings */
	if (tal_state[trx_id] == TAL_TFA_CW_RX) {
		tal_state[trx_id] = TAL_IDLE;
		switch_to_rx(trx_id);
	} else {
		tal_state[trx_id] = TAL_IDLE;
		/* Switch to TRXOFF */
#ifdef IQ_RADIO
		pal_dev_reg_write(RF215_RF, reg_offset + RG_RF09_CMD,
				RF_TRXOFF);
		pal_dev_reg_write(RF215_BB, reg_offset + RG_RF09_CMD,
				RF_TRXOFF);
#else
		trx_reg_write(reg_offset + RG_RF09_CMD, RF_TRXOFF);
#endif
		trx_state[trx_id] = RF_TRXOFF;
	}
}
Esempio n. 6
0
/**
 * @brief Perform a CCA
 *
 * This blocking function performs a CCA request.
 *
 * @return phy_enum_t PHY_IDLE or PHY_BUSY
 */
phy_enum_t tfa_cca_perform(trx_id_t trx_id)
{
	phy_enum_t ret;

	if (tal_state[trx_id] != TAL_IDLE) {
		ret = PHY_BUSY;
	} else {
		rf_cmd_state_t previous_state = trx_state[trx_id];

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

		if (trx_state[trx_id] != RF_RX) {
			switch_to_rx(trx_id);
			pal_timer_delay(tal_pib[trx_id].agc_settle_dur); /*
			                                                  * allow
			                                                  * filters
			                                                  * to
			                                                  * settle */
		}

		/* Disable BB */
		uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id;
		trx_bit_write(reg_offset + SR_BBC0_PC_BBEN, 0);

#ifndef BASIC_MODE
		/* Enable EDC interrupt */
		trx_bit_write(reg_offset + SR_RF09_IRQM_EDC, 1);
#endif
		/* Start single ED measurement; use reg_write - it's the only
		 *subregister */
		tal_state[trx_id] = TAL_TFA_CCA;
#ifdef IQ_RADIO
		/* Enable EDC interrupt */
		pal_dev_bit_write(RF215_RF, reg_offset + SR_RF09_IRQM_EDC, 1);
		pal_dev_reg_write(RF215_RF, reg_offset + RG_RF09_EDC,
				RF_EDSINGLE);
#else
		trx_reg_write(reg_offset + RG_RF09_EDC, RF_EDSINGLE);
#endif

		/* Wait until measurement is completed */
		while (TAL_RF_IS_IRQ_SET(trx_id, RF_IRQ_EDC) == false) {
		}
		TAL_RF_IRQ_CLR(trx_id, RF_IRQ_EDC);

#ifndef BASIC_MODE
		/* Disable EDC interrupt again */
		trx_bit_write(reg_offset + SR_RF09_IRQM_EDC, 0);
#endif
#ifdef IQ_RADIO
		pal_dev_bit_write(RF215_RF, reg_offset + SR_RF09_IRQM_EDC, 0);
#endif
		/* Since it is a blocking function, restore TAL state */
		tal_state[trx_id] = TAL_IDLE;

		switch_to_txprep(trx_id); /* Leave Rx mode */

		/* Switch BB on again */
		trx_bit_write(reg_offset + SR_BBC0_PC_BBEN, 1);

		/* Capture ED value for current frame / ED scan */
#ifdef IQ_RADIO
		tal_current_ed_val[trx_id] = pal_dev_reg_read(RF215_RF,
				reg_offset +
				RG_RF09_EDV);
#else
		tal_current_ed_val[trx_id] = trx_reg_read(
				reg_offset + RG_RF09_EDV);
#endif

		if (tal_current_ed_val[trx_id] < tal_pib[trx_id].CCAThreshold) {
			/* Idle */
			ret = PHY_IDLE;
		} else {
			/* Busy */
			ret = PHY_BUSY;
		}

		/* Restore previous trx state */
		if (previous_state == RF_RX) {
			switch_to_rx(trx_id);
		} else {
			/* Switch to TRXOFF */
			trx_reg_write(reg_offset + RG_RF09_CMD, RF_TRXOFF);
#ifdef IQ_RADIO
			pal_dev_reg_write(RF215_RF, reg_offset + RG_RF09_CMD,
					RF_TRXOFF);
#endif
			trx_state[trx_id] = RF_TRXOFF;
		}
	}

	return ret;
}
Esempio n. 7
0
/*
 * @brief The main thread run, receiving and processing messages in an infinite
 * loop
 */
static void *run(void *arg)
{
    (void) arg;

    msg_init_queue(msg_buffer, TRANSCEIVER_MSG_BUFFER_SIZE);

    while (1) {
        DEBUG("transceiver: Waiting for next message\n");
        msg_t m;
        msg_receive(&m);
        /* only makes sense for messages for upper layers */
        transceiver_command_t *cmd = (transceiver_command_t *) m.content.ptr;
        DEBUG("transceiver: Transceiver: Message received, type: %02X\n", m.type);

        switch (m.type) {
            case RCV_PKT_CC1020:
            case RCV_PKT_CC1100:
            case RCV_PKT_CC2420:
            case RCV_PKT_MC1322X:
            case RCV_PKT_NATIVE:
            case RCV_PKT_AT86RF231:
                receive_packet(m.type, m.content.value);
                break;

            case SND_PKT:
                response = send_packet(cmd->transceivers, cmd->data);
                m.content.value = response;
                msg_reply(&m, &m);
                break;

            case GET_CHANNEL:
                *((int32_t *) cmd->data) = get_channel(cmd->transceivers);
                msg_reply(&m, &m);
                break;

            case SET_CHANNEL:
                *((int32_t *) cmd->data) = set_channel(cmd->transceivers, cmd->data);
                msg_reply(&m, &m);
                break;

            case GET_ADDRESS:
                *((radio_address_t *) cmd->data) = get_address(cmd->transceivers);
                msg_reply(&m, &m);
                break;

            case SET_ADDRESS:
                *((radio_address_t *) cmd->data) = set_address(cmd->transceivers, cmd->data);
                msg_reply(&m, &m);
                break;

            case GET_LONG_ADDR:
                *((transceiver_eui64_t *) cmd->data) = get_long_addr(cmd->transceivers);
                msg_reply(&m, &m);
                break;

            case SET_LONG_ADDR:
                *((transceiver_eui64_t *) cmd->data) = set_long_addr(cmd->transceivers, cmd->data);
                msg_reply(&m, &m);
                break;

            case SET_MONITOR:
                set_monitor(cmd->transceivers, cmd->data);
                break;

            case POWERDOWN:
                powerdown(cmd->transceivers);
                break;

            case SWITCH_RX:
                switch_to_rx(cmd->transceivers);
                break;

            case GET_PAN:
                *((int32_t *) cmd->data) = get_pan(cmd->transceivers);
                msg_reply(&m, &m);
                break;

            case SET_PAN:
                *((int32_t *) cmd->data) = set_pan(cmd->transceivers, cmd->data);
                msg_reply(&m, &m);
                break;

#ifdef DBG_IGNORE
            case DBG_IGN:
                *((int16_t *) cmd->data) = ignore_add(cmd->transceivers, cmd->data);
                msg_reply(&m, &m);
                break;
#endif

            default:
                DEBUG("transceiver: Unknown message received\n");
                break;
        }
    }

    return NULL;
}
Esempio n. 8
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]);
	}
}