⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.c

📁 光电鼠标IC资料
💻 C
📖 第 1 页 / 共 3 页
字号:
					// check if valid Call Setup Packet
					ENABLE_RF_SPI;
					read_rf_byte(R_RX_PAYLOAD);
					payload[0] = read_rf_byte(R_RX_PAYLOAD);
					payload[1] = read_rf_byte(R_RX_PAYLOAD);
					payload[2] = read_rf_byte(R_RX_PAYLOAD);
					DISABLE_RF_SPI;
					if(payload[0] == SIGNAL_CALL_SETUP)
					{
						freq[0] = payload[1];
						freq[1] = payload[2];
						return(CALL_SETUP_OK);
					}
					else
						freq_ptr++;
				}
				else
					return(CALL_SETUP_FAILURE);
			}	
			// else try next frequency
			else
				freq_ptr++;
		}
	}
	
	// No 'Call_Setup_Ack' is received
	return(CALL_SETUP_FAILURE);
}

/***************************************************************************
Declaration : void audio_transfer(void)

Description : Writes an audio payload to the radio and exchanges audio
			  payloads at the given frequencies. Reads the audio payload
			  from the radio if any is received.
***************************************************************************/
void audio_transfer(void)
{
char status[2];
int i;

	#ifdef DONGLE
	
	// Exchange Audio Packets at each frequency
	event_time = &event_times[0];
	for(i=0; i<N_FREQ_CONNECTED; i++)
	{
		// Send TX packet synchronized to frame
		set_rf_tx(freq[i]);
		clear_rf_interrupt();
		#ifdef USB
			SET_TIMER2_EVENT((char)*event_time++);
			while(!TIMER2_EVENT)
				;
		#else
			SET_TIMER1_EVENT(*event_time++);
			while(!TIMER1_EVENT)
				;
		#endif
		rf_enable_pulse();
		wait_rf_irq(TIMEOUT_AUDIO_PACKET,DIV8);
		
		// Receive Audio RX packet
		set_rf_rx(freq[i]);
		clear_rf_interrupt();
		RF_ENABLE;
		#ifdef USB
			SET_TIMER2_EVENT((char)*event_time++);
			while(!TIMER2_EVENT)
				;
		#else
			SET_TIMER1_EVENT(*event_time++);
			while(!TIMER1_EVENT)
				;
		#endif
		if(!nRF_IRQ)
			status[i] = STATUS_RX_OK;
		else
			status[i] = STATUS_RX_FAILED;

		RF_DISABLE;
	}
	
	#ifdef USB
		STOP_TIMER2;
	#endif
	
	// Read RX Audio Packet if any, else stuff a packet
	if((status[0] == STATUS_RX_OK) || (status[1] == STATUS_RX_OK))
	{
		get_audio_packet();
		frame_loss = 0;
	}
	else
	{
		// Set Signal
		stuff_packet();
		frame_loss += 1;
	}
	
	// Flush RX FIFO	
	flush_rf_rx();
	
	
	// Update Packet Loss counters
	if((signal_in[0] & SIGNAL_PACKET0_OK) && (status[0] == STATUS_RX_OK))
	{
		packet_loss[0] -= PACKET_LOSS_DECREMENT;
		if(packet_loss[0] < 0)
			packet_loss[0] = 0;
	}
	else
		packet_loss[0] += PACKET_LOSS_INCREMENT;
	
	if((signal_in[0] & SIGNAL_PACKET1_OK) && (status[1] == STATUS_RX_OK))
	{
		packet_loss[1] -= PACKET_LOSS_DECREMENT;
		if(packet_loss[1] < 0)
			packet_loss[1] = 0;
	}
	else
		packet_loss[1] += PACKET_LOSS_INCREMENT;
		
	// Change Frequency based on Packet Loss Statistics
	if(packet_loss[0] >= PACKET_LOSS_THRESHOLD)
	{
		freq[0] += FREQ_STEP;
		if(freq[0] > FREQ0_MAX)
			freq[0] -= (FREQ0_MAX - FREQ0_MIN);
		packet_loss[0] = 0;
		packet_loss[1] = 0;
	}
	if(packet_loss[1] >= PACKET_LOSS_THRESHOLD)
	{
		freq[1] += FREQ_STEP;
		if(freq[1] > FREQ1_MAX)
			freq[1] -= (FREQ1_MAX - FREQ1_MIN);
		packet_loss[0] = 0;
		packet_loss[1] = 0;
	}
	
	signal_out[1] = freq[1] - freq[0];

	//Write TX Audio Packet and enable payload re-use
	put_audio_packet();
	reuse_rf_payload();
	
	#endif
	
	#ifdef HEADSET
	
	// Exchange Audio Packets at each frequency
	event_time = &event_times[0];
	SET_TIMER1_EVENT(*event_time++);
	for(i=0; i<N_FREQ_CONNECTED; i++)
	{
		// Receive Audio RX packet
		set_rf_rx(freq[i]);
		clear_rf_interrupt();
		while(!TIMER1_EVENT)
			;
		RF_ENABLE;
		SET_TIMER1_EVENT(*event_time++);
		while(!TIMER1_EVENT && nRF_IRQ)
		//while(!TIMER1_EVENT)
			;
		// If RF Interrupt request, RX OK
		if(!nRF_IRQ)
		{
			status[i] = STATUS_RX_OK;
			SET_TIMER1(master_sync_times[i]);
		}
		else
			status[i] = STATUS_RX_FAILED;

		RF_DISABLE;
		
		// Send Audio TX packet
		set_rf_tx(freq[i]);
		clear_rf_interrupt();
		SET_TIMER1_EVENT(*event_time++);
		while(!TIMER1_EVENT)
			;
		rf_enable_pulse();
		SET_TIMER1_EVENT(*event_time++);
		wait_rf_irq(TIMEOUT_AUDIO_PACKET,DIV8);
	}

	// Read RX Audio Packet if any, else stuff a packet
	if((status[0] == STATUS_RX_OK) || (status[1] == STATUS_RX_OK))
	{
		get_audio_packet();
		frame_loss = 0;
	}
	else
	{
		stuff_packet();
		signal_in[0] &= ~SIGNAL_CALL_CLEAR;
		frame_loss += 1;
	}

	// Flush RX FIFO	
	flush_rf_rx();
	
	// Set Receive Status bits and update Frequency
	if(status[0] == STATUS_RX_OK)
	{
		signal_out[0] |= SIGNAL_PACKET0_OK;
		if(status[1] == STATUS_RX_OK)
			signal_out[0] |= SIGNAL_PACKET1_OK;
		else
		{
			signal_out[0] &= ~SIGNAL_PACKET1_OK;
			freq[1] = freq[0] + signal_in[1];
		}
	}
	else
	{
		signal_out[0] &= ~SIGNAL_PACKET0_OK;
		if(status[1] == STATUS_RX_OK)
		{
			signal_out[0] |= SIGNAL_PACKET1_OK;
			freq[0] = freq[1] - signal_in[1];
		}
		else
			signal_out[0] &= ~SIGNAL_PACKET1_OK;
	}
	
	// Write TX Audio Packet and enable payload re-use
	put_audio_packet();
	reuse_rf_payload();
	
	#endif
}

/***************************************************************************
Declaration : char get_sync(void)

Description : The Slave synchronizes to the Master frame by resetting the 
			  frame timer when a valid packet is received. 
***************************************************************************/
char get_sync(void)
{
char status;
char sync_counter = 0;
int i;

	// Receive until valid packet or timeout
	while(1)
	{
		for(i=0; i<N_FREQ_CONNECTED; i++)
		{
			set_rf_rx(freq[i]);
			clear_rf_interrupt();
			RF_ENABLE;
			status = wait_rf_irq(TIMEOUT_SYNC,DIV64);
			RF_DISABLE;
			if(status == STATUS_TIMEOUT)
			{
				// Increment sync attempt counter
				sync_counter += 1;
				if(sync_counter >= N_SYNC_ATTEMPTS)
					return(call_status & ~MASTER_SYNC);
			}
			else
			{
				SET_TIMER1((master_sync_times[i]+SYNC_DELAY));
				return(call_status | MASTER_SYNC);
			}
		}
	}
}

/***************************************************************************
Declaration : void put_audio_packet(void)

Description : 
***************************************************************************/
void put_audio_packet(void)
{
int audio_sample,abs_audio;
volatile char status;
char audio_byte;
int i;
	
	// Put RF Payload
	ENABLE_RF_SPI;
	write_rf_byte(W_TX_PAYLOAD);
	
	// Put Signalling bytes
	write_rf_byte(signal_out[0]);
	write_rf_byte(signal_out[1]);
	
	// Put audio bytes
	for(i=0; i< AUDIO_SAMPLES; i++)
	{
		// Read 16bit audio sample from input buffer
		audio_sample = (unsigned int)(*input_read_ptr++) << 8;
		audio_sample += (unsigned int)*input_read_ptr++;
		#ifndef USB
		input_read_ptr += 2;
		#endif
		if(input_read_ptr >= &input[AUDIO_BUFFER_LENGTH])
			input_read_ptr = &input[0];
		
		// Compress 16bit --> 12bit --> 8bit
		if(audio_sample < 0)
			abs_audio = -audio_sample;
		else
			abs_audio = audio_sample;
		audio_byte = pgm_read_byte(&Alaw_compress[(abs_audio >> 4) & 0x7FF]);
		if(audio_sample < 0)
			audio_byte |= 0x80;
		
		// Put audio byte in nRF24L01 FIFO
		READ_SPI_STATUS(status);
		WRITE_SPI(audio_byte);
	}
	
	if(!(protocol_flags & FLAG_BUFFER_SYNC1))
	{
		input_read_ptr = (char *)((unsigned int)input_write_ptr & 0xFFFC);
		input_read_ptr -= 40;
		if(input_read_ptr < &input[0])
			input_read_ptr += AUDIO_BUFFER_LENGTH;
		protocol_flags |= FLAG_BUFFER_SYNC1;
	}
	
	#ifdef HEADSET
	// Handle slip due to clock differences
	i = (int)input_write_ptr - (int)input_read_ptr;
	if(i < 0)
		i += AUDIO_BUFFER_LENGTH;
	if(i < 20)
	{
		#ifdef USB
		input_read_ptr -= 2;
		#else
		input_read_ptr -= 4;
		#endif
		if(input_read_ptr < &input[0])
			input_read_ptr = &input[AUDIO_BUFFER_LENGTH-1];
	}
	if(i > 60)
	{
		#ifdef USB
		input_read_ptr -= 2;
		#else
		input_read_ptr -= 4;
		#endif
		if(input_read_ptr >= &input[AUDIO_BUFFER_LENGTH])
			input_read_ptr = &input[0];
	}
	#endif

	WAIT_SPI_READY;
	DISABLE_RF_SPI;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -