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

📄 protocol.c

📁 Cypress公司开发的2.4G无线键盘鼠标及其Bridge源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        { 
            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 + -