4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #ifndef XCSOAR_DEVICE_DRIVER_HPP
25 #define XCSOAR_DEVICE_DRIVER_HPP
27 #include "Time/BrokenDate.hpp"
28 #include "Time/BrokenTime.hpp"
29 #include "Util/StaticArray.hpp"
30 #include "Math/fixed.hpp"
42 class AtmosphericPressure
;
44 class OperationEnvironment
;
46 struct RecordedFlightInfo
{
49 BrokenTime start_time
, end_time
;
52 * Optional driver specific data to address a flight.
56 * Flight number, used by the CAI302 driver.
61 * Flight address, used by the IMI ERIXX driver.
67 * File name. Only used by the LXNAV Nano sub-driver. If this
68 * is empty, then the "classic" Colibri protocol is used.
70 char nano_filename
[16];
72 uint8_t start_address
[3];
73 uint8_t end_address
[3];
77 * Flight number, used by the FLARM driver.
82 * Flight number, used by Volkslogger driver
87 * Flight number, used by the Flytec driver.
93 class RecordedFlightList
: public StaticArray
<RecordedFlightInfo
, 128u> {
97 * This is the interface for a device driver.
104 * Called after there has not been any NMEA input on the port for
105 * some time, and XCSoar considers the device "disconnected". The
106 * next EnableNMEA() code should attempt to put the device back to
109 virtual void LinkTimeout() = 0;
112 * Enable NMEA mode. This method is called after opening the
113 * device, after LinkTimeout() and after all other methods that
114 * manipulate the device. If a driver does not need to disable NMEA
115 * mode for a method implementation, this should be a no-op.
117 * The caller is responsible for invoking Port::StartRxThread().
119 virtual bool EnableNMEA(OperationEnvironment
&env
) = 0;
122 * Parse a line of input from the port.
124 * @param info destination for sensor values
125 * @return true when the line has been processed
127 virtual bool ParseNMEA(const char *line
, struct NMEAInfo
&info
) = 0;
130 * Send the new MacCready value to the device.
132 * @param mac_cready the new MacCready value [m/s]
133 * @return true on success
135 virtual bool PutMacCready(fixed mac_cready
, OperationEnvironment
&env
) = 0;
138 * Send the new "bugs" value to the device (degradation of the
141 * @param bugs the new bugs value (XXX define this)
142 * @return true on success
144 virtual bool PutBugs(fixed bugs
, OperationEnvironment
&env
) = 0;
147 * Send the new ballast value to the device.
149 * @param fraction the new ballast value (0=no ballast, 1=full)
150 * @param overload an alternative description of ballast value
151 * @return true on success
153 virtual bool PutBallast(fixed fraction
, fixed overload
,
154 OperationEnvironment
&env
) = 0;
157 * Send the new QNH value to the device.
159 * @param pressure the new QNH
160 * @param calculated the current set of calculation results
161 * @return true on success
163 virtual bool PutQNH(const AtmosphericPressure
&pressure
,
164 OperationEnvironment
&env
) = 0;
167 * Set the radio volume.
169 * @param volume the new volume (0 - 100%)
170 * @return true on success
172 virtual bool PutVolume(unsigned volume
, OperationEnvironment
&env
) = 0;
175 * Set a new radio frequency.
177 * @param frequency the new frequency
178 * @return true on success
180 virtual bool PutActiveFrequency(RadioFrequency frequency
,
181 OperationEnvironment
&env
) = 0;
184 * Set a new "standby" radio frequency.
186 * @param frequency the new frequency
187 * @return true on success
189 virtual bool PutStandbyFrequency(RadioFrequency frequency
,
190 OperationEnvironment
&env
) = 0;
193 * Enable pass-through mode. This may be used to communicate
194 * directly with the device that is "behind" this one (e.g. a LX1600
195 * connected to a FLARM).
197 virtual bool EnablePassThrough(OperationEnvironment
&env
) = 0;
202 * @param declaration the task declaration
203 * @param home the home waypoint, or NULL if not known/configured;
204 * this is not part of the task declaration, but some drivers might
205 * want to send it to the logger during the declaration process
206 * @return true on success
208 virtual bool Declare(const Declaration
&declaration
, const Waypoint
*home
,
209 OperationEnvironment
&env
) = 0;
212 * Read the list of recorded flights.
214 * @param flight_list the flights will be appended to this list
215 * @return true on success
217 virtual bool ReadFlightList(RecordedFlightList
&flight_list
,
218 OperationEnvironment
&env
) = 0;
221 * Download a flight into a file.
223 * @param flight the flight that shall be downloaded
224 * @param path the file name to save to
225 * @return true on success
227 virtual bool DownloadFlight(const RecordedFlightInfo
&flight
,
229 OperationEnvironment
&env
) = 0;
232 * Called periodically each second
234 * @param calculated the current set of calculation results
236 virtual void OnSysTicker() = 0;
239 * Called when data is received and the device is configured to
240 * use the binary data directly.
242 * @return true when the data has been processed,
243 * false if more data is necessary
245 virtual bool DataReceived(const void *data
, size_t length
,
246 struct NMEAInfo
&info
) = 0;
249 * This method is invoked by #MergeThread after each merge,
250 * i.e. each time any device updates its #NMEAInfo object. If there
251 * are many devices or if there is a device with a high output rate,
252 * this method may be called very often. If no device is connected,
253 * it may not be called at all.
255 * It is meant to be implemented by drivers that forward data
256 * quickly to the device, for example an analog vario needle.
258 * Note that this method will be invoked on sensor changes on any
259 * device, including this one.
261 * Caution! This method will be called with the DeviceBlackboard
262 * mutex locked. Therefore it must not block and must be very
263 * careful with obtaining more mutexes, as this may block the whole
266 * @param basic the merged sensor data
268 virtual void OnSensorUpdate(const MoreData
&basic
) = 0;
271 * This method is invoked by the main thread after each
272 * CalculationThread run. It is meant for drivers which want to
273 * send calculation results to the device.
275 virtual void OnCalculatedUpdate(const MoreData
&basic
,
276 const DerivedInfo
&calculated
) = 0;
280 * This class implements all #Device methods. You may use it as a
281 * base class for specific device drivers.
283 class AbstractDevice
: public Device
{
285 virtual void LinkTimeout() override
;
286 virtual bool EnableNMEA(OperationEnvironment
&env
) override
;
288 virtual bool ParseNMEA(const char *line
, struct NMEAInfo
&info
) override
;
290 virtual bool PutMacCready(fixed MacCready
, OperationEnvironment
&env
) override
;
291 virtual bool PutBugs(fixed bugs
, OperationEnvironment
&env
) override
;
292 virtual bool PutBallast(fixed fraction
, fixed overload
,
293 OperationEnvironment
&env
) override
;
294 virtual bool PutQNH(const AtmosphericPressure
&pres
,
295 OperationEnvironment
&env
) override
;
296 virtual bool PutVolume(unsigned volume
, OperationEnvironment
&env
) override
;
297 virtual bool PutActiveFrequency(RadioFrequency frequency
,
298 OperationEnvironment
&env
) override
;
299 virtual bool PutStandbyFrequency(RadioFrequency frequency
,
300 OperationEnvironment
&env
) override
;
302 virtual bool EnablePassThrough(OperationEnvironment
&env
) override
;
304 virtual bool Declare(const Declaration
&declaration
, const Waypoint
*home
,
305 OperationEnvironment
&env
) override
;
307 virtual bool ReadFlightList(RecordedFlightList
&flight_list
,
308 OperationEnvironment
&env
) override
;
310 virtual bool DownloadFlight(const RecordedFlightInfo
&flight
,
312 OperationEnvironment
&env
) override
;
314 virtual void OnSysTicker() override
;
316 virtual bool DataReceived(const void *data
, size_t length
,
317 struct NMEAInfo
&info
) override
;
319 virtual void OnSensorUpdate(const MoreData
&basic
) override
{}
321 virtual void OnCalculatedUpdate(const MoreData
&basic
,
322 const DerivedInfo
&calculated
) override
{}
326 * This is the structure exported by a device driver.
328 struct DeviceRegister
{
331 * Makes XCSoar forward all NMEA input to this device. This is
332 * only used by the "NmeaOut" driver.
337 * Does this driver support task declaration with
343 * Does this device store flight logs which can be downloaded?
344 * See Device::ReadFlightList(), Device::DownloadFlight().
349 * Does this driver support switching to a "bulk" baud rate?
351 BULK_BAUD_RATE
= 0x8,
354 * Does this driver support additional configuration in form
355 * of a "Manage" dialog?
360 * Shall timeout and auto-restart be disabled for this driver?
361 * This flag should be set for devices that are not expected to
362 * send data every second.
367 * Is this device sending GPS data in binary form? The line-based
368 * handler/parser will be disabled in this case.
373 * Is this driver able to receive settings like MC value,
374 * bugs or ballast from the device?
376 RECEIVE_SETTINGS
= 0x80,
379 * Is this driver able to send settings like MC value,
380 * bugs or ballast to the device?
382 SEND_SETTINGS
= 0x100,
385 * Is this driver capable of passing through communication to
386 * another device behind it? This indicates that
387 * EnablePassThrough() is implemented.
389 PASS_THROUGH
= 0x200,
393 * The internal name of the driver, i.e. the one that is stored in
399 * The human-readable name of this driver.
401 const TCHAR
*display_name
;
404 * A bit set describing the features of this driver.
409 * Create an instance of this driver for the given NMEA port.
411 Device
*(*CreateOnPort
)(const DeviceConfig
&config
, Port
&com_port
);
414 * Is this driver able to receive settings like MC value,
415 * bugs or ballast from the device?
417 bool CanReceiveSettings() const {
418 return (flags
& RECEIVE_SETTINGS
) != 0;
422 * Is this driver able to send settings like MC value,
423 * bugs or ballast to the device?
425 bool CanSendSettings() const {
426 return (flags
& SEND_SETTINGS
) != 0;
430 * Is this the NMEA out driver?
432 bool IsNMEAOut() const {
433 return (flags
& NMEA_OUT
) != 0;
437 * Does this driver support task declaration with Device::Declare()?
439 bool CanDeclare() const {
440 return (flags
& DECLARE
) != 0;
444 * Does this device store flight logs which can be downloaded?
445 * See Device::ReadFlightList(), Device::DownloadFlight().
447 bool IsLogger() const {
448 return (flags
& LOGGER
) != 0;
452 * Does this device support additional configuration in form
453 * of a "Manage" dialog?
455 bool IsManageable() const {
456 return (flags
& MANAGE
) != 0;
460 * Does this driver support switching to a "bulk" baud rate?
462 bool SupportsBulkBaudRate() const {
463 return (flags
& BULK_BAUD_RATE
) != 0;
467 * Shall devices be restarted automatically when they time out?
469 bool HasTimeout() const {
470 return (flags
& NO_TIMEOUT
) == 0;
474 * Is this device sending GPS data in binary form? The line-based
475 * handler/parser will be disabled in this case.
477 bool UsesRawData() const {
478 return (flags
& RAW_GPS_DATA
) != 0;
482 * Does this driver implement EnablePassThrough()?
484 bool HasPassThrough() const {
485 return (flags
& PASS_THROUGH
) != 0;