📄 main.c
字号:
#include "cc2511_app_ex_lib_headers.h"
#include "winamp_remote_control.h"
#define DONGLE_DEVICE_ADDR 0x01
#define NETWORK_ADDR_0 0x10
#define NETWORK_ADDR_1 0x11
#define NETWORK_ADDR_2 0x12
#define MY_DEVICE_ADDR 0x02
#define RC_SCROLL_TITLE_INTERVAL 300
#define RC_SCROLL_PAD_LENGTH 4
#define CTRL_DATA_FIFO 0
//display data state
#define DDS_IDLE 0
#define DDS_PROCESS 1
#define DDS_RECEIVE 2
//controll data state
#define CDS_IDLE 0
#define CDS_READY 1
#define CDS_TRANSMIT 2
BOOL __xdata waDispDataValid;
REMOTE_CONTROL_DATA __xdata rcData;
WINAMP_DISPLAY_DATA __xdata waDispData;
BYTE __xdata rxPacket[216]; // 207 BYTE WINAMP_DISPLAY_DATA + 9 byte requried by the rf framework
RF_PACKET __xdata * pRfRxPacket = (RF_PACKET __xdata *) rxPacket;
REMOTE_CONTROL_DATA __xdata rcData;
BYTE __xdata txPacket[9];
RF_PACKET __xdata * pRfTxPacket = (RF_PACKET __xdata *) txPacket;
UINT8 rfTxRetryCounter;
BYTE refreshSequenceNr;
BOOL firstPacket;
BYTE lostDataPolls;
BOOL connectedToDongle;
void main(void) {
WINAMP_CONTROL_DATA __xdata *pWaCtrlData;
BYTE i;
fifoInit();
timeInit();
rcInit();
ctrlInit();
rfruInit(216);
firstPacket = TRUE;
connectedToDongle = FALSE;
lostDataPolls = 0;
rfruSetMyAddress(NETWORK_ADDR_0, NETWORK_ADDR_1, NETWORK_ADDR_2, MY_DEVICE_ADDR);
INT_GLOBAL_ENABLE(INT_ON);
refreshSequenceNr = 0;
dispInit();
t4mgrSetupCallback(250, rcPollDispDataCallback);
while (TRUE) {
// Handle incoming display data
if (rcData.dispDataState == DDS_PROCESS) {
//check if it is a new packet, not previously received
if(firstPacket)
{
timeSyncToWinamp(&waDispData);
dispRefreshTime();
dispRefreshState();
dispRefreshShuffle();
rcProcessTitle();
dispRefreshTitle(rcData.scrollPos);
dispRefreshVolume();
firstPacket = FALSE;
}
else if((waDispData.refresh & WDD_REFRESH_SEQUENCE_NR) != (((WINAMP_DISPLAY_DATA __xdata *) pRfRxPacket->data)->refresh & WDD_REFRESH_SEQUENCE_NR))
{
for(i = 0; i < ((WINAMP_DISPLAY_DATA __xdata *) pRfRxPacket->data)->totalLength; i++)
{
((BYTE __xdata *) &waDispData)[i] = pRfRxPacket->data[i];//save the new display data structure
}
// Time recording
timeSyncToWinamp(&waDispData);
// Register which items that need to be refreshed
if (waDispData.refresh & WDD_REFRESH_PLAY_STATE_BM) dispRefreshState();
if (waDispData.refresh & WDD_REFRESH_SHUFFLE_STATE_BM) dispRefreshShuffle();
if (waDispData.refresh & WDD_REFRESH_TIME_BM) dispRefreshTime();
if (waDispData.refresh & WDD_REFRESH_TITLE_BM) { rcProcessTitle(); dispRefreshTitle(rcData.scrollPos); }
}
// Allow for new updates to be received
rcData.dispDataState = DDS_IDLE;
}
if(connectedToDongle)
{
// Do local display updates
if (rcData.refreshTime) { rcData.refreshTime = FALSE; dispRefreshTime(); }
if (rcData.refreshVolume) { rcData.refreshVolume = FALSE; dispRefreshVolume(); }
if (rcData.refreshTitle) { rcData.refreshTitle = FALSE; dispRefreshTitle(rcData.scrollPos); }
}
// Handle outgoing control data
if ((rcData.ctrlDataState == CDS_IDLE) && fifoGetUsedSlots(CTRL_DATA_FIFO)) {
// Add the control data to the TX packet
pWaCtrlData = (WINAMP_CONTROL_DATA __xdata *) fifoStartDequeue(CTRL_DATA_FIFO);
pRfTxPacket->data[0] = pWaCtrlData->command;
pRfTxPacket->data[1] = pWaCtrlData->value;
pRfTxPacket->destAddress = DONGLE_DEVICE_ADDR;
pRfTxPacket->length = 8;
pRfTxPacket->flag = RF_ACK_REQUEST;
// Prepare for transmission
rfTxRetryCounter = 0;
rcData.ctrlDataState = CDS_READY;
}
// Send control data
if (rcData.ctrlDataState == CDS_READY) {
// Retry 10 times before giving up!
if (rfTxRetryCounter > 10) {
fifoFinishedDequeue(CTRL_DATA_FIFO);
rcData.ctrlDataState = CDS_IDLE;
// Do it!
} else if (rfruSendDataPacket(pRfTxPacket)) {
rfTxRetryCounter++;
rcData.ctrlDataState = CDS_TRANSMIT;
}
}
}
} // main
void rcProcessTitle(void) {
UINT8 n;
UINT8 titleLength = waDispData.totalLength - 7;
// Append spaces to fill one LCD line
if (titleLength < LCD_LINE_SIZE) {
rcData.maxScrollPos = 0;
for (n = 0; n < LCD_LINE_SIZE; n++) {
waDispData.pTitle[titleLength + n] = ' ';
}
// Append the start of the text to the end of it so that we can scroll from start to end
} else {
rcData.maxScrollPos = titleLength + RC_SCROLL_PAD_LENGTH - 1;
for (n = 0; n < LCD_LINE_SIZE; n++) {
waDispData.pTitle[titleLength + n] = ' ';
}
for (n = 0; n < LCD_LINE_SIZE; n++) {
waDispData.pTitle[titleLength + RC_SCROLL_PAD_LENGTH + n] = waDispData.pTitle[n];
}
}
rcData.scrollPos = 0;
} // rcProcessTitle
void rcInit(void) {
t4mgrSetupCallback(100, rcScrollTitleCallback);
waDispDataValid = FALSE;
waDispData.state = WDD_STATE_PAUSED_BM;
rcData.gotFirstWaDispData = FALSE;
rcData.refreshTime = TRUE;
rcData.refreshVolume = TRUE;
rcData.refreshState = TRUE;
rcData.refreshTitle = TRUE;
rcData.refreshShuffle = TRUE;
rcData.scrollPos = 0;
rcData.maxScrollPos = 0;
rcData.volume = 0;
rcData.dispDataState = DDS_IDLE;
rcData.ctrlDataState = CDS_IDLE;
} // rcInit
void rcScrollTitleCallback(void) {
static UINT8 n = 0;
if (++n == (RC_SCROLL_TITLE_INTERVAL / 100)) {
n = 0;
if (++rcData.scrollPos >= rcData.maxScrollPos) {
rcData.scrollPos = 0;
}
rcData.refreshTitle = TRUE;
}
} // rcScrollTitleCallback
void rcPollDispDataCallback(void) {
static UINT8 count = 0;
count++;
if(count > 5) {
if (rcData.dispDataState == DDS_IDLE) {
if(rfruSendDataRequest(DONGLE_DEVICE_ADDR, pRfRxPacket))
{
rcData.dispDataState = DDS_RECEIVE;
count = 0;
}
} else {
count = 5; //avoid overflow of the count variable
}
}
} // rcPollWaDispData
// ****************************************************************************************
// Hook required by the RF library.
// ****************************************************************************************
void rfruHookRfEvent(BYTE rfEvent, BYTE eventData){
// Which event?
switch (rfEvent)
{
// ______________ Display data requests _______________:
case RFRU_EVENT_DATA_PACKET_RECEIVED :
rcData.dispDataState = DDS_PROCESS;
lostDataPolls = 0;
connectedToDongle = TRUE;
break;
case RFRU_EVENT_DATA_PACKET_REQUEST_TIMEOUT:
case RFRU_EVENT_DATA_REQUEST_NACKED:
// No new display data, so don't process
rcData.dispDataState = DDS_IDLE;
lostDataPolls++;
if(lostDataPolls == 6)//lost connection with CC2511 USB Dongle
{
connectedToDongle = FALSE;
firstPacket = TRUE;
dispSplashScreen();
}
else if(lostDataPolls > 6) { lostDataPolls = 7; }//avoid that dispDataState wraps around
break;
case RFRU_EVENT_RETRANSMSSION_RECEIVED ://No ack is used on display data so this will not happen
break;
// ______________ Control data transmission _______________:
case RFRU_EVENT_ACK_RECEIVED :
// Success. Pop the command from the FIFO
fifoFinishedDequeue(CTRL_DATA_FIFO);
rcData.ctrlDataState = CDS_IDLE;
break;
case RFRU_EVENT_NACK_RECEIVED :
case RFRU_EVENT_ACK_TIMEOUT :
// The transmission failed, so try again (or abort)
rcData.ctrlDataState = CDS_READY;
break;
// ______________ Binding _______________:
//use a fixed address in this example
case RFRU_EVENT_BIND_REQUEST_TIMEOUT://dont care
break;
case RFRU_EVENT_BIND_SUCCESSFULL ://dont care
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -