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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
|
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
©2013 Semtech-Cycleo
Lora Gateway HAL user manual
============================
1. Introduction
---------------
The Lora Gateway Hardware Abstraction Layer is a C library that allow you to
use a Semtech Lora gateway hardware through a reduced number of high level C
functions to configure the hardware, send and receive packets.
The Semtech Lora gateway is a digital multi-channel multi-standard packet radio
used to send and receive packets wirelessly using Lora or FSK modulations.
2. Components of the library
----------------------------
The library is composed of 5 modules:
* loragw_hal
* loragw_reg
* loragw_spi
* loragw_aux
* loragw_gps
The library also contains 4 test programs to demonstrate code use and check
functionality.
### 2.1. loragw_hal ###
This is the main module and contains the high level functions to configure and
use the Lora gateway:
* lgw_rxrf_setconf, to set the configuration of the radio channels
* lgw_rxif_setconf, to set the configuration of the IF+modem channels
* lgw_start, to apply the set configuration to the hardware and start it
* lgw_stop, to stop the hardware
* lgw_receive, to fetch packets if any was received
* lgw_send, to send a single packet (non-blocking, see warning in usage section)
* lgw_status, to check when a packet has effectively been sent
For an standard application, include only this module.
The use of this module is detailed on the usage section.
### 2.2. loragw_reg ###
This module is used to access to the Lora gateway registers by name instead of
by address:
* lgw_connect, to initialise and check the connection with the hardware
* lgw_disconnect, to disconnect the hardware
* lgw_soft_reset, to reset the whole hardware by resetting the register array
* lgw_reg_check, to check all registers vs. their default value and output the
result to a file
* lgw_reg_r, read a named register
* lgw_reg_w, write a named register
* lgw_reg_rb, read a name register in burst
* lgw_reg_wb, write a named register in burst
This module handles pagination, read-only registers protection, multi-byte
registers management, signed registers management, read-modify-write routines
for sub-byte registers and read/write burst fragmentation to respect SPI
maximum burst length constraints.
It make the code much easier to read and to debug.
Moreover, if registers are relocated between different hardware revisions but
keep the same function, the code written using register names can be reused "as
is".
If you need access to all the registers, include this module in your
application.
**/!\ Warning** please be sure to have a good understanding of the Lora gateway
inner working before accessing the internal registers directly.
### 2.3. loragw_spi ###
This module contains the functions to access the Lora gateway register array
through the SPI interface:
* lgw_spi_r to read one byte
* lgw_spi_w to write one byte
* lgw_spi_rb to read two bytes or more
* lgw_spi_wb to write two bytes or more
Please *do not* include that module directly into your application.
**/!\ Warning** Accessing the Lora gateway register array without the checks
and safety provided by the functions in loragw_reg is not recommended.
### 2.4. loragw_aux ###
This module contains a single host-dependant function wait_ms to pause for a
defined amount of milliseconds.
The procedure to start and configure the Lora gateway hardware contained in the
loragw_hal module requires to wait for several milliseconds at certain steps,
typically to allow for supply voltages or clocks to stabilize after been
switched on.
An accuracy of 1 ms or less is ideal.
If your system doesn't allow that level of accuracy, make sure that the actual
delay is *longer* that the time specified when the function is called (ie.
wait_ms(X) *MUST NOT* before X milliseconds under any circumstance).
If the minimum delays are not guaranteed during the configuration and start
procedure, the hardware might not work at nominal performance.
Most likely, it will not work at all.
### 2.5. loragw_gps ###
This module contains functions to synchronize the concentrator internal
counter with an absolute time reference, in our case a GPS satellite receiver.
The internal concentrator counter is used to timestamp incoming packets and to
triggers outgoing packets with a microsecond accuracy.
In some cases, it might be useful to be able to transform that internal
timestamp (that is independent for each concentrator running in a typical
networked system) into an absolute UTC time.
In a typical implementation a GPS specific thread will be called, doing the
following things after opening the serial port:
* blocking reads on the serial port (using system read() function)
* parse NMEA sentences (using lgw_parse_nmea)
And each time an RMC sentence has been received:
* get the concentrator timestamp (using lgw_get_trigcnt, mutex needed to
protect access to the concentrator)
* get the UTC time contained in the NMEA sentence (using lgw_gps_get)
* call the lgw_gps_sync function (use mutex to protect the time reference that
should be a global shared variable).
Then, in other threads, you can simply used that continuously adjusted time
reference to convert internal timestamps to UTC time (using lgw_cnt2utc) or
the other way around (using lgw_utc2cnt).
3. Software dependencies
------------------------
The library is written following ANSI C conventions but using C99 explicit
length data type for all data exchanges with hardware and for parameters.
The loragw_aux module contains POSIX dependant functions for millisecond
accuracy pause.
For embedded platforms, the function could be rewritten using hardware times.
All modules use the fprintf(stderr,...) function to display debug diagnostic
messages if the DEBUG_xxx is set to 1 in library.cfg
Depending on config, SPI module needs LibMPSSE to access the FTDI SPI-over-USB
bridge. Please go to that URL to download that library:
http://code.google.com/p/libmpsse/
The code was tested with version 1.3 of LibMPSSE:
http://libmpsse.googlecode.com/files/libmpsse-1.3.tar.gz
SHA1 Checksum: 1b994a23b118f83144261e3e786c43df74a81cd5
That library has some dependencies itself, please read the installation
instructions.
4. Hardware dependencies
------------------------
### 4.1. Hardware revision ###
The loragw_reg and loragw_hal are written for a specific version on the Semtech
hardware (IP and/or silicon revision).
All relevant details are contained in the VERSION.TXT file.
The library will not work if there is a mismatch between the hardware version
and the library version. You can use the test program test_loragw_reg to check
if the hardware registers match their software declaration.
### 4.2. SPI communication ###
loragw_spi contains 4 SPI functions (read, write, burst read, burst write) that
are platform-dependant.
The functions must be rewritten depending on the SPI bridge you use:
* SPI master matched to the Linux SPI device driver (provided)
* SPI over USB using FTDI components (provided)
* native SPI using a microcontroller peripheral (not provided)
Edit library.cfg to chose which SPI physical interface you want to use.
You can use the test program test_loragw_spi to check with a logic analyser
that the SPI communication is working
### 4.3. GPS receiver (or other GNSS system) ###
To use the GPS module of the library, the host must be connected to a GPS
receiver via a serial link (or an equivalent receiver using a different
satellite constellation).
The serial link must appear as a "tty" device in the /dev/ directory, and the
user launching the program must have the proper system rights to read and
write on that device.
Use `chmod a+rw` to allow all users to access that specific tty device, or use
sudo to run all your programs (eg. `sudo ./test_loragw_gps`).
In the current revision, the library only reads data from the serial port,
expecting to receive NMEA frames that are generally sent by GPS receivers as
soon as they are powered up.
The GPS receiver __MUST__ send RMC NMEA sentences (starting with "$G<any
character>RMC") shortly after sending a PPS pulse on to allow internal
concentrator timestamps to be converted to absolute UTC time.
If the GPS receiver sends a GGA sentence, the gateway 3D position will also be
available.
The PPS pulse must be sent to the pin 22 of connector CONN400 on the Semtech
FPGA-based nano-concentrator board. Ground is available on pins 2 and 12 of
the same connector.
The pin is loaded by an FPGA internal pull-down, and the signal level coming
in the FPGA must be 3.3V.
Timing is captured on the rising edge of the PPS signal.
5. Usage
--------
### 5.1. Setting the software environment ###
For a typical application you need to:
* include loragw_hal.h in your program source
* link to the libloragw.a static library during compilation
* link to the librt library due to loragw_aux dependencies (timing functions)
* link to the libmpsse library if you use a FTDI SPI-over-USB bridge
For an application that will also access the concentrator configuration
registers directly (eg. for advanced configuration) you also need to:
* include loragw_reg.h in your program source
### 5.2. Using the software API ###
To use the HAL in your application, you must follow some basic rules:
* configure the radios path and IF+modem path before starting the radio
* the configuration is only transferred to hardware when you call the *start*
function
* you cannot receive packets until one (or +) radio is enabled AND one (or +)
IF+modem part is enabled AND the gateway is started
* you cannot send packets until one (or +) radio is enabled AND the gateway is
started
* you must stop the gateway before changing the configuration
A typical application flow for using the HAL is the following:
<configure the radios and IF+modems>
<start the Lora gateway>
loop {
<fetch packets that were received by the gateway>
<process, store and/or forward received packets>
<send packets through the gateway>
}
<stop the gateway>
**/!\ Warning** The lgw_send function is non-blocking and returns while the
Lora gateway is still sending the packet, or even before the packet has started
to be transmitted if the packet is triggered on a future event.
While a packet is emitted, no packet can be received (limitation intrinsic to
most radio frequency systems).
Your application *must* take into account the time it takes to send a packet or
check the status (using lgw_status) before attempting to send another packet.
Trying to send a packet while the previous packet has not finished being send
will result in the previous packet not being sent or being sent only partially
(resulting in a CRC error in the receiver).
### 5.3. Debugging mode ###
To debug your application, it might help to compile the loragw_hal function
with the debug messages activated (set DEBUG_HAL=1 in library.cfg).
It then send a lot of details, including detailed error messages to *stderr*.
*EOF*
|