📄 main.c
字号:
/* Copyright (c) 2007 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is confidential property of
* Nordic Semiconductor. The use, copying, transfer or disclosure
* of such information is prohibited except by express written
* agreement with Nordic Semiconductor.
*/
/** @file
*
* Application for PS2 Keyboard and Mouse using the nRF basic feature board.
*
* @author Lasse Olsen
*
*/
#include "app_ps2.h"
#include "wdp_device.h"
#include "mcu_f320.h"
#include "l01_bfb.h"
#include "circle_test.h"
#include <string.h>
#define APP_MOUSE_POLL_PERIOD (8000/FAP_RX_PERIOD) // Poll mouse every 8 ms
extern volatile uint16_t timer_cnt; // Global timer variable
typedef enum
{
NO_DATA_RDY,
SYNC_DATA_RDY,
UNSYNC_DATA_RDY
} tx_buf_states_t;
void main(void)
{
tx_buf_states_t tx_buf_state = NO_DATA_RDY; // TX buffer status variable
uint8_t buttons, dev_type, tx_pl_length, rx_pl_length;
uint16_t tries=0, packages=0, rx_pack=0; // For communication monitoring
xdata int8_t tx_buf[WDP_MAX_UL_PL_LENGTH]; // Transmit (uplink) data buffer
xdata int8_t rx_buf[WDP_MAX_DL_PL_LENGTH]; // Receive (downlink) data buffer
system_init(); // MCU initialization
LED1_OFF();
LED2_OFF();
LED3_OFF();
LED4_OFF();
//-----------------------------------------------------------------------------
// Init PS2 device and modify device setup based on ps2 device type.
// This code is for the PS2 demo only and should be removed in a "real" device
// application.
//-----------------------------------------------------------------------------
buttons = app_ps2_init(); // "Borrows" buttons variable
if(buttons == PS2_MOUSE_STANDARD) // If PS2 mouse connected
{
LED2_OFF();
LED1_ON(); // LED1 ON if mouse
dev_type = WDP_MOUSE;
tx_pl_length = APP_MOUSE_PL_LENGTH;
wdp_device_init(WDP_MOUSE); // Protocol initialize as mouse
}
else
if(buttons == PS2_KEYBOARD)
{
EX1 = 1; // Use PS2 interrupt if keyboard
IE1 = 0; // Clear PS2 interrupt flag
LED2_ON(); // LED2 ON if keyboard
LED1_OFF();
dev_type = WDP_KEYBOARD;
tx_pl_length = APP_KEYBOARD_PL_LENGTH;
wdp_device_init(WDP_KEYBOARD); // Protocol initialize as keyboard
}
else
{ // No PS2 device connected!
LED1_OFF();
LED2_OFF();
while(1);
}
wdp_select_radio_idle_mode(WDP_STANDBY_IDLE); // Radio in IDLE between transmissions for minimum latency
// Clear TX and RX buffer
for(buttons = 0; buttons < WDP_MAX_DL_PL_LENGTH; buttons++)
{
rx_buf[buttons] = tx_buf[buttons] = 0;
}
GLOBAL_INT_ENABLE();
//-----------------------------------------------------------------------------
// Main application
//-----------------------------------------------------------------------------
while(1)
{
wdp_device_process_events(); // Maintains continuous link if activated
if(!wdp_device_connected()) // Check if continuous link activated
{
wdp_device_connect(); // Set up continuous link if not activated
}
if(!SW1) // If SW1 pressed -> draw circle
{
/* Assemble new mouse data every 8 ms. Accumulates with previous packet if
ongoing tranmission not completed */
if(dev_type == WDP_MOUSE && timer_cnt >= APP_MOUSE_POLL_PERIOD)
{
timer_cnt = 0;
tx_pl_length = APP_MOUSE_PL_LENGTH;
tx_buf[APP_CMD]=APP_USER_INPUT;
circle_test_get(&tx_buf[APP_MOUSE_X_DISP]);
tx_buf[APP_MOUSE_BUTTONS] = 0x09; // Left mouse button pressed
tx_buf_state = SYNC_DATA_RDY; // Indicates new data, protocol sync OK
wdp_device_ch_sync_enable(); // Synchronize new transmission to receive channel rotation
}
}
else
if(!SW2) // If SW2 pressed -> request return data in payload
{
tx_buf[APP_CMD]=APP_GET_REQUEST; // Send data request command
tx_buf_state = UNSYNC_DATA_RDY; // Indicates new data, do not use synchronization
tx_pl_length = 1;
wdp_device_ch_sync_disable(); // Not synchronized. New transmission will start immediately after issuing wdp_send_data()
}
else
if(dev_type == WDP_MOUSE && timer_cnt >= APP_MOUSE_POLL_PERIOD) // Poll PS2 mouse every 8 ms
{
timer_cnt = 0; // Reset global timing variable
tx_pl_length = APP_MOUSE_PL_LENGTH;
/*
If SW2 not pressed -> aquire mouse data from PS2 interface.
Note, this causes protocol sync to be lost due to disabling of
WDP interrupts during PS2 communication. Thus, the WDP synchronization
mechanisms cannot be used when transmitting this data.
*/
GLOBAL_INT_DISABLE();
tx_buf[APP_CMD]=APP_USER_INPUT; // Assemble TX packet
ps2_write(PS2_READ_DATA_NO_RET); // Send PS2 "read data" command to mouse
buttons = ps2_read();
tx_buf[APP_MOUSE_X_DISP] += ps2_read(); // Assemble TX packet
tx_buf[APP_MOUSE_Y_DISP] += -ps2_read(); // Assemble TX packet
tx_buf[APP_MOUSE_Z_DISP] = 0; // Assemble TX packet
GLOBAL_INT_ENABLE();
// If mouse movement or buttons altered
if(tx_buf[APP_MOUSE_X_DISP] || tx_buf[APP_MOUSE_Y_DISP] || (tx_buf[APP_MOUSE_BUTTONS] != buttons))
{
tx_buf[APP_MOUSE_BUTTONS] = buttons;
tx_buf_state = UNSYNC_DATA_RDY; // Indicates new data, protocol out of sync
wdp_device_ch_sync_disable();
}
}
else // If PS2 keyboard connected, check for new keyboard data
if(dev_type == WDP_KEYBOARD && wdp_get_mode() == WDP_IDLE)
{
if(app_ps2_get_and_convert(tx_buf))
{
tx_pl_length = APP_KEYBOARD_PL_LENGTH;
tx_buf_state = UNSYNC_DATA_RDY; // Indicates new data, protocol out of sync
wdp_device_ch_sync_disable();
}
}
//-----------------------------------------------------------------------------
// Transmit mouse/keyboard data
//-----------------------------------------------------------------------------
/*
For "circle test" data, transmission is started using
synchronization to the previous good channel.
*/
if(wdp_get_mode() == WDP_IDLE)
{
if(((tx_buf_state == SYNC_DATA_RDY) && (wdp_device_get_ch_offset()==0)) || (tx_buf_state == UNSYNC_DATA_RDY))
{
tries += wdp_device_get_tries(); // Counts the number of sent payloads including retransmits
packages++; // Counts the number sent data packages excluding retransmits
if(!wdp_device_tx_success())
{
wdp_device_request_pairing(); // Send pairing request whenever previous transmission failed
}
wdp_device_send_data(tx_buf, tx_pl_length); // Transmit data
/*
Assumes that data transmission will succeed, thus clears tx buffer. This assumption is plausible
as the transmission essentially never fails, but only experiences latency if poor radio conditions.
*/
if(dev_type == WDP_MOUSE)
{
tx_buf[APP_MOUSE_X_DISP] = 0;
tx_buf[APP_MOUSE_Y_DISP] = 0;
tx_buf[APP_MOUSE_Z_DISP] = 0;
}
tx_buf_state = NO_DATA_RDY; // Indicates no unsent data
}
}
//-----------------------------------------------------------------------------
// Downlink data from host to device
//-----------------------------------------------------------------------------
if(wdp_device_get_downlink_data(rx_buf, &rx_pl_length))
{
rx_pack++;
if(!(rx_pack % (50000/(WDP_MAX_DL_PL_LENGTH*8))))
{
LED4_TOGGLE();
} // Toggle LED4 for every 50 kb of received data
}
} // End while()
} // End main()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -