/** * @brief Start the module * * @return -1 if initialisation failed, 0 on success */ static int32_t RadioComBridgeStart(void) { if (data) { // Check if this is the coordinator modem data->isCoordinator = PIOS_RFM22B_IsCoordinator(PIOS_COM_RFM22B); // Parse UAVTalk out of the link data->parseUAVTalk = true; // Configure our UAVObjects for updates. UAVObjConnectQueue(UAVObjGetByID(RFM22BSTATUS_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ); UAVObjConnectQueue(UAVObjGetByID(OBJECTPERSISTENCE_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL); if (data->isCoordinator) { UAVObjConnectQueue(UAVObjGetByID(RFM22BRECEIVER_OBJID), data->radioEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ); } else { UAVObjConnectQueue(UAVObjGetByID(RFM22BRECEIVER_OBJID), data->uavtalkEventQueue, EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ); } if (data->isCoordinator) { registerObject(RadioComBridgeStatsHandle()); } // Configure the UAVObject callbacks ObjectPersistenceConnectCallback(&objectPersistenceUpdatedCb); // Start the primary tasks for receiving/sending UAVTalk packets from the GCS. data->telemetryTxTaskHandle = PIOS_Thread_Create(telemetryTxTask, "telemetryTxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY); data->telemetryRxTaskHandle = PIOS_Thread_Create(telemetryRxTask, "telemetryRxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY); if (PIOS_PPM_RECEIVER != 0) { data->PPMInputTaskHandle = PIOS_Thread_Create(PPMInputTask, "PPMInputTask",STACK_SIZE_BYTES, NULL, TASK_PRIORITY); #ifdef PIOS_INCLUDE_WDG PIOS_WDG_RegisterFlag(PIOS_WDG_PPMINPUT); #endif } if (!data->parseUAVTalk) { // If the user wants raw serial communication, we need to spawn another thread to handle it. data->serialRxTaskHandle = PIOS_Thread_Create(serialRxTask, "serialRxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY); #ifdef PIOS_INCLUDE_WDG PIOS_WDG_RegisterFlag(PIOS_WDG_SERIALRX); #endif } data->radioTxTaskHandle = PIOS_Thread_Create(radioTxTask, "radioTxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY); data->radioRxTaskHandle = PIOS_Thread_Create(radioRxTask, "radioRxTask", STACK_SIZE_BYTES, NULL, TASK_PRIORITY); // Register the watchdog timers. #ifdef PIOS_INCLUDE_WDG PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMETRYTX); PIOS_WDG_RegisterFlag(PIOS_WDG_TELEMETRYRX); PIOS_WDG_RegisterFlag(PIOS_WDG_RADIOTX); PIOS_WDG_RegisterFlag(PIOS_WDG_RADIORX); #endif return 0; } return -1; }
/** * Update object's queue connections and timer, depending on object's settings * \param[in] obj Object to updates */ static void updateObject(UAVObjHandle obj, int32_t eventType) { UAVObjMetadata metadata; UAVObjUpdateMode updateMode; int32_t eventMask; // Get metadata UAVObjGetMetadata(obj, &metadata); updateMode = UAVObjGetTelemetryUpdateMode(&metadata); // Setup object depending on update mode if (updateMode == UPDATEMODE_PERIODIC) { // Set update period setUpdatePeriod(obj, metadata.telemetryUpdatePeriod); // Connect queue eventMask = EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ; if (UAVObjIsMetaobject(obj)) { eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events) } UAVObjConnectQueue(obj, priorityQueue, eventMask); } else if (updateMode == UPDATEMODE_ONCHANGE) { // Set update period setUpdatePeriod(obj, 0); // Connect queue eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ; if (UAVObjIsMetaobject(obj)) { eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events) } UAVObjConnectQueue(obj, priorityQueue, eventMask); } else if (updateMode == UPDATEMODE_THROTTLED) { if ((eventType == EV_UPDATED_PERIODIC) || (eventType == EV_NONE)) { // If we received a periodic update, we can change back to update on change eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ; // Set update period on initialization and metadata change if (eventType == EV_NONE) setUpdatePeriod(obj, metadata.telemetryUpdatePeriod); } else { // Otherwise, we just received an object update, so switch to periodic for the timeout period to prevent more updates eventMask = EV_UPDATED_PERIODIC | EV_UPDATED_MANUAL | EV_UPDATE_REQ; } if (UAVObjIsMetaobject(obj)) { eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events) } UAVObjConnectQueue(obj, priorityQueue, eventMask); } else if (updateMode == UPDATEMODE_MANUAL) { // Set update period setUpdatePeriod(obj, 0); // Connect queue eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ; if (UAVObjIsMetaobject(obj)) { eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events) } UAVObjConnectQueue(obj, priorityQueue, eventMask); } }
/** * Register a new object, adds object to local list and connects the queue depending on the object's * telemetry settings. * \param[in] obj Object to connect */ static void registerObject(UAVObjHandle obj) { if (UAVObjIsMetaobject(obj)) { /* Only connect change notifications for meta objects. No periodic updates */ UAVObjConnectQueue(obj, priorityQueue, EV_MASK_ALL_UPDATES); return; } else { UAVObjMetadata metadata; UAVObjUpdateMode updateMode; UAVObjGetMetadata(obj, &metadata); updateMode = UAVObjGetTelemetryUpdateMode(&metadata); /* Only create a periodic event for objects that are periodic */ if ((updateMode == UPDATEMODE_PERIODIC) || (updateMode == UPDATEMODE_THROTTLED)) { // Setup object for periodic updates UAVObjEvent ev = { .obj = obj, .instId = UAVOBJ_ALL_INSTANCES, .event = EV_UPDATED_PERIODIC, }; EventPeriodicQueueCreate(&ev, queue, 0); } // Setup object for telemetry updates updateObject(obj, EV_NONE); }
/** * Register a new object, adds object to local list and connects the queue depending on the object's * telemetry settings. * \param[in] obj Object to connect */ static void registerObject(UAVObjHandle obj) { int32_t eventMask; eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ; if (UAVObjIsMetaobject(obj)) { eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events) } UAVObjConnectQueue(obj, queue, eventMask); }
/** * Update object's queue connections and timer, depending on object's settings * \param[in] obj Object to updates */ static void updateObject(UAVObjHandle obj) { UAVObjMetadata metadata; int32_t eventMask; // Get metadata UAVObjGetMetadata(obj, &metadata); // Setup object depending on update mode if (metadata.telemetryUpdateMode == UPDATEMODE_PERIODIC) { // Set update period setUpdatePeriod(obj, metadata.telemetryUpdatePeriod); // Connect queue eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ; if (UAVObjIsMetaobject(obj)) { eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events) } UAVObjConnectQueue(obj, priorityQueue, eventMask); } else if (metadata.telemetryUpdateMode == UPDATEMODE_ONCHANGE) { // Set update period setUpdatePeriod(obj, 0); // Connect queue eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ; if (UAVObjIsMetaobject(obj)) { eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events) } UAVObjConnectQueue(obj, priorityQueue, eventMask); } else if (metadata.telemetryUpdateMode == UPDATEMODE_MANUAL) { // Set update period setUpdatePeriod(obj, 0); // Connect queue eventMask = EV_UPDATED_MANUAL | EV_UPDATE_REQ; if (UAVObjIsMetaobject(obj)) { eventMask |= EV_UNPACKED; // we also need to act on remote updates (unpack events) } UAVObjConnectQueue(obj, priorityQueue, eventMask); } else if (metadata.telemetryUpdateMode == UPDATEMODE_NEVER) { // Set update period setUpdatePeriod(obj, 0); // Disconnect queue UAVObjDisconnectQueue(obj, priorityQueue); } }
/** * Register a new object, adds object to local list and connects the queue depending on the object's * telemetry settings. * \param[in] obj Object to connect */ static void register_object(UAVObjHandle obj) { int32_t eventMask; eventMask = EV_UPDATED | EV_UPDATED_MANUAL | EV_UPDATE_REQ | EV_UNPACKED; UAVObjConnectQueue(obj, queue, eventMask); }