📄 protocol.c
字号:
// 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 + -