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

📄 main.c

📁 reference about wireless design which is helpful to everyone
💻 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 + -