Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
LoRaWAN benchmark
RIOT - IM880B
Commits
ee520636
Commit
ee520636
authored
Apr 26, 2019
by
Guillaume Gonnet
Browse files
Continue driver module implementation.
parent
a56a4bff
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
562 additions
and
6 deletions
+562
-6
Makefile
Makefile
+1
-1
src/app/Makefile
src/app/Makefile
+1
-0
src/app/drivers/ds75lx.h
src/app/drivers/ds75lx.h
+1
-0
src/app/drivers/gps.c
src/app/drivers/gps.c
+507
-5
src/app/drivers/gps.h
src/app/drivers/gps.h
+52
-0
No files found.
Makefile
View file @
ee520636
...
...
@@ -37,7 +37,7 @@ USEMODULE += cubsat-app
# USEMODULE += cubsat-app-benchmark
USEMODULE
+=
cubsat-app-cmds
USEMODULE
+=
cubsat-app-providers
#
USEMODULE += cubsat-app-drivers
USEMODULE
+=
cubsat-app-drivers
USEMODULE
+=
lorariot-ctrl
USEMODULE
+=
lorariot-adapter
USEMODULE
+=
lorariot-region
...
...
src/app/Makefile
View file @
ee520636
...
...
@@ -8,6 +8,7 @@ MODULE := cubsat-app
DIRS
+=
commands
DIRS
+=
providers
DIRS
+=
drivers
INCLUDES
+=
$(LORARIOT_INC)
-I
$(CURDIR)
...
...
src/app/drivers/ds75lx.h
View file @
ee520636
...
...
@@ -2,6 +2,7 @@
Driver for the DS75LX digital thermometer.
Copyright (C) 2019, ENSIMAG students
This file is based on DS75LX module from IBM LMIC, under Eclipse Public License
v1.0.
...
...
src/app/drivers/gps.c
View file @
ee520636
...
...
@@ -3,19 +3,521 @@
Decode GPS data.
Copyright (C) 2019, ENSIMAG students
This
project is under the MIT l
icense
This
file is based on LoRaMAC-node from Semtech, under Revised BSD L
icense
.
*/
#include "app.h"
gps_isr_info_t
gps_isr_info
=
{
MUTEX_INIT
,
0
,
0
,
"
\0
"
};
uint8_t
gps_parse_data
(
void
)
{
// TODO.
// TODO
: limit update
.
return
0
;
}
#define TRIGGER_GPS_CNT 10
// Various type of NMEA data we can receive with the GPS.
static
const
char
NmeaDataTypeGPGGA
[]
=
"GPGGA"
;
static
const
char
NmeaDataTypeGPRMC
[]
=
"GPRMC"
;
// Value used for the conversion of the position from DMS to decimal.
static
const
int32_t
MaxNorthPosition
=
8388607
;
// 2^23 - 1
static
const
int32_t
MaxSouthPosition
=
8388608
;
// -2^23
static
const
int32_t
MaxEastPosition
=
8388607
;
// 2^23 - 1
static
const
int32_t
MaxWestPosition
=
8388608
;
// -2^23
gps_nmea_t
gps_nmea
;
// Parsed data in double and binary formats.
static
double
HasFix
=
false
;
static
double
latitude
=
0
;
static
double
longitude
=
0
;
static
int32_t
latitude_bin
=
0
;
static
int32_t
longitude_bin
=
0
;
static
int16_t
altitude
=
0xFFFF
;
// Get the lastest GPS position in binary format.
uint8_t
gps_position_binary
(
int32_t
*
latiBin
,
int32_t
*
longiBin
)
{
// TODO: lock mutex
uint8_t
status
=
HasFix
?
GPS_SUCCESS
:
GPS_FAIL
;
if
(
!
HasFix
)
GpsResetPosition
();
*
latiBin
=
LatitudeBinary
;
*
longiBin
=
LongitudeBinary
;
return
status
;
}
// Get the lastest GPS altitude.
int16_t
gps_altitude
(
void
)
{
// TODO: lock mutex
BoardDisableIrq
(
);
if
(
HasFix
==
true
)
{
Altitude
=
atoi
(
NmeaGpsData
.
NmeaAltitude
);
}
else
{
Altitude
=
0xFFFF
;
}
BoardEnableIrq
(
);
return
Altitude
;
}
void
GpsConvertPositionIntoBinary
(
void
)
{
long
double
temp
;
if
(
latitude
>=
0
)
{
// North
temp
=
latitude
*
MaxNorthPosition
;
latitude_bin
=
temp
/
90
;
}
else
{
// South
temp
=
latitude
*
MaxSouthPosition
;
latitude_bin
=
temp
/
90
;
}
if
(
longitude
>=
0
)
{
// East
temp
=
longitude
*
MaxEastPosition
;
longitude_bin
=
temp
/
180
;
}
else
{
// West
temp
=
longitude
*
MaxWestPosition
;
longitude_bin
=
temp
/
180
;
}
}
// Convert GPS positions from ASCII to double values.
static
void
positions_to_double
(
void
)
{
double
valueTmp1
,
valueTmp2
,
valueTmp3
,
valueTmp4
;
// Convert the latitude from ASCII to uint8_t values.
for
(
int
i
=
0
;
i
<
10
;
i
++
)
gps_nmea
.
latitude
[
i
]
=
gps_nmea
.
latitude
[
i
]
&
0xF
;
// Convert latitude from degree/minute/second (DMS) format into decimal.
valueTmp1
=
(
double
)
gps_nmea
.
latitude
[
0
]
*
10
.
0
+
(
double
)
gps_nmea
.
latitude
[
1
];
valueTmp2
=
(
double
)
gps_nmea
.
latitude
[
2
]
*
10
.
0
+
(
double
)
gps_nmea
.
latitude
[
3
];
valueTmp3
=
(
double
)
gps_nmea
.
latitude
[
5
]
*
1000
.
0
+
(
double
)
gps_nmea
.
latitude
[
6
]
*
100
.
0
+
(
double
)
gps_nmea
.
latitude
[
7
]
*
10
.
0
+
(
double
)
gps_nmea
.
latitude
[
8
];
latitude
=
valueTmp1
+
((
valueTmp2
+
(
valueTmp3
*
0
.
0001
))
/
60
.
0
);
if
(
gps_nmea
.
latitude_pole
[
0
]
==
'S'
)
latitude
*=
-
1
;
// Convert the longitude from ASCII to uint8_t values.
for
(
int
i
=
0
;
i
<
10
;
i
++
)
gps_nmea
.
longitude
[
i
]
=
gps_nmea
.
longitude
[
i
]
&
0xF
;
// Convert longitude from degree/minute/second (DMS) format into decimal.
valueTmp1
=
(
double
)
gps_nmea
.
longitude
[
0
]
*
100
.
0
+
(
double
)
gps_nmea
.
longitude
[
1
]
*
10
.
0
+
(
double
)
gps_nmea
.
longitude
[
2
];
valueTmp2
=
(
double
)
gps_nmea
.
longitude
[
3
]
*
10
.
0
+
(
double
)
gps_nmea
.
longitude
[
4
];
valueTmp3
=
(
double
)
gps_nmea
.
longitude
[
6
]
*
1000
.
0
+
(
double
)
gps_nmea
.
longitude
[
7
]
*
100
;
valueTmp4
=
(
double
)
gps_nmea
.
longitude
[
8
]
*
10
.
0
+
(
double
)
gps_nmea
.
longitude
[
9
];
longitude
=
valueTmp1
+
(
valueTmp2
/
60
.
0
)
+
(((
valueTmp3
+
valueTmp4
)
*
0
.
0001
)
/
60
.
0
);
if
(
gps_nmea
.
longitude_pole
[
0
]
==
'W'
)
Longitude
*=
-
1
;
}
// Calculates the checksum for a NMEA sentence (and return the position of the
// checksum in the sentence).
static
int32_t
nmea_checksum
(
int8_t
*
nmeaStr
,
int32_t
nmeaStrSize
,
int8_t
*
checksum
)
{
int
i
=
0
;
uint8_t
checkNum
=
0
;
if
((
nmeaStr
==
NULL
)
||
(
checksum
==
NULL
)
||
(
nmeaStrSize
<=
1
))
return
-
1
;
if
(
nmeaStr
[
i
]
==
'$'
)
i
+=
1
;
// Skip the first '$' if necessary.
while
(
nmeaStr
[
i
]
!=
'*'
)
{
checkNum
^=
nmeaStr
[
i
];
// XOR until '*' or max length is reached.
i
+=
1
;
if
(
i
>=
nmeaStrSize
)
return
-
1
;
}
// Convert checksum value to 2 hexadecimal characters.
checksum
[
0
]
=
Nibble2HexChar
(
checkNum
/
16
);
// upper nibble
checksum
[
1
]
=
Nibble2HexChar
(
checkNum
%
16
);
// lower nibble
return
i
+
1
;
}
// Calculate the checksum of a NMEA frame and compare it to the checksum that
// is present at the end of it (return true if it matches).
static
bool
nmea_validate_checksum
(
int8_t
*
serialBuff
,
int32_t
buffSize
)
{
int32_t
checksumIndex
;
int8_t
checksum
[
2
];
// 2 characters to calculate NMEA checksum.
checksumIndex
=
nmea_checksum
(
serialBuff
,
buffSize
,
checksum
);
if
(
checksumIndex
<
0
)
return
false
;
if
(
checksumIndex
>=
(
buffSize
-
2
))
return
false
;
// Not enough char in the serial buffer to read checksum.
return
// Check the checksum.
(
serialBuff
[
checksumIndex
+
0
]
==
checksum
[
0
])
&&
(
serialBuff
[
checksumIndex
+
1
]
==
checksum
[
1
]);
}
// TODO: rename this function.
uint8_t
GpsParseGpsData
(
int8_t
*
rxBuffer
,
int32_t
rxBufferSize
)
{
uint8_t
i
=
1
;
uint8_t
j
=
0
;
if
(
!
nmea_validate_checksum
(
rxBuffer
,
rxBufferSize
))
return
GPS_FAIL
;
uint8_t
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
6
)
return
GPS_FAIL
;
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
gps_nmea
.
data_type
[
j
]
=
rxBuffer
[
i
];
// Parse the GPGGA data.
if
(
strncmp
(
gps_nmea
.
data_type
,
NmeaDataTypeGPGGA
,
5
)
==
0
)
{
// NmeaUtcTime
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
11
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaUtcTime
[
j
]
=
rxBuffer
[
i
];
}
// NmeaLatitude
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
10
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaLatitude
[
j
]
=
rxBuffer
[
i
];
}
// NmeaLatitudePole
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
2
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaLatitudePole
[
j
]
=
rxBuffer
[
i
];
}
// NmeaLongitude
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
11
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaLongitude
[
j
]
=
rxBuffer
[
i
];
}
// NmeaLongitudePole
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
2
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaLongitudePole
[
j
]
=
rxBuffer
[
i
];
}
// NmeaFixQuality
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
2
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaFixQuality
[
j
]
=
rxBuffer
[
i
];
}
// NmeaSatelliteTracked
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
3
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaSatelliteTracked
[
j
]
=
rxBuffer
[
i
];
}
// NmeaHorizontalDilution
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
6
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaHorizontalDilution
[
j
]
=
rxBuffer
[
i
];
}
// NmeaAltitude
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
8
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaAltitude
[
j
]
=
rxBuffer
[
i
];
}
// NmeaAltitudeUnit
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
2
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaAltitudeUnit
[
j
]
=
rxBuffer
[
i
];
}
// NmeaHeightGeoid
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
8
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaHeightGeoid
[
j
]
=
rxBuffer
[
i
];
}
// NmeaHeightGeoidUnit
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
2
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaHeightGeoidUnit
[
j
]
=
rxBuffer
[
i
];
}
GpsFormatGpsData
(
);
return
SUCCESS
;
}
else
if
(
strncmp
(
NmeaGpsData
.
NmeaDataType
,
NmeaDataTypeGPRMC
,
5
)
==
0
)
{
// NmeaUtcTime
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
11
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaUtcTime
[
j
]
=
rxBuffer
[
i
];
}
// NmeaDataStatus
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
2
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaDataStatus
[
j
]
=
rxBuffer
[
i
];
}
// NmeaLatitude
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
10
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaLatitude
[
j
]
=
rxBuffer
[
i
];
}
// NmeaLatitudePole
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
2
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaLatitudePole
[
j
]
=
rxBuffer
[
i
];
}
// NmeaLongitude
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
11
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
gps_nmea
.
NmeaLongitude
[
j
]
=
rxBuffer
[
i
];
}
// NmeaLongitudePole
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
2
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
NmeaGpsData
.
NmeaLongitudePole
[
j
]
=
rxBuffer
[
i
];
}
// NmeaSpeed
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
8
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
NmeaGpsData
.
NmeaSpeed
[
j
]
=
rxBuffer
[
i
];
}
// NmeaDetectionAngle
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
8
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
NmeaGpsData
.
NmeaDetectionAngle
[
j
]
=
rxBuffer
[
i
];
}
// NmeaDate
fieldSize
=
0
;
while
(
rxBuffer
[
i
+
fieldSize
++
]
!=
','
)
{
if
(
fieldSize
>
8
)
{
return
FAIL
;
}
}
for
(
j
=
0
;
j
<
fieldSize
;
j
++
,
i
++
)
{
NmeaGpsData
.
NmeaDate
[
j
]
=
rxBuffer
[
i
];
}
GpsFormatGpsData
(
);
return
SUCCESS
;
}
else
{
return
GPS_FAIL
;
}
}
void
GpsFormatGpsData
(
void
)
{
if
(
strncmp
(
(
const
char
*
)
NmeaGpsData
.
NmeaDataType
,
(
const
char
*
)
NmeaDataTypeGPGGA
,
5
)
==
0
)
{
HasFix
=
(
NmeaGpsData
.
NmeaFixQuality
[
0
]
>
0x30
)
?
true
:
false
;
}
else
if
(
strncmp
(
(
const
char
*
)
NmeaGpsData
.
NmeaDataType
,
(
const
char
*
)
NmeaDataTypeGPRMC
,
5
)
==
0
)
{
HasFix
=
(
NmeaGpsData
.
NmeaDataStatus
[
0
]
==
0x41
)
?
true
:
false
;
}
positions_to_double
(
);
GpsConvertPositionIntoBinary
(
);
}
void
GpsResetPosition
(
void
)
{
Altitude
=
0xFFFF
;
Latitude
=
0
;
Longitude
=
0
;
LatitudeBinary
=
0
;
LongitudeBinary
=
0
;
}
src/app/drivers/gps.h
0 → 100644
View file @
ee520636
/*
Decode GPS data.
Copyright (C) 2019, ENSIMAG students
This file is based on LoRaMAC-node from Semtech, under Revised BSD License.
*/
#pragma once
// Return codes.
#define GPS_SUCCESS 0
#define GPS_FAIL 1
// Store the GPS parsed data in ASCII.
typedef
struct
{
char
data_type
[
6
];
char
utc_time
[
11
];
char
data_status
[
2
];
char
latitude
[
10
];
char
latitude_pole
[
2
];
char
longitude
[
11
];
char
longitude_pole
[
2
];
char
fix_quality
[
2
];
char
satellite_tracked
[
3
];
char
horizontal_dilution
[
6
];
char
altitude
[
8
];
char
altitude_unit
[
2
];
char
height_geoid
[
8
];
char
height_geoid_unit
[
2
];
char
speed
[
8
];
char
detection_angle
[
8
];
char
date
[
8
];
}
gps_nmea_t
;
/**
* @brief Get the lastest GPS position in binary format.
* @param latiBin Where to store the latitude.
* @param latiBin Where to store the longitude.
* @return Either `GPS_SUCCESS` or `GPS_FAIL`.
*/
uint8_t
gps_position_binary
(
int32_t
*
latiBin
,
int32_t
*
longiBin
);
/**
* @brief Get the lastest GPS altitude.
* @return Altitude (in m) or `0xFFFF` on error.
*/
int16_t
gps_altitude
(
void
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment