From 0cedc27e22a9fbc9ccfe1b403c84d728bb23220d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 11 Sep 2014 15:00:25 -0700 Subject: altos: Fix ability to disable telemetry by setting interval to 0 For non-zero telemetry intervals, the radio code limits the value based on the data rate. However, a zero interval means that telemetry should be entirely disabled, so that value should be left alone when checking. Signed-off-by: Keith Packard --- src/kernel/ao_telemetry.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 56bd715e..27306a34 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -518,7 +518,7 @@ ao_telemetry_set_interval(uint16_t interval) }; ao_telemetry_desired_interval = interval; - if (interval < min_interval[ao_config.radio_rate]) + if (interval && interval < min_interval[ao_config.radio_rate]) interval = min_interval[ao_config.radio_rate]; #endif ao_telemetry_interval = interval; -- cgit v1.2.3 From 807e62ccebc83eb6427a63431d06effa074e5e76 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 11 Sep 2014 19:56:13 -0700 Subject: altos: Make sure we don't beep out continuity twice in idle mode If the battery voltage report takes longer than the initialiation sequence, we could get to the state reporting after the state had switched from startup to idle. This would result in continuity being reported the first time through the loop. Then, as the state had already changed, we'd pass through the while test and go back to report continuity a second time. Fixed by using the state remembered before beeping out the voltage to decide whether to report the continuity. Signed-off-by: Keith Packard --- src/kernel/ao_report.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_report.c b/src/kernel/ao_report.c index 5314fc8f..f4253b3d 100644 --- a/src/kernel/ao_report.c +++ b/src/kernel/ao_report.c @@ -246,15 +246,15 @@ ao_report_continuity(void) __reentrant void ao_report(void) { - ao_report_state = ao_flight_state; for(;;) { + ao_report_state = ao_flight_state; #if HAS_BATTERY_REPORT - if (ao_flight_state == ao_flight_startup) + if (ao_report_state == ao_flight_startup) ao_report_battery(); else #endif ao_report_beep(); - if (ao_flight_state == ao_flight_landed) { + if (ao_report_state == ao_flight_landed) { ao_report_altitude(); #if HAS_FLIGHT ao_delay(AO_SEC_TO_TICKS(5)); @@ -262,7 +262,7 @@ ao_report(void) #endif } #if HAS_IGNITE_REPORT - if (ao_flight_state == ao_flight_idle) + if (ao_report_state == ao_flight_idle) ao_report_continuity(); while (ao_flight_state == ao_flight_pad) { uint8_t c; @@ -272,10 +272,8 @@ ao_report(void) pause(AO_MS_TO_TICKS(100)); } #endif - while (ao_report_state == ao_flight_state) ao_sleep(DATA_TO_XDATA(&ao_flight_state)); - ao_report_state = ao_flight_state; } } -- cgit v1.2.3 From 9521dc63671b69065d27fc1ccba6d20cc90643cb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 4 Oct 2014 00:04:39 -0700 Subject: altos: Record 32-bits for gyro calibration values The gyro ground calibration values are scaled by 512 to provide a bit more precision for the computations. This means they don't fit in 16 bits, so change the format of the flight log record. Also change the reported format so that AltosUI has a chance of figuring it out. Signed-off-by: Keith Packard --- src/kernel/ao_log.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index c13a2580..3354c243 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -43,11 +43,12 @@ extern __pdata enum ao_flight_state ao_log_state; #define AO_LOG_FORMAT_TINY 2 /* two byte state/baro records */ #define AO_LOG_FORMAT_TELEMETRY 3 /* 32 byte ao_telemetry records */ #define AO_LOG_FORMAT_TELESCIENCE 4 /* 32 byte typed telescience records */ -#define AO_LOG_FORMAT_TELEMEGA 5 /* 32 byte typed telemega records */ +#define AO_LOG_FORMAT_TELEMEGA_OLD 5 /* 32 byte typed telemega records */ #define AO_LOG_FORMAT_EASYMINI 6 /* 16-byte MS5607 baro only, 3.0V supply */ #define AO_LOG_FORMAT_TELEMETRUM 7 /* 16-byte typed telemetrum records */ #define AO_LOG_FORMAT_TELEMINI 8 /* 16-byte MS5607 baro only, 3.3V supply */ #define AO_LOG_FORMAT_TELEGPS 9 /* 32 byte telegps records */ +#define AO_LOG_FORMAT_TELEMEGA 10 /* 32 byte typed telemega records with 32 bit gyro cal */ #define AO_LOG_FORMAT_NONE 127 /* No log at all */ extern __code uint8_t ao_log_format; @@ -208,6 +209,18 @@ struct ao_log_mega { uint16_t tick; /* 2 */ union { /* 4 */ /* AO_LOG_FLIGHT */ + struct { + uint16_t flight; /* 4 */ + int16_t ground_accel; /* 6 */ + uint32_t ground_pres; /* 8 */ + int16_t ground_accel_along; /* 12 */ + int16_t ground_accel_across; /* 14 */ + int16_t ground_accel_through; /* 16 */ + int16_t pad /* 18 */ + int32_t ground_roll; /* 20 */ + int32_t ground_pitch; /* 24 */ + int32_t ground_yaw; /* 28 */ + } flight; /* 32 */ struct { uint16_t flight; /* 4 */ int16_t ground_accel; /* 6 */ @@ -218,7 +231,7 @@ struct ao_log_mega { int16_t ground_roll; /* 18 */ int16_t ground_pitch; /* 20 */ int16_t ground_yaw; /* 22 */ - } flight; /* 24 */ + } flight_old; /* 24 */ /* AO_LOG_STATE */ struct { uint16_t state; -- cgit v1.2.3 From 62628c8b429d06ee834f0b6511c430cbeaab9303 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 4 Oct 2014 00:30:54 -0700 Subject: altos: Fix syntax error with ao_log_mega change. Missed a semi-colon. Signed-off-by: Keith Packard --- src/kernel/ao_log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_log.h b/src/kernel/ao_log.h index 3354c243..f86fb359 100644 --- a/src/kernel/ao_log.h +++ b/src/kernel/ao_log.h @@ -216,7 +216,7 @@ struct ao_log_mega { int16_t ground_accel_along; /* 12 */ int16_t ground_accel_across; /* 14 */ int16_t ground_accel_through; /* 16 */ - int16_t pad /* 18 */ + int16_t pad_18; /* 18 */ int32_t ground_roll; /* 20 */ int32_t ground_pitch; /* 24 */ int32_t ground_yaw; /* 28 */ -- cgit v1.2.3 From 7fea8b245cdccc1ec77aa559433952f339676473 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 7 Oct 2014 05:35:10 +0200 Subject: altos: Expose telemetry altitude macros even without GPS This allows for APRS testing in the new teledongle code Signed-off-by: Keith Packard --- src/kernel/ao_telemetry.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h index 83d432cf..340c388e 100644 --- a/src/kernel/ao_telemetry.h +++ b/src/kernel/ao_telemetry.h @@ -116,8 +116,6 @@ struct ao_telemetry_location { /* 32 */ }; -#if HAS_GPS - #ifndef HAS_WIDE_GPS #define HAS_WIDE_GPS 1 #endif @@ -135,8 +133,6 @@ typedef int16_t gps_alt_t; (l)->altitude_low = (a))) #endif /* HAS_WIDE_GPS */ -#endif /* HAS_GPS */ - #define AO_TELEMETRY_SATELLITE 0x06 struct ao_telemetry_satellite_info { -- cgit v1.2.3 From 9102183b40f0b32d4fb6d24502b79a6431184310 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 25 Oct 2014 10:17:48 -0700 Subject: altos: Sort out ao_gps_print altitude fetching ao_gps_print is used by both teledongle/telebt and the host-based GPS test code. The first instance uses the old internal GPS structure, containing just a 16-bit altitude while the second uses an ao_telemetry structure, which contains 32 bits split into two members. Signed-off-by: Keith Packard --- src/kernel/ao_gps_print.c | 6 +++--- src/test/ao_gps_test_ublox.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_gps_print.c b/src/kernel/ao_gps_print.c index d26021da..6d9ee346 100644 --- a/src/kernel/ao_gps_print.c +++ b/src/kernel/ao_gps_print.c @@ -20,8 +20,8 @@ #endif #include "ao_telem.h" -#ifndef AO_TELEMETRY_LOCATION_ALTITUDE -#define AO_TELEMETRY_LOCATION_ALTITUDE(l) ((l)->altitude) +#ifndef AO_GPS_ORIG_ALTITUDE +#define AO_GPS_ORIG_ALTITUDE(l) ((l)->altitude) #endif void @@ -46,7 +46,7 @@ ao_gps_print(__xdata struct ao_gps_orig *gps_data) __reentrant AO_TELEM_GPS_ALTITUDE " %d ", (long) gps_data->latitude, (long) gps_data->longitude, - AO_TELEMETRY_LOCATION_ALTITUDE(gps_data)); + AO_GPS_ORIG_ALTITUDE(gps_data)); if (gps_data->flags & AO_GPS_DATE_VALID) printf(AO_TELEM_GPS_YEAR " %d " diff --git a/src/test/ao_gps_test_ublox.c b/src/test/ao_gps_test_ublox.c index 5ea205d6..83efbb4f 100644 --- a/src/test/ao_gps_test_ublox.c +++ b/src/test/ao_gps_test_ublox.c @@ -59,6 +59,7 @@ struct ao_telemetry_location { typedef int32_t gps_alt_t; #define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) +#define AO_GPS_ORIG_ALTITUDE(l) AO_TELEMETRY_LOCATION_ALTITUDE(l) #define AO_TELEMETRY_LOCATION_SET_ALTITUDE(l,a) (((l)->altitude_high = (a) >> 16), \ ((l)->altitude_low = (a))) -- cgit v1.2.3 From 3f7263f57b1b697d92ed6c3d62956e5bdfc11f24 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 25 Oct 2014 11:20:44 -0700 Subject: altos: Remove old AO_SEND_ALL_BARO bits This was used for testing the original TeleMini which couldn't log data at full speed. Signed-off-by: Keith Packard --- src/kernel/ao.h | 6 ------ src/kernel/ao_telemetry.c | 30 ------------------------------ 2 files changed, 36 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao.h b/src/kernel/ao.h index ad5bbf8e..244421f3 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -518,15 +518,9 @@ struct ao_telemetry_raw_recv { /* Set delay between telemetry reports (0 to disable) */ -#ifdef AO_SEND_ALL_BARO -#define AO_TELEMETRY_INTERVAL_PAD AO_MS_TO_TICKS(100) -#define AO_TELEMETRY_INTERVAL_FLIGHT AO_MS_TO_TICKS(100) -#define AO_TELEMETRY_INTERVAL_RECOVER AO_MS_TO_TICKS(100) -#else #define AO_TELEMETRY_INTERVAL_PAD AO_MS_TO_TICKS(1000) #define AO_TELEMETRY_INTERVAL_FLIGHT AO_MS_TO_TICKS(100) #define AO_TELEMETRY_INTERVAL_RECOVER AO_MS_TO_TICKS(1000) -#endif void ao_telemetry_reset_interval(void); diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 27306a34..5b56d025 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -269,30 +269,6 @@ ao_send_mini(void) #endif /* AO_SEND_MINI */ -#ifdef AO_SEND_ALL_BARO -static uint8_t ao_baro_sample; - -static void -ao_send_baro(void) -{ - uint8_t sample = ao_sample_data; - uint8_t samples = (sample - ao_baro_sample) & (AO_DATA_RING - 1); - - if (samples > 12) { - ao_baro_sample = (ao_baro_sample + (samples - 12)) & (AO_DATA_RING - 1); - samples = 12; - } - telemetry.generic.tick = ao_data_ring[sample].tick; - telemetry.generic.type = AO_TELEMETRY_BARO; - telemetry.baro.samples = samples; - for (sample = 0; sample < samples; sample++) { - telemetry.baro.baro[sample] = ao_data_ring[ao_baro_sample].adc.pres; - ao_baro_sample = ao_data_ring_next(ao_baro_sample); - } - ao_radio_send(&telemetry, sizeof (telemetry)); -} -#endif - static __pdata int8_t ao_telemetry_config_max; static __pdata int8_t ao_telemetry_config_cur; @@ -422,10 +398,6 @@ ao_telemetry(void) if (!(ao_config.radio_enable & AO_RADIO_DISABLE_TELEMETRY)) #endif { -#ifdef AO_SEND_ALL_BARO - ao_send_baro(); -#endif - #if HAS_FLIGHT # ifdef AO_SEND_MEGA ao_send_mega_sensor(); @@ -453,7 +425,6 @@ ao_telemetry(void) ao_send_satellite(); #endif } -#ifndef AO_SEND_ALL_BARO #if HAS_RDF if (ao_rdf && #if HAS_APRS @@ -481,7 +452,6 @@ ao_telemetry(void) ao_aprs_send(); } #endif /* HAS_APRS */ -#endif /* !AO_SEND_ALL_BARO */ time += ao_telemetry_interval; delay = time - ao_time(); if (delay > 0) { -- cgit v1.2.3 From 4d51570ed8776461d084726149923c5be43d622e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 25 Oct 2014 19:56:25 -0700 Subject: altos: Fix up telemetry delay computations With RDF, APRS and telemetry all being sent at varying rates, computing when to send the next radio data is not as simple as sending telemetry and then figuring out whether to send RDF and/or APRS. Fix this by computing times for the next telemetry/rdf/aprs packet, and only sending each when that time has passed. Compute the delay until the next radio activity as the minimum time to any transmission. This also adds code to the config bits to reset the radio times whenever something changes that might affect which radio data to send next. Signed-off-by: Keith Packard --- src/kernel/ao_config.c | 9 ++- src/kernel/ao_telemetry.c | 143 +++++++++++++++++++++++++++++----------------- src/kernel/ao_telemetry.h | 6 ++ 3 files changed, 104 insertions(+), 54 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 6b8a1813..8dab7c42 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -557,10 +557,10 @@ ao_config_radio_rate_set(void) __reentrant } _ao_config_edit_start(); ao_config.radio_rate = ao_cmd_lex_i; + _ao_config_edit_finish(); #if HAS_TELEMETRY ao_telemetry_reset_interval(); #endif - _ao_config_edit_finish(); #if HAS_RADIO_RECV ao_radio_recv_abort(); #endif @@ -684,6 +684,9 @@ ao_config_radio_enable_set(void) __reentrant _ao_config_edit_start(); ao_config.radio_enable = ao_cmd_lex_i; _ao_config_edit_finish(); +#if HAS_TELEMETRY && HAS_RADIO_RATE + ao_telemetry_reset_interval(); +#endif } #endif /* HAS_RADIO */ @@ -735,6 +738,7 @@ ao_config_aprs_set(void) _ao_config_edit_start(); ao_config.aprs_interval = ao_cmd_lex_i; _ao_config_edit_finish(); + ao_telemetry_reset_interval(); } #endif /* HAS_APRS */ @@ -825,6 +829,9 @@ ao_config_tracker_set(void) ao_config.tracker_motion = m; ao_config.tracker_interval = i; _ao_config_edit_finish(); +#if HAS_TELEMETRY + ao_telemetry_reset_interval(); +#endif } #endif /* HAS_TRACKER */ diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 5b56d025..868b3260 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -19,19 +19,32 @@ #include "ao_log.h" #include "ao_product.h" -#ifndef HAS_RDF -#define HAS_RDF 1 -#endif - static __pdata uint16_t ao_telemetry_interval; #if HAS_RADIO_RATE static __xdata uint16_t ao_telemetry_desired_interval; #endif +/* TeleMetrum v1.0 just doesn't have enough space to + * manage the more complicated telemetry scheduling, so + * it loses the ability to disable telem/rdf separately + */ + +#if defined(TELEMETRUM_V_1_0) +#define SIMPLIFY +#endif + +#ifdef SIMPLIFY +#define ao_telemetry_time time +#define RDF_SPACE __pdata +#else +#define RDF_SPACE __xdata +static __pdata uint16_t ao_telemetry_time; +#endif + #if HAS_RDF -static __pdata uint8_t ao_rdf = 0; -static __pdata uint16_t ao_rdf_time; +static RDF_SPACE uint8_t ao_rdf = 0; +static RDF_SPACE uint16_t ao_rdf_time; #endif #if HAS_APRS @@ -308,6 +321,7 @@ ao_send_configuration(void) #if HAS_GPS +static __pdata int8_t ao_telemetry_gps_max; static __pdata int8_t ao_telemetry_loc_cur; static __pdata int8_t ao_telemetry_sat_cur; @@ -324,7 +338,7 @@ ao_send_location(void) telemetry.location.tick = ao_gps_tick; ao_mutex_put(&ao_gps_mutex); ao_radio_send(&telemetry, sizeof (telemetry)); - ao_telemetry_loc_cur = ao_telemetry_config_max; + ao_telemetry_loc_cur = ao_telemetry_gps_max; } } @@ -341,7 +355,7 @@ ao_send_satellite(void) AO_MAX_GPS_TRACKING * sizeof (struct ao_telemetry_satellite_info)); ao_mutex_put(&ao_gps_mutex); ao_radio_send(&telemetry, sizeof (telemetry)); - ao_telemetry_sat_cur = ao_telemetry_config_max; + ao_telemetry_sat_cur = ao_telemetry_gps_max; } } #endif @@ -387,6 +401,7 @@ ao_telemetry(void) while (ao_telemetry_interval == 0) ao_sleep(&telemetry); time = ao_time(); + ao_telemetry_time = time; #if HAS_RDF ao_rdf_time = time; #endif @@ -394,73 +409,85 @@ ao_telemetry(void) ao_aprs_time = time; #endif while (ao_telemetry_interval) { -#if HAS_APRS + time = ao_time() + AO_SEC_TO_TICKS(100); +#ifndef SIMPLIFY if (!(ao_config.radio_enable & AO_RADIO_DISABLE_TELEMETRY)) #endif { -#if HAS_FLIGHT +#ifndef SIMPLIFY + if ( (int16_t) (ao_time() - ao_telemetry_time) >= 0) +#endif + { + ao_telemetry_time = ao_time() + ao_telemetry_interval; # ifdef AO_SEND_MEGA - ao_send_mega_sensor(); - ao_send_mega_data(); + ao_send_mega_sensor(); + ao_send_mega_data(); # endif # ifdef AO_SEND_METRUM - ao_send_metrum_sensor(); - ao_send_metrum_data(); + ao_send_metrum_sensor(); + ao_send_metrum_data(); # endif # ifdef AO_SEND_MINI - ao_send_mini(); + ao_send_mini(); # endif # ifdef AO_TELEMETRY_SENSOR - ao_send_sensor(); + ao_send_sensor(); # endif -#endif /* HAS_FLIGHT */ - #if HAS_COMPANION - if (ao_companion_running) - ao_send_companion(); + if (ao_companion_running) + ao_send_companion(); #endif - ao_send_configuration(); #if HAS_GPS - ao_send_location(); - ao_send_satellite(); + ao_send_location(); + ao_send_satellite(); +#endif + ao_send_configuration(); + } +#ifndef SIMPLIFY + time = ao_telemetry_time; #endif } #if HAS_RDF - if (ao_rdf && -#if HAS_APRS - !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) && -#endif /* HAS_APRS */ - (int16_t) (ao_time() - ao_rdf_time) >= 0) + if (ao_rdf +#ifndef SIMPLIFY + && !(ao_config.radio_enable & AO_RADIO_DISABLE_RDF) +#endif + ) { + if ((int16_t) (ao_time() - ao_rdf_time) >= 0) { #if HAS_IGNITE_REPORT - uint8_t c; -#endif /* HAS_IGNITE_REPORT */ - ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS; + uint8_t c; +#endif + ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS; #if HAS_IGNITE_REPORT - if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter())) - ao_radio_continuity(c); - else -#endif /* HAS_IGNITE_REPORT*/ - ao_radio_rdf(); + if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter())) + ao_radio_continuity(c); + else +#endif + ao_radio_rdf(); + } +#ifndef SIMPLIFY + if ((int16_t) (time - ao_rdf_time) > 0) + time = ao_rdf_time; +#endif } #endif /* HAS_RDF */ #if HAS_APRS - if (ao_config.aprs_interval != 0 && - (int16_t) (ao_time() - ao_aprs_time) >= 0) - { - ao_aprs_time = ao_time() + AO_SEC_TO_TICKS(ao_config.aprs_interval); - ao_aprs_send(); + if (ao_config.aprs_interval != 0) { + if ((int16_t) (ao_time() - ao_aprs_time) >= 0) { + ao_aprs_time = ao_time() + AO_SEC_TO_TICKS(ao_config.aprs_interval); + ao_aprs_send(); + } + if ((int16_t) (time - ao_aprs_time) > 0) + time = ao_aprs_time; } #endif /* HAS_APRS */ - time += ao_telemetry_interval; delay = time - ao_time(); if (delay > 0) { ao_alarm(delay); ao_sleep(&telemetry); ao_clear_alarm(); } - else - time = ao_time(); } } } @@ -517,21 +544,31 @@ ao_telemetry_set_interval(uint16_t interval) ao_telemetry_companion_cur = cur; #endif - ao_telemetry_config_max = AO_SEC_TO_TICKS(5) / interval; -#if HAS_COMPANION - if (ao_telemetry_config_max > cur) - cur++; - ao_telemetry_config_cur = cur; -#endif - #if HAS_GPS - if (ao_telemetry_config_max > cur) + ao_telemetry_gps_max = AO_SEC_TO_TICKS(1) / interval; + if (ao_telemetry_gps_max > cur) cur++; ao_telemetry_loc_cur = cur; - if (ao_telemetry_config_max > cur) + if (ao_telemetry_gps_max > cur) cur++; ao_telemetry_sat_cur = cur; #endif + + ao_telemetry_config_max = AO_SEC_TO_TICKS(5) / interval; + if (ao_telemetry_config_max > cur) + cur++; + ao_telemetry_config_cur = cur; + +#ifndef SIMPLIFY + ao_telemetry_time = +#if HAS_RDF + ao_rdf_time = +#endif +#if HAS_APRS + ao_aprs_time = +#endif + ao_time(); +#endif ao_wakeup(&telemetry); } diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h index 340c388e..711e0d36 100644 --- a/src/kernel/ao_telemetry.h +++ b/src/kernel/ao_telemetry.h @@ -120,6 +120,12 @@ struct ao_telemetry_location { #define HAS_WIDE_GPS 1 #endif +#ifdef HAS_TELEMETRY +#ifndef HAS_RDF +#define HAS_RDF 1 +#endif +#endif + #if HAS_WIDE_GPS typedef int32_t gps_alt_t; #define AO_TELEMETRY_LOCATION_ALTITUDE(l) (((gps_alt_t) (l)->altitude_high << 16) | ((l)->altitude_low)) -- cgit v1.2.3 From f2e5ffd839fe5be99359e4c86a96f03148bac698 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 6 Nov 2014 15:58:42 -0800 Subject: altos: Declare port register type only in arch header Instead of defaulting to 8 bits, explicitly require declaration of the type of the port register for each architecture. Signed-off-by: Keith Packard --- src/attiny/ao_arch.h | 2 ++ src/avr/ao_arch.h | 2 ++ src/cc1111/ao_arch.h | 2 ++ src/kernel/ao.h | 4 ---- 4 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/kernel') diff --git a/src/attiny/ao_arch.h b/src/attiny/ao_arch.h index 8140dd30..6ca12af6 100644 --- a/src/attiny/ao_arch.h +++ b/src/attiny/ao_arch.h @@ -31,6 +31,8 @@ #define AO_STACK_SIZE 116 +#define AO_PORT_TYPE uint8_t + /* Various definitions to make GCC look more like SDCC */ #define ao_arch_naked_declare __attribute__((naked)) diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index d626e830..f8c7f042 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -41,6 +41,8 @@ #define AO_STACK_SIZE 116 #endif +#define AO_PORT_TYPE uint8_t + /* Various definitions to make GCC look more like SDCC */ #define ao_arch_naked_declare __attribute__((naked)) diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index fcac331b..b3c6b5dc 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -40,6 +40,8 @@ #define AO_STACK_END 0xfe #define AO_STACK_SIZE (AO_STACK_END - AO_STACK_START + 1) +#define AO_PORT_TYPE uint8_t + #define ao_arch_reboot() do { \ WDCTL = WDCTL_EN | WDCTL_MODE_WATCHDOG | WDCTL_INT_64; \ ao_delay(AO_SEC_TO_TICKS(2)); \ diff --git a/src/kernel/ao.h b/src/kernel/ao.h index 244421f3..48b06490 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -43,10 +43,6 @@ #define HAS_TASK 1 #endif -#ifndef AO_PORT_TYPE -#define AO_PORT_TYPE uint8_t -#endif - typedef AO_PORT_TYPE ao_port_t; #if HAS_TASK -- cgit v1.2.3 From d3dd45b060c996153ff8195bd371e9e1f3b15efb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 6 Nov 2014 16:02:47 -0800 Subject: altos: Use other TeleDongle LED for CRC-invalid packet reporting Instead of blinking out some fake-o RSSI indication, just blink the red LED when a packet with a bad CRC is received. Signed-off-by: Keith Packard --- src/kernel/ao.h | 1 + src/kernel/ao_monitor.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/kernel') diff --git a/src/kernel/ao.h b/src/kernel/ao.h index 48b06490..16d600aa 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -652,6 +652,7 @@ union ao_monitor { extern __xdata union ao_monitor ao_monitor_ring[AO_MONITOR_RING]; #define ao_monitor_ring_next(n) (((n) + 1) & (AO_MONITOR_RING - 1)) +#define ao_monitor_ring_prev(n) (((n) - 1) & (AO_MONITOR_RING - 1)) extern __data uint8_t ao_monitoring; extern __data uint8_t ao_monitor_head; diff --git a/src/kernel/ao_monitor.c b/src/kernel/ao_monitor.c index 2d75c41c..cba0d80a 100644 --- a/src/kernel/ao_monitor.c +++ b/src/kernel/ao_monitor.c @@ -94,9 +94,18 @@ __xdata struct ao_task ao_monitor_blink_task; void ao_monitor_blink(void) { +#ifdef AO_MONITOR_BAD + uint8_t *recv; +#endif for (;;) { ao_sleep(DATA_TO_XDATA(&ao_monitor_head)); - ao_led_for(AO_MONITOR_LED, AO_MS_TO_TICKS(100)); +#ifdef AO_MONITOR_BAD + recv = (uint8_t *) &ao_monitor_ring[ao_monitor_ring_prev(ao_monitor_head)]; + if (ao_monitoring && !(recv[ao_monitoring + 1] & AO_RADIO_STATUS_CRC_OK)) + ao_led_for(AO_MONITOR_BAD, AO_MS_TO_TICKS(100)); + else +#endif + ao_led_for(AO_MONITOR_LED, AO_MS_TO_TICKS(100)); } } #endif -- cgit v1.2.3 From 54f7ab842a8cba3003cd5a9deb2515151263ca2e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 16 Nov 2014 16:38:12 -0800 Subject: altos: Allow TeleMega to be built without MPU6000 Robert Braibish's board has a dead MPU6000; this fix lets the TeleMega firmware build without that driver so the rest of the board could be verified. Signed-off-by: Keith Packard --- src/kernel/ao_telemetry.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/kernel') diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 868b3260..e2197f7a 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -133,7 +133,9 @@ ao_send_mega_sensor(void) telemetry.generic.tick = packet->tick; telemetry.generic.type = AO_TELEMETRY_MEGA_SENSOR; +#if HAS_MPU6000 telemetry.mega_sensor.orient = ao_sample_orient; +#endif telemetry.mega_sensor.accel = ao_data_accel(packet); telemetry.mega_sensor.pres = ao_data_pres(packet); telemetry.mega_sensor.temp = ao_data_temp(packet); -- cgit v1.2.3 From e05e0c6b71a1df65f188e00622e9632eb27510fd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 16 Jan 2015 22:09:26 +1300 Subject: Set version to 1.5.9.1 --- configure.ac | 2 +- icon/application-vnd.altusmetrum.micropeak.svg | 1 - src/kernel/ao_config.c | 7 +- src/lpc/ao_arch.h | 2 + src/lpc/ao_arch_funcs.h | 6 + src/lpc/ao_usb_lpc.c | 76 +++++++--- src/usbtrng/ao_pins.h | 2 + src/usbtrng/ao_usbtrng.c | 195 ++++++++++++++++++++++++- 8 files changed, 264 insertions(+), 27 deletions(-) delete mode 120000 icon/application-vnd.altusmetrum.micropeak.svg (limited to 'src/kernel') diff --git a/configure.ac b/configure.ac index a38ef092..2c7b19c5 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.5.9.0) +AC_INIT([altos], 1.5.9.1) AC_CONFIG_SRCDIR([src/kernel/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE diff --git a/icon/application-vnd.altusmetrum.micropeak.svg b/icon/application-vnd.altusmetrum.micropeak.svg deleted file mode 120000 index 6efd3200..00000000 --- a/icon/application-vnd.altusmetrum.micropeak.svg +++ /dev/null @@ -1 +0,0 @@ -altusmetrum-micropeak.svg \ No newline at end of file diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 8dab7c42..83a8cd77 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -388,6 +388,7 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant uint16_t i; int32_t accel_total; uint8_t cal_data_ring; + int16_t min = 32767, max = -32768; #if HAS_GYRO int32_t accel_along_total = 0; int32_t accel_across_total = 0; @@ -405,7 +406,10 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant while (i) { ao_sleep(DATA_TO_XDATA(&ao_sample_data)); while (i && cal_data_ring != ao_sample_data) { - accel_total += (int32_t) ao_data_accel(&ao_data_ring[cal_data_ring]); + int16_t v = ao_data_accel(&ao_data_ring[cal_data_ring]); + accel_total += (int32_t) v; + if (v < min) min = v; + if (v > max) max = v; #if HAS_GYRO accel_along_total += (int32_t) ao_data_along(&ao_data_ring[cal_data_ring]); accel_across_total += (int32_t) ao_data_across(&ao_data_ring[cal_data_ring]); @@ -420,6 +424,7 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant accel_cal_across = accel_across_total >> ACCEL_CALIBRATE_SHIFT; accel_cal_through = accel_through_total >> ACCEL_CALIBRATE_SHIFT; #endif + printf ("total %d min %d max %d\n", accel_total, min, max); return accel_total >> ACCEL_CALIBRATE_SHIFT; } diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index 42faf06f..1b4c61f2 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -124,6 +124,8 @@ ao_adc_init(void); #define AO_USB_OUT_EP 2 #define AO_USB_IN_EP 3 +extern uint8_t ao_usb_out_avail; + void ao_serial_init(void); diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index fbe641d8..b963d3ab 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -249,4 +249,10 @@ static inline void ao_arch_start_scheduler(void) { asm("isb"); } +void * +ao_usb_alloc(uint16_t len); + +void +ao_usb_write(void *block, int len); + #endif /* _AO_ARCH_FUNCS_H_ */ diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 12f5d8e6..499de9e9 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -80,14 +80,12 @@ static uint8_t *ao_usb_ep0_setup_buffer; static uint8_t *ao_usb_ep0_rx_buffer; /* Pointer to bulk data tx/rx buffers in USB memory */ -static uint8_t *ao_usb_in_tx_buffer; -static uint8_t *ao_usb_out_rx_buffer; - -/* Our data buffers */ -static uint8_t ao_usb_tx_buffer[AO_USB_IN_SIZE]; +static uint8_t *ao_usb_in_tx_buffer[2]; +static uint8_t ao_usb_in_tx_cur; static uint8_t ao_usb_tx_count; -static uint8_t ao_usb_rx_buffer[AO_USB_OUT_SIZE]; +static uint8_t *ao_usb_out_rx_buffer[2]; +static uint8_t ao_usb_out_rx_cur; static uint8_t ao_usb_rx_count, ao_usb_rx_pos; extern struct lpc_usb_endpoint lpc_usb_endpoint; @@ -108,7 +106,7 @@ static uint8_t ao_usb_in_pending; /* Marks when an OUT packet has been received by the hardware * but not pulled to the shadow buffer. */ -static uint8_t ao_usb_out_avail; +uint8_t ao_usb_out_avail; uint8_t ao_usb_running; static uint8_t ao_usb_configuration; @@ -362,12 +360,16 @@ ao_usb_set_configuration(void) /* Set up the INT end point */ ao_usb_enable_epn(AO_USB_INT_EP, 0, NULL, 0, NULL); - + /* Set up the OUT end point */ - ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, &ao_usb_out_rx_buffer, 0, NULL); + ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE * 2, &ao_usb_out_rx_buffer[0], 0, NULL); + ao_usb_out_rx_buffer[1] = ao_usb_out_rx_buffer[0] + AO_USB_OUT_SIZE; + ao_usb_out_rx_cur = 0; /* Set up the IN end point */ - ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE, &ao_usb_in_tx_buffer); + ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE * 2, &ao_usb_in_tx_buffer[0]); + ao_usb_in_tx_buffer[1] = ao_usb_in_tx_buffer[0] + AO_USB_IN_SIZE; + ao_usb_in_tx_cur = 0; ao_usb_running = 1; } @@ -716,8 +718,8 @@ _ao_usb_in_send(void) ao_usb_in_pending = 1; if (ao_usb_tx_count != AO_USB_IN_SIZE) ao_usb_in_flushed = 1; - memcpy(ao_usb_in_tx_buffer, ao_usb_tx_buffer, ao_usb_tx_count); - ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP), ao_usb_in_tx_buffer, ao_usb_tx_count); + ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP), ao_usb_in_tx_buffer[ao_usb_in_tx_cur], ao_usb_tx_count); + ao_usb_in_tx_cur = 1 - ao_usb_in_tx_cur; ao_usb_tx_count = 0; _tx_dbg0("in_send end"); } @@ -769,10 +771,12 @@ ao_usb_putchar(char c) ao_arch_block_interrupts(); _ao_usb_in_wait(); + ao_arch_release_interrupts(); ao_usb_in_flushed = 0; - ao_usb_tx_buffer[ao_usb_tx_count++] = (uint8_t) c; + ao_usb_in_tx_buffer[ao_usb_in_tx_cur][ao_usb_tx_count++] = (uint8_t) c; + ao_arch_block_interrupts(); /* Send the packet when full */ if (ao_usb_tx_count == AO_USB_IN_SIZE) { _tx_dbg0("putchar full"); @@ -782,6 +786,43 @@ ao_usb_putchar(char c) ao_arch_release_interrupts(); } +void * +ao_usb_alloc(uint16_t len) +{ + return ao_usb_alloc_sram(len); +} + +void +ao_usb_write(void *block, int len) +{ + uint8_t *b = block; + int this_time; + + if (!ao_usb_running) + return; + + if (!ao_usb_in_flushed) + ao_usb_flush(); + + while (len) { + ao_usb_in_flushed = 0; + this_time = AO_USB_IN_SIZE; + if (this_time > len) + this_time = len; + b += this_time; + len -= this_time; + + ao_arch_block_interrupts(); + while (ao_usb_in_pending) + ao_sleep(&ao_usb_in_pending); + ao_usb_in_pending = 1; + if (this_time != AO_USB_IN_SIZE) + ao_usb_in_flushed = 1; + ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP), b, this_time); + ao_arch_release_interrupts(); + } +} + static void _ao_usb_out_recv(void) { @@ -792,13 +833,12 @@ _ao_usb_out_recv(void) _rx_dbg1("out_recv count", ao_usb_rx_count); debug ("recv %d\n", ao_usb_rx_count); - debug_data("Fill OUT len %d:", ao_usb_rx_count); - memcpy(ao_usb_rx_buffer, ao_usb_out_rx_buffer, ao_usb_rx_count); - debug_data("\n"); + debug_data("Fill OUT len %d\n", ao_usb_rx_count); ao_usb_rx_pos = 0; + ao_usb_rx_out_cur = 1 - ao_usb_rx_out_cur; /* ACK the packet */ - ao_usb_set_epn_out(AO_USB_OUT_EP, ao_usb_out_rx_buffer, AO_USB_OUT_SIZE); + ao_usb_set_epn_out(AO_USB_OUT_EP, ao_usb_out_rx_buffer[1-ao_usb_rx_out_cur], AO_USB_OUT_SIZE); } int @@ -823,7 +863,7 @@ _ao_usb_pollchar(void) } /* Pull a character out of the fifo */ - c = ao_usb_rx_buffer[ao_usb_rx_pos++]; + c = ao_usb_rx_buffer[ao_usb_rx_out_cur][ao_usb_rx_pos++]; return c; } diff --git a/src/usbtrng/ao_pins.h b/src/usbtrng/ao_pins.h index b1fa6eb9..0f2b1ea6 100644 --- a/src/usbtrng/ao_pins.h +++ b/src/usbtrng/ao_pins.h @@ -71,3 +71,5 @@ */ #define HAS_SCK1 0 #define HAS_MOSI1 0 + +#define AO_ADC_6 1 diff --git a/src/usbtrng/ao_usbtrng.c b/src/usbtrng/ao_usbtrng.c index 6b4d20fe..66e12337 100644 --- a/src/usbtrng/ao_usbtrng.c +++ b/src/usbtrng/ao_usbtrng.c @@ -18,7 +18,53 @@ #include #define AO_TRNG_SPI_BUS 1 -#define AO_TRNG_SPI_SPEED AO_SPI_SPEED_250kHz + +static uint32_t spi_speed = AO_SPI_SPEED_4MHz; + +#define AO_TRNG_SPI_BUF 1024 + +#if 0 + +static uint8_t *spi_buf; +static uint8_t *spi_head, *spi_tail; +static uint8_t spi_wakeup; + +static void +ao_trng_run(void) +{ + int this_time; + uint8_t *end; + + if (!spi_buf) + spi_buf = ao_usb_alloc(AO_TRNG_SPI_BUF); + flush(); + ao_spi_get(AO_TRNG_SPI_BUS, spi_speed); + spi_tail = spi_buf; + spi_head = spi_buf; + ao_spi_recv_ring_start(spi_buf, AO_TRNG_SPI_BUF, &spi_head, &spi_tail, &spi_wakeup, AO_TRNG_SPI_BUS); + while (!ao_usb_out_avail) { + ao_arch_block_interrupts(); + while (spi_head == spi_tail) { + spi_wakeup = 0; + ao_sleep(&spi_wakeup); + } + ao_arch_release_interrupts(); + if (spi_tail > spi_head) + end = spi_buf + AO_TRNG_SPI_BUF; + else + end = spi_head; + this_time = end - spi_tail; + if (this_time > 64) + this_time = 64; + ao_usb_write(spi_tail, this_time); + spi_tail += this_time; + if (spi_tail == spi_buf + AO_TRNG_SPI_BUF) + spi_tail = spi_buf; + } + ao_spi_put(AO_TRNG_SPI_BUS); + getchar(); +} + static void ao_trng_test(void) @@ -26,16 +72,153 @@ ao_trng_test(void) static uint8_t random[32]; uint8_t i; - ao_spi_get(AO_TRNG_SPI_BUS, AO_TRNG_SPI_SPEED); + ao_spi_get(AO_TRNG_SPI_BUS, spi_speed); ao_spi_recv(random, sizeof (random), AO_TRNG_SPI_BUS); ao_spi_put(AO_TRNG_SPI_BUS); for (i = 0; i < sizeof (random); i++) printf (" %02x", random[i]); printf ("\n"); } +#endif + +#define ADC_RING_SIZE 512 + +static uint8_t *adc_ring; +static uint16_t adc_head, adc_tail; +static uint16_t adc_wake; + +void lpc_adc_isr(void) +{ + uint16_t avail; + uint16_t this, next; + + this = adc_head; + next = (this + 1) & (ADC_RING_SIZE - 1); + if (next == adc_tail) { + lpc_adc.inten = 0; + return; + } + adc_ring[this] = lpc_adc.dr[6] >> 8; + adc_head = next; + + /* If there are enough entries, wake up any waiters + */ + avail = (next - adc_tail) & (ADC_RING_SIZE - 1); + if (avail >= adc_wake) { + adc_wake = 0; + ao_wakeup(&adc_wake); + } +} + +#define AO_ADC_CLKDIV (AO_LPC_SYSCLK / 450000) + +static void +ao_trng_adc_init(void) +{ + adc_ring = ao_usb_alloc(ADC_RING_SIZE); + + lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_ADC); + lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_ADC_PD); + + /* Enable interrupt when AO_ADC_6 is complete */ + lpc_adc.inten = 0; + + lpc_nvic_set_enable(LPC_ISR_ADC_POS); + lpc_nvic_set_priority(LPC_ISR_ADC_POS, AO_LPC_NVIC_CLOCK_PRIORITY); + +#if AO_ADC_0 + ao_enable_analog(0, 11, 0); +#endif +#if AO_ADC_1 + ao_enable_analog(0, 12, 1); +#endif +#if AO_ADC_2 + ao_enable_analog(0, 13, 2); +#endif +#if AO_ADC_3 + ao_enable_analog(0, 14, 3); +#endif +#if AO_ADC_4 + ao_enable_analog(0, 15, 4); +#endif +#if AO_ADC_5 + ao_enable_analog(0, 16, 5); +#endif +#if AO_ADC_6 + ao_enable_analog(0, 22, 6); +#endif +#if AO_ADC_7 + ao_enable_analog(0, 23, 7); +#endif + + lpc_adc.cr = ((1 << (LPC_ADC_CR_SEL + 6)) | + (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) | + (1 << LPC_ADC_CR_BURST) | + (LPC_ADC_CR_CLKS_9 << LPC_ADC_CR_CLKS)); +} + +static void +ao_trng_adc_dump(void) +{ + int i; + + while (((adc_head - adc_tail) & (ADC_RING_SIZE - 1)) < 16) { + lpc_adc.inten = (1 << (LPC_ADC_INTEN_ADINTEN + 6)); + adc_wake = 16; + ao_sleep(&adc_wake); + } + printf("adc_head %d tail %d\n", adc_head, adc_tail); + + for (i = 0; i < 16; i++) { + printf(" %4d", adc_ring[adc_tail]); + adc_tail = (adc_tail + 1) & (ADC_RING_SIZE - 1); + } + printf("\n"); + lpc_adc.inten = 0; +} + +static void +ao_trng_run(void) +{ + uint16_t this_time; + flush(); + + while (!ao_usb_out_avail) { + ao_arch_block_interrupts(); + while (((adc_head - adc_tail) & (ADC_RING_SIZE - 1)) < 64) { + lpc_adc.inten = (1 << (LPC_ADC_INTEN_ADINTEN + 6)); + adc_wake = 64; + ao_sleep(&adc_wake); + } + ao_arch_release_interrupts(); + + this_time = ADC_RING_SIZE - adc_tail; + if (this_time > 64) + this_time = 64; + ao_usb_write(&adc_ring[adc_tail], this_time); + adc_tail = (adc_tail + this_time) & (ADC_RING_SIZE - 1); + } + lpc_adc.inten = 0; +} + +static void +ao_trng_speed(void) +{ + ao_cmd_decimal(); + + if (ao_cmd_lex_u32 == 0 || ao_cmd_status != ao_cmd_success) { + ao_cmd_status = ao_cmd_success; + printf ("Current spi speed %d\n", spi_speed); + } else { + spi_speed = ao_cmd_lex_u32; + } +} static const struct ao_cmds ao_trng_cmds[] = { - { ao_trng_test, "R\0Dump some random numbers" }, +// { ao_trng_test, "R\0Dump some random numbers" }, + { ao_trng_run, "s\0Send random bits until char" }, + { ao_trng_speed, "S \0Set SPI speed (48MHz/speed)" }, + { ao_trng_adc_dump, "a\0Dump ADC data" }, { 0, NULL } }; @@ -46,15 +229,15 @@ main(void) ao_task_init(); ao_timer_init(); - ao_spi_init(); +// ao_spi_init(); ao_usb_init(); + ao_trng_adc_init(); + ao_serial_init(); ao_led_init(LEDS_AVAILABLE); - ao_led_on(AO_LED_GREEN); - ao_cmd_init(); ao_cmd_register(ao_trng_cmds); -- cgit v1.2.3 From 291eec859606b73b43072cd2debfbb92659e0d95 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 22 Jan 2015 20:34:43 -0800 Subject: altos: Get rid of some accidental debug code I was debugging the accelerometer calibration code and left some printfs in it, which made TM run out of flash space. Signed-off-by: Keith Packard --- src/kernel/ao_config.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 83a8cd77..8dab7c42 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -388,7 +388,6 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant uint16_t i; int32_t accel_total; uint8_t cal_data_ring; - int16_t min = 32767, max = -32768; #if HAS_GYRO int32_t accel_along_total = 0; int32_t accel_across_total = 0; @@ -406,10 +405,7 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant while (i) { ao_sleep(DATA_TO_XDATA(&ao_sample_data)); while (i && cal_data_ring != ao_sample_data) { - int16_t v = ao_data_accel(&ao_data_ring[cal_data_ring]); - accel_total += (int32_t) v; - if (v < min) min = v; - if (v > max) max = v; + accel_total += (int32_t) ao_data_accel(&ao_data_ring[cal_data_ring]); #if HAS_GYRO accel_along_total += (int32_t) ao_data_along(&ao_data_ring[cal_data_ring]); accel_across_total += (int32_t) ao_data_across(&ao_data_ring[cal_data_ring]); @@ -424,7 +420,6 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant accel_cal_across = accel_across_total >> ACCEL_CALIBRATE_SHIFT; accel_cal_through = accel_through_total >> ACCEL_CALIBRATE_SHIFT; #endif - printf ("total %d min %d max %d\n", accel_total, min, max); return accel_total >> ACCEL_CALIBRATE_SHIFT; } -- cgit v1.2.3 From 0e7d1c89fea98eabca738f10cbfebec631be3bb7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 24 Jan 2015 11:18:59 -0800 Subject: altos: Add support for TeleBT v3.0 Add support to the BTM driver for non-CC1111 interrupts Add HW flow control to STM serial driver Signed-off-by: Keith Packard --- src/Makefile | 3 +- src/drivers/ao_btm.c | 52 ++++++++- src/kernel/ao_serial.h | 12 ++ src/stm/ao_led.c | 2 +- src/stm/ao_serial_stm.c | 59 +++++++++- src/telebt-v3.0/ao_pins.h | 202 +++++++++++++++++++++++++++++++++ src/telebt-v3.0/ao_telebt.c | 57 ++++++++++ src/telebt-v3.0/flash-loader/ao_pins.h | 34 ++++++ 8 files changed, 410 insertions(+), 11 deletions(-) create mode 100644 src/telebt-v3.0/ao_pins.h create mode 100644 src/telebt-v3.0/ao_telebt.c create mode 100644 src/telebt-v3.0/flash-loader/ao_pins.h (limited to 'src/kernel') diff --git a/src/Makefile b/src/Makefile index a5d7b0f3..c8563c9d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -36,7 +36,8 @@ ARMM3DIRS=\ telelco-v0.2 telelco-v0.2/flash-loader \ telescience-v0.2 telescience-v0.2/flash-loader \ teledongle-v1.9 teledongle-v1.9/flash-loader \ - teleballoon-v2.0 + teleballoon-v2.0 \ + telebt-v3.0 telebt-v3.0/flash-loader ARMM0DIRS=\ easymini-v1.0 easymini-v1.0/flash-loader diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c index 3b6028a0..9ea638ba 100644 --- a/src/drivers/ao_btm.c +++ b/src/drivers/ao_btm.c @@ -16,13 +16,16 @@ */ #include "ao.h" +#ifdef AO_BTM_INT_PORT +#include +#endif #ifndef ao_serial_btm_getchar #define ao_serial_btm_putchar ao_serial1_putchar #define _ao_serial_btm_pollchar _ao_serial1_pollchar +#define _ao_serial_btm_sleep() ao_sleep((void *) &ao_serial1_rx_fifo) #define ao_serial_btm_set_speed ao_serial1_set_speed #define ao_serial_btm_drain ao_serial1_drain -#define ao_serial_btm_rx_fifo ao_serial1_rx_fifo #endif int8_t ao_btm_stdio; @@ -125,7 +128,7 @@ ao_btm_getchar(void) ao_arch_block_interrupts(); while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN) { ao_alarm(AO_MS_TO_TICKS(10)); - c = ao_sleep(&ao_serial_btm_rx_fifo); + c = _ao_serial_btm_sleep(); ao_clear_alarm(); if (c) { c = AO_READ_AGAIN; @@ -146,6 +149,7 @@ ao_btm_get_line(void) { uint8_t ao_btm_reply_len = 0; int c; + uint8_t l; while ((c = ao_btm_getchar()) != AO_READ_AGAIN) { ao_btm_log_in_char(c); @@ -154,8 +158,8 @@ ao_btm_get_line(void) if (c == '\r' || c == '\n') break; } - for (c = ao_btm_reply_len; c < sizeof (ao_btm_reply);) - ao_btm_reply[c++] = '\0'; + for (l = ao_btm_reply_len; l < sizeof (ao_btm_reply);) + ao_btm_reply[l++] = '\0'; return ao_btm_reply_len; } @@ -214,7 +218,7 @@ ao_btm_string(__code char *cmd) { char c; - while (c = *cmd++) + while ((c = *cmd++) != '\0') ao_btm_putchar(c); } @@ -263,6 +267,12 @@ ao_btm_try_speed(uint8_t speed) void ao_btm(void) { +#ifdef AO_BTM_RESET_PORT + ao_gpio_set(AO_BTM_RESET_PORT, AO_BTM_RESET_PIN, AO_BTM_RESET, 0); + ao_delay(AO_MS_TO_TICKS(20)); + ao_gpio_set(AO_BTM_RESET_PORT, AO_BTM_RESET_PIN, AO_BTM_RESET, 1); +#endif + /* * Wait for the bluetooth device to boot */ @@ -316,6 +326,7 @@ __xdata struct ao_task ao_btm_task; #define BT_PDIR P2DIR #define BT_PINP P2INP #define BT_IEN2_PIE IEN2_P2IE +#define BT_CC1111 1 #endif #if BT_LINK_ON_P1 #define BT_PICTL_ICON PICTL_P1ICON @@ -323,11 +334,13 @@ __xdata struct ao_task ao_btm_task; #define BT_PDIR P1DIR #define BT_PINP P1INP #define BT_IEN2_PIE IEN2_P1IE +#define BT_CC1111 1 #endif void ao_btm_check_link() { +#if BT_CC1111 ao_arch_critical( /* Check the pin and configure the interrupt detector to wait for the * pin to flip the other way @@ -340,8 +353,10 @@ ao_btm_check_link() PICTL &= ~BT_PICTL_ICON; } ); +#endif } +#if BT_CC1111 void ao_btm_isr(void) #if BT_LINK_ON_P1 @@ -357,6 +372,16 @@ ao_btm_isr(void) } BT_PIFG = 0; } +#endif + +#ifdef AO_BTM_INT_PORT +void +ao_btm_isr(void) +{ + ao_btm_check_link(); + ao_wakeup(&ao_btm_connected); +} +#endif void ao_btm_init (void) @@ -365,6 +390,18 @@ ao_btm_init (void) ao_serial_btm_set_speed(AO_SERIAL_SPEED_19200); +#ifdef AO_BTM_RESET_PORT + ao_enable_output(AO_BTM_RESET_PORT,AO_BTM_RESET_PIN,AO_BTM_RESET,0); +#endif + +#ifdef AO_BTM_INT_PORT + ao_enable_port(AO_BTM_INT_PORT); + ao_exti_setup(AO_BTM_INT_PORT, AO_BTM_INT_PIN, + AO_EXTI_MODE_FALLING|AO_EXTI_MODE_RISING|AO_EXTI_PRIORITY_LOW, + ao_btm_isr); +#endif + +#if BT_CC1111 #if BT_LINK_ON_P1 /* * Configure ser reset line @@ -386,10 +423,15 @@ ao_btm_init (void) /* Enable interrupts */ IEN2 |= BT_IEN2_PIE; +#endif /* Check current pin state */ ao_btm_check_link(); +#ifdef AO_BTM_INT_PORT + ao_exti_enable(AO_BTM_INT_PORT, AO_BTM_INT_PIN); +#endif + #if BT_LINK_ON_P2 /* Eable the pin interrupt */ PICTL |= PICTL_P2IEN; diff --git a/src/kernel/ao_serial.h b/src/kernel/ao_serial.h index baf213c0..dbc9f8e4 100644 --- a/src/kernel/ao_serial.h +++ b/src/kernel/ao_serial.h @@ -34,6 +34,9 @@ ao_serial0_getchar(void); int _ao_serial0_pollchar(void); +uint8_t +_ao_serial0_sleep(void); + void ao_serial0_putchar(char c); @@ -54,6 +57,9 @@ ao_serial1_getchar(void); int _ao_serial1_pollchar(void); +uint8_t +_ao_serial1_sleep(void); + void ao_serial1_putchar(char c); @@ -74,6 +80,9 @@ ao_serial2_getchar(void); int _ao_serial2_pollchar(void); +uint8_t +_ao_serial2_sleep(void); + void ao_serial2_putchar(char c); @@ -94,6 +103,9 @@ ao_serial3_getchar(void); int _ao_serial3_pollchar(void); +uint8_t +_ao_serial3_sleep(void); + void ao_serial3_putchar(char c); diff --git a/src/stm/ao_led.c b/src/stm/ao_led.c index 0acab106..9b61cf62 100644 --- a/src/stm/ao_led.c +++ b/src/stm/ao_led.c @@ -86,7 +86,7 @@ ao_led_for(uint16_t colors, uint16_t ticks) __reentrant stm_moder_set(port, bit, STM_MODER_OUTPUT); \ stm_otyper_set(port, bit, STM_OTYPER_PUSH_PULL); \ } while (0) - + void ao_led_init(uint16_t enable) { diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c index 2133c584..e356b944 100644 --- a/src/stm/ao_serial_stm.c +++ b/src/stm/ao_serial_stm.c @@ -63,7 +63,7 @@ int _ao_usart_pollchar(struct ao_stm_usart *usart) { int c; - + if (ao_fifo_empty(usart->rx_fifo)) c = AO_READ_AGAIN; else { @@ -85,6 +85,12 @@ ao_usart_getchar(struct ao_stm_usart *usart) return (char) c; } +static inline uint8_t +_ao_usart_sleep(struct ao_stm_usart *usart) +{ + return ao_sleep(&usart->rx_fifo); +} + void ao_usart_putchar(struct ao_stm_usart *usart, char c) { @@ -179,6 +185,13 @@ ao_usart_init(struct ao_stm_usart *usart) ao_usart_set_speed(usart, AO_SERIAL_SPEED_9600); } +void +ao_usart_set_flow(struct ao_stm_usart *usart) +{ + usart->reg->cr3 |= ((1 << STM_USART_CR3_CTSE) | + (1 << STM_USART_CR3_RTSE)); +} + #if HAS_SERIAL_1 struct ao_stm_usart ao_stm_usart1; @@ -203,6 +216,18 @@ _ao_serial1_pollchar(void) return _ao_usart_pollchar(&ao_stm_usart1); } +uint8_t +_ao_serial1_sleep(void) +{ + return _ao_usart_sleep(&ao_stm_usart1); +} + +void +ao_serial1_drain(void) +{ + ao_usart_drain(&ao_stm_usart1); +} + void ao_serial1_set_speed(uint8_t speed) { @@ -234,6 +259,18 @@ _ao_serial2_pollchar(void) return _ao_usart_pollchar(&ao_stm_usart2); } +uint8_t +_ao_serial2_sleep(void) +{ + return _ao_usart_sleep(&ao_stm_usart2); +} + +void +ao_serial2_drain(void) +{ + ao_usart_drain(&ao_stm_usart2); +} + void ao_serial2_set_speed(uint8_t speed) { @@ -265,6 +302,12 @@ _ao_serial3_pollchar(void) return _ao_usart_pollchar(&ao_stm_usart3); } +uint8_t +_ao_serial3_sleep(void) +{ + return _ao_usart_sleep(&ao_stm_usart3); +} + void ao_serial3_set_speed(uint8_t speed) { @@ -324,21 +367,31 @@ ao_serial_init(void) stm_afr_set(&stm_gpioa, 2, STM_AFR_AF7); stm_afr_set(&stm_gpioa, 3, STM_AFR_AF7); +#if USE_SERIAL_2_FLOW + stm_afr_set(&stm_gpioa, 0, STM_AFR_AF7); + stm_afr_set(&stm_gpioa, 1, STM_AFR_AF7); +#endif #else #if SERIAL_2_PD5_PD6 stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); stm_afr_set(&stm_gpiod, 5, STM_AFR_AF7); stm_afr_set(&stm_gpiod, 6, STM_AFR_AF7); +#if USE_SERIAL_2_FLOW +#error "Don't know how to set flowcontrol for serial 2 on PD" +#endif #else #error "No SERIAL_2 port configuration specified" -#endif +#endif #endif /* Enable USART */ stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_USART2EN); ao_stm_usart2.reg = &stm_usart2; ao_usart_init(&ao_stm_usart2); +#if USE_SERIAL_2_FLOW + ao_usart_set_flow(&ao_stm_usart2); +#endif stm_nvic_set_enable(STM_ISR_USART2_POS); stm_nvic_set_priority(STM_ISR_USART2_POS, 4); @@ -393,5 +446,3 @@ ao_serial_init(void) #endif #endif } - - diff --git a/src/telebt-v3.0/ao_pins.h b/src/telebt-v3.0/ao_pins.h new file mode 100644 index 00000000..0d03f94d --- /dev/null +++ b/src/telebt-v3.0/ao_pins.h @@ -0,0 +1,202 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define HAS_TASK_QUEUE 1 + +/* 8MHz High speed external crystal */ +#define AO_HSE 8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL 12 +#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV 3 +#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER 2 +#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER 2 +#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_SERIAL_1 0 +#define USE_SERIAL_1_STDIN 0 +#define SERIAL_1_PB6_PB7 0 +#define SERIAL_1_PA9_PA10 1 + +#define HAS_SERIAL_2 1 +#define USE_SERIAL_2_STDIN 0 +#define USE_SERIAL_2_FLOW 1 +#define SERIAL_2_PA2_PA3 1 +#define SERIAL_2_PD5_PD6 0 + +#define HAS_SERIAL_3 1 +#define USE_SERIAL_3_STDIN 0 +#define SERIAL_3_PB10_PB11 1 +#define SERIAL_3_PC10_PC11 0 +#define SERIAL_3_PD8_PD9 0 + +#define AO_CONFIG_MAX_SIZE 1024 + +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 1 +#define USE_STORAGE_CONFIG 0 +#define HAS_USB 1 +#define HAS_BEEP 0 +#define HAS_BATTERY_REPORT 0 +#define HAS_RADIO 1 +#define HAS_TELEMETRY 0 +#define HAS_APRS 0 +#define HAS_ACCEL 0 + +#define HAS_SPI_1 1 +#define SPI_1_PA5_PA6_PA7 1 /* CC1200 */ +#define SPI_1_PB3_PB4_PB5 0 +#define SPI_1_PE13_PE14_PE15 0 +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_SPI_2 0 +#define SPI_2_PB13_PB14_PB15 0 +#define SPI_2_PD1_PD3_PD4 0 +#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_I2C_1 0 +#define I2C_1_PB8_PB9 0 + +#define HAS_I2C_2 0 +#define I2C_2_PB10_PB11 0 + +#define PACKET_HAS_SLAVE 0 +#define PACKET_HAS_MASTER 1 + +#define LOW_LEVEL_DEBUG 0 + +#define LED_PORT_0_ENABLE STM_RCC_AHBENR_GPIOAEN +#define LED_PORT_1_ENABLE STM_RCC_AHBENR_GPIOCEN +#define LED_PORT_0 (&stm_gpioa) +#define LED_PORT_1 (&stm_gpioc) +#define LED_PORT_0_SHIFT 0 +#define LED_PORT_1_SHIFT 0 +#define LED_PIN_RED (4 + LED_PORT_0_SHIFT) +#define LED_PIN_BLUE (15 + LED_PORT_1_SHIFT) +#define AO_LED_RED (1 << LED_PIN_RED) +#define AO_LED_BLUE (1 << LED_PIN_BLUE) +#define LED_PORT_0_MASK (AO_LED_RED) +#define LED_PORT_1_MASK (AO_LED_BLUE) +#define AO_BT_LED AO_LED_BLUE + +#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_BLUE) + +#define HAS_GPS 0 +#define HAS_FLIGHT 0 +#define HAS_ADC 1 +#define HAS_ADC_TEMP 0 +#define HAS_LOG 0 + +/* + * ADC + */ +#define AO_DATA_RING 32 +#define AO_ADC_NUM_SENSE 2 + +struct ao_adc { + int16_t v_batt; +}; + +#define AO_ADC_DUMP(p) \ + printf("tick: %5u %5d batt: %5d\n", \ + (p)->tick, \ + (p)->adc.v_batt); + +#define AO_ADC_V_BATT 8 +#define AO_ADC_V_BATT_PORT (&stm_gpiob) +#define AO_ADC_V_BATT_PIN 0 + +#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_GPIOEEN)) + +#define AO_NUM_ADC_PIN 1 + +#define AO_ADC_PIN0_PORT AO_ADC_V_BATT_PORT +#define AO_ADC_PIN0_PIN AO_ADC_V_BATT_PIN + +#define AO_NUM_ADC (AO_NUM_ADC_PIN) + +#define AO_ADC_SQ1 AO_ADC_V_BATT + +/* + * Voltage divider on ADC battery sampler + */ +#define AO_BATTERY_DIV_PLUS 51 /* 5.6k */ +#define AO_BATTERY_DIV_MINUS 100 /* 10k */ + +/* + * ADC reference in decivolts + */ +#define AO_ADC_REFERENCE_DV 33 + +/* + * BTM + */ +#define HAS_BTM 1 + +#define ao_serial_btm_getchar ao_serial2_getchar +#define ao_serial_btm_putchar ao_serial2_putchar +#define _ao_serial_btm_pollchar _ao_serial2_pollchar +#define _ao_serial_btm_sleep _ao_serial2_sleep +#define ao_serial_btm_set_speed ao_serial2_set_speed +#define ao_serial_btm_drain ao_serial2_drain +#define ao_serial_btm_rx_fifo ao_serial2_rx_fifo + +#define AO_BTM_INT_PORT (&stm_gpioa) +#define AO_BTM_INT_PIN 15 +#define AO_BTM_RESET_PORT (&stm_gpiob) +#define AO_BTM_RESET_PIN 3 + +/* + * Radio (cc1200) + */ + +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 0x6ca333 + +#define AO_FEC_DEBUG 0 +#define AO_CC1200_SPI_CS_PORT (&stm_gpiob) +#define AO_CC1200_SPI_CS_PIN 10 +#define AO_CC1200_SPI_BUS AO_SPI_1_PA5_PA6_PA7 +#define AO_CC1200_SPI stm_spi1 + +#define AO_CC1200_INT_PORT (&stm_gpiob) +#define AO_CC1200_INT_PIN (11) + +#define AO_CC1200_INT_GPIO 2 +#define AO_CC1200_INT_GPIO_IOCFG CC1200_IOCFG2 + +#define HAS_BOOT_RADIO 0 + +#endif /* _AO_PINS_H_ */ diff --git a/src/telebt-v3.0/ao_telebt.c b/src/telebt-v3.0/ao_telebt.c new file mode 100644 index 00000000..f3906e3f --- /dev/null +++ b/src/telebt-v3.0/ao_telebt.c @@ -0,0 +1,57 @@ +/* + * Copyright © 2015 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include +#include +#include +#include +#if HAS_SAMPLE_PROFILE +#include +#endif + +int +main(void) +{ + ao_clock_init(); + + ao_task_init(); + ao_serial_init(); + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_RED); + ao_timer_init(); + + ao_spi_init(); + ao_dma_init(); + ao_exti_init(); + + ao_adc_init(); + ao_btm_init(); + ao_cmd_init(); + + ao_eeprom_init(); + + ao_usb_init(); + ao_radio_init(); + ao_packet_master_init(); + + ao_config_init(); + + ao_start_scheduler(); + return 0; +} diff --git a/src/telebt-v3.0/flash-loader/ao_pins.h b/src/telebt-v3.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..8711548d --- /dev/null +++ b/src/telebt-v3.0/flash-loader/ao_pins.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +/* External crystal at 8MHz */ +#define AO_HSE 8000000 + +#include + +/* Blue LED */ + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO stm_gpioc +#define AO_BOOT_APPLICATION_PIN 15 +#define AO_BOOT_APPLICATION_VALUE 0 +#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_DOWN + +#endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 8ca1f234586225caea1040bc229b63491dadc1cb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 27 Jan 2015 20:41:15 -0800 Subject: altos/stmf0: Re-implement fast ADC code for stmf0 This creates a ring buffer for ADC data so that ADC fetching can run in parallel with other activities. Signed-off-by: Keith Packard --- src/kernel/ao.h | 1 + src/stmf0/ao_adc_fast.c | 42 +++++++++++++++-------------- src/stmf0/ao_adc_fast.h | 62 +++++++++++++++++++++++++++++++++++++++++++ src/usbtrng-v2.0/ao_usbtrng.c | 10 ++++--- 4 files changed, 91 insertions(+), 24 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao.h b/src/kernel/ao.h index 16d600aa..59a469ae 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -72,6 +72,7 @@ typedef AO_PORT_TYPE ao_port_t; #define AO_PANIC_BUFIO 15 /* Mis-using bufio API */ #define AO_PANIC_EXTI 16 /* Mis-using exti API */ #define AO_PANIC_FAST_TIMER 17 /* Mis-using fast timer API */ +#define AO_PANIC_ADC 18 /* Mis-using ADC interface */ #define AO_PANIC_SELF_TEST_CC1120 0x40 | 1 /* Self test failure */ #define AO_PANIC_SELF_TEST_HMC5883 0x40 | 2 /* Self test failure */ #define AO_PANIC_SELF_TEST_MPU6000 0x40 | 3 /* Self test failure */ diff --git a/src/stmf0/ao_adc_fast.c b/src/stmf0/ao_adc_fast.c index 5885ae4f..be9b5986 100644 --- a/src/stmf0/ao_adc_fast.c +++ b/src/stmf0/ao_adc_fast.c @@ -18,7 +18,10 @@ #include #include -static uint8_t ao_adc_done; +uint16_t ao_adc_ring[AO_ADC_RING_SIZE]; + +uint16_t ao_adc_ring_head, ao_adc_ring_tail; +uint8_t ao_adc_running; /* * Callback from DMA ISR @@ -28,22 +31,30 @@ static uint8_t ao_adc_done; static void ao_adc_dma_done(int index) { (void) index; - ao_adc_done = 1; - ao_wakeup(&ao_adc_done); + ao_adc_ring_head += AO_ADC_RING_CHUNK; + if (ao_adc_ring_head == AO_ADC_RING_SIZE) + ao_adc_ring_head = 0; + ao_adc_running = 0; + ao_wakeup(&ao_adc_ring_head); + ao_dma_done_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); } -/* - * Start the ADC sequence using the DMA engine - */ void -ao_adc_read(uint16_t *dest, int len) +_ao_adc_start(void) { - ao_adc_done = 0; + uint16_t *buf; + + if (ao_adc_running) + return; + if (_ao_adc_space() < AO_ADC_RING_CHUNK) + return; + ao_adc_running = 1; + buf = ao_adc_ring + ao_adc_ring_head; stm_adc.isr = 0; ao_dma_set_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1), &stm_adc.dr, - dest, - len, + buf, + AO_ADC_RING_CHUNK, (0 << STM_DMA_CCR_MEM2MEM) | (STM_DMA_CCR_PL_HIGH << STM_DMA_CCR_PL) | (STM_DMA_CCR_MSIZE_16 << STM_DMA_CCR_MSIZE) | @@ -56,16 +67,6 @@ ao_adc_read(uint16_t *dest, int len) ao_dma_start(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); stm_adc.cr |= (1 << STM_ADC_CR_ADSTART); - ao_arch_block_interrupts(); - while (!ao_adc_done) - ao_sleep(&ao_adc_done); - ao_arch_release_interrupts(); - - ao_dma_done_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); - - stm_adc.cr |= (1 << STM_ADC_CR_ADSTP); - while ((stm_adc.cr & (1 << STM_ADC_CR_ADSTP)) != 0) - ; } void @@ -185,4 +186,5 @@ ao_adc_init(void) stm_syscfg.cfgr1 &= ~(1 << STM_SYSCFG_CFGR1_ADC_DMA_RMP); ao_dma_alloc(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); + ao_dma_set_isr(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1), ao_adc_dma_done); } diff --git a/src/stmf0/ao_adc_fast.h b/src/stmf0/ao_adc_fast.h index a2408d14..eec45505 100644 --- a/src/stmf0/ao_adc_fast.h +++ b/src/stmf0/ao_adc_fast.h @@ -24,4 +24,66 @@ ao_adc_read(uint16_t *dest, int len); void ao_adc_init(void); +/* Total ring size in samples */ +#define AO_ADC_RING_SIZE 256 +/* Number of samples fetched per ao_adc_start call */ +#define AO_ADC_RING_CHUNK (AO_ADC_RING_SIZE >> 1) + +extern uint16_t ao_adc_ring[AO_ADC_RING_SIZE]; + +#define ao_adc_ring_step(pos,inc) (((pos) + (inc)) & (AO_ADC_RING_SIZE - 1)) + +extern uint16_t ao_adc_ring_head, ao_adc_ring_tail; +extern uint8_t ao_adc_running; + +void +_ao_adc_start(void); + +static inline uint16_t +_ao_adc_remain(void) +{ + if (ao_adc_ring_tail > ao_adc_ring_head) + return AO_ADC_RING_SIZE - ao_adc_ring_tail; + return ao_adc_ring_head - ao_adc_ring_tail; +} + +static inline uint16_t +_ao_adc_space(void) +{ + if (ao_adc_ring_head == ao_adc_ring_tail) + return AO_ADC_RING_SIZE; + if (ao_adc_ring_head > ao_adc_ring_tail) + return AO_ADC_RING_SIZE - ao_adc_ring_head; + return ao_adc_ring_tail - ao_adc_ring_head; +} + +static inline uint16_t * +ao_adc_get(uint16_t n) +{ + if (ao_adc_ring_tail + n > AO_ADC_RING_SIZE) + ao_panic(AO_PANIC_ADC); + ao_arch_block_interrupts(); + while (_ao_adc_remain() < n) { + if (!ao_adc_running) + _ao_adc_start(); + ao_sleep(&ao_adc_ring_head); + } + ao_arch_release_interrupts(); + return &ao_adc_ring[ao_adc_ring_tail]; +} + +static inline void +ao_adc_ack(uint16_t n) +{ + if (ao_adc_ring_tail + n > AO_ADC_RING_SIZE) + ao_panic(AO_PANIC_ADC); + ao_arch_block_interrupts(); + ao_adc_ring_tail += n; + if (ao_adc_ring_tail == AO_ADC_RING_SIZE) + ao_adc_ring_tail = 0; + if (!ao_adc_running && _ao_adc_space() >= AO_ADC_RING_CHUNK) + _ao_adc_start(); + ao_arch_release_interrupts(); +} + #endif /* _AO_ADC_FAST_H_ */ diff --git a/src/usbtrng-v2.0/ao_usbtrng.c b/src/usbtrng-v2.0/ao_usbtrng.c index 26cfbac9..e1f43cdd 100644 --- a/src/usbtrng-v2.0/ao_usbtrng.c +++ b/src/usbtrng-v2.0/ao_usbtrng.c @@ -23,7 +23,6 @@ static void ao_trng_fetch(void) { static uint16_t *buffer[2]; - static uint32_t adc_in[AO_USB_IN_SIZE/2]; /* twice as many as we need */ uint32_t kbytes = 1; uint32_t count; int usb_buf_id; @@ -50,18 +49,21 @@ ao_trng_fetch(void) ao_led_on(AO_LED_GREEN); while (count--) { - ao_adc_read((uint16_t *) adc_in, AO_USB_IN_SIZE); - rnd = adc_in; buf = buffer[usb_buf_id]; +// printf ("before get: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush(); + rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */ +// printf ("after get: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush(); for (i = 0; i < 32; i++) *buf++ = ao_crc_in_32_out_16(*rnd++); + ao_adc_ack(AO_USB_IN_SIZE); +// printf ("after ack: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush(); ao_led_toggle(AO_LED_GREEN|AO_LED_RED); ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE); ao_led_toggle(AO_LED_GREEN|AO_LED_RED); usb_buf_id = 1-usb_buf_id; } ao_led_off(AO_LED_GREEN|AO_LED_RED); - ao_usb_flush(); + flush(); } static const struct ao_cmds usbtrng_cmds[] = { -- cgit v1.2.3 From a138e05ae6241a6743ca9f64528124f5f6c8e0ee Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 1 Feb 2015 16:42:01 +0100 Subject: altos: Always include a check for stdio overflow For some reason, the check for running out of space to record stdio devices was disabled when only one device was expected. Signed-off-by: Keith Packard --- src/kernel/ao_stdio.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_stdio.c b/src/kernel/ao_stdio.c index 99118137..1d65fcf5 100644 --- a/src/kernel/ao_stdio.c +++ b/src/kernel/ao_stdio.c @@ -142,10 +142,8 @@ ao_add_stdio(int (*_pollchar)(void), void (*putchar)(char), void (*flush)(void)) __reentrant { -#if AO_NUM_STDIOS > 1 if (ao_num_stdios == AO_NUM_STDIOS) ao_panic(AO_PANIC_STDIO); -#endif ao_stdios[ao_num_stdios]._pollchar = _pollchar; ao_stdios[ao_num_stdios].putchar = putchar; ao_stdios[ao_num_stdios].flush = flush; -- cgit v1.2.3 From 211cb482e4da04dc032432abc236ef8b5a5e732f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 7 Feb 2015 01:30:21 -0800 Subject: altos: Separate out ao_tracker force from dbg Allow enabling telemetry when USB is connected without also enabling the motion debugging output. Signed-off-by: Keith Packard --- src/kernel/ao_tracker.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/ao_tracker.c b/src/kernel/ao_tracker.c index 9b007af8..962f145d 100644 --- a/src/kernel/ao_tracker.c +++ b/src/kernel/ao_tracker.c @@ -132,7 +132,7 @@ ao_tracker(void) if (height < 0) height = -height; - if (ao_tracker_force_telem) + if (ao_tracker_force_telem > 1) printf("head %d ring %d ground_distance %d height %d\n", gps_head, ring, ground_distance, height); if (ground_distance > ao_config.tracker_motion || height > (ao_config.tracker_motion << 1)) @@ -141,7 +141,7 @@ ao_tracker(void) break; } } - if (ao_tracker_force_telem) { + if (ao_tracker_force_telem > 1) { printf ("moving %d started %d\n", moving, log_started); flush(); } @@ -191,11 +191,9 @@ static struct ao_task ao_tracker_task; static void ao_tracker_set_telem(void) { - uint8_t telem; ao_cmd_hex(); - telem = ao_cmd_lex_i; if (ao_cmd_status == ao_cmd_success) - ao_tracker_force_telem = telem; + ao_tracker_force_telem = ao_cmd_lex_i; ao_cmd_status = ao_cmd_success; printf ("flight: %d\n", ao_flight_number); printf ("force_telem: %d\n", ao_tracker_force_telem); @@ -211,7 +209,7 @@ ao_tracker_set_telem(void) } static const struct ao_cmds ao_tracker_cmds[] = { - { ao_tracker_set_telem, "t \0Set telem on USB" }, + { ao_tracker_set_telem, "t \0Set telem on USB (0 off, 1 on, 2 dbg)" }, { 0, NULL }, }; -- cgit v1.2.3