-
Notifications
You must be signed in to change notification settings - Fork 1
/
RH_ABZ.h
198 lines (184 loc) · 9.11 KB
/
RH_ABZ.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// RH_ABZ.h
//
// Definitions for SX1276 radio in muRata CMWX1ZZABZ (TypeABZ) module
// as used in GrumpyOldPizza Grasshopper-L082CZ, EcoNode SmartTrap etc with
// GrumpyOldPizza / ArduinoCore-stm32l0 installed per https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0
//
// For data refer to muRata Application note: AN-ZZABZ-001
// muRata Preliminary Specification Number : SP-ABZ-093-E
// $p/EcoNode
//
// Author: Mike McCauley (mikem@airspayce.com)
// Copyright (C) 2020 Mike McCauley
// $Id: RH_ABZ.h,v 1.1 2020/06/15 23:39:39 mikem Exp $
//
#ifndef RH_ABZ_h
#define RH_ABZ_h
#include <RH_RF95.h>
/////////////////////////////////////////////////////////////////////
/// \class RH_ABZ RH_ABZ.h <RH_ABZ.h>
/// \brief Driver to send and receive unaddressed, unreliable datagrams via
/// radio transceiver in a muRata cmwx1zzabz module, which includes an STM32L0 processor,
/// a SX1276 LoRa radio and an antenna switch.
///
/// Requires the Grumpy Old Pizza Arduino Core installed per https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0
///
/// Works with EcoNode SmartTrap, Tlera Grasshopper and family. Almost any board equipped with a muRata cmwx1zzabz module
/// should work. Tested with EcoNode SmartTrap, Arduino 1.8.9, GrumpyOldPizza Arduino Core for STM32L0.
/// When building for EcoNode SmartTrap in Arduino IDE, select board type Grasshopper-L082CZ.
/// This chip and GrumpyOldPizza Arduino Core for STM32L0 are now supported by PlatformIO:
/// https://docs.platformio.org/en/latest/platforms/ststm32.html#arduino-stm32l0-configuration-system
///
/// \par Overview
///
/// This class is a specialisation of the RH_RF95 class, but with overridden functions to ensure that RH_RF95 communicates
/// with the SX1276 radio on the correct SPI interface (STM32L0_SPI_INSTANCE_SPI1). The class configures the SPI and
/// interfaces with the radio using native stm32l0 calls. It also uses stm32l0 calls to intialise the radio interface pins,
/// antenna interface pins, and to toggle the radio NSS pin for SPI communicaitons. The reason for this speicalisaiton is that
/// all the STM32L0 variants in the Grumpy Pizzas Arduino Core define the Arduino compatible SPI interface and the
/// Arduino compatible IO pins in varying and inconsistent ways. So we use native stm32l0 calls to make _sure_ we get the right
/// pins and interfaces.
///
/// All the comments in the RH_RF95 class concerning modulation, packet formats etc apply equally to this module.
///
/// \par Temperature Controlled Crystal Oscillator (TCXO)
///
/// The muRata cmwx1zzabz module includes a TCXO. Pins to enable the TCXO and to connect to 32MHz output to the radio
/// are exposed on the module. Some boards (Econode SmartTrap for example) permanently power the TCXO and permanenetly
/// connect it to the radio. Other boards (Grasshopper for example) have the TCXO enable connected to a GPIO pin, allowing
/// the TCXO to be controlled by software. Different boards may use different GPIO pins to control the TCXO.
///
/// The SX1276 radio can be configured to use the TCXO, and the Arduino Core defaults the radio to using TCXO.
/// Therefore it is important that you ensure the TCXO is powered up, at least when you want the radio to operate.
/// If the TCXO is not powered, the radio will not work.
///
/// On the Tlera boards supported the Arduino Core, you can call SX1276SetBoardTcxo() to enable or disable the TCXO
/// by controlling the correct pin for your board.
/// By default the core disables TCXO at the end of initialisation, so by the time your sketch starts to run
/// the TCXO is powered off.
/// You will almost certainly need to call
/// \code
/// SX1276SetBoardTcxo(true);
/// \endcode
/// in your setup() or at other times when you want the radio to operate.
///
/// If you have a board where the TCXO is permanently powered, this is unnecessary.
///
/// \par Connecting and configuring the radio
///
/// There is no special configuration for the SX1276 radio in the muRata cmwx1zzabz module: the CPU, radio and
/// antenna switch are all hardwired within the module can, and cannot be changed. Initialise the radio like this
/// with the default constructor:
/// \code
/// RH_ABZ driver;
/// \endcode
///
/// \par Range
///
/// We made some primitive range tests with 2 identical EcoNode SmartTrap at 868MHz, 20dBm transmit power with
/// modem config RH_RF95::Bw125Cr45Sf2048, using the abz_client and abz_server sketches included in this distribution.
/// We monitored for reliabilty of 2-way communications (ie how reliably can the client get a reply from the server,
/// which is a 2-way comms that depends on both send and receive. The SmartTrap has a simple small helical antenna.
/// The environment was a beach in a developed area, one node was stationary
/// on a rock about 1m above sand level. The mobile node was handl-held at 1 m above ground level. All measurements were line-of-sight.
///
/// \code
/// Location Distance (km) % successful round trip
/// Elephant Rock 0 100
/// Dune St 1.48 100
/// Shell St 1.71 100
/// Sand St 1.93 100
/// Sea St 2.15 0
/// Short St 2.36 50
/// John St 2.59 50
/// Surf St 2.80 100
/// Matters St 2.98 100
/// Mills St 3.92 100
/// North Kirra 4.62 0
/// North Kirra SLSC 4.81 80
/// Haig St 5.20 0
/// Kirra SLSC 5.91 0
/// \endcode
///
/// \par Transmitter Power
///
/// We have made some actual power measurements against
/// programmed power on an EcoNode SmartTrap.
/// - EcoNode SmartTrap at 868MHz
/// - 15cm RG316 soldered direct to SmartTrap antenna pin
/// - SMA/BNC connector
/// - 12db attenuator (calibrated as 13.5dB at 868MHz)
/// - SMA/BNC connector
/// - 30cm RG316
/// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
/// - Tektronix TDS220 scope to measure the Vout from power head
/// \code
/// useRFO==false (ie uses PA_BOOST for higher power)
/// Program power Measured Power
/// dBm dBm
/// 2 2.7
/// 5 5
/// 7 6.5
/// 10 9.5
/// 13 12.5
/// 15 14.5
/// 16 15.5
/// 17 16.5
/// 18 17.2
/// 19 17.6
/// 20 18.2
///
/// useRFO==true (ie no PA_BOOST)
/// Program power Measured Power
/// dBm dBm
/// 0 -5.5
/// 2 -2.5
/// 4 -0.5
/// 6 2
/// 8 4
/// 10 6.5
/// 12 9
/// 13 10.5
/// 14 11.5
/// 15 12.5
/// \endcode
/// In the the Grumpy Old Pizza Arduino Core, there is a function for turning the
/// TCXO power source on and off, which depends on exactly which board is being compiled for
/// If the Radio in your boards has its TCXO connected to a programmable power pin,
/// and if you enable TCXO on the radio (by default it is on these boards)
/// then this function needs to be called to enable the TCXO before the radio will work.
extern "C" void SX1276SetBoardTcxo( bool state );
class RH_ABZ : public RH_RF95
{
public:
/// Constructor
RH_ABZ();
/// Initialise the Driver transport hardware and software. Leaves the radio in idle mode,
/// with default configuration of: 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
/// \return true if initialisation succeeded.
virtual bool init();
/// Deinitialise the interrupt handler, allowing the radio to be temporarily used by another stack.
/// If you wish to use the radio again after this call, you wil need to call init() again.
/// \return true if deinitialisation succeeded.
bool deinit();
protected:
/// Called by RH_RF95 when the radio mode is about to change to a new setting.
/// Configures the antenna switch to connect to the right radio pin.
/// \param[in] mode RHMode the new mode about to take effect
/// \return true if the subclasses changes successful
virtual bool modeWillChange(RHMode mode);
/// Called by RHSPIDriver when the SPI is about to talk to the radio.
/// Uses native spi32l0 calls to enable the radio NSS pin
virtual void selectSlave();
/// Called by RHSPIDriver when the SPI is finished talking to the radio.
/// Uses native spi32l0 calls to disable the radio NSS pin
virtual void deselectSlave();
private:
/// Glue code between the DIO0 interrupt the interrupt handler in RH_RF95
static void RH_INTERRUPT_ATTR isr();
/// Pointer to the one and only instance permitted, for interrupt linkage
static RH_ABZ* _thisDevice;
};
/// @example abz_client.pde
/// @example abz_server.pde
#endif