?? wdp_host.c
字號:
/* Copyright (c) 2007 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRENTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision: 2290 $
*/
/** @file
*
* Host source file for the Wireless Desktop Protocol.
*
* @author Lasse Olsen
*
*/
#include <stdint.h>
#include <string.h>
#include "wdp_host.h"
/**
Device parameter struct type definition.
*/
typedef struct
{
uint16_t dev_keep_alive_interval;
uint8_t dev_b0_address;
} wdp_dev_params_t;
const wdp_dev_params_t wdp_dev_params[WDP_DEVICE_SUPPORT_SIZE]=
{
{WDP_MOUSE_KA_INTERVAL, WDP_MOUSE_ADR_B0},
{WDP_KEYBOARD_KA_INTERVAL, WDP_KEYBOARD_ADR_B0},
{WDP_REMOTE_KA_INTERVAL, WDP_REMOTE_ADR_B0}
};
typedef struct
{
uint8_t pairing[FAP_ADDRESS_WIDTH];
uint8_t master[FAP_ADDRESS_WIDTH-1];
} wdp_addresses_t;
static wdp_addresses_t wdp_addresses =
{
WDP_PAIRING_ADDRESS,
WDP_INIT_MASTER_ADDRESS
};
/**
WDP status register flag.
*/
#define WDP_EN_ADR_GEN 0
/**
WDP status register flag.
*/
#define WDP_PAIRING_EXECUTED 1
/**
WDP status register flag.
*/
#define WDP_APP_DATA_RDY 2
//*****************************************************************************
// Misc. macros
//*****************************************************************************
#define WDP_GET_BIT(a, b) ((a >> b) & 0x01)
#define WDP_CLEAR_BIT(a, b) (a &= ~(1 << b))
#define WDP_SET_BIT(a, b) (a |= (1 << b))
static xdata uint8_t wdp_status_reg;
static xdata fap_tx_rx_struct_t wdp_rx_struct;
static xdata fap_tx_rx_struct_t wdp_gen_purp_struct;
static xdata uint16_t wdp_device_alive_array[WDP_DEVICE_SUPPORT_SIZE];
static const uint8_t wdp_pairing_ch_tab[FAP_CH_TAB_SIZE] = WDP_PAIRING_CHANNELS;
bool wdp_host_get_rx_data(uint8_t *dst, uint8_t* length, wdp_dev_types_t* origin)
{
if(WDP_GET_BIT(wdp_status_reg, WDP_APP_DATA_RDY))
{
*length = (wdp_rx_struct.pl_length - WDP_APP_PL_START);
*origin = (wdp_dev_types_t) wdp_rx_struct.pipe;
memcpy(dst, &wdp_rx_struct.pl[WDP_APP_PL_START], *length);
WDP_CLEAR_BIT(wdp_status_reg, WDP_APP_DATA_RDY);
return true;
}
else
{
return false;
}
}
void wdp_host_init(void)
{
uint8_t temp_adr;
fap_init();
fap_select_radio_idle_mode(FAP_PDOWN_IDLE);
fap_set_address(FAP_DEVICE0, (uint8_t*) &wdp_addresses.pairing[0]);
temp_adr = WDP_KEYBOARD_ADR_B0;
fap_set_address(FAP_DEVICE2, &temp_adr);
temp_adr = WDP_REMOTE_ADR_B0;
fap_set_address(FAP_DEVICE3, &temp_adr);
WDP_SET_BIT(wdp_status_reg, WDP_EN_ADR_GEN);
WDP_CLEAR_BIT(wdp_status_reg, WDP_PAIRING_EXECUTED);
}
void wdp_host_get_master_adr(uint8_t *adr)
{
memcpy(adr, &wdp_addresses.master[0], (FAP_ADDRESS_WIDTH-1));
}
void wdp_host_enable_random_adr_gen(void)
{
WDP_SET_BIT(wdp_status_reg, WDP_EN_ADR_GEN);
}
bool wdp_host_set_master_adr(uint8_t *adr)
{
if(fap_get_mode() == FAP_IDLE)
{
memcpy(&wdp_addresses.master[0], adr, (FAP_ADDRESS_WIDTH-1));
wdp_gen_purp_struct.pl[0] = wdp_dev_params[0].dev_b0_address;
memcpy(&wdp_gen_purp_struct.pl[1], adr, (FAP_ADDRESS_WIDTH-1));
WDP_CLEAR_BIT(wdp_status_reg, WDP_EN_ADR_GEN);
fap_set_address(FAP_DEVICE1, &wdp_gen_purp_struct.pl[0]);
return true;
}
else
{
return false;
}
}
void wdp_host_rx_setup(wdp_rx_setup_t setup)
{
fap_goto_idle_mode();
fap_flush_rx_fifo();
fap_flush_tx_fifo();
if(setup == WDP_RX_PAIRING)
{
WDP_CLEAR_BIT(wdp_status_reg, WDP_PAIRING_EXECUTED);
// Setup pairing receive channels
fap_set_channels(wdp_pairing_ch_tab);
// Note: Pipe 0 (pairing) address setup by wdp_host_init()
fap_rx_data( (uint8_t) setup, 0);
}
else
if(setup == WDP_RX_NORMAL)
{
// Setup receive channels
wdp_extract_channels(wdp_addresses.master[0], &wdp_gen_purp_struct.pl[0]);
fap_set_channels(&wdp_gen_purp_struct.pl[0]);
// Setup pipe 1 address (master)
wdp_gen_purp_struct.pl[0] = wdp_dev_params[0].dev_b0_address; // Mouse address on pipe 1
memcpy(&wdp_gen_purp_struct.pl[1], &wdp_addresses.master[0], FAP_ADDRESS_WIDTH -1);
fap_set_address(FAP_DEVICE1, &wdp_gen_purp_struct.pl[0]);
fap_rx_data( (uint8_t) setup, 0);
}
else
if(setup == WDP_RX_SUSPEND)
{
fap_rx_data( (uint8_t) setup, FAP_RX_SINGLE_CH_REV);
}
}
bool wdp_host_get_clear_pairing_result(void)
{
bool retbit;
retbit = WDP_GET_BIT(wdp_status_reg, WDP_PAIRING_EXECUTED);
WDP_CLEAR_BIT(wdp_status_reg, WDP_PAIRING_EXECUTED);
return retbit;
}
bool wdp_host_process_events(void)
{
uint8_t temp_dev_index;
// Random address counter
if(WDP_GET_BIT(wdp_status_reg, WDP_EN_ADR_GEN))
{
(*((uint16_t*)(&wdp_addresses.master[2]))) += 4;
(*((uint16_t*)(&wdp_addresses.master[0])))++;
}
// Check if received data
if(fap_read_rx_fifo(&wdp_rx_struct))
{
WDP_CLEAR_BIT(wdp_status_reg, WDP_APP_DATA_RDY);
if(wdp_rx_struct.pipe == WDP_PAIRING_PIPE)
{
switch(wdp_rx_struct.pl[WDP_TYPE_ID])
{
case PAIRING_REQ:
temp_dev_index = wdp_rx_struct.pl[DEV_TYPE] - 1;
if(!(temp_dev_index < WDP_DEVICE_SUPPORT_SIZE))
{
break;
}
WDP_CLEAR_BIT(wdp_status_reg, WDP_EN_ADR_GEN); // Stop address generator
// Assemble pairing return payload
wdp_gen_purp_struct.pl[WDP_TYPE_ID] = PAIRING_RESP;
wdp_gen_purp_struct.pl[DEV_TYPE] = wdp_rx_struct.pl[DEV_TYPE];
wdp_gen_purp_struct.pl[ADDRESS_B0] = wdp_dev_params[temp_dev_index].dev_b0_address;
memcpy(&wdp_gen_purp_struct.pl[MASTER_ADDRESS_START], wdp_addresses.master, FAP_ADDRESS_WIDTH -1 );
wdp_gen_purp_struct.pipe = WDP_PAIRING_PIPE;
wdp_gen_purp_struct.pl_length = WDP_PAIRING_PL_LENGTH;
// Write pairing return payload to downlink buffer (ack payload)
fap_write_ack_pload(&wdp_gen_purp_struct);
break;
case PAIRING_COMPL:
WDP_SET_BIT(wdp_status_reg, WDP_PAIRING_EXECUTED);
break;
default:
break;
}
}
else
{
temp_dev_index = wdp_rx_struct.pipe - 1;
if(temp_dev_index < WDP_DEVICE_SUPPORT_SIZE) // If data received on device address (not pairing address)
{
wdp_device_alive_array[temp_dev_index]= wdp_dev_params[temp_dev_index].dev_keep_alive_interval*2;
}
switch(wdp_rx_struct.pl[WDP_TYPE_ID])
{
case KEEP_ALIVE:
break;
case USER_DATA:
WDP_SET_BIT(wdp_status_reg, WDP_APP_DATA_RDY);
break;
default:
break;
}
}
return true;
}
return false;
}
void wdp_timer_isr_function(void)
{
uint8_t index;
for(index=0; index<WDP_DEVICE_SUPPORT_SIZE; index++)
{
if(wdp_device_alive_array[index]>1) // Stops at 1 when going from connect to disconnect
{
wdp_device_alive_array[index]--;
}
}
return;
}
bool wdp_host_write_downlink_data(wdp_dev_types_t dev_type, uint8_t *src, uint8_t length)
{
if(!(length > WDP_MAX_DL_PL_LENGTH))
{
memcpy(&wdp_gen_purp_struct.pl[0], src, length);
wdp_gen_purp_struct.pipe = dev_type;
wdp_gen_purp_struct.pl_length = length;
return fap_write_ack_pload(&wdp_gen_purp_struct);
}
else
{
return false;
}
}
bool wdp_host_get_connection_status(wdp_dev_types_t dev_type)
{
if(wdp_device_alive_array[dev_type-1] == 1)
{
wdp_device_alive_array[dev_type-1] = 0;
return false;
}
else
{
return true;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -