From 8b6e706a6a71d70e40a16ead18aee0e6fb88c911 Mon Sep 17 00:00:00 2001 From: Richard Meadows Date: Sun, 22 Nov 2015 19:36:10 +0000 Subject: [PATCH] SE880 running. Cycles between standby and gps running --- firmware/inc/data.h | 1 + firmware/inc/gps.h | 13 +- firmware/inc/hw_config.h | 6 +- firmware/inc/osp_messages.h | 357 ++++++++++++++++++++++++++++++--- firmware/inc/watchdog.h | 1 + firmware/src/data.c | 47 +++-- firmware/src/gps_osp.c | 381 +++++++++++++++++++++++++++++++----- firmware/src/init.c | 27 ++- firmware/src/main.c | 12 +- firmware/src/sequencer.c | 11 +- firmware/src/system/gclk.c | 5 +- firmware/src/watchdog.c | 40 ++-- 12 files changed, 759 insertions(+), 142 deletions(-) diff --git a/firmware/inc/data.h b/firmware/inc/data.h index e640a16..babf1c9 100644 --- a/firmware/inc/data.h +++ b/firmware/inc/data.h @@ -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 */ diff --git a/firmware/inc/gps.h b/firmware/inc/gps.h index fde59d1..0192609 100644 --- a/firmware/inc/gps.h +++ b/firmware/inc/gps.h @@ -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); diff --git a/firmware/inc/hw_config.h b/firmware/inc/hw_config.h index a7aaa4e..7be4e4b 100644 --- a/firmware/inc/hw_config.h +++ b/firmware/inc/hw_config.h @@ -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 @@ -204,7 +206,7 @@ */ #define USE_XOSC 1 #define XOSC_FREQUENCY 16369000 -#define XOSC_GCLK_DIVIDE 2 /* ~8MHz on GCLK*/ +#define XOSC_GCLK_DIVIDE 2 /* ~8MHz on GCLK */ #define OSC8M_GCLK_DIVIDE 1 /* ~8MHz on GCLK */ /** diff --git a/firmware/inc/osp_messages.h b/firmware/inc/osp_messages.h index 2f2f35d..a98ea07 100644 --- a/firmware/inc/osp_messages.h +++ b/firmware/inc/osp_messages.h @@ -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 @@ -333,7 +454,7 @@ struct osp_in_approximate_ms_position_response { * 6.2 OSP Measure Naviagation Data Out */ #define OSP_OUT_MEASURE_NAVIGATION_DATA_OUT_ID 2 - struct osp_out_measure_navigation_data_out { +struct osp_out_measure_navigation_data_out { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -364,12 +485,25 @@ 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 */ #define OSP_OUT_CLOCK_STATUS_DATA_ID 7 - struct osp_out_clock_status_data { +struct osp_out_clock_status_data { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -382,12 +516,22 @@ 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 */ #define OSP_OUT_EPHEMERIS_DATA_ID 15 - struct osp_out_ephemeris_data { +struct osp_out_ephemeris_data { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -396,12 +540,20 @@ 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 */ #define OSP_OUT_OKTOSEND_ID 18 - struct osp_out_oktosend { +struct osp_out_oktosend { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -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 @@ -418,7 +574,7 @@ enum osp_oktosend { * 6.27 OSP Geodetic Navigation Data */ #define OSP_OUT_GEODETIC_NAVIGATION_DATA_ID 41 - struct osp_out_geodetic_navigation_data { +struct osp_out_geodetic_navigation_data { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -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,13 +616,49 @@ 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); +} /** * 6.42 OSP 1PPS Time */ #define OSP_OUT_1PPS_TIME_ID 52 - struct osp_out_1pps_time { +struct osp_out_1pps_time { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -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 */ @@ -493,7 +693,7 @@ enum osp_1pps_status { * 6.55 OSP GPIO State */ #define OSP_OUT_GPIO_STATE_ID 65 - struct osp_out_gpio_state { +struct osp_out_gpio_state { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -502,23 +702,113 @@ 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 */ #define OSP_OUT_HW_CONFIG_REQ_ID 71 - struct osp_out_hw_config_req { +struct osp_out_hw_config_req { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; struct { } __PACKED__ payload; }; +static void osp_out_hw_config_req_post(osp_message_t* o) +{ + (void)o; +} /** * 6.70 OSP Various Aiding Requests */ #define OSP_OUT_AIDING_REQUEST_ID 73 - struct osp_out_aiding_request { +struct osp_out_aiding_request { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -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 }; @@ -541,7 +835,7 @@ enum { * 6.84 OSP CW Controller Output */ #define OSP_OUT_CW_CONTROLLER_OUTPUT_ID 92 - struct osp_out_cw_controller_output { +struct osp_out_cw_controller_output { osp_message_id_t id; enum osp_packet_state state; uint16_t max_payload_size; @@ -563,20 +857,29 @@ enum { }; } __PACKED__ payload; }; +static void osp_out_cw_controller_output_post(osp_message_t* o) +{ + (void)o; +} /* /\** */ /* * */ /* *\/ */ /* #define OSP__ID - struct osp_ { */ +struct osp_ { */ /* osp_message_id_t id; */ /* enum osp_packet_state state; uint16_t max_payload_size; */ /* struct { */ /* } __PACKED__ payload; */ -/* }; */ +/* }; +static void osp__post(osp_message_t* o) +{ + struct osp_* m = (struct osp_*)o; + +} */ diff --git a/firmware/inc/watchdog.h b/firmware/inc/watchdog.h index f63a755..d770b35 100644 --- a/firmware/inc/watchdog.h +++ b/firmware/inc/watchdog.h @@ -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; /** diff --git a/firmware/src/data.c b/firmware/src/data.c index e79ac9f..0005476 100644 --- a/firmware/src/data.c +++ b/firmware/src/data.c @@ -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; } diff --git a/firmware/src/gps_osp.c b/firmware/src/gps_osp.c index 9dd077d..b27087a 100644 --- a/firmware/src/gps_osp.c +++ b/firmware/src/gps_osp.c @@ -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,24 +535,120 @@ 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? */ - 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; + /* 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)); +} + + /** * ============================================================================= * Commands =================================================================== @@ -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,68 +782,105 @@ 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) { - /* We received the hw config req */ - if (osp_out_hw_config_req.state == OSP_PACKET_UPDATED) { - /* send response */ - osp_send_hw_config_resp(); + /* Attempt to turn on GPS */ + gps_se_on_off_pulse(); - /* clear state */ - osp_out_hw_config_req.state = OSP_PACKET_WAITING; - } + while (1) { /* TODO: timeout */ - /* aiding request */ - if (osp_out_aiding_request.state == OSP_PACKET_UPDATED) { + /* We received the hw config req */ + if (osp_out_hw_config_req.state == OSP_PACKET_UPDATED) { + /* send response */ + osp_send_hw_config_resp(); - 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_set_messages(); - - gps_make_oktosend = 0; /* all done */ + /* clear state */ + osp_out_hw_config_req.state = OSP_PACKET_WAITING; } - /* clear state */ - osp_out_aiding_request.state = OSP_PACKET_WAITING; - } + /* aiding request */ + if (osp_out_aiding_request.state == OSP_PACKET_UPDATED) { + if (osp_out_aiding_request.payload.subid == + OSP_AIDING_REQUEST_SUBID_APPROXIMATE_MS_POSITION) { + /* send response to approximate ms position request */ + osp_send_reject_not_available(OSP_OUT_AIDING_REQUEST_ID, + OSP_AIDING_REQUEST_SUBID_APPROXIMATE_MS_POSITION); - /* We're trying to make it oktosend */ - if (gps_make_oktosend == 1) { - /* And we've had an oktosend packet */ + /* Set message formats */ + osp_set_messages(); + + /* Check these get ack'd? */ + + /* Otherwise we're done */ + break; + } + + /* clear state */ + osp_out_aiding_request.state = OSP_PACKET_WAITING; + } + + /* 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(); } diff --git a/firmware/src/init.c b/firmware/src/init.c index 2ab14fd..467dd73 100644 --- a/firmware/src/init.c +++ b/firmware/src/init.c @@ -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(); } diff --git a/firmware/src/main.c b/firmware/src/main.c index 13bee68..a4dfaa8 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -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(); diff --git a/firmware/src/sequencer.c b/firmware/src/sequencer.c index b77dfd7..8cb9a6d 100644 --- a/firmware/src/sequencer.c +++ b/firmware/src/sequencer.c @@ -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); } } diff --git a/firmware/src/system/gclk.c b/firmware/src/system/gclk.c index ca10cd8..eb0554a 100644 --- a/firmware/src/system/gclk.c +++ b/firmware/src/system/gclk.c @@ -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; diff --git a/firmware/src/watchdog.c b/firmware/src/watchdog.c index bf76ab3..79de96a 100644 --- a/firmware/src/watchdog.c +++ b/firmware/src/watchdog.c @@ -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();