📄 main.c
字号:
#include "cc2511_app_ex_lib_headers.h"
#include "cc2511_usb_library_headers.h"
#include "winamp_remote_control.h"
#define MY_DEVICE_ADDR 0x01
#define NETWORK_ADDR_0 0x10
#define NETWORK_ADDR_1 0x11
#define NETWORK_ADDR_2 0x12
#define REMOTE_UNIT_DEVICE_ADDR 0x02
WINAMP_DISPLAY_DATA __xdata waDispData;
BYTE __xdata txPacket[213];
RF_PACKET __xdata * pRfDispPacket = (RF_PACKET __xdata *) txPacket;
BOOL __xdata waDispDataValid;
REMOTE_CONTROL_DATA __xdata rcData;
extern TIME_DATA __xdata timeData;
BYTE refreshSequenceNr;
void main(void) {
WINAMP_CONTROL_DATA __xdata *pWaCtrlData;
P0DIR |= 0x03;
fifoInit();
timeInit();
rfudInit(11);
rfudSetMyAddress(NETWORK_ADDR_0, NETWORK_ADDR_1, NETWORK_ADDR_2 , MY_DEVICE_ADDR);
usbfwInit();
waDispDataValid = FALSE;
refreshSequenceNr = 0;
usbirqInit(USBIRQ_EVENT_RESET | USBIRQ_EVENT_SETUP);
INT_GLOBAL_ENABLE(INT_ON);
while (TRUE) {
//handle USB reset.
if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_RESET) {
usbfwResetHandler();
USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESET);
}
// Handle USB packets on EP0
if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SETUP) {
usbfwSetupHandler();
USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SETUP);
}
// Handle USB suspend
if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SUSPEND) {
USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SUSPEND);// Clear USB suspend interrupt
rfudStopRadio(); // turn off the radio
usbsuspEnter();// calling this function will take the chip into PM1 until a USB resume is deteceted.
USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESUME); // Clear USB resume interrupt.
}
// Handle incoming display data
if (usbReadDisplayData()) {
rcData.gotFirstWaDispData = TRUE;
timeSyncToWinamp();
}
// Handle outgoing control data
if (fifoGetUsedSlots(0)) {
pWaCtrlData = (WINAMP_CONTROL_DATA __xdata *) (((RF_PACKET __xdata *) fifoStartDequeue(0))->data);
if (usbWriteControlData(pWaCtrlData)) {
fifoFinishedDequeue(0);
}
}
//Radio related
//Radio does not have a RX buffer and we have a buffer ready.
if(rfudRxBufferNeeded() && fifoGetFreeSlots(0))
{
//Give the rfud module a RX buffer so the radio can go to RX.
rfudStartReceive((RF_PACKET __xdata *) fifoStartEnqueue(0));
}
}
}
BOOL usbReadDisplayData(void) {
static UINT8 __xdata position = 0;
BOOL result = FALSE;
UINT8 count;
BYTE critSect = utilEnterCriticalSection();
USBFW_SELECT_ENDPOINT(REMOTE_DISPLAY_EP);
if (USBFW_OUT_ENDPOINT_DISARMED()) {
count = USBFW_GET_OUT_ENDPOINT_COUNT();
if (count) {
usbfwReadFifo(REMOTE_DISPLAY_FIFO, count, ((BYTE __xdata*) &waDispData) + position);
USBFW_ARM_OUT_ENDPOINT();
position += count;
if (position && (position == waDispData.totalLength)) {
position = 0;
refreshSequenceNr++;
if(refreshSequenceNr > 0x0F) { refreshSequenceNr = 1; }
waDispData.refresh &= ~WDD_REFRESH_SEQUENCE_NR;
waDispData.refresh |= (refreshSequenceNr << 4);
result = TRUE;
}
} else {
USBFW_ARM_OUT_ENDPOINT();
}
waDispDataValid = (position == 0);
}
utilLeaveCriticalSection(critSect);
return result;
}
BOOL usbWriteControlData(WINAMP_CONTROL_DATA __xdata *pWaCtrlData) {
BOOL result = FALSE;
BYTE critSect = utilEnterCriticalSection();
USBFW_SELECT_ENDPOINT(REMOTE_CONTROL_EP);
if (USBFW_IN_ENDPOINT_DISARMED()) {
usbfwWriteFifo(REMOTE_CONTROL_FIFO, sizeof(WINAMP_CONTROL_DATA), (BYTE __xdata*) pWaCtrlData);
USBFW_ARM_IN_ENDPOINT();
result = TRUE;
}
utilLeaveCriticalSection(critSect);
return result;
}
// ****************************************************************************************
// All Hooks and functions required by the RF library.
// ****************************************************************************************
BYTE rfudHookBindRequest(BYTE preferredAddress) {
//We accept all bind requests and assign address 0x14
return REMOTE_UNIT_DEVICE_ADDR;
}
BOOL rfudHookAckPkt(BYTE sourceAddress, BYTE __xdata * ackPktflag){
//if packet is from address 0x14 we send ack
if(sourceAddress == REMOTE_UNIT_DEVICE_ADDR) { return TRUE; }
else { return FALSE; }
}
RF_PACKET __xdata * rfudHookDataPktRequest(BYTE sourceAddress) {
BYTE i;
BYTE critSect;
if(waDispDataValid)//if display data have been received from the PC
{
critSect = utilEnterCriticalSection();
pRfDispPacket->length = waDispData.totalLength + 6;//length of RF packet
pRfDispPacket->flag = 0; //no ack
//copy data to RF packet
for(i = 0; i < waDispData.totalLength; i++)
{
pRfDispPacket->data[i] = ((BYTE __xdata *) &waDispData)[i];
}
//Get latest time data from time_handler.c
((WINAMP_DISPLAY_DATA __xdata *) &pRfDispPacket->data)->minutes = timeData.minutes;
((WINAMP_DISPLAY_DATA __xdata *) pRfDispPacket->data)->seconds = timeData.seconds;
((WINAMP_DISPLAY_DATA __xdata *) &pRfDispPacket->data)->milliseconds = timeData.milliseconds;
utilLeaveCriticalSection(critSect);
return pRfDispPacket;
}
else
{
return NULL;
}
}
void rfudHookRfEvent(BYTE rfEvent, BYTE eventData){
switch (rfEvent)
{
case RFUD_EVENT_DATA_PACKET_RECEIVED :
if((eventData == REMOTE_UNIT_DEVICE_ADDR) && (((RF_PACKET __xdata *) fifoStartEnqueue(0))->length == 8))
{//if packet is from address REMOTE_UNIT_DEVICE_ADDR, and have the correct length
fifoFinishedEnqueue(0); //Save packet in the FIFO.
}
break;
case RFUD_EVENT_ACK_RECEIVED ://dont care
break;
case RFUD_EVENT_NACK_RECEIVED ://dont care
break;
case RFUD_EVENT_ACK_TIMEOUT ://dont care
break;
}
}
// ****************************************************************************************
// All Hooks and functions required by the USB library.
// ****************************************************************************************
// **************** Process USB class requests with OUT data phase ************************
void usbcrHookProcessOut(void) { usbfwData.ep0Status = EP_STALL; }
// **************** Process USB class requests with IN data phase *************************
void usbcrHookProcessIn(void) { usbfwData.ep0Status = EP_STALL; }
// ******************************** Unsupported USB hooks ********************************
void usbvrHookProcessOut(void) {usbfwData.ep0Status = EP_STALL; }
void usbvrHookProcessIn(void) {usbfwData.ep0Status = EP_STALL; }
// ************************ unsupported/unhandled standard requests **********************
void usbsrHookSetDescriptor(void) { usbfwData.ep0Status = EP_STALL; }
void usbsrHookSynchFrame(void) { usbfwData.ep0Status = EP_STALL; }
void usbsrHookClearFeature(void) { usbfwData.ep0Status = EP_STALL; }
void usbsrHookSetFeature(void) { usbfwData.ep0Status = EP_STALL; }
void usbsrHookModifyGetStatus(BYTE recipient, BYTE index, WORD __xdata *pStatus) { }
// ************************ USB standard request event processing *************************
void usbsrHookProcessEvent(BYTE event, UINT8 index) {
// Process relevant events, one at a time.
switch (event) {
case USBSR_EVENT_CONFIGURATION_CHANGING : //(the device configuration is about to change)
break;
case USBSR_EVENT_CONFIGURATION_CHANGED :// (the device configuration has changed)
break;
case USBSR_EVENT_INTERFACE_CHANGING ://(the alternate setting of the given interface is about to change)
break;
case USBSR_EVENT_INTERFACE_CHANGED : //(the alternate setting of the given interface has changed)
break;
case USBSR_EVENT_REMOTE_WAKEUP_ENABLED ://(remote wakeup has been enabled by the host)
break;
case USBSR_EVENT_REMOTE_WAKEUP_DISABLED ://(remote wakeup has been disabled by the host)
break;
case USBSR_EVENT_EPIN_STALL_CLEARED ://(the given IN endpoint's stall condition has been cleared the host)
break;
case USBSR_EVENT_EPIN_STALL_SET ://(the given IN endpoint has been stalled by the host)
break;
case USBSR_EVENT_EPOUT_STALL_CLEARED ://(the given OUT endpoint's stall condition has been cleared the host)
break;
case USBSR_EVENT_EPOUT_STALL_SET ://(the given OUT endpoint has been stalled by the PC)
break;
}
}
// ************************ USB interrupt event processing ********************************
void usbirqHookProcessEvents(void) {
// Handle events that require immediate processing here
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -