📄 rfdesign.c
字号:
static unsigned char output_byte_mask;
// saves last three output bit values
static unsigned char last_three_outputs;
bit EAstate;
USHORT value;
// This flag is set in Asleep() and is used to re-initialize static
// variables the first time RXalgorithm() runs after the communications
// channel changes from idle to active
if(INIT_RX_ALGORITHM)
{
RXI1 = 0;
RXI2 = 0;
output_byte = 0;
output_byte_mask = 0x80;
last_three_outputs = 1;
INIT_RX_ALGORITHM = 0;
}
EAstate=EA;
EA = 0; // disable interrupts while compressing
value.S = ADCRXFIFO_Pull(); // pull the next ADC value
EA = EAstate;
last_three_outputs<<=1; // only the lower 3 bytes are used,
// LSB is set to zero with a shift
// This conditional performs a level conversion. If the current ADC
// value is greater than the value in RXI1, a 1 is saved as the UTX
// byte and a 1 is saved as the last output (which is used in the
// next conditional).
// input - I1 = positive number
if (((short)value.S - (RXI1>>I1_TIMECONST)) > 0)
{
output_byte |= output_byte_mask; // sets the output bit
// samples are compressed so that
// the LSB of output_byte is the most
// recently compressed sample
last_three_outputs |= 0x01; // saves output by setting LSB
}
// Conditional checks for 3 consecutive 1's or 0's, which indicates that
// the sigma size needs to be increased in order for the compression
// algorithm to track the sample properly
if ( ((last_three_outputs & 0x07) == 0x07) ||
((last_three_outputs & 0x07) == 0x00))
{
RXI2 += DELTAMAX;
}
else
{
if (RXI2 != 0) // guards against RXI2 becoming negative
RXI2 -= DELTAMAX;
}
// This conditional adjusts RXI1 using the new value of RXI2.
if ((last_three_outputs & 0x01) == 1)
{
RXI1 += ((RXI2>>I2_TIMECONST) + DELTAMIN);
}
else
RXI1 -= ((RXI2>>I2_TIMECONST) + DELTAMIN);
// If output_byte_mask = 1, a TX UART byte is ready to be transmitted
// because 8 left shifts on 0x80 have occurred.
if (output_byte_mask == 1)
{
output_byte_mask = 0x80; // reset mask for next sample
EAstate=EA;
EA = 0; // disable interrupts while compressing
UTXFIFO_Push(output_byte); // push byte of compressed data
// to UART
EA = EAstate;
// This conditional begins a UART transmission if the UART is in
// transmit mode, a TX is not already in progress, a transition
// between RX and TX or TX and RX is not in progress, and there
// are at least DATA_BYTES_PER_TRANSMISSION bytes in the URX FIFO.
if ((UART_MODE == TX_MODE) && !(TX_IN_PROGRESS) &&
!(TRANSITION_IN_PROGRESS) &&
(UTXFIFO.COUNT >= DATA_BYTES_PER_TRANSMISSION))
{
TX_IN_PROGRESS = 1; // set flag so this conditional
// only executes once per TX session
TI0 = 1;
}
output_byte = 0; // reset output_byte
}
else
{
output_byte_mask >>= 1; // shift mask for next sample
}
EA = EAstate;
}
//-----------------------------------------------------------------------------
// TXalgorithm
//-----------------------------------------------------------------------------
// TXalgorithm pulls 1 received UART byte per 8 iterations, and
// pushes one DAC sample every 2 iterations.
//
void TXalgorithm(void)
{
bit EAstate;
static short TXI1;
static unsigned short TXI2;
static unsigned char top_of_FIFO; // saves newest pull from RXFIFO
// used to read from top_of_FIFO
static unsigned char top_of_FIFO_mask;
// saves last three input bit values
static unsigned char last_three_inputs;
if(INIT_TX_ALGORITHM)
{
top_of_FIFO = 0;
top_of_FIFO_mask = 0;
last_three_inputs = 1;
TXI1 = 0;
TXI2 = 0;
accumulate = 0;
DACstartupTimer = 0;
INIT_TX_ALGORITHM = 0;
}
// This conditional checks to see if 8 bits have been
// read from the top_of_FIFO variable. If so, another
// byte from the URXFIFO must be pulled before the
// algorithm can continue.
if (top_of_FIFO_mask == 0)
{
EAstate=EA;
EA = 0;
top_of_FIFO = URXFIFO_Pull(); // pull another compressed byte
EA = EAstate;
top_of_FIFO_mask = 0x80; // reset mask
}
last_three_inputs<<=1; // only last 3 bits are used,
// LSB is cleared
// This conditional reads a bit from the byte pulled
// from URXFIFO and saves it in last_three_inputs.
if((top_of_FIFO & top_of_FIFO_mask) != 0)
{
last_three_inputs |= 0x01; // set LSB
}
top_of_FIFO_mask>>=1; // shift mask for next sample
// checks for 3 consecutive 0's or 1's and increases
// TXI2 if that pattern occurs.
if (((last_three_inputs & 0x07) == 0x07) ||
((last_three_inputs & 0x07) == 0x00))
{
TXI2+=DELTAMAX;
}
else
{
if (TXI2 != 0)
TXI2-=DELTAMAX;
}
// Adjusts TXI1 with new value of TXI2
if(last_three_inputs & 0x01)
{
TXI1 += ((TXI2>>I2_TIMECONST) + DELTAMIN);
}
else
{
TXI1 -= ((TXI2>>I2_TIMECONST) + DELTAMIN);
}
// This code averages every pair of samples to minimize
// noise at the DAC output.
if(!accumulate)
{
// divide TXI1 to account for I1's time constant
accumulate = (TXI1>>I1_TIMECONST);
}
else
{
// add second value, dividing for I1's time constant
accumulate = accumulate + (TXI1>>I1_TIMECONST);
accumulate = accumulate >> 1; // divide sum by to average total
EAstate=EA;
EA = 0;
DACTXFIFO_Push(accumulate); // push result
EA = EAstate;
accumulate = 0; // reset accumulator
}
EA = EAstate;
}
//-----------------------------------------------------------------------------
// Power Consumption Functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// ASLEEP
//-----------------------------------------------------------------------------
//
// This function runs when audio levels on both transceivers are below
// AUDIO_THRESHOLD. The ADC samples the audio input and the RSSI/IF
// pin of the RF transceiver. If the audio input goes above
// AUDIO_THRESHOLD or the RSSI/IF pin's value drops below SIGNAL_THRESHOLD,
// a synchronization sequence begins.
//
void ASLEEP(void)
{
unsigned int audio_value;
unsigned int RSSI_value;
EA = 0; // disable global interrupts
CR = 0;
RUN_ASLEEP = 0;
CLEAR_FIFOS(); // removes any old audio samples
ADC0CN &=~0x07;
ADC0CN |=0x00; // Set ADC to sample when AD0BUSY = 1
PALE = 1; // PALE should be high as default
C1000_Init(); // initialize the transceiver
C1000_RSSI(); // set it to output received
// signal strength
UART_MODE = RX_MODE; // set initial UART mode to RX
AD0EN = 1;
do{
// check audio input (amplitude) voltage level
AMX0P = 0x0B; // set to P1.3 (audio input)
// wait for ADC MUX to settle
WaitUS(60); // wait 60 microseconds
AD0INT = 0; // clear flag
AD0BUSY = 1; // begin capture
while(!AD0INT); // spin until ADC capture is complete
audio_value = ADC0; // save value
// check RSSI pin voltage level
AMX0P = 0x09; // set to P1.1 (RSSI input)
// wait for ADC MUX to settle
WaitUS(60); // wait 60 microseconds
AD0INT = 0; // clear flag
AD0BUSY = 1; // begin capture
while(!AD0INT); // spin until ADC capture is complete
RSSI_value = ADC0; // save value
}while((audio_value < AUDIO_THRESHOLD)
&& (RSSI_value > RSSI_THRESHOLD));
ADCRXFIFO_Push(audio_value);
RX_STATEMACHINE = RX_UNCALIBRATED; // reset receive state machine
TX_STATEMACHINE = TX_UNCALIBRATED; // reset transmit state machine
AMX0P = 0x0B; // set ADC to P1.3 (audio input)
ADC0CN &=~0x07;
ADC0CN |= 0x02; // set ADC to sample on Tmr 2 overflows
// RX Algorithm Variable Initialization
INIT_RX_ALGORITHM = 1;
// TX Algorithm Variable Initialization
INIT_TX_ALGORITHM = 1;
// Shutdown state machine initialization
REMOTE_SHUTDOWN_STATE = 0;
LOCAL_SHUTDOWN_STATE = 0;
ADC_LOW = 0;
// Clear UART flags and interrupts
RI0 = 0;
TI0 = 0;
TX_IN_PROGRESS = 0;
RX_IN_PROGRESS = 0;
C1000_UNLOCK_FILTER(); // unlocks RF transceiver's Averaging
// filter, will be locked inside
// PCA ISR during calibration sequence
// if received signal strength indicates that the other endpoint is
// transmitting, set to Receive Mode before exiting Asleep()
if (RSSI_value <= RSSI_THRESHOLD)
{
SETREG(MAIN, 0x11); // set to RX Mode
SETREG(PA_POW,0x00); // set output power to 0
SETREG(CURRENT,0x88); // set to RX current
CR = 1; // enable PCA timer
EIE1 |= 0x10; // Enable PCA0 interrupts
UART_MODE = RX_MODE; // set initial UART mode to RX
}
// if the local signal is loud enough to transmit, set the system
// to TX Mode before exiting Asleep()
else
{
SETREG(PA_POW,0x00); // set output power to 0
SETREG(MAIN,0xE1); // set to TX Mode
SETREG(CURRENT,0xF3); // set TX current
// wait 250 microseconds
WaitUS(250);
SETREG(PA_POW,0x80);
//wait for 20 microseconds
WaitUS(20);
UART_MODE = TX_MODE; // set initial UART mode to TX
}
AD0EN = 1; // enable ADC
EA = 1; // enable global interrupts
}
void WaitUS(unsigned int count)
{
unsigned int x;
TR0 = 1;
// each iteration of the for loop lasts approximately 1 us
for(x = 0; x < count; x++)
{
TF0 = 0;
while(!TF0);
}
TF0 = 0;
TR0 = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -