Ejemplo n.º 1
0
static void handle_received_frame_irq(void)
{
	/* Actual frame length of received frame. */
	uint8_t phy_frame_len;

	uint8_t *rx_frame_ptr = at86rfx_rx_buffer;

	/* Perform FCS check for frame validation */
	if (CRC16_NOT_VALID == pal_trx_bit_read(SR_RX_CRC_VALID)) {
		return;
	}

	/* Get frame length from transceiver. */
	pal_trx_frame_read(&phy_frame_len, LENGTH_FIELD_LEN);

	/* Check for valid frame length. */
	if (phy_frame_len > PHY_MAX_LENGTH) {
		return;
	}

	/* Frame read from transceiver buffer. */
	pal_trx_frame_read(rx_frame_ptr, LENGTH_FIELD_LEN + phy_frame_len);

	/* Set flag indicating received frame to be handled. */
	at86rfx_frame_rx = true;

	set_trx_state(CMD_RX_ON);
}
Ejemplo n.º 2
0
/*
 * \brief Generates a 16-bit random number used as initial seed for srand()
 */
void tal_generate_rand_seed(void)
{
    /*
     * For AT86RF230B  bysed systems the random seed is generated by reading
     *the random contents of the frame buffer after initialization
     *	since there is no tranceiver based random number generator
     * available.
     */
    static uint8_t data[127];
    static uint16_t seed;

    pal_trx_frame_read(data, 127);

    for (uint8_t i = 0; i < 127; i++) {
        seed = seed + data[i];
    }
    srand(seed);
}
Ejemplo n.º 3
0
/*
 * \brief Handle received frame interrupt
 *
 * This function handles transceiver interrupts for received frames and
 * uploads the frames from the trx.
 */
void handle_received_frame_irq(void)
{
    uint8_t ed_value;
    /* Actual frame length of received frame. */
    uint8_t phy_frame_len;
    /* Extended frame length appended by LQI and ED. */
    uint8_t ext_frame_length;
    frame_info_t *receive_frame;
    uint8_t *frame_ptr;

    if (tal_rx_buffer == NULL)
    {
        Assert("no tal_rx_buffer available" == 0);
        /*
         * Although the buffer protection mode is enabled and the receiver has
         * been switched to PLL_ON, the next incoming frame was faster.
         * It cannot be handled and is discarded.
         */
        pal_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
        pal_trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE);  /* Enable buffer protection mode */
        return;
    }

    receive_frame = (frame_info_t *)BMM_BUFFER_POINTER(tal_rx_buffer);

#ifdef PROMISCUOUS_MODE
    if (tal_pib.PromiscuousMode)
    {
        /* Check for valid FCS */
        if (pal_trx_bit_read(SR_RX_CRC_VALID) == CRC16_NOT_VALID)
        {
            return;
        }
    }
#endif

    /* Get ED value; needed to normalize LQI. */
    ed_value = pal_trx_reg_read(RG_PHY_ED_LEVEL);

    /* Get frame length from transceiver. */
    phy_frame_len = ext_frame_length = pal_trx_reg_read(RG_TST_RX_LENGTH);

    /* Check for valid frame length. */
    if (phy_frame_len > 127)
    {
        return;
    }

    /*
     * The PHY header is also included in the frame (length field), hence the frame length
     * is incremented.
     * In addition to that, the LQI and ED value are uploaded, too.
     */
    ext_frame_length += LQI_LEN + ED_VAL_LEN;

    /* Update payload pointer to store received frame. */
    frame_ptr = (uint8_t *)receive_frame + LARGE_BUFFER_SIZE - ext_frame_length;

    /*
     * Note: The following code is different from other non-single chip
     * transceivers, where reading the frame via SPI contains the length field
     * in the first octet.
     */
    pal_trx_frame_read(frame_ptr, phy_frame_len + LQI_LEN);
    frame_ptr--;
    *frame_ptr = phy_frame_len;
    receive_frame->mpdu = frame_ptr;
    /* Add ED value at the end of the frame buffer. */
    receive_frame->mpdu[phy_frame_len + LQI_LEN + ED_VAL_LEN] = ed_value;


#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)
    /*
     * Store the timestamp.
     * The timestamping is only required for beaconing networks
     * or if timestamping is explicitly enabled.
     */
    receive_frame->time_stamp = tal_rx_timestamp;
#endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

    /* Append received frame to incoming_frame_queue and get new rx buffer. */
    qmm_queue_append(&tal_incoming_frame_queue, tal_rx_buffer);

    /* The previous buffer is eaten up and a new buffer is not assigned yet. */
    tal_rx_buffer = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

    /* Check if receive buffer is available */
    if (NULL == tal_rx_buffer)
    {
        /*
         * Turn off the receiver until a buffer is available again.
         * tal_task() will take care of eventually reactivating it.
         * Due to ongoing ACK transmission do not force to switch it off.
         */

        /* Do not change the state since buffer protection mode is not re-enabled yet.
         * Buffer protection will be re-enabled after buffer becomes available
         */
        //set_trx_state(CMD_PLL_ON);
        tal_rx_on_required = true;
    }
    else
    {
        /*
         * Trx returns to RX_AACK_ON automatically, if this was its previous state.
         * Keep the following as a reminder, if receiver is used with RX_ON instead.
         */
        //pal_trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON);
        /*
         * Release the protected buffer and set it again for further protection since
         * the buffer is available
         */
        pal_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
        pal_trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE);  /* Enable buffer protection mode */
    }

    /*
     * Clear pending TX_END IRQ: The TX_END IRQ is envoked for the transmission
     * end of an automatically sent ACK frame. This implementation does not use
     * this feature.
     */
    pal_trx_irq_flag_clr_tx_end();
}
Ejemplo n.º 4
0
/**
 * \brief Interrupt handler for ACK reception
 *
 * \param parameter Unused callback parameter
 */
static void ack_reception_handler_cb(void *parameter)
{
	trx_irq_reason_t trx_irq_cause;

	if (tal_csma_state == TX_DONE_NO_ACK) {
		return; /* ack expiration timer has already been fired */
	}

	trx_irq_cause = (trx_irq_reason_t)pal_trx_reg_read(RG_IRQ_STATUS);

	if (trx_irq_cause & TRX_IRQ_TRX_END) {
		retval_t timer_status;

		switch (tal_csma_state) {
		case FRAME_SENDING_WITH_ACK:
			set_trx_state(CMD_RX_ON);

			timer_status
				= pal_timer_start(TAL_ACK_WAIT_TIMER,
					TAL_CONVERT_SYMBOLS_TO_US(
					TAL_ACK_WAIT_DURATION_DEFAULT),
					TIMEOUT_RELATIVE,
					(FUNC_PTR)ack_timer_expiry_handler_cb,
					NULL);

			if (timer_status == MAC_SUCCESS) {
				tal_csma_state = WAITING_FOR_ACK;
			} else if (timer_status == PAL_TMR_ALREADY_RUNNING) {
				tal_csma_state = WAITING_FOR_ACK;
			} else {
				tal_csma_state = TX_DONE_NO_ACK;
				Assert("timer start failed" == 0);
			}

			/* debug pin to switch on: define ENABLE_DEBUG_PINS,
			 *pal_config.h */
			PIN_TX_END();
			PIN_ACK_WAITING_START();
			break;

		case WAITING_FOR_ACK:
		{
			uint8_t ack_frame[ACK_FRAME_LEN + LENGTH_FIELD_LEN];

			/*
			 * Read the frame buffer, identify if this is an ACK
			 *frame,
			 * and get the sequence number.
			 * Üpload the frame from the transceiver.
			 */
			pal_trx_frame_read(ack_frame,
					(ACK_FRAME_LEN +
					LENGTH_FIELD_LEN));

			/* Check if the uploaded frame is an ACK frame */
			if ((ack_frame[1] & ACK_FRAME) != ACK_FRAME) {
				/* The received frame is not an ACK frame */
				return;
			}

			/* check CRC */
			if (pal_trx_bit_read(SR_RX_CRC_VALID) != CRC16_VALID) {
				return;
			}

			/* check the sequence number */
			if (ack_frame[3] == tal_frame_to_tx[SEQ_NUMBER_POS]) {
				/*
				 * If we are here, the ACK is valid and matches
				 * the transmitted sequence number.
				 */
				pal_timer_stop(TAL_ACK_WAIT_TIMER);
#if (_DEBUG_ > 0)
				if (pal_is_timer_running(TAL_ACK_WAIT_TIMER)) {
					Assert("Ack timer running" == 0);
				}

#endif
				/* restore the interrupt handler */
				pal_trx_irq_init((FUNC_PTR)trx_irq_handler_cb);
				pal_trx_irq_en();

				if (NULL != tal_rx_buffer) {
					pal_trx_reg_write(RG_TRX_STATE,
							CMD_RX_AACK_ON);
				} else {
					tal_rx_on_required = true;
				}

				/* debug pin to switch on: define
				 *ENABLE_DEBUG_PINS, pal_config.h */
				PIN_ACK_OK_START();

				if (ack_frame[1] & FCF_FRAME_PENDING) {
					tal_csma_state = TX_DONE_FRAME_PENDING;
				} else {
					tal_csma_state = TX_DONE_SUCCESS;
				}

				/* debug pin to switch on: define
				 *ENABLE_DEBUG_PINS, pal_config.h */
				PIN_ACK_OK_END();
				PIN_ACK_WAITING_END();
			}
		}
		break;

		case FRAME_SENDING_NO_ACK:
			/* Tx is done */
			/* debug pin to switch on: define ENABLE_DEBUG_PINS,
			 *pal_config.h */
			PIN_TX_END();
			tal_csma_state = TX_DONE_SUCCESS;
			break;

		default:
			Assert("unknown tal_csma_state" == 0);
			break;
		}
	} else { /* other interrupt than TRX_END */
		/* no interest in any other interrupt */
		return;
	}

	parameter = parameter; /* Keep compiler happy. */
}
Ejemplo n.º 5
0
/**
 * @brief Handle received frame interrupt
 *
 * This function handles transceiver interrupts for received frames and
 * uploads the frames from the trx.
 */
void handle_received_frame_irq(void)
{
    uint8_t ed_value;
    /* Actual frame length of received frame. */
    uint8_t phy_frame_len;
    /* Extended frame length appended by LQI and ED. */
    uint8_t ext_frame_length;
    frame_info_t *receive_frame;
    uint8_t *frame_ptr;
#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)
    uint32_t timestamp_us;
#endif  /*if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

    if (tal_rx_buffer == NULL)
    {
        ASSERT("no tal_rx_buffer available" == 0);
        return;
    }

#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)
    /*
     * The timestamping is only required for beaconing networks
     * or if timestamping is explicitly enabled.
     */
    pal_trx_read_timestamp(&timestamp_us);
#endif  /*if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

    receive_frame = (frame_info_t *)BMM_BUFFER_POINTER(tal_rx_buffer);

#ifdef PROMISCUOUS_MODE
    if (tal_pib.PromiscuousMode)
    {
        /* Check for valid FCS */
        if (pal_trx_bit_read(SR_RX_CRC_VALID) == CRC16_NOT_VALID)
        {
            return;
        }
    }
#endif

    /* Get ED value; needed to normalize LQI. */
    ed_value = pal_trx_reg_read(RG_PHY_ED_LEVEL);

    /* Get frame length from transceiver. */
    pal_trx_frame_read(&phy_frame_len, LENGTH_FIELD_LEN);

    /* Check for valid frame length. */
    if (phy_frame_len > 127)
    {
        return;
    }

    /*
     * The PHY header is also included in the frame (length field), hence the frame length
     * is incremented.
     * In addition to that, the LQI and ED value are uploaded, too.
     */
    ext_frame_length = phy_frame_len + LENGTH_FIELD_LEN + LQI_LEN + ED_VAL_LEN;

    /* Update payload pointer to store received frame. */
    frame_ptr = (uint8_t *)receive_frame + LARGE_BUFFER_SIZE - ext_frame_length;

    /*
     * Note: The following code is different from single chip
     * transceivers, since reading the frame via SPI contains the length field
     * in the first octet.
     */
    pal_trx_frame_read(frame_ptr, LENGTH_FIELD_LEN + phy_frame_len + LQI_LEN);
    receive_frame->mpdu = frame_ptr;
    /* Add ED value at the end of the frame buffer. */
    receive_frame->mpdu[phy_frame_len + LQI_LEN + ED_VAL_LEN] = ed_value;

#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)
    /*
     * Store the timestamp.
     * The timestamping is only required for beaconing networks
     * or if timestamping is explicitly enabled.
     */
    receive_frame->time_stamp = timestamp_us;
#endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

    /* Append received frame to incoming_frame_queue and get new rx buffer. */
    qmm_queue_append(&tal_incoming_frame_queue, tal_rx_buffer);

    /* The previous buffer is eaten up and a new buffer is not assigned yet. */
    tal_rx_buffer = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

    /* Check if receive buffer is available */
    if (NULL == tal_rx_buffer)
    {
        /*
         * Turn off the receiver until a buffer is available again.
         * tal_task() will take care of eventually reactivating it.
         * Due to ongoing ACK transmission do not force to switch it off.
         */
        set_trx_state(CMD_PLL_ON);
        tal_rx_on_required = true;
    }
    else
    {
        /*
         * Trx returns to RX_AACK_ON automatically, if this was its previous state.
         * Keep the following as a reminder, if receiver is used with RX_ON instead.
         */
        //pal_trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON);
    }
}
Ejemplo n.º 6
0
/*
 * \brief Handle received frame interrupt
 *
 * This function handles transceiver interrupts for received frames and
 * uploads the frames from the trx.
 */
void handle_received_frame_irq(void)
{
	/* Actual frame length of received frame. */
	uint8_t phy_frame_len;
	/* Extended frame length appended by LQI and ED. */
	uint8_t ext_frame_length;
	frame_info_t *receive_frame;
	uint8_t *frame_ptr;

	if (tal_rx_buffer == NULL) {
		Assert("no tal_rx_buffer available" == 0);

		/*
		 * Although the buffer protection mode is enabled and the
		 *receiver has
		 * been switched to PLL_ON, the next incoming frame was faster.
		 * It cannot be handled and is discarded. Reading anything from
		 *the
		 * frame resets the buffer protection mode.
		 */
		uint8_t dummy;
		pal_trx_frame_read(&dummy, 1);
		return;
	}

	receive_frame = (frame_info_t *)BMM_BUFFER_POINTER(tal_rx_buffer);

#ifdef PROMISCUOUS_MODE
	if (tal_pib.PromiscuousMode) {
		/* Check for valid FCS */
		if (pal_trx_bit_read(SR_RX_CRC_VALID) == CRC16_NOT_VALID) {
			return;
		}
	}

#endif

#if (defined ENABLE_TRX_SRAM) || defined(ENABLE_TRX_SRAM_READ)
	/* Use SRAM read to keep rx safe mode armed. */
	pal_trx_sram_read(0x00, &phy_frame_len, LENGTH_FIELD_LEN); /* 0x00: SRAM
	                                                            * offset
	                                                            * address */
#else
	/* Get frame length from transceiver. */
	pal_trx_frame_read(&phy_frame_len, LENGTH_FIELD_LEN);
#endif

	/* Check for valid frame length. */
	if (phy_frame_len > 127) {
		return;
	}

	/*
	 * The PHY header is also included in the frame (length field), hence
	 *the frame length
	 * is incremented.
	 * In addition to that, the LQI and ED value are uploaded, too.
	 */
	ext_frame_length = phy_frame_len + LENGTH_FIELD_LEN + LQI_LEN +
			ED_VAL_LEN;

	/* Update payload pointer to store received frame. */
	frame_ptr = (uint8_t *)receive_frame + LARGE_BUFFER_SIZE -
			ext_frame_length;

	/*
	 * Note: The following code is different from single chip
	 * transceivers, since reading the frame via SPI contains the length
	 *field
	 * in the first octet. RF233's frame buffer includes ED value too.
	 */
	pal_trx_frame_read(frame_ptr,
			LENGTH_FIELD_LEN + phy_frame_len + LQI_LEN +
			ED_VAL_LEN);
	receive_frame->mpdu = frame_ptr;

#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)

	/*
	 * Store the timestamp.
	 * The timestamping is only required for beaconing networks
	 * or if timestamping is explicitly enabled.
	 */
	receive_frame->time_stamp = tal_timestamp;
#endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

	/* Append received frame to incoming_frame_queue and get new rx buffer.
	 **/
	qmm_queue_append(&tal_incoming_frame_queue, tal_rx_buffer);

	/* The previous buffer is eaten up and a new buffer is not assigned yet.
	 **/
	tal_rx_buffer = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

	/* Check if receive buffer is available */
	if (NULL == tal_rx_buffer) {
		/*
		 * Turn off the receiver until a buffer is available again.
		 * tal_task() will take care of eventually reactivating it.
		 * Due to ongoing ACK transmission do not force to switch it
		 *off.
		 */
		set_trx_state(CMD_PLL_ON);
		tal_rx_on_required = true;
	} else {
		/*
		 * Trx returns to RX_AACK_ON automatically, if this was its
		 *previous state.
		 * Keep the following as a reminder, if receiver is used with
		 *RX_ON instead.
		 */
		/* pal_trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON); */
	}
}