📄 main.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 + -