static int req_start(uint8_t chan, bool coord) /* this function configures the coordinator. * NOTE: when in periodic mode, active scan will NOT be answered immediatly. */ { void *mac = pvAppApiGetMacHandle(); MAC_Pib_s *pib = MAC_psPibGetHandle(mac); MAC_MlmeReqRsp_s mlmereq; MAC_MlmeSyncCfm_s mlmecfm; memcpy(&pib->sCoordExtAddr, pvAppApiGetMacAddrLocation(), sizeof(MAC_ExtAddr_s)); mlmereq.u8Type = MAC_MLME_REQ_START; mlmereq.u8ParamLength = sizeof(MAC_MlmeReqScan_s); mlmereq.uParam.sReqStart.u16PanId = 0xbeef; mlmereq.uParam.sReqStart.u8Channel = chan; mlmereq.uParam.sReqStart.u8BeaconOrder = 15; mlmereq.uParam.sReqStart.u8SuperframeOrder = 15; mlmereq.uParam.sReqStart.u8PanCoordinator = coord; mlmereq.uParam.sReqStart.u8BatteryLifeExt = false; mlmereq.uParam.sReqStart.u8Realignment = false; mlmereq.uParam.sReqStart.u8SecurityEnable = false; vAppApiMlmeRequest(&mlmereq, &mlmecfm); return mlmecfm.uParam.sCfmStart.u8Status; }
/**************************************************************************** * * NAME: NODE_vInit * * DESCRIPTION: * Initialises Zigbee stack, hardware and application. * ****************************************************************************/ PUBLIC void NODE_vInit(void) { uint32 u32RandomSeed; /* Debug */ DBG_vPrintf(NODE_TRACE, "\n%d NODE < NODE_vInit()", NODE_sData.u32Timer); /* Seed the pseudo random number generator using the hardware random gen */ *((volatile uint32 *)0x02001010) |= (1 << 30); /* clear ready flag */ vAHI_StartRandomNumberGenerator(TRUE /* single shot */, FALSE /* no ints */); while (!bAHI_RndNumPoll()); u32RandomSeed = ((uint32)u16AHI_ReadRandomNumber()) << 16; *((volatile uint32 *)0x02001010) |= (1 << 30); /* clear ready flag */ vAHI_StartRandomNumberGenerator(TRUE /* single shot */, FALSE /* no ints */); while (!bAHI_RndNumPoll()); u32RandomSeed |= u16AHI_ReadRandomNumber(); RND_vInit(u32RandomSeed); DBG_vPrintf(NODE_TRACE, " RND=%08x", u32RandomSeed); /* Initialise JenOS modules */ PWRM_vInit(E_AHI_SLEEP_OSCON_RAMON); DBG_vPrintf(NODE_TRACE, " PWRM"); /* Initialise persistent data */ PDM_vInit(7, 1, 64*1024, NULL, mutexPdmMedia, NULL, NULL); DBG_vPrintf(NODE_TRACE, " PDM"); /* Delete persistent data - always start over for now */ PDM_vDelete(); DBG_vPrintf(NODE_TRACE, "deleted"); PDUM_vInit(); DBG_vPrintf(NODE_TRACE, " PDUM"); /* Initialise ZigbeePro stack */ ZPS_eAplAfInit(); DBG_vPrintf(NODE_TRACE, " ZPS"); /* No state yet */ NODE_sData.eNwkState = NODE_NWKSTATE_NONE; /* Initialise non-zero node structure members */ NODE_sData.u64Address = *(uint64 *) pvAppApiGetMacAddrLocation(); /**< Address of node */ NODE_sData.u16Address = 0xffff; /**< Short address of node */ NODE_sData.u16Parent = 0xffff; /**< Short address of node's parent */ /* Initialise node structure pointer members */ NODE_sData.pvMac = (void *) pvAppApiGetMacHandle(); NODE_sData.psPib = MAC_psPibGetHandle(NODE_sData.pvMac); NODE_sData.pvNwk = ZPS_pvNwkGetHandle(); NODE_sData.psNib = ZPS_psNwkNibGetHandle(NODE_sData.pvNwk); /* Note initial MinBe */ NODE_sData.u8DefPibMinBe = NODE_sData.psPib->u8MinBe_ReadOnly; }
/**************************************************************************** * * NAME: vInitSystem * * DESCRIPTION: Initialise the radio system * * RETURNS: * void * ****************************************************************************/ PRIVATE void vInitSystem(void) { // Setup interface to MAC (void) u32AHI_Init(); (void) u32AppQApiInit(NULL,mcpsCallback , NULL); loadSettings(); if (useHighPowerModule == TRUE) { //max power for europe including antenna gain is 10dBm // TODO see if we can use more power as rx antenna is lower gain //??? boost is +2.5 ant is 1 and power set to 4 = 7.5 ???? vAHI_HighPowerModuleEnable(TRUE, TRUE); #ifdef JN5168 eAppApiPlmeSet(PHY_PIB_ATTR_TX_POWER, 34+10*2); #else bAHI_PhyRadioSetPower(2); #endif } // Initialise end device state sEndDeviceData.eState = E_STATE_IDLE; sEndDeviceData.u8TxPacketSeqNb = 0; sEndDeviceData.u8RxPacketSeqNb = 0; sEndDeviceData.u8ChannelSeqNo = 0; // Set up the MAC handles. Must be called AFTER u32AppQApiInit() s_pvMac = pvAppApiGetMacHandle(); s_psMacPib = MAC_psPibGetHandle(s_pvMac); // Set Pan ID in PIB (also sets match register in hardware) MAC_vPibSetPanId(s_pvMac, PAN_ID); // Enable receiver to be on when idle MAC_vPibSetRxOnWhenIdle(s_pvMac, TRUE, FALSE); // sometimes useful during development // all messages are passed up from lower levels // MAC_vPibSetPromiscuousMode(s_pvMac, TRUE, FALSE); module_MAC_ExtAddr_s* macptr = (module_MAC_ExtAddr_s*)pvAppApiGetMacAddrLocation(); //moved to after u32AHI_Init() for jn5148 randomizeHopSequence(((uint32) macptr->u32H) ^ ((uint32) macptr->u32L)); #if (defined JN5148 || defined JN5168) /* Enable TOF ranging. */ // vAppApiTofInit(TRUE); #endif }
/**************************************************************************** * * NAME: MibNwkSecurity_vResumeGateway * * DESCRIPTION: * REsumes running in a gateway system * ****************************************************************************/ PATCH_POINT_PUBLIC(uint8,MibNwkSecurity_u8ResumeGateway)(tsNetworkConfigData *psNetworkConfigData, uint8 u8NwkStatusUpMode, uint32 u32NwkStatusFrameCounter) { MAC_DeviceDescriptor_s sDeviceDescriptor; /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\nMibNwkSecurity_u8ResumeGateway()"); /* Use network key */ MibNwkSecurity_vSetSecurityKey(MIB_NWK_SECURITY_SECURITY_KEY_NETWORK); /* Build security descriptor for this node */ sDeviceDescriptor.u16PanId = psMibNwkSecurity->sPerm.u16PanId; sDeviceDescriptor.u16Short = 0xfffe; memcpy(&sDeviceDescriptor.sExt, pvAppApiGetMacAddrLocation(), sizeof(MAC_ExtAddr_s)); sDeviceDescriptor.u32FrameCounter = u32NwkStatusFrameCounter; sDeviceDescriptor.bExempt = FALSE; /* Restore security descriptor for this node */ (void) bSecuritySetDescriptor(0, &sDeviceDescriptor); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tbSecuritySetDescriptor(0, %x:%x, %d)", sDeviceDescriptor.sExt.u32H, sDeviceDescriptor.sExt.u32L, sDeviceDescriptor.u32FrameCounter); /* Make three attempts to rejoin gateway with current network key */ psMibNwkSecurity->u8GatewayRejoin = 3; /* Revert to none up mode */ u8NwkStatusUpMode = MIB_NWK_STATUS_UP_MODE_NONE; /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tu8NwkStatusUpMode=%d", u8NwkStatusUpMode); /* Resuming as a coordinator ? */ if (psMibNwkSecurity->u8DeviceType == E_6LP_COORDINATOR) { /* Pass in network config data as parameter to do this */ /* Override scan channels and PAN ID to restore previous network */ psNetworkConfigData->u32ScanChannels = (1<<psMibNwkSecurity->sPerm.u8Channel); psNetworkConfigData->u16PanID = psMibNwkSecurity->sPerm.u16PanId; } return u8NwkStatusUpMode; }
/**************************************************************************** * * NAME: MibNwkSecurity_vResumeStandalone * * DESCRIPTION: * Resumes running in a standalone system * ****************************************************************************/ PATCH_POINT_PUBLIC(uint8,MibNwkSecurity_u8ResumeStandalone)(tsNetworkConfigData *psNetworkConfigData, uint8 u8NwkStatusUpMode, uint32 u32NwkStatusFrameCounter) { MAC_DeviceDescriptor_s sDeviceDescriptor; uint8 u8SecureAddr; uint8 u8Restored = 0; /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\nMibNwkSecurity_u8ResumeStandalone()"); /* Use network key */ MibNwkSecurity_vSetSecurityKey(MIB_NWK_SECURITY_SECURITY_KEY_NETWORK); /* Build security descriptor for this node */ sDeviceDescriptor.u16PanId = psMibNwkSecurity->sPerm.u16PanId; sDeviceDescriptor.u16Short = 0xfffe; memcpy(&sDeviceDescriptor.sExt, pvAppApiGetMacAddrLocation(), sizeof(MAC_ExtAddr_s)); sDeviceDescriptor.u32FrameCounter = u32NwkStatusFrameCounter; sDeviceDescriptor.bExempt = FALSE; /* Restore security descriptor for this node */ (void) bSecuritySetDescriptor(u8Restored++, &sDeviceDescriptor); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tbSecuritySetDescriptor(%d, %x:%x, %d)", u8Restored, sDeviceDescriptor.sExt.u32H, sDeviceDescriptor.sExt.u32L, sDeviceDescriptor.u32FrameCounter); /* Zero frame counter for other descriptors we are going to create */ sDeviceDescriptor.u32FrameCounter = 0; /* Loop through stored secure addresses */ for (u8SecureAddr = 0; u8SecureAddr < MIB_NWK_SECURITY_SECURE_ADDR_COUNT; u8SecureAddr++) { /* Valid secure address ? */ if (psMibNwkSecurity->sPerm.asSecureAddr[u8SecureAddr].u32H != 0 || psMibNwkSecurity->sPerm.asSecureAddr[u8SecureAddr].u32L != 0) { /* Build security descriptor for this node */ memcpy(&sDeviceDescriptor.sExt, &psMibNwkSecurity->sPerm.asSecureAddr[u8SecureAddr], sizeof(MAC_ExtAddr_s)); /* Restore security descriptor for this node (well reserve a slot anyway as we are zeroing the frame counter) */ (void) bSecuritySetDescriptor(u8Restored++, &sDeviceDescriptor); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tbSecuritySetDescriptor(%d, %x:%x, %d)", u8Restored, sDeviceDescriptor.sExt.u32H, sDeviceDescriptor.sExt.u32L, sDeviceDescriptor.u32FrameCounter); } } /* Set profile for standalone system */ MibNwkSecurity_vSetProfile(TRUE); /* Start in standalone mode */ vApi_SetStackMode(STACK_MODE_STANDALONE); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tvApi_SetStackMode(%x)", STACK_MODE_STANDALONE); /* Note network is up */ psMibNwkSecurity->bUp = TRUE; /* Skip the normal joining process */ vApi_SkipJoin(psMibNwkSecurity->sPerm.u16PanId, psMibNwkSecurity->sPerm.u8Channel); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_NWK_SECURITY, "\n\tvApi_SkipJoin(%x, %d)", psMibNwkSecurity->sPerm.u16PanId, psMibNwkSecurity->sPerm.u8Channel); return u8NwkStatusUpMode; }
/**************************************************************************** * * NAME: vHandleMcpsDataInd * * DESCRIPTION: Handler for received data * * PARAMETERS: Name RW Usage * psMcpsInd R pointer to received data struct * RETURNS: * * NOTES: ****************************************************************************/ PRIVATE void vHandleMcpsDataInd(MAC_McpsDcfmInd_s *psMcpsInd) { // Get the received data structure MAC_RxFrameData_s *psFrame = &psMcpsInd->uParam.sIndData.sFrame; // Get the mac address // TODO - pvAppApiGetMacAddrLocation not in docs // TODO - macptr not used as code is commented out module_MAC_ExtAddr_s* macptr = (module_MAC_ExtAddr_s*)pvAppApiGetMacAddrLocation(); uint8 realTimeDataLen=psFrame->au8Sdu[0]; uint8 lowPriorityDataLen=psFrame->u8SduLength-1-realTimeDataLen; // If not associated ?? // TODO - should this be merged with similar code below [1] if (sEndDeviceData.eState != E_STATE_ASSOCIATED) { // Check for bind acceptance // if routed packet, handle it if(lowPriorityDataLen>0) { handleLowPriorityData(&psFrame->au8Sdu[realTimeDataLen+1], lowPriorityDataLen); return; } } // Only accept from bound tx // TODO - the TX_ADDRESS_MODE stops the following code from being reached if (TX_ADDRESS_MODE == 3 && (psFrame->sSrcAddr.uAddr.sExt.u32H != txMACh || psFrame->sSrcAddr.uAddr.sExt.u32L != txMACl)) { return; } //debugCount1++; // First frame, we have an association // TODO - Should this be merged with code above [1] if (sEndDeviceData.eState != E_STATE_ASSOCIATED) { // dbgPrintf("tx found \r\n"); dbgPrintf("tx found %x %x\r\n",txMACh ,txMACl ); // Update the association state sEndDeviceData.eState = E_STATE_ASSOCIATED; // Set the hopping mode setHopMode(hoppingContinuous); } //the same packet can be received many times if the ack was not received by the sender if(!frameReceived) { frameReceived=TRUE; // Record the link quality txLinkQuality = psFrame->u8LinkQuality; /* * TODO - define a structure for this * packet layout: * [0] - 8 bit seqno * [1] - 16 bit tx time */ /* now done in interrupt context // retrieve the tx time, calculate the rx time ?? // TODO - explain rx time calc int txTime = (psFrame->au8Sdu[1] + (psFrame->au8Sdu[2] << 8)) * 160; //allow for latencies along the way and calculate the time we think the tx has now. //allow for variations in packet length @ 250kbps //32us per byte is 512 clocks per byte int rxTime = (txTime + 2000* 16 +(psFrame->u8SduLength-8)*512 ) % (31* 20000* 16 ) ; // TODO - Explain this calcSyncError(rxTime); */ // Update global rx data packet counter rxdpackets++; // Update latest received se. no. sEndDeviceData.u8RxPacketSeqNb = psFrame->au8Sdu[0]; // Process the data packet vProcessReceivedDataPacket(&psFrame->au8Sdu[3], realTimeDataLen-2); // If there is more data, process it if(lowPriorityDataLen>0) { // debugCount1++; handleLowPriorityData(&psFrame->au8Sdu[realTimeDataLen+1], lowPriorityDataLen); } // Send some data back // should check there is time to do this and limit retries #ifdef JN5168 //don't send if near the end of the frame as jn5168 gets upset //if channel changed during transmission // if(getSeqClock()%(20000*16)>14000*16)return; // return; #endif // Declare the return packet data and default size uint8 au8Packet[6]; uint8 packetLen = 4; // Set the return packet data indicator au8Packet[1] = returnPacketIdx; uint16 val = 0; switch (returnPacketIdx) { case 0: case 1: case 2: case 3: case 4: case 5: { // 0 - 5 ADC channels val = u16ReadADC(returnPacketIdx); au8Packet[2] = val & 0xff; au8Packet[3] = val >> 8; break; } case 6: { // 6 - TX Quality au8Packet[2] = getErrorRate(); au8Packet[3] = txLinkQuality; // If unable to read GPS data skip the GPS data items if (readNmeaGps(&gpsData) == FALSE) returnPacketIdx = 13; break; } case 7: { // 7 - GPS speed readNmeaGps(&gpsData); memcpy(&au8Packet[2], &gpsData.nmeaspeed, sizeof(gpsData.nmeaspeed)); packetLen = 6; break; } case 8: { // 8 - GPS height readNmeaGps(&gpsData); memcpy(&au8Packet[2], &gpsData.nmeaheight, sizeof(gpsData.nmeaheight)); packetLen = 6; break; } case 9: { // 9 - GPS track readNmeaGps(&gpsData); memcpy(&au8Packet[2], &gpsData.nmeatrack, sizeof(gpsData.nmeatrack)); packetLen = 6; break; } case 10: { // 10 - GPS time readNmeaGps(&gpsData); memcpy(&au8Packet[2], &gpsData.nmeatime, sizeof(gpsData.nmeatime)); packetLen = 6; break; } case 11: { // 11 - GPS latitude readNmeaGps(&gpsData); memcpy(&au8Packet[2], &gpsData.nmealat, sizeof(gpsData.nmealat)); packetLen = 6; break; } case 12: { // 12 - GPS longitude readNmeaGps(&gpsData); memcpy(&au8Packet[2], &gpsData.nmealong, sizeof(gpsData.nmealong)); packetLen = 6; break; } case 13: { // 13 - satellites readNmeaGps(&gpsData); memcpy(&au8Packet[2], &gpsData.nmeasats, sizeof(gpsData.nmeasats)); packetLen = 6; break; } case 14: { //corrected battery voltage in 0.01v units val = u16ReadADC(rxHardware.batVoltageChannel); int volts=val*rxHardware.batVoltageMultiplier/4096+rxHardware.batVoltageOffset; au8Packet[2] = volts & 0xff; au8Packet[3] = volts >> 8; } } // Set the data length au8Packet[0] = packetLen - 1; // Send the packet vTransmitDataPacket(au8Packet, packetLen, FALSE); // Update the data type for the next packet returnPacketIdx++; // If the last data type has been sent, reset to 0 if (returnPacketIdx >= 15) returnPacketIdx = 0; }
/**************************************************************************** * * NAME: frameStartEvent * * DESCRIPTION: Handler for the frame start notification * * PARAMETERS: Name RW Usage * buff ? unused?? * * RETURNS: * * NOTES: ****************************************************************************/ void frameStartEvent(void* context,void* buff) { // Called every frame, currently 20ms frameCounter++; #ifdef JN5168 /* MAC_McpsReqRsp_s sMcpsReqRsp; MAC_McpsSyncCfm_s sMcpsSyncCfm; // Send request to remove a data frame from transaction queue sMcpsReqRsp.u8Type = MAC_MCPS_REQ_PURGE; sMcpsReqRsp.u8ParamLength = sizeof(MAC_McpsReqPurge_s); sMcpsReqRsp.uParam.sReqPurge.u8Handle = 1; vAppApiMcpsRequest(&sMcpsReqRsp, &sMcpsSyncCfm); */ //reset MAC MAC_MlmeReqRsp_s sMlmeReqRsp; MAC_MlmeSyncCfm_s sMlmeSyncCfm; sMlmeReqRsp.u8Type = MAC_MLME_REQ_RESET; sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeReqReset_s); sMlmeReqRsp.uParam.sReqReset.u8SetDefaultPib = FALSE; vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm); uint32 newchannel = getHopChannel(getSeqClock()); eAppApiPlmeSet(PHY_PIB_ATTR_CURRENT_CHANNEL, newchannel); #endif if(frameReceived==FALSE) { RX.missedFrames++; } else { RX.missedFrames=0; } //used instead of sequence number to prevent handling the same frame twice frameReceived=FALSE; // Binding check // Only do automatic bind request after 10secs incase this // was an unintended reboot in flight. // Only do if not already communicating with a tx if ((frameCounter > 500 && frameCounter < 5000) && getHopMode() == hoppingRxStartup) { // TODO - add binding button check and an option to disable auto binding uint32 channel = 0; eAppApiPlmeGet(PHY_PIB_ATTR_CURRENT_CHANNEL, &channel); if (channel == 11) { // TODO - Get rid of magic numbers uint8 packet[14]; packet[0] = 0; //no high priority data packet[1] = 0; //seq no packet[2] = 0; //chunk no packet[3] = 10; //length of message packet[4] = 0; //no route packet[5] = 16; //bind request module_MAC_ExtAddr_s* macptr = (module_MAC_ExtAddr_s*)pvAppApiGetMacAddrLocation(); // TODO - can't we just memcpy the whole thing in one call? memcpy(&packet[6], &macptr->u32L, sizeof(macptr->u32L)); memcpy(&packet[10], &macptr->u32H, sizeof(macptr->u32H)); vTransmitDataPacket(packet, sizeof(packet), TRUE); } // Set the flash rate to fast to indicate binding attempts rxLEDFlashLimit = LED_FLASH_FAST; } // LED Flasher to indicate binding state. if ((getHopMode() == hoppingContinuous) && !rxLEDState) { // We have bound, set the LED on rxLEDState = TRUE; vAHI_DioSetOutput(rxHardware.ledBit, 0); } else { if (frameCounter > 5000) // We have timed out rxLEDFlashLimit = LED_FLASH_SLOW; // If the count exceeds the current limit, toggle the LED state if (++rxLEDFlashCount > rxLEDFlashLimit) { // Toggle the state flag rxLEDState = !rxLEDState; // Set the output accordingly if (rxLEDState) vAHI_DioSetOutput(rxHardware.ledBit, 0); else vAHI_DioSetOutput(0, rxHardware.ledBit); // Reset the counter for the next cycle rxLEDFlashCount = 0; } } }
/**************************************************************************** * * NAME: AppColdStart * * DESCRIPTION: * Entry point for application from boot loader. Initialises system and runs * main loop. * * RETURNS: * Never returns. * ****************************************************************************/ PUBLIC void AppColdStart(void) { #if (defined JN5148 || defined JN5168 ) // TODO - use watch dog and probably disable brownout reset vAHI_WatchdogStop(); #endif #ifdef JN5139 vAppApiSetBoostMode(TRUE); #endif // Initialise the hopping mode status // TODO - move to settings? setHopMode(hoppingRxStartup); connectObjects(); RX.ro.version=2; // Initialise the system vInitSystem(); // set up the exception handlers setExceptionHandlers(); if(!radioDebug)debugRoute=&pcViaComPort; else debugRoute=&pcViaTx; if (debugRoute->routeNodes[0] == CONPC) { // Don't use uart pins for servo op initPcComs(&pccoms, CONPC, 0, rxHandleRoutedMessage); rxHardware.uart0InUse=TRUE; } // Initialise the clock // TODO - fix this /* the jn5148 defaults to 16MHz for the processor, it can be switched to 32Mhz however the servo driving code would need tweaking */ //bAHI_SetClockRate(3); resetType rt=getResetReason(); if(rt!=NOEXCEPTION) { dbgPrintf("EXCEPTION %d \r\n",rt); } // Set handler for incoming data setRadioDataCallback(rxHandleRoutedMessage, CONTX); // Retrieve the MAC address and log it to the PC module_MAC_ExtAddr_s* macptr = (module_MAC_ExtAddr_s*)pvAppApiGetMacAddrLocation(); // Send init string to PC log rx mac and bound tx mac to pc dbgPrintf("rx24 2.10 rx %x %x tx %x %x",macptr->u32H, macptr->u32L,txMACh ,txMACl ); // Use dio 16 for test sync pulse vAHI_DioSetDirection(0, 1 << 16); // Set demands to impossible values // TODO - fix magic numbers grrr int i; for (i = 0; i < 20; i++) { RX.rxDemands[i] = 4096; RX.rxMixedDemands[i] = 4096; } rxHardware.i2cInUse=imu.enabled; startIMU(&imu); // Set up digital inputs and outputs initInputs(&rxHardware); initOutputs(&rxHardware); if(rxHardware.oneWireEnabled==TRUE) { // enable onewire sensor bus initOneWireBus(&sensorBus1,CONONEWIRE,rxHardware.oneWirePort,rxHandleRoutedMessage); } if(rxHardware.gpsEnabled==TRUE) { initNmeaGps(rxHardware.gpsPort, E_AHI_UART_RATE_38400); } // Setup DIO for the LED vAHI_DioSetDirection(0, rxHardware.ledBit); // Initialise Analogue peripherals vAHI_ApConfigure(E_AHI_AP_REGULATOR_ENABLE, E_AHI_AP_INT_DISABLE, E_AHI_AP_SAMPLE_8, E_AHI_AP_CLOCKDIV_500KHZ, E_AHI_AP_INTREF); while (bAHI_APRegulatorEnabled() == 0) ; // Start the servo pwm generator setFrameCallback(frameStartEvent); setMixCallback(mixEvent); startServoPwm(RX.servoUpdateRate); // Enter the never ending main handler while (1) { // Process any events vProcessEventQueues(); } }