Merge branch 'easymotor-flight'
authorKeith Packard <keithp@keithp.com>
Thu, 19 Jan 2023 20:21:32 +0000 (12:21 -0800)
committerKeith Packard <keithp@keithp.com>
Thu, 19 Jan 2023 20:21:32 +0000 (12:21 -0800)
49 files changed:
altoslib/AltosConfigData.java
altoslib/AltosEepromRecordMega.java
altoslib/AltosEepromRecordSet.java
altoslib/AltosIMU.java
altoslib/AltosIdleFetch.java
altoslib/AltosLib.java
altoslib/AltosTelemetry.java
altoslib/AltosTelemetryStandard.java
altoslib/NewProduct
ao-tools/ao-eeprom/ao-eeprom.c
ao-tools/lib/ao-eeprom-read.h
ao-tools/lib/ao-hex.c
doc/altos.txt
doc/altusmetrum-theme.yml
doc/altusmetrum.txt
doc/companion.txt
doc/easymini.txt
doc/map-loading.txt
doc/micropeak.txt
doc/motortest.txt
doc/release-head.inc
doc/telegps.txt
doc/telelaunch.txt
doc/telemetry.txt
libaltos/libaltos.h
libaltos/libaltos.i0
src/Makefile
src/drivers/ao_aprs.c
src/drivers/ao_bmi088.c [new file with mode: 0644]
src/drivers/ao_bmi088.h [new file with mode: 0644]
src/drivers/ao_lco.h
src/drivers/ao_lco_bits.c
src/drivers/ao_ms5607.c
src/kernel/ao_data.h
src/kernel/ao_log.h
src/kernel/ao_log_mega.c
src/kernel/ao_telemetry.c
src/kernel/ao_telemetry.h
src/nucleao-32/Makefile
src/nucleao-32/ao_nucleo.c
src/nucleao-32/ao_pins.h
src/stm/ao_arch_funcs.h
src/stm/ao_spi_stm.c
src/stmf0/ao_arch_funcs.h
src/stmf0/ao_spi_stm.c
src/telelco-v2.0/ao_lco_v2.c
src/telemega-v6.0/ao_pins.h [new file with mode: 0644]
src/telemega-v6.0/ao_telemega.c [new file with mode: 0644]
src/telemega-v6.0/flash-loader/ao_pins.h [new file with mode: 0644]

index 5797f6325c64071226ccdb256eb059d1f90242b3..ce34db7fd67ccc06b01dcb9a25c61dadba3421dc 100644 (file)
@@ -217,8 +217,11 @@ public class AltosConfigData {
                                return 4095 - value;
                        /* fall through */
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
                case AltosLib.AO_LOG_FORMAT_EASYMOTOR:
+                       /* ADXL375 */
                        return -value;
                default:
                        if (product.startsWith("EasyTimer-"))
@@ -670,6 +673,10 @@ public class AltosConfigData {
                                return true;
                        if (product.startsWith("TeleMega-v4"))
                                return true;
+                       if (product.startsWith("TeleMega-v5"))
+                               return true;
+                       if (product.startsWith("TeleMega-v6"))
+                               return true;
                        if (product.startsWith("EasyMotor-v2"))
                                return true;
                        if (product.startsWith("EasyMotor-v3"))
@@ -688,6 +695,10 @@ public class AltosConfigData {
                                return AltosAdxl375.X_AXIS;
                        if (product.startsWith("TeleMega-v4"))
                                return AltosAdxl375.X_AXIS;
+                       if (product.startsWith("TeleMega-v5"))
+                               return AltosAdxl375.X_AXIS;
+                       if (product.startsWith("TeleMega-v6"))
+                               return AltosAdxl375.X_AXIS;
                        if (product.startsWith("EasyMotor-v2"))
                                return AltosAdxl375.X_AXIS;
                        if (product.startsWith("EasyMotor-v3"))
index 57de0a4137406a38b9ca54f9fedd10d8ecc27b1f..bf94b676c4bf795738effd637d54350f93375223 100644 (file)
@@ -35,6 +35,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
                        return data32(16);
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
                        return data16(14);
@@ -49,6 +50,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
                        return data32(20);
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
                        return data16(16);
@@ -63,6 +65,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
                        return data32(24);
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_OLD:
                        return data16(18);
@@ -119,6 +122,8 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
                switch (log_format) {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
                        return AltosLib.model_mpu6000;
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
+                       return AltosLib.model_bmi088;
                }
                return AltosLib.MISSING;
        }
@@ -126,6 +131,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
        private boolean sensor_normalized() {
                switch (log_format) {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
                        return true;
                }
                return false;
@@ -134,6 +140,7 @@ public class AltosEepromRecordMega extends AltosEepromRecord {
        private int mag_model() {
                switch (log_format) {
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
                        return AltosLib.model_mmc5983;
                }
                return AltosLib.MISSING;
index 3b19ee682ff9b633884c45fdf33584f5447affa6..2c2089d7ebb90d42a5e583fb2f2ca08d4385fc2a 100644 (file)
@@ -87,6 +87,7 @@ public class AltosEepromRecordSet implements AltosRecordSet {
                case AltosLib.AO_LOG_FORMAT_EASYMEGA_2:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_4:
                case AltosLib.AO_LOG_FORMAT_TELEMEGA_5:
+               case AltosLib.AO_LOG_FORMAT_TELEMEGA_6:
                        record = new AltosEepromRecordMega(eeprom);
                        break;
                case AltosLib.AO_LOG_FORMAT_TELEMETRUM:
index 0ff27c75421618a49753afdd7538af45da7bbcd6..87570a79a5458ec580198c714f56d3c92c39e78a 100644 (file)
@@ -52,6 +52,7 @@ public class AltosIMU implements Cloneable {
        public static final double      counts_per_g_mpu = 2048.0;
        public static final double      counts_per_g_bmx = 2048.0;
        public static final double      counts_per_g_adxl = 20.5;
+       public static final double      counts_per_g_bmi088 = 1365.0;
 
        private static double counts_per_g(int imu_type, int imu_model) {
                switch (imu_model) {
@@ -62,6 +63,8 @@ public class AltosIMU implements Cloneable {
                        return counts_per_g_adxl;
                case AltosLib.model_bmx160:
                        return counts_per_g_bmx;
+               case AltosLib.model_bmi088:
+                       return counts_per_g_bmi088;
                }
 
                switch (imu_type) {
@@ -93,6 +96,7 @@ public class AltosIMU implements Cloneable {
        public static final double      GYRO_FULLSCALE_DEGREES_BMX = 2000.0;
        public static final double      GYRO_COUNTS_BMX = 32767.0;
        public static final double      counts_per_degree_bmx = GYRO_COUNTS_BMX / GYRO_FULLSCALE_DEGREES_BMX;
+       public static final double      counts_per_degree_bmi088 = 16.384;
 
        private static double counts_per_degree(int imu_type, int imu_model) {
                switch (imu_model) {
@@ -101,6 +105,8 @@ public class AltosIMU implements Cloneable {
                        return counts_per_degree_mpu;
                case AltosLib.model_bmx160:
                        return counts_per_degree_bmx;
+               case AltosLib.model_bmi088:
+                       return counts_per_degree_bmi088;
                }
 
                switch (imu_type) {
@@ -185,6 +191,21 @@ public class AltosIMU implements Cloneable {
                        }
                        return true;
                }
+               if (line.startsWith("BMI088:")) {
+                       String[] items = line.split("\\s+");
+
+                       imu_model = AltosLib.model_bmi088;
+
+                       if (items.length >= 7) {
+                               accel_along = Integer.parseInt(items[1]);
+                               accel_across = Integer.parseInt(items[2]);
+                               accel_through = Integer.parseInt(items[3]);
+                               gyro_roll = Integer.parseInt(items[4]);
+                               gyro_pitch = Integer.parseInt(items[5]);
+                               gyro_yaw = Integer.parseInt(items[6]);
+                       }
+                       return true;
+               }
 
                return false;
        }
index b2552b24bdf73d561378585808c8c8660c61621f..25a36096f6d98b275dcf2810a990b384fd02a19a 100644 (file)
@@ -224,6 +224,12 @@ public class AltosIdleFetch implements AltosDataProvider {
                               AltosIdler.idle_ms5607,
                               AltosIdler.idle_imu, AltosIdler.idle_mag,
                               AltosIdler.idle_sensor_mega),
+               new AltosIdler("TeleMega-v6",
+                              AltosIdler.idle_gps,
+                              AltosIdler.idle_adxl375,
+                              AltosIdler.idle_ms5607,
+                              AltosIdler.idle_imu, AltosIdler.idle_mag,
+                              AltosIdler.idle_sensor_mega),
                new AltosIdler("EasyMega-v1",
                               AltosIdler.idle_mma655x,
                               AltosIdler.idle_ms5607,
index 47c10cbf2fdac279f9a9cfe4b4607c221d691421..5293badce58eee47e6fb109741e7caced1e2be04 100644 (file)
@@ -386,6 +386,7 @@ public class AltosLib {
        public static final int AO_LOG_FORMAT_TELEMEGA_4 = 19;
        public static final int AO_LOG_FORMAT_EASYMOTOR = 20;
        public static final int AO_LOG_FORMAT_TELEMEGA_5 = 21;
+       public static final int AO_LOG_FORMAT_TELEMEGA_6 = 22;
        public static final int AO_LOG_FORMAT_NONE = 127;
 
        public static final int model_mpu6000 = 0;
@@ -394,6 +395,7 @@ public class AltosLib {
        public static final int model_bmx160 = 3;
        public static final int model_hmc5883 = 4;
        public static final int model_mmc5983 = 5;
+       public static final int model_bmi088 = 6;
 
        public static boolean isspace(int c) {
                switch (c) {
@@ -663,6 +665,8 @@ public class AltosLib {
                        return product_easymotor;
                case AO_LOG_FORMAT_TELEMEGA_5:
                        return product_telemega;
+               case AO_LOG_FORMAT_TELEMEGA_6:
+                       return product_telemega;
                case AO_LOG_FORMAT_NONE:
                        return product_altusmetrum;
                default:
index 54dd04dac4c2695f006f4b73528a47d556ac98f4..5fa5fc3bbb9955676dfa96c3391ace005bccd808 100644 (file)
@@ -82,6 +82,7 @@ public abstract class AltosTelemetry implements AltosDataProvider {
        final static int packet_type_mini3 = 0x11;
        final static int packet_type_mega_sensor_bmx160 = 0x12;
        final static int packet_type_mega_norm_mpu6000_mmc5983 = 0x13;
+       final static int packet_type_mega_norm_bmi088_mmc5983 = 0x14;
 
        static AltosTelemetry parse_hex(String hex)  throws ParseException, AltosCRCException {
                AltosTelemetry  telem = null;
index 7f6626dbf286074c4ae6782a8f6032c3c63ef904..bea217c82dcbe10ad00497df323018a226ec5536 100644 (file)
@@ -99,6 +99,9 @@ public abstract class AltosTelemetryStandard extends AltosTelemetry {
                case packet_type_mega_norm_mpu6000_mmc5983:
                        telem = new AltosTelemetryMegaNorm(bytes, AltosLib.model_mpu6000, AltosLib.model_mmc5983);
                        break;
+               case packet_type_mega_norm_bmi088_mmc5983:
+                       telem = new AltosTelemetryMegaNorm(bytes, AltosLib.model_bmi088, AltosLib.model_mmc5983);
+                       break;
                default:
                        telem = new AltosTelemetryRaw(bytes);
                        break;
index 27d94d11a0d0b0e9209c4f79fd54dd27050fe3eb..e502fdfff0d0ea29a2de3efd0437268383283726 100644 (file)
@@ -9,6 +9,8 @@ altoslib/
        Declare new USB ids
        Declare new Product name
        Add item to product_name function
+       Add entry in product_id_from_log_format
+       Declare new sensor model
 
  2. AltosIdleFetch.java
 
index d9b331953d35bd84677046fbe98940d71096e13f..8650f38d7f35e0a947447c065d2abc6f93ca32b3 100644 (file)
@@ -355,6 +355,7 @@ main (int argc, char **argv)
                        break;
                case AO_LOG_FORMAT_TELEMEGA_4:
                case AO_LOG_FORMAT_TELEMEGA_5:
+               case AO_LOG_FORMAT_TELEMEGA_6:
                        len = 32;
                        max_adc= 4095;
                        adc_ref = 3.3;
@@ -428,6 +429,7 @@ main (int argc, char **argv)
                                case AO_LOG_FORMAT_EASYMEGA_2:
                                case AO_LOG_FORMAT_TELEMEGA_4:
                                case AO_LOG_FORMAT_TELEMEGA_5:
+                               case AO_LOG_FORMAT_TELEMEGA_6:
                                        log_mega = (struct ao_log_mega *) &eeprom->data[pos];
                                        switch (log_mega->type) {
                                        case AO_LOG_FLIGHT:
index a103824b35bfd148556f3d38d223351d6e94d2b4..01c2ef35aa6af46804ad43393d049c2f273f90b6 100644 (file)
@@ -47,6 +47,7 @@
 #define AO_LOG_FORMAT_TELEMEGA_4       19      /* 32 byte typed telemega records with 32 bit gyro cal and Bmx160 */
 #define AO_LOG_FORMAT_EASYMOTOR                20      /* 16 byte typed easymotor records with pressure sensor and adxl375 */
 #define AO_LOG_FORMAT_TELEMEGA_5       21      /* 32 byte typed telemega records with 32 bit gyro cal, mpu6000 and mmc5983 */
+#define AO_LOG_FORMAT_TELEMEGA_6       22      /* 32 byte typed telemega records with 32 bit gyro cal, bmi088 and mmc5983 */
 #define AO_LOG_FORMAT_NONE             127     /* No log at all */
 
 enum ao_pyro_flag {
index 73f3d7bed61dde5534fe03631ff62e4b563f49c9..c275baafb2c296b41c011f7872c3c1d4d34330f0 100644 (file)
@@ -565,7 +565,7 @@ ao_hex_file_create(struct ao_hex_image *image, struct ao_sym *symbols, int num_s
 
        /* Stick an EOF after the data
         */
-       record = calloc(sizeof (struct ao_hex_record), 1);
+       record = calloc(1,sizeof (struct ao_hex_record) + 2);
        record->type = AO_HEX_RECORD_EOF;
        record->address = 0;
        record->length = 0;
index 9d12f12b324e2d0b02fe86457976dddc49b9f790..8a042df852428aabe98b31bebc987979f7349368 100644 (file)
@@ -5,8 +5,8 @@ Keith Packard <keithp@keithp.com>
 :stylesheet: am.css
 :linkcss:
 :numbered:
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
        include::header.adoc[]
index c4f6f96bdf5368588330d7f0d34d448b8ba78cda..78e1064f319d37c971d28854a7c46a7e499ef617 100644 (file)
@@ -1,10 +1,13 @@
+extends: default
 base:
   font_family: Open Sans Light
+  font-size: 12
 heading:
   font_color: #78079a
   font_size: 17
 font:
   catalog:
+    merge: true
     Open Sans Light:
       normal: OpenSans-Light.ttf
       italic: OpenSans-LightItalic.ttf
@@ -42,7 +45,7 @@ admonition_label:
 page:
   background_color: ffffff
   layout: portrait
-  margin: [0.5in, 0.67in, 0.75in, 0.67in]
+  margin: [0.5in, 0.67in, 0.67in, 0.67in]
   size: letter
 footer:
   height: 0.5in
@@ -57,7 +60,7 @@ footer:
       content: $footer_recto_right_content
     right:
       content: '{page-number}'
-literal:
+codespan:
   font_family: DejaVu Sans Mono
 code:
   font_family: DejaVu Sans Mono
index b655c0b23a166e0ff480f2b5ec7cc4d68fe1584f..a66f31a2208fcbf49ddc9c1e651b61e5c24fed36 100644 (file)
@@ -23,8 +23,8 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>; Bob Finch; Anth
 :easytimer: 1
 :easymotor: 1
 :application: AltosUI
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
        include::header.adoc[]
index 256ffad77cae3c4a11dd142030a67f17ae4bb9f9..c23aab1872b7cf4a874fbfe0fc635b2a2be359dd 100644 (file)
@@ -4,8 +4,8 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
 :copyright: Bdale Garbee and Keith Packard 2018
 :stylesheet: am.css
 :linkcss:
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 :toc:
 
index 6a4b1e4abedc9e17b442e34866d1182329ed3afc..322a5ef43ddf983b6175565f9376cb7dddab675d 100644 (file)
@@ -12,8 +12,8 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
 :altusmetrum: 1
 :easymini: 1
 :application: AltosUI
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
        include::header.adoc[]
index f83281769a949ff0dd7884308527b18f40bbfca0..b1c5c10a004f8d6d04198df1a29e00a4fcca4988 100644 (file)
@@ -5,8 +5,8 @@ Keith Packard <keithp@keithp.com>
 :doctype: article
 :stylesheet: am-notoc.css
 :linkcss:
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
 == The Google Maps Problem
index c02c613a8287c14a145254545c75d674044c1fdd..fb75aacb4d3dd6d165073059207f05b1bff68060 100644 (file)
@@ -8,8 +8,8 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
 :toc:
 :doctype: book
 :numbered:
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
        include::header.adoc[]
index 97926c0e34d6db201dbf5bded2bb56c5eeda90c5..c3d25c96afbf94dbe23e3393df2b5116f6e0cd0f 100644 (file)
@@ -13,8 +13,8 @@ Bdale Garbee <bdale@gag.com>
 :toc:
 :motortest: 1
 :application: Motor Testing
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
        include::header.adoc[]
index 0dbdfc2b5656648c7225334cb1dc23083433ca09..2c04a84d7ce1da424d7a38804244aca1599bb800 100644 (file)
@@ -2,6 +2,6 @@
 :doctype: article
 :stylesheet: am-notoc.css
 :linkcss:
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
index 608a6db363c110737cce7b143c4069789cb17ec5..aae74424966a6867d65c40475c90f6e274e1f488 100644 (file)
@@ -13,8 +13,8 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
 :radio: 1
 :gps: 1
 :application: TeleGPS
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
        include::header.adoc[]
index 89f98dd451eca44d437c311e25ae45108da4f3c1..b72ec06f2df7d2b06e9b63b6895534006814a91b 100644 (file)
@@ -13,8 +13,8 @@ Bdale Garbee <bdale@gag.com>
 :toc:
 :telelaunch: 1
 :application: TeleLaunch
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
        include::header.adoc[]
index 0df96abdd2b199efd72bd4937f460f7fff728ccb..c867c6cdac0e5eb0dc65c11c4ef51b78937cc8a5 100644 (file)
@@ -8,8 +8,8 @@ Keith Packard <keithp@keithp.com>; Bdale Garbee <bdale@gag.com>
 :doctype: article
 :toc:
 :numbered:
-:pdf-stylesdir: .
-:pdf-style: altusmetrum
+:pdf-themesdir: .
+:pdf-theme: altusmetrum
 :pdf-fontsdir: fonts
 
        include::header.adoc[]
index 8c49346fdf3a7e45f19934c2bea1355f6b0a7bc0..f7fc90826ac9b0288f3a21abe8ccb8e60507284c 100644 (file)
@@ -42,6 +42,7 @@ struct altos_device {
        int                             serial;
        char                            name[256];
        char                            path[256];
+       int                             (*method_1)(int x, int y);
        //%mutable;
 };
 
index d06468f5a379985f4e3dde7f50a8fd035536a807..ac45fbaf3c591b2520d0cb973a2f4fc0e6064547 100644 (file)
@@ -2,4 +2,8 @@
 %{
 #include "libaltos.h"
 %}
-
+%extend altos_device {
+       int method_1(int x, int y) {
+               return ($self->method_1)(x, y);
+       }
+}
index 45adc166059d717fd00b68f9c224b1c4b3dd52af..ff7f1bd9bd3ebdb3b1ba1f1990d2f317f5434fef 100644 (file)
@@ -27,6 +27,7 @@ ARMM3DIRS=\
        telemega-v3.0 telemega-v3.0/flash-loader \
        telemega-v4.0 telemega-v4.0/flash-loader \
        telemega-v5.0 telemega-v5.0/flash-loader \
+       telemega-v6.0 telemega-v6.0/flash-loader \
        telemetrum-v2.0 telemetrum-v2.0/flash-loader \
        telemetrum-v3.0 telemetrum-v3.0/flash-loader \
        telegps-v0.3 telegps-v0.3/flash-loader \
index 3ac4cd535b231a8ac11622e5719dfe115839a202..b0645465c586ddb6e88f11f29ff37962cfc61277 100644 (file)
@@ -310,6 +310,7 @@ static uint8_t tncBitStuff;
 /// Buffer to hold the message portion of the AX.25 packet as we prepare it.
 static uint8_t tncBuffer[TNC_BUFFER_SIZE];
 
+#pragma GCC diagnostic ignored "-Wformat-overflow="
 /**
  *   Initialize the TNC internal variables.
  */
diff --git a/src/drivers/ao_bmi088.c b/src/drivers/ao_bmi088.c
new file mode 100644 (file)
index 0000000..d03fcea
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Copyright © 2022 Keith Packard <keithp@keithp.com>
+ *
+ * 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <ao.h>
+#include <ao_bmi088.h>
+#include <ao_data.h>
+
+#define AO_BMI088_SPI_SPEED    ao_spi_speed(100000)
+
+#define ao_bmi088_spi_get()    ao_spi_get(AO_BMI088_SPI_BUS, AO_BMI088_SPI_SPEED)
+#define ao_bmi088_spi_put()    ao_spi_put(AO_BMI088_SPI_BUS)
+
+#define ao_bmi088_acc_start()  ao_spi_set_cs(AO_BMI088_ACC_CS_PORT,    \
+                                             (1 << AO_BMI088_ACC_CS_PIN))
+#define ao_bmi088_acc_end()    ao_spi_clr_cs(AO_BMI088_ACC_CS_PORT,    \
+                                             (1 << AO_BMI088_ACC_CS_PIN))
+#define ao_bmi088_gyr_start()  ao_spi_set_cs(AO_BMI088_GYR_CS_PORT,    \
+                                             (1 << AO_BMI088_GYR_CS_PIN))
+#define ao_bmi088_gyr_end()    ao_spi_clr_cs(AO_BMI088_GYR_CS_PORT,    \
+                                             (1 << AO_BMI088_GYR_CS_PIN))
+
+static uint8_t
+_ao_bmi088_acc_reg_read(uint8_t addr)
+{
+       uint8_t v[2];
+       addr |= 0x80;
+       ao_bmi088_acc_start();
+       ao_spi_send(&addr, 1, AO_BMI088_SPI_BUS);
+       ao_spi_recv(v, 2, AO_BMI088_SPI_BUS);   /* part sends garbage for first byte */
+       ao_bmi088_acc_end();
+       return v[1];
+}
+
+static void
+_ao_bmi088_acc_reg_write(uint8_t addr, uint8_t value)
+{
+       uint8_t d[2] = { addr, value };
+       ao_bmi088_acc_start();
+       ao_spi_send(d, 2, AO_BMI088_SPI_BUS);
+       ao_bmi088_acc_end();
+}
+
+static void
+_ao_bmi088_acc_sample_read(struct ao_bmi088_acc_sample *sample)
+{
+       uint8_t dummy;
+       uint8_t addr = BMI088_ACC_DATA | 0x80;
+
+       ao_bmi088_acc_start();
+       ao_spi_send(&addr, 1, AO_BMI088_SPI_BUS);
+       ao_spi_recv(&dummy, 1, AO_BMI088_SPI_BUS);      /* part sends garbage for first byte */
+       ao_spi_recv(sample, sizeof(struct ao_bmi088_acc_sample), AO_BMI088_SPI_BUS);
+       ao_bmi088_acc_end();
+}
+
+static void
+_ao_bmi088_gyr_read(uint8_t addr, void *data, uint8_t len)
+{
+       addr |= 0x80;
+       ao_bmi088_gyr_start();
+       ao_spi_send(&addr, 1, AO_BMI088_SPI_BUS);
+       ao_spi_recv(data, len, AO_BMI088_SPI_BUS);
+       ao_bmi088_gyr_end();
+}
+
+static uint8_t
+_ao_bmi088_gyr_reg_read(uint8_t addr)
+{
+       uint8_t v;
+       _ao_bmi088_gyr_read(addr, &v, 1);
+       return v;
+}
+
+static void
+_ao_bmi088_gyr_reg_write(uint8_t addr, uint8_t value)
+{
+       uint8_t d[2] = { addr, value };
+       ao_bmi088_gyr_start();
+       ao_spi_send(d, 2, AO_BMI088_SPI_BUS);
+       ao_bmi088_gyr_end();
+}
+
+static void
+_ao_bmi088_gyr_sample_read(struct ao_bmi088_gyr_sample *sample)
+{
+       _ao_bmi088_gyr_read(BMI088_GYRO_DATA, sample, sizeof (struct ao_bmi088_gyr_sample));
+}
+
+static void
+ao_bmi088_reset(void)
+{
+       ao_bmi088_spi_get();
+
+       /* reset the two devices */
+       _ao_bmi088_acc_reg_write(BMI088_ACC_SOFTRESET, BMI088_ACC_SOFTRESET_RESET);
+       _ao_bmi088_gyr_reg_write(BMI088_GYRO_SOFTRESET, BMI088_GYRO_SOFTRESET_RESET);
+
+       /* wait 30ms (that's how long the gyro takes */
+       ao_delay(AO_MS_TO_TICKS(30));
+
+       /* force acc part to SPI mode */
+       ao_bmi088_acc_start();
+
+       ao_delay(AO_MS_TO_TICKS(1));
+
+       ao_bmi088_acc_end();
+
+       ao_bmi088_spi_put();
+}
+
+static bool
+ao_bmi088_accel_good(int16_t pos, int16_t neg, int32_t good)
+{
+       int32_t diff = (int32_t) pos - (int32_t) neg;
+
+       return diff >= good;
+}
+
+static void
+ao_bmi088_setup(void)
+{
+       bool working = false;
+       struct ao_bmi088_acc_sample     acc_pos, acc_neg;
+
+       ao_bmi088_reset();
+
+       ao_bmi088_spi_get();
+
+       /* Make sure the two devices are alive */
+       if (_ao_bmi088_acc_reg_read(BMI088_ACC_CHIP_ID) != BMI088_ACC_CHIP_ID_BMI088)
+               goto failure;
+
+       if (_ao_bmi088_gyr_reg_read(BMI088_GYRO_CHIP_ID) != BMI088_GYRO_CHIP_ID_BMI088)
+               goto failure;
+
+       /* Turn on the accelerometer */
+
+       _ao_bmi088_acc_reg_write(BMI088_ACC_PWR_CTRL, BMI088_ACC_PWR_CTRL_ON);
+
+       /* Wait 5ms after changing accel power mode */
+       ao_delay(AO_MS_TO_TICKS(5));
+
+       /* Accel self test. Procedure:
+        *
+        * 1) Set ±24g range by writing 0x03 to register ACC_RANGE (0x41)
+         * 2) Set ODR=1.6kHz, continuous sampling mode, “normal mode” (norm_avg4) by writing 0xA7 to
+         * register ACC_CONF (0x40)
+         * • Continuous filter function: set bit7 in ACC_CONF
+         * • “normal avg4 mode”: ACC_CONF |= 0x02<<4
+         * • ODR=1.6kHz: ACC_CONF |= 0x0C
+         * 3) Wait for > 2 ms
+         * 4) Enable the positive self-test polarity (i.e. write 0x0D to register ACC_SELF_TEST (0x6D))
+         * 5) Wait for > 50ms
+         * 6) Read the accelerometer offset values for each axis (positive self-test response)
+         * 7) Enable the negative self-test polarity (i.e. write 0x09 to register ACC_SELF_TEST (0x6D))
+         * 8) Wait for > 50ms
+         * 9) Read the accelerometer offset values for each axis (negative self-test response)
+         * 10) Disable the self-test (i.e. write 0x00 to register ACC_SELF_TEST (0x6D))
+         * 11) Calculate difference of positive and negative self-test response and compare with the expected
+         * values (see table below)
+         * 12) Wait for > 50ms to let the sensor settle to normal mode steady state operation
+        */
+
+       _ao_bmi088_acc_reg_write(BMI088_ACC_RANGE, BMI088_ACC_RANGE_24);
+
+       _ao_bmi088_acc_reg_write(BMI088_ACC_CONF,
+                                (BMI088_ACC_CONF_BWP_NORMAL << BMI088_ACC_CONF_BWP) |
+                                (BMI088_ACC_CONF_ODR_1600 << BMI088_ACC_CONF_ODR));
+
+       ao_delay(AO_MS_TO_TICKS(2));
+
+       _ao_bmi088_acc_reg_write(BMI088_ACC_SELF_TEST, BMI088_ACC_SELF_TEST_POSITIVE);
+
+       ao_delay(AO_MS_TO_TICKS(50));
+
+       _ao_bmi088_acc_sample_read(&acc_pos);
+
+       _ao_bmi088_acc_reg_write(BMI088_ACC_SELF_TEST, BMI088_ACC_SELF_TEST_NEGATIVE);
+
+       ao_delay(AO_MS_TO_TICKS(50));
+
+       _ao_bmi088_acc_sample_read(&acc_neg);
+
+       _ao_bmi088_acc_reg_write(BMI088_ACC_SELF_TEST, BMI088_ACC_SELF_TEST_OFF);
+
+       /* Self test X and Y must show at least 1000 mg difference,
+        * Z must show at least 500mg difference
+        */
+       if (!ao_bmi088_accel_good(acc_pos.x, acc_neg.x, (int32_t) ao_bmi_accel_to_sample(GRAVITY)))
+               goto failure;
+
+       if (!ao_bmi088_accel_good(acc_pos.y, acc_neg.y, (int32_t) ao_bmi_accel_to_sample(GRAVITY)))
+               goto failure;
+
+       if (!ao_bmi088_accel_good(acc_pos.z, acc_neg.z, (int32_t) ao_bmi_accel_to_sample(GRAVITY/2)))
+               goto failure;
+
+       /*
+        * Self-test gyro
+        *
+        * To trigger the self-test, bit #0 (‘bite_trig’) in address
+        * GYRO_SELF_TEST must be set. When the test is finished, bit
+        * #1 (‘bist_rdy’) will be set by the gyro and the test result
+        * can then be found in bit #2 (‘bist_fail’).  A ‘0’ indicates
+        * that the test was passed without issues. If a failure
+        * occurred, the bit ‘bist_fail’ will be set to ‘1’.
+        */
+
+       _ao_bmi088_gyr_reg_write(BMI088_GYRO_SELF_TEST,
+                                (1 << BMI088_GYRO_SELF_TEST_TRIG_BIST));
+
+       uint8_t gyro_self_test;
+       for(;;) {
+               gyro_self_test = _ao_bmi088_gyr_reg_read(BMI088_GYRO_SELF_TEST);
+               if ((gyro_self_test & (1 << BMI088_GYRO_SELF_TEST_BIST_RDY)) != 0)
+                       break;
+       }
+       if ((gyro_self_test & (1 << BMI088_GYRO_SELF_TEST_BIST_FAIL)) != 0)
+               goto failure;
+
+
+       /* Put accel in desired mode */
+
+       /* 200 Hz sampling rate, normal filter */
+       _ao_bmi088_acc_reg_write(BMI088_ACC_CONF,
+                                (BMI088_ACC_CONF_BWP_NORMAL << BMI088_ACC_CONF_BWP) |
+                                (BMI088_ACC_CONF_ODR_200 << BMI088_ACC_CONF_ODR));
+
+
+       /* 24 g range */
+       _ao_bmi088_acc_reg_write(BMI088_ACC_RANGE, BMI088_ACC_RANGE_24);
+
+       /* Put gyro in desired mode */
+
+       /* 2000°/s range */
+       _ao_bmi088_gyr_reg_write(BMI088_GYRO_RANGE, BMI088_GYRO_RANGE_2000);
+
+       /* 200 Hz sampling rate, 64Hz filter */
+       _ao_bmi088_gyr_reg_write(BMI088_GYRO_BANDWIDTH, BMI088_GYRO_BANDWIDTH_200_64);
+
+       working = true;
+failure:
+       if (!working)
+               AO_SENSOR_ERROR(AO_DATA_BMI088);
+
+       ao_bmi088_spi_put();
+}
+
+struct ao_bmi088_sample        ao_bmi088_current;
+
+static void
+ao_bmi088(void)
+{
+       struct ao_bmi088_sample sample;
+
+       ao_bmi088_setup();
+       for (;;)
+       {
+               ao_bmi088_spi_get();
+               _ao_bmi088_acc_sample_read(&sample.acc);
+               _ao_bmi088_gyr_sample_read(&sample.gyr);
+               ao_bmi088_spi_put();
+               ao_arch_block_interrupts();
+               ao_bmi088_current = sample;
+               AO_DATA_PRESENT(AO_DATA_BMI088);
+               AO_DATA_WAIT();
+               ao_arch_release_interrupts();
+       }
+}
+
+static struct ao_task ao_bmi088_task;
+
+static void
+ao_bmi088_show(void)
+{
+#ifdef AO_LOG_NORMALIZED
+       printf ("BMI088: %7d %7d %7d %7d %7d %7d\n",
+               ao_bmi088_along(&ao_bmi088_current),
+               ao_bmi088_across(&ao_bmi088_current),
+               ao_bmi088_through(&ao_bmi088_current),
+               ao_bmi088_roll(&ao_bmi088_current),
+               ao_bmi088_pitch(&ao_bmi088_current),
+               ao_bmi088_yaw(&ao_bmi088_current));
+#else
+       printf ("Accel: %7d %7d %7d Gyro: %7d %7d %7d\n",
+               ao_bmi088_current.acc.x,
+               ao_bmi088_current.acc.y,
+               ao_bmi088_current.acc.z,
+               ao_bmi088_current.gyr.x,
+               ao_bmi088_current.gyr.y,
+               ao_bmi088_current.gyr.z);
+#endif
+}
+
+static const struct ao_cmds bmi_cmds[] = {
+       { ao_bmi088_show,               "I\0Show BMI088 status" },
+       { 0, 0 }
+};
+
+void
+ao_bmi088_init(void)
+{
+       AO_TICK_TYPE    then;
+       ao_spi_init_cs(AO_BMI088_ACC_CS_PORT, (1 << AO_BMI088_ACC_CS_PIN));
+       ao_spi_init_cs(AO_BMI088_GYR_CS_PORT, (1 << AO_BMI088_GYR_CS_PIN));
+
+       /* force acc part to SPI mode */
+       ao_bmi088_acc_start();
+       then = ao_time();
+       while ((ao_time() - then) < 2)
+               ;
+       ao_bmi088_acc_end();
+
+       ao_add_task(&ao_bmi088_task, ao_bmi088, "bmi088");
+
+       ao_cmd_register(bmi_cmds);
+}
diff --git a/src/drivers/ao_bmi088.h b/src/drivers/ao_bmi088.h
new file mode 100644 (file)
index 0000000..592ed85
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright © 2022 Keith Packard <keithp@keithp.com>
+ *
+ * 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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_BMI088_H_
+#define _AO_BMI088_H_
+
+#include <math.h>
+
+struct ao_bmi088_acc_sample {
+       int16_t         x;
+       int16_t         y;
+       int16_t         z;
+};
+
+struct ao_bmi088_gyr_sample {
+       int16_t         x;
+       int16_t         y;
+       int16_t         z;
+};
+
+struct ao_bmi088_sample {
+       struct ao_bmi088_acc_sample acc;
+       struct ao_bmi088_gyr_sample gyr;
+};
+
+extern struct ao_bmi088_sample ao_bmi088_current;
+
+void
+ao_bmi088_init(void);
+
+#define BMI088_ACC_CHIP_ID     0x00
+#define  BMI088_ACC_CHIP_ID_BMI088     0x1e
+
+#define BMI088_ACC_ERR_REG     0x02
+# define BMI088_ACC_ERR_REG_ERROR_CODE 2
+# define BMI088_ACC_ERR_REG_FATAL_ERR  0
+
+#define BMI088_ACC_STATUS      0x03
+# define BMI088_ACC_STATUS_ACC_DRDY    7
+
+#define BMI088_ACC_DATA                0x12
+#define BMI088_ACC_TIME                0x18
+
+#define BMI088_ACC_INT_STAT_1  0x1d
+# define BMI088_ACC_INT_STAT_1_ACC_DRDY        7
+
+#define BMI088_ACC_TEMP                0x22
+
+#define BMI088_ACC_CONF                0x40
+# define BMI088_ACC_CONF_BWP           4
+# define BMI088_ACC_CONF_BWP_OSR4              0x08
+# define BMI088_ACC_CONF_BWP_OSR2              0x08
+# define BMI088_ACC_CONF_BWP_NORMAL            0x0a
+# define BMI088_ACC_CONF_ODR           0
+# define BMI088_ACC_CONF_ODR_12_5              0x05
+# define BMI088_ACC_CONF_ODR_25                        0x06
+# define BMI088_ACC_CONF_ODR_50                        0x07
+# define BMI088_ACC_CONF_ODR_100               0x08
+# define BMI088_ACC_CONF_ODR_200               0x09
+# define BMI088_ACC_CONF_ODR_400               0x0a
+# define BMI088_ACC_CONF_ODR_800               0x0b
+# define BMI088_ACC_CONF_ODR_1600              0x0c
+
+#define BMI088_ACC_RANGE       0x41
+# define BMI088_ACC_RANGE_3                    0x00
+# define BMI088_ACC_RANGE_6                    0x01
+# define BMI088_ACC_RANGE_12                   0x02
+# define BMI088_ACC_RANGE_24                   0x03
+
+#define BMI088_INT1_IO_CONF    0x53
+# define BMI088_INT1_IO_CONF_INT1_IN   4
+# define BMI088_INT1_IO_CONF_INT1_OUT  3
+# define BMI088_INT1_IO_CONF_INT1_OD   2
+# define BMI088_INT1_IO_CONF_INT1_LVL  1
+
+#define BMI088_INT2_IO_CONF    0x54
+# define BMI088_INT2_IO_CONF_INT2_IN   4
+# define BMI088_INT2_IO_CONF_INT2_OUT  3
+# define BMI088_INT2_IO_CONF_INT2_OD   2
+# define BMI088_INT2_IO_CONF_INT2_LVL  1
+
+#define BMI088_INT2_INT2_MAP_DATA      0x58
+# define BMI088_INT2_INT2_MAP_DATA_INT2_DRDY   6
+# define BMI088_INT2_INT2_MAP_DATA_INT1_DRDY   2
+
+#define BMI088_ACC_SELF_TEST   0x6d
+# define BMI088_ACC_SELF_TEST_OFF      0x00
+# define BMI088_ACC_SELF_TEST_POSITIVE 0x0d
+# define BMI088_ACC_SELF_TEST_NEGATIVE 0x09
+
+#define BMI088_ACC_PWR_CONF    0x7c
+# define BMI088_ACC_PWR_CONF_SUSPEND   0x03
+# define BMI088_ACC_PWR_CONF_ACTIVE    0x00
+
+#define BMI088_ACC_PWR_CTRL    0x7d
+# define BMI088_ACC_PWR_CTRL_OFF       0x00
+# define BMI088_ACC_PWR_CTRL_ON                0x04
+
+#define BMI088_ACC_SOFTRESET   0x7e
+# define BMI088_ACC_SOFTRESET_RESET    0xb6
+
+#define BMI088_GYRO_CHIP_ID    0x00
+# define BMI088_GYRO_CHIP_ID_BMI088    0x0f
+
+#define BMI088_GYRO_DATA       0x02
+#define BMI088_GYRO_DATA_X     0x02
+#define BMI088_GYRO_DATA_Y     0x04
+#define BMI088_GYRO_DATA_Z     0x06
+
+#define BMI088_GYRO_INT_STAT_1 0x0a
+# define BMI088_GYRO_INT_STAT_1_GYRO_DRDY      7
+
+#define BMI088_GYRO_RANGE      0x0f
+# define BMI088_GYRO_RANGE_2000                0x00
+# define BMI088_GYRO_RANGE_1000                0x01
+# define BMI088_GYRO_RANGE_500         0x02
+# define BMI088_GYRO_RANGE_250         0x03
+# define BMI088_GYRO_RANGE_125         0x04
+
+#define BMI088_GYRO_BANDWIDTH  0x10
+# define BMI088_GYRO_BANDWIDTH_2000_532        0x00
+# define BMI088_GYRO_BANDWIDTH_2000_230        0x01
+# define BMI088_GYRO_BANDWIDTH_1000_116        0x02
+# define BMI088_GYRO_BANDWIDTH_400_47  0x03
+# define BMI088_GYRO_BANDWIDTH_200_23  0x04
+# define BMI088_GYRO_BANDWIDTH_100_12  0x05
+# define BMI088_GYRO_BANDWIDTH_200_64  0x06
+# define BMI088_GYRO_BANDWIDTH_100_32  0x07
+
+#define BMI088_GYRO_LPM1       0x11
+# define BMI088_GYRO_LPM1_NORMAL       0x00
+# define BMI088_GYRO_LPM1_SUSPEND      0x80
+# define BMI088_GYRO_LPM1_DEEP_SUSPEND 0x20
+
+#define BMI088_GYRO_SOFTRESET  0x14
+# define BMI088_GYRO_SOFTRESET_RESET   0xb6
+
+#define BMI088_GYRO_INT_CTRL   0x15
+# define BMI088_GYRO_INT_CTRL_DISABLE  0x00
+# define BMI088_GYRO_INT_CTRL_ENABLE   0x80
+
+#define BMI088_INT3_INT4_IO_CONF       0x16
+# define BMI088_INT3_INT4_IO_CONF_INT4_OD      3
+# define BMI088_INT3_INT4_IO_CONF_INT4_LVL     2
+# define BMI088_INT3_INT4_IO_CONF_INT3_OD      1
+# define BMI088_INT3_INT4_IO_CONF_INT3_LVL     0
+
+#define BMI088_INT3_INT4_IO_MAP                0x18
+# define BMI088_INT3_INT4_IO_MAP_NONE          0x00
+# define BMI088_INT3_INT4_IO_MAP_INT3          0x01
+# define BMI088_INT3_INT4_IO_MAP_INT4          0x80
+# define BMI088_INT3_INT4_IO_MAP_INT3_INT4     0x81
+
+#define BMI088_GYRO_SELF_TEST  0x3c
+# define BMI088_GYRO_SELF_TEST_RATE_OK         4
+# define BMI088_GYRO_SELF_TEST_BIST_FAIL       2
+# define BMI088_GYRO_SELF_TEST_BIST_RDY                1
+# define BMI088_GYRO_SELF_TEST_TRIG_BIST       0
+
+#define BMI088_GYRO_FULLSCALE  ((float) 2000.0f * (float) M_PI / 180.0f)
+
+static inline float
+ao_bmi088_gyro(float sensor) {
+       return sensor * ((float) (BMI088_GYRO_FULLSCALE / 32767.0));
+}
+
+#define ao_bmi_gyro_to_sample(gyro) ((gyro) * (32767.0f / (BMI088_GYRO_FULLSCALE
+
+#define BMI088_ACCEL_FULLSCALE 24
+
+static inline float
+ao_bmi088_accel(int16_t sensor) {
+       return (float) sensor * ((float) (BMI088_ACCEL_FULLSCALE * GRAVITY / 32767.0));
+}
+
+#define ao_bmi_accel_to_sample(accel) ((accel) * (32767.0f / (BMI088_ACCEL_FULLSCALE * GRAVITY)))
+
+#endif /* _AO_BMI088_H_ */
index 65e9a8c9cb76c4a70a6650eb7145a75682056885..03c810be49fe7f0bfe6a9210323ff342735ad93d 100644 (file)
@@ -87,6 +87,9 @@ ao_lco_set_armed(uint8_t armed);
 void
 ao_lco_set_firing(uint8_t firing);
 
+void
+ao_lco_pretend(void);
+
 void
 ao_lco_toggle_drag(void);
 
index c88170b8c91dec772d36747715b955978d502de0..acdea87e3328759d8b292864ee02e28be3497e64 100644 (file)
@@ -26,6 +26,8 @@ uint8_t               ao_lco_firing;                                  /* fire active */
 
 uint16_t       ao_lco_min_box, ao_lco_max_box;
 
+uint8_t                ao_lco_pretending;
+
 #if AO_LCO_DRAG
 uint8_t                ao_lco_drag_race;
 #endif
@@ -197,6 +199,7 @@ ao_lco_box_reset_present(void)
 {
        ao_lco_min_box = 0xff;
        ao_lco_max_box = 0x00;
+       ao_lco_pretending = 0;
        memset(ao_lco_box_mask, 0, sizeof (ao_lco_box_mask));
 }
 
@@ -223,8 +226,12 @@ void
 ao_lco_set_box(uint16_t new_box)
 {
        ao_lco_box = new_box;
-       if (ao_lco_box < AO_PAD_MAX_BOXES)
-               ao_lco_channels[ao_lco_box] = 0;
+       if (ao_lco_box < AO_PAD_MAX_BOXES) {
+               if (ao_lco_pretending)
+                       ao_lco_channels[ao_lco_box] = 0xff;
+               else
+                       ao_lco_channels[ao_lco_box] = 0;
+       }
        ao_lco_pad = 1;
        ao_lco_show();
 }
@@ -288,8 +295,8 @@ ao_lco_search(void)
 {
        int8_t          r;
        int8_t          try;
-       uint8_t         box;
-       uint8_t         boxes = 0;
+       uint16_t        box;
+       uint16_t        boxes = 0;
 
        ao_lco_box_reset_present();
        ao_lco_show_box(0);
@@ -304,7 +311,7 @@ ao_lco_search(void)
                        if (r == AO_RADIO_CMAC_OK) {
                                ++boxes;
                                ao_lco_box_set_present(box);
-                               ao_lco_show_pad(boxes % 10);
+                               ao_lco_show_pad((uint8_t) (boxes % 10));
                                ao_delay(AO_MS_TO_TICKS(30));
                                break;
                        }
@@ -319,6 +326,22 @@ ao_lco_search(void)
        ao_lco_set_box(ao_lco_min_box);
 }
 
+void
+ao_lco_pretend(void)
+{
+       uint16_t box;
+
+       ao_lco_pretending = 1;
+       ao_lco_min_box = 1;
+       ao_lco_max_box = AO_PAD_MAX_BOXES - 1;
+       for (box = ao_lco_min_box; box < ao_lco_max_box; box++)
+               ao_lco_box_set_present(box);
+       ao_lco_box = ao_lco_min_box;
+       memset(ao_lco_valid, 0, sizeof (ao_lco_valid));
+       memset(ao_lco_channels, 0, sizeof (ao_lco_channels));
+       ao_lco_set_box(ao_lco_min_box);
+}
+
 void
 ao_lco_monitor(void)
 {
index 895e1d3492173815ef2100e94a3be32cb5007795..dce7c0e6a3c5a5de8af7ccf570ee6b43c0c5f9b9 100644 (file)
@@ -148,7 +148,6 @@ static void
 ao_ms5607_isr(void)
 {
        ao_exti_disable(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN);
-       ao_ms5607_done = 1;
        ao_wakeup((void *) &ao_ms5607_done);
 }
 
@@ -156,26 +155,27 @@ static uint32_t
 ao_ms5607_get_sample(uint8_t cmd) {
        uint8_t reply[4];
 
-       ao_ms5607_done = 0;
-
        ao_ms5607_start();
-       ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX);
 
        ao_exti_enable(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN);
 
+       ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX);
+
 #if AO_MS5607_PRIVATE_PINS
-       ao_spi_put(AO_MS5607_SPI_INDEX);
+       ao_spi_put_pins(AO_MS5607_SPI_INDEX);
 #endif
        ao_arch_block_interrupts();
-       while (!ao_gpio_get(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN) &&
-              !ao_ms5607_done)
-       {
+#if !HAS_TASK
+#define ao_sleep_for(a,t) ao_sleep(a)
+#endif
+       while (!ao_gpio_get(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN)) {
                if (ao_sleep_for((void *) &ao_ms5607_done, AO_MS_TO_TICKS(10)))
                        break;
        }
+       ao_exti_disable(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN);
        ao_arch_release_interrupts();
 #if AO_MS5607_PRIVATE_PINS
-       ao_gpio_set(AO_MS5607_CS_PORT, AO_MS5607_CS_PIN, 1);
+       ao_spi_clr_cs(AO_MS5607_CS_PORT, 1 << (AO_MS5607_CS_PIN));
 #else
        ao_ms5607_stop();
 #endif
index b49d6a558db2b3b2eb0e18d6c950f42f5e4e04b5..8545c7d4ddfabfa10763d4b79095ef6bf410ad54 100644 (file)
 #define AO_DATA_BMX160 0
 #endif
 
+#if HAS_BMI088
+#include <ao_bmi088.h>
+#define AO_DATA_BMI088 (1 << 2)
+#else
+#define AO_DATA_BMI088 0
+#endif
+
 #ifndef HAS_SENSOR_ERRORS
 #if HAS_IMU || HAS_MMA655X || HAS_MS5607 || HAS_MS5611
 #define HAS_SENSOR_ERRORS      1
@@ -102,7 +109,7 @@ extern uint8_t                      ao_sensor_errors;
 
 #ifdef AO_DATA_RING
 
-#define AO_DATA_ALL    (AO_DATA_ADC|AO_DATA_MS5607|AO_DATA_MPU6000|AO_DATA_HMC5883|AO_DATA_MMA655X|AO_DATA_MPU9250|AO_DATA_ADXL375|AO_DATA_BMX160|AO_DATA_MMC5983)
+#define AO_DATA_ALL    (AO_DATA_ADC|AO_DATA_MS5607|AO_DATA_MPU6000|AO_DATA_HMC5883|AO_DATA_MMA655X|AO_DATA_MPU9250|AO_DATA_ADXL375|AO_DATA_BMX160|AO_DATA_MMC5983|AO_DATA_BMI088)
 
 struct ao_data {
        AO_TICK_TYPE                    tick;
@@ -149,6 +156,12 @@ struct ao_data {
        int16_t z_accel;
 #endif
 #endif
+#if HAS_BMI088
+       struct ao_bmi088_sample         bmi088;
+#if !HAS_ADXL375
+       int16_t z_accel;
+#endif
+#endif
 };
 
 #define ao_data_ring_next(n)   (((n) + 1) & (AO_DATA_RING - 1))
@@ -490,6 +503,29 @@ static inline float ao_convert_accel(int16_t sensor)
 
 #endif
 
+#if !HAS_GYRO && HAS_BMI088
+
+#define HAS_GYRO       1
+
+typedef int16_t        gyro_t;         /* in raw sample units */
+typedef int16_t angle_t;       /* in degrees */
+
+/* X axis is aligned with the direction of motion (along) */
+/* Y axis is aligned in the other board axis (across) */
+/* Z axis is aligned perpendicular to the board (through) */
+
+static inline float ao_convert_gyro(float sensor)
+{
+       return ao_bmi088_gyro(sensor);
+}
+
+static inline float ao_convert_accel(int16_t sensor)
+{
+       return ao_bmi088_accel(sensor);
+}
+
+#endif
+
 #if !HAS_MAG && HAS_HMC5883
 
 #define HAS_MAG                1
@@ -563,6 +599,9 @@ ao_data_fill(int head) {
 #endif
 #if HAS_BMX160
                ao_data_ring[head].bmx160 = ao_bmx160_current;
+#endif
+#if HAS_BMI088
+               ao_data_ring[head].bmi088 = ao_bmi088_current;
 #endif
                ao_data_ring[head].tick = ao_tick_count;
                ao_data_head = ao_data_ring_next(head);
index 1faea957639ce667ad44895b60dd22bf52b893d7..9df34b4e566cf383daf1c573e4458c9da1778afe 100644 (file)
@@ -61,6 +61,7 @@ extern enum ao_flight_state ao_log_state;
 #define AO_LOG_FORMAT_TELEMEGA_4       19      /* 32 byte typed telemega records with 32 bit gyro cal and Bmx160 */
 #define AO_LOG_FORMAT_EASYMOTOR                20      /* 16 byte typed easymotor records with pressure sensor and adxl375 */
 #define AO_LOG_FORMAT_TELEMEGA_5       21      /* 32 byte typed telemega records with 32 bit gyro cal, mpu6000 and mmc5983 */
+#define AO_LOG_FORMAT_TELEMEGA_6       22      /* 32 byte typed telemega records with 32 bit gyro cal, bmi088 and mmc5983 */
 #define AO_LOG_FORMAT_NONE             127     /* No log at all */
 
 /* Return the flight number from the given log slot, 0 if none, -slot on failure */
@@ -549,7 +550,7 @@ struct ao_log_motor {
        } u;
 };
 
-#if AO_LOG_FORMAT == AO_LOG_FOMAT_TELEMEGA_OLD || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_3 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_2 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_4 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_5
+#if AO_LOG_FORMAT == AO_LOG_FOMAT_TELEMEGA_OLD || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_3 || AO_LOG_FORMAT == AO_LOG_FORMAT_EASYMEGA_2 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_4 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_5 || AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_6
 typedef struct ao_log_mega ao_log_type;
 #endif
 
index 432f1b851c7918c00180db1cb4748acc1ab473df..ca7bc8bbaa1272d76bac21f0021399f050c5724f 100644 (file)
@@ -83,15 +83,23 @@ ao_log(void)
                                ao_log_data.u.sensor.pres = d->ms5607_raw.pres;
                                ao_log_data.u.sensor.temp = d->ms5607_raw.temp;
 #endif
-#if HAS_MPU6000
+
 #ifdef AO_LOG_NORMALIZED
+# if HAS_IMU
                                ao_log_data.u.sensor.accel_along = ao_data_along(d);
                                ao_log_data.u.sensor.accel_across = ao_data_across(d);
                                ao_log_data.u.sensor.accel_through = ao_data_through(d);
                                ao_log_data.u.sensor.gyro_roll = ao_data_roll(d);
                                ao_log_data.u.sensor.gyro_pitch = ao_data_pitch(d);
                                ao_log_data.u.sensor.gyro_yaw = ao_data_yaw(d);
-#else
+# endif
+# if HAS_MAG
+                               ao_log_data.u.sensor.mag_along = ao_data_mag_along(d);
+                               ao_log_data.u.sensor.mag_across = ao_data_mag_across(d);
+                               ao_log_data.u.sensor.mag_through = ao_data_mag_through(d);
+# endif
+#else  /* AO_LOG_NORMALIZED */
+#if HAS_MPU6000
                                ao_log_data.u.sensor.accel_x = d->mpu6000.accel_x;
                                ao_log_data.u.sensor.accel_y = d->mpu6000.accel_y;
                                ao_log_data.u.sensor.accel_z = d->mpu6000.accel_z;
@@ -99,17 +107,11 @@ ao_log(void)
                                ao_log_data.u.sensor.gyro_y = d->mpu6000.gyro_y;
                                ao_log_data.u.sensor.gyro_z = d->mpu6000.gyro_z;
 #endif
-#endif
 #if HAS_HMC5883
                                ao_log_data.u.sensor.mag_x = d->hmc5883.x;
                                ao_log_data.u.sensor.mag_z = d->hmc5883.z;
                                ao_log_data.u.sensor.mag_y = d->hmc5883.y;
 #endif
-#ifdef HAS_MMC5983
-                               ao_log_data.u.sensor.mag_along = ao_data_mag_along(d);
-                               ao_log_data.u.sensor.mag_across = ao_data_mag_across(d);
-                               ao_log_data.u.sensor.mag_through = ao_data_mag_through(d);
-#endif
 #if HAS_MPU9250
                                ao_log_data.u.sensor.accel_x = d->mpu9250.accel_x;
                                ao_log_data.u.sensor.accel_y = d->mpu9250.accel_y;
@@ -132,6 +134,7 @@ ao_log(void)
                                ao_log_data.u.sensor.mag_z = d->bmx160.mag_z;
                                ao_log_data.u.sensor.mag_y = d->bmx160.mag_y;
 #endif
+#endif /* !AO_LOG_NORMALIZED */
                                ao_log_data.u.sensor.accel = ao_data_accel(&ao_data_ring[ao_log_data_pos]);
                                ao_log_write(&ao_log_data);
                                if (ao_log_state <= ao_flight_coast)
index e0f4d8c22aea4f6399cf03c4b46ad3915b63b335..8586efd548f59cce09f4aa4b0de43a439471ba5b 100644 (file)
@@ -142,6 +142,8 @@ ao_send_mega_sensor(void)
 #if AO_LOG_NORMALIZED
 #if AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_5
        telemetry.generic.type = AO_TELEMETRY_MEGA_NORM_MPU6000_MMC5983;
+#elif AO_LOG_FORMAT == AO_LOG_FORMAT_TELEMEGA_6
+       telemetry.generic.type = AO_TELEMETRY_MEGA_NORM_BMI088_MMC5983;
 #else
 #error unknown normalized log type
 #endif
@@ -153,7 +155,7 @@ ao_send_mega_sensor(void)
        telemetry.mega_norm.pres = ao_data_pres(packet);
        telemetry.mega_norm.temp = ao_data_temp(packet);
 
-#if HAS_MPU6000
+#ifdef ao_data_along
        telemetry.mega_norm.accel_along = ao_data_along(packet);
        telemetry.mega_norm.accel_across = ao_data_across(packet);
        telemetry.mega_norm.accel_through = ao_data_through(packet);
@@ -163,7 +165,7 @@ ao_send_mega_sensor(void)
        telemetry.mega_norm.gyro_yaw = ao_data_yaw(packet);
 #endif
 
-#if HAS_MMC5983
+#ifdef ao_data_mag_along
        telemetry.mega_norm.mag_along = ao_data_mag_along(packet);
        telemetry.mega_norm.mag_across = ao_data_mag_across(packet);
        telemetry.mega_norm.mag_through = ao_data_mag_through(packet);
index 251a3fcda3fd36934d4e336617cbb20ef267fed9..983a99b8fd1cba7ef4adf0b4d41a047f9bb5f1e8 100644 (file)
@@ -298,6 +298,7 @@ struct ao_telemetry_mini {
 };
 
 #define AO_TELEMETRY_MEGA_NORM_MPU6000_MMC5983 0x13
+#define AO_TELEMETRY_MEGA_NORM_BMI088_MMC5983  0x14
 
 struct ao_telemetry_mega_norm {
        uint16_t        serial;         /*  0 */
index fba99c88b6931a4166eaa66c54d8ff5fbcec4f6c..538b98a002b7262e488ee1eddaef7e1ac99e4f65 100644 (file)
@@ -3,7 +3,9 @@
 #
 #
 
-include ../stmf0/Makefile.defs
+TOPDIR=..
+
+include $(TOPDIR)/stmf0/Makefile.defs
 
 INC = \
        ao.h \
@@ -13,8 +15,6 @@ INC = \
        ao_pins.h \
        ao_product.h \
        ao_task.h \
-       ao_lisp.h \
-       ao_lisp_const.h \
        stm32f0.h \
        Makefile
 
@@ -25,42 +25,24 @@ ALTOS_SRC = \
        ao_romconfig.c \
        ao_cmd.c \
        ao_config.c \
+       ao_data.c \
        ao_task.c \
        ao_led_stmf0.c \
-       ao_beep_stm.c \
        ao_dma_stm.c \
        ao_stdio.c \
        ao_panic.c \
        ao_timer.c \
        ao_mutex.c \
        ao_usb_stm.c \
-       ao_serial_stm.c \
        ao_flash_stm.c \
-       ao_lisp_atom.c \
-       ao_lisp_builtin.c \
-       ao_lisp_cons.c \
-       ao_lisp_error.c \
-       ao_lisp_eval.c \
-       ao_lisp_frame.c \
-       ao_lisp_int.c \
-       ao_lisp_lambda.c \
-       ao_lisp_lex.c \
-       ao_lisp_mem.c \
-       ao_lisp_poly.c \
-       ao_lisp_read.c \
-       ao_lisp_rep.c \
-       ao_lisp_save.c \
-       ao_lisp_stack.c \
-       ao_lisp_string.c \
-       ao_lisp_os_save.c
+       ao_spi_stm.c \
+       ao_bmi088.c
 
 PRODUCT=Nucleo-32
 PRODUCT_DEF=-DNUCLEO
 IDPRODUCT=0x000a
 
-CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS)
-
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Tload.ld -n
+CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) $(PROFILE_DEF)
 
 PROGNAME=nucleo-32
 PROG=$(PROGNAME)-$(VERSION).elf
@@ -72,20 +54,14 @@ OBJ=$(SRC:.c=.o)
 all: $(PROG) $(HEX)
 
 $(PROG): Makefile $(OBJ) altos.ld
-       $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+       $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS) -Wl,-Map=$(PROGNAME)-$(VERSION).map
 
 $(OBJ): $(INC)
 
-ao_product.h: ao-make-product.5c ../Version
-       $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
-
-load: $(PROG)
-       stm-load $(PROG)
-
 distclean:     clean
 
 clean:
-       rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+       rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx $(PROGNAME)-*.map
        rm -f ao_product.h
 
 install:
index 6b4cbaaed195d23687c6f670951fd35e96a0b53e..5854fe58860d8fa76525ce119967805d0d4a0117 100644 (file)
  */
 
 #include <ao.h>
-#include <ao_lisp.h>
-#include <ao_beep.h>
+#include <ao_bmi088.h>
 
-static void lisp_cmd() {
-       ao_lisp_read_eval_print();
-}
-
-static void beep() {
-       ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200));
-}
-
-static const struct ao_cmds blink_cmds[] = {
-       { lisp_cmd,     "l\0Run lisp interpreter" },
-       { beep,         "b\0Beep" },
-       { 0, 0 }
-};
+uint8_t        ao_sensor_errors;
 
-void main(void)
+int main(void)
 {
-       ao_led_init(LEDS_AVAILABLE);
+       ao_led_init();
        ao_clock_init();
        ao_task_init();
        ao_timer_init();
        ao_dma_init();
        ao_usb_init();
-       ao_serial_init();
-       ao_beep_init();
+       ao_spi_init();
+       ao_bmi088_init();
        ao_cmd_init();
-       ao_cmd_register(blink_cmds);
        ao_start_scheduler();
 }
 
index cee4616f08ceabd872beace2dcbd7782f8ae8665..0cc91d7334f5e0dcf91c89a0b8862fc6710dddf2 100644 (file)
 #define HAS_USB                                1
 #define AO_USB_DIRECTIO                        0
 #define AO_PA11_PA12_RMP               0
-#define HAS_BEEP                       1
-
-#define BEEPER_TIMER                   2
-#define BEEPER_CHANNEL                 4
-#define BEEPER_PORT                    (&stm_gpioa)
-#define BEEPER_PIN                     3
+#define HAS_BEEP                       0
 
 #define IS_FLASH_LOADER        0
 
-#define HAS_SERIAL_2           1
+#define HAS_SERIAL_2           0
 #define SERIAL_2_PA2_PA15      1
 #define USE_SERIAL_2_FLOW      0
 #define USE_SERIAL_2_STDIN     1
 #define DELAY_SERIAL_2_STDIN   0
 
+#define HAS_SPI_1      1
+#define SPI_1_PA5_PA6_PA7      1
+#define SPI_1_OSPEEDR          STM_OSPEEDR_HIGH
+#define SPI_1_PB3_PB4_PB5      0
+
+#define HAS_SPI_2      0
+
+#define HAS_BMI088     1
+#define HAS_IMU                1
+
+#define ao_data_along(packet)   ((packet)->bmi088.acc.x)
+#define ao_data_across(packet)  (-(packet)->bmi088.acc.y)
+#define ao_data_through(packet) ((packet)->bmi088.acc.z)
+
+#define ao_data_roll(packet)    ((packet)->bmi088.gyr.x)
+#define ao_data_pitch(packet)   (-(packet)->bmi088.gyr.y)
+#define ao_data_yaw(packet)     ((packet)->bmi088.gyr.z)
+
+#define AO_BMI088_ACC_CS_PORT  (&stm_gpioa)
+#define AO_BMI088_ACC_CS_PIN   0
+#define AO_BMI088_GYR_CS_PORT  (&stm_gpioa)
+#define AO_BMI088_GYR_CS_PIN   1
+#define AO_BMI088_SPI_BUS      (AO_SPI_1_PA5_PA6_PA7 | AO_SPI_MODE_0)
+
+#define AO_DATA_RING   32
+
 #endif /* _AO_PINS_H_ */
index 9f31a36fa6f9e8bc5a58b98f46b6b1ce3a2aa038..9922513be007bf005c19c9d9d1cd5021e3266300 100644 (file)
@@ -92,6 +92,9 @@ ao_spi_get(uint8_t spi_index, uint32_t speed);
 void
 ao_spi_put(uint8_t spi_index);
 
+void
+ao_spi_put_pins(uint8_t spi_index);
+
 void
 ao_spi_send(const void *block, uint16_t len, uint8_t spi_index);
 
index 0215f03ebd6a56bf173c16e16e8c0a53cd008955..ad8f55b5b0941f9955ad260b7c35ad144f07e40b 100644 (file)
@@ -427,6 +427,16 @@ ao_spi_put(uint8_t spi_index)
        ao_mutex_put(&ao_spi_mutex[id]);
 }
 
+void
+ao_spi_put_pins(uint8_t spi_index)
+{
+       uint8_t         id = AO_SPI_INDEX(spi_index);
+
+       ao_spi_disable_pin_config(ao_spi_pin_config[id]);
+       ao_spi_pin_config[id] = AO_SPI_CONFIG_NONE;
+       ao_spi_put(spi_index);
+}
+
 static void
 ao_spi_channel_init(uint8_t spi_index)
 {
index 8a173b57e5be79e928bebb5acf6ffb0bc1fa3d72..1a9f28e30ef0b68d4f7ac69fe846e16dea915bb5 100644 (file)
@@ -95,6 +95,9 @@ ao_spi_get(uint8_t spi_index, uint32_t speed);
 void
 ao_spi_put(uint8_t spi_index);
 
+void
+ao_spi_put_pins(uint8_t spi_index);
+
 void
 ao_spi_send(const void *block, uint16_t len, uint8_t spi_index);
 
index 0ce114cb0aeef99cffbc2297d70685bd5b1120df..ae4417a274f4b3cc1f628bbdfedfbdd047e58f60 100644 (file)
@@ -499,6 +499,16 @@ ao_spi_put(uint8_t spi_index)
        ao_mutex_put(&ao_spi_mutex[id]);
 }
 
+void
+ao_spi_put_pins(uint8_t spi_index)
+{
+       uint8_t         id = AO_SPI_INDEX(spi_index);
+
+       ao_spi_disable_pin_config(ao_spi_pin_config[id]);
+       ao_spi_pin_config[id] = AO_SPI_CONFIG_NONE;
+       ao_spi_put(spi_index);
+}
+
 static void
 ao_spi_channel_init(uint8_t spi_index)
 {
index 3583be98f9ec23a7586c1d4d00ce46237bd34f27..78849bc9b43bc00f551a70133aef6fbdcd66327a 100644 (file)
@@ -33,6 +33,9 @@
 
 /* UI values */
 static uint8_t ao_lco_select_mode;
+static uint8_t ao_lco_event_debug;
+
+#define PRINTE(...) do { if (!ao_lco_debug && !ao_lco_event_debug) break; printf ("\r%5lu %s: ", (unsigned long) ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } while(0)
 #define AO_LCO_SELECT_PAD      0
 #define AO_LCO_SELECT_BOX      1
 
@@ -176,7 +179,7 @@ ao_lco_input(void)
 
        for (;;) {
                ao_event_get(&event);
-               PRINTD("event type %d unit %d value %ld\n",
+               PRINTE("event type %d unit %d value %ld\n",
                       event.type, event.unit, (long) event.value);
                switch (event.type) {
                case AO_EVENT_QUADRATURE:
@@ -283,13 +286,16 @@ static void
 ao_lco_set_debug(void)
 {
        uint32_t r = ao_cmd_decimal();
-       if (ao_cmd_status == ao_cmd_success)
-               ao_lco_debug = r != 0;
+       if (ao_cmd_status == ao_cmd_success){
+               ao_lco_debug = r & 1;
+               ao_lco_event_debug = (r & 2) >> 1;
+       }
 }
 
 const struct ao_cmds ao_lco_cmds[] = {
        { ao_lco_set_debug,     "D <0 off, 1 on>\0Debug" },
        { ao_lco_search,        "s\0Search for pad boxes" },
+       { ao_lco_pretend,       "p\0Pretend there are lots of pad boxes" },
        { 0, NULL }
 };
 #endif
diff --git a/src/telemega-v6.0/ao_pins.h b/src/telemega-v6.0/ao_pins.h
new file mode 100644 (file)
index 0000000..da1dd15
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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_
+
+
+/* 16MHz High speed external crystal */
+#define AO_HSE                 16000000
+
+/* PLLVCO = 96MHz (so that USB will work) */
+#define AO_PLLMUL              6
+#define AO_RCC_CFGR_PLLMUL     (STM_RCC_CFGR_PLLMUL_6)
+
+/* 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      0
+
+#define HAS_SERIAL_2           1
+#define USE_SERIAL_2_STDIN     0
+#define SERIAL_2_PA2_PA3       1
+#define SERIAL_2_PD5_PD6       0
+#define USE_SERIAL_2_FLOW      0
+#define USE_SERIAL_2_SW_FLOW   0
+
+#define HAS_SERIAL_3           0
+#define USE_SERIAL_3_STDIN     0
+#define SERIAL_3_PB10_PB11     0
+#define SERIAL_3_PC10_PC11     0
+#define SERIAL_3_PD8_PD9       0
+
+#define ao_gps_getchar         ao_serial2_getchar
+#define ao_gps_putchar         ao_serial2_putchar
+#define ao_gps_set_speed       ao_serial2_set_speed
+#define ao_gps_fifo            (ao_stm_usart2.rx_fifo)
+
+#define AO_CONFIG_DEFAULT_FLIGHT_LOG_MAX       (1024 * 1024)
+#define AO_CONFIG_MAX_SIZE                     1024
+#define LOG_ERASE_MARK                         0x55
+#define LOG_MAX_ERASE                          128
+#define AO_LOG_FORMAT                          AO_LOG_FORMAT_TELEMEGA_6
+#define AO_LOG_NORMALIZED                      1
+
+#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               1
+#define BEEPER_TIMER           3
+#define BEEPER_CHANNEL         2
+#define BEEPER_PORT            (&stm_gpioe)
+#define BEEPER_PIN             4
+#define AO_BEEP_MID_DEFAULT    179             /* 2100 Hz */
+#define AO_BEEP_MAKE_LOW(m)    ((uint8_t) ((m) * 197U/179U)) /* 1900 Hz */
+#define AO_BEEP_MAKE_HIGH(m)   ((uint8_t) ((m) * 163U/179U)) /* 2300 Hz */
+#define HAS_BATTERY_REPORT     1
+#define HAS_RADIO              1
+#define HAS_TELEMETRY          1
+#define HAS_APRS               1
+#define HAS_COMPANION          1
+
+#define HAS_SPI_1              1
+#define SPI_1_PA5_PA6_PA7      1       /* Barometer */
+#define SPI_1_PB3_PB4_PB5      1       /* Accelerometer */
+#define SPI_1_PE13_PE14_PE15   1       /* MPU6000 */
+#define SPI_1_OSPEEDR          STM_OSPEEDR_10MHz
+
+//#define MMC5983_I2C          1
+
+#define HAS_SPI_2              1
+#define SPI_2_PB13_PB14_PB15   1       /* Flash, Companion */
+#ifndef MMC5983_I2C
+#define SPI_2_PD1_PD3_PD4      1       /* MMC5983 */
+#endif
+#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       1
+#define PACKET_HAS_MASTER      0
+
+#define LOW_LEVEL_DEBUG                0
+
+#define LED_PORT_ENABLE                STM_RCC_AHBENR_GPIOCEN
+#define LED_PORT               (&stm_gpioc)
+#define LED_PIN_RED            8
+#define LED_PIN_GREEN          9
+#define AO_LED_RED             (1 << LED_PIN_RED)
+#define AO_LED_GREEN           (1 << LED_PIN_GREEN)
+
+#define LEDS_AVAILABLE         (AO_LED_RED | AO_LED_GREEN)
+
+#define HAS_GPS                        1
+#define HAS_FLIGHT             1
+#define HAS_ADC                        1
+#define HAS_ADC_TEMP           1
+#define HAS_LOG                        1
+
+/*
+ * Igniter
+ */
+
+#define HAS_IGNITE             1
+#define HAS_IGNITE_REPORT      1
+
+#define AO_SENSE_PYRO(p,n)     ((p)->adc.sense[n])
+#define AO_SENSE_DROGUE(p)     ((p)->adc.sense[4])
+#define AO_SENSE_MAIN(p)       ((p)->adc.sense[5])
+#define AO_IGNITER_CLOSED      400
+#define AO_IGNITER_OPEN                60
+
+/* Pyro A */
+#define AO_PYRO_PORT_0 (&stm_gpiod)
+#define AO_PYRO_PIN_0  6
+
+/* Pyro B */
+#define AO_PYRO_PORT_1 (&stm_gpiod)
+#define AO_PYRO_PIN_1  7
+
+/* Pyro C */
+#define AO_PYRO_PORT_2 (&stm_gpioe)
+#define AO_PYRO_PIN_2  3
+
+/* Pyro D */
+#define AO_PYRO_PORT_3 (&stm_gpioe)
+#define AO_PYRO_PIN_3  2
+
+/* Drogue */
+#define AO_IGNITER_DROGUE_PORT (&stm_gpioe)
+#define AO_IGNITER_DROGUE_PIN  6
+
+/* Main */
+#define AO_IGNITER_MAIN_PORT   (&stm_gpioe)
+#define AO_IGNITER_MAIN_PIN    5
+
+/* Number of general purpose pyro channels available */
+#define AO_PYRO_NUM    4
+
+/*
+ * ADC
+ */
+#define AO_DATA_RING           32
+#define AO_ADC_NUM_SENSE       6
+
+struct ao_adc {
+       int16_t                 sense[AO_ADC_NUM_SENSE];
+       int16_t                 v_batt;
+       int16_t                 v_pbatt;
+       int16_t                 temp;
+};
+
+#define AO_ADC_DUMP(p) \
+       printf("tick: %5lu A: %5d B: %5d C: %5d D: %5d drogue: %5d main: %5d batt: %5d pbatt: %5d temp: %5d\n", \
+              (p)->tick, \
+              (p)->adc.sense[0], (p)->adc.sense[1], (p)->adc.sense[2], \
+              (p)->adc.sense[3], (p)->adc.sense[4], (p)->adc.sense[5], \
+              (p)->adc.v_batt, (p)->adc.v_pbatt, (p)->adc.temp)
+
+#define AO_ADC_SENSE_A         0
+#define AO_ADC_SENSE_A_PORT    (&stm_gpioa)
+#define AO_ADC_SENSE_A_PIN     0
+
+#define AO_ADC_SENSE_B         1
+#define AO_ADC_SENSE_B_PORT    (&stm_gpioa)
+#define AO_ADC_SENSE_B_PIN     1
+
+#define AO_ADC_SENSE_C         24
+#define AO_ADC_SENSE_C_PORT    (&stm_gpioe)
+#define AO_ADC_SENSE_C_PIN     9
+
+#define AO_ADC_SENSE_D         25
+#define AO_ADC_SENSE_D_PORT    (&stm_gpioe)
+#define AO_ADC_SENSE_D_PIN     10
+
+#define AO_ADC_SENSE_DROGUE    4
+#define AO_ADC_SENSE_DROGUE_PORT       (&stm_gpioa)
+#define AO_ADC_SENSE_DROGUE_PIN        4
+
+#define AO_ADC_SENSE_MAIN      22
+#define AO_ADC_SENSE_MAIN_PORT (&stm_gpioe)
+#define AO_ADC_SENSE_MAIN_PIN  7
+
+#define AO_ADC_V_BATT          8
+#define AO_ADC_V_BATT_PORT     (&stm_gpiob)
+#define AO_ADC_V_BATT_PIN      0
+
+#define AO_ADC_V_PBATT         9
+#define AO_ADC_V_PBATT_PORT    (&stm_gpiob)
+#define AO_ADC_V_PBATT_PIN     1
+
+#define AO_ADC_TEMP            16
+
+#define AO_ADC_RCC_AHBENR      ((1 << STM_RCC_AHBENR_GPIOAEN) | \
+                                (1 << STM_RCC_AHBENR_GPIOEEN) | \
+                                (1 << STM_RCC_AHBENR_GPIOBEN))
+
+#define AO_NUM_ADC_PIN         (AO_ADC_NUM_SENSE + 2)
+
+#define AO_ADC_PIN0_PORT       AO_ADC_SENSE_A_PORT
+#define AO_ADC_PIN0_PIN                AO_ADC_SENSE_A_PIN
+#define AO_ADC_PIN1_PORT       AO_ADC_SENSE_B_PORT
+#define AO_ADC_PIN1_PIN                AO_ADC_SENSE_B_PIN
+#define AO_ADC_PIN2_PORT       AO_ADC_SENSE_C_PORT
+#define AO_ADC_PIN2_PIN                AO_ADC_SENSE_C_PIN
+#define AO_ADC_PIN3_PORT       AO_ADC_SENSE_D_PORT
+#define AO_ADC_PIN3_PIN                AO_ADC_SENSE_D_PIN
+#define AO_ADC_PIN4_PORT       AO_ADC_SENSE_DROGUE_PORT
+#define AO_ADC_PIN4_PIN                AO_ADC_SENSE_DROGUE_PIN
+#define AO_ADC_PIN5_PORT       AO_ADC_SENSE_MAIN_PORT
+#define AO_ADC_PIN5_PIN                AO_ADC_SENSE_MAIN_PIN
+#define AO_ADC_PIN6_PORT       AO_ADC_V_BATT_PORT
+#define AO_ADC_PIN6_PIN                AO_ADC_V_BATT_PIN
+#define AO_ADC_PIN7_PORT       AO_ADC_V_PBATT_PORT
+#define AO_ADC_PIN7_PIN                AO_ADC_V_PBATT_PIN
+
+#define AO_NUM_ADC             (AO_ADC_NUM_SENSE + 3)
+
+#define AO_ADC_SQ1             AO_ADC_SENSE_A
+#define AO_ADC_SQ2             AO_ADC_SENSE_B
+#define AO_ADC_SQ3             AO_ADC_SENSE_C
+#define AO_ADC_SQ4             AO_ADC_SENSE_D
+#define AO_ADC_SQ5             AO_ADC_SENSE_DROGUE
+#define AO_ADC_SQ6             AO_ADC_SENSE_MAIN
+#define AO_ADC_SQ7             AO_ADC_V_BATT
+#define AO_ADC_SQ8             AO_ADC_V_PBATT
+#define AO_ADC_SQ9             AO_ADC_TEMP
+
+/*
+ * Voltage divider on ADC battery sampler
+ */
+#define AO_BATTERY_DIV_PLUS    56      /* 5.6k */
+#define AO_BATTERY_DIV_MINUS   100     /* 10k */
+
+/*
+ * Voltage divider on ADC igniter samplers
+ */
+#define AO_IGNITE_DIV_PLUS     100     /* 100k */
+#define AO_IGNITE_DIV_MINUS    27      /* 27k */
+
+/*
+ * ADC reference in decivolts
+ */
+#define AO_ADC_REFERENCE_DV    33
+
+/*
+ * Pressure sensor settings
+ */
+#define HAS_MS5607             1
+#define HAS_MS5611             0
+#define AO_MS5607_PRIVATE_PINS 1
+#define AO_MS5607_CS_PORT      (&stm_gpioc)
+#define AO_MS5607_CS_PIN       4
+#define AO_MS5607_CS_MASK      (1 << AO_MS5607_CS)
+#define AO_MS5607_MISO_PORT    (&stm_gpioa)
+#define AO_MS5607_MISO_PIN     6
+#define AO_MS5607_MISO_MASK    (1 << AO_MS5607_MISO)
+#define AO_MS5607_SPI_INDEX    AO_SPI_1_PA5_PA6_PA7
+
+/*
+ * SPI Flash memory
+ */
+
+#define M25_MAX_CHIPS          1
+#define AO_M25_SPI_CS_PORT     (&stm_gpiod)
+#define AO_M25_SPI_CS_MASK     (1 << 10)
+#define AO_M25_SPI_BUS         AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Radio (cc1200)
+ */
+
+/* gets pretty close to 434.550 */
+
+#define AO_RADIO_CAL_DEFAULT   5695733
+
+#define AO_FEC_DEBUG           0
+#define AO_CC1200_SPI_CS_PORT  (&stm_gpioc)
+#define AO_CC1200_SPI_CS_PIN   5
+#define AO_CC1200_SPI_BUS      AO_SPI_2_PB13_PB14_PB15
+#define AO_CC1200_SPI          stm_spi2
+
+#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 AO_CC1200_MARC_GPIO    3
+#define AO_CC1200_MARC_GPIO_IOCFG      CC1200_IOCFG3
+
+#define HAS_BOOT_RADIO         0
+
+
+/*
+ *
+ * If the board is laying component side up with
+ * the antenna (nose) pointing north
+ *
+ * +along      north   +roll   left up
+ * +across     west    +pitch  nose down
+ * +through    up      +yaw    left turn
+ */
+
+/*
+ * bmi088
+ *
+ *     pin 1 NE corner of chip
+ *
+ *     +along          +Y      +roll   +Y
+ *     +across         -X      +pitch  -X
+ *     +through        +Z      +yaw    +Z
+ */
+
+#define HAS_BMI088             1
+#define AO_BMI088_SPI_BUS      AO_SPI_1_PE13_PE14_PE15
+#define AO_BMI088_ACC_CS_PORT  (&stm_gpioc)
+#define AO_BMI088_ACC_CS_PIN   14
+#define AO_BMI088_GYR_CS_PORT  (&stm_gpioc)
+#define AO_BMI088_GYR_CS_PIN   13
+#define HAS_IMU                        1
+
+#define ao_bmi088_along(m)     ((m)->acc.y)
+#define ao_bmi088_across(m)    (-(m)->acc.x)
+#define ao_bmi088_through(m)   ((m)->acc.z)
+
+#define ao_bmi088_roll(m)      ((m)->gyr.y)
+#define ao_bmi088_pitch(m)     (-(m)->gyr.x)
+#define ao_bmi088_yaw(m)       ((m)->gyr.z)
+
+#define ao_data_along(packet)  ao_bmi088_along(&(packet)->bmi088)
+#define ao_data_across(packet) ao_bmi088_across(&(packet)->bmi088)
+#define ao_data_through(packet)        ao_bmi088_through(&(packet)->bmi088)
+
+#define ao_data_roll(packet)   ao_bmi088_roll(&(packet)->bmi088)
+#define ao_data_pitch(packet)  ao_bmi088_pitch(&(packet)->bmi088)
+#define ao_data_yaw(packet)    ao_bmi088_yaw(&(packet)->bmi088)
+
+/*
+ * MMC5983
+ *
+ *     pin 1 NE corner of chip
+ *
+ *     +along          -Y
+ *     +across         +X
+ *     +through        -Z
+ */
+
+#define HAS_MMC5983            1
+#define AO_MMC5983_INT_PORT    (&stm_gpiod)
+#define AO_MMC5983_INT_PIN     5
+#define AO_MMC5983_SPI_CLK_PORT        (&stm_gpiod)
+#define AO_MMC5983_SPI_CLK_PIN 1
+#define AO_MMC5983_SPI_MISO_PORT       (&stm_gpiod)
+#define AO_MMC5983_SPI_MISO_PIN        3
+#define AO_MMC5983_SPI_MOSI_PORT       (&stm_gpiod)
+#define AO_MMC5983_SPI_MOSI_PIN        4
+#define AO_MMC5983_SPI_INDEX   (AO_SPI_2_PD1_PD3_PD4 | AO_SPI_MODE_3)
+#define AO_MMC5983_SPI_CS_PORT (&stm_gpioa)
+#define AO_MMC5983_SPI_CS_PIN  15
+
+#define ao_mmc5983_along(m)            (-(m)->y)
+#define ao_mmc5983_across(m)           ((m)->x)
+#define ao_mmc5983_through(m)          (-(m)->z)
+
+#define ao_data_mag_along(packet)      ao_mmc5983_along(&(packet)->mmc5983)
+#define ao_data_mag_across(packet)     ao_mmc5983_across(&(packet)->mmc5983)
+#define ao_data_mag_through(packet)    ao_mmc5983_through(&(packet)->mmc5983)
+
+/*
+ * ADXL375
+ *
+ * pin 1 NW corner of chip
+ *
+ *     +along          +X
+ *     +across         +Y
+ *     +through        +Z
+ */
+
+#define HAS_ADXL375            1
+#define AO_ADXL375_SPI_INDEX   (AO_SPI_1_PB3_PB4_PB5 | AO_SPI_MODE_3)
+#define AO_ADXL375_CS_PORT     (&stm_gpioc)
+#define AO_ADXL375_CS_PIN      0
+
+#define AO_ADXL375_AXIS                x
+#define AO_ADXL375_INVERT      1
+
+#define NUM_CMDS               16
+
+/*
+ * Companion
+ */
+
+#define AO_COMPANION_CS_PORT   (&stm_gpiob)
+#define AO_COMPANION_CS_PIN_0  (6)
+#define AO_COMPANION_CS_PIN    AO_COMPANION_CS_PIN_0
+#define AO_COMPANION_CS_PIN_1  (7)
+#define AO_COMPANION_SPI_BUS   AO_SPI_2_PB13_PB14_PB15
+
+/*
+ * Monitor
+ */
+
+#define HAS_MONITOR            0
+#define LEGACY_MONITOR         0
+#define HAS_MONITOR_PUT                1
+#define AO_MONITOR_LED         0
+#define HAS_RSSI               0
+
+/*
+ * Profiling Viterbi decoding
+ */
+
+#ifndef AO_PROFILE
+#define AO_PROFILE             0
+#endif
+
+/*
+ * PWM output
+ */
+
+#define NUM_PWM                        4
+#define PWM_MAX                        20000
+#define AO_PWM_TIMER           stm_tim4
+#define AO_PWM_TIMER_ENABLE    STM_RCC_APB1ENR_TIM4EN
+#define AO_PWM_TIMER_SCALE     32
+
+#define AO_PWM_0_GPIO          (&stm_gpiod)
+#define AO_PWM_0_PIN           12
+
+#define AO_PWM_1_GPIO          (&stm_gpiod)
+#define AO_PWM_1_PIN           13
+
+#define AO_PWM_2_GPIO          (&stm_gpiod)
+#define AO_PWM_2_PIN           15
+
+#define AO_PWM_3_GPIO          (&stm_gpiod)
+#define AO_PWM_3_PIN           14
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telemega-v6.0/ao_telemega.c b/src/telemega-v6.0/ao_telemega.c
new file mode 100644 (file)
index 0000000..91526a8
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <ao.h>
+#include <ao_bmi088.h>
+#include <ao_mmc5983.h>
+#include <ao_adxl375.h>
+#include <ao_log.h>
+#include <ao_exti.h>
+#include <ao_packet.h>
+#include <ao_companion.h>
+#include <ao_profile.h>
+#include <ao_eeprom.h>
+#include <ao_i2c_bit.h>
+#if HAS_SAMPLE_PROFILE
+#include <ao_sample_profile.h>
+#endif
+#include <ao_pyro.h>
+#if HAS_STACK_GUARD
+#include <ao_mpu.h>
+#endif
+#include <ao_pwm.h>
+
+int
+main(void)
+{
+       ao_clock_init();
+
+#if HAS_STACK_GUARD
+       ao_mpu_init();
+#endif
+
+       ao_task_init();
+       ao_serial_init();
+       ao_led_init();
+       ao_led_on(LEDS_AVAILABLE);
+       ao_timer_init();
+
+       ao_spi_init();
+#ifdef MMC5983_I2C
+       ao_i2c_bit_init();
+#endif
+       ao_dma_init();
+       ao_exti_init();
+
+       ao_adc_init();
+#if HAS_BEEP
+       ao_beep_init();
+#endif
+       ao_cmd_init();
+
+       ao_ms5607_init();
+       ao_bmi088_init();
+       ao_mmc5983_init();
+       ao_adxl375_init();
+
+       ao_eeprom_init();
+       ao_storage_init();
+
+       ao_flight_init();
+       ao_log_init();
+       ao_report_init();
+
+       ao_usb_init();
+       ao_gps_init();
+       ao_gps_report_mega_init();
+       ao_telemetry_init();
+       ao_radio_init();
+       ao_packet_slave_init(false);
+       ao_igniter_init();
+       ao_companion_init();
+       ao_pyro_init();
+
+       ao_config_init();
+#if AO_PROFILE
+       ao_profile_init();
+#endif
+#if HAS_SAMPLE_PROFILE
+       ao_sample_profile_init();
+#endif
+
+       ao_pwm_init();
+
+       ao_led_off(LEDS_AVAILABLE);
+
+       ao_start_scheduler();
+       return 0;
+}
diff --git a/src/telemega-v6.0/flash-loader/ao_pins.h b/src/telemega-v6.0/flash-loader/ao_pins.h
new file mode 100644 (file)
index 0000000..46ba162
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2021 Keith Packard <keithp@keithp.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 16MHz */
+#define AO_HSE         16000000
+
+#include <ao_flash_stm_pins.h>
+
+/* Companion port cs_companion0 PB6 */
+
+#define AO_BOOT_PIN                    1
+#define AO_BOOT_APPLICATION_GPIO       stm_gpiob
+#define AO_BOOT_APPLICATION_PIN                6
+#define AO_BOOT_APPLICATION_VALUE      1
+#define AO_BOOT_APPLICATION_MODE       AO_EXTI_MODE_PULL_UP
+
+#endif /* _AO_PINS_H_ */