示例#1
0
// Called at the beginning of each listening window for transmitting to
// the tag.
static void ranging_listening_window_task () {
	// Check if we are done transmitting to the tag.
	// Ideally we never get here, as an ack from the tag will cause us to stop
	// cycling through listening windows and put us back into a ready state.
	if (_ranging_listening_window_num == NUM_RANGING_CHANNELS) {
		// Go back to IDLE
		_state = ASTATE_IDLE;
		// Stop the timer for the window
		timer_stop(_anchor_timer);

		// Restart being an anchor
		oneway_anchor_start();

	} else {

		// Setup the channel and antenna settings
		oneway_set_ranging_listening_window_settings(ANCHOR,
		                                             _ranging_listening_window_num,
		                                             pp_anc_final_pkt.final_antenna);

		// Prepare the outgoing packet to send back to the
		// tag with our TOAs.
		pp_anc_final_pkt.ieee154_header_unicast.seqNum++;
		const uint16_t frame_len = sizeof(struct pp_anc_final);
		// const uint16_t frame_len = sizeof(struct pp_anc_final) - (sizeof(uint64_t)*NUM_RANGING_BROADCASTS);
		dwt_writetxfctrl(frame_len, 0);

		// Pick a slot to respond in. Generate a random number and mod it
		// by the number of slots
		uint8_t slot_num = ranval(&_prng_state) % (_ranging_operation_config.anchor_reply_window_in_us /
		                                          _ranging_operation_config.anchor_reply_slot_time_in_us);

		// Come up with the time to send this packet back to the
		// tag based on the slot we picked.
		uint32_t delay_time = dwt_readsystimestamphi32() +
			DW_DELAY_FROM_US(ANC_FINAL_INITIAL_DELAY_HACK_VALUE +
				(slot_num*_ranging_operation_config.anchor_reply_slot_time_in_us));

		delay_time &= 0xFFFFFFFE;

		// Record the outgoing time in the packet. Do not take calibration into
		// account here, as that is done on all of the RX timestamps.
		pp_anc_final_pkt.dw_time_sent = (((uint64_t) delay_time) << 8);

		// Set the packet to be transmitted later.
		dwt_setdelayedtrxtime(delay_time);

		// Send the response packet
		// TODO: handle if starttx errors. I'm not sure what to do about it,
		//       other than just wait for the next slot.
		dwt_starttx(DWT_START_TX_DELAYED);
		dwt_settxantennadelay(DW1000_ANTENNA_DELAY_TX);
		dwt_writetxdata(frame_len, (uint8_t*) &pp_anc_final_pkt, 0);

		_ranging_listening_window_num++;
	}
}
示例#2
0
// Called at the beginning of each listening window for transmitting to
// the tag.
static void ranging_listening_window_task () {
	// Check if we are done transmitting to the tag.
	// Ideally we never get here, as an ack from the tag will cause us to stop
	// cycling through listening windows and put us back into a ready state.
	if (_ranging_listening_window_num == NUM_RANGING_CHANNELS) {
		// Go back to IDLE
		_state = ASTATE_IDLE;
		// Stop the timer for the window
		timer_stop(_ranging_broadcast_timer);

	} else {

		// Setup the channel and antenna settings
		dw1000_set_ranging_listening_window_settings(ANCHOR,
		                                             _ranging_listening_window_num,
		                                             pp_anc_final_pkt.final_antenna,
		                                             FALSE);

		// Prepare the outgoing packet to send back to the
		// tag with our TOAs.
		pp_anc_final_pkt.ieee154_header_unicast.seqNum++;
		const uint16_t frame_len = sizeof(struct pp_anc_final);
		dwt_writetxfctrl(frame_len, 0);

		// Pick a slot to respond in. Generate a random number and mod it
		// by the number of slots
		uint8_t slot_num = ranval(&_prng_state) % (_ranging_operation_config.anchor_reply_window_in_us /
		                                          _ranging_operation_config.anchor_reply_slot_time_in_us);

		// Come up with the time to send this packet back to the
		// tag based on the slot we picked.
		uint32_t delay_time = dwt_readsystimestamphi32() +
			DW_DELAY_FROM_US(ANC_FINAL_INITIAL_DELAY_HACK_VALUE +
				(slot_num*_ranging_operation_config.anchor_reply_slot_time_in_us));

		delay_time &= 0xFFFFFFFE;
		pp_anc_final_pkt.dw_time_sent = delay_time;
		dwt_setdelayedtrxtime(delay_time);

		// Send the response packet
		int err = dwt_starttx(DWT_START_TX_DELAYED);
		dwt_settxantennadelay(DW1000_ANTENNA_DELAY_TX);
		dwt_writetxdata(frame_len, (uint8_t*) &pp_anc_final_pkt, 0);

		_ranging_listening_window_num++;
	}
}
示例#3
0
// Triggered when we receive a packet
void app_dw1000_rxcallback (const dwt_callback_data_t *rxd) {
	// First grab a copy of local time when this arrived
	rtimer_clock_t rt_timestamp = RTIMER_NOW();
	DEBUG_B6_HIGH;

	if (rxd->event == DWT_SIG_RX_OKAY) {
		leds_toggle(LEDS_BLUE);

		uint8_t packet_type;
		uint64_t dw_timestamp;
		uint8_t recv_pkt_buf[RX_PKT_BUF_LEN];

		// Get the dw_timestamp first
		uint8_t txTimeStamp[5] = {0, 0, 0, 0, 0};
		dwt_readrxtimestamp(txTimeStamp);
		dw_timestamp = ((uint64_t) (*((uint32_t*) txTimeStamp))) | (((uint64_t) txTimeStamp[4]) << 32);

		// Get the packet
		dwt_readrxdata(recv_pkt_buf, MIN(RX_PKT_BUF_LEN, rxd->datalength), 0);
		packet_type = recv_pkt_buf[offsetof(struct pp_tag_poll, message_type)];
		global_round_num = recv_pkt_buf[offsetof(struct pp_tag_poll, roundNum)];

		if (packet_type == MSG_TYPE_PP_ONEWAY_TAG_POLL) {
			struct pp_tag_poll* pkt = (struct pp_tag_poll*) recv_pkt_buf;
			DEBUG_P("TAG_POLL rx: %u\r\n", pkt->subsequence);

			if (global_subseq_num == pkt->subsequence) {
				// Configurations matched, record arrival time
				pp_anc_final_pkt.TOAs[global_subseq_num] = dw_timestamp;
			} else {
				// Tag/anchor weren't on same settings, so we
				// drop this sample and catch the anchor up
				global_subseq_num = pkt->subsequence;
			}

			if (!global_round_active) {
				DEBUG_B4_LOW;
				DEBUG_B5_LOW;
				memset(antenna_statistics, 0, sizeof(antenna_statistics));
				global_round_active = true;
				start_of_new_subseq = true;
				substate_timer_fired = true;
				/*
				subseq_start_time = rt_timestamp - US_TO_RT(TAG_SQ_START_TO_POLL_SFD_HIGH_US);
				rtimer_clock_t set_to = subseq_start_time + US_TO_RT(POLL_TO_SS_US+SS_TO_SQ_US);
				*/
				rtimer_clock_t set_to = rt_timestamp + US_TO_RT(
						POLL_TO_SS_US + SS_TO_SQ_US
						- TAG_SQ_START_TO_POLL_SFD_HIGH_US
						- ANC_MYSTERY_STARTUP_DELAY_US);
				rtimer_set(&subsequence_timer,
						set_to,
						1,
						(rtimer_callback_t)subsequence_task,
						NULL);
			}

			//Keep a running total of the number of packets seen from each antenna
			antenna_statistics[subseq_num_to_anchor_sel(global_subseq_num)]++;
		} else if (packet_type == MSG_TYPE_PP_ONEWAY_TAG_FINAL) {
			if (!global_round_active) {
				// The first packet we happened to receive was
				// an ANC_FINAL. We have nothing interesting to
				// reply with, so don't. But we *do* need to set
				// receive mode again so that a new poll will be
				// caught
				dwt_rxenable(0);
				return;
			}

			//We're likely in RX mode, so we need to exit before transmission
			dwt_forcetrxoff();

			pp_anc_final_pkt.TOAs[NUM_MEASUREMENTS] = dw_timestamp;

			pp_anc_final_pkt.header.seqNum++;
			const uint16 frame_len = sizeof(struct pp_anc_final);
			dwt_writetxfctrl(frame_len, 0);

			//Schedule this transmission for our scheduled time slot
			DEBUG_B6_LOW;
			uint32_t temp = dwt_readsystimestamphi32();
			uint32_t delay_time = temp +
				DW_DELAY_FROM_US(
					ANC_FINAL_INITIAL_DELAY_HACK_VALUE +
					(ANC_FINAL_RX_TIME_ON_TAG*(ANCHOR_EUI-1))
					);
				/* I don't understand what exactly is going on
				 * here. The chip seems to want way longer for
				 * this preamble than others -- maybe something
				 * to do with the large payload? From empirical
				 * measurements, the 300 base delay is about the
				 * minimum (250 next tested as not working)
				DW_DELAY_FROM_US(
					REVISED_DELAY_FROM_PKT_LEN_US(frame_len) +
					(2*ANC_FINAL_RX_TIME_ON_TAG*(ANCHOR_EUI-1))
					);
				*/
			delay_time &= 0xFFFFFFFE;
			pp_anc_final_pkt.dw_time_sent = delay_time;
			dwt_setdelayedtrxtime(delay_time);

			int err = dwt_starttx(DWT_START_TX_DELAYED);
			dwt_settxantennadelay(TX_ANTENNA_DELAY);
			dwt_writetxdata(frame_len, (uint8_t*) &pp_anc_final_pkt, 0);
			DEBUG_B6_HIGH;

#ifdef DW_DEBUG
			// No printing until after all dwt timing op's
			struct pp_tag_poll* pkt = (struct pp_tag_poll*) recv_pkt_buf;
			DEBUG_P("TAG_FINAL rx: %u\r\n", pkt->subsequence);
#endif

			if (err) {
#ifdef DW_DEBUG
				uint32_t now = dwt_readsystimestamphi32();
				DEBUG_P("Could not send anchor response\r\n");
				DEBUG_P(" -- sched time %lu, now %lu (diff %lu)\r\n", delay_time, now, now-delay_time);
				leds_on(LEDS_RED);
#endif
			} else {
				DEBUG_P("Send ANC_FINAL\r\n");
				leds_off(LEDS_RED);
			}
		} else {
			DEBUG_P("*** ERR: RX Unknown packet type: 0x%X\r\n", packet_type);
		}
	} else {