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

📄 main.c

📁 reference about wireless design which is helpful to everyone
💻 C
字号:
#include "cc2511_app_ex_lib_headers.h"
#include "RF04EB.h"
#include "lcd.h"
#include "select_uart_settings.h"



#define UART_TO_RADIO_BUFFER     0
#define RADIO_TO_UART_BUFFER     1

#define RF_BUFFER_SIZE              137

#define MAX_DATA_BYTES           ((RF_BUFFER_SIZE - HEADER_LENGTH) - CRC_LENGTH)
#define MAX_LENGTH_BYTE          (RF_BUFFER_SIZE - 3)

#define UART_RX_TIMEOUT          10
#define SW_RTS                P0_5
#define SW_CTS                P0_4
#define UART_FLOW_CTRL_STOP      1
#define UART_FLOW_CTRL_GO        0

#define UART_TX_BUFFER_EMPTY              0x01
#define UART_TX_STOPED_BY_FLOW_CTRL       0x02

//uartToRadioBufStatus
#define U_TO_R_BUF_STOPED                  0x01
#define U_TO_R_BUF_STOPPED_BY_UART_ISR     0x02
#define U_TO_R_BUF_STOPPED_BY_T4_ISR       0x04

char __code const lcdBindText[16] = {'P', 'u', 's', 'h', ' ', 'S', '1', ' ', 't', 'o', ' ', 'b', 'i', 'n', 'd', ' '};
char __code const lcdBindOkText[16] = {'D', 'e', 'v', 'i', 'c', 'e', ' ', 'C', 'o', 'n', 'n', 'c', 't', 'e', 'd', ' '};



void dataRequestTimeoutCallBack(void);
void uartRxTimeoutCallBack(void);


BOOL __xdata rfLastPacketDirOut;
BYTE __xdata dongleAddress;
BYTE __xdata uartRxPacketTimeoutIndex;
RF_PACKET __xdata * pUartRxCurrentBuffer;
BYTE __xdata uartRxOverflowDumpByte;
BOOL __xdata uartRxTimeout;
BYTE __xdata * pUartTxData;
BYTE __data uartTxBytesLeft;
BYTE __xdata uartTxStopped;


void main( void )
{
   RF_PACKET __xdata * pTempPacketBuffer;

   fifoInit();
   t4mgrInit(1000);
   initLcd();
   rfruInit(RF_BUFFER_SIZE);


   uartRxPacketTimeoutIndex = t4mgrSetupCallback(T4MGR_SUSPENDED_CALLBACK, uartRxTimeoutCallBack);


   //init variables
   rfLastPacketDirOut = FALSE;
   dongleAddress = 0;
   uartRxTimeout = FALSE;
   uartTxStopped = UART_TX_BUFFER_EMPTY;//signal to main loop to start a UART TX when data arrives

   //when filling the buffer from the UART, the length byte is used, hence we must set it
   //to default (HEADER_LENGTH - 1) in all the buffers.
   while(pTempPacketBuffer = (RF_PACKET __xdata *) fifoStartEnqueue(UART_TO_RADIO_BUFFER)) {
      pTempPacketBuffer->length = (HEADER_LENGTH - 1);
      fifoFinishedEnqueue(UART_TO_RADIO_BUFFER);
   }
   //dequeue all the packets again.
   while(fifoGetUsedSlots(UART_TO_RADIO_BUFFER)) { fifoFinishedDequeue(UART_TO_RADIO_BUFFER); }

   //get pointer to UART rx buffer
   pUartRxCurrentBuffer = (RF_PACKET __xdata *) fifoStartEnqueue(UART_TO_RADIO_BUFFER);
   t4mgrModifyCallback(uartRxPacketTimeoutIndex, UART_RX_TIMEOUT, 0);

   //setup UART
   IP0 = 0x04;//Uart RX and TX interrupt highest priority
   IP1 = 0x04;//Uart RX and TX interrupt highest priority
   selectUartSettings();
   lcdUpdateLine(LINE2,(__xdata char *) &lcdBindText[0]);

   P0DIR |= 0x20; //SW_RTS
   SW_RTS =0;
   U0CSR |= 0x40; //turn on RX
   INT_ENABLE(INUM_URX0, INT_ON);
   INT_ENABLE(INUM_UTX0, INT_ON);


   INT_GLOBAL_ENABLE(TRUE);


   while(1){
      //if radio is ready, and we have a dongleAddress e.g. a successful bind has occurred.
      if(rfruIsRadioReady() && dongleAddress){
         //check if we should send a packet
         if(fifoGetUsedSlots(UART_TO_RADIO_BUFFER) && !rfLastPacketDirOut)
         {
            rfLastPacketDirOut = TRUE;
            pTempPacketBuffer = (RF_PACKET __xdata *) fifoStartDequeue(UART_TO_RADIO_BUFFER);
            //set destAddress and ACK_REQUEST on packet to be sent
            pTempPacketBuffer->destAddress = dongleAddress;

            //set the RF_ACK_REQUEST flag. If we have more than one data packet ready, also set the RF_DATA_PENDING flag
            if(fifoGetUsedSlots(UART_TO_RADIO_BUFFER) > 1) { pTempPacketBuffer->flag = (RF_DATA_PENDING | RF_ACK_REQUEST); }
            else { pTempPacketBuffer->flag = RF_ACK_REQUEST; }
            //send packet
            rfruSendDataPacket(pTempPacketBuffer);
         }
         //send a data request
         else
         {
            rfLastPacketDirOut = FALSE;
            if(fifoGetFreeSlots(RADIO_TO_UART_BUFFER))
            {
               rfruSendDataRequest(dongleAddress, (RF_PACKET __xdata *) fifoStartEnqueue(RADIO_TO_UART_BUFFER));
            }
         }
      }
      if(buttonPushed())
      {
         dongleAddress = 0;
         rfruSendBindRequest(0x35);
         halWait(200);
      }

      //To keep the UART RX interrupt fast and small, some buffer handling
      //and the flow control handling is done here.
      //if running low on buffers, clear RTS
      if(fifoGetFreeSlots(UART_TO_RADIO_BUFFER) <= 2) {
         SW_RTS = UART_FLOW_CTRL_STOP;
      }
      //if enough buffers, set RTS
      if(fifoGetFreeSlots(UART_TO_RADIO_BUFFER) > 3) {
         SW_RTS = UART_FLOW_CTRL_GO;
      }
      //if no UART rx buffer, try to get one
      if(!pUartRxCurrentBuffer) { pUartRxCurrentBuffer = (RF_PACKET __xdata *) fifoStartEnqueue(UART_TO_RADIO_BUFFER); }


      //UART rx timeout
      if(uartRxTimeout)
      {
         uartRxTimeout = FALSE;
         INT_GLOBAL_ENABLE(FALSE);
         if(pUartRxCurrentBuffer)//check if we have a buffer
         {
            //check if we have data in the current buffer;
            if(pUartRxCurrentBuffer->length > (HEADER_LENGTH - 1)){
               fifoFinishedEnqueue(UART_TO_RADIO_BUFFER);
               pUartRxCurrentBuffer = (RF_PACKET __xdata *) fifoStartEnqueue(UART_TO_RADIO_BUFFER);
            }
         }
         INT_GLOBAL_ENABLE(TRUE);
         //restart timeout
         t4mgrModifyCallback(uartRxPacketTimeoutIndex, UART_RX_TIMEOUT, 0);
      }


      //If UART TX has stoppet, see if it can be restarted.
      if(uartTxStopped)
      {
         if(uartTxStopped & UART_TX_BUFFER_EMPTY)
         {
            if(pTempPacketBuffer = (RF_PACKET __xdata *) fifoStartDequeue(RADIO_TO_UART_BUFFER))
            {
               //if a new buffer is ready, restart UART TX
               pUartTxData = (BYTE __xdata *) &pTempPacketBuffer->data[0];
               uartTxBytesLeft = pTempPacketBuffer->length - (HEADER_LENGTH - 1);
               if(uartTxBytesLeft)
               {
                  uartTxStopped &= ~UART_TX_BUFFER_EMPTY;
                  INT_SETFLAG(INUM_UTX0, INT_SET);
               }
               else
               {
                  fifoFinishedDequeue(RADIO_TO_UART_BUFFER);
               }
            }
         }
         else if(uartTxStopped & UART_TX_STOPED_BY_FLOW_CTRL)
         {
            if(SW_CTS == UART_FLOW_CTRL_GO)
            {
               //flow controll say go, restart UART TX
               uartTxStopped &= ~UART_TX_STOPED_BY_FLOW_CTRL;
               INT_SETFLAG(INUM_UTX0, INT_SET);
            }
         }
      }
   }
}

// ****************************************************************************************
// Callback function called from timer4 manager
// ****************************************************************************************
void uartRxTimeoutCallBack(void)
{
   uartRxTimeout = TRUE;
}

// ****************************************************************************************
// All Hooks and functions required by the RF library.
// ****************************************************************************************
void rfruHookRfEvent(BYTE rfEvent, BYTE eventData){
   switch (rfEvent)
   {
   case RFRU_EVENT_DATA_PACKET_RECEIVED :
      //save packet
      fifoFinishedEnqueue(RADIO_TO_UART_BUFFER);
      break;
   case RFRU_EVENT_RETRANSMSSION_RECEIVED :
      //dont care
      break;
   case RFRU_EVENT_ACK_RECEIVED :
         //a packet successfully sent, "clear" the packet by setting the length byte.
         ((RF_PACKET __xdata *) fifoStartDequeue(UART_TO_RADIO_BUFFER))->length = (HEADER_LENGTH - 1);
         fifoFinishedDequeue(UART_TO_RADIO_BUFFER);//finish dequeue
      break;
   case RFRU_EVENT_NACK_RECEIVED :
      //dont care
      break;
   case RFRU_EVENT_DATA_REQUEST_NACKED:
      //dont care
      break;
   case RFRU_EVENT_BIND_SUCCESSFULL :
      //save device address of the dongle.
      dongleAddress = eventData;
      lcdUpdateLine(LINE2,(__xdata char *) &lcdBindOkText[0]);
      break;
   case RFRU_EVENT_ACK_TIMEOUT :
      //dont care
      break;
   case RFRU_EVENT_DATA_PACKET_REQUEST_TIMEOUT:
      //dont care
      break;
   case RFRU_EVENT_BIND_REQUEST_TIMEOUT:
      //dont care
      break;
   }
}

// ****************************************************************************************
// UART RX ISR
// ****************************************************************************************
#pragma vector=URX0_VECTOR
__interrupt void uartRxIrq(void)
{
   //if we have a valid buffer
   if(pUartRxCurrentBuffer)
   {
      //read a byte from UART, and update length byte
      ((BYTE __xdata *) pUartRxCurrentBuffer)[++(pUartRxCurrentBuffer->length)] = U0DBUF;

      //if we dont have room for the next byte in the current buffer.
      if(pUartRxCurrentBuffer->length == MAX_LENGTH_BYTE)
      {
         //this buffer is full, so finish enqueue.
         fifoFinishedEnqueue(UART_TO_RADIO_BUFFER);
         //get next buffer
         pUartRxCurrentBuffer = (RF_PACKET __xdata *) fifoStartEnqueue(UART_TO_RADIO_BUFFER);
         //if we have did not have another buffer ready, pUartRxCurrentBuffer will be 0
         //This will only happen if the device sending data to this unit does not
         //stop when RTS is set, and sends more than MAX_DATA_BYTES bytes in violation of the
         //flow control. If that happens data is dumped until a buffer is ready

         //if we got a new buffer, restart timeout
         if(pUartRxCurrentBuffer) { t4mgrModifyCallback(uartRxPacketTimeoutIndex, UART_RX_TIMEOUT, 0); }
      }
   }
   else
   {
      //the sender is sending data in violation of the flow control, no buffer is available so data is dumped.
      uartRxOverflowDumpByte = U0DBUF;
   }
}

// ****************************************************************************************
// UART TX ISR
// ****************************************************************************************
#pragma vector=UTX0_VECTOR
__interrupt void uartTxIrq(void)
{
   INT_SETFLAG(INUM_UTX0, INT_CLR);
   if(uartTxBytesLeft)
   {
      if(SW_CTS == UART_FLOW_CTRL_GO){
         U0DBUF = *pUartTxData;
         pUartTxData++;
         uartTxBytesLeft--;
         //if buffer is empty, finish dequeue
         if(!uartTxBytesLeft) { fifoFinishedDequeue(RADIO_TO_UART_BUFFER); }
      }else { uartTxStopped = UART_TX_STOPED_BY_FLOW_CTRL; }//signal to main loop that flow controll is set
   }
   else { uartTxStopped = UART_TX_BUFFER_EMPTY; }//signal to main loop that current buffer is sent
}

⌨️ 快捷键说明

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