summaryrefslogtreecommitdiff
path: root/protocol.hpp
blob: c71b7d32a7621f27de4c8c783eb237d287d9abab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#ifndef THROTTLE_QUADRANT_PROTOCOL_HPP
#define THROTTLE_QUADRANT_PROTOCOL_HPP

#include "utilities.hpp"

#include <Arduino.h>

//! All our custom code lives in its own name space to avoid collisions.
namespace tq::protocol {

//! A message as received from the throttle quadrant.
struct [[gnu::packed]] message {
  //! The current throttle value (unit TBD).
  byte throttle;
  //! The current propeller speed value (unit TBD).
  byte propeller_speed;
  //! The current mixture value (unit TBD).
  byte mixture;

  //! The state (pressed/released) of the first trigger.
  byte trigger_1 : 1;
  //! The state (pressed/released) of the second trigger.
  byte trigger_2 : 1;
  //! The state (pressed/released) of the third trigger.
  byte trigger_3 : 1;
  //! The state (pressed/released) of the fourth trigger.
  byte trigger_4 : 1;
  //! The state (pressed/released) of the fifth trigger.
  byte trigger_5 : 1;
  //! The state (pressed/released) of the sixth trigger.
  byte trigger_6 : 1;

  //! Whether the throttle is idle or not.
  byte throttle_idle : 1;

  //! Whether the throttle is feathered or not (?).
  byte propeller_feather : 1;

  //! Whether the mixture is cut off or not.
  byte mixture_cutoff : 1;

  //! Reserved bits.
  byte : 7;
};

//! Initialize the protocol handling subsystem.
auto init() -> void;

//! Start a run of the protocol handling subsystem.
//!
//! A new run is only started if there is not current run ongoing.
//!
//! @return true iff. a new run was started, false otherwise.
auto start() -> bool;

//! Perform the synchronous SPI transfer, if one is pending.
//!
//! Perform the final synchronous transfer from the throttle quadrant. If no
//! new data is available, an empty optional is returned.
//!
//! @return An optional object containing a new message if one is available.
auto perform_transfer() -> optional<message>;

//! @internal
//! Process the "data ready" signal coming from the throttle quadrant.
//!
//! When the throttle quadrant pulls the "data ready" line low, we know that
//! there is new data available to be read out. We must adhere to a somewhat
//! strict timing protocol, as detailed in the implemenation of this function.
auto on_data_ready() -> void;

//! @internal
//! Process the "start delay" signal coming from the throttle quadrant.
//!
//! After notifying us about the data being ready, the "data ready" line will
//! be deasserted. However, we must wait an additional 1.2ms before we start
//! the transfer.
auto on_start_delay() -> void;

//! @internal
//! Process the end of the start delay.
//!
//! The data is of the throttle quadrant is now ready to be read.
auto on_start_delay_passed() -> void;

}

#endif