📄 an147_cvsd.c
字号:
// timer will synchronize with master's at the end
// of the first received data packet
SPI_TimerEnable = TRUE;
SPI_Timer = SPI_SlopTimeOut + TX_NumBytesPreamble;
RXTX_MasterSelect = RXTX_Slave;
// reset counter
PreambleByte = 0;
}
}
else // received byte was not Preamble
{
// reset counter
PreambleByte = 0;
}
break;
case(RX_Preamble):
{
if(!SPI_TimeOutEvent)
{
// of byte received is Preamble, increment counter
if((SPI0DAT == 0x55) || (SPI0DAT == 0xAA))
{
// if minimum number of Preamble bytes has been received,
// begin searching for the Sync word
if(PreambleByte++ >= RX_MinBytesPreamble)
{
RXTX_StateMachine = RX_SyncWord;
PreambleByte = 0;
SPI_DataBytes = 0;
}
}
else
{
// received byte was not Preamble, reset counter
PreambleByte = 0;
}
}
// if time allotted to finding preamble has expired, enter
// Time Out state with failure information
else // (SPI_TimeOutEvent)
{
TimeOut_EntryMode = TimeOut_RXNoPreamble;
RXTX_StateMachine = RXTX_TimeOut;
PreambleByte = 0;
}
}
break;
case(RX_SyncWord):
{
// only acknowledge time-outs during data reception
//Sync Word not found before SPI TimeOut Event
if(SPI_TimeOutEvent == TRUE)
{
TimeOut_EntryMode = TimeOut_RXNoSyncWord;
RXTX_StateMachine = RXTX_TimeOut;
}
else if(SPI_Input == 0xFF)
{
// configure external interrupt to trigger on falling edge
// of MOSI data line
SPIEN = 0; // disable SPI, re-enabled in PCA ISR
PCA0CPM0 = 3<<4; // Set PCA to edge-capture on rising
// and falling edges
PCA0CPM0 |= 1; // enable CCF0 interrupts
// route PCA CEX0 instead of SPI to RF transceiver data line
RoutePCA();
// enable PCA to edge-capture mode on P1.1
EIE1 |= 0x10; // enable PCA0 interrupts
CCF0 = 0; // clear pending interrupt flag
RXTX_StateMachine = RX_AudioState;
}
}
break;
case(RX_AudioState):
{
Audio_RemoteState = SPI0DAT;
// if local endpoint is designated as slave, and the shutdown
// command has been received, configure the RF state machine
// to shutdown
if((RXTX_MasterSelect == RXTX_Slave) &&
(Audio_RemoteState == Audio_ChannelShutdown))
{
RXTX_StateMachine = RXTX_Shutdown;
}
// else receive a packet of data
else
{
RXTX_StateMachine = RX_Data;
}
}
break;
case(RX_Data):
{
ReceiveFIFO_Push(SPI0DAT); // store received byte
SPI_DataBytes++; // increment received bytes counter
// once all packet's bytes have been received, exit state
if(SPI_DataBytes == RXTX_BytesOfData)
{
// configure state machine to enter time out state a
// fter SPI_Timer reaches terminal value
TimeOut_EntryMode = TimeOut_RXSuccessful;
RXTX_StateMachine = RXTX_WaitForTimeOut;
// reset the SPI timer to the value it should be during
// this point in packet reception
if(RXTX_MasterSelect == RXTX_Slave)
{
// The slave should re-sync the SPI clock to the
// reception of the last transmitted master CRC
SPI_Timer = SPI_SlopTimeOut + TX_NumBytesPreamble
+ RXTX_SyncWordSize + Audio_StateSize
+ RXTX_BytesOfData;
}
// This code will adjust the output rate of the DAC
// in order to avoid data overflows and underflows
DAC_Error = (signed int)ReceiveFIFO_COUNT -
(signed int)ReceiveFIFO_TARGET;
DAC_Error *= 5;
TMR3RL = -((SYSCLK/DAC_UPDATERATE) - DAC_Error);
}
}
break;
case(TX_SwitchTime):
{
// spin until defined time period has passed
if(SPI_Timer <= SPI_SlopTimeOut)
{
SPI0DAT = 0xFF;
}
else
{
SPI0DAT = 0xFF;
RXTX_StateMachine = TX_Preamble;
}
}
break;
case (TX_InitPreamble):
if(PreambleByte++ != TX_NumBytesInitPreamble - 1)
{
// only write to SPI0DAt if the transmit buffer is empty
if(TXBMT)
{
SPI0DAT = 0x55;
}
_nop_();
if(TXBMT)
{
// conditional should execute only once
SPI0DAT = 0x55;
}
}
else // transmit last byte of Preamble
{
SPI0DAT = 0x55;
SPI_TimerEnable = TRUE;
// set timer to position it would be in at this
// point during a normal data transmission
SPI_Timer = SPI_SlopTimeOut + TX_NumBytesPreamble;
RXTX_StateMachine = TX_SyncWord;
PreambleByte = 0;
SPI_DataBytes = 0;
}
break;
case(TX_Preamble):
if(PreambleByte++ != TX_NumBytesPreamble - 1)
{
if(TXBMT)
{
SPI0DAT = 0x55;
}
_nop_();
if(TXBMT)
{
// conditional should execute only once
SPI0DAT = 0x55;
}
}
else
{
SPI0DAT = 0x55;
RXTX_StateMachine = TX_SyncWord;
PreambleByte = 0;
SPI_DataBytes = 0;
}
break;
case(TX_SyncWord):
{
// State Transmits 0xFFFFEE
if(SyncWordByte < 2)
{
SPI0DAT = 0xFF;
++SyncWordByte;
}
else
{
SPI0DAT = 0xEE;
RXTX_StateMachine = TX_AudioState;
SyncWordByte = 0;
}
break;
}
case(TX_AudioState):
{
// if both endpoints' audio signals are "quiet" and the
// local endpoint is designated as the master, transmit
// the Shutdown command to terminate the Communication Channel
if((RXTX_MasterSelect == RXTX_Master) &&
(Audio_RemoteState == Audio_Quiet)
&& (Audio_LocalState == Audio_Quiet))
{
SPI0DAT = Audio_ChannelShutdown;
RXTX_StateMachine = RXTX_Shutdown;
}
else
{
SPI0DAT = Audio_LocalState;
RXTX_StateMachine = TX_Data;
}
}
break;
case(TX_Data):
{
SPI0DAT = TransmitFIFO_Pull(); // pull compressed byte and transmit
SPI_DataBytes++; // increment byte counter
// once defined number of bytes has been transmitted, exit state
if(SPI_DataBytes == RXTX_BytesOfData)
{
SPI_DataBytes = 0;
SPI_DataBytes = 0;
TimeOut_EntryMode = TimeOut_TXSuccessful;
RXTX_StateMachine = RXTX_WaitForTimeOut;
// This code adjusts the sampling rate of the ADC
// in order to avoid data overflows or underflows
DAC_Error = (signed int)TransmitFIFO_COUNT -
(signed int)TransmitFIFO_TARGET;
DAC_Error *= 5;
// adjust ADC sample rate
TMR2RL = -((SYSCLK/DAC_UPDATERATE) + DAC_Error);
}
}
break;
case(RXTX_WaitForTimeOut):
{
// state machine will exit state after SPI_Timer has reached its
// terminal value
if(TXBMT)
{
SPI0DAT = 0x00;
}
if(SPI_TimeOutEvent == TRUE)
{
RXTX_StateMachine = RXTX_TimeOut;
}
}
break;
case(RXTX_TimeOut):
SPI_TimeOutEvent = FALSE; // clear flag
// reset RX failure counter if receive was successful
if(TimeOut_EntryMode == TimeOut_RXSuccessful)
{
RXTX_NoPreambleCount = 0;
}
switch(TimeOut_EntryMode)
{
case(TimeOut_RXSuccessful):
// toggle LED on to indicate that RF is
// entering transmit mode
LED2 = 0;
RXTX_StateMachine = Switch_ToTX01;
break;
case(TimeOut_TXSuccessful):
// toggle LED off to indicate that RF is
// entering receive mode
LED2 = 1;
RXTX_StateMachine = Switch_ToRX01;
break;
case(TimeOut_RXNoPreamble):
LED2 = 0;
// count consecutive failed preamble detections,
// make decision based on count
if(++RXTX_NoPreambleCount == RXTX_NoPreambleLevel)
{
RXTX_NoPreambleCount = 0;
RXTX_StateMachine = RXTX_Shutdown;
}
// else if endpoint is master, transmit a packet
else if(RXTX_MasterSelect == RXTX_Master)
{
RXTX_StateMachine = Switch_ToTX01;
}
// if endpoint is slave, continue trying to receive a packet
else
{
RXTX_StateMachine = RX_Preamble;
}
break;
case(TimeOut_RXNoSyncWord):
// if master, transmit a packet
if(RXTX_MasterSelect == RXTX_Master)
{
RXTX_StateMachine = Switch_ToTX01;
}
// if slave, try to receive a packet again
else
{
RXTX_StateMachine = RX_Preamble;
}
break;
} // switch(TimeOut_EntryMode)
break;
case(RXTX_Shutdown):
// set system to search for a Communication Channel
RXTX_MasterSelect = RXTX_Searching;
RXTX_RunInitSlave = TRUE;
SPI_TimerEnable = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -