kopia lustrzana https://github.com/DL7AD/pecanpico10
Work in progress (note: POS may not be functional in this rev)
- Revise config.c structure to move items out to global level - Rework collector to be service style thread - Reworking beacon.c to become telem service for both DIGI and POSpull/4/head
rodzic
1ea876b6a8
commit
684ab321e2
|
@ -29,7 +29,6 @@
|
|||
#define _CHCONF_H_
|
||||
|
||||
#define _CHIBIOS_RT_CONF_
|
||||
#define _CHIBIOS_RT_CONF_VER_5_0_
|
||||
#define _CHIBIOS_RT_CONF_VER_6_0_
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -86,10 +86,12 @@ const SerialConfig debug_config = {
|
|||
/*===========================================================================*/
|
||||
|
||||
void pktConfigSerialDiag(void) {
|
||||
#if ENABLE_EXTERNAL_I2C == FALSE
|
||||
/* USART3 TX. */
|
||||
palSetLineMode(LINE_USART3_TX, PAL_MODE_ALTERNATE(7));
|
||||
/* USART3 RX. */
|
||||
palSetLineMode(LINE_USART3_RX, PAL_MODE_ALTERNATE(7));
|
||||
#endif
|
||||
}
|
||||
|
||||
void pktConfigSerialPkt(void) {
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
//#define LINE_UART4_RX PAL_LINE(GPIOA, 11U)
|
||||
|
||||
/* The external port can be used for bit bang I2C. */
|
||||
#define ENABLE_EXTERNAL_I2C FALSE
|
||||
#define ENABLE_EXTERNAL_I2C TRUE
|
||||
|
||||
#if ENABLE_EXTERNAL_I2C == FALSE
|
||||
#define LINE_USART3_TX LINE_IO_TXD
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#define _CHCONF_H_
|
||||
|
||||
#define _CHIBIOS_RT_CONF_
|
||||
#define _CHIBIOS_RT_CONF_VER_5_0_
|
||||
#define _CHIBIOS_RT_CONF_VER_6_0_
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -12,7 +12,7 @@ conf_t conf_sram;
|
|||
const conf_t conf_flash_default = {
|
||||
// Primary position app
|
||||
.pos_pri = {
|
||||
.thread_conf = {
|
||||
.svc_conf = {
|
||||
.active = false,
|
||||
.cycle = TIME_S2I(60 * 5),
|
||||
.init_delay = TIME_S2I(30)
|
||||
|
@ -29,12 +29,12 @@ const conf_t conf_flash_default = {
|
|||
.symbol = SYM_ANTENNA,
|
||||
.aprs_msg = true,
|
||||
// How often to send telemetry config
|
||||
.tel_enc_cycle = TIME_S2I(60 * 60)
|
||||
//.tel_enc_cycle = TIME_S2I(60 * 60)
|
||||
},
|
||||
|
||||
// Secondary position app
|
||||
.pos_sec = {
|
||||
.thread_conf = {
|
||||
.svc_conf = {
|
||||
.active = false,
|
||||
.cycle = TIME_S2I(180),
|
||||
.init_delay = TIME_S2I(60)
|
||||
|
@ -51,12 +51,12 @@ const conf_t conf_flash_default = {
|
|||
.symbol = SYM_BALLOON,
|
||||
.aprs_msg = true,
|
||||
|
||||
.tel_enc_cycle = TIME_S2I(0)
|
||||
//.tel_enc_cycle = TIME_S2I(0)
|
||||
},
|
||||
|
||||
// Primary image app
|
||||
.img_pri = {
|
||||
.thread_conf = {
|
||||
.svc_conf = {
|
||||
.active = false,
|
||||
.cycle = CYCLE_CONTINUOUSLY,
|
||||
.init_delay = TIME_S2I(90),
|
||||
|
@ -82,7 +82,7 @@ const conf_t conf_flash_default = {
|
|||
|
||||
// Secondary image app
|
||||
.img_sec = {
|
||||
.thread_conf = {
|
||||
.svc_conf = {
|
||||
.active = false,
|
||||
.cycle = TIME_S2I(60 * 30),
|
||||
.init_delay = TIME_S2I(60 * 1),
|
||||
|
@ -107,7 +107,7 @@ const conf_t conf_flash_default = {
|
|||
|
||||
// Log app
|
||||
.log = {
|
||||
.thread_conf = {
|
||||
.svc_conf = {
|
||||
.active = false,
|
||||
.cycle = TIME_S2I(10),
|
||||
.init_delay = TIME_S2I(5)
|
||||
|
@ -126,14 +126,12 @@ const conf_t conf_flash_default = {
|
|||
|
||||
// APRS app
|
||||
.aprs = {
|
||||
.thread_conf = {
|
||||
.svc_conf = {
|
||||
// The packet receive service is enabled if true
|
||||
// Receive is resumed after any transmission
|
||||
.active = true,
|
||||
.init_delay = TIME_S2I(20)
|
||||
},
|
||||
// The default APRS frequency when geofence is not resolved
|
||||
.freq = APRS_FREQ_AUSTRALIA,
|
||||
// The receive identity for APRS
|
||||
.rx = {
|
||||
// Receive radio configuration
|
||||
|
@ -156,48 +154,48 @@ const conf_t conf_flash_default = {
|
|||
.mod = MOD_AFSK,
|
||||
.cca = 0x4F
|
||||
},
|
||||
// Digipeat identity
|
||||
.beacon = {
|
||||
.svc_conf = {
|
||||
// The telemetry beacon service is enabled if true
|
||||
// Receive is resumed after any transmission
|
||||
.active = true,
|
||||
.init_delay = TIME_S2I(20),
|
||||
.cycle = TIME_S2I(60 * 30), // Beacon interval
|
||||
},
|
||||
.fixed = true, // Use fixed position data if true
|
||||
.lat = -337331175, // Degrees (expressed in 1e-7 form)
|
||||
.lon = 1511143478, // Degrees (expressed in 1e-7 form)
|
||||
.alt = 144, // Altitude in metres
|
||||
},
|
||||
// Digipeat transmission identity
|
||||
.call = "VK2GJ-5",
|
||||
.path = "WIDE2-1",
|
||||
.symbol = SYM_DIGIPEATER,
|
||||
// Set to have digi beacon position, telemetry & APRSD information.
|
||||
// This starts a BCN thread specifically for digi
|
||||
.beacon = true,
|
||||
.cycle = TIME_S2I(60 * 30), // Beacon interval
|
||||
// Set true to have digi use GPS for position
|
||||
// If valid position is not stored then default lat, lon and alt will be used.
|
||||
// If RTC time is invalid then GPS will be enabled to get time.
|
||||
// Once RTC is set then GPS is released and can be switched off.
|
||||
// This will be the case if no other position thread is using GPS.
|
||||
.gps = true,
|
||||
// How often to send telemetry config (TODO: Move out to global level)
|
||||
.tel_enc_cycle = TIME_S2I(60 * 60 * 2)
|
||||
},
|
||||
// The base station identity
|
||||
.base = {
|
||||
// Tracker originated messages will be sent to this call sign if enabled
|
||||
.enabled = true,
|
||||
.call = "VK2GJ-7",
|
||||
.path = "WIDE2-1",
|
||||
.symbol = SYM_DIGIPEATER
|
||||
},
|
||||
},
|
||||
|
||||
// Global controls
|
||||
// Power control
|
||||
.keep_cam_switched_on = false,
|
||||
.gps_on_vbat = 1000, // mV
|
||||
.gps_off_vbat = 1000, // mV
|
||||
.gps_onper_vbat = 1000, // mV
|
||||
.gps_on_vbat = 3800, // mV
|
||||
.gps_off_vbat = 3600, // mV
|
||||
.gps_onper_vbat = 4000, // mV
|
||||
|
||||
// GPS altitude model control (air pressure determined by on-board BME280)
|
||||
.gps_pressure = 90000, // Air pressure (Pa) threshold for alt model switch
|
||||
.gps_low_alt = GPS_STATIONARY,
|
||||
.gps_high_alt = GPS_AIRBORNE_1G,
|
||||
|
||||
// A pre-set location if GPS never enabled or unable to acquire lock.
|
||||
.lat = -337331175, // Degrees (expressed in 1e-7 form)
|
||||
.lon = 1511143478, // Degrees (expressed in 1e-7 form)
|
||||
.alt = 144, // Altitude in metres
|
||||
|
||||
// How often to send telemetry config
|
||||
.tel_enc_cycle = TIME_S2I(60 * 60 * 2),
|
||||
// The default APRS frequency when geofence is not resolved
|
||||
.freq = APRS_FREQ_AUSTRALIA,
|
||||
// The base station identity
|
||||
.base = {
|
||||
// Tracker originated messages will be addressed to this call sign if enabled
|
||||
.enabled = true,
|
||||
.call = "VK2GJ-7",
|
||||
.path = "WIDE2-1",
|
||||
},
|
||||
.magic = CONFIG_MAGIC_DEFAULT // Do not remove. This is the activation bit.
|
||||
};
|
||||
|
|
|
@ -1,238 +1,223 @@
|
|||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
|
||||
#include "ch.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "ublox.h"
|
||||
|
||||
typedef enum {
|
||||
FREQ_RADIO_INVALID = 0,
|
||||
FREQ_APRS_DYNAMIC, /* Geofencing frequency (144.8 default). */
|
||||
FREQ_APRS_SCAN, /* Frequency last found in RX scan. - TBI */
|
||||
FREQ_APRS_RECEIVE, /* Active RX frequency - fall back to DYNAMIC. */
|
||||
FREQ_CMDC_RECEIVE, /* Frequency used for command and control. TBI */
|
||||
FREQ_APRS_DEFAULT, /* Default frequency specified in configuration */
|
||||
FREQ_CODES_END
|
||||
} freq_codes_t;
|
||||
|
||||
#define FREQ_RADIO_INVALID 0
|
||||
#define FREQ_APRS_DYNAMIC 1 /* Geofencing frequency (144.8 default). */
|
||||
#define FREQ_APRS_SCAN 2 /* Frequency based on band base + channel scan. */
|
||||
#define FREQ_APRS_RECEIVE 3 /* Active RX frequency - fall back to DYNAMIC. */
|
||||
#define FREQ_CMDC_RECEIVE 4 /* Frequency used for command and control. TBI */
|
||||
#define FREQ_APRS_DEFAULT 5 /* Default frequency specified in configuration */
|
||||
#define FREQ_CODES_END 6
|
||||
|
||||
#define CYCLE_CONTINUOUSLY 0
|
||||
|
||||
#define TYPE_NULL 0
|
||||
#define TYPE_INT 1
|
||||
#define TYPE_TIME 2
|
||||
#define TYPE_STR 3
|
||||
|
||||
typedef enum {
|
||||
SLEEP_DISABLED = 0,
|
||||
SLEEP_WHEN_VBAT_BELOW_THRES,
|
||||
SLEEP_WHEN_VSOL_BELOW_THRES,
|
||||
SLEEP_WHEN_VBAT_ABOVE_THRES,
|
||||
SLEEP_WHEN_VSOL_ABOVE_THRES,
|
||||
SLEEP_WHEN_DISCHARGING,
|
||||
SLEEP_WHEN_CHARGING
|
||||
} sleep_type_t;
|
||||
|
||||
typedef struct {
|
||||
sleep_type_t type;
|
||||
volt_level_t vbat_thres;
|
||||
volt_level_t vsol_thres;
|
||||
} sleep_conf_t;
|
||||
|
||||
typedef enum { // Modulation type
|
||||
MOD_NONE,
|
||||
MOD_AFSK,
|
||||
MOD_2FSK
|
||||
} mod_t;
|
||||
|
||||
typedef enum {
|
||||
RES_NONE = 0,
|
||||
RES_QQVGA,
|
||||
RES_QVGA,
|
||||
RES_VGA,
|
||||
RES_VGA_ZOOMED,
|
||||
RES_XGA,
|
||||
RES_UXGA,
|
||||
RES_MAX
|
||||
} resolution_t;
|
||||
|
||||
/*typedef union {
|
||||
radio_squelch_t cca;
|
||||
radio_squelch_t rssi;
|
||||
} radio_sq_t;*/
|
||||
|
||||
typedef struct {
|
||||
radio_pwr_t pwr;
|
||||
radio_freq_t freq;
|
||||
mod_t mod;
|
||||
link_speed_t speed;
|
||||
union {
|
||||
radio_squelch_t cca;
|
||||
radio_squelch_t rssi;
|
||||
};
|
||||
} radio_conf_t;
|
||||
|
||||
typedef struct {
|
||||
radio_pwr_t pwr;
|
||||
radio_freq_t freq;
|
||||
mod_t mod;
|
||||
link_speed_t speed;
|
||||
radio_squelch_t cca;
|
||||
} radio_tx_conf_t; // Radio / Modulation
|
||||
|
||||
typedef struct {
|
||||
radio_freq_t freq;
|
||||
mod_t mod;
|
||||
link_speed_t speed;
|
||||
radio_squelch_t rssi;
|
||||
} radio_rx_conf_t; // Radio / Modulation
|
||||
|
||||
typedef struct {
|
||||
bool active;
|
||||
sysinterval_t init_delay;
|
||||
sysinterval_t send_spacing;
|
||||
sleep_conf_t sleep_conf;
|
||||
sysinterval_t cycle; // Cycle time (0: continously)
|
||||
sysinterval_t duration;
|
||||
} thread_conf_t; // Thread
|
||||
|
||||
typedef struct {
|
||||
thread_conf_t thread_conf;
|
||||
radio_tx_conf_t radio_conf;
|
||||
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
aprs_sym_t symbol;
|
||||
bool aprs_msg;
|
||||
sysinterval_t tel_enc_cycle;
|
||||
} thd_pos_conf_t;
|
||||
|
||||
typedef struct {
|
||||
thread_conf_t thread_conf;
|
||||
radio_tx_conf_t radio_conf;
|
||||
bool redundantTx;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
|
||||
resolution_t res; // Picture resolution
|
||||
uint8_t quality; // SSDV Quality ranging from 0-7
|
||||
uint32_t buf_size; // SRAM buffer size for the picture
|
||||
} thd_img_conf_t;
|
||||
|
||||
typedef struct {
|
||||
thread_conf_t thread_conf;
|
||||
radio_tx_conf_t radio_conf;
|
||||
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
|
||||
uint8_t density; // Density of log points being sent out in 1/x (value 10 => 10%)
|
||||
} thd_log_conf_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
radio_rx_conf_t radio_conf;
|
||||
aprs_sym_t symbol;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
} thd_rx_conf_t;
|
||||
|
||||
typedef struct {
|
||||
radio_tx_conf_t radio_conf;
|
||||
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
aprs_sym_t symbol;
|
||||
} thd_tx_conf_t;
|
||||
|
||||
typedef struct {
|
||||
radio_tx_conf_t radio_conf;
|
||||
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
aprs_sym_t symbol;
|
||||
bool enabled;
|
||||
} thd_base_conf_t;
|
||||
|
||||
typedef struct {
|
||||
bool active; // Digipeater active flag
|
||||
radio_tx_conf_t radio_conf;
|
||||
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
aprs_sym_t symbol;
|
||||
bool enabled;
|
||||
bool beacon;
|
||||
bool gps;
|
||||
/* gps_coord_t lat;
|
||||
gps_coord_t lon;
|
||||
gps_alt_t alt;*/
|
||||
sysinterval_t cycle; // Beacon interval (0: continously)
|
||||
sysinterval_t tel_enc_cycle;
|
||||
|
||||
} thd_digi_conf_t;
|
||||
|
||||
/* APRS configuration. */
|
||||
typedef struct {
|
||||
thread_conf_t thread_conf;
|
||||
thd_rx_conf_t rx;
|
||||
thd_digi_conf_t digi;
|
||||
// Base station call sign for receipt of tracker initiated sends
|
||||
// These are sends by the tracker which are not in response to a query.
|
||||
thd_base_conf_t base;
|
||||
// Default APRS frequency if geolocation is not available (GPS offline)
|
||||
radio_freq_t freq;
|
||||
} thd_aprs_conf_t;
|
||||
|
||||
typedef struct {
|
||||
thd_pos_conf_t pos_pri; // Primary position thread configuration
|
||||
thd_pos_conf_t pos_sec; // Secondary position thread configuration
|
||||
|
||||
thd_img_conf_t img_pri; // Primary image thread configuration
|
||||
thd_img_conf_t img_sec; // Secondary image thread configuration
|
||||
|
||||
thd_log_conf_t log; // Log transmission configuration
|
||||
thd_aprs_conf_t aprs;
|
||||
|
||||
bool keep_cam_switched_on; // Keep camera switched on and initialized, this makes image capturing faster but takes a lot of power over long time
|
||||
|
||||
volt_level_t gps_on_vbat; // Battery voltage threshold at which GPS is switched on
|
||||
volt_level_t gps_off_vbat; // Battery voltage threshold at which GPS is switched off
|
||||
volt_level_t gps_onper_vbat; // Battery voltage threshold at which GPS is kept switched on all time. This value must be larger
|
||||
// When gps_on_vbat and gps_off_vbat otherwise this value has no effect. Value 0 disables this feature
|
||||
uint32_t gps_pressure; // Air pressure below which GPS is switched to airborne mode
|
||||
gps_hp_model_t gps_low_alt; // Model to use when air pressure is above gps_pa_threshold
|
||||
gps_lp_model_t gps_high_alt; // Model to use when air pressure is below gps_pa_threshold
|
||||
|
||||
// Default lat, lon and alt when GPS is not enabled or not operable
|
||||
gps_coord_t lat;
|
||||
gps_coord_t lon;
|
||||
gps_alt_t alt;
|
||||
|
||||
uint32_t magic; // Key that indicates if the flash is loaded or has been updated
|
||||
uint16_t crc; // CRC to verify content
|
||||
} conf_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
char name[64];
|
||||
size_t size;
|
||||
void *ptr;
|
||||
} conf_command_t;
|
||||
|
||||
#endif /* __TYPES_H__ */
|
||||
|
||||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
|
||||
#include "ch.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "ublox.h"
|
||||
|
||||
typedef enum {
|
||||
FREQ_RADIO_INVALID = 0,
|
||||
FREQ_APRS_DYNAMIC, /* Geofencing frequency (144.8 default). */
|
||||
FREQ_APRS_SCAN, /* Frequency last found in RX scan. - TBI */
|
||||
FREQ_APRS_RECEIVE, /* Active RX frequency - fall back to DYNAMIC. */
|
||||
FREQ_CMDC_RECEIVE, /* Frequency used for command and control. TBI */
|
||||
FREQ_APRS_DEFAULT, /* Default frequency specified in configuration */
|
||||
FREQ_CODES_END
|
||||
} freq_codes_t;
|
||||
|
||||
#define FREQ_RADIO_INVALID 0
|
||||
#define FREQ_APRS_DYNAMIC 1 /* Geofencing frequency (144.8 default). */
|
||||
#define FREQ_APRS_SCAN 2 /* Frequency based on band base + channel scan. */
|
||||
#define FREQ_APRS_RECEIVE 3 /* Active RX frequency - fall back to DYNAMIC. */
|
||||
#define FREQ_CMDC_RECEIVE 4 /* Frequency used for command and control. TBI */
|
||||
#define FREQ_APRS_DEFAULT 5 /* Default frequency specified in configuration */
|
||||
#define FREQ_CODES_END 6
|
||||
|
||||
#define CYCLE_CONTINUOUSLY 0
|
||||
|
||||
#define TYPE_NULL 0
|
||||
#define TYPE_INT 1
|
||||
#define TYPE_TIME 2
|
||||
#define TYPE_STR 3
|
||||
|
||||
typedef enum {
|
||||
SLEEP_DISABLED = 0,
|
||||
SLEEP_WHEN_VBAT_BELOW_THRES,
|
||||
SLEEP_WHEN_VSOL_BELOW_THRES,
|
||||
SLEEP_WHEN_VBAT_ABOVE_THRES,
|
||||
SLEEP_WHEN_VSOL_ABOVE_THRES,
|
||||
SLEEP_WHEN_DISCHARGING,
|
||||
SLEEP_WHEN_CHARGING
|
||||
} sleep_type_t;
|
||||
|
||||
typedef struct {
|
||||
sleep_type_t type;
|
||||
volt_level_t vbat_thres;
|
||||
volt_level_t vsol_thres;
|
||||
} sleep_conf_t;
|
||||
|
||||
typedef enum { // Modulation type
|
||||
MOD_NONE,
|
||||
MOD_AFSK,
|
||||
MOD_2FSK
|
||||
} mod_t;
|
||||
|
||||
typedef enum {
|
||||
RES_NONE = 0,
|
||||
RES_QQVGA,
|
||||
RES_QVGA,
|
||||
RES_VGA,
|
||||
RES_VGA_ZOOMED,
|
||||
RES_XGA,
|
||||
RES_UXGA,
|
||||
RES_MAX
|
||||
} resolution_t;
|
||||
|
||||
typedef struct {
|
||||
radio_pwr_t pwr;
|
||||
radio_freq_t freq;
|
||||
mod_t mod;
|
||||
link_speed_t speed;
|
||||
union {
|
||||
radio_squelch_t cca;
|
||||
radio_squelch_t rssi;
|
||||
};
|
||||
} radio_conf_t;
|
||||
|
||||
typedef struct {
|
||||
radio_pwr_t pwr;
|
||||
radio_freq_t freq;
|
||||
mod_t mod;
|
||||
link_speed_t speed;
|
||||
radio_squelch_t cca;
|
||||
} radio_tx_conf_t; // Radio / Modulation
|
||||
|
||||
typedef struct {
|
||||
radio_freq_t freq;
|
||||
mod_t mod;
|
||||
link_speed_t speed;
|
||||
radio_squelch_t rssi;
|
||||
} radio_rx_conf_t; // Radio / Modulation
|
||||
|
||||
typedef struct {
|
||||
bool active;
|
||||
sysinterval_t init_delay;
|
||||
sysinterval_t send_spacing;
|
||||
sleep_conf_t sleep_conf;
|
||||
sysinterval_t cycle; // Cycle time (0: continuously)
|
||||
sysinterval_t duration;
|
||||
} thread_conf_t; // Thread
|
||||
|
||||
typedef struct {
|
||||
thread_conf_t svc_conf;
|
||||
radio_tx_conf_t radio_conf;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
aprs_sym_t symbol;
|
||||
bool aprs_msg;
|
||||
// Default lat, lon and alt when fixed is enabled
|
||||
bool fixed;
|
||||
gps_coord_t lat;
|
||||
gps_coord_t lon;
|
||||
gps_alt_t alt;
|
||||
} thd_pos_conf_t;
|
||||
|
||||
typedef struct {
|
||||
thread_conf_t svc_conf;
|
||||
radio_tx_conf_t radio_conf;
|
||||
bool redundantTx;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
resolution_t res; // Picture resolution
|
||||
uint8_t quality; // SSDV Quality ranging from 0-7
|
||||
uint32_t buf_size; // SRAM buffer size for the picture
|
||||
} thd_img_conf_t;
|
||||
|
||||
typedef struct {
|
||||
thread_conf_t svc_conf;
|
||||
radio_tx_conf_t radio_conf;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
uint8_t density; // Density of log points being sent out in 1/x (value 10 => 10%)
|
||||
} thd_log_conf_t;
|
||||
|
||||
typedef struct {
|
||||
radio_rx_conf_t radio_conf;
|
||||
aprs_sym_t symbol;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
} thd_rx_conf_t;
|
||||
|
||||
typedef struct {
|
||||
radio_tx_conf_t radio_conf;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
aprs_sym_t symbol;
|
||||
} thd_tx_conf_t;
|
||||
|
||||
typedef struct {
|
||||
radio_tx_conf_t radio_conf;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
aprs_sym_t symbol;
|
||||
bool enabled;
|
||||
} thd_base_conf_t;
|
||||
|
||||
typedef struct {
|
||||
bool active; // Digipeater active flag
|
||||
radio_tx_conf_t radio_conf;
|
||||
// Protocol
|
||||
char call[AX25_MAX_ADDR_LEN];
|
||||
char path[16];
|
||||
aprs_sym_t symbol;
|
||||
thd_pos_conf_t beacon;
|
||||
//sysinterval_t tel_enc_cycle;
|
||||
} thd_digi_conf_t;
|
||||
|
||||
/* APRS configuration. */
|
||||
typedef struct {
|
||||
thread_conf_t svc_conf;
|
||||
thd_rx_conf_t rx;
|
||||
thd_digi_conf_t digi;
|
||||
// Base station call sign for receipt of tracker initiated sends
|
||||
// These are sends by the tracker which are not in response to a query.
|
||||
//thd_base_conf_t base;
|
||||
// Default APRS frequency if geolocation is not available (GPS offline)
|
||||
//radio_freq_t freq;
|
||||
} thd_aprs_conf_t;
|
||||
|
||||
typedef struct {
|
||||
thd_pos_conf_t pos_pri; // Primary position thread configuration
|
||||
thd_pos_conf_t pos_sec; // Secondary position thread configuration
|
||||
|
||||
thd_img_conf_t img_pri; // Primary image thread configuration
|
||||
thd_img_conf_t img_sec; // Secondary image thread configuration
|
||||
|
||||
thd_log_conf_t log; // Log transmission configuration
|
||||
thd_aprs_conf_t aprs;
|
||||
|
||||
bool keep_cam_switched_on; // Keep camera switched on and initialized, this makes image capturing faster but takes a lot of power over long time
|
||||
|
||||
volt_level_t gps_on_vbat; // Battery voltage threshold at which GPS is switched on
|
||||
volt_level_t gps_off_vbat; // Battery voltage threshold at which GPS is switched off
|
||||
volt_level_t gps_onper_vbat; // Battery voltage threshold at which GPS is kept switched on all time. This value must be larger
|
||||
// When gps_on_vbat and gps_off_vbat otherwise this value has no effect. Value 0 disables this feature
|
||||
uint32_t gps_pressure; // Air pressure below which GPS is switched to airborne mode
|
||||
gps_hp_model_t gps_low_alt; // Model to use when air pressure is above gps_pa_threshold
|
||||
gps_lp_model_t gps_high_alt; // Model to use when air pressure is below gps_pa_threshold
|
||||
|
||||
//APRS global
|
||||
sysinterval_t tel_enc_cycle; // Cycle for sending of telemetry config headers
|
||||
radio_freq_t freq; // Default APRS frequency if geolocation not available
|
||||
// Base station call sign for receipt of tracker initiated sends
|
||||
// These are sends by the tracker which are not in response to a query.
|
||||
thd_base_conf_t base;
|
||||
|
||||
uint32_t magic; // Key that indicates if the flash is loaded or has been updated
|
||||
uint16_t crc; // CRC to verify content
|
||||
} conf_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
char name[64];
|
||||
size_t size;
|
||||
void *ptr;
|
||||
} conf_command_t;
|
||||
|
||||
#endif /* __TYPES_H__ */
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -647,8 +647,8 @@ radio_freq_t pktGetDefaultOperatingFrequency(const radio_unit_t radio) {
|
|||
/* FIXME: Default frequency in config to be per radio. */
|
||||
(void)radio;
|
||||
/* FIXME: INVALID relies on 0 in conf if no default set. */
|
||||
if(conf_sram.aprs.freq != FREQ_RADIO_INVALID)
|
||||
return conf_sram.aprs.freq;
|
||||
if(conf_sram.freq != FREQ_RADIO_INVALID)
|
||||
return conf_sram.freq;
|
||||
else
|
||||
return DEFAULT_OPERATING_FREQ;
|
||||
}
|
||||
|
|
|
@ -43,12 +43,12 @@ static heard_t heard_list[APRS_HEARD_LIST_SIZE];
|
|||
static bool dedupe_initialized;
|
||||
|
||||
const conf_command_t command_list[] = {
|
||||
{TYPE_INT, "pos_pri.active", sizeof(conf_sram.pos_pri.thread_conf.active), &conf_sram.pos_pri.thread_conf.active },
|
||||
{TYPE_TIME, "pos_pri.init_delay", sizeof(conf_sram.pos_pri.thread_conf.init_delay), &conf_sram.pos_pri.thread_conf.init_delay },
|
||||
{TYPE_INT, "pos_pri.sleep_conf.type", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.type), &conf_sram.pos_pri.thread_conf.sleep_conf.type },
|
||||
{TYPE_INT, "pos_pri.sleep_conf.vbat_thres", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.vbat_thres), &conf_sram.pos_pri.thread_conf.sleep_conf.vbat_thres},
|
||||
{TYPE_INT, "pos_pri.sleep_conf.vsol_thres", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.vsol_thres), &conf_sram.pos_pri.thread_conf.sleep_conf.vsol_thres},
|
||||
{TYPE_TIME, "pos_pri.cycle", sizeof(conf_sram.pos_pri.thread_conf.cycle), &conf_sram.pos_pri.thread_conf.cycle },
|
||||
{TYPE_INT, "pos_pri.active", sizeof(conf_sram.pos_pri.svc_conf.active), &conf_sram.pos_pri.svc_conf.active },
|
||||
{TYPE_TIME, "pos_pri.init_delay", sizeof(conf_sram.pos_pri.svc_conf.init_delay), &conf_sram.pos_pri.svc_conf.init_delay },
|
||||
{TYPE_INT, "pos_pri.sleep_conf.type", sizeof(conf_sram.pos_pri.svc_conf.sleep_conf.type), &conf_sram.pos_pri.svc_conf.sleep_conf.type },
|
||||
{TYPE_INT, "pos_pri.sleep_conf.vbat_thres", sizeof(conf_sram.pos_pri.svc_conf.sleep_conf.vbat_thres), &conf_sram.pos_pri.svc_conf.sleep_conf.vbat_thres },
|
||||
{TYPE_INT, "pos_pri.sleep_conf.vsol_thres", sizeof(conf_sram.pos_pri.svc_conf.sleep_conf.vsol_thres), &conf_sram.pos_pri.svc_conf.sleep_conf.vsol_thres },
|
||||
{TYPE_TIME, "pos_pri.cycle", sizeof(conf_sram.pos_pri.svc_conf.cycle), &conf_sram.pos_pri.svc_conf.cycle },
|
||||
{TYPE_INT, "pos_pri.pwr", sizeof(conf_sram.pos_pri.radio_conf.pwr), &conf_sram.pos_pri.radio_conf.pwr },
|
||||
{TYPE_INT, "pos_pri.freq", sizeof(conf_sram.pos_pri.radio_conf.freq), &conf_sram.pos_pri.radio_conf.freq },
|
||||
{TYPE_INT, "pos_pri.mod", sizeof(conf_sram.pos_pri.radio_conf.mod), &conf_sram.pos_pri.radio_conf.mod },
|
||||
|
@ -57,14 +57,13 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_STR, "pos_pri.path", sizeof(conf_sram.pos_pri.path), &conf_sram.pos_pri.path },
|
||||
{TYPE_INT, "pos_pri.symbol", sizeof(conf_sram.pos_pri.symbol), &conf_sram.pos_pri.symbol },
|
||||
{TYPE_INT, "pos_pri.aprs_msg", sizeof(conf_sram.pos_pri.aprs_msg), &conf_sram.pos_pri.aprs_msg },
|
||||
{TYPE_TIME, "pos_pri.tel_enc_cycle", sizeof(conf_sram.pos_pri.tel_enc_cycle), &conf_sram.pos_pri.tel_enc_cycle },
|
||||
|
||||
{TYPE_INT, "pos_sec.active", sizeof(conf_sram.pos_sec.thread_conf.active), &conf_sram.pos_sec.thread_conf.active },
|
||||
{TYPE_TIME, "pos_sec.init_delay", sizeof(conf_sram.pos_sec.thread_conf.init_delay), &conf_sram.pos_sec.thread_conf.init_delay },
|
||||
{TYPE_INT, "pos_sec.sleep_conf.type", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.type), &conf_sram.pos_sec.thread_conf.sleep_conf.type },
|
||||
{TYPE_INT, "pos_sec.sleep_conf.vbat_thres", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.vbat_thres), &conf_sram.pos_sec.thread_conf.sleep_conf.vbat_thres},
|
||||
{TYPE_INT, "pos_sec.sleep_conf.vsol_thres", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.vsol_thres), &conf_sram.pos_sec.thread_conf.sleep_conf.vsol_thres},
|
||||
{TYPE_TIME, "pos_sec.cycle", sizeof(conf_sram.pos_sec.thread_conf.cycle), &conf_sram.pos_sec.thread_conf.cycle },
|
||||
{TYPE_INT, "pos_sec.active", sizeof(conf_sram.pos_sec.svc_conf.active), &conf_sram.pos_sec.svc_conf.active },
|
||||
{TYPE_TIME, "pos_sec.init_delay", sizeof(conf_sram.pos_sec.svc_conf.init_delay), &conf_sram.pos_sec.svc_conf.init_delay },
|
||||
{TYPE_INT, "pos_sec.sleep_conf.type", sizeof(conf_sram.pos_sec.svc_conf.sleep_conf.type), &conf_sram.pos_sec.svc_conf.sleep_conf.type },
|
||||
{TYPE_INT, "pos_sec.sleep_conf.vbat_thres", sizeof(conf_sram.pos_sec.svc_conf.sleep_conf.vbat_thres), &conf_sram.pos_sec.svc_conf.sleep_conf.vbat_thres },
|
||||
{TYPE_INT, "pos_sec.sleep_conf.vsol_thres", sizeof(conf_sram.pos_sec.svc_conf.sleep_conf.vsol_thres), &conf_sram.pos_sec.svc_conf.sleep_conf.vsol_thres },
|
||||
{TYPE_TIME, "pos_sec.cycle", sizeof(conf_sram.pos_sec.svc_conf.cycle), &conf_sram.pos_sec.svc_conf.cycle },
|
||||
{TYPE_INT, "pos_sec.pwr", sizeof(conf_sram.pos_sec.radio_conf.pwr), &conf_sram.pos_sec.radio_conf.pwr },
|
||||
{TYPE_INT, "pos_sec.freq", sizeof(conf_sram.pos_sec.radio_conf.freq), &conf_sram.pos_sec.radio_conf.freq },
|
||||
{TYPE_INT, "pos_sec.mod", sizeof(conf_sram.pos_sec.radio_conf.mod), &conf_sram.pos_sec.radio_conf.mod },
|
||||
|
@ -73,15 +72,14 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_STR, "pos_sec.path", sizeof(conf_sram.pos_sec.path), &conf_sram.pos_sec.path },
|
||||
{TYPE_INT, "pos_sec.symbol", sizeof(conf_sram.pos_sec.symbol), &conf_sram.pos_sec.symbol },
|
||||
{TYPE_INT, "pos_sec.aprs_msg", sizeof(conf_sram.pos_sec.aprs_msg), &conf_sram.pos_sec.aprs_msg },
|
||||
{TYPE_TIME, "pos_sec.tel_enc_cycle", sizeof(conf_sram.pos_sec.tel_enc_cycle), &conf_sram.pos_sec.tel_enc_cycle },
|
||||
|
||||
{TYPE_INT, "img_pri.active", sizeof(conf_sram.img_pri.thread_conf.active), &conf_sram.img_pri.thread_conf.active },
|
||||
{TYPE_TIME, "img_pri.init_delay", sizeof(conf_sram.img_pri.thread_conf.init_delay), &conf_sram.img_pri.thread_conf.init_delay },
|
||||
{TYPE_TIME, "img_pri.send_spacing", sizeof(conf_sram.img_pri.thread_conf.send_spacing), &conf_sram.img_pri.thread_conf.send_spacing },
|
||||
{TYPE_INT, "img_pri.sleep_conf.type", sizeof(conf_sram.img_pri.thread_conf.sleep_conf.type), &conf_sram.img_pri.thread_conf.sleep_conf.type },
|
||||
{TYPE_INT, "img_pri.sleep_conf.vbat_thres", sizeof(conf_sram.img_pri.thread_conf.sleep_conf.vbat_thres), &conf_sram.img_pri.thread_conf.sleep_conf.vbat_thres},
|
||||
{TYPE_INT, "img_pri.sleep_conf.vsol_thres", sizeof(conf_sram.img_pri.thread_conf.sleep_conf.vsol_thres), &conf_sram.img_pri.thread_conf.sleep_conf.vsol_thres},
|
||||
{TYPE_TIME, "img_pri.cycle", sizeof(conf_sram.img_pri.thread_conf.cycle), &conf_sram.img_pri.thread_conf.cycle },
|
||||
{TYPE_INT, "img_pri.active", sizeof(conf_sram.img_pri.svc_conf.active), &conf_sram.img_pri.svc_conf.active },
|
||||
{TYPE_TIME, "img_pri.init_delay", sizeof(conf_sram.img_pri.svc_conf.init_delay), &conf_sram.img_pri.svc_conf.init_delay },
|
||||
{TYPE_TIME, "img_pri.send_spacing", sizeof(conf_sram.img_pri.svc_conf.send_spacing), &conf_sram.img_pri.svc_conf.send_spacing },
|
||||
{TYPE_INT, "img_pri.sleep_conf.type", sizeof(conf_sram.img_pri.svc_conf.sleep_conf.type), &conf_sram.img_pri.svc_conf.sleep_conf.type },
|
||||
{TYPE_INT, "img_pri.sleep_conf.vbat_thres", sizeof(conf_sram.img_pri.svc_conf.sleep_conf.vbat_thres), &conf_sram.img_pri.svc_conf.sleep_conf.vbat_thres },
|
||||
{TYPE_INT, "img_pri.sleep_conf.vsol_thres", sizeof(conf_sram.img_pri.svc_conf.sleep_conf.vsol_thres), &conf_sram.img_pri.svc_conf.sleep_conf.vsol_thres },
|
||||
{TYPE_TIME, "img_pri.cycle", sizeof(conf_sram.img_pri.svc_conf.cycle), &conf_sram.img_pri.svc_conf.cycle },
|
||||
{TYPE_INT, "img_pri.pwr", sizeof(conf_sram.img_pri.radio_conf.pwr), &conf_sram.img_pri.radio_conf.pwr },
|
||||
{TYPE_INT, "img_pri.freq", sizeof(conf_sram.img_pri.radio_conf.freq), &conf_sram.img_pri.radio_conf.freq },
|
||||
{TYPE_INT, "img_pri.mod", sizeof(conf_sram.img_pri.radio_conf.mod), &conf_sram.img_pri.radio_conf.mod },
|
||||
|
@ -94,13 +92,13 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_INT, "img_pri.quality", sizeof(conf_sram.img_pri.quality), &conf_sram.img_pri.quality },
|
||||
{TYPE_INT, "img_pri.buf_size", sizeof(conf_sram.img_pri.buf_size), &conf_sram.img_pri.buf_size },
|
||||
|
||||
{TYPE_INT, "img_sec.active", sizeof(conf_sram.img_sec.thread_conf.active), &conf_sram.img_sec.thread_conf.active },
|
||||
{TYPE_TIME, "img_sec.init_delay", sizeof(conf_sram.img_sec.thread_conf.init_delay), &conf_sram.img_sec.thread_conf.init_delay },
|
||||
{TYPE_TIME, "img_sec.send_spacing", sizeof(conf_sram.img_sec.thread_conf.send_spacing), &conf_sram.img_sec.thread_conf.send_spacing },
|
||||
{TYPE_INT, "img_sec.sleep_conf.type", sizeof(conf_sram.img_sec.thread_conf.sleep_conf.type), &conf_sram.img_sec.thread_conf.sleep_conf.type },
|
||||
{TYPE_INT, "img_sec.sleep_conf.vbat_thres", sizeof(conf_sram.img_sec.thread_conf.sleep_conf.vbat_thres), &conf_sram.img_sec.thread_conf.sleep_conf.vbat_thres},
|
||||
{TYPE_INT, "img_sec.sleep_conf.vsol_thres", sizeof(conf_sram.img_sec.thread_conf.sleep_conf.vsol_thres), &conf_sram.img_sec.thread_conf.sleep_conf.vsol_thres},
|
||||
{TYPE_TIME, "img_sec.cycle", sizeof(conf_sram.img_sec.thread_conf.cycle), &conf_sram.img_sec.thread_conf.cycle },
|
||||
{TYPE_INT, "img_sec.active", sizeof(conf_sram.img_sec.svc_conf.active), &conf_sram.img_sec.svc_conf.active },
|
||||
{TYPE_TIME, "img_sec.init_delay", sizeof(conf_sram.img_sec.svc_conf.init_delay), &conf_sram.img_sec.svc_conf.init_delay },
|
||||
{TYPE_TIME, "img_sec.send_spacing", sizeof(conf_sram.img_sec.svc_conf.send_spacing), &conf_sram.img_sec.svc_conf.send_spacing },
|
||||
{TYPE_INT, "img_sec.sleep_conf.type", sizeof(conf_sram.img_sec.svc_conf.sleep_conf.type), &conf_sram.img_sec.svc_conf.sleep_conf.type },
|
||||
{TYPE_INT, "img_sec.sleep_conf.vbat_thres", sizeof(conf_sram.img_sec.svc_conf.sleep_conf.vbat_thres), &conf_sram.img_sec.svc_conf.sleep_conf.vbat_thres },
|
||||
{TYPE_INT, "img_sec.sleep_conf.vsol_thres", sizeof(conf_sram.img_sec.svc_conf.sleep_conf.vsol_thres), &conf_sram.img_sec.svc_conf.sleep_conf.vsol_thres },
|
||||
{TYPE_TIME, "img_sec.cycle", sizeof(conf_sram.img_sec.svc_conf.cycle), &conf_sram.img_sec.svc_conf.cycle },
|
||||
{TYPE_INT, "img_sec.pwr", sizeof(conf_sram.img_sec.radio_conf.pwr), &conf_sram.img_sec.radio_conf.pwr },
|
||||
{TYPE_INT, "img_sec.freq", sizeof(conf_sram.img_sec.radio_conf.freq), &conf_sram.img_sec.radio_conf.freq },
|
||||
{TYPE_INT, "img_sec.mod", sizeof(conf_sram.img_sec.radio_conf.mod), &conf_sram.img_sec.radio_conf.mod },
|
||||
|
@ -113,13 +111,13 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_INT, "img_sec.quality", sizeof(conf_sram.img_sec.quality), &conf_sram.img_sec.quality },
|
||||
{TYPE_INT, "img_sec.buf_size", sizeof(conf_sram.img_sec.buf_size), &conf_sram.img_sec.buf_size },
|
||||
|
||||
{TYPE_INT, "log.active", sizeof(conf_sram.log.thread_conf.active), &conf_sram.log.thread_conf.active },
|
||||
{TYPE_TIME, "log.init_delay", sizeof(conf_sram.log.thread_conf.init_delay), &conf_sram.log.thread_conf.init_delay },
|
||||
{TYPE_TIME, "log.send_spacing", sizeof(conf_sram.log.thread_conf.send_spacing), &conf_sram.log.thread_conf.send_spacing },
|
||||
{TYPE_INT, "log.sleep_conf.type", sizeof(conf_sram.log.thread_conf.sleep_conf.type), &conf_sram.log.thread_conf.sleep_conf.type },
|
||||
{TYPE_INT, "log.sleep_conf.vbat_thres", sizeof(conf_sram.log.thread_conf.sleep_conf.vbat_thres), &conf_sram.log.thread_conf.sleep_conf.vbat_thres },
|
||||
{TYPE_INT, "log.sleep_conf.vsol_thres", sizeof(conf_sram.log.thread_conf.sleep_conf.vsol_thres), &conf_sram.log.thread_conf.sleep_conf.vsol_thres },
|
||||
{TYPE_TIME, "log.cycle", sizeof(conf_sram.log.thread_conf.cycle), &conf_sram.log.thread_conf.cycle },
|
||||
{TYPE_INT, "log.active", sizeof(conf_sram.log.svc_conf.active), &conf_sram.log.svc_conf.active },
|
||||
{TYPE_TIME, "log.init_delay", sizeof(conf_sram.log.svc_conf.init_delay), &conf_sram.log.svc_conf.init_delay },
|
||||
{TYPE_TIME, "log.send_spacing", sizeof(conf_sram.log.svc_conf.send_spacing), &conf_sram.log.svc_conf.send_spacing },
|
||||
{TYPE_INT, "log.sleep_conf.type", sizeof(conf_sram.log.svc_conf.sleep_conf.type), &conf_sram.log.svc_conf.sleep_conf.type },
|
||||
{TYPE_INT, "log.sleep_conf.vbat_thres", sizeof(conf_sram.log.svc_conf.sleep_conf.vbat_thres), &conf_sram.log.svc_conf.sleep_conf.vbat_thres },
|
||||
{TYPE_INT, "log.sleep_conf.vsol_thres", sizeof(conf_sram.log.svc_conf.sleep_conf.vsol_thres), &conf_sram.log.svc_conf.sleep_conf.vsol_thres },
|
||||
{TYPE_TIME, "log.cycle", sizeof(conf_sram.log.svc_conf.cycle), &conf_sram.log.svc_conf.cycle },
|
||||
{TYPE_INT, "log.pwr", sizeof(conf_sram.log.radio_conf.pwr), &conf_sram.log.radio_conf.pwr },
|
||||
{TYPE_INT, "log.freq", sizeof(conf_sram.log.radio_conf.freq), &conf_sram.log.radio_conf.freq },
|
||||
{TYPE_INT, "log.mod", sizeof(conf_sram.log.radio_conf.mod), &conf_sram.log.radio_conf.mod },
|
||||
|
@ -129,20 +127,15 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_STR, "log.path", sizeof(conf_sram.log.path), &conf_sram.log.path },
|
||||
{TYPE_INT, "log.density", sizeof(conf_sram.log.density), &conf_sram.log.density },
|
||||
|
||||
{TYPE_INT, "aprs.active", sizeof(conf_sram.aprs.thread_conf.active), &conf_sram.aprs.thread_conf.active },
|
||||
{TYPE_TIME, "aprs.init_delay", sizeof(conf_sram.aprs.thread_conf.init_delay), &conf_sram.aprs.thread_conf.init_delay },
|
||||
{TYPE_INT, "aprs.active", sizeof(conf_sram.aprs.svc_conf.active), &conf_sram.aprs.svc_conf.active },
|
||||
{TYPE_TIME, "aprs.init_delay", sizeof(conf_sram.aprs.svc_conf.init_delay), &conf_sram.aprs.svc_conf.init_delay },
|
||||
|
||||
{TYPE_INT, "aprs.rx.freq", sizeof(conf_sram.aprs.rx.radio_conf.freq), &conf_sram.aprs.rx.radio_conf.freq },
|
||||
{TYPE_INT, "aprs.rx.mod", sizeof(conf_sram.aprs.rx.radio_conf.mod), &conf_sram.aprs.rx.radio_conf.mod },
|
||||
{TYPE_INT, "aprs.rx.speed", sizeof(conf_sram.aprs.rx.radio_conf.speed), &conf_sram.aprs.rx.radio_conf.speed },
|
||||
{TYPE_STR, "aprs.rx.call", sizeof(conf_sram.aprs.rx.call), &conf_sram.aprs.rx.call },
|
||||
|
||||
{TYPE_INT, "aprs.base.freq", sizeof(conf_sram.aprs.base.radio_conf.freq), &conf_sram.aprs.base.radio_conf.freq },
|
||||
{TYPE_INT, "aprs.base.pwr", sizeof(conf_sram.aprs.base.radio_conf.pwr), &conf_sram.aprs.base.radio_conf.pwr },
|
||||
{TYPE_INT, "aprs.base.mod", sizeof(conf_sram.aprs.base.radio_conf.mod), &conf_sram.aprs.base.radio_conf.mod },
|
||||
{TYPE_INT, "aprs.base.cca", sizeof(conf_sram.aprs.base.radio_conf.cca), &conf_sram.aprs.base.radio_conf.cca },
|
||||
{TYPE_STR, "aprs.base.call", sizeof(conf_sram.aprs.base.call), &conf_sram.aprs.base.call },
|
||||
|
||||
{TYPE_INT, "aprs.digi.active", sizeof(conf_sram.aprs.digi.active), &conf_sram.aprs.digi.active },
|
||||
{TYPE_INT, "aprs.digi.freq", sizeof(conf_sram.aprs.digi.radio_conf.freq), &conf_sram.aprs.digi.radio_conf.freq },
|
||||
{TYPE_INT, "aprs.digi.pwr", sizeof(conf_sram.aprs.digi.radio_conf.pwr), &conf_sram.aprs.digi.radio_conf.pwr },
|
||||
{TYPE_INT, "aprs.digi.mod", sizeof(conf_sram.aprs.digi.radio_conf.mod), &conf_sram.aprs.digi.radio_conf.mod },
|
||||
|
@ -150,14 +143,13 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_STR, "aprs.digi.call", sizeof(conf_sram.aprs.digi.call), &conf_sram.aprs.digi.call },
|
||||
{TYPE_STR, "aprs.digi.path", sizeof(conf_sram.aprs.digi.path), &conf_sram.aprs.digi.path },
|
||||
{TYPE_INT, "aprs.digi.symbol", sizeof(conf_sram.aprs.digi.symbol), &conf_sram.aprs.digi.symbol },
|
||||
{TYPE_INT, "aprs.digi.beacon", sizeof(conf_sram.aprs.digi.beacon), &conf_sram.aprs.digi.beacon },
|
||||
{TYPE_INT, "aprs.digi.gps", sizeof(conf_sram.aprs.digi.gps), &conf_sram.aprs.digi.gps },
|
||||
{TYPE_INT, "lat", sizeof(conf_sram.lat), &conf_sram.lat },
|
||||
{TYPE_INT, "lon", sizeof(conf_sram.lon), &conf_sram.lon },
|
||||
{TYPE_INT, "alt", sizeof(conf_sram.alt), &conf_sram.alt },
|
||||
{TYPE_INT, "aprs.digi.cycle", sizeof(conf_sram.aprs.digi.cycle), &conf_sram.aprs.digi.cycle },
|
||||
{TYPE_INT, "aprs.digi.digi_active", sizeof(conf_sram.aprs.digi.active), &conf_sram.aprs.digi.active },
|
||||
{TYPE_INT, "aprs.freq", sizeof(conf_sram.aprs.freq), &conf_sram.aprs.freq },
|
||||
{TYPE_INT, "aprs.digi.beacon", sizeof(conf_sram.aprs.digi.beacon.svc_conf.active), &conf_sram.aprs.digi.beacon.svc_conf.active },
|
||||
|
||||
{TYPE_INT, "aprs.beacon.lat", sizeof(conf_sram.aprs.digi.beacon.lat), &conf_sram.aprs.digi.beacon.lat },
|
||||
{TYPE_INT, "aprs.beacon.lon", sizeof(conf_sram.aprs.digi.beacon.lon), &conf_sram.aprs.digi.beacon.lon },
|
||||
{TYPE_INT, "aprs.beacon.alt", sizeof(conf_sram.aprs.digi.beacon.alt), &conf_sram.aprs.digi.beacon.alt },
|
||||
{TYPE_INT, "aprs.beacon.cycle", sizeof(conf_sram.aprs.digi.beacon.svc_conf.cycle), &conf_sram.aprs.digi.beacon.svc_conf.cycle },
|
||||
|
||||
{TYPE_INT, "keep_cam_switched_on", sizeof(conf_sram.keep_cam_switched_on), &conf_sram.keep_cam_switched_on },
|
||||
{TYPE_INT, "gps_on_vbat", sizeof(conf_sram.gps_on_vbat), &conf_sram.gps_on_vbat },
|
||||
{TYPE_INT, "gps_off_vbat", sizeof(conf_sram.gps_off_vbat), &conf_sram.gps_off_vbat },
|
||||
|
@ -166,6 +158,16 @@ const conf_command_t command_list[] = {
|
|||
{TYPE_INT, "gps_low_alt", sizeof(conf_sram.gps_low_alt), &conf_sram.gps_low_alt },
|
||||
{TYPE_INT, "gps_high_alt", sizeof(conf_sram.gps_high_alt), &conf_sram.gps_high_alt },
|
||||
|
||||
{TYPE_INT, "default.freq", sizeof(conf_sram.freq), &conf_sram.freq },
|
||||
|
||||
{TYPE_INT, "base.freq", sizeof(conf_sram.base.radio_conf.freq), &conf_sram.base.radio_conf.freq },
|
||||
{TYPE_INT, "base.pwr", sizeof(conf_sram.base.radio_conf.pwr), &conf_sram.base.radio_conf.pwr },
|
||||
{TYPE_INT, "base.mod", sizeof(conf_sram.base.radio_conf.mod), &conf_sram.base.radio_conf.mod },
|
||||
{TYPE_INT, "base.cca", sizeof(conf_sram.base.radio_conf.cca), &conf_sram.base.radio_conf.cca },
|
||||
{TYPE_STR, "base.call", sizeof(conf_sram.base.call), &conf_sram.base.call },
|
||||
|
||||
{TYPE_TIME, "tel_enc_cycle", sizeof(conf_sram.tel_enc_cycle), &conf_sram.tel_enc_cycle },
|
||||
|
||||
{TYPE_NULL}
|
||||
};
|
||||
|
||||
|
@ -1136,7 +1138,7 @@ static bool aprs_decode_message(packet_t pp) {
|
|||
/* Check which apps are enabled to accept APRS messages. */
|
||||
bool pos_pri = (strcmp(conf_sram.pos_pri.call, dest) == 0)
|
||||
&& (conf_sram.pos_pri.aprs_msg)
|
||||
&& (conf_sram.pos_pri.thread_conf.active);
|
||||
&& (conf_sram.pos_pri.svc_conf.active);
|
||||
|
||||
if(pos_pri) {
|
||||
strcpy(identity.call, conf_sram.pos_pri.call);
|
||||
|
@ -1146,7 +1148,7 @@ static bool aprs_decode_message(packet_t pp) {
|
|||
|
||||
bool pos_sec = (strcmp(conf_sram.pos_sec.call, dest) == 0)
|
||||
&& (conf_sram.pos_sec.aprs_msg)
|
||||
&& (conf_sram.pos_sec.thread_conf.active);
|
||||
&& (conf_sram.pos_sec.svc_conf.active);
|
||||
if(pos_sec) {
|
||||
strcpy(identity.call, conf_sram.pos_sec.call);
|
||||
strcpy(identity.path, conf_sram.pos_sec.path);
|
||||
|
@ -1154,7 +1156,7 @@ static bool aprs_decode_message(packet_t pp) {
|
|||
}
|
||||
|
||||
bool aprs_rx = (strcmp(conf_sram.aprs.rx.call, dest) == 0)
|
||||
&& (conf_sram.aprs.thread_conf.active);
|
||||
&& (conf_sram.aprs.svc_conf.active);
|
||||
if(aprs_rx) {
|
||||
strcpy(identity.call, conf_sram.aprs.rx.call);
|
||||
identity.symbol = conf_sram.aprs.rx.symbol;
|
||||
|
@ -1163,7 +1165,7 @@ static bool aprs_decode_message(packet_t pp) {
|
|||
|
||||
/* Even if the digi is not active respond on the digi (TX) call. */
|
||||
bool aprs_tx = (strcmp(conf_sram.aprs.digi.call, dest) == 0)
|
||||
&& (conf_sram.aprs.thread_conf.active)
|
||||
&& (conf_sram.aprs.svc_conf.active)
|
||||
/*&& (conf_sram.aprs.digi.active)*/;
|
||||
/* Default already set tx parameters. */
|
||||
|
||||
|
|
|
@ -31,10 +31,17 @@
|
|||
static dataPoint_t dataPoints[2];
|
||||
static dataPoint_t* lastDataPoint;
|
||||
static bool threadStarted = false;
|
||||
#if USE_NEW_COLLECTOR != TRUE
|
||||
static uint8_t useGPS = 0;
|
||||
#endif
|
||||
static uint8_t useCFG = 0;
|
||||
static uint8_t bme280_error;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module external variables. */
|
||||
/*===========================================================================*/
|
||||
thread_t *collector_thd;
|
||||
|
||||
/**
|
||||
* Returns most recent data point which is complete.
|
||||
*/
|
||||
|
@ -45,11 +52,11 @@ dataPoint_t* getLastDataPoint(void) {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
void waitForNewDataPoint(void) {
|
||||
/*void waitForNewDataPoint(void) {
|
||||
uint32_t old_id = getLastDataPoint()->id;
|
||||
while(old_id == getLastDataPoint()->id)
|
||||
chThdSleep(TIME_S2I(1));
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* @brief Determine best fallback data when GPS not operable.
|
||||
|
@ -107,8 +114,7 @@ static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp,
|
|||
gpsFix_t gpsFix = {0};
|
||||
|
||||
/*
|
||||
* Switch on GPS if...
|
||||
* position/time is requested by a service and power is available.
|
||||
* Is there enough battery voltage for GPS?
|
||||
*/
|
||||
uint16_t batt = stm32_get_vbat();
|
||||
if(batt < conf_sram.gps_on_vbat) {
|
||||
|
@ -144,8 +150,8 @@ static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp,
|
|||
|
||||
if(batt < conf_sram.gps_off_vbat) {
|
||||
/*
|
||||
* GPS was switched on but battery fell below threshold.
|
||||
* Switch off GPS.
|
||||
* GPS was switched on but battery fell below threshold during acquisition.
|
||||
* Switch off GPS and get fallback position data.
|
||||
*/
|
||||
|
||||
GPS_Deinit();
|
||||
|
@ -156,7 +162,7 @@ static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp,
|
|||
}
|
||||
if(!isGPSLocked(&gpsFix)) {
|
||||
/*
|
||||
* GPS was switched on but it failed to get a lock in timeout period.
|
||||
* GPS was switched on but it failed to get a lock within timeout period.
|
||||
* Keep GPS switched on.
|
||||
*/
|
||||
TRACE_WARN("COLL > GPS sampling finished GPS LOSS");
|
||||
|
@ -190,8 +196,10 @@ static void aquirePosition(dataPoint_t* tp, dataPoint_t* ltp,
|
|||
if(timeout < TIME_S2I(60)) {
|
||||
TRACE_INFO("COLL > Keep GPS switched on because cycle < 60sec");
|
||||
tp->gps_state = GPS_LOCKED2;
|
||||
} else if(conf_sram.gps_onper_vbat != 0 && batt >= conf_sram.gps_onper_vbat) {
|
||||
TRACE_INFO("COLL > Keep GPS switched on because VBAT >= %dmV", conf_sram.gps_onper_vbat);
|
||||
} else if(conf_sram.gps_onper_vbat != 0
|
||||
&& batt >= conf_sram.gps_onper_vbat) {
|
||||
TRACE_INFO("COLL > Keep GPS switched on because VBAT >= %dmV",
|
||||
conf_sram.gps_onper_vbat);
|
||||
tp->gps_state = GPS_LOCKED2;
|
||||
} else {
|
||||
TRACE_INFO("COLL > Switching off GPS");
|
||||
|
@ -441,18 +449,20 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
// Determine cycle time and if GPS should be used.
|
||||
sysinterval_t data_cycle_time = TIME_S2I(600); // Default.
|
||||
|
||||
if(conf_sram.pos_pri.thread_conf.active && conf_sram.pos_sec.thread_conf.active) { // Both position threads are active
|
||||
data_cycle_time = conf_sram.pos_pri.thread_conf.cycle < conf_sram.pos_sec.thread_conf.cycle ? conf_sram.pos_pri.thread_conf.cycle : conf_sram.pos_sec.thread_conf.cycle; // Choose the smallest cycle
|
||||
if(conf_sram.pos_pri.svc_conf.active && conf_sram.pos_sec.svc_conf.active) { // Both position threads are active
|
||||
data_cycle_time = conf_sram.pos_pri.svc_conf.cycle < conf_sram.pos_sec.svc_conf.cycle ? conf_sram.pos_pri.svc_conf.cycle : conf_sram.pos_sec.svc_conf.cycle; // Choose the smallest cycle
|
||||
(*useGPS)++;
|
||||
} else if(conf_sram.pos_pri.thread_conf.active) { // Only primary position thread is active
|
||||
data_cycle_time = conf_sram.pos_pri.thread_conf.cycle;
|
||||
} else if(conf_sram.pos_pri.svc_conf.active) { // Only primary position thread is active
|
||||
data_cycle_time = conf_sram.pos_pri.svc_conf.cycle;
|
||||
(*useGPS)++;
|
||||
} else if(conf_sram.pos_sec.thread_conf.active) { // Only secondary position thread is active
|
||||
data_cycle_time = conf_sram.pos_sec.thread_conf.cycle;
|
||||
} else if(conf_sram.pos_sec.svc_conf.active) { // Only secondary position thread is active
|
||||
data_cycle_time = conf_sram.pos_sec.svc_conf.cycle;
|
||||
(*useGPS)++;
|
||||
} else if(conf_sram.aprs.thread_conf.active && conf_sram.aprs.digi.beacon) { // DIGI beacon is active
|
||||
data_cycle_time = conf_sram.aprs.digi.cycle;
|
||||
if(conf_sram.aprs.digi.gps) {
|
||||
} else if(conf_sram.aprs.svc_conf.active
|
||||
&& conf_sram.aprs.digi.active
|
||||
&& conf_sram.aprs.digi.beacon.svc_conf.active) { // DIGI beacon is active
|
||||
data_cycle_time = conf_sram.aprs.digi.beacon.svc_conf.cycle;
|
||||
if(conf_sram.aprs.digi.beacon.svc_conf.active) {
|
||||
(*useGPS)++;
|
||||
}
|
||||
} else { // There must be an error
|
||||
|
@ -495,7 +505,7 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
continue;
|
||||
}
|
||||
TRACE_INFO("COLL > Time acquired from GPS");
|
||||
/* Switch GPS off. */
|
||||
/* Switch GPS off since there are no other users. */
|
||||
GPS_Deinit();
|
||||
}
|
||||
|
||||
|
@ -513,9 +523,9 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
TRACE_INFO("COLL > Using fixed location");
|
||||
getTime(&time);
|
||||
unixTimestamp2Date(&time, tp->gps_time);
|
||||
tp->gps_alt = conf_sram.alt;
|
||||
tp->gps_lat = conf_sram.lat;
|
||||
tp->gps_lon = conf_sram.lon;
|
||||
//tp->gps_alt = conf_sram.alt;
|
||||
//tp->gps_lat = conf_sram.lat;
|
||||
//tp->gps_lon = conf_sram.lon;
|
||||
tp->gps_state = GPS_FIXED;
|
||||
}
|
||||
|
||||
|
@ -556,7 +566,6 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
* Any thread sending telemetry would request this service be started.
|
||||
*/
|
||||
THD_FUNCTION(configThread, arg) {
|
||||
//uint8_t *useCFG = arg;
|
||||
(void)arg;
|
||||
while(true) chThdSleep(TIME_S2I(1));
|
||||
}
|
||||
|
@ -566,9 +575,167 @@ THD_FUNCTION(configThread, arg) {
|
|||
* TODO: To provide GPS status and data.
|
||||
*/
|
||||
THD_FUNCTION(gpsThread, arg) {
|
||||
//uint8_t *useCFG = arg;
|
||||
(void)arg;
|
||||
while(true) chThdSleep(TIME_S2I(1));
|
||||
|
||||
uint32_t id = 0;
|
||||
//msg_t result;
|
||||
|
||||
// Read time from RTC
|
||||
ptime_t time;
|
||||
getTime(&time);
|
||||
dataPoints[0].gps_time = date2UnixTimestamp(&time);
|
||||
dataPoints[1].gps_time = date2UnixTimestamp(&time);
|
||||
|
||||
lastDataPoint = &dataPoints[0];
|
||||
dataPoint_t *newDataPoint = lastDataPoint++;
|
||||
|
||||
// Get last data point from memory
|
||||
TRACE_INFO("COLL > Read last data point from flash memory");
|
||||
dataPoint_t* lastLogPoint = flash_getNewestLogEntry();
|
||||
|
||||
if(lastLogPoint != NULL) { // If there is stored data point, then get it.
|
||||
dataPoints[0].reset = lastLogPoint->reset+1;
|
||||
dataPoints[1].reset = lastLogPoint->reset+1;
|
||||
unixTimestamp2Date(&time, lastDataPoint->gps_time);
|
||||
lastDataPoint->gps_lat = lastLogPoint->gps_lat;
|
||||
lastDataPoint->gps_lon = lastLogPoint->gps_lon;
|
||||
lastDataPoint->gps_alt = lastLogPoint->gps_alt;
|
||||
lastDataPoint->gps_sats = lastLogPoint->gps_sats;
|
||||
lastDataPoint->gps_ttff = lastLogPoint->gps_ttff;
|
||||
|
||||
TRACE_INFO(
|
||||
"COLL > Last data point (from memory)\r\n"
|
||||
"%s Reset %d ID %d\r\n"
|
||||
"%s Time %04d-%02d-%02d %02d:%02d:%02d\r\n"
|
||||
"%s Latitude: %d.%07ddeg\r\n"
|
||||
"%s Longitude: %d.%07ddeg\r\n"
|
||||
"%s Altitude: %d Meter",
|
||||
TRACE_TAB, lastLogPoint->reset, lastLogPoint->id,
|
||||
TRACE_TAB, time.year, time.month, time.day, time.hour,
|
||||
time.minute, time.day,
|
||||
TRACE_TAB, lastDataPoint->gps_lat/10000000,
|
||||
(lastDataPoint->gps_lat > 0
|
||||
? 1:-1)*lastDataPoint->gps_lat%10000000,
|
||||
TRACE_TAB, lastDataPoint->gps_lon/10000000,
|
||||
(lastDataPoint->gps_lon > 0
|
||||
? 1:-1)*lastDataPoint->gps_lon%10000000,
|
||||
TRACE_TAB, lastDataPoint->gps_alt
|
||||
);
|
||||
lastDataPoint->gps_state = GPS_LOG; // Mark dataPoint as LOG packet
|
||||
//result = MSG_OK;
|
||||
} else {
|
||||
TRACE_INFO("COLL > No data point found in flash memory");
|
||||
/* State indicates that no valid stored position is available. */
|
||||
lastDataPoint->gps_state = GPS_OFF;
|
||||
//result = MSG_TIMEOUT;
|
||||
}
|
||||
|
||||
// Measure telemetry
|
||||
measureVoltage(lastDataPoint);
|
||||
getSensors(lastDataPoint);
|
||||
getGPIO(lastDataPoint);
|
||||
setSystemStatus(lastDataPoint);
|
||||
|
||||
// Write data point to Flash memory
|
||||
flash_writeLogDataPoint(lastDataPoint);
|
||||
|
||||
// Wait for position threads to start
|
||||
//chThdSleep(TIME_MS2I(500));
|
||||
|
||||
//sysinterval_t cycle_time = chVTGetSystemTime();
|
||||
|
||||
// Determine cycle time and if GPS should be used.
|
||||
sysinterval_t data_cycle_time = TIME_S2I(600); // Default.
|
||||
|
||||
getTime(&time);
|
||||
if(time.year == RTC_BASE_YEAR) {
|
||||
/*
|
||||
* The RTC is not set.
|
||||
* Enable the GPS and attempt a lock which results in setting the RTC.
|
||||
*/
|
||||
TRACE_INFO("COLL > Acquire time using GPS");
|
||||
aquirePosition(newDataPoint, lastDataPoint, data_cycle_time - TIME_S2I(3));
|
||||
/* RTC is set in aquirePosition(...). */
|
||||
if(hasGPSacquiredLock(newDataPoint)) {
|
||||
/* Acquisition succeeded. */
|
||||
TRACE_INFO("COLL > Time acquisition from GPS succeeded");
|
||||
/* Update with freshly acquired data. */
|
||||
lastDataPoint = newDataPoint;
|
||||
GPS_Deinit();
|
||||
//result = MSG_OK;
|
||||
} else {
|
||||
TRACE_INFO("COLL > Time not acquired from GPS");
|
||||
//result = MSG_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
while(true) { /* Primary loop. */
|
||||
/* Wait for a request from a client. */
|
||||
thread_t *caller = chMsgWait();
|
||||
/* Fetch the message. */
|
||||
thd_pos_conf_t *config;
|
||||
config = (thd_pos_conf_t *)chMsgGet(caller);
|
||||
|
||||
TRACE_INFO("COLL > Respond to request for DATA COLLECTOR cycle");
|
||||
|
||||
dataPoint_t* tp = &dataPoints[(id+1) % 2]; // Current data point (the one which is processed now)
|
||||
dataPoint_t* ltp = &dataPoints[ id % 2]; // Last data point
|
||||
|
||||
/* Clear remnant data. */
|
||||
memset(tp, 0, sizeof(dataPoint_t));
|
||||
|
||||
/* Gather telemetry and system status data. */
|
||||
measureVoltage(tp);
|
||||
getSensors(tp);
|
||||
getGPIO(tp);
|
||||
setSystemStatus(tp);
|
||||
|
||||
if(!config->fixed) {
|
||||
TRACE_INFO("COLL > Acquire position using GPS");
|
||||
aquirePosition(tp, ltp, data_cycle_time - TIME_S2I(3));
|
||||
//result = MSG_OK;
|
||||
} else {
|
||||
/*
|
||||
* Update datapoint time from RTC.
|
||||
* Set fixed location.
|
||||
*/
|
||||
TRACE_INFO("COLL > Using fixed location");
|
||||
getTime(&time);
|
||||
unixTimestamp2Date(&time, tp->gps_time);
|
||||
tp->gps_alt = config->alt;
|
||||
tp->gps_lat = config->lat;
|
||||
tp->gps_lon = config->lon;
|
||||
tp->gps_state = GPS_FIXED;
|
||||
//result = MSG_OK;
|
||||
}
|
||||
tp->id = ++id; // Serial ID
|
||||
|
||||
// Trace data
|
||||
unixTimestamp2Date(&time, tp->gps_time);
|
||||
TRACE_INFO( "COLL > New data point available (ID=%d)\r\n"
|
||||
"%s Time %04d-%02d-%02d %02d:%02d:%02d\r\n"
|
||||
"%s Pos %d.%05d %d.%05d Alt %dm\r\n"
|
||||
"%s Sats %d TTFF %dsec\r\n"
|
||||
"%s ADC Vbat=%d.%03dV Vsol=%d.%03dV Pbat=%dmW\r\n"
|
||||
"%s AIR p=%d.%01dPa T=%d.%02ddegC phi=%d.%01d%%\r\n"
|
||||
"%s IOP IO1=%d IO2=%d IO3=%d IO4=%d",
|
||||
tp->id,
|
||||
TRACE_TAB, time.year, time.month, time.day, time.hour, time.minute, time.day,
|
||||
TRACE_TAB, tp->gps_lat/10000000, (tp->gps_lat > 0 ? 1:-1)*(tp->gps_lat/100)%100000, tp->gps_lon/10000000, (tp->gps_lon > 0 ? 1:-1)*(tp->gps_lon/100)%100000, tp->gps_alt,
|
||||
TRACE_TAB, tp->gps_sats, tp->gps_ttff,
|
||||
TRACE_TAB, tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->pac_pbat,
|
||||
TRACE_TAB, tp->sen_i1_press/10, tp->sen_i1_press%10, tp->sen_i1_temp/100, tp->sen_i1_temp%100, tp->sen_i1_hum/10, tp->sen_i1_hum%10,
|
||||
TRACE_TAB, tp->gpio & 1, (tp->gpio >> 1) & 1, (tp->gpio >> 2) & 1, (tp->gpio >> 3) & 1
|
||||
);
|
||||
|
||||
// Write data point to Flash memory
|
||||
flash_writeLogDataPoint(tp);
|
||||
|
||||
// Switch last data point
|
||||
lastDataPoint = tp;
|
||||
/* Reply to the calling thread. */
|
||||
chMsgRelease(caller, (msg_t)tp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -578,7 +745,7 @@ void init_data_collector() {
|
|||
if(!threadStarted) {
|
||||
|
||||
threadStarted = true;
|
||||
|
||||
#if USE_NEW_COLLECTOR != TRUE
|
||||
TRACE_INFO("COLL > Startup data collector thread");
|
||||
thread_t *th = chThdCreateFromHeap(NULL,
|
||||
THD_WORKING_AREA_SIZE(10*1024),
|
||||
|
@ -591,7 +758,9 @@ void init_data_collector() {
|
|||
} else {
|
||||
chThdSleep(TIME_MS2I(300)); // Wait a little bit until data collector has initialized first dataset
|
||||
}
|
||||
|
||||
#else
|
||||
thread_t *th;
|
||||
#endif
|
||||
TRACE_INFO("CFG > Startup telemetry config thread");
|
||||
th = chThdCreateFromHeap(NULL,
|
||||
THD_WORKING_AREA_SIZE(2*1024),
|
||||
|
@ -615,6 +784,7 @@ void init_data_collector() {
|
|||
TRACE_ERROR("GPS > Could not start"
|
||||
" thread (not enough memory available)");
|
||||
} else {
|
||||
collector_thd = th;
|
||||
chThdSleep(TIME_MS2I(300));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,139 +1,148 @@
|
|||
#ifndef __COLLECTOR_H__
|
||||
#define __COLLECTOR_H__
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "ptime.h"
|
||||
|
||||
#define BME_STATUS_BITS 2
|
||||
#define BME_STATUS_MASK 0x3
|
||||
#define BME_OK_VALUE 0x0
|
||||
#define BME_FAIL_VALUE 0x1
|
||||
#define BME_NOT_FITTED_VALUE 0x2
|
||||
|
||||
#define BME_ALL_STATUS_MASK 0x3F
|
||||
#define BME_ALL_STATUS_SHIFT 8
|
||||
|
||||
#define BMEI1_STATUS_SHIFT BME_ALL_STATUS_SHIFT
|
||||
#define BMEI1_STATUS_MASK (BME_STATUS_MASK << BMEI1_STATUS_SHIFT)
|
||||
|
||||
#define BMEE1_STATUS_SHIFT BMEI1_STATUS_SHIFT + BME_STATUS_BITS
|
||||
#define BMEE1_STATUS_MASK (BME_STATUS_MASK << BMEE1_STATUS_SHIFT)
|
||||
|
||||
#define BMEE2_STATUS_SHIFT BMEI1_STATUS_SHIFT + BME_STATUS)BITS
|
||||
#define BMEE2_STATUS_MASK (BME_STATUS_MASK << BMEE2_STATUS_SHIFT)
|
||||
|
||||
typedef enum {
|
||||
GPS_LOCKED1, // The GPS is locked, the GPS has been switched off
|
||||
GPS_LOCKED2, // The GPS is locked, the GPS has been kept switched on
|
||||
GPS_LOSS, // The GPS was switched on all time but it couln't acquire a fix
|
||||
GPS_LOWBATT1, // The GPS wasn't switched on because the battery has not enough energy
|
||||
GPS_LOWBATT2, // The GPS was switched on but has been switched off prematurely while the battery has not enough energy (or is too cold)
|
||||
GPS_LOG, // The tracker has just been switched on and the position has been taken from the log
|
||||
GPS_OFF, // There was no prior acquisition by GPS
|
||||
GPS_ERROR, // The GPS has a communication error
|
||||
GPS_FIXED // Fixed location data used from APRS location
|
||||
} gpsState_t;
|
||||
|
||||
typedef struct {
|
||||
// Voltage and current measurement
|
||||
uint16_t adc_vsol; // Current solar voltage in mV
|
||||
uint16_t adc_vbat; // Current battery voltage in mV
|
||||
uint16_t pac_vsol;
|
||||
uint16_t pac_vbat;
|
||||
int16_t pac_pbat;
|
||||
int16_t pac_psol;
|
||||
|
||||
uint16_t light_intensity;
|
||||
|
||||
// GPS
|
||||
gpsState_t gps_state; // GPS state
|
||||
uint8_t gps_sats; // Satellites used for solution
|
||||
uint8_t gps_ttff; // Time to first fix in seconds
|
||||
uint8_t gps_pdop; // Position DOP in 0.05 per arbitrary unit
|
||||
uint16_t gps_alt; // Altitude in meter
|
||||
int32_t gps_lat; // Latitude in 10^(-7)° per unit
|
||||
int32_t gps_lon; // Longitude in 10^(-7)° per unit
|
||||
|
||||
// BME280 (on board i1 + off board e1 & e2)
|
||||
uint32_t sen_i1_press; // Airpressure in Pa*10 (in 0.1Pa)
|
||||
uint32_t sen_e1_press; // Airpressure in Pa*10 (in 0.1Pa)
|
||||
uint32_t sen_e2_press; // Airpressure in Pa*10 (in 0.1Pa)
|
||||
|
||||
int16_t sen_i1_temp; // Temperature in 0.01°C per unit
|
||||
int16_t sen_e1_temp; // Temperature in 0.01°C per unit
|
||||
int16_t sen_e2_temp; // Temperature in 0.01°C per unit
|
||||
|
||||
uint8_t sen_i1_hum; // Rel. humidity in %
|
||||
uint8_t sen_e1_hum; // Rel. humidity in %
|
||||
uint8_t sen_e2_hum; // Rel. humidity in %
|
||||
|
||||
uint8_t dummy2;
|
||||
|
||||
int16_t stm32_temp;
|
||||
int16_t si446x_temp;
|
||||
|
||||
uint16_t reset;
|
||||
uint32_t id; // Serial ID
|
||||
uint32_t gps_time; // GPS time
|
||||
|
||||
uint32_t sys_time; // System time (in seconds)
|
||||
uint32_t sys_error; // System error flags
|
||||
/*
|
||||
* Set system errors.
|
||||
*
|
||||
* Bit usage:
|
||||
* - 0:1 I2C status
|
||||
* - 2:2 GPS status
|
||||
* - 3:4 pac1720 status
|
||||
* - 5:7 OV5640 status
|
||||
* - 8:9 BMEi1 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
* - 10:11 BMEe1 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
* - 12:13 BMEe2 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
*/
|
||||
|
||||
uint8_t gpio; // GPIO states
|
||||
} dataPoint_t;
|
||||
|
||||
void waitForNewDataPoint(void);
|
||||
dataPoint_t* getLastDataPoint(void);
|
||||
void getSensors(dataPoint_t* tp);
|
||||
void setSystemStatus(dataPoint_t* tp);
|
||||
void init_data_collector(void);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Has GPS achieved lock (even if now switched off).
|
||||
*
|
||||
* @param[in] pointer to data point
|
||||
*
|
||||
* @returns result of check
|
||||
* @retval true if lock has been achieved
|
||||
* @retval false if lock has not yet been achieved
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define hasGPSacquiredLock(dp) (dp->gps_state == GPS_LOCKED1 \
|
||||
|| dp->gps_state == GPS_LOCKED2)
|
||||
|
||||
/**
|
||||
* @brief Is position valid.
|
||||
*
|
||||
* @param[in] pointer to data point
|
||||
*
|
||||
* @returns result of check
|
||||
* @retval true if position data is valid
|
||||
* @retval false if position not valid
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define isPositionValid(dp) (dp->gps_state == GPS_LOCKED1 \
|
||||
|| dp->gps_state == GPS_LOCKED2 \
|
||||
|| dp->gps_state == GPS_FIXED \
|
||||
|| dp->gps_state == GPS_LOG)
|
||||
|
||||
#endif /* __COLLECTOR_H__ */
|
||||
|
||||
#ifndef __COLLECTOR_H__
|
||||
#define __COLLECTOR_H__
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "ptime.h"
|
||||
#include "types.h"
|
||||
|
||||
#define BME_STATUS_BITS 2
|
||||
#define BME_STATUS_MASK 0x3
|
||||
#define BME_OK_VALUE 0x0
|
||||
#define BME_FAIL_VALUE 0x1
|
||||
#define BME_NOT_FITTED_VALUE 0x2
|
||||
|
||||
#define BME_ALL_STATUS_MASK 0x3F
|
||||
#define BME_ALL_STATUS_SHIFT 8
|
||||
|
||||
#define BMEI1_STATUS_SHIFT BME_ALL_STATUS_SHIFT
|
||||
#define BMEI1_STATUS_MASK (BME_STATUS_MASK << BMEI1_STATUS_SHIFT)
|
||||
|
||||
#define BMEE1_STATUS_SHIFT BMEI1_STATUS_SHIFT + BME_STATUS_BITS
|
||||
#define BMEE1_STATUS_MASK (BME_STATUS_MASK << BMEE1_STATUS_SHIFT)
|
||||
|
||||
#define BMEE2_STATUS_SHIFT BMEI1_STATUS_SHIFT + BME_STATUS)BITS
|
||||
#define BMEE2_STATUS_MASK (BME_STATUS_MASK << BMEE2_STATUS_SHIFT)
|
||||
|
||||
#define USE_NEW_COLLECTOR TRUE
|
||||
|
||||
typedef enum {
|
||||
GPS_LOCKED1, // The GPS is locked, the GPS has been switched off
|
||||
GPS_LOCKED2, // The GPS is locked, the GPS has been kept switched on
|
||||
GPS_LOSS, // The GPS was switched on all time but it couln't acquire a fix
|
||||
GPS_LOWBATT1, // The GPS wasn't switched on because the battery has not enough energy
|
||||
GPS_LOWBATT2, // The GPS was switched on but has been switched off prematurely while the battery has not enough energy (or is too cold)
|
||||
GPS_LOG, // The tracker has just been switched on and the position has been taken from the log
|
||||
GPS_OFF, // There was no prior acquisition by GPS
|
||||
GPS_ERROR, // The GPS has a communication error
|
||||
GPS_FIXED // Fixed location data used from APRS location
|
||||
} gpsState_t;
|
||||
|
||||
typedef struct {
|
||||
// Voltage and current measurement
|
||||
uint16_t adc_vsol; // Current solar voltage in mV
|
||||
uint16_t adc_vbat; // Current battery voltage in mV
|
||||
uint16_t pac_vsol;
|
||||
uint16_t pac_vbat;
|
||||
int16_t pac_pbat;
|
||||
int16_t pac_psol;
|
||||
|
||||
uint16_t light_intensity;
|
||||
|
||||
// GPS
|
||||
gpsState_t gps_state; // GPS state
|
||||
uint8_t gps_sats; // Satellites used for solution
|
||||
uint8_t gps_ttff; // Time to first fix in seconds
|
||||
uint8_t gps_pdop; // Position DOP in 0.05 per arbitrary unit
|
||||
uint16_t gps_alt; // Altitude in meter
|
||||
int32_t gps_lat; // Latitude in 10^(-7)° per unit
|
||||
int32_t gps_lon; // Longitude in 10^(-7)° per unit
|
||||
|
||||
// BME280 (on board i1 + off board e1 & e2)
|
||||
uint32_t sen_i1_press; // Airpressure in Pa*10 (in 0.1Pa)
|
||||
uint32_t sen_e1_press; // Airpressure in Pa*10 (in 0.1Pa)
|
||||
uint32_t sen_e2_press; // Airpressure in Pa*10 (in 0.1Pa)
|
||||
|
||||
int16_t sen_i1_temp; // Temperature in 0.01°C per unit
|
||||
int16_t sen_e1_temp; // Temperature in 0.01°C per unit
|
||||
int16_t sen_e2_temp; // Temperature in 0.01°C per unit
|
||||
|
||||
uint8_t sen_i1_hum; // Rel. humidity in %
|
||||
uint8_t sen_e1_hum; // Rel. humidity in %
|
||||
uint8_t sen_e2_hum; // Rel. humidity in %
|
||||
|
||||
uint8_t dummy2;
|
||||
|
||||
int16_t stm32_temp;
|
||||
int16_t si446x_temp;
|
||||
|
||||
uint16_t reset;
|
||||
uint32_t id; // Serial ID
|
||||
uint32_t gps_time; // GPS time
|
||||
|
||||
uint32_t sys_time; // System time (in seconds)
|
||||
uint32_t sys_error; // System error flags
|
||||
/*
|
||||
* Set system errors.
|
||||
*
|
||||
* Bit usage:
|
||||
* - 0:1 I2C status
|
||||
* - 2:2 GPS status
|
||||
* - 3:4 pac1720 status
|
||||
* - 5:7 OV5640 status
|
||||
* - 8:9 BMEi1 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
* - 10:11 BMEe1 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
* - 12:13 BMEe2 status (0 = OK, 1 = Fail, 2 = Not fitted)
|
||||
*/
|
||||
|
||||
uint8_t gpio; // GPIO states
|
||||
} dataPoint_t;
|
||||
|
||||
|
||||
/*typedef struct telemRequest {
|
||||
dataPoint_t dp;
|
||||
thd_pos_conf_t *conf;
|
||||
} telem_request_t;*/
|
||||
|
||||
//void waitForNewDataPoint(void);
|
||||
dataPoint_t* getLastDataPoint(void);
|
||||
void getSensors(dataPoint_t* tp);
|
||||
void setSystemStatus(dataPoint_t* tp);
|
||||
void init_data_collector(void);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Has GPS achieved lock (even if now switched off).
|
||||
*
|
||||
* @param[in] pointer to data point
|
||||
*
|
||||
* @returns result of check
|
||||
* @retval true if lock has been achieved
|
||||
* @retval false if lock has not yet been achieved
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define hasGPSacquiredLock(dp) (dp->gps_state == GPS_LOCKED1 \
|
||||
|| dp->gps_state == GPS_LOCKED2)
|
||||
|
||||
/**
|
||||
* @brief Is position valid.
|
||||
*
|
||||
* @param[in] pointer to data point
|
||||
*
|
||||
* @returns result of check
|
||||
* @retval true if position data is valid
|
||||
* @retval false if position not valid
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define isPositionValid(dp) (dp->gps_state == GPS_LOCKED1 \
|
||||
|| dp->gps_state == GPS_LOCKED2 \
|
||||
|| dp->gps_state == GPS_FIXED \
|
||||
|| dp->gps_state == GPS_LOG)
|
||||
|
||||
#endif /* __COLLECTOR_H__ */
|
||||
|
||||
|
|
|
@ -1,157 +1,177 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "threads.h"
|
||||
#include "config.h"
|
||||
#include "radio.h"
|
||||
#include "aprs.h"
|
||||
#include "sleep.h"
|
||||
#include "chprintf.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "watchdog.h"
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
THD_FUNCTION(bcnThread, arg) {
|
||||
thd_aprs_conf_t* conf = (thd_aprs_conf_t *)arg;
|
||||
|
||||
// Wait
|
||||
if(conf->thread_conf.init_delay) chThdSleep(conf->thread_conf.init_delay);
|
||||
|
||||
// Start data collector (if not running yet)
|
||||
init_data_collector();
|
||||
|
||||
// Start position thread
|
||||
TRACE_INFO("BCN > Startup beacon thread");
|
||||
|
||||
// Set telemetry configuration transmission variables
|
||||
sysinterval_t last_conf_transmission =
|
||||
chVTGetSystemTime() - conf->digi.tel_enc_cycle;
|
||||
sysinterval_t time = chVTGetSystemTime();
|
||||
|
||||
while(true) {
|
||||
char code_s[100];
|
||||
pktDisplayFrequencyCode(conf->digi.radio_conf.freq,
|
||||
code_s, sizeof(code_s));
|
||||
TRACE_INFO("POS > Do module BEACON cycle for %s on %s",
|
||||
conf->digi.call, code_s);
|
||||
|
||||
dataPoint_t* dataPoint = getLastDataPoint();
|
||||
if(!p_sleep(&conf->thread_conf.sleep_conf)) {
|
||||
|
||||
// Telemetry encoding parameter transmissions
|
||||
if(conf->digi.tel_enc_cycle != 0 && last_conf_transmission
|
||||
+ conf->digi.tel_enc_cycle < chVTGetSystemTime()) {
|
||||
|
||||
TRACE_INFO("BCN > Transmit telemetry configuration");
|
||||
|
||||
// Encode and transmit telemetry config packet
|
||||
for(uint8_t type = 0; type < APRS_NUM_TELEM_GROUPS; type++) {
|
||||
packet_t packet = aprs_encode_telemetry_configuration(
|
||||
conf->digi.call,
|
||||
conf->digi.path,
|
||||
conf->digi.call,
|
||||
type);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("BCN > No free packet objects for"
|
||||
" telemetry config transmission");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->digi.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->digi.radio_conf.pwr,
|
||||
conf->digi.radio_conf.mod,
|
||||
conf->digi.radio_conf.cca)) {
|
||||
TRACE_ERROR("BCN > Failed to transmit telemetry config");
|
||||
}
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
last_conf_transmission += conf->digi.tel_enc_cycle;
|
||||
}
|
||||
|
||||
while(!isPositionValid(dataPoint)) {
|
||||
TRACE_INFO("BCN > Waiting for position data for beacon");
|
||||
chThdSleep(TIME_S2I(60));
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACE_INFO("BCN > Transmit position and telemetry");
|
||||
|
||||
// Encode/Transmit position packet
|
||||
packet_t packet = aprs_encode_position_and_telemetry(conf->digi.call,
|
||||
conf->digi.path,
|
||||
conf->digi.symbol,
|
||||
dataPoint, true);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("BCN > No free packet objects"
|
||||
" for position transmission");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->digi.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->digi.radio_conf.pwr,
|
||||
conf->digi.radio_conf.mod,
|
||||
conf->digi.radio_conf.cca)) {
|
||||
TRACE_ERROR("BCN > failed to transmit beacon data");
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
|
||||
TRACE_INFO("BCN > Transmit recently heard direct");
|
||||
/*
|
||||
* Encode/Transmit APRSD packet.
|
||||
* This is a tracker originated message (not a reply to a request).
|
||||
* The message will be addressed to the base station if set.
|
||||
* Else send it to device identity.
|
||||
*/
|
||||
char *call = conf_sram.aprs.base.enabled
|
||||
? conf_sram.aprs.base.call : conf->digi.call;
|
||||
|
||||
/*
|
||||
* Send message from this device.
|
||||
* Use call sign and path as specified in base config.
|
||||
* There is no acknowledgment requested.
|
||||
*/
|
||||
packet = aprs_compose_aprsd_message(
|
||||
conf->digi.call,
|
||||
conf->base.path,
|
||||
call);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("BCN > No free packet objects "
|
||||
"or badly formed APRSD message");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->digi.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->digi.radio_conf.pwr,
|
||||
conf->digi.radio_conf.mod,
|
||||
conf->digi.radio_conf.cca
|
||||
)) {
|
||||
TRACE_ERROR("BCN > Failed to transmit APRSD data");
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
} /* psleep */
|
||||
time = waitForTrigger(time, conf->digi.cycle);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void start_beacon_thread(thd_aprs_conf_t *conf) {
|
||||
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(10*1024),
|
||||
"BCN", LOWPRIO, bcnThread, conf);
|
||||
if(!th) {
|
||||
// Print startup error, do not start watchdog for this thread
|
||||
TRACE_ERROR("BCN > Could not start thread (not enough memory available)");
|
||||
}
|
||||
}
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "threads.h"
|
||||
#include "config.h"
|
||||
#include "radio.h"
|
||||
#include "aprs.h"
|
||||
#include "sleep.h"
|
||||
#include "chprintf.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "watchdog.h"
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
THD_FUNCTION(bcnThread, arg) {
|
||||
thd_aprs_conf_t* conf = (thd_aprs_conf_t *)arg;
|
||||
|
||||
// Wait
|
||||
if(conf->svc_conf.init_delay) chThdSleep(conf->svc_conf.init_delay);
|
||||
|
||||
// Start data collector (if not running yet)
|
||||
init_data_collector();
|
||||
|
||||
// Start position thread
|
||||
TRACE_INFO("BCN > Startup beacon thread");
|
||||
|
||||
// Set telemetry configuration transmission variables
|
||||
sysinterval_t last_conf_transmission =
|
||||
chVTGetSystemTime() - conf_sram.tel_enc_cycle;
|
||||
sysinterval_t time = chVTGetSystemTime();
|
||||
|
||||
/*
|
||||
* Already waited for APRS start delay.
|
||||
* Now wait for our further delay before starting.
|
||||
*/
|
||||
sysinterval_t delay = conf->digi.beacon.svc_conf.init_delay;
|
||||
|
||||
chThdSleep(delay);
|
||||
|
||||
while(true) {
|
||||
|
||||
char code_s[100];
|
||||
pktDisplayFrequencyCode(conf->digi.radio_conf.freq,
|
||||
code_s, sizeof(code_s));
|
||||
TRACE_INFO("POS > Do module BEACON cycle for %s on %s",
|
||||
conf->digi.call, code_s);
|
||||
#if USE_NEW_COLLECTOR == TRUE
|
||||
extern thread_t *collector_thd;
|
||||
/*
|
||||
* Pass pointer to beacon config to the collector thread.
|
||||
* TODO: return message should be pointer to latest updated datapoint?
|
||||
*/
|
||||
dataPoint_t * dataPoint =
|
||||
(dataPoint_t *)chMsgSend(collector_thd, (msg_t)&conf->digi.beacon);
|
||||
#else
|
||||
dataPoint_t* dataPoint = getLastDataPoint();
|
||||
#endif
|
||||
if(!p_sleep(&conf->svc_conf.sleep_conf)) {
|
||||
|
||||
// Telemetry encoding parameter transmissions
|
||||
if(conf_sram.tel_enc_cycle != 0 && last_conf_transmission
|
||||
+ conf_sram.tel_enc_cycle < chVTGetSystemTime()) {
|
||||
|
||||
TRACE_INFO("BCN > Transmit telemetry configuration");
|
||||
|
||||
// Encode and transmit telemetry config packet
|
||||
for(uint8_t type = 0; type < APRS_NUM_TELEM_GROUPS; type++) {
|
||||
packet_t packet = aprs_encode_telemetry_configuration(
|
||||
conf->digi.call,
|
||||
conf->digi.path,
|
||||
conf->digi.call,
|
||||
type);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("BCN > No free packet objects for"
|
||||
" telemetry config transmission");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->digi.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->digi.radio_conf.pwr,
|
||||
conf->digi.radio_conf.mod,
|
||||
conf->digi.radio_conf.cca)) {
|
||||
TRACE_ERROR("BCN > Failed to transmit telemetry config");
|
||||
}
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
last_conf_transmission += conf_sram.tel_enc_cycle;
|
||||
}
|
||||
|
||||
while(!isPositionValid(dataPoint)) {
|
||||
TRACE_INFO("BCN > Waiting for position data for beacon");
|
||||
chThdSleep(TIME_S2I(60));
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACE_INFO("BCN > Transmit position and telemetry");
|
||||
|
||||
// Encode/Transmit position packet
|
||||
packet_t packet = aprs_encode_position_and_telemetry(conf->digi.call,
|
||||
conf->digi.path,
|
||||
conf->digi.symbol,
|
||||
dataPoint, true);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("BCN > No free packet objects"
|
||||
" for position transmission");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->digi.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->digi.radio_conf.pwr,
|
||||
conf->digi.radio_conf.mod,
|
||||
conf->digi.radio_conf.cca)) {
|
||||
TRACE_ERROR("BCN > failed to transmit beacon data");
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
|
||||
TRACE_INFO("BCN > Transmit recently heard direct");
|
||||
/*
|
||||
* Encode/Transmit APRSD packet.
|
||||
* This is a tracker originated message (not a reply to a request).
|
||||
* The message will be addressed to the base station if set.
|
||||
* Else send it to device identity.
|
||||
*/
|
||||
char *call = conf_sram.base.enabled
|
||||
? conf_sram.base.call : conf->digi.call;
|
||||
|
||||
/*
|
||||
* Send message from this device.
|
||||
* Use call sign and path as specified in base config.
|
||||
* There is no acknowledgment requested.
|
||||
*/
|
||||
packet = aprs_compose_aprsd_message(
|
||||
conf_sram.aprs.digi.call,
|
||||
//conf->digi.call,
|
||||
conf_sram.base.path,
|
||||
//conf->base.path,
|
||||
call);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("BCN > No free packet objects "
|
||||
"or badly formed APRSD message");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->digi.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->digi.radio_conf.pwr,
|
||||
conf->digi.radio_conf.mod,
|
||||
conf->digi.radio_conf.cca
|
||||
)) {
|
||||
TRACE_ERROR("BCN > Failed to transmit APRSD data");
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
} /* psleep */
|
||||
time = waitForTrigger(time, conf->digi.beacon.svc_conf.cycle);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void start_beacon_thread(thd_aprs_conf_t *conf) {
|
||||
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(10*1024),
|
||||
"BCN", LOWPRIO, bcnThread, conf);
|
||||
if(!th) {
|
||||
// Print startup error, do not start watchdog for this thread
|
||||
TRACE_ERROR("BCN > Could not start thread (not enough memory available)");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -1,89 +1,89 @@
|
|||
/**
|
||||
* Logging module
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "threads.h"
|
||||
#include "base91.h"
|
||||
#include "aprs.h"
|
||||
#include "sleep.h"
|
||||
#include "radio.h"
|
||||
#include "log.h"
|
||||
#include "pflash.h"
|
||||
|
||||
static uint16_t log_id = 0;
|
||||
|
||||
static dataPoint_t* getNextLogDataPoint(uint8_t density)
|
||||
{
|
||||
// Determine sector
|
||||
dataPoint_t *tp;
|
||||
uint32_t i = 0;
|
||||
do {
|
||||
if((tp = flash_getLogBuffer(log_id))) {
|
||||
log_id += density;
|
||||
} else {
|
||||
log_id = 0;
|
||||
tp = flash_getLogBuffer(0);
|
||||
}
|
||||
} while(LOG_IS_EMPTY(tp) && i++ < LOG_FLASH_SIZE / sizeof(dataPoint_t));
|
||||
|
||||
return LOG_IS_EMPTY(tp) ? NULL : tp;
|
||||
}
|
||||
|
||||
THD_FUNCTION(logThread, arg)
|
||||
{
|
||||
thd_log_conf_t* conf = (thd_log_conf_t*)arg;
|
||||
|
||||
if(conf->thread_conf.init_delay) chThdSleep(conf->thread_conf.init_delay);
|
||||
TRACE_INFO("LOG > Startup logging thread");
|
||||
|
||||
sysinterval_t time = chVTGetSystemTime();
|
||||
while(true)
|
||||
{
|
||||
TRACE_INFO("LOG > Do module LOG cycle");
|
||||
|
||||
if(!p_sleep(&conf->thread_conf.sleep_conf))
|
||||
{
|
||||
// Get log from memory
|
||||
dataPoint_t *log = getNextLogDataPoint(conf->density);
|
||||
|
||||
if(log) {
|
||||
// Encode Base91
|
||||
uint8_t pkt_base91[BASE91LEN(sizeof(dataPoint_t))];
|
||||
base91_encode((uint8_t*)log, pkt_base91, sizeof(dataPoint_t));
|
||||
// Encode and transmit log packet
|
||||
packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'L', pkt_base91); // Encode packet
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("LOG > No free packet objects for log transmission");
|
||||
} else {
|
||||
// Transmit packet
|
||||
transmitOnRadio(packet,
|
||||
conf->radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->radio_conf.pwr,
|
||||
conf->radio_conf.mod,
|
||||
conf->radio_conf.cca);
|
||||
}
|
||||
} else {
|
||||
TRACE_INFO("LOG > No log point in memory");
|
||||
}
|
||||
}
|
||||
|
||||
time = waitForTrigger(time, conf->thread_conf.cycle);
|
||||
}
|
||||
}
|
||||
|
||||
void start_logging_thread(thd_log_conf_t *conf)
|
||||
{
|
||||
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(6*1024), "LOG", LOWPRIO, logThread, conf);
|
||||
if(!th) {
|
||||
// Print startup error, do not start watchdog for this thread
|
||||
TRACE_ERROR("LOG > Could not startup thread (not enough memory available)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logging module
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "threads.h"
|
||||
#include "base91.h"
|
||||
#include "aprs.h"
|
||||
#include "sleep.h"
|
||||
#include "radio.h"
|
||||
#include "log.h"
|
||||
#include "pflash.h"
|
||||
|
||||
static uint16_t log_id = 0;
|
||||
|
||||
static dataPoint_t* getNextLogDataPoint(uint8_t density)
|
||||
{
|
||||
// Determine sector
|
||||
dataPoint_t *tp;
|
||||
uint32_t i = 0;
|
||||
do {
|
||||
if((tp = flash_getLogBuffer(log_id))) {
|
||||
log_id += density;
|
||||
} else {
|
||||
log_id = 0;
|
||||
tp = flash_getLogBuffer(0);
|
||||
}
|
||||
} while(LOG_IS_EMPTY(tp) && i++ < LOG_FLASH_SIZE / sizeof(dataPoint_t));
|
||||
|
||||
return LOG_IS_EMPTY(tp) ? NULL : tp;
|
||||
}
|
||||
|
||||
THD_FUNCTION(logThread, arg)
|
||||
{
|
||||
thd_log_conf_t* conf = (thd_log_conf_t*)arg;
|
||||
|
||||
if(conf->svc_conf.init_delay) chThdSleep(conf->svc_conf.init_delay);
|
||||
TRACE_INFO("LOG > Startup logging thread");
|
||||
|
||||
sysinterval_t time = chVTGetSystemTime();
|
||||
while(true)
|
||||
{
|
||||
TRACE_INFO("LOG > Do module LOG cycle");
|
||||
|
||||
if(!p_sleep(&conf->svc_conf.sleep_conf))
|
||||
{
|
||||
// Get log from memory
|
||||
dataPoint_t *log = getNextLogDataPoint(conf->density);
|
||||
|
||||
if(log) {
|
||||
// Encode Base91
|
||||
uint8_t pkt_base91[BASE91LEN(sizeof(dataPoint_t))];
|
||||
base91_encode((uint8_t*)log, pkt_base91, sizeof(dataPoint_t));
|
||||
// Encode and transmit log packet
|
||||
packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'L', pkt_base91); // Encode packet
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("LOG > No free packet objects for log transmission");
|
||||
} else {
|
||||
// Transmit packet
|
||||
transmitOnRadio(packet,
|
||||
conf->radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->radio_conf.pwr,
|
||||
conf->radio_conf.mod,
|
||||
conf->radio_conf.cca);
|
||||
}
|
||||
} else {
|
||||
TRACE_INFO("LOG > No log point in memory");
|
||||
}
|
||||
}
|
||||
|
||||
time = waitForTrigger(time, conf->svc_conf.cycle);
|
||||
}
|
||||
}
|
||||
|
||||
void start_logging_thread(thd_log_conf_t *conf)
|
||||
{
|
||||
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(6*1024), "LOG", LOWPRIO, logThread, conf);
|
||||
if(!th) {
|
||||
// Print startup error, do not start watchdog for this thread
|
||||
TRACE_ERROR("LOG > Could not startup thread (not enough memory available)");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,153 +1,153 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "threads.h"
|
||||
#include "config.h"
|
||||
#include "radio.h"
|
||||
#include "aprs.h"
|
||||
#include "sleep.h"
|
||||
#include "chprintf.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "watchdog.h"
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
THD_FUNCTION(posThread, arg)
|
||||
{
|
||||
thd_pos_conf_t* conf = (thd_pos_conf_t*)arg;
|
||||
|
||||
// Wait
|
||||
if(conf->thread_conf.init_delay) chThdSleep(conf->thread_conf.init_delay);
|
||||
|
||||
// Start data collector (if not running yet)
|
||||
init_data_collector();
|
||||
|
||||
// Start position thread
|
||||
TRACE_INFO("POS > Startup position thread");
|
||||
|
||||
// Set telemetry configuration transmission variables
|
||||
sysinterval_t last_conf_transmission =
|
||||
chVTGetSystemTime() - conf->tel_enc_cycle;
|
||||
sysinterval_t time = chVTGetSystemTime();
|
||||
|
||||
while(true) {
|
||||
char code_s[100];
|
||||
pktDisplayFrequencyCode(conf->radio_conf.freq,
|
||||
code_s, sizeof(code_s));
|
||||
TRACE_INFO("POS > Do module POSITION cycle for %s on %s",
|
||||
conf->call, code_s);
|
||||
|
||||
TRACE_INFO("POS > Get last data point");
|
||||
dataPoint_t* dataPoint = getLastDataPoint();
|
||||
|
||||
if(!p_sleep(&conf->thread_conf.sleep_conf)) {
|
||||
TRACE_INFO("POS > Transmit position");
|
||||
|
||||
// Telemetry encoding parameter transmission
|
||||
if(conf->tel_enc_cycle != 0 && last_conf_transmission
|
||||
+ conf->tel_enc_cycle < chVTGetSystemTime()) {
|
||||
|
||||
TRACE_INFO("POS > Transmit telemetry configuration");
|
||||
|
||||
// Encode and transmit telemetry config packet
|
||||
for(uint8_t type = 0; type < APRS_NUM_TELEM_GROUPS; type++) {
|
||||
packet_t packet = aprs_encode_telemetry_configuration(
|
||||
conf->call,
|
||||
conf->path,
|
||||
conf->call,
|
||||
type);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("POS > No free packet objects for"
|
||||
" telemetry transmission");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->radio_conf.pwr,
|
||||
conf->radio_conf.mod,
|
||||
conf->radio_conf.cca)) {
|
||||
TRACE_ERROR("POS > Failed to transmit telemetry data");
|
||||
}
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
|
||||
last_conf_transmission += conf->tel_enc_cycle;
|
||||
}
|
||||
// Encode/Transmit position packet
|
||||
packet_t packet = aprs_encode_position_and_telemetry(conf->call,
|
||||
conf->path,
|
||||
conf->symbol,
|
||||
dataPoint,
|
||||
true);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("POS > No free packet objects"
|
||||
" for position transmission");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->radio_conf.pwr,
|
||||
conf->radio_conf.mod,
|
||||
conf->radio_conf.cca)) {
|
||||
TRACE_ERROR("POS > failed to transmit position data");
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode/Transmit APRSD packet.
|
||||
* This is a tracker originated message (not a reply to a request).
|
||||
* The message will be sent to the base station if set.
|
||||
* Else send it to device identity.
|
||||
*/
|
||||
char *call = conf_sram.aprs.base.enabled
|
||||
? conf_sram.aprs.base.call : conf->call;
|
||||
/*
|
||||
* Send message from this device.
|
||||
* Use call sign and path as specified in base config.
|
||||
* There is no acknowledgment requested.
|
||||
*/
|
||||
packet = aprs_compose_aprsd_message(
|
||||
conf->call,
|
||||
conf->path,
|
||||
call);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("POS > No free packet objects "
|
||||
"or badly formed APRSD message");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->radio_conf.pwr,
|
||||
conf->radio_conf.mod,
|
||||
conf->radio_conf.cca
|
||||
)) {
|
||||
TRACE_ERROR("POS > Failed to transmit APRSD data");
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
}
|
||||
time = waitForTrigger(time, conf->thread_conf.cycle);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void start_position_thread(thd_pos_conf_t *conf)
|
||||
{
|
||||
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(10*1024),
|
||||
"POS", LOWPRIO, posThread, conf);
|
||||
if(!th) {
|
||||
// Print startup error, do not start watchdog for this thread
|
||||
TRACE_ERROR("POS > Could not startup thread (not enough memory available)");
|
||||
}
|
||||
}
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "threads.h"
|
||||
#include "config.h"
|
||||
#include "radio.h"
|
||||
#include "aprs.h"
|
||||
#include "sleep.h"
|
||||
#include "chprintf.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "watchdog.h"
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
THD_FUNCTION(posThread, arg)
|
||||
{
|
||||
thd_pos_conf_t* conf = (thd_pos_conf_t*)arg;
|
||||
|
||||
// Wait
|
||||
if(conf->svc_conf.init_delay) chThdSleep(conf->svc_conf.init_delay);
|
||||
|
||||
// Start data collector (if not running yet)
|
||||
init_data_collector();
|
||||
|
||||
// Start position thread
|
||||
TRACE_INFO("POS > Startup position thread");
|
||||
|
||||
// Set telemetry configuration transmission variables
|
||||
sysinterval_t last_conf_transmission =
|
||||
chVTGetSystemTime() - conf_sram.tel_enc_cycle;
|
||||
sysinterval_t time = chVTGetSystemTime();
|
||||
|
||||
while(true) {
|
||||
char code_s[100];
|
||||
pktDisplayFrequencyCode(conf->radio_conf.freq,
|
||||
code_s, sizeof(code_s));
|
||||
TRACE_INFO("POS > Do module POSITION cycle for %s on %s",
|
||||
conf->call, code_s);
|
||||
|
||||
TRACE_INFO("POS > Get last data point");
|
||||
dataPoint_t* dataPoint = getLastDataPoint();
|
||||
|
||||
if(!p_sleep(&conf->svc_conf.sleep_conf)) {
|
||||
TRACE_INFO("POS > Transmit position");
|
||||
|
||||
// Telemetry encoding parameter transmission
|
||||
if(conf_sram.tel_enc_cycle != 0 && last_conf_transmission
|
||||
+ conf_sram.tel_enc_cycle < chVTGetSystemTime()) {
|
||||
|
||||
TRACE_INFO("POS > Transmit telemetry configuration");
|
||||
|
||||
// Encode and transmit telemetry config packet
|
||||
for(uint8_t type = 0; type < APRS_NUM_TELEM_GROUPS; type++) {
|
||||
packet_t packet = aprs_encode_telemetry_configuration(
|
||||
conf->call,
|
||||
conf->path,
|
||||
conf->call,
|
||||
type);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("POS > No free packet objects for"
|
||||
" telemetry transmission");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->radio_conf.pwr,
|
||||
conf->radio_conf.mod,
|
||||
conf->radio_conf.cca)) {
|
||||
TRACE_ERROR("POS > Failed to transmit telemetry data");
|
||||
}
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
|
||||
last_conf_transmission += conf_sram.tel_enc_cycle;
|
||||
}
|
||||
// Encode/Transmit position packet
|
||||
packet_t packet = aprs_encode_position_and_telemetry(conf->call,
|
||||
conf->path,
|
||||
conf->symbol,
|
||||
dataPoint,
|
||||
true);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("POS > No free packet objects"
|
||||
" for position transmission");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->radio_conf.pwr,
|
||||
conf->radio_conf.mod,
|
||||
conf->radio_conf.cca)) {
|
||||
TRACE_ERROR("POS > failed to transmit position data");
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode/Transmit APRSD packet.
|
||||
* This is a tracker originated message (not a reply to a request).
|
||||
* The message will be sent to the base station if set.
|
||||
* Else send it to device identity.
|
||||
*/
|
||||
char *call = conf_sram.base.enabled
|
||||
? conf_sram.base.call : conf->call;
|
||||
/*
|
||||
* Send message from this device.
|
||||
* Use call sign and path as specified in base config.
|
||||
* There is no acknowledgment requested.
|
||||
*/
|
||||
packet = aprs_compose_aprsd_message(
|
||||
conf->call,
|
||||
conf->path,
|
||||
call);
|
||||
if(packet == NULL) {
|
||||
TRACE_WARN("POS > No free packet objects "
|
||||
"or badly formed APRSD message");
|
||||
} else {
|
||||
if(!transmitOnRadio(packet,
|
||||
conf->radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf->radio_conf.pwr,
|
||||
conf->radio_conf.mod,
|
||||
conf->radio_conf.cca
|
||||
)) {
|
||||
TRACE_ERROR("POS > Failed to transmit APRSD data");
|
||||
}
|
||||
chThdSleep(TIME_S2I(5));
|
||||
}
|
||||
}
|
||||
time = waitForTrigger(time, conf->svc_conf.cycle);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void start_position_thread(thd_pos_conf_t *conf)
|
||||
{
|
||||
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(10*1024),
|
||||
"POS", LOWPRIO, posThread, conf);
|
||||
if(!th) {
|
||||
// Print startup error, do not start watchdog for this thread
|
||||
TRACE_ERROR("POS > Could not startup thread (not enough memory available)");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,64 +1,71 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "watchdog.h"
|
||||
#include "pi2c.h"
|
||||
#include "pac1720.h"
|
||||
#include "radio.h"
|
||||
#include "si446x.h"
|
||||
#include "image.h"
|
||||
#include "position.h"
|
||||
#include "beacon.h"
|
||||
#include "log.h"
|
||||
#include "radio.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "flash.h"
|
||||
|
||||
sysinterval_t watchdog_tracking;
|
||||
|
||||
void start_essential_threads(void)
|
||||
{
|
||||
init_watchdog(); // Init watchdog
|
||||
pac1720_init(); // Initialize current measurement
|
||||
chThdSleep(TIME_MS2I(300)); // Wait for tracking manager to initialize
|
||||
}
|
||||
|
||||
void start_user_threads(void)
|
||||
{
|
||||
conf_t *conf_flash = (conf_t*)0x08060000;
|
||||
/* Check if a user update has been made to configuration in flash. */
|
||||
if(conf_flash->magic != CONFIG_MAGIC_UPDATED) {
|
||||
if(conf_flash->magic != CONFIG_MAGIC_DEFAULT
|
||||
|| memcmp(&conf_flash, &conf_flash_default, sizeof(conf_t)) != 0) {
|
||||
/* No configuration found in flash memory or default config has changed. */
|
||||
flashSectorBegin(flashSectorAt((uint32_t)conf_flash));
|
||||
flashErase((uint32_t)conf_flash, 0x20000);
|
||||
flashWrite((uint32_t)conf_flash, (char*)&conf_flash_default, sizeof(conf_t));
|
||||
flashSectorEnd(flashSectorAt((uint32_t)conf_flash));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy
|
||||
memcpy(&conf_sram, conf_flash, sizeof(conf_t));
|
||||
|
||||
if(conf_sram.pos_pri.thread_conf.active) start_position_thread(&conf_sram.pos_pri);
|
||||
if(conf_sram.pos_sec.thread_conf.active) start_position_thread(&conf_sram.pos_sec);
|
||||
|
||||
if(conf_sram.img_pri.thread_conf.active) start_image_thread(&conf_sram.img_pri);
|
||||
if(conf_sram.img_sec.thread_conf.active) start_image_thread(&conf_sram.img_sec);
|
||||
|
||||
if(conf_sram.log.thread_conf.active) start_logging_thread(&conf_sram.log);
|
||||
|
||||
if(conf_sram.aprs.thread_conf.active && conf_sram.aprs.digi.beacon)
|
||||
start_beacon_thread(&conf_sram.aprs);
|
||||
|
||||
if(conf_sram.aprs.thread_conf.active) {
|
||||
chThdSleep(conf_sram.aprs.thread_conf.init_delay);
|
||||
start_aprs_threads(PKT_RADIO_1,
|
||||
conf_sram.aprs.rx.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf_sram.aprs.rx.radio_conf.rssi);
|
||||
}
|
||||
}
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "watchdog.h"
|
||||
#include "pi2c.h"
|
||||
#include "pac1720.h"
|
||||
#include "radio.h"
|
||||
#include "si446x.h"
|
||||
#include "image.h"
|
||||
#include "position.h"
|
||||
#include "beacon.h"
|
||||
#include "log.h"
|
||||
#include "radio.h"
|
||||
#include "ax25_pad.h"
|
||||
#include "flash.h"
|
||||
|
||||
sysinterval_t watchdog_tracking;
|
||||
|
||||
void start_essential_threads(void)
|
||||
{
|
||||
init_watchdog(); // Init watchdog
|
||||
pac1720_init(); // Initialize current measurement
|
||||
chThdSleep(TIME_MS2I(300)); // Wait for tracking manager to initialize
|
||||
}
|
||||
|
||||
void start_user_threads(void)
|
||||
{
|
||||
conf_t *conf_flash = (conf_t*)0x08060000;
|
||||
/* Check if a user update has been made to configuration in flash. */
|
||||
if(conf_flash->magic != CONFIG_MAGIC_UPDATED) {
|
||||
if(conf_flash->magic != CONFIG_MAGIC_DEFAULT
|
||||
|| memcmp(&conf_flash, &conf_flash_default, sizeof(conf_t)) != 0) {
|
||||
/* No configuration found in flash memory or default config has changed. */
|
||||
flashSectorBegin(flashSectorAt((uint32_t)conf_flash));
|
||||
flashErase((uint32_t)conf_flash, 0x20000);
|
||||
flashWrite((uint32_t)conf_flash, (char*)&conf_flash_default, sizeof(conf_t));
|
||||
flashSectorEnd(flashSectorAt((uint32_t)conf_flash));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy
|
||||
memcpy(&conf_sram, conf_flash, sizeof(conf_t));
|
||||
|
||||
if(conf_sram.pos_pri.svc_conf.active)
|
||||
start_position_thread(&conf_sram.pos_pri);
|
||||
if(conf_sram.pos_sec.svc_conf.active)
|
||||
start_position_thread(&conf_sram.pos_sec);
|
||||
|
||||
if(conf_sram.img_pri.svc_conf.active)
|
||||
start_image_thread(&conf_sram.img_pri);
|
||||
if(conf_sram.img_sec.svc_conf.active)
|
||||
start_image_thread(&conf_sram.img_sec);
|
||||
|
||||
if(conf_sram.log.svc_conf.active)
|
||||
start_logging_thread(&conf_sram.log);
|
||||
|
||||
if(conf_sram.aprs.svc_conf.active
|
||||
&& conf_sram.aprs.digi.beacon.svc_conf.active) {
|
||||
start_beacon_thread(&conf_sram.aprs);
|
||||
}
|
||||
|
||||
if(conf_sram.aprs.svc_conf.active) {
|
||||
chThdSleep(conf_sram.aprs.svc_conf.init_delay);
|
||||
start_aprs_threads(PKT_RADIO_1,
|
||||
conf_sram.aprs.rx.radio_conf.freq,
|
||||
0,
|
||||
0,
|
||||
conf_sram.aprs.rx.radio_conf.rssi);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue