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

📄 protocol.c

📁 Cypress公司开发的2.4G无线键盘鼠标及其Bridge源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
{
    unsigned char rssi;
    
    // Dummy read
    (void)RadioGetRssi();

    rssi = RadioGetRssi();

    // If RSSI was triggered from SOP read RSSI again to get a non-transmission reading
    if (rssi & SOP_RSSI)
    {
        rssi = RadioGetRssi();
    }
  
    return rssi & RSSI_LVL_MSK;
}

///////////////////////////////////////////////////////////////////////////////
//
//  Function:    MasterProtocolDeviceTypeToBit
//
//!  Description: Convert the device type to bit
//!               
//!
//!  Inputs:      Device type
//!
//!  Returns:     Bit mask
//!
///////////////////////////////////////////////////////////////////////////////

static unsigned char MasterProtocolDeviceTypeToBit(unsigned char dev_type)
{
    return (1 << dev_type);
}



#else //MASTER_PROTOCOL

//*****************************************************************************
//*****************************************************************************
//
// *******************  For Slave Protocol ************************************
//
//*****************************************************************************
//*****************************************************************************


///////////////////////////////////////////////////////////////////////////////
//
//   Function:    SlaveProtocolInit
//
//!  Description: Inspects stored configuration and figures device parameters using 
//!               algorithms to find PN code, channel, pin, and CRC seed  
//!               (based off the MID). Calls radio init,. 
//!
//!  Inputs:      Void
//!
//!  Returns:     Void
//!
///////////////////////////////////////////////////////////////////////////////

void SlaveProtocolInit(void)
{
    // Configure the Radio
    RadioInit(ACK_EN|END_STATE_SLEEP|ACK_TO_8X, DATA_MODE_PA|DATCODE_LEN_32|DATMODE_8DR);

    // Configure the frame
    RadioSetFrameConfig(SOP_EN|LEN_EN|4);

    // Load the Preamble with 0x01
    // This design defaults to using 16-chip Preamble. The 16 chip Preamble sequence 
    // may be repeated multiple times (see Register PREAMBLE_ADR). The longer 
    // Preamble allows the receiver amble time to "lock" to the coming signal. Our 
    // testing shows that 16-chip sequence is sufficient.
    RadioSetPreambleCount(0x01);

    // Set LVI Threshold to 1.8V  
    RadioWrite(PWR_CTRL_ADR, PWR_CTRL_SETTING); 

    // Retrieve the bridge MID
    SlaveProtocolRetrieveBridgeMid();    

    // Set CRC
    RadioSetNonzeroCrcSeed();
        
    connected_state = PROTOCOL_DISCONNECTED;

#ifdef ENCRYPT_TEA
    encrypt_key_received = FALSE;
#endif //ENCRYPT_TEA
}


///////////////////////////////////////////////////////////////////////////////
//
//  Function:    SlaveProtocolButtonBind
//
//!  Description: The device sets the current channel and PN code to the channel 
//!               and PN code specified in the Bind ID. The device sends out
//!               a Bind Request on each channel for a certain time before selecting 
//!               the next channel. If the device receives a Bind Response from the 
//!               Bridge, it will store the bridge抯 Manufacturing ID and try to 
//!               connect to the bridge. The device will also exit the bind mode   
//!               if the defined time period has elapsed. 
//!
//!  Inputs:      
//!               - dev_type - device type 
//!
//!  Returns:     
//!               - PROTOCOL_CONNECT_STATE
//!
///////////////////////////////////////////////////////////////////////////////

void SlaveProtocolButtonBind(unsigned char dev_type)
{
    unsigned short bind_retry = 0;
    unsigned char  packet_length;
    PROTOCOL_STATUS status = PROTOCOL_FAILED;

    NotifyStartBind();

    // Enter disconnected state
    connected_state = PROTOCOL_DISCONNECTED;

#ifdef ENCRYPT_TEA
    encrypt_key_received = FALSE;
#endif //ENCRYPT_TEA

    // Initialize tx packet header
    tx_packet.first.byte                = 0;   // clear the packet
    tx_packet.bind_request.hdr.type     = BIND_REQ; 
    tx_packet.bind_request.hdr.dev_type = dev_type; 
    
    // Set the bind pn code
    RadioSetSopPnCode( BIND_PN_CODE );

    // seed the channel algorithm with bind parameters 0,0
    sys_params.network_id.channel = BIND_BASE_CHANNEL;
       
    // Set Zero CRC
    RadioSetCrcSeed(0);
 
    // Set PA setting
    RadioSetPa( BUTTON_BIND_PA );
    
    // Force endstate to idle
    RadioForceState(END_STATE_IDLE);
    
    // send a bind request and wait for response, if no response change
    // the channel and try again
    while(bind_retry < BIND_RETRY_COUNT)
    {   
        bind_retry++;
        
        M8C_ClearWDTAndSleep;

        RadioSetChannel( sys_params.network_id.channel );

        if( RadioSendPacket(BIND_REQ_RETRIES, BIND_REQ_LEN) )
        {
            // If a ACK is received, it will take 50ms to wait for a packet.
            // It roughly equals to 32 cycles (1.56ms per cycle). 
            bind_retry += 32;
            
            packet_length = RadioReceivePacket();

            if( packet_length == BIND_RESP_LEN &&
                rx_packet.bind_response.hdr.type == BIND_RESP )
            {
                // extract Bridge MID from bind response packet 
                sys_params.bridge_mid.mid_1 = rx_packet.bind_response.mid_1;
                sys_params.bridge_mid.mid_2 = rx_packet.bind_response.mid_2;
                sys_params.bridge_mid.mid_3 = rx_packet.bind_response.mid_3;
                sys_params.bridge_mid.mid_4 = rx_packet.bind_response.mid_4;

                sys_params.bridge_mid.signature   = SIGNATURE_BYTE;

                // exit loop with success
                status = PROTOCOL_SUCCESS;

                break;
            }                
        }

        RadioGetNextChannel();

        if((bind_retry & 0x00FF) == 0x0080)
            NotifyContinueBind();
    }
    
    // Force endstate to sleep
    RadioForceState(END_STATE_SLEEP);
    
    // Restore PA setting to default state
    RadioSetPa( DATA_MODE_PA );
    
    if( status == PROTOCOL_SUCCESS )
    {
        StoreSystemParameters();

        RadioCalculateNetworkId();
        // set CRC
        RadioSetNonzeroCrcSeed();
     
        // give the dongle time to ping before trying to reconnect
        TimerDelayMsec( BRIDGE_PING_TIME_MS );
        
        SlaveProtocolReconnect(dev_type);

    }
    else
    {
        // can't Bind, reset to original bind parameters
        SlaveProtocolRetrieveBridgeMid();    

        // Set CRC
        RadioSetNonzeroCrcSeed();
    }
    
    NotifyStopBind();
}

#ifdef KISS_BIND
///////////////////////////////////////////////////////////////////////////////
//
//  Function:    SlaveProtocolKissBind
//
//!  Description: Kiss bind 
//!
//!  Inputs:      Void
//!
//!  Returns:     Void
//!
///////////////////////////////////////////////////////////////////////////////


static void SlaveProtocolKissBind(unsigned char dev_type)
{
    unsigned char  status = PROTOCOL_FAILED;
    unsigned char  packet_length;
    unsigned char  pncode;
    unsigned char  channel;
   

    connected_state = PROTOCOL_DISCONNECTED;

#ifdef ENCRYPT_TEA
    encrypt_key_received = FALSE;
#endif //ENCRYPT_TEA

    // Set BIND PA on the radio
    RadioSetPa( KISS_BIND_PA );

    // Force endstate to idle
    RadioForceState(END_STATE_IDLE);

    // Set Zero CRC
    RadioSetCrcSeed(0);

    for( pncode = 0; pncode < NUM_PN_CODES; pncode++)
    { 
        // build the Kiss Bind Request Packet
        tx_packet.first.byte                = 0;   // clear the packet
        tx_packet.bind_request.hdr.type     = KISS_BIND_REQ; 
        tx_packet.bind_request.hdr.dev_type = dev_type; 

        RadioSetSopPnCode( pncode );

        for(channel = 0; channel < NUM_CHANNELS; channel++)
        {
            M8C_ClearWDTAndSleep;

            RadioSetChannel( channel );

            if( RadioSendPacket(KISS_BIND_REQ_RETRIES, KISS_BIND_REQ_LEN) )
            {
                packet_length = RadioReceivePacket();

                if((packet_length == BIND_RESP_LEN) && 
                   (rx_packet.bind_response.hdr.type == KISS_BIND_RESP) &&
                   (rx_packet.bind_response.hdr.dev_type  == dev_type))
                {
// In order to use RSSI_QUALIFY, the Master side MUST define PROMISCUOUS_MODE
#if (defined RSSI_QUALIFY && defined PROMISCUOUS_MODE)
                    if((RadioGetRxRssi() >= KISS_BIND_RSSI_THRESHOLD))
#endif //defined RSSI_QUALIFY && defined PROMISCUOUS_MODE
                    {
                        // Copy radio MID from receive packet
                        sys_params.bridge_mid.mid_1 = rx_packet.bind_response.mid_1;
                        sys_params.bridge_mid.mid_2 = rx_packet.bind_response.mid_2;
                        sys_params.bridge_mid.mid_3 = rx_packet.bind_response.mid_3;
                        sys_params.bridge_mid.mid_4 = rx_packet.bind_response.mid_4;
                        
                        sys_params.bridge_mid.signature   = SIGNATURE_BYTE;

                        status = PROTOCOL_SUCCESS;
                        break;
                    }
                }                
            }
        }

        if( status == PROTOCOL_SUCCESS )
        {
            StoreSystemParameters();

            RadioCalculateNetworkId();
            sys_params.network_id.channel = channel;
            break;
        }        
    }

    // Force endstate to sleep
    RadioForceState(END_STATE_SLEEP);

    // Restore default PA
    RadioSetPa( DATA_MODE_PA );    

    // Set CRC
    RadioSetNonzeroCrcSeed();

}

///////////////////////////////////////////////////////////////////////////////
//
//  Function:    SlaveProtocolUnbind
//
//!  Description: Unbind the device from the bridge by writting invalid signature 
//!               into the flash.
//!
//!  Inputs:      Void
//!
//!  Returns:     Void
//!
///////////////////////////////////////////////////////////////////////////////

void SlaveProtocolUnbind(void)
{
    // Enter disconnected state
    connected_state = PROTOCOL_DISCONNECTED;
    
    sys_params.bridge_mid.signature = 0;
    StoreSystemParameters();
    
    //loop here indefinately.
    while(1)
    {
        //Clear Watchdog and Sleep
        M8C_ClearWDTAndSleep;
        
        // Once this state is entered, it does not exit until the
        // batteries are changed.
        M8C_Sleep;
    }
}
#endif // KISS_BIND

///////////////////////////////////////////////////////////////////////////////
//
//  Function:    SlaveProtocolGetTxPkt
//
//!  Description: returns the pointer to the application packet. 
//!
//!  Inputs:      Void
//!
//!  Returns:     Void
//!
///////////////////////////////////////////////////////////////////////////////

void *SlaveProtocolGetTxPkt(void)
{
    return tx_packet.data.payload;
}


///////////////////////////////////////////////////////////////////////////////
//
//   Function:    SlaveProtocolSendPacket
//
//!  Description: Sends packet to the bridge if the device is connected to this  
//!               brige. Otherwise, connects to this brige first. 
//!
//!  Inputs:      
//!               - dev_type - device type
//!               - data_length - data length
//!
//!  Returns:     
//!               - PROTOCOL_STATUS
//!
///////////////////////////////////////////////////////////////////////////////
PROTOCOL_STATUS SlaveProtocolSendPacket(  unsigned char dev_type 
                                         ,unsigned char data_dev_type 
                                         ,unsigned char data_length 

#ifdef BACK_CHANNEL_SUPPORT
                                         ,unsigned char back_channel
#endif //BACK_CHANNEL_SUPPORT
                                         )   

{
    if( connected_state == PROTOCOL_DISCONNECTED )
    {
        SlaveProtocolReconnect(dev_type);

        return PROTOCOL_TX_TIMEOUT;
    }

    tx_packet.first.byte = 0;           // clear the header byte

    if( data_length < PAYLOAD_LENGTH + 1 )
    {
        // setup for a Data Packet and bump the data toggle
        tx_packet.data.hdr.type    = DATA_PACKET;
        tx_packet.data.hdr.data_dev_type  = data_dev_type_swap_table[data_dev_type];
        tx_packet.data.hdr.dt_data = tx_data_toggle;

#ifdef BACK_CHANNEL_SUPPORT
        tx_packet.data.hdr.back_ch_req = back_channel;
#else //BACK_CHANNEL_SUPPORT
        tx_packet.data.hdr.back_ch_req = 0;
#endif //BACK_CHANNEL_SUPPORT
        
        data_length += 1;   // length = header + data
    }
    else
    {
        return( PROTOCOL_FAILED );   
    }
    
#ifdef ENCRYPT_AES  
    EncryptData(data_length);   
    data_length = 16;
#endif //ENCRYPT_AES    

#ifdef BACK_CHANNEL_SUPPORT
    // Force endstate to idle
    RadioForceState(END_STATE_IDLE);
#endif //BACK_CHANNEL_SUPPORT

    if( RadioSendPacket( DATA_PACKET_RETRIES, data_length ) )
    {    
        tx_data_toggle ^= 1;

#ifdef BACK_CHANNEL_SUPPORT

        if( back_channel) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -