aboutsummaryrefslogtreecommitdiff
path: root/apps/drivers/gps/gps.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apps/drivers/gps/gps.cpp')
-rw-r--r--apps/drivers/gps/gps.cpp536
1 files changed, 0 insertions, 536 deletions
diff --git a/apps/drivers/gps/gps.cpp b/apps/drivers/gps/gps.cpp
deleted file mode 100644
index e35bdb944..000000000
--- a/apps/drivers/gps/gps.cpp
+++ /dev/null
@@ -1,536 +0,0 @@
-/****************************************************************************
- *
- * Copyright (C) 2013 PX4 Development Team. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name PX4 nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-/**
- * @file gps.cpp
- * Driver for the GPS on a serial port
- */
-
-#include <nuttx/clock.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <semaphore.h>
-#include <string.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <errno.h>
-#include <stdio.h>
-#include <math.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <nuttx/config.h>
-#include <nuttx/arch.h>
-#include <arch/board/board.h>
-#include <drivers/drv_hrt.h>
-#include <drivers/device/i2c.h>
-#include <systemlib/perf_counter.h>
-#include <systemlib/scheduling_priorities.h>
-#include <systemlib/err.h>
-#include <drivers/drv_gps.h>
-#include <uORB/uORB.h>
-#include <uORB/topics/vehicle_gps_position.h>
-
-#include "ubx.h"
-#include "mtk.h"
-
-
-#define TIMEOUT_5HZ 500
-#define RATE_MEASUREMENT_PERIOD 5000000
-
-/* oddly, ERROR is not defined for c++ */
-#ifdef ERROR
-# undef ERROR
-#endif
-static const int ERROR = -1;
-
-#ifndef CONFIG_SCHED_WORKQUEUE
-# error This requires CONFIG_SCHED_WORKQUEUE.
-#endif
-
-
-
-class GPS : public device::CDev
-{
-public:
- GPS(const char* uart_path);
- virtual ~GPS();
-
- virtual int init();
-
- virtual int ioctl(struct file *filp, int cmd, unsigned long arg);
-
- /**
- * Diagnostics - print some basic information about the driver.
- */
- void print_info();
-
-private:
-
- bool _task_should_exit; ///< flag to make the main worker task exit
- int _serial_fd; ///< serial interface to GPS
- unsigned _baudrate; ///< current baudrate
- char _port[20]; ///< device / serial port path
- volatile int _task; //< worker task
- bool _healthy; ///< flag to signal if the GPS is ok
- bool _baudrate_changed; ///< flag to signal that the baudrate with the GPS has changed
- bool _mode_changed; ///< flag that the GPS mode has changed
- gps_driver_mode_t _mode; ///< current mode
- GPS_Helper *_Helper; ///< instance of GPS parser
- struct vehicle_gps_position_s _report; ///< uORB topic for gps position
- orb_advert_t _report_pub; ///< uORB pub for gps position
- float _rate; ///< position update rate
-
-
- /**
- * Try to configure the GPS, handle outgoing communication to the GPS
- */
- void config();
-
- /**
- * Trampoline to the worker task
- */
- static void task_main_trampoline(void *arg);
-
-
- /**
- * Worker task: main GPS thread that configures the GPS and parses incoming data, always running
- */
- void task_main(void);
-
- /**
- * Set the baudrate of the UART to the GPS
- */
- int set_baudrate(unsigned baud);
-
- /**
- * Send a reset command to the GPS
- */
- void cmd_reset();
-
-};
-
-
-/*
- * Driver 'main' command.
- */
-extern "C" __EXPORT int gps_main(int argc, char *argv[]);
-
-namespace
-{
-
-GPS *g_dev;
-
-}
-
-
-GPS::GPS(const char* uart_path) :
- CDev("gps", GPS_DEVICE_PATH),
- _task_should_exit(false),
- _healthy(false),
- _mode_changed(false),
- _mode(GPS_DRIVER_MODE_UBX),
- _Helper(nullptr),
- _report_pub(-1),
- _rate(0.0f)
-{
- /* store port name */
- strncpy(_port, uart_path, sizeof(_port));
- /* enforce null termination */
- _port[sizeof(_port) - 1] = '\0';
-
- /* we need this potentially before it could be set in task_main */
- g_dev = this;
- memset(&_report, 0, sizeof(_report));
-
- _debug_enabled = true;
-}
-
-GPS::~GPS()
-{
- /* tell the task we want it to go away */
- _task_should_exit = true;
-
- /* spin waiting for the task to stop */
- for (unsigned i = 0; (i < 10) && (_task != -1); i++) {
- /* give it another 100ms */
- usleep(100000);
- }
-
- /* well, kill it anyway, though this will probably crash */
- if (_task != -1)
- task_delete(_task);
- g_dev = nullptr;
-
-}
-
-int
-GPS::init()
-{
- int ret = ERROR;
-
- /* do regular cdev init */
- if (CDev::init() != OK)
- goto out;
-
- /* start the GPS driver worker task */
- _task = task_create("gps", SCHED_PRIORITY_SLOW_DRIVER, 2048, (main_t)&GPS::task_main_trampoline, nullptr);
-
- if (_task < 0) {
- warnx("task start failed: %d", errno);
- return -errno;
- }
-
- ret = OK;
-out:
- return ret;
-}
-
-int
-GPS::ioctl(struct file *filp, int cmd, unsigned long arg)
-{
- lock();
-
- int ret = OK;
-
- switch (cmd) {
- case SENSORIOCRESET:
- cmd_reset();
- break;
- }
-
- unlock();
-
- return ret;
-}
-
-void
-GPS::task_main_trampoline(void *arg)
-{
- g_dev->task_main();
-}
-
-void
-GPS::task_main()
-{
- log("starting");
-
- /* open the serial port */
- _serial_fd = ::open(_port, O_RDWR);
-
- if (_serial_fd < 0) {
- log("failed to open serial port: %s err: %d", _port, errno);
- /* tell the dtor that we are exiting, set error code */
- _task = -1;
- _exit(1);
- }
-
- uint64_t last_rate_measurement = hrt_absolute_time();
- unsigned last_rate_count = 0;
-
- /* loop handling received serial bytes and also configuring in between */
- while (!_task_should_exit) {
-
- if (_Helper != nullptr) {
- delete(_Helper);
- /* set to zero to ensure parser is not used while not instantiated */
- _Helper = nullptr;
- }
-
- switch (_mode) {
- case GPS_DRIVER_MODE_UBX:
- _Helper = new UBX(_serial_fd, &_report);
- break;
- case GPS_DRIVER_MODE_MTK:
- _Helper = new MTK(_serial_fd, &_report);
- break;
- case GPS_DRIVER_MODE_NMEA:
- //_Helper = new NMEA(); //TODO: add NMEA
- break;
- default:
- break;
- }
- unlock();
- if (_Helper->configure(_baudrate) == 0) {
- unlock();
- while (_Helper->receive(TIMEOUT_5HZ) > 0 && !_task_should_exit) {
-// lock();
- /* opportunistic publishing - else invalid data would end up on the bus */
- if (_report_pub > 0) {
- orb_publish(ORB_ID(vehicle_gps_position), _report_pub, &_report);
- } else {
- _report_pub = orb_advertise(ORB_ID(vehicle_gps_position), &_report);
- }
-
- last_rate_count++;
-
- /* measure update rate every 5 seconds */
- if (hrt_absolute_time() - last_rate_measurement > RATE_MEASUREMENT_PERIOD) {
- _rate = last_rate_count / ((float)((hrt_absolute_time() - last_rate_measurement)) / 1000000.0f);
- last_rate_measurement = hrt_absolute_time();
- last_rate_count = 0;
- }
-
- if (!_healthy) {
- warnx("module found");
- _healthy = true;
- }
- }
- if (_healthy) {
- warnx("module lost");
- _healthy = false;
- _rate = 0.0f;
- }
-
- lock();
- }
- lock();
-
- /* select next mode */
- switch (_mode) {
- case GPS_DRIVER_MODE_UBX:
- _mode = GPS_DRIVER_MODE_MTK;
- break;
- case GPS_DRIVER_MODE_MTK:
- _mode = GPS_DRIVER_MODE_UBX;
- break;
- // case GPS_DRIVER_MODE_NMEA:
- // _mode = GPS_DRIVER_MODE_UBX;
- // break;
- default:
- break;
- }
-
- }
- debug("exiting");
-
- ::close(_serial_fd);
-
- /* tell the dtor that we are exiting */
- _task = -1;
- _exit(0);
-}
-
-
-
-void
-GPS::cmd_reset()
-{
- //XXX add reset?
-}
-
-void
-GPS::print_info()
-{
- switch (_mode) {
- case GPS_DRIVER_MODE_UBX:
- warnx("protocol: UBX");
- break;
- case GPS_DRIVER_MODE_MTK:
- warnx("protocol: MTK");
- break;
- case GPS_DRIVER_MODE_NMEA:
- warnx("protocol: NMEA");
- break;
- default:
- break;
- }
- warnx("port: %s, baudrate: %d, status: %s", _port, _baudrate, (_healthy) ? "OK" : "NOT OK");
- if (_report.timestamp_position != 0) {
- warnx("position lock: %dD, last update %4.2f seconds ago", (int)_report.fix_type,
- (double)((float)(hrt_absolute_time() - _report.timestamp_position) / 1000000.0f));
- warnx("lat: %d, lon: %d, alt: %d", _report.lat, _report.lon, _report.alt);
- warnx("update rate: %6.2f Hz", (double)_rate);
- }
-
- usleep(100000);
-}
-
-/**
- * Local functions in support of the shell command.
- */
-namespace gps
-{
-
-GPS *g_dev;
-
-void start(const char *uart_path);
-void stop();
-void test();
-void reset();
-void info();
-
-/**
- * Start the driver.
- */
-void
-start(const char *uart_path)
-{
- int fd;
-
- if (g_dev != nullptr)
- errx(1, "already started");
-
- /* create the driver */
- g_dev = new GPS(uart_path);
-
- if (g_dev == nullptr)
- goto fail;
-
- if (OK != g_dev->init())
- goto fail;
-
- /* set the poll rate to default, starts automatic data collection */
- fd = open(GPS_DEVICE_PATH, O_RDONLY);
-
- if (fd < 0) {
- errx(1, "Could not open device path: %s\n", GPS_DEVICE_PATH);
- goto fail;
- }
- exit(0);
-
-fail:
-
- if (g_dev != nullptr) {
- delete g_dev;
- g_dev = nullptr;
- }
-
- errx(1, "driver start failed");
-}
-
-/**
- * Stop the driver.
- */
-void
-stop()
-{
- delete g_dev;
- g_dev = nullptr;
-
- exit(0);
-}
-
-/**
- * Perform some basic functional tests on the driver;
- * make sure we can collect data from the sensor in polled
- * and automatic modes.
- */
-void
-test()
-{
-
- errx(0, "PASS");
-}
-
-/**
- * Reset the driver.
- */
-void
-reset()
-{
- int fd = open(GPS_DEVICE_PATH, O_RDONLY);
-
- if (fd < 0)
- err(1, "failed ");
-
- if (ioctl(fd, SENSORIOCRESET, 0) < 0)
- err(1, "driver reset failed");
-
- exit(0);
-}
-
-/**
- * Print the status of the driver.
- */
-void
-info()
-{
- if (g_dev == nullptr)
- errx(1, "driver not running");
-
- g_dev->print_info();
-
- exit(0);
-}
-
-} // namespace
-
-
-int
-gps_main(int argc, char *argv[])
-{
-
- /* set to default */
- char* device_name = GPS_DEFAULT_UART_PORT;
-
- /*
- * Start/load the driver.
- */
- if (!strcmp(argv[1], "start")) {
- /* work around getopt unreliability */
- if (argc > 3) {
- if (!strcmp(argv[2], "-d")) {
- device_name = argv[3];
- } else {
- goto out;
- }
- }
- gps::start(device_name);
- }
-
- if (!strcmp(argv[1], "stop"))
- gps::stop();
- /*
- * Test the driver/device.
- */
- if (!strcmp(argv[1], "test"))
- gps::test();
-
- /*
- * Reset the driver.
- */
- if (!strcmp(argv[1], "reset"))
- gps::reset();
-
- /*
- * Print driver status.
- */
- if (!strcmp(argv[1], "status"))
- gps::info();
-
-out:
- errx(1, "unrecognized command, try 'start', 'stop', 'test', 'reset' or 'status' [-d /dev/ttyS0-n]");
-}