QRSS Rx Network receiver. A receiver to sample a segment of RF spectrum and send this data to a server for further processing and display. NXP mbed Design Challenge entry (Honorable Mention). Published in Circuit Cellar, Feb 2012
Dependencies: NetServices mbed DNSResolver
comms.cpp
- Committer:
- claytong
- Date:
- 2012-01-25
- Revision:
- 0:82ff15078322
File content as of revision 0:82ff15078322:
/*--------------------------------------------------------------------------- QRSS Receiver Application by Clayton ZL3TKA/VK1TKA clayton@isnotcrazy.com Communications Module ---------------------------------------------------------------------------*/ // include files #include "comms.h" // Definitions #define COMMS_DEBUG 0 // Macros // Local Data // Global Data // Function Prototypes //--------------------------------------------------------------------------- // API METHODS //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // // Initialisation Method // void TCommunications::Init() { eState = ST_START_ETH; iBufferCount = 0; PollTimer.start(); CommandTimer.start(); uiTestModeInc = 0; } //--------------------------------------------------------------------------- // // Processing Method // Main state machine // void TCommunications::Poll() { UDPSocketErr udpErr; EthernetErr ethErr; switch ( eState ) { case ST_START_ETH: // Initialise the Ethernet interface EthernetUpLED = 0; RunningLED = 0; ethErr = eth.setup( 25000 ); if ( ethErr == ETH_OK ) { const char * pcHWAddr = eth.getHwAddr(); IpAddr ip = eth.getIp(); printf("mbed MAC Address is %02X-%02X-%02X-%02X-%02X-%02X\r\n", pcHWAddr[0], pcHWAddr[1], pcHWAddr[2], pcHWAddr[3], pcHWAddr[4], pcHWAddr[5] ); printf("mbed IP Address is %d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3] ); } // Set up UDP ServerSocket.setOnEvent( this, &TCommunications::onUDPSocketEvent ); MyPort.setIp( IpAddr() ); MyPort.setPort( QRSS_UDP_PORT ); ServerSocket.bind( MyPort ); udpErr = ServerSocket.bind( MyPort ); if ( udpErr != UDPSOCKET_OK ) { printf("UDP Bind error %d\r\n", udpErr); break; } // to poll state, and force sending of poll message printf("*POLL_SERVER State*\r\n" ); eState = ST_POLL_SERVER; iPPSCount = POLL_MSG_PERIOD; bGotCmnd = false; break; case ST_POLL_SERVER: // Poll the server and wait for it to start the system EthernetUpLED = 1; RunningLED = 0; if ( (iPPSCount>=POLL_MSG_PERIOD) || (PollTimer.read_ms()>POLL_TIMEOUT) ) { // Send a poll message iPPSCount = 0; ServerAddr = dnsService.resolveName( szServerName ); if ( ServerAddr.isNull() ) { printf("DNS Failed - *START_ETH State*\r\n" ); eState = ST_START_ETH; break; } ServerPort.setIp( ServerAddr ); ServerPort.setPort( QRSS_UDP_PORT ); if ( !SendPollMessage() ) { printf("*START_ETH State*\r\n" ); eState = ST_START_ETH; break; } } if ( bGotCmnd ) { bGotCmnd = false; if ( uiCommand!=0 ) { // start uiNCOPhaseInc = uiNCO; uiTestModeInc = uiTestOsc; printf("*RUNNING State*\r\n" ); eState = ST_RUNNING; iBufferCount = 0; CommandTimer.reset(); } } break; case ST_RUNNING: // Running - transfer data to the server EthernetUpLED = 1; RunningLED = 1; if ( (iPPSCount>=POLL_MSG_PERIOD) || (PollTimer.read_ms()>POLL_TIMEOUT) ) { // Send a poll message iPPSCount = 0; if ( !SendPollMessage() ) { printf("*START_ETH State*\r\n" ); eState = ST_START_ETH; break; } } if ( bGotCmnd ) { bGotCmnd = false; CommandTimer.reset(); if ( uiCommand==0 ) { // stop printf("*POLL_SERVER State*\r\n" ); eState = ST_POLL_SERVER; iPPSCount = POLL_MSG_PERIOD; iBufferCount = 0; } } if ( CommandTimer.read_ms()>RUNNING_TIMEOUT ) { printf("Timeout - *POLL_SERVER State*\r\n" ); eState = ST_POLL_SERVER; iPPSCount = POLL_MSG_PERIOD; iBufferCount = 0; } break; } } //--------------------------------------------------------------------------- // // RecordPPSTimestamps Method // Records timestamps of events (1PPS or capture of LO divider) // void TCommunications::RecordPPSTimestamps( uint32_t uiPPSCapture, uint32_t uiLOscCapture, TGPSController::TGPSData &GPSInfo ) { int ii; #if COMMS_DEBUG>0 printf( "PPS-Timestamp:Time %d Count %d PPSCap %u LOCap %u PPS %u LO %u\r\n", LastGPSInfo.iGPSTimeSeconds, iPPSCount, uiPPSCapture, uiLOscCapture, uiPPSCapture-auiPPSCaptures[0], uiLOscCapture-auiLOscCaptures[0] ); #endif // clear the captures if GPS is non-operation if ( GPSInfo.iGPSQuality<=0 ) { // GPS is offline uiPPSCapture = 0; uiLOscCapture = 0; } // shuffle the queue along for ( ii=7; ii>0; ii-- ) { auiPPSCaptures[ii] = auiPPSCaptures[ii-1]; auiLOscCaptures[ii] = auiLOscCaptures[ii-1]; } // record newest data auiPPSCaptures[0] = uiPPSCapture; auiLOscCaptures[0] = uiLOscCapture; LastGPSInfo = GPSInfo; // count event iPPSCount++; } //--------------------------------------------------------------------------- // // Pass sample data for sending. Send when buffer is full // void TCommunications::SendSamples( uint32_t uiTimestamp, TDataSample sSample ) { if ( eState!=ST_RUNNING ) return; if ( iBufferCount==0 ) { // Build buffer header pucBuffDataPtr = (uint8_t *)auiDataBuffer; WriteWord( pucBuffDataPtr, COMM_DATA_MSG, iBufferCount ); WriteWord( pucBuffDataPtr, uiTimestamp, iBufferCount ); } // append data *((TDataSample*)pucBuffDataPtr) = sSample; pucBuffDataPtr += SAMPLE_SET_SIZE; iBufferCount += SAMPLE_SET_SIZE; // send buffer when full if ( iBufferCount>=COMMS_DATABUFF_SIZE ) { // send message int iRet = ServerSocket.sendto( (char *)auiDataBuffer ,iBufferCount, &ServerPort ); if ( iRet!=iBufferCount ) printf("Sent Error - %d\r\n", iRet ); iBufferCount = 0; } } //--------------------------------------------------------------------------- // PRIVATE METHODS //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // // UDP Callback Method // void TCommunications::onUDPSocketEvent( UDPSocketEvent evnt ) { if ( evnt==UDPSOCKET_READABLE ) { uint8_t aucInBf[COMMS_CNTRLBUFF_SIZE]; Host FromHost; int iLen; while ( 1 ) { iLen = ServerSocket.recvfrom( (char *)aucInBf, COMMS_CNTRLBUFF_SIZE, &FromHost ); if ( iLen<=0 ) break; if ( iLen!=COMM_CMND_MSG_LENGTH ) continue; if ( ReadWord(&(aucInBf[0]))!=COMM_CMND_MSG ) continue; if ( ReadWord(&(aucInBf[4]))!=COMM_MSG_VERSION ) continue; // have a real message! uiCommand = ReadWord( &(aucInBf[8]) ); uiNCO = ReadWord( &(aucInBf[12]) ); uiTestOsc = ReadWord( &(aucInBf[16]) ); bGotCmnd = true; #if COMMS_DEBUG>0 printf("Command %d\r\n", uiCommand ); printf("NCO %d\r\n", uiNCO ); printf("Test %d\r\n", uiTestOsc ); #endif } } } //--------------------------------------------------------------------------- // // Send a UDP Poll Message // bool TCommunications::SendPollMessage() { // Build poll message uint8_t aucPollBuffer[150]; uint8_t *pucPtr = aucPollBuffer; int iLen = 0; int iRet; // reset the backup timer PollTimer.reset(); // Build Message WriteWord( pucPtr, COMM_POLL_MSG, iLen ); WriteWord( pucPtr, COMM_MSG_VERSION, iLen ); WriteWord( pucPtr, COMM_MSG_HW_ID, iLen ); WriteWord( pucPtr, COMM_MSG_SW_VERSION, iLen ); WriteWord( pucPtr, LastGPSInfo.iGPSQuality, iLen ); WriteWord( pucPtr, LastGPSInfo.iGPSSatellites, iLen ); WriteWord( pucPtr, LastGPSInfo.iGPSTimeSeconds, iLen ); WriteWord( pucPtr, LastGPSInfo.iGPSLatMicroDegrees, iLen ); WriteWord( pucPtr, LastGPSInfo.iGPSLongMicroDegrees, iLen ); WriteWord( pucPtr, LastGPSInfo.iGPSAltitudeMeters, iLen ); WriteWord( pucPtr, COMM_MSG_REF_CLOCK, iLen ); WriteWord( pucPtr, COMM_MSG_RF_MIXER, iLen ); WriteWord( pucPtr, COMM_MSG_SAMPLE_CLOCK, iLen ); WriteWord( pucPtr, COMM_MSG_SAMPLE_DIVIDER, iLen ); WriteWord( pucPtr, auiPPSCaptures[0], iLen ); WriteWord( pucPtr, auiPPSCaptures[1], iLen ); WriteWord( pucPtr, auiPPSCaptures[2], iLen ); WriteWord( pucPtr, auiPPSCaptures[3], iLen ); WriteWord( pucPtr, auiPPSCaptures[4], iLen ); WriteWord( pucPtr, auiPPSCaptures[5], iLen ); WriteWord( pucPtr, auiPPSCaptures[6], iLen ); WriteWord( pucPtr, auiPPSCaptures[7], iLen ); WriteWord( pucPtr, auiLOscCaptures[0], iLen ); WriteWord( pucPtr, auiLOscCaptures[1], iLen ); WriteWord( pucPtr, auiLOscCaptures[2], iLen ); WriteWord( pucPtr, auiLOscCaptures[3], iLen ); WriteWord( pucPtr, auiLOscCaptures[4], iLen ); WriteWord( pucPtr, auiLOscCaptures[5], iLen ); WriteWord( pucPtr, auiLOscCaptures[6], iLen ); WriteWord( pucPtr, auiLOscCaptures[7], iLen ); memcpy( pucPtr, COMM_MSG_NAME, COMM_MSGNAME_LEN ); pucPtr += COMM_MSGNAME_LEN; iLen += COMM_MSGNAME_LEN; // send message iRet = ServerSocket.sendto( (char *)aucPollBuffer ,iLen, &ServerPort ); if ( iRet < 0 ) return false; return true; } //--------------------------------------------------------------------------- // END //---------------------------------------------------------------------------