-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPikoFox.h
139 lines (111 loc) · 3.09 KB
/
PikoFox.h
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef PIKOFOX_H
#define PIKOFOX_H
/* Author: Matthew Van Gundy */
#if (ARDUINO < 100)
#include <WProgram.h>
#else
#include <Arduino.h>
#endif
#include <MorseASK.h>
#define PF_MAX(a,b) ((a) > (b) ? (a) : (b))
// instantiate virtualwire and MorseASK
// Add ability to write entire message to MorseASK
//
// Data:
// - inter_packet_delay
// - packets_per_round
// - cw_message
// - to_call_sign
// - from_call_sign
// - courtesy_delay
// - radio_pin
// - bit_rate
#define PF_ACTIVE_HIGH MorseASK::ACTIVE_HIGH
#define PF_ACTIVE_LOW MorseASK::ACTIVE_LOW
class PF_Fox {
static const char DEFAULT_MSG[];
public:
PF_Fox(byte radioPin, byte id, byte nfoxes, const char *toCall, const char *fromCall,
const char *cwMsg = DEFAULT_MSG,
uint32_t pktDelayMS = 1000, byte pktsPerRound = 30, float courtesyDelayFactor = 1.05,
uint16_t bitRate = 500, uint8_t cwWPM = 10, bool activeLevel = PF_ACTIVE_LOW);
bool cwMessage(const char *cwMsg);
bool available();
void run();
private:
typedef void (PF_Fox::*StateFunc)();
byte foxId;
byte totalFoxes;
const char *toCall;
const char *fromCall;
const char *cwMsg;
uint32_t pktDelay; // in milliseconds
byte pktsPerRound;
float courtesyDelayFactor;
MorseASK morseTx;
uint32_t seq;
StateFunc state;
void init();
void txPkt();
void txCW();
void courtesyWait();
};
// forward declarations :-/
class PF_AnyMsg;
struct PF_Msg {
static const byte INVALID_MSG;
static const byte ID_MSG;
static const byte BEACON_MSG;
byte foxId;
uint32_t seq;
byte type() { return tag; }
// TODO: ntoh(), hton()
protected:
byte tag;
PF_Msg() : PF_Msg(INVALID_MSG, -1, 0) { };
PF_Msg(byte tag) : PF_Msg(tag, -1, 0) { };
PF_Msg(byte tag, byte id, uint32_t seq) : tag(tag), foxId(id), seq(seq) { }
static PF_Msg* init(PF_Msg *msg, byte tag);
friend class PF_AnyMsg;
};
struct PF_IdMsg : public PF_Msg {
char to[9];
char from[9];
PF_IdMsg();
static PF_IdMsg* init(PF_AnyMsg *msg);
static PF_IdMsg* init(PF_IdMsg *msg);
void setto(const char *call, size_t callLen);
void setfrom(const char *call, size_t callLen);
};
struct PF_BeaconMsg : public PF_Msg {
PF_BeaconMsg();
static PF_BeaconMsg* init(PF_AnyMsg *msg);
static PF_BeaconMsg* init(PF_BeaconMsg *msg);
};
class PF_AnyMsg {
union {
PF_Msg base;
PF_IdMsg id;
PF_BeaconMsg beacon;
};
friend class PF_IdMsg;
friend class PF_BeaconMsg;
public:
PF_AnyMsg() : base() { };
PF_AnyMsg(const PF_AnyMsg &o) : base(o.base) { };
// Return current message type
inline byte type() const;
// If PF_AnyMsg is of the requested type, these functions will
// return a non-NULL pointer. Returns NULL otherwise.
PF_Msg* toMsg(uint16_t len);
PF_IdMsg* toIdMsg(uint16_t len);
PF_BeaconMsg* toBeaconMsg(uint16_t len);
};
struct PF_Util {
static void zeroCopy(byte *to, size_t toLen, byte *from, size_t fromLen);
};
#define PF_MAX_MSG_LEN \
PF_MAX(sizeof(PF_Msg), \
PF_MAX(sizeof(PF_IdMsg), \
sizeof(PF_BeaconMsg)))
#endif