ti-Chipcon CC251x 2.4G Soc应用开发源码实例。包括rf,powermodes,clockmodes,flashRW,interrupts,timer,pwm,uart...所有

源代码在线查看: chipcon remote control.cpp

软件大小: 1306 K
上传用户: wodn76
关键词: ti-Chipcon powermodes clockmodes interrupts
下载地址: 免注册下载 普通下载 VIP

相关代码

				#include "stdafx.h"
				#include "Chipcon Remote Control.h"
				#include "WinampGen.h"
				#include "WinampIpc.h"
				
				static const GUID WINAMP_REMOTE_GUID = { 0xEFA3F566, 0x6E8C, 0x4CC2, { 0x93, 0xFB, 0x31, 0x3B, 0x1B, 0xA3, 0x4D, 0x9E } };
				
				// Global variables
				HANDLE hRemoteControlThread;
				HANDLE hRemoteDisplayThread;
				HANDLE hDeviceMonitorThread;
				CudalPipe *pControlPipe;
				CudalPipe *pDisplayPipe;
				CudalDongle *pDongle;
				BOOL quitAsap;
				
				
				// Function prototypes
				int waInit(void);
				void waConfig(void);
				void waQuit(void);
				
				
				winampGeneralPurposePlugin plugin = {
					GPPHDR_VER,
					"Chipcon Remote Control", // Description
					waInit,					  // Initialization function
					waConfig,					  // Configuration function
					waQuit					  // Deinitialization function
				};
				
				
				
				
				BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
				    return TRUE;
				}
				
				
				
				
				DWORD WINAPI RemoteDisplayThread(LPVOID lpParameter) {
				    WINAMP_DISPLAY_DATA lastWaDispData;
				    WINAMP_DISPLAY_DATA waDispData;
				    int lastTime = -1;
				    BOOL forceRefresh;
				    memset(&lastWaDispData, 0x00, sizeof(WINAMP_DISPLAY_DATA));
				
				    // Bail out when Winamp tells us to, or die in sympathy for the other thread
				    while (!quitAsap && pControlPipe) {
				
				        // Initialize displayData
				        memset(&waDispData, 0x00, sizeof(WINAMP_DISPLAY_DATA));
				
				        // Get output time
				        int time = WA_GET_PLAY_TIME();
				        if (time != -1) {
				            waDispData.milliseconds = time % 1000;
				            waDispData.seconds = (time / 1000) % 60;
				            waDispData.minutes = time / (1000 * 60);
				
				            // Check output time for changes
				            if ((waDispData.milliseconds != lastWaDispData.milliseconds) ||
				                (waDispData.seconds != lastWaDispData.seconds) ||
				                (waDispData.minutes != lastWaDispData.minutes)) {
				                waDispData.refresh |= WDD_REFRESH_TIME_BM;
				            }
				        }
				
				        // Check the time for significant changes
				        if (time < lastTime) {
				            forceRefresh = TRUE;
				        } else if (time > (lastTime + SIGNIFICANT_TIME_DELTA)) {
				            forceRefresh = TRUE;
				        } else {
				            forceRefresh = FALSE;
				        }
				        lastTime = time;
				        
				        // Get play state
				        waDispData.state = 0x00;
				        if (WA_IS_PLAYING()) {
				            waDispData.state |= WDD_STATE_PLAYING_BM;
				        } else if (WA_IS_PAUSED()) {
				            waDispData.state |= WDD_STATE_PAUSED_BM;
				        }
				
				        // Check player state for changes
				        if ((waDispData.state & (WDD_STATE_PLAYING_BM | WDD_STATE_PAUSED_BM)) != 
				            (lastWaDispData.state & (WDD_STATE_PLAYING_BM | WDD_STATE_PAUSED_BM))) {
				            waDispData.refresh |= WDD_REFRESH_PLAY_STATE_BM;
				        }
				
				        // Get shuffle state
				        if (WA_GET_SHUFFLE()) waDispData.state |= WDD_STATE_SHUFFLE_BM;
				
				        // Check shuffle state for changes
				        if ((waDispData.state & WDD_STATE_SHUFFLE_BM) != (lastWaDispData.state & WDD_STATE_SHUFFLE_BM)) {
				            waDispData.refresh |= WDD_REFRESH_SHUFFLE_STATE_BM;
				        }
				
				        // Get track title
				        int titleLength;
				        if (WA_GET_LIST_LENGTH()) {
				            char *pTitlePtr = WA_GET_LIST_TITLE(WA_GET_LIST_POS());
				            memcpy(waDispData.pTitle, pTitlePtr, min(sizeof(waDispData.pTitle), strlen(pTitlePtr)));
				            titleLength = strlen(pTitlePtr);
				        } else {
				            sprintf(waDispData.pTitle, "- No playlist -");
				            titleLength = strlen(waDispData.pTitle);
				        }
				
				        // Calculate the total length of the display data 
				        waDispData.totalLength = sizeof(waDispData) 
				                               - sizeof(waDispData.pTitle)
				                               + titleLength;
				
				        // Check track title for changes
				        if ((waDispData.totalLength != lastWaDispData.totalLength) ||
				            (memcmp(waDispData.pTitle, lastWaDispData.pTitle, titleLength) != 0)) {
				            waDispData.refresh |= WDD_REFRESH_TITLE_BM;
				        }
				
				        // Send it if there are any relevant changes
				        if ((waDispData.refresh & (WDD_REFRESH_PLAY_STATE_BM | WDD_REFRESH_SHUFFLE_STATE_BM | WDD_REFRESH_TITLE_BM)) || 
				            (forceRefresh)) {
				
				            DWORD length = waDispData.totalLength;
				            switch (pDisplayPipe->WriteSync(&waDispData, &length, 100)) {
				            case USBIO_ERR_SUCCESS:
				            case USBIO_ERR_TIMEOUT:
				                // It's only a success if the transferred length is correct
				                if (length == waDispData.totalLength) break;
				            default:
				                // Fatal error (possibly disconnection)
				                goto error;
				            }
				        }
				
				        memcpy(&lastWaDispData, &waDispData, sizeof(WINAMP_DISPLAY_DATA));
				
				        Sleep(DISPLAY_INTERVAL);
				    }
				error:
				    delete pDisplayPipe;
				    pDisplayPipe = NULL;    
				
				    return 0;
				}
				
				
				
				
				DWORD WINAPI RemoteControlThread(LPVOID lpParameter) {
				    WINAMP_CONTROL_DATA controlData;
				    CudalAsyncInfo asyncInfo;
				    DWORD length;
				
				    // Start polling
				    if (!pControlPipe->ReadAsync(&asyncInfo, &controlData, sizeof(WINAMP_CONTROL_DATA))) {
				        goto error;
				    }
				
				    // Bail out when Winamp tells us to, or die in sympathy for the other thread
				    while (!quitAsap && pDisplayPipe) {
				
				        // Did we get anything?
				        switch (pControlPipe->WaitAsync(&asyncInfo, &length, 100)) {
				        case USBIO_ERR_SUCCESS:
				
				            // Make sure that we got it all...
				            if (length == 2) {
				
				                // When a command is received, perform the corresponding action
				                switch (controlData.command) {
				                case DONGLE_CMD_PREVIOUS_TRACK: WA_CMD_PREVIOUS_TRACK();             break;
				                case DONGLE_CMD_PLAY:           WA_CMD_PLAY();                       break;
				                case DONGLE_CMD_PAUSE:          WA_CMD_PAUSE();                      break;
				                case DONGLE_CMD_STOP:           WA_CMD_STOP();                       break;
				                case DONGLE_CMD_NEXT_TRACK:     WA_CMD_NEXT_TRACK();                 break;
				                case DONGLE_CMD_VOLUMEUP:       WA_CMD_VOLUMEUP();                   break;
				                case DONGLE_CMD_VOLUMEDOWN:     WA_CMD_VOLUMEDOWN();                 break;
				                case DONGLE_CMD_FFWD5S:         WA_CMD_FFWD5S();                     break;
				                case DONGLE_CMD_REW5S:          WA_CMD_REW5S();                      break;
				                case DONGLE_SET_REPEAT:         WA_SET_REPEAT(controlData.value);    break;
				                case DONGLE_SET_SHUFFLE:        WA_SET_SHUFFLE(controlData.value);   break;
				                case DONGLE_SET_VOLUME:         WA_SET_VOLUME(controlData.value);    break;
				                }
				            }
				
				            // Continue polling
				            if (!pControlPipe->ReadAsync(&asyncInfo, &controlData, sizeof(WINAMP_CONTROL_DATA))) {
				                goto error;
				            }
				            break;
				
				        case USBIO_ERR_TIMEOUT:
				            // A timeout does not have any effect
				            break;
				
				        default:
				            // Fatal error (possibly disconnection)
				            goto error;
				        }
				    }
				
				error:
				
				    // Terminate the transfer
				    pControlPipe->AbortAll();
				    pControlPipe->WaitAsyncTermination(&asyncInfo);
				
				    // Delete the control pipe to tell the other threads that we're done
				    delete pControlPipe;
				    pControlPipe = NULL;
				    
				    return 0;
				}
				
				
				
				
				DWORD WINAPI DongleMonitorThread(LPVOID lpParameter) {
				    DWORD dummy;
					
				    
				    // This is sort of the main loop. Leave when the quit signal is given
				    while (!quitAsap) {
				
				        // If the pipes don't exist, then try to find a dongle to connect to
				        if (!pControlPipe && !pDisplayPipe) {
				
				            // Close the old thread handles
				            if (hRemoteControlThread) { 
				                CloseHandle(hRemoteControlThread); 
				                hRemoteControlThread = NULL; 
				            }
				            if (hRemoteDisplayThread) { 
				                CloseHandle(hRemoteDisplayThread); 
				                hRemoteDisplayThread = NULL; 
				            }
				            
				            // Clean up after last rounds
				            if (pDongle) { 
				                delete pDongle; 
				                pDongle = NULL;
				            }
				
				            // Find the correct dongle type
				            CUDAL_DONGLE_INFO pDongleInfo[MAX_DONGLE_ENUM_COUNT];
				            int dongleCount = CudalDongle::EnumDongles(pDongleInfo, MAX_DONGLE_ENUM_COUNT, &WINAMP_REMOTE_GUID);
				            for (int n = 0; n < dongleCount; n++) {
				                if ((pDongleInfo[n].vendorId == CHIPCON_VID) &&
				                    (pDongleInfo[n].productId == WINAMP_REMOTE_CONTROL_PID)) {
				
				                    // If the dongle object could be created, then create the control and display pipes
				                    if (pDongle = CudalDongle::CreateDongle(&pDongleInfo[n], 0, &WINAMP_REMOTE_GUID)) {
				                        pDisplayPipe = pDongle->CreatePipe(REMOTE_DISPLAY_ENDPOINT, FALSE);
				                        pControlPipe = pDongle->CreatePipe(REMOTE_CONTROL_ENDPOINT, TRUE);
				
				                        // When both pipes have been created, the two data transfer threads can be started
				                        if (pDisplayPipe && pControlPipe) {
				                            hRemoteControlThread = CreateThread(NULL, 0, RemoteControlThread, NULL, 0, &dummy);
				                            hRemoteDisplayThread = CreateThread(NULL, 0, RemoteDisplayThread, NULL, 0, &dummy);
											n = dongleCount;//stop searching
				                        
				                        // If not, then destroy everything
				                        } else {
				                            if (pDisplayPipe) { delete pDisplayPipe; pDisplayPipe = NULL; }
				                            if (pControlPipe) { delete pControlPipe; pControlPipe = NULL; }
				                            if (pDongle) { delete pDongle; pDongle = NULL; }
				                        }
				                    }
				                }
				            }
				        }
				
				        // Reduce activity
				        for (int s = 0; s < 10; s++) {
				            if (!quitAsap) {
				                Sleep(MONITOR_INTERVAL / 10);
				            }
				        }
				    }
				
				    // Wait for the other threads to quit before destroying the dongle object
				    if (hRemoteControlThread) {
				        WaitForSingleObject(hRemoteControlThread, 5000);
				        CloseHandle(hRemoteControlThread);
				    }
				    if (hRemoteDisplayThread) {
				        WaitForSingleObject(hRemoteDisplayThread, 5000);
				        CloseHandle(hRemoteDisplayThread);
				    }
				    if (pDongle) delete pDongle;
				
				    return 0;
				}
				
				
				
				
				int waInit(void) {
				    DWORD dummy;
				    
				    // Reset relevant globals
				    hRemoteControlThread = 0;
				    hRemoteDisplayThread = 0;
				    pControlPipe = NULL;
				    pDisplayPipe = NULL;
				    pDongle = NULL;
				    quitAsap = FALSE;
				
				    // Start the monitoring thread, which discovers a dongle and initializes it
				    hDeviceMonitorThread = CreateThread(NULL, 0, DongleMonitorThread, NULL, 0, &dummy);
				    return 0;
				}
				
				
				
				
				void waConfig(void) { 
				    MessageBox(plugin.hwndParent, 
				               "This plug-in demonstrates the Chipcon USB Dongle Access Library\n"
				               "(CUDAL). Download \"winamp_remote.hex\" into a CC2510 on a\n"
				               "SmartRF04EB, and \"winamp_dongle.hex\" into the CC2511 dongle.\n"
				               "The plug-in will detect and attach to the first unused remote\n"
				               "control that it finds. The dongle safely be removed at any time\n"
				               "and re-connected later on.", 
				               "Chipcon Remote Control",
				               MB_OK | MB_ICONINFORMATION);
				}
				
				
				
				
				void waQuit(void) {   
				    quitAsap = TRUE;
				    WaitForSingleObject(hDeviceMonitorThread, INFINITE);
				    CloseHandle(hDeviceMonitorThread);
				}
				
				
				
				extern "C" {
				    __declspec(dllexport) winampGeneralPurposePlugin *winampGetGeneralPurposePlugin(void) { 
					    return &plugin;
				    }
				}
							

相关资源