📄 protocol.c
字号:
{
RadioSetBackChannelCrcSeed();
rx_data_length = RadioReceivePacket();
if( (rx_packet.data.hdr.type == BACK_CHANNEL_PACKET) &&
(rx_packet.data.hdr.dt_data == rx_data_toggle))
{
rx_data_toggle ^= 1;
NotifyDownloadBackChannelData();
}
//return to system CRC
RadioSetNonzeroCrcSeed();
}
// Force endstate to sleep
RadioForceState(END_STATE_SLEEP);
#endif //BACK_CHANNEL_SUPPORT
return( PROTOCOL_SUCCESS );
}
#ifdef BACK_CHANNEL_SUPPORT
else
{
// Force endstate to sleep
RadioForceState(END_STATE_SLEEP);
}
#endif //BACK_CHANNEL_SUPPORT
SlaveProtocolReconnect(dev_type);
return( PROTOCOL_TX_TIMEOUT );
}
///////////////////////////////////////////////////////////////////////////////
//
// Function: SlaveProtocolReconnect
//
//! Description: Connects the device to the bridge.
//!
//! Inputs:
//! - dev_type - device type
//!
//! Returns:
//! - Void
//!
///////////////////////////////////////////////////////////////////////////////
void SlaveProtocolReconnect(unsigned char dev_type)
{
unsigned char retry;
unsigned char packet_length;
// check for unbound device
if( sys_params.network_id.pin == 0 )
{
#ifdef KISS_BIND
// If the device is unbind, do KissBind once
SlaveProtocolKissBind(dev_type);
if( sys_params.network_id.pin == 0 )
return;
#else
return;
#endif
}
connected_state = PROTOCOL_DISCONNECTED;
// select a channel, send a connect request, and
// wait for a connect response
tx_packet.first.byte = 0; // clear the packet
tx_packet.connect_request.hdr.dev_type = dev_type;
tx_packet.connect_request.hdr.type = CONNECT_REQ;
tx_packet.connect_request.mid_1 = sys_params.bridge_mid.mid_1;
tx_packet.connect_request.mid_2 = sys_params.bridge_mid.mid_2;
tx_packet.connect_request.mid_3 = sys_params.bridge_mid.mid_3;
tx_packet.connect_request.mid_4 = sys_params.bridge_mid.mid_4;
// load the pnCode index
RadioSetSopPnCode( sys_params.network_id.pn_code );
// Force endstate to idle
RadioForceState(END_STATE_IDLE);
// send a connect request and wait for response, if no response change
// the channel and try again
for( retry = 0; retry < CONNECT_RETRY_COUNT; retry++ )
{
M8C_ClearWDTAndSleep;
RadioSetChannel( sys_params.network_id.channel );
if( RadioSendPacket(CONNECT_REQ_RETRIES, CONNECT_REQ_LEN) )
{
// Auto ACK off
RadioSetXactConfig(RadioXactConfig & 0x1F );
packet_length = RadioReceivePacket();
// Auto ACK back on
RadioSetXactConfig(RadioXactConfig | 0x80 );
if((packet_length == CONNECT_RESP_LEN) &&
(rx_packet.connect_response.hdr.type == CONNECT_RESP) &&
(rx_packet.connect_response.hdr.flag == 1))
{
connected_state = PROTOCOL_CONNECTED;
#ifdef ENCRYPT_TEA
if(!encrypt_key_received)
{
// Reduce PA
RadioSetPa( ENCRYPT_KEY_PA );
if(EncryptRequestKey())
{
encrypt_key_received = TRUE;
}
// Restore PA Level
RadioSetPa( DATA_MODE_PA );
}
#endif //ENCRYPT_TEA
break;
}
}
// Try a few times on the original channel
if( retry > ORIG_CHAN_RECONNECT_COUNT )
{
RadioGetNextChannel();
}
} // end for loop
// Force endstate to sleep
RadioForceState(END_STATE_SLEEP);
}
///////////////////////////////////////////////////////////////////////////////
//
// Function: SlaveProtocolRetrieveBridgeMid
//
//! Description: Retrieve the bridge MID saved in the flash
//!
//!
//! Inputs: Void
//!
//! Returns: Void
//!
///////////////////////////////////////////////////////////////////////////////
static void SlaveProtocolRetrieveBridgeMid(void)
{
RetrieveSystemParameters();
// check for uninitialized flash
if (sys_params.bridge_mid.signature != SIGNATURE_BYTE)
{
// set channel and pn_code to a value that will allow the different
// devices to coexist and interfere less with each other
sys_params.network_id.channel = 0;
sys_params.network_id.pn_code = 0;
sys_params.network_id.seed = 0;
sys_params.network_id.pin = 0;
}
else
{
// calculate channel, PN code, etc. from Bridge MID and store
// values in sys_params
RadioCalculateNetworkId();
}
}
#endif //MASTER_PROTOCOL
//*****************************************************************************
//*****************************************************************************
//
// ******************* For Common ********************************************
//
//*****************************************************************************
//*****************************************************************************
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioCalculateNetworkId
//
//! Description: Hash values for PN Code, Base Channel, and Network
//! PIN using the same algorithm as all devices.
//!
//! Inputs: Void
//!
//! Returns: Void
//!
///////////////////////////////////////////////////////////////////////////////
static void RadioCalculateNetworkId(void)
{
sys_params.network_id.pn_code = (sys_params.bridge_mid.mid_1 << 2) +
sys_params.bridge_mid.mid_2 +
sys_params.bridge_mid.mid_3;
while( sys_params.network_id.pn_code >= NUM_PN_CODES )
{
sys_params.network_id.pn_code -= NUM_PN_CODES;
}
sys_params.network_id.channel = (sys_params.bridge_mid.mid_2 >> 2) -
(sys_params.bridge_mid.mid_1 << 5) +
sys_params.bridge_mid.mid_3;
while( sys_params.network_id.channel >= NUM_CHANNELS )
{
sys_params.network_id.channel -= NUM_CHANNELS;
}
sys_params.network_id.pin = (((sys_params.bridge_mid.mid_1 - sys_params.bridge_mid.mid_2) &
PIN_MASK) + MIN_PIN);
sys_params.network_id.seed = ((sys_params.bridge_mid.mid_2 >> 6)) +
sys_params.bridge_mid.mid_1 +
sys_params.bridge_mid.mid_3;
// If seed equal 0, let it to be 1
if(sys_params.network_id.seed == 0)
sys_params.network_id.seed++;
}
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioGetNextChannel
//
//! Description: Performs the channel selection algorithm. Every sixth channel
//! will be used.
//!
//! Inputs: Void
//!
//! Returns: Void
//!
///////////////////////////////////////////////////////////////////////////////
static void RadioGetNextChannel(void)
{
sys_params.network_id.channel += (6 * (sys_params.network_id.pin + 1));
if((NUM_CHANNELS) - 1 < sys_params.network_id.channel)
{
sys_params.network_id.channel -= NUM_CHANNELS;
}
}
#if (defined KISS_BIND && defined RSSI_QUALIFY && defined PROMISCUOUS_MODE)
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioGetRxRssi
//
//! Description: Get RSSI for trasmission
//!
//!
//! Inputs: Void
//!
//! Returns: RSSI value
//!
///////////////////////////////////////////////////////////////////////////////
static unsigned char RadioGetRxRssi(void)
{
unsigned char rssi;
rssi = RadioGetRssi();
// Only the transmission RSSI is needed. If RSSI was NOT triggered from SOP, return 0.
if (!(rssi & SOP_RSSI))
{
return 0;
}
return rssi & RSSI_LVL_MSK;
}
#endif //(defined KISS_BIND && defined RSSI_QUALIFY && defined PROMISCUOUS_MODE)
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioSetPa
//
//! Description: Set the new PA value
//!
//!
//! Inputs: new PA value
//!
//! Returns: Void
//!
///////////////////////////////////////////////////////////////////////////////
static void RadioSetPa(unsigned char pa)
{
RadioSetTxConfig((DATCODE_LEN_32|DATMODE_8DR) | (pa & PA_VAL_MSK) );
}
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioSetNonzeroCrcSeed
//
//! Description: Set the non-zero CRC seed
//!
//!
//! Inputs: Void
//!
//! Returns: Void
//!
///////////////////////////////////////////////////////////////////////////////
static void RadioSetNonzeroCrcSeed(void)
{
// Set CRC
RadioSetCrcSeed((((unsigned short)sys_params.network_id.seed)<<8) + (unsigned short)sys_params.network_id.seed);
}
#ifdef BACK_CHANNEL_SUPPORT
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioSetBackChannelCrcSeed
//
//! Description: Set the back channel CRC seed
//!
//!
//! Inputs: Void
//!
//! Returns: Void
//!
///////////////////////////////////////////////////////////////////////////////
static void RadioSetBackChannelCrcSeed(void)
{
// Set CRC
RadioSetCrcSeed((((unsigned short)(~sys_params.network_id.seed))<<8) + (unsigned short)sys_params.network_id.seed);
}
#endif //BACK_CHANNEL_SUPPORT
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioSendPacket
//
//! Description: send a packet
//!
//!
//! Inputs: retry time and packet length
//!
//! Returns:
//! - TRUE - for successful transmission
//! - FALSE - for unsuccessful transmission
//!
///////////////////////////////////////////////////////////////////////////////
unsigned char RadioSendPacket( unsigned char retry, unsigned char length )
{
unsigned char status;
unsigned char success = FALSE;
RadioSetPtr((unsigned char *)&tx_packet);
status = RadioBlockingTransmit(retry, length);
if( (status & (RADIO_ERROR | RADIO_COMPLETE)) == RADIO_COMPLETE )
success = TRUE;
return success;
}
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioReceivePacket
//
//! Description: Wait for packet
//!
//!
//! Inputs: length
//!
//! Returns: received packet length
//!
///////////////////////////////////////////////////////////////////////////////
unsigned char RadioReceivePacket(void)
{
unsigned short timeout;
unsigned char status;
unsigned char pkt_len = 0;
RadioStartReceivePacket();
// Spin until packet received or timeout
for( timeout=0; timeout<RX_PACKET_TIMEOUT; ++timeout )
{
status = RadioGetReceiveState();
if( (status & (RADIO_ERROR | RADIO_COMPLETE)) == RADIO_COMPLETE)
{
pkt_len = RadioEndReceive();
break;
}
else if (status & RADIO_ERROR)
{
(void)RadioEndReceive();
RadioStartReceivePacket();
}
//Clear Watchdog and Sleep
M8C_ClearWDTAndSleep;
TimerDelay50usec();
}
if (timeout == RX_PACKET_TIMEOUT)
{
(void)RadioAbort();
}
return pkt_len;
}
///////////////////////////////////////////////////////////////////////////////
//
// Function: RadioStartReceivePacket
//
//! Description: start to receive a packet
//!
//!
//! Inputs: Void
//!
//! Returns: Void
//!
///////////////////////////////////////////////////////////////////////////////
void RadioStartReceivePacket(void)
{
RadioSetLength(sizeof(rx_packet));
RadioSetPtr((unsigned char *)&rx_packet);
RadioStartReceive();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -