kopia lustrzana https://github.com/bristol-seds/pico-tracker
SE880 running. Cycles between standby and gps running
rodzic
aa3e48174c
commit
8b6e706a6a
|
@ -42,6 +42,7 @@ typedef struct tracker_datapoint {
|
|||
int32_t longitude; /* 100 nanodeg */
|
||||
int32_t altitude; /* mm */
|
||||
uint8_t satillite_count; /* */
|
||||
uint8_t time_to_first_fix; /* seconds / counts */
|
||||
|
||||
/* Sensors */
|
||||
float battery; /* Volts */
|
||||
|
|
|
@ -35,7 +35,14 @@ enum gps_error_t {
|
|||
GPS_NOERROR,
|
||||
GPS_ERROR_BAD_CHECKSUM,
|
||||
GPS_ERROR_INVALID_FRAME,
|
||||
};
|
||||
|
||||
/**
|
||||
* GPS Flight State
|
||||
*/
|
||||
enum gps_flight_state_t {
|
||||
GPS_FLIGHT_STATE_LAUNCH,
|
||||
GPS_FLIGHT_STATE_FLOAT,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -46,6 +53,7 @@ struct gps_data_t {
|
|||
int32_t altitude; /* mm */
|
||||
uint8_t satillite_count;
|
||||
uint8_t is_locked; /* 1 = locked, 0 = not locked */
|
||||
uint8_t time_to_first_fix; /* seconds / counts */
|
||||
};
|
||||
|
||||
/* UBX ------------------------------------------------------------- */
|
||||
|
@ -84,14 +92,15 @@ struct gps_data_t gps_get_data(void);
|
|||
|
||||
static uint8_t gps_is_locked(void){return 0;}
|
||||
|
||||
static void gps_set_power_state(bool gnss_running){}
|
||||
|
||||
void gps_service(void);
|
||||
void gps_setup(void);
|
||||
|
||||
#endif /* GPS_TYPE_OSP */
|
||||
|
||||
|
||||
/* Both ------------------------------------------------------------ */
|
||||
enum gps_flight_state_t gps_get_flight_state(void);
|
||||
|
||||
void gps_usart_init_enable(uint32_t baud_rate);
|
||||
void gps_reset(void);
|
||||
void gps_init(void);
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
#define GPS_SERCOM_MIGO_PIN PIN_PA07
|
||||
#define GPS_SERCOM_MIGO_PINMUX PINMUX_PA07D_SERCOM0_PAD3
|
||||
#define GPS_SERCOM_MUX USART_RX_3_TX_2_XCK_3
|
||||
#define GPS_GCLK GCLK_GENERATOR_1
|
||||
#define GPS_GCLK GCLK_GENERATOR_0
|
||||
|
||||
#ifdef V0986
|
||||
#define GPS_TYPE_OSP
|
||||
|
@ -95,6 +95,8 @@
|
|||
|
||||
#endif
|
||||
|
||||
#define GPS_FLIGHT_STATE_THREASHOLD_M 1000
|
||||
|
||||
|
||||
/**
|
||||
* USART Loopback Testing
|
||||
|
|
|
@ -45,6 +45,10 @@ typedef struct {
|
|||
uint16_t max_payload_size;
|
||||
} osp_message_t;
|
||||
|
||||
/** Function typedef for post-processing functions */
|
||||
typedef void (*osp_post_func)(osp_message_t* const);
|
||||
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* OSP Input Messages =======================================================
|
||||
|
@ -55,8 +59,8 @@ typedef struct {
|
|||
/**
|
||||
* 5.3 OSP Advanced Power Management
|
||||
*/
|
||||
#define OSP_IN_ADVANCED_POWER_MEASUREMENT_ID 53
|
||||
struct osp_in_advanced_power_measurement {
|
||||
#define OSP_IN_ADVANCED_POWER_MANAGEMENT_ID 53
|
||||
struct osp_in_advanced_power_management {
|
||||
osp_message_id_t id;
|
||||
enum osp_packet_state state;
|
||||
uint16_t max_payload_size;
|
||||
|
@ -65,8 +69,8 @@ struct osp_in_advanced_power_measurement {
|
|||
uint8_t number_fixes_apm_cycles;
|
||||
uint8_t time_between_fixes; /* s */
|
||||
uint8_t spare1;
|
||||
uint8_t maximum_horizontal_error; /* enum osp_apm_max_error_t */
|
||||
uint8_t maximum_vertical_error; /* enum osp_apm_max_error_t */
|
||||
uint8_t maximum_horizontal_error; /* enum osp_max_error_t */
|
||||
uint8_t maximum_vertical_error; /* enum osp_max_error_t */
|
||||
uint8_t maximum_response_time;
|
||||
uint8_t time_acc_priority;
|
||||
uint8_t power_duty_cycle; /* duty cycle x 0.2 */
|
||||
|
@ -74,15 +78,19 @@ struct osp_in_advanced_power_measurement {
|
|||
uint8_t spare2;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
enum osp_apm_max_error_t {
|
||||
OSP_APM_MAX_ERROR_1_METER = 0,
|
||||
OSP_APM_MAX_ERROR_5_METER,
|
||||
OSP_APM_MAX_ERROR_10_METER,
|
||||
OSP_APM_MAX_ERROR_20_METER,
|
||||
OSP_APM_MAX_ERROR_40_METER,
|
||||
OSP_APM_MAX_ERROR_80_METER,
|
||||
OSP_APM_MAX_ERROR_160_METER,
|
||||
OSP_APM_MAX_ERROR_NO_MAX,
|
||||
static void osp_in_advanced_power_management_pre(struct osp_in_advanced_power_management* m)
|
||||
{
|
||||
(void)m;
|
||||
}
|
||||
enum osp_max_error_t {
|
||||
OSP_MAX_ERROR_1_METER = 0,
|
||||
OSP_MAX_ERROR_5_METER,
|
||||
OSP_MAX_ERROR_10_METER,
|
||||
OSP_MAX_ERROR_20_METER,
|
||||
OSP_MAX_ERROR_40_METER,
|
||||
OSP_MAX_ERROR_80_METER,
|
||||
OSP_MAX_ERROR_160_METER,
|
||||
OSP_MAX_ERROR_NO_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -104,7 +112,15 @@ enum osp_apm_max_error_t {
|
|||
uint8_t reset_config_bitmap;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
|
||||
static void osp_in_initialise_data_source_pre(struct osp_in_initialise_data_source* m)
|
||||
{
|
||||
m->payload.x_position = __REV(m->payload.x_position);
|
||||
m->payload.y_position = __REV(m->payload.y_position);
|
||||
m->payload.z_position = __REV(m->payload.z_position);
|
||||
m->payload.clock_drift = __REV(m->payload.clock_drift);
|
||||
m->payload.gps_tow = __REV(m->payload.gps_tow);
|
||||
m->payload.gps_week_number = __REV16(m->payload.gps_week_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 5.13 Mode Control
|
||||
|
@ -128,6 +144,11 @@ enum osp_apm_max_error_t {
|
|||
uint8_t measurement_and_track_smoothing;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_mode_control_pre(struct osp_in_mode_control* m)
|
||||
{
|
||||
m->payload.res1 = __REV16(m->payload.res1);
|
||||
m->payload.altitude = __REV16(m->payload.altitude);
|
||||
}
|
||||
enum osp_degraded_mode { /* MUST set DO_NOT_ALLOW for GSW3.2.5 and later */
|
||||
OSP_DEGRADED_ALLOW_1SV_FREEZE_DIRECTION = 0,
|
||||
OSP_DEGRADED_ALLOW_1SV_FREEZE_CLOCK_DRIFT,
|
||||
|
@ -154,6 +175,11 @@ enum osp_altitude_hold_mode {
|
|||
int16_t navigation_mask; /* deg */
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_elevation_mask_pre(struct osp_in_elevation_mask* m)
|
||||
{
|
||||
m->payload.tracking_mask = __REV16(m->payload.tracking_mask);
|
||||
m->payload.navigation_mask = __REV16(m->payload.navigation_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* 5.17 OSP Power Mask
|
||||
|
@ -168,6 +194,10 @@ enum osp_altitude_hold_mode {
|
|||
uint8_t navigation_mask; /* dBHz */
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_power_mask_pre(struct osp_in_power_mask* m)
|
||||
{
|
||||
(void)m;
|
||||
}
|
||||
|
||||
/**
|
||||
* 5.26 OSP Set TricklePower Parameters
|
||||
|
@ -183,6 +213,12 @@ struct osp_in_set_tricklepower_parameters {
|
|||
int32_t on_time; /* ms */
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_set_tricklepower_parameters_pre(struct osp_in_set_tricklepower_parameters* m)
|
||||
{
|
||||
m->payload.pushtofix_mode = __REV16(m->payload.pushtofix_mode);
|
||||
m->payload.duty_cycle = __REV16(m->payload.duty_cycle);
|
||||
m->payload.on_time = __REV(m->payload.on_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 5.30 OSP Set Message Rate
|
||||
|
@ -202,6 +238,10 @@ struct osp_in_set_tricklepower_parameters {
|
|||
uint8_t res4;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_set_message_rate_pre(struct osp_in_set_message_rate m)
|
||||
{
|
||||
(void)m;
|
||||
}
|
||||
enum osp_message_rate {
|
||||
OSP_SET_MESSAGE_RATE_ONE = 0,
|
||||
OSP_SET_MESSAGE_RATE_POLL_ONE,
|
||||
|
@ -225,6 +265,51 @@ enum osp_message_rate {
|
|||
uint16_t adaptive_tricklepower;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_set_low_power_acquisition_parameters_pre(struct osp_in_set_low_power_acquisition_parameters* m)
|
||||
{
|
||||
m->payload.max_off_time = __REV(m->payload.max_off_time);
|
||||
m->payload.max_search_time = __REV(m->payload.max_search_time);
|
||||
m->payload.pushtofix_period = __REV(m->payload.pushtofix_period);
|
||||
m->payload.adaptive_tricklepower = __REV16(m->payload.adaptive_tricklepower);
|
||||
}
|
||||
|
||||
/**
|
||||
* 5.47 OSP Position Request
|
||||
*/
|
||||
#define OSP_IN_POSITION_REQUEST_ID 210
|
||||
struct osp_in_position_request {
|
||||
osp_message_id_t id;
|
||||
enum osp_packet_state state;
|
||||
uint16_t max_payload_size;
|
||||
struct {
|
||||
uint8_t pos_request_id;
|
||||
uint8_t num_fixes;
|
||||
uint8_t time_between_fixes; /* s */
|
||||
uint8_t horizontal_error_max; /* m */
|
||||
uint8_t vertical_error_max; /* enum osp_max_error_t */
|
||||
uint8_t response_time_max; /* s */
|
||||
uint8_t time_acc_priority; /* enum osp_time_acc_priority */
|
||||
uint8_t location_method; /* enum osp_location_method */
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_position_request_pre(struct osp_in_position_request* m)
|
||||
{
|
||||
(void)m;
|
||||
}
|
||||
enum osp_time_acc_priority {
|
||||
OSP_TIME_ACC_PRIORITY_NONE = 0,
|
||||
OSP_TIME_ACC_PRIORITY_TIME = 1,
|
||||
OSP_TIME_ACC_PRIORITY_ACCURACY = 2,
|
||||
OSP_TIME_ACC_PRIORITY_USE_FULL_TIME = 3
|
||||
};
|
||||
enum osp_location_method {
|
||||
OSP_LOCATION_METHOD_MS_ASSISTED = 0,
|
||||
OSP_LOCATION_METHOD_MS_BASED = 1,
|
||||
OSP_LOCATION_METHOD_MS_BASED_ALLOW_ASSISTED = 2,
|
||||
OSP_LOCATION_METHOD_MS_ASSISTED_ALLOW_BASED = 3,
|
||||
OSP_LOCATION_METHOD_SIMULTANEOUS = 4,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 5.65 OSP Session Request
|
||||
|
@ -239,6 +324,10 @@ enum osp_message_rate {
|
|||
uint8_t info;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_session_request_pre(struct osp_in_session_request* m)
|
||||
{
|
||||
(void)m;
|
||||
}
|
||||
enum osp_session_request {
|
||||
OSP_SESSION_REQUEST_OPEN = 1,
|
||||
OSP_SESSION_REQUEST_CLOSE = 2,
|
||||
|
@ -259,6 +348,10 @@ struct osp_in_hardware_configuration_response {
|
|||
uint8_t network_enhancement_type;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_hardware_configuration_response_pre(struct osp_in_hardware_configuration_response* m)
|
||||
{
|
||||
m->payload.nominal_frequency_low = __REV(m->payload.nominal_frequency_low);
|
||||
}
|
||||
enum osp_hw_config {
|
||||
OSP_HW_CONFIG_PRECISE_TIME_TRANSFER_NO = (0<<0),
|
||||
OSP_HW_CONFIG_PRECISE_TIME_TRANSFER_YES = (1<<0),
|
||||
|
@ -297,7 +390,35 @@ struct osp_in_approximate_ms_position_response {
|
|||
uint8_t use_alt_aiding;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_in_approximate_ms_position_response_pre(struct osp_in_approximate_ms_position_response* m)
|
||||
{
|
||||
m->payload.lat = __REV(m->payload.lat);
|
||||
m->payload.lon = __REV(m->payload.lon);
|
||||
m->payload.alt = __REV16(m->payload.alt);
|
||||
m->payload.est_ver_er = __REV16(m->payload.est_ver_er);
|
||||
}
|
||||
|
||||
/**
|
||||
* 5.74 OSP Reject
|
||||
*/
|
||||
#define OSP_IN_REJECT_ID 216
|
||||
struct osp_in_reject {
|
||||
osp_message_id_t id;
|
||||
enum osp_packet_state state;
|
||||
uint16_t max_payload_size;
|
||||
struct {
|
||||
uint8_t sub_id;
|
||||
uint8_t rejected_message_id;
|
||||
uint8_t rejected_message_sub_id;
|
||||
uint8_t rejected_message_reason; /* enum osp_rejected_message_reason */
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
enum osp_rejected_message_reason {
|
||||
OSP_REJECTED_MESSAGE_NOT_READY = (1<<1),
|
||||
OSP_REJECTED_MESSAGE_NOT_AVAILABLE = (1<<2),
|
||||
OSP_REJECTED_MESSAGE_BAD_FORMATTING = (1<<3),
|
||||
OSP_REJECTED_MESSAGE_NO_TIME_PULSE = (1<<4),
|
||||
};
|
||||
|
||||
/**
|
||||
* 5.76 OSP Power Mode Request
|
||||
|
@ -364,6 +485,19 @@ struct osp_in_approximate_ms_position_response {
|
|||
uint8_t ch12_prn;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_measure_navigation_data_out_post(osp_message_t* o)
|
||||
{
|
||||
struct osp_out_measure_navigation_data_out* m = (struct osp_out_measure_navigation_data_out*)o;
|
||||
|
||||
m->payload.x_position = __REV(m->payload.x_position);
|
||||
m->payload.y_position = __REV(m->payload.y_position);
|
||||
m->payload.z_position = __REV(m->payload.z_position);
|
||||
m->payload.x_velocity = __REV16(m->payload.x_velocity);
|
||||
m->payload.y_velocity = __REV16(m->payload.y_velocity);
|
||||
m->payload.z_velocity = __REV16(m->payload.z_velocity);
|
||||
m->payload.gps_week = __REV16(m->payload.gps_week);
|
||||
m->payload.gps_tow = __REV(m->payload.gps_tow);
|
||||
}
|
||||
|
||||
/**
|
||||
* 6.7 OSP Clock Status Data
|
||||
|
@ -382,6 +516,16 @@ struct osp_in_approximate_ms_position_response {
|
|||
uint32_t extimated_gps_time; /* ms */
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_clock_status_data_post(osp_message_t* o)
|
||||
{
|
||||
struct osp_out_clock_status_data* m = (struct osp_out_clock_status_data*)o;
|
||||
|
||||
m->payload.extended_gps_week = __REV16(m->payload.extended_gps_week);
|
||||
m->payload.gps_tow = __REV(m->payload.gps_tow);
|
||||
m->payload.clock_drift = __REV(m->payload.clock_drift);
|
||||
m->payload.clock_bias = __REV(m->payload.clock_bias);
|
||||
m->payload.extimated_gps_time = __REV(m->payload.extimated_gps_time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 6.15 OSP Ephemeris Data
|
||||
|
@ -396,6 +540,14 @@ struct osp_in_approximate_ms_position_response {
|
|||
uint16_t data[45];
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_ephemeris_data_post(osp_message_t* o)
|
||||
{
|
||||
struct osp_out_ephemeris_data* m = (struct osp_out_ephemeris_data*)o;
|
||||
|
||||
for (int i = 0; i < 45; i++) {
|
||||
m->payload.data[i] = __REV16(m->payload.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 6.18 OSP OkToSend
|
||||
|
@ -409,6 +561,10 @@ struct osp_in_approximate_ms_position_response {
|
|||
uint8_t oktosend;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_oktosend_post(osp_message_t* o)
|
||||
{
|
||||
(void)o;
|
||||
}
|
||||
enum osp_oktosend {
|
||||
OSP_OKTOSEND_NO = 0,
|
||||
OSP_OKTOSEND_YES = 1
|
||||
|
@ -450,7 +606,7 @@ enum osp_oktosend {
|
|||
uint16_t estimated_horizontal_velocity_error; /* cms-1 */
|
||||
int32_t clock_bias; /* cm */
|
||||
uint32_t clock_bias_error; /* cm */
|
||||
int32_t clock_drft; /* cms-1 */
|
||||
int32_t clock_drift; /* cms-1 */
|
||||
uint32_t clock_drift_error; /* cms-1 */
|
||||
uint32_t distance; /* m */
|
||||
uint16_t distance_error; /* m */
|
||||
|
@ -460,6 +616,42 @@ enum osp_oktosend {
|
|||
uint8_t additional_mode_info;
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_geodetic_navigation_data_post(osp_message_t* o)
|
||||
{
|
||||
struct osp_out_geodetic_navigation_data* m = (struct osp_out_geodetic_navigation_data*)o;
|
||||
|
||||
m->payload.nav_valid = __REV16(m->payload.nav_valid);
|
||||
m->payload.nav_type = __REV16(m->payload.nav_type);
|
||||
m->payload.extended_week_number = __REV16(m->payload.extended_week_number);
|
||||
m->payload.tow = __REV(m->payload.tow);
|
||||
m->payload.utc_year = __REV16(m->payload.utc_year);
|
||||
m->payload.utc_second = __REV16(m->payload.utc_second);
|
||||
m->payload.satellite_id_list = __REV(m->payload.satellite_id_list);
|
||||
|
||||
m->payload.latitude = __REV(m->payload.latitude);
|
||||
m->payload.longitude = __REV(m->payload.longitude);
|
||||
m->payload.altitude_from_ellipsoid = __REV(m->payload.altitude_from_ellipsoid);
|
||||
m->payload.altitude_from_msl = __REV(m->payload.altitude_from_msl);
|
||||
|
||||
m->payload.speed_over_ground = __REV16(m->payload.speed_over_ground);
|
||||
m->payload.course_over_ground = __REV16(m->payload.course_over_ground);
|
||||
m->payload.magnetic_variation = __REV16(m->payload.magnetic_variation);
|
||||
m->payload.climb_rate = __REV16(m->payload.climb_rate);
|
||||
m->payload.heading_rate = __REV16(m->payload.heading_rate);
|
||||
|
||||
m->payload.estimated_horizontal_position_error = __REV(m->payload.estimated_horizontal_position_error);
|
||||
m->payload.estimated_vertical_position_error = __REV(m->payload.estimated_vertical_position_error);
|
||||
m->payload.estimated_time_error = __REV(m->payload.estimated_time_error);
|
||||
m->payload.estimated_horizontal_velocity_error = __REV16(m->payload.estimated_horizontal_velocity_error);
|
||||
|
||||
m->payload.clock_bias = __REV(m->payload.clock_bias);
|
||||
m->payload.clock_bias_error = __REV(m->payload.clock_bias_error);
|
||||
m->payload.clock_drift = __REV(m->payload.clock_drift);
|
||||
m->payload.clock_drift_error = __REV(m->payload.clock_drift_error);
|
||||
m->payload.distance = __REV(m->payload.distance);
|
||||
m->payload.distance_error = __REV16(m->payload.distance_error);
|
||||
m->payload.heading_error = __REV16(m->payload.heading_error);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -482,6 +674,14 @@ enum osp_oktosend {
|
|||
uint8_t status; /* enum osp_1pps_status */
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_1pps_time_post(osp_message_t* o)
|
||||
{
|
||||
struct osp_out_1pps_time* m = (struct osp_out_1pps_time*)o;
|
||||
|
||||
m->payload.year = __REV16(m->payload.year);
|
||||
m->payload.utc_offset_int = __REV16(m->payload.utc_offset_int);
|
||||
m->payload.utc_offset_frac = __REV(m->payload.utc_offset_frac);
|
||||
}
|
||||
enum osp_1pps_status {
|
||||
OSP_1PPS_VALID = (1<<0),
|
||||
OSP_1PPS_IS_UTCTIME = (1<<1), /* otherwise gps time */
|
||||
|
@ -502,6 +702,92 @@ enum osp_1pps_status {
|
|||
uint16_t gpio_state; /* bitmapped */
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_gpio_state_post(osp_message_t* o)
|
||||
{
|
||||
struct osp_out_gpio_state* m = (struct osp_out_gpio_state*)o;
|
||||
|
||||
m->payload.gpio_state = __REV16(m->payload.gpio_state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 6.58 OSP Position Response
|
||||
*/
|
||||
#define OSP_OUT_POSITION_RESPONSE_ID 69
|
||||
struct osp_out_position_response {
|
||||
osp_message_id_t id;
|
||||
enum osp_packet_state state;
|
||||
uint16_t max_payload_size;
|
||||
struct {
|
||||
uint8_t subid; /* ensure always 1 for position response */
|
||||
uint8_t position_request_id;
|
||||
uint8_t position_results_flag;
|
||||
uint8_t position_error_status; /* enum osp_position_error_status */
|
||||
uint8_t position_accuracy_met;
|
||||
uint8_t position_type;
|
||||
uint8_t dgps_correction; /* enum os_dgps_correction_type */
|
||||
uint16_t gps_week;
|
||||
uint32_t gps_seconds; /* ms */
|
||||
int32_t latitude; /* 180/2^32 degrees */
|
||||
int32_t longitude; /* 360/2^32 degrees */
|
||||
uint8_t other_sections;
|
||||
/* Horizontal error */
|
||||
uint8_t er_el_angle; /* 180/2^8 degrees */
|
||||
uint8_t major_std_error;
|
||||
uint8_t minor_std_error;
|
||||
/* Vertical error */
|
||||
uint16_t height; /* dm+500m.. ONLY SUPPORTS TO +6km */
|
||||
uint8_t height_std_error;
|
||||
/* Velocity section */
|
||||
uint16_t horizonal_velocity; /* 0.0625 ms-1 */
|
||||
uint16_t heading; /* 360/2^16 degrees */
|
||||
uint8_t vertical_velocity; /* 0.5ms-1 */
|
||||
uint8_t velocity_er_el_angle; /* 0.75 degrees */
|
||||
uint8_t velocity_major_std_error;
|
||||
uint8_t velicity_minor_std_error;
|
||||
uint8_t vertical_velocity_std_error;
|
||||
/* Clock correction section */
|
||||
uint8_t time_reference;
|
||||
uint16_t clock_bias;
|
||||
uint16_t clock_drift;
|
||||
uint8_t clock_std_error;
|
||||
uint8_t utc_offset; /* s */
|
||||
/* Position Correction Section */
|
||||
uint8_t number_svs;
|
||||
struct {
|
||||
uint8_t sv_prn;
|
||||
uint8_t c_n0; /* dBHz */
|
||||
} svs[16];
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_position_response_post(osp_message_t* o)
|
||||
{
|
||||
struct osp_out_position_response* m = (struct osp_out_position_response*)o;
|
||||
|
||||
m->payload.gps_week = __REV16(m->payload.gps_week);
|
||||
m->payload.gps_seconds = __REV(m->payload.gps_seconds);
|
||||
m->payload.latitude = __REV(m->payload.latitude);
|
||||
m->payload.longitude = __REV(m->payload.longitude);
|
||||
m->payload.height = __REV16(m->payload.height);
|
||||
m->payload.horizonal_velocity = __REV16(m->payload.horizonal_velocity);
|
||||
m->payload.heading = __REV16(m->payload.heading);
|
||||
m->payload.clock_bias = __REV16(m->payload.clock_bias);
|
||||
m->payload.clock_drift = __REV16(m->payload.clock_drift);
|
||||
}
|
||||
enum osp_position_error_status {
|
||||
OSP_POSITION_ERROR_STATUS_VALID = 0,
|
||||
OSP_POSITION_ERROR_STATUS_NOT_ENOUGH_SATS = 1,
|
||||
OSP_POSITION_ERROR_STATUS_GPS_AIDING_MISSING = 2,
|
||||
OSP_POSITION_ERROR_STATUS_NEED_MORE_TIME = 3,
|
||||
OSP_POSITION_ERROR_STATUS_NO_AFTER_FULL_SEARCH= 4,
|
||||
OSP_POSITION_ERROR_STATUS_POS_REPORT_DISABLED = 5,
|
||||
OSP_POSITION_ERROR_STATUS_REJECTED_FOR_QOP = 6,
|
||||
};
|
||||
enum osp_dgps_correction_type {
|
||||
OSP_DGPS_CORRECTION_NO = 0,
|
||||
OSP_DGPS_CORRECTION_LOCAL = 1,
|
||||
OSP_DGPS_CORRECTION_WAAS = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* OSP HW_CONFIG_REQ
|
||||
|
@ -514,6 +800,10 @@ enum osp_1pps_status {
|
|||
struct {
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_hw_config_req_post(osp_message_t* o)
|
||||
{
|
||||
(void)o;
|
||||
}
|
||||
/**
|
||||
* 6.70 OSP Various Aiding Requests
|
||||
*/
|
||||
|
@ -532,6 +822,10 @@ enum osp_1pps_status {
|
|||
};
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_aiding_request_post(osp_message_t* o)
|
||||
{
|
||||
(void)o;
|
||||
}
|
||||
enum {
|
||||
OSP_AIDING_REQUEST_SUBID_APPROXIMATE_MS_POSITION = 1
|
||||
};
|
||||
|
@ -563,6 +857,10 @@ enum {
|
|||
};
|
||||
} __PACKED__ payload;
|
||||
};
|
||||
static void osp_out_cw_controller_output_post(osp_message_t* o)
|
||||
{
|
||||
(void)o;
|
||||
}
|
||||
|
||||
|
||||
/* /\** */
|
||||
|
@ -576,7 +874,12 @@ enum {
|
|||
/* struct { */
|
||||
|
||||
/* } __PACKED__ payload; */
|
||||
/* }; */
|
||||
/* };
|
||||
static void osp__post(osp_message_t* o)
|
||||
{
|
||||
struct osp_* m = (struct osp_*)o;
|
||||
|
||||
} */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef enum {
|
|||
IDLE_NONE,
|
||||
IDLE_TELEMETRY_ACTIVE = 0x15476064,
|
||||
IDLE_WAIT_FOR_NEXT_TELEMETRY = 0x36749870,
|
||||
IDLE_WAIT_FOR_GPS = 0x57786644,
|
||||
} idle_wait_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -63,23 +63,41 @@ void collect_data_async(void)
|
|||
*/
|
||||
struct tracker_datapoint* collect_data(void)
|
||||
{
|
||||
#ifdef GPS_TYPE_OSP
|
||||
/**
|
||||
* ---- Analogue ----
|
||||
* ---- GPS OSP ----
|
||||
*/
|
||||
datapoint.battery = get_battery(); /* Will return zero by default */
|
||||
datapoint.solar = get_solar(); /* Will return zero by default */
|
||||
datapoint.radio_die_temperature = telemetry_si_temperature();
|
||||
datapoint.thermistor_temperature = thermistor_voltage_to_temperature(get_thermistor());
|
||||
|
||||
/**
|
||||
* ---- Barometer ----
|
||||
*/
|
||||
struct barometer* b = get_barometer();
|
||||
datapoint.main_pressure = b->pressure;
|
||||
datapoint.bmp180_temperature = (float)b->temperature;
|
||||
struct gps_data_t data = gps_get_data();
|
||||
|
||||
if (data.is_locked) { /* valid? */
|
||||
datapoint.latitude = data.latitude; /* hndeg */
|
||||
datapoint.longitude = data.longitude; /* hdeg */
|
||||
datapoint.altitude = data.altitude; /* mm */
|
||||
datapoint.satillite_count = data.satillite_count;
|
||||
datapoint.time_to_first_fix = data.time_to_first_fix; /* seconds / counts */
|
||||
}
|
||||
#endif /* GPS_TYPE_OSP */
|
||||
|
||||
|
||||
/* /\** */
|
||||
/* * ---- Analogue ---- */
|
||||
/* *\/ */
|
||||
/* datapoint.battery = get_battery(); /\* Will return zero by default *\/ */
|
||||
/* datapoint.solar = get_solar(); /\* Will return zero by default *\/ */
|
||||
/* datapoint.radio_die_temperature = telemetry_si_temperature(); */
|
||||
/* datapoint.thermistor_temperature = thermistor_voltage_to_temperature(get_thermistor()); */
|
||||
|
||||
/* /\** */
|
||||
/* * ---- Barometer ---- */
|
||||
/* *\/ */
|
||||
/* struct barometer* b = get_barometer(); */
|
||||
/* datapoint.main_pressure = b->pressure; */
|
||||
/* datapoint.bmp180_temperature = (float)b->temperature; */
|
||||
|
||||
#ifdef GPS_TYPE_UBX
|
||||
/**
|
||||
* ---- GPS ----
|
||||
* ---- GPS UBX ----
|
||||
*/
|
||||
if (gps_update_position_pending() || (gps_get_error_state() != GPS_NOERROR)) {
|
||||
/* Error updating GPS position */
|
||||
|
@ -91,9 +109,10 @@ struct tracker_datapoint* collect_data(void)
|
|||
} else { /* GPS position updated correctly */
|
||||
|
||||
/* GPS Status */
|
||||
#ifdef GPS_TYPE_UBX
|
||||
|
||||
struct ubx_nav_sol sol = gps_get_nav_sol();
|
||||
datapoint.satillite_count = sol.payload.numSV;
|
||||
datapoint.time_to_first_fix = 0;
|
||||
|
||||
/* GPS Position */
|
||||
if (gps_is_locked()) {
|
||||
|
@ -106,8 +125,8 @@ struct tracker_datapoint* collect_data(void)
|
|||
|
||||
/* GPS Powersave */
|
||||
gps_set_powersave_auto();
|
||||
#endif /* GPS_TYPE_UBX */
|
||||
}
|
||||
#endif /* GPS_TYPE_UBX */
|
||||
|
||||
return &datapoint;
|
||||
}
|
||||
|
|
|
@ -58,8 +58,19 @@ uint8_t osp_irq_buffer[OSP_BUFFER_LEN];
|
|||
|
||||
volatile enum gps_error_t gps_error_state;
|
||||
|
||||
/* Temp??? */
|
||||
uint8_t gps_make_oktosend = 0;
|
||||
/**
|
||||
* GPS Active?
|
||||
*/
|
||||
enum gps_power_state_t {
|
||||
GPS_HIBERNATE = 0,
|
||||
GPS_ACTIVE = 1,
|
||||
};
|
||||
enum gps_power_state_t gps_power_state = GPS_HIBERNATE;
|
||||
|
||||
/**
|
||||
* Flight State
|
||||
*/
|
||||
enum gps_flight_state_t gps_flight_state = GPS_FLIGHT_STATE_LAUNCH;
|
||||
|
||||
/**
|
||||
* OSP Output Ack/Nack
|
||||
|
@ -105,6 +116,11 @@ volatile struct osp_out_gpio_state osp_out_gpio_state = {
|
|||
.state = OSP_PACKET_WAITING,
|
||||
.max_payload_size = sizeof(osp_out_gpio_state.payload)
|
||||
};
|
||||
volatile struct osp_out_position_response osp_out_position_response = {
|
||||
.id = OSP_OUT_POSITION_RESPONSE_ID,
|
||||
.state = OSP_PACKET_WAITING,
|
||||
.max_payload_size = sizeof(osp_out_position_response.payload)
|
||||
};
|
||||
volatile struct osp_out_hw_config_req osp_out_hw_config_req = {
|
||||
.id = OSP_OUT_HW_CONFIG_REQ_ID,
|
||||
.state = OSP_PACKET_WAITING,
|
||||
|
@ -132,18 +148,37 @@ volatile osp_message_t* const osp_out_messages[] = {
|
|||
(osp_message_t*)&osp_out_geodetic_navigation_data,
|
||||
(osp_message_t*)&osp_out_1pps_time,
|
||||
(osp_message_t*)&osp_out_gpio_state,
|
||||
(osp_message_t*)&osp_out_position_response,
|
||||
(osp_message_t*)&osp_out_hw_config_req,
|
||||
(osp_message_t*)&osp_out_aiding_request,
|
||||
(osp_message_t*)&osp_out_cw_controller_output,
|
||||
};
|
||||
/**
|
||||
* OSP Output Post Processing functions
|
||||
* ** same order as above **
|
||||
*/
|
||||
const osp_post_func osp_out_post_functions[] = {
|
||||
osp_out_measure_navigation_data_out_post,
|
||||
osp_out_clock_status_data_post,
|
||||
osp_out_ephemeris_data_post,
|
||||
osp_out_oktosend_post,
|
||||
osp_out_geodetic_navigation_data_post,
|
||||
osp_out_1pps_time_post,
|
||||
osp_out_gpio_state_post,
|
||||
osp_out_position_response_post,
|
||||
osp_out_hw_config_req_post,
|
||||
osp_out_aiding_request_post,
|
||||
osp_out_cw_controller_output_post,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* OSP Input Messages
|
||||
*
|
||||
* Instances are of the generic type (no payload) to save ram
|
||||
*/
|
||||
volatile osp_message_t osp_in_advanced_power_measurement = {
|
||||
.id = OSP_IN_ADVANCED_POWER_MEASUREMENT_ID,
|
||||
volatile osp_message_t osp_in_advanced_power_management = {
|
||||
.id = OSP_IN_ADVANCED_POWER_MANAGEMENT_ID,
|
||||
.state = OSP_PACKET_WAITING
|
||||
};
|
||||
volatile osp_message_t osp_in_initialise_data_source = {
|
||||
|
@ -174,6 +209,10 @@ volatile osp_message_t osp_in_set_low_power_acquisition_parameters = {
|
|||
.id = OSP_IN_SET_LOW_POWER_ACQUISITION_PARAMETERS_ID,
|
||||
.state = OSP_PACKET_WAITING
|
||||
};
|
||||
volatile osp_message_t osp_in_set_position_request = {
|
||||
.id = OSP_IN_POSITION_REQUEST_ID,
|
||||
.state = OSP_PACKET_WAITING
|
||||
};
|
||||
volatile osp_message_t osp_in_session_request = {
|
||||
.id = OSP_IN_SESSION_REQUEST_ID,
|
||||
.state = OSP_PACKET_WAITING
|
||||
|
@ -186,6 +225,10 @@ volatile osp_message_t osp_in_approximate_ms_position_response = {
|
|||
.id = OSP_IN_APPROXIMATE_MS_POSITION_RESPONSE_ID,
|
||||
.state = OSP_PACKET_WAITING
|
||||
};
|
||||
volatile osp_message_t osp_in_reject = {
|
||||
.id = OSP_IN_REJECT_ID,
|
||||
.state = OSP_PACKET_WAITING
|
||||
};
|
||||
volatile osp_message_t osp_in_power_mode_request = {
|
||||
.id = OSP_IN_POWER_MODE_REQUEST_ID,
|
||||
.state = OSP_PACKET_WAITING
|
||||
|
@ -196,7 +239,7 @@ volatile osp_message_t osp_in_power_mode_request = {
|
|||
* OSP Input Messages
|
||||
*/
|
||||
volatile osp_message_t* const osp_in_messages[] = {
|
||||
&osp_in_advanced_power_measurement,
|
||||
&osp_in_advanced_power_management,
|
||||
&osp_in_initialise_data_source,
|
||||
&osp_in_mode_control,
|
||||
&osp_in_elevation_mask,
|
||||
|
@ -305,14 +348,19 @@ void osp_process_frame(uint8_t* frame, uint16_t payload_length)
|
|||
/* (less than for various subfields which have different lengths) */
|
||||
if (payload_length_less_message_id <= osp_out_messages[i]->max_payload_size) {
|
||||
|
||||
/* Reject measurement response for the moment */
|
||||
if (message_id == OSP_OUT_POSITION_RESPONSE_ID && (frame+2+1)[0] != 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Populate struct. Ignore message ID */
|
||||
memcpy((void*)(osp_out_messages[i]+1), frame+2+1, payload_length_less_message_id);
|
||||
|
||||
/* Set the message state */
|
||||
osp_out_messages[i]->state = OSP_PACKET_UPDATED;
|
||||
|
||||
if(message_id==41){led_toggle();}
|
||||
|
||||
/* Call post function for this message */
|
||||
osp_out_post_functions[i](osp_out_messages[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -413,14 +461,70 @@ void _osp_send_message(osp_message_t* message, uint8_t* payload, uint16_t length
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* Flight State ================================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns current flight state
|
||||
*/
|
||||
enum gps_flight_state_t gps_get_flight_state(void)
|
||||
{
|
||||
return gps_flight_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets flight state
|
||||
*
|
||||
* altitude in mm
|
||||
*/
|
||||
void gps_set_flight_state(int32_t altitude)
|
||||
{
|
||||
if (altitude > GPS_FLIGHT_STATE_THREASHOLD_M*1000) {
|
||||
gps_flight_state = GPS_FLIGHT_STATE_FLOAT;
|
||||
} else {
|
||||
gps_flight_state = GPS_FLIGHT_STATE_LAUNCH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* Power State ================================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Puts the GPS into hibernate state
|
||||
*/
|
||||
void gps_make_active(void)
|
||||
{
|
||||
if (gps_power_state == GPS_HIBERNATE) {
|
||||
gps_se_on_off_pulse();
|
||||
gps_power_state = GPS_ACTIVE;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Puts the GPS into hibernate state
|
||||
*/
|
||||
void gps_make_hibernate(void)
|
||||
{
|
||||
if (gps_power_state == GPS_ACTIVE) {
|
||||
gps_se_on_off_pulse();
|
||||
gps_power_state = GPS_HIBERNATE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* Getters ===================================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the current error state of the GPS to check validity of last
|
||||
* request
|
||||
|
@ -431,22 +535,118 @@ enum gps_error_t gps_get_error_state(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the most recent datapint from the gps
|
||||
* Powers up the GPS, waits up to 60 seconds for a fix
|
||||
*
|
||||
* Uses the Geodetic Navigation Data frame.
|
||||
*/
|
||||
struct gps_data_t gps_get_data(void)
|
||||
{
|
||||
struct gps_data_t data;
|
||||
uint32_t i;
|
||||
|
||||
data.is_locked = (osp_out_geodetic_navigation_data.payload.nav_type == 0)?1:0; /* nav_valid = 0? */
|
||||
/* Clear status */
|
||||
osp_out_geodetic_navigation_data.state = OSP_PACKET_WAITING;
|
||||
|
||||
/* Take the GPS out of hibernate*/
|
||||
gps_make_active();
|
||||
|
||||
for (i = 0; i < 3*2; i++) {
|
||||
|
||||
while (osp_out_geodetic_navigation_data.state != OSP_PACKET_UPDATED) {
|
||||
/* idle */
|
||||
idle(IDLE_WAIT_FOR_GPS);
|
||||
}
|
||||
|
||||
/* Clear status */
|
||||
osp_out_geodetic_navigation_data.state = OSP_PACKET_WAITING;
|
||||
|
||||
/* Got packet */
|
||||
if (gps_get_flight_state() == GPS_FLIGHT_STATE_LAUNCH) {
|
||||
led_toggle();
|
||||
}
|
||||
|
||||
/* Check nav */
|
||||
if ((osp_out_geodetic_navigation_data.payload.nav_valid == 0) && /* Valid fix */
|
||||
((osp_out_geodetic_navigation_data.payload.nav_type & 0x7) != 0) && /* Currently have this fix */
|
||||
(osp_out_geodetic_navigation_data.payload.estimated_vertical_position_error < 100*100)) /* < 100m error */
|
||||
{
|
||||
/* GPS back to hibernate */
|
||||
gps_make_hibernate();
|
||||
|
||||
data.is_locked = 1; /* valid fix */
|
||||
data.latitude = osp_out_geodetic_navigation_data.payload.latitude; /* hndeg */
|
||||
data.longitude = osp_out_geodetic_navigation_data.payload.longitude; /* hndeg */
|
||||
data.altitude = osp_out_geodetic_navigation_data.payload.altitude_from_msl*10; /* cm -> mm */
|
||||
data.satillite_count = osp_out_geodetic_navigation_data.payload.svs_in_fix;
|
||||
data.time_to_first_fix = i+1; /* number of geo nav packets this took */
|
||||
|
||||
gps_set_flight_state(data.altitude);
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/* GPS back to hibernate */
|
||||
gps_make_hibernate();
|
||||
|
||||
data.is_locked = 0; /* invalid */
|
||||
data.latitude = 0;
|
||||
data.longitude = 0;
|
||||
data.altitude = 0;
|
||||
data.satillite_count = 0;
|
||||
data.time_to_first_fix = i;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* Low Power ===================================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Request Full power mode
|
||||
*/
|
||||
void osp_session_request_close(void)
|
||||
{
|
||||
/* session request #213 */
|
||||
struct osp_in_session_request config;
|
||||
memset(&config, 0, sizeof(struct osp_in_session_request));
|
||||
config.id = OSP_IN_SESSION_REQUEST_ID;
|
||||
|
||||
/* values */
|
||||
config.payload.sub_id = OSP_SESSION_REQUEST_CLOSE;
|
||||
config.payload.info = 0; /* Session close requested */
|
||||
|
||||
/* send */
|
||||
_osp_send_message((osp_message_t*)&config,
|
||||
(uint8_t*)&config.payload,
|
||||
sizeof(config.payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter push-to-fix mode
|
||||
*/
|
||||
void osp_enter_push_to_fix_mode(void)
|
||||
{
|
||||
/* set tricklepower parameters #151 */
|
||||
struct osp_in_set_tricklepower_parameters config;
|
||||
memset(&config, 0, sizeof(struct osp_in_set_tricklepower_parameters));
|
||||
config.id = OSP_IN_SET_TRICKLEPOWER_PARAMETERS_ID;
|
||||
|
||||
/* values */
|
||||
config.payload.pushtofix_mode = 1; /* Enable push-to-fix */
|
||||
config.payload.on_time = 200; /* 200 ms (minimum) */
|
||||
config.payload.duty_cycle = 10; /* 1% */
|
||||
|
||||
/* send */
|
||||
osp_in_set_tricklepower_parameters_pre(&config);
|
||||
_osp_send_message((osp_message_t*)&config,
|
||||
(uint8_t*)&config.payload,
|
||||
sizeof(config.payload));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -511,16 +711,59 @@ void osp_send_hw_config_resp(void)
|
|||
OSP_HW_CONFIG_FREQUENCY_REFCLK_OFF
|
||||
);
|
||||
config.payload.nominal_frequency_high = 0;
|
||||
config.payload.nominal_frequency_low = __REV(1*1000); /* 1Hz?? */
|
||||
config.payload.nominal_frequency_low = 1*1000; /* 1Hz */
|
||||
config.payload.network_enhancement_type = 0; /* No enhancement */
|
||||
|
||||
osp_in_hardware_configuration_response_pre(&config);
|
||||
_osp_send_message((osp_message_t*)&config,
|
||||
(uint8_t*)&config.payload,
|
||||
sizeof(config.payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to position aiding request
|
||||
* Reset Initialise
|
||||
*/
|
||||
void osp_reset_initialise(void)
|
||||
{
|
||||
/* initialise data source #128 */
|
||||
struct osp_in_initialise_data_source config;
|
||||
memset(&config, 0, sizeof(struct osp_in_initialise_data_source));
|
||||
config.id = OSP_IN_INITIALISE_DATA_SOURCE_ID;
|
||||
|
||||
/* values */
|
||||
/* All zeros */
|
||||
|
||||
/* send */
|
||||
_osp_send_message((osp_message_t*)&config,
|
||||
(uint8_t*)&config.payload,
|
||||
sizeof(config.payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send reject message NOT AVAILABLE
|
||||
*/
|
||||
void osp_send_reject_not_available(uint8_t message_id_to_reject,
|
||||
uint8_t message_sub_id_to_reject)
|
||||
{
|
||||
/* reject #216 */
|
||||
struct osp_in_reject config;
|
||||
memset(&config, 0, sizeof(struct osp_in_reject));
|
||||
config.id = OSP_IN_REJECT_ID;
|
||||
|
||||
/* values */
|
||||
config.payload.sub_id = 2;
|
||||
config.payload.rejected_message_id = message_id_to_reject;
|
||||
config.payload.rejected_message_sub_id = message_sub_id_to_reject;
|
||||
config.payload.rejected_message_reason = OSP_REJECTED_MESSAGE_NOT_AVAILABLE;
|
||||
|
||||
/* send */
|
||||
_osp_send_message((osp_message_t*)&config,
|
||||
(uint8_t*)&config.payload,
|
||||
sizeof(config.payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to approximate ms request
|
||||
*/
|
||||
void osp_send_approximate_ms_postion(void)
|
||||
{
|
||||
|
@ -539,24 +782,56 @@ void osp_send_approximate_ms_postion(void)
|
|||
config.payload.use_alt_aiding = 0; /* don't even use the altitude */
|
||||
|
||||
/* send */
|
||||
osp_in_approximate_ms_position_response_pre(&config);
|
||||
_osp_send_message((osp_message_t*)&config,
|
||||
(uint8_t*)&config.payload,
|
||||
sizeof(config.payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* Place a position request
|
||||
*/
|
||||
void osp_send_position_request(void)
|
||||
{
|
||||
/* approximate ms position */
|
||||
struct osp_in_position_request config;
|
||||
memset(&config, 0, sizeof(struct osp_in_position_request));
|
||||
config.id = OSP_IN_POSITION_REQUEST_ID;
|
||||
|
||||
/* values */
|
||||
config.payload.pos_request_id = 0;
|
||||
config.payload.num_fixes = 1; /* Just one fix */
|
||||
config.payload.time_between_fixes = 0;
|
||||
config.payload.horizontal_error_max = 100; /* 100m horizonal error */
|
||||
config.payload.vertical_error_max = OSP_MAX_ERROR_80_METER; /* 80m vertical error */
|
||||
config.payload.response_time_max = 0; /* any time */
|
||||
config.payload.time_acc_priority = OSP_TIME_ACC_PRIORITY_NONE;
|
||||
config.payload.location_method = 0; /* ???? */
|
||||
|
||||
/* send */
|
||||
osp_in_position_request_pre(&config);
|
||||
_osp_send_message((osp_message_t*)&config,
|
||||
(uint8_t*)&config.payload,
|
||||
sizeof(config.payload));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* Serivce ===================================================================
|
||||
* Setup ===================================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle connection-orientated messages from the GPS that need servicing
|
||||
* GPS configuration
|
||||
*/
|
||||
void gps_service(void)
|
||||
void gps_setup(void)
|
||||
{
|
||||
/* Attempt to turn on GPS */
|
||||
gps_se_on_off_pulse();
|
||||
|
||||
while (1) { /* TODO: timeout */
|
||||
|
||||
/* We received the hw config req */
|
||||
if (osp_out_hw_config_req.state == OSP_PACKET_UPDATED) {
|
||||
/* send response */
|
||||
|
@ -572,35 +847,40 @@ void gps_service(void)
|
|||
if (osp_out_aiding_request.payload.subid ==
|
||||
OSP_AIDING_REQUEST_SUBID_APPROXIMATE_MS_POSITION) {
|
||||
/* send response to approximate ms position request */
|
||||
osp_send_approximate_ms_postion();
|
||||
osp_send_reject_not_available(OSP_OUT_AIDING_REQUEST_ID,
|
||||
OSP_AIDING_REQUEST_SUBID_APPROXIMATE_MS_POSITION);
|
||||
|
||||
/* Set message formats */
|
||||
osp_set_messages();
|
||||
|
||||
gps_make_oktosend = 0; /* all done */
|
||||
/* Check these get ack'd? */
|
||||
|
||||
/* Otherwise we're done */
|
||||
break;
|
||||
}
|
||||
|
||||
/* clear state */
|
||||
osp_out_aiding_request.state = OSP_PACKET_WAITING;
|
||||
}
|
||||
|
||||
|
||||
/* We're trying to make it oktosend */
|
||||
if (gps_make_oktosend == 1) {
|
||||
/* And we've had an oktosend packet */
|
||||
/* oktosend packet */
|
||||
if (osp_out_oktosend.state == OSP_PACKET_UPDATED) {
|
||||
|
||||
/* was this an enable or disable packet? */
|
||||
if (osp_out_oktosend.payload.oktosend == OSP_OKTOSEND_YES) {
|
||||
/* all done */
|
||||
/* we're now active */
|
||||
gps_power_state = GPS_ACTIVE;
|
||||
} else {
|
||||
gps_se_on_off_pulse(); /* send another on_off pulse */
|
||||
gps_power_state = GPS_HIBERNATE;
|
||||
}
|
||||
|
||||
/* clear state */
|
||||
osp_out_oktosend.state = OSP_PACKET_WAITING;
|
||||
}
|
||||
}
|
||||
|
||||
idle(IDLE_WAIT_FOR_GPS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -634,7 +914,7 @@ void gps_usart_init_enable(uint32_t baud_rate)
|
|||
false, /** Sample on the rising edge of XLCK */
|
||||
false, /** Use the external clock applied to the XCK pin. */
|
||||
0, /** External clock frequency in synchronous mode. */
|
||||
true, /** Run in standby */
|
||||
false, /** Run in standby */
|
||||
GPS_GCLK, /** GCLK generator source */
|
||||
GPS_SERCOM_MOGI_PINMUX, /** PAD0 pinmux */
|
||||
GPS_SERCOM_MIGO_PINMUX, /** PAD1 pinmux */
|
||||
|
@ -689,13 +969,10 @@ void gps_init(void)
|
|||
|
||||
/* ---- GPS Configuration ---- */
|
||||
|
||||
/* Bring up the GPS */
|
||||
gps_make_oktosend = 1;
|
||||
gps_se_on_off_pulse();
|
||||
/* Close any currently running session. Doesn't do anything unless debugging */
|
||||
osp_reset_initialise();
|
||||
|
||||
while (gps_make_oktosend == 1) {
|
||||
gps_service();
|
||||
}
|
||||
gps_setup();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -99,7 +99,6 @@ void init(enum init_type init_t)
|
|||
system_flash_set_waitstates(SYSTEM_WAIT_STATE_1_8V_14MHZ);
|
||||
|
||||
/* Restart the GCLK Module */
|
||||
system_gclk_init();
|
||||
system_events_init();
|
||||
system_extint_init();
|
||||
|
||||
|
@ -109,8 +108,7 @@ void init(enum init_type init_t)
|
|||
}
|
||||
|
||||
/* Configure Sleep Mode */
|
||||
//system_set_sleepmode(SYSTEM_SLEEPMODE_STANDBY);
|
||||
system_set_sleepmode(SYSTEM_SLEEPMODE_IDLE_2); /* Disable CPU, AHB and APB */
|
||||
system_set_sleepmode(SYSTEM_SLEEPMODE_IDLE_2); /* Lowest power */
|
||||
|
||||
/* Configure the Power Manager */
|
||||
powermananger_init();
|
||||
|
@ -121,21 +119,34 @@ void init(enum init_type init_t)
|
|||
*/
|
||||
|
||||
/* Memory */
|
||||
init_memory();
|
||||
//init_memory();
|
||||
|
||||
/* Timepulse_Pin */
|
||||
port_pin_set_config(GPS_TIMEPULSE_PIN,
|
||||
PORT_PIN_DIR_INPUT, /* Direction */
|
||||
PORT_PIN_PULL_NONE, /* Pull */
|
||||
false); /* Powersave */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Enable the xosc on gclk1 */
|
||||
xosc_init();
|
||||
|
||||
/* i2c */
|
||||
i2c_init(I2C_SERCOM, I2C_SERCOM_SDA_PINMUX, I2C_SERCOM_SCL_PINMUX);
|
||||
// i2c_init(I2C_SERCOM, I2C_SERCOM_SDA_PINMUX, I2C_SERCOM_SCL_PINMUX);
|
||||
|
||||
/* barometer */
|
||||
bmp180_init();
|
||||
// bmp180_init();
|
||||
|
||||
if (init_t != INIT_TESTCASE) {
|
||||
/* Telemetry init depends on gclk */
|
||||
telemetry_init();
|
||||
|
||||
/* We need to wait for the GPS 32kHz clock to start (~300ms). TODO: more robust method for this */
|
||||
for (int i = 0; i < 1*1000*1000; i++);
|
||||
|
||||
/* GPS init */
|
||||
gps_init();
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ volatile uint8_t run_flag = 1; /* run immediately after init */
|
|||
void lf_tick(uint32_t tick)
|
||||
{
|
||||
/* When we're due to run again */
|
||||
if (tick >= 20) {
|
||||
if (tick >= 10) {
|
||||
/* Stop */
|
||||
lf_tick_stop();
|
||||
|
||||
|
@ -254,24 +254,22 @@ int main(void)
|
|||
/* Turn off LED to show we've initialised correctly */
|
||||
led_off();
|
||||
|
||||
/* Clocks off */
|
||||
gclk0_to_lf_clock();
|
||||
hf_clock_disable();
|
||||
|
||||
while (1) {
|
||||
/* Run sequence */
|
||||
/* Run sequence - starts immediately on first iteration */
|
||||
if (run_flag) {
|
||||
run_flag = 0;
|
||||
|
||||
/* Clocks on */
|
||||
hf_clock_enable();
|
||||
gclk0_to_hf_clock();
|
||||
system_set_sleepmode(SYSTEM_SLEEPMODE_IDLE_2); /* Low power */
|
||||
|
||||
/* Run */
|
||||
//run_sequencer(n++);
|
||||
for (int i = 0; i < 100*1000; i++);
|
||||
run_sequencer(n++);
|
||||
|
||||
/* Clocks off */
|
||||
system_set_sleepmode(SYSTEM_SLEEPMODE_STANDBY); /* Lowest power */
|
||||
gclk0_to_lf_clock();
|
||||
hf_clock_disable();
|
||||
|
||||
|
|
|
@ -82,22 +82,17 @@ void run_sequencer(uint32_t n)
|
|||
{
|
||||
struct tracker_datapoint* dp;
|
||||
|
||||
/* Trigger GPS */
|
||||
|
||||
/* Async data */
|
||||
collect_data_async();
|
||||
|
||||
/* Wait for GPS */
|
||||
|
||||
//collect_data_async();
|
||||
|
||||
/* Data */
|
||||
dp = collect_data();
|
||||
|
||||
/* Telemetry */
|
||||
telemetry_sequence(dp, n);
|
||||
//telemetry_sequence(dp, n);
|
||||
|
||||
/* Backlog */
|
||||
if ((n % 60) == 10) { /* Every hour, start ten minutes */
|
||||
record_backlog(dp);
|
||||
//record_backlog(dp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -247,9 +247,10 @@ uint32_t system_gclk_gen_get_hz(const uint8_t generator)
|
|||
/* Select the appropriate generator */
|
||||
*((uint8_t*)&GCLK->GENCTRL.reg) = generator;
|
||||
GCLK_WAIT_FOR_SYNC();
|
||||
enum system_clock_source src = (enum system_clock_source)GCLK->GENCTRL.bit.SRC;
|
||||
|
||||
/* Get the frequency of the source connected to the GCLK generator */
|
||||
uint32_t gen_input_hz = system_clock_source_get_hz(
|
||||
(enum system_clock_source)GCLK->GENCTRL.bit.SRC);
|
||||
uint32_t gen_input_hz = system_clock_source_get_hz(src);
|
||||
|
||||
*((uint8_t*)&GCLK->GENCTRL.reg) = generator;
|
||||
|
||||
|
|
|
@ -113,31 +113,31 @@ void kick_the_watchdog(void)
|
|||
void idle(idle_wait_t idle_t)
|
||||
{
|
||||
/* Check valid */
|
||||
if ((idle_t != IDLE_TELEMETRY_ACTIVE) &&
|
||||
(idle_t != IDLE_WAIT_FOR_NEXT_TELEMETRY)) {
|
||||
/* Oh dear */
|
||||
while (1);
|
||||
}
|
||||
/* if ((idle_t != IDLE_TELEMETRY_ACTIVE) && */
|
||||
/* (idle_t != IDLE_WAIT_FOR_NEXT_TELEMETRY)) { */
|
||||
/* /\* Oh dear *\/ */
|
||||
/* while (1); */
|
||||
/* } */
|
||||
|
||||
/* Maybe clear */
|
||||
if (idle_t != last_idle_t) {
|
||||
clear_idle_counters();
|
||||
last_idle_t = idle_t;
|
||||
}
|
||||
/* /\* Maybe clear *\/ */
|
||||
/* if (idle_t != last_idle_t) { */
|
||||
/* clear_idle_counters(); */
|
||||
/* last_idle_t = idle_t; */
|
||||
/* } */
|
||||
|
||||
/* Increment the idle counter */
|
||||
increment_idle_counter(idle_t);
|
||||
/* /\* Increment the idle counter *\/ */
|
||||
/* increment_idle_counter(idle_t); */
|
||||
|
||||
/* Check idle counter is still okay */
|
||||
check_idle_counters();
|
||||
/* /\* Check idle counter is still okay *\/ */
|
||||
/* check_idle_counters(); */
|
||||
|
||||
/* Kick the watchdog */
|
||||
#ifdef DEBUG_USE_INTWATCHDOG
|
||||
wdt_reset_count();
|
||||
#endif
|
||||
/* /\* Kick the watchdog *\/ */
|
||||
/* #ifdef DEBUG_USE_INTWATCHDOG */
|
||||
/* wdt_reset_count(); */
|
||||
/* #endif */
|
||||
|
||||
/* WDI low */
|
||||
port_pin_set_output_level(WDT_WDI_PIN, 0);
|
||||
/* WDI toggle */
|
||||
port_pin_toggle_output_level(WDT_WDI_PIN);
|
||||
|
||||
/* And sleep */
|
||||
system_sleep();
|
||||
|
|
Ładowanie…
Reference in New Issue