Beispiel #1
0
void tal_tx_beacon(frame_info_t *tx_frame)
{
	tal_trx_status_t trx_status;

	/* Set pointer to actual mpdu to be downloaded to the transceiver. */
	uint8_t *tal_beacon_to_tx = tx_frame->mpdu;

	/* Avoid that the beacon is transmitted while other transmision is
	 * on-going. */
	if (tal_state == TAL_TX_AUTO) {
		Assert(
				"trying to transmit beacon while ongoing transmission" ==
				0);
		return;
	}

	/* Send the pre-created beacon frame to the transceiver. */
	do {
		trx_status = set_trx_state(CMD_PLL_ON);
#if (_DEBUG_ > 1)
		if (trx_status != PLL_ON) {
			Assert("PLL_ON failed for beacon transmission" == 0);
		}
#endif
	} while (trx_status != PLL_ON);

	/* \TODO wait for talbeaconTxTime */

	pal_trx_irq_dis();

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * + 1 extra octet (see datasheet)
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_beacon_to_tx, tal_beacon_to_tx[0]);

	tal_beacon_transmission = true;

#ifndef NON_BLOCKING_SPI
	pal_trx_irq_en();
#endif
#ifdef TX_OCTET_COUNTER
	tal_tx_octet_cnt += PHY_OVERHEAD + LENGTH_FIELD_LEN +
			tal_beacon_to_tx[0];
#endif
}
Beispiel #2
0
void tal_tx_beacon(frame_info_t *tx_frame)
{
	tal_trx_status_t trx_status;

	/* Set pointer to actual mpdu to be downloaded to the transceiver. */
	uint8_t *tal_beacon_to_tx = tx_frame->mpdu;

	/* Avoid that the beacon is transmitted while other transmision is
	 *on-going. */
	if (tal_state == TAL_TX_AUTO) {
		Assert(
				"trying to transmit beacon while ongoing transmission" ==
				0);
		return;
	}

	/* Send the pre-created beacon frame to the transceiver. */
	do {
		trx_status = set_trx_state(CMD_PLL_ON);
#if (_DEBUG_ > 1)
		if (trx_status != PLL_ON) {
			Assert("PLL_ON failed for beacon transmission" == 0);
		}

#endif
	} while (trx_status != PLL_ON);

	/* \TODO wait for talbeaconTxTime */

	ENTER_CRITICAL_REGION(); /* prevent from buffer underrun */

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_beacon_to_tx, tal_beacon_to_tx[0] - 1);

	tal_beacon_transmission = true;

	LEAVE_CRITICAL_REGION();
}
Beispiel #3
0
/**
 * \brief Transmits the frame over-the-air
 */
static void tx_frame(void)
{
    tal_trx_status_t trx_status;

    /*
     * Trigger transmission
     * In case of an ongoing reception,
     * the incoming frame is handled first within ISR.
     */
    do
    {
        trx_status = set_trx_state(CMD_TX_ARET_ON);
    }
    while (trx_status != TX_ARET_ON);

    pal_trx_irq_dis();

    /* Toggle the SLP_TR pin triggering transmission. */
    PAL_SLP_TR_HIGH();
    PAL_WAIT_65_NS();
    PAL_SLP_TR_LOW();

    /*
     * Send the frame to the transceiver.
     * Note: The PhyHeader is the first byte of the frame to
     * be sent to the transceiver and this contains the frame
     * length.
     * The actual length of the frame to be downloaded
     * (parameter two of pal_trx_frame_write)
     * is
     * 1 octet frame length octet
     * + n octets frame (i.e. value of frame_tx[0])
     * + 1 extra octet (see datasheet)
     * - 2 octets FCS
     */
    pal_trx_frame_write(tal_frame_to_tx, tal_frame_to_tx[0]);

    tal_state = TAL_TX_AUTO;

#ifndef NON_BLOCKING_SPI
    pal_trx_irq_en();
#endif
#ifdef TX_OCTET_COUNTER
    tal_tx_octet_cnt += PHY_OVERHEAD + LENGTH_FIELD_LEN + tal_frame_to_tx[0];
#endif
}
Beispiel #4
0
/*
 * \brief Sends frame
 *
 * \param use_csma Flag indicating if CSMA is requested
 * \param tx_retries Flag indicating if transmission retries are requested
 *                   by the MAC layer
 */
void send_frame(csma_mode_t csma_mode, bool tx_retries)
{
	tal_trx_status_t trx_status;

	/* Configure tx according to tx_retries */
	if (tx_retries) {
		trx_bit_write(SR_MAX_FRAME_RETRIES,
				tal_pib.MaxFrameRetries);
	} else {
		trx_bit_write(SR_MAX_FRAME_RETRIES, 0);
	}

	/* Configure tx according to csma usage */
	if ((csma_mode == NO_CSMA_NO_IFS) || (csma_mode == NO_CSMA_WITH_IFS)) {
		if (tx_retries) {
			trx_bit_write(SR_MAX_CSMA_RETRIES,
					tal_pib.MaxCSMABackoffs);
			trx_reg_write(RG_CSMA_BE, 0x00);
		} else {
			trx_bit_write(SR_MAX_CSMA_RETRIES, 7);
		}
	} else {
		trx_reg_write(RG_CSMA_BE,
				((tal_pib.MaxBE << 4) | tal_pib.MinBE));
		trx_bit_write(SR_MAX_CSMA_RETRIES, tal_pib.MaxCSMABackoffs);
	}

	do {
		trx_status = set_trx_state(CMD_TX_ARET_ON);
	} while (trx_status != TX_ARET_ON);

	/* Handle interframe spacing */
	if (csma_mode == NO_CSMA_WITH_IFS) {
		if (last_frame_length > aMaxSIFSFrameSize) {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinLIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		} else {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinSIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		}
	} else {
		/*
		 * If no delay is applied after switching to TX_ARET_ON,
		 * a short delay is required that allows that a pending TX_END
		 * IRQ for
		 * ACK transmission gets served.
		 */
		pal_timer_delay(TRX_IRQ_DELAY_US);
	}

	ENTER_CRITICAL_REGION(); /* prevent from buffer underrun */

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_frame_to_tx, tal_frame_to_tx[0] - 1);

	tal_state = TAL_TX_AUTO;

	LEAVE_CRITICAL_REGION();
}
Beispiel #5
0
/*
 * \brief Sends frame using trx features to handle CSMA and re-transmissions
 *
 * \param use_csma Flag indicating if CSMA is requested
 * \param tx_retries Flag indicating if transmission retries are requested
 *                   by the MAC layer
 */
void send_frame(csma_mode_t csma_mode, bool tx_retries)
{
	tal_trx_status_t trx_status;

	/* Configure tx according to tx_retries */
	if (tx_retries) {
		trx_bit_write(SR_MAX_FRAME_RETRIES,
				tal_pib.MaxFrameRetries);
	} else {
		trx_bit_write(SR_MAX_FRAME_RETRIES, 0);
	}

	/* Configure tx according to csma usage */
	if ((csma_mode == NO_CSMA_NO_IFS) || (csma_mode == NO_CSMA_WITH_IFS)) {
		trx_bit_write(SR_MAX_CSMA_RETRIES, 7); /* immediate
		                                        * transmission */
	} else {
		trx_bit_write(SR_MAX_CSMA_RETRIES, tal_pib.MaxCSMABackoffs);
	}

	do {
		trx_status = set_trx_state(CMD_TX_ARET_ON);
	} while (trx_status != TX_ARET_ON);

	pal_trx_irq_dis();

	/* Handle interframe spacing */
	if (csma_mode == NO_CSMA_WITH_IFS) {
		if (last_frame_length > aMaxSIFSFrameSize) {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinLIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		} else {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinSIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		}
	}

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * - 2 octets FCS
	 */
	trx_frame_write(tal_frame_to_tx, tal_frame_to_tx[0] - 1);

	tal_state = TAL_TX_AUTO;

#ifndef NON_BLOCKING_SPI
	pal_trx_irq_en();
#endif
#ifdef TX_OCTET_COUNTER
	tal_tx_octet_cnt += PHY_OVERHEAD + LENGTH_FIELD_LEN + frame_tx[0];
#endif
}
Beispiel #6
0
void tal_tx_beacon(frame_info_t *tx_frame)
{
	tal_trx_status_t trx_status;

	/* Set pointer to actual mpdu to be downloaded to the transceiver. */
	uint8_t *tal_beacon_to_tx = tx_frame->mpdu;

	/*
	 * Avoid that the beacon is transmitted while transmitting
	 * a frame using slotted CSMA.
	 */
	if ((tal_csma_state == FRAME_SENDING_WITH_ACK) ||
			(tal_csma_state == FRAME_SENDING_NO_ACK) ||
			(tal_csma_state == WAITING_FOR_ACK)) {
		Assert(
				"trying to transmit beacon while ongoing transmission" ==
				0);
		return;
	}

	/* Send the pre-created beacon frame to the transceiver. */
	/* debug pin to switch on: define ENABLE_DEBUG_PINS, pal_config.h */
	PIN_BEACON_START();

	/* \TODO wait for talbeaconTxTime */
	do {
		trx_status = set_trx_state(CMD_FORCE_PLL_ON);
#if (_DEBUG_ > 1)
		if (trx_status != PLL_ON) {
			Assert("PLL_ON failed for beacon transmission" == 0);
		}

#endif
	} while (trx_status != PLL_ON);

	pal_trx_irq_dis();

	/* Toggle the SLP_TR pin triggering transmission. */
	PAL_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	PAL_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of pal_trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * - 2 octets FCS
	 */
	pal_trx_frame_write(tal_beacon_to_tx, tal_beacon_to_tx[0] - 1);

#ifndef NON_BLOCKING_SPI
	pal_trx_irq_en();
#endif

	tal_state = TAL_TX_BEACON;
}
Beispiel #7
0
/*
 * \brief Sends frame
 *
 * \param use_csma Flag indicating if CSMA is requested
 * \param tx_retries Flag indicating if transmission retries are requested
 *                   by the MAC layer
 */
void send_frame(csma_mode_t csma_mode, bool tx_retries)
{
	tal_trx_status_t trx_status;

#ifdef BEACON_SUPPORT
	/* Handle frame transmission in slotted CSMA via basic mode */
	if (tal_csma_state != CSMA_IDLE) {
		do {
			trx_status = set_trx_state(CMD_PLL_ON);
		} while (trx_status != PLL_ON);

		tal_state = TAL_TX_BASIC;
	} else
#endif
	{
		/* Configure tx according to tx_retries */
		if (tx_retries) {
			pal_trx_bit_write(SR_MAX_FRAME_RETRIES,
					tal_pib.MaxFrameRetries);
		} else {
			pal_trx_bit_write(SR_MAX_FRAME_RETRIES, 0);
		}

		/* Configure tx according to csma usage */
		if ((csma_mode == NO_CSMA_NO_IFS) ||
				(csma_mode == NO_CSMA_WITH_IFS)) {
			/*
			 * RF230B does not support "no" CSMA mode,
			 * therefore use shortest CSMA mode: CCA w/o backoff
			 */
			pal_trx_bit_write(SR_MIN_BE, 0x00);
			pal_trx_bit_write(SR_MAX_CSMA_RETRIES, 0);
		} else {
			pal_trx_bit_write(SR_MIN_BE, tal_pib.MinBE);
			pal_trx_bit_write(SR_MAX_CSMA_RETRIES,
					tal_pib.MaxCSMABackoffs);

			/*
			 * Handle interframe spacing
			 * Reduce IFS duration, since RF230B does CCA
			 */
			if (csma_mode == NO_CSMA_WITH_IFS) {
				if (last_frame_length > aMaxSIFSFrameSize) {
					pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
							macMinLIFSPeriod_def -
							CCA_DURATION_SYM)
							- IRQ_PROCESSING_DLY_US -
							PRE_TX_DURATION_US);
				} else {
					/*
					 * No delay required, since processing
					 *delay and CCA_DURATION_SYM
					 * delay the handling enough.
					 */
				}
			}
		}

		do {
			trx_status = set_trx_state(CMD_TX_ARET_ON);
		} while (trx_status != TX_ARET_ON);

		tal_state = TAL_TX_AUTO;
	}

	pal_trx_irq_dis();

	/* Toggle the SLP_TR pin triggering transmission. */
	PAL_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	PAL_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 * The actual length of the frame to be downloaded
	 * (parameter two of pal_trx_frame_write)
	 * is
	 * 1 octet frame length octet
	 * + n octets frame (i.e. value of frame_tx[0])
	 * - 2 octets FCS
	 */
	pal_trx_frame_write(tal_frame_to_tx, tal_frame_to_tx[0] - 1);

#ifndef NON_BLOCKING_SPI
	pal_trx_irq_en();
#endif
}
Beispiel #8
0
/*
 * \brief Handles interrupts issued due to end of transmission
 *
 * \param underrun_occured  true if under-run has occurred
 */
void handle_tx_end_irq(bool underrun_occured)
{
#if ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT))
	if (tal_beacon_transmission) {
		tal_beacon_transmission = false;

		if (tal_csma_state == BACKOFF_WAITING_FOR_BEACON) {
			/* Slotted CSMA has been waiting for a beacon, now it
			 * can continue. */
			tal_csma_state = CSMA_HANDLE_BEACON;
		}
	} else
#endif /* ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT)) */
	{
#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)

		/*
		 * Store tx timestamp to frame_info_t structure.
		 * The timestamping is only required for beaconing networks
		 * or if timestamping is explicitly enabled.
		 */
#if (DISABLE_TSTAMP_IRQ == 0)

		/*
		 * The Tx timestamp is stored during the timestamp interrupt
		 * at DIG2.
		 */
		mac_frame_ptr->time_stamp = tal_timestamp;
#else
		{
			uint32_t time_stamp_temp = 0;
			pal_trx_read_timestamp(&time_stamp_temp);
			mac_frame_ptr->time_stamp = time_stamp_temp;
		}
#endif
#endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

		/* Read trac status before enabling RX_AACK_ON. */
		if (underrun_occured) {
			trx_trac_status = TRAC_INVALID;
		} else {
			trx_trac_status = /*(trx_trac_status_t)*/ trx_bit_read(
					SR_TRAC_STATUS);
		}

#ifdef BEACON_SUPPORT
		if (tal_csma_state == FRAME_SENDING) { /* Transmission was
			                                * issued by slotted CSMA
			                                **/
			PIN_TX_END();
			tal_state = TAL_SLOTTED_CSMA;

			/* Map status message of transceiver to TAL constants.
			**/
			switch (trx_trac_status) {
			case TRAC_SUCCESS_DATA_PENDING:
				PIN_ACK_OK_START();
				tal_csma_state = TX_DONE_FRAME_PENDING;
				break;

			case TRAC_SUCCESS:
				PIN_ACK_OK_START();
				tal_csma_state = TX_DONE_SUCCESS;
				break;

			case TRAC_CHANNEL_ACCESS_FAILURE:
				PIN_NO_ACK_START();
				tal_csma_state = CSMA_ACCESS_FAILURE;
				break;

			case TRAC_NO_ACK:
				PIN_NO_ACK_START();
				tal_csma_state = TX_DONE_NO_ACK;
				break;

			case TRAC_INVALID: /* Handle this in the same way as
				            * default. */
			default:
				Assert("not handled trac status" == 0);
				tal_csma_state = CSMA_ACCESS_FAILURE;
				break;
			}
			PIN_ACK_OK_END();
			PIN_ACK_WAITING_END();
		} else
#endif  /* BEACON_SUPPORT */
		/* Trx has handled the entire transmission incl. CSMA */
		{
			if (tal_sw_retry_no_csma_ca && tal_sw_retry_count &&
					TRAC_NO_ACK == trx_trac_status) {
				tal_trx_status_t trx_status;
				do {
					trx_status = set_trx_state(
							CMD_TX_ARET_ON);
				} while (trx_status != TX_ARET_ON);
				/* Toggle the SLP_TR pin triggering
				 *transmission. */
				TRX_SLP_TR_HIGH();
				PAL_WAIT_65_NS();
				TRX_SLP_TR_LOW();
				if (--tal_sw_retry_count == 0) {
					tal_sw_retry_no_csma_ca = false;
				}
			} else {
				tal_state = TAL_TX_DONE; /* Further handling is
				                          * done by
				                          * tx_done_handling()
				                          **/
			}
		}
	}

	/*
	 * After transmission has finished, switch receiver on again.
	 * Check if receive buffer is available.
	 */
	if (NULL == tal_rx_buffer) {
		set_trx_state(CMD_PLL_ON);
		tal_rx_on_required = true;
	} else {
		set_trx_state(CMD_RX_AACK_ON);
	}
}