diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 1 | ||||
-rw-r--r-- | src/drivers/ao_companion.c | 4 | ||||
-rw-r--r-- | src/drivers/ao_lco.c | 475 | ||||
-rw-r--r-- | src/drivers/ao_lco_cmd.c | 2 | ||||
-rw-r--r-- | src/drivers/ao_lco_func.c | 11 | ||||
-rw-r--r-- | src/drivers/ao_lco_func.h | 2 | ||||
-rw-r--r-- | src/drivers/ao_pad.c | 10 | ||||
-rw-r--r-- | src/drivers/ao_pwm.h | 29 | ||||
-rw-r--r-- | src/drivers/ao_seven_segment.c | 17 | ||||
-rw-r--r-- | src/drivers/ao_seven_segment.h | 3 | ||||
-rw-r--r-- | src/easymega-v1.0/ao_pins.h | 1 | ||||
-rw-r--r-- | src/kernel/ao_telemetry.c | 27 | ||||
-rw-r--r-- | src/stm/ao_pwm_stm.c | 192 | ||||
-rw-r--r-- | src/stm/stm32l.h | 4 | ||||
-rw-r--r-- | src/teleballoon-v2.0/ao_pins.h | 1 | ||||
-rw-r--r-- | src/telemega-v0.1/ao_pins.h | 1 | ||||
-rw-r--r-- | src/telemega-v1.0/ao_pins.h | 1 | ||||
-rw-r--r-- | src/telemega-v2.0/.gitignore | 2 | ||||
-rw-r--r-- | src/telemega-v2.0/Makefile | 156 | ||||
-rw-r--r-- | src/telemega-v2.0/ao_pins.h | 407 | ||||
-rw-r--r-- | src/telemega-v2.0/ao_telemega.c | 105 | ||||
-rw-r--r-- | src/telemega-v2.0/flash-loader/Makefile | 8 | ||||
-rw-r--r-- | src/telemega-v2.0/flash-loader/ao_pins.h | 34 | ||||
-rw-r--r-- | src/telemetrum-v2.0/ao_pins.h | 1 |
24 files changed, 1359 insertions, 135 deletions
diff --git a/src/Makefile b/src/Makefile index dc74bf8c..ebe1df9c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -29,6 +29,7 @@ ARMM3DIRS=\ easymega-v1.0 easymega-v1.0/flash-loader \ telemega-v0.1 telemega-v0.1/flash-loader \ telemega-v1.0 telemega-v1.0/flash-loader \ + telemega-v2.0 telemega-v2.0/flash-loader \ telemetrum-v2.0 telemetrum-v2.0/flash-loader \ megadongle-v0.1 megadongle-v0.1/flash-loader \ telegps-v0.3 telegps-v0.3/flash-loader \ diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index 7e02939b..5f07e8b0 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -23,6 +23,10 @@ #define ao_spi_fast(b) #endif +#if !HAS_COMPANION +#error HAS_COMPANION not set in ao_companion.c +#endif + #define COMPANION_SELECT() do { \ ao_spi_get_bit(AO_COMPANION_CS_PORT, \ AO_COMPANION_CS_PIN, \ diff --git a/src/drivers/ao_lco.c b/src/drivers/ao_lco.c index b8698a80..6c192537 100644 --- a/src/drivers/ao_lco.c +++ b/src/drivers/ao_lco.c @@ -36,28 +36,70 @@ static uint8_t ao_lco_debug; #define AO_LCO_BOX_DIGIT_1 1 #define AO_LCO_BOX_DIGIT_10 2 +#define AO_LCO_DRAG_RACE_START_TIME AO_SEC_TO_TICKS(5) +#define AO_LCO_DRAG_RACE_STOP_TIME AO_SEC_TO_TICKS(2) + +#define AO_LCO_VALID_LAST 1 +#define AO_LCO_VALID_EVER 2 + static uint8_t ao_lco_min_box, ao_lco_max_box; -static uint8_t ao_lco_pad; -static uint8_t ao_lco_box; +static uint8_t ao_lco_selected[AO_PAD_MAX_BOXES]; +static uint8_t ao_lco_valid[AO_PAD_MAX_BOXES]; +static uint8_t ao_lco_channels[AO_PAD_MAX_BOXES]; +static uint16_t ao_lco_tick_offset[AO_PAD_MAX_BOXES]; + +/* UI values */ static uint8_t ao_lco_armed; static uint8_t ao_lco_firing; -static uint8_t ao_lco_valid; -static uint8_t ao_lco_got_channels; -static uint16_t ao_lco_tick_offset; +static uint16_t ao_lco_fire_tick; +static uint8_t ao_lco_fire_down; +static uint8_t ao_lco_drag_race; +static uint8_t ao_lco_pad; +static int16_t ao_lco_box; + +#define AO_LCO_BOX_DRAG 0x1000 static struct ao_pad_query ao_pad_query; +static uint8_t ao_lco_display_mutex; + static void ao_lco_set_pad(uint8_t pad) { - ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad); + ao_mutex_get(&ao_lco_display_mutex); + ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad | (ao_lco_drag_race << 4)); + ao_mutex_put(&ao_lco_display_mutex); } +#define SEVEN_SEGMENT_d ((0 << 0) | \ + (0 << 1) | \ + (1 << 2) | \ + (1 << 3) | \ + (1 << 4) | \ + (1 << 5) | \ + (1 << 6)) + + +#define SEVEN_SEGMENT_r ((0 << 0) | \ + (0 << 1) | \ + (0 << 2) | \ + (1 << 3) | \ + (1 << 4) | \ + (0 << 5) | \ + (0 << 6)) + static void -ao_lco_set_box(uint8_t box) +ao_lco_set_box(uint16_t box) { - ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, box % 10); - ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10); + ao_mutex_get(&ao_lco_display_mutex); + if (box == AO_LCO_BOX_DRAG) { + ao_seven_segment_direct(AO_LCO_BOX_DIGIT_10, SEVEN_SEGMENT_d | (ao_lco_drag_race << 7)); + ao_seven_segment_direct(AO_LCO_BOX_DIGIT_1, SEVEN_SEGMENT_r | (ao_lco_drag_race << 7)); + } else { + ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, box % 10 | (ao_lco_drag_race << 4)); + ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10 | (ao_lco_drag_race << 4)); + } + ao_mutex_put(&ao_lco_display_mutex); } static void @@ -68,18 +110,23 @@ ao_lco_set_voltage(uint16_t decivolts) tenths = decivolts % 10; ones = (decivolts / 10) % 10; tens = (decivolts / 100) % 10; + ao_mutex_get(&ao_lco_display_mutex); ao_seven_segment_set(AO_LCO_PAD_DIGIT, tenths); ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, ones | 0x10); ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, tens); + ao_mutex_put(&ao_lco_display_mutex); } static void ao_lco_set_display(void) { - if (ao_lco_pad == 0) { + if (ao_lco_pad == 0 && ao_lco_box != AO_LCO_BOX_DRAG) { ao_lco_set_voltage(ao_pad_query.battery); } else { - ao_lco_set_pad(ao_lco_pad); + if (ao_lco_box == AO_LCO_BOX_DRAG) + ao_lco_set_pad(ao_lco_drag_race); + else + ao_lco_set_pad(ao_lco_pad); ao_lco_set_box(ao_lco_box); } } @@ -91,42 +138,205 @@ ao_lco_set_display(void) static uint8_t ao_lco_box_mask[MASK_SIZE(AO_PAD_MAX_BOXES)]; static uint8_t -ao_lco_box_present(uint8_t box) +ao_lco_box_present(uint16_t box) { + if (box == AO_LCO_BOX_DRAG) + return 1; + if (box >= AO_PAD_MAX_BOXES) return 0; return (ao_lco_box_mask[MASK_ID(box)] >> MASK_SHIFT(box)) & 1; } static uint8_t -ao_lco_pad_present(uint8_t pad) +ao_lco_pad_present(uint8_t box, uint8_t pad) { - if (!ao_lco_got_channels || !ao_pad_query.channels) - return pad == 0; /* voltage measurement is always valid */ if (pad == 0) return 1; + if (!ao_lco_channels[box]) + return 0; if (pad > AO_PAD_MAX_CHANNELS) return 0; - return (ao_pad_query.channels >> (pad - 1)) & 1; + return (ao_lco_channels[box] >> (pad - 1)) & 1; } static uint8_t -ao_lco_pad_first(void) +ao_lco_pad_first(uint8_t box) { uint8_t pad; for (pad = 1; pad <= AO_PAD_MAX_CHANNELS; pad++) - if (ao_lco_pad_present(pad)) + if (ao_lco_pad_present(box, pad)) return pad; return 0; } +static struct ao_task ao_lco_drag_task; +static uint8_t ao_lco_drag_active; +static uint8_t ao_lco_drag_beep_count; +static uint8_t ao_lco_drag_beep_on; +static uint16_t ao_lco_drag_beep_time; +static uint16_t ao_lco_drag_warn_time; + +#define AO_LCO_DRAG_BEEP_TIME AO_MS_TO_TICKS(50) +#define AO_LCO_DRAG_WARN_TIME AO_SEC_TO_TICKS(5) + +static void +ao_lco_drag_beep_start(void) +{ + ao_beep(AO_BEEP_HIGH); + PRINTD("beep start\n"); + ao_lco_drag_beep_on = 1; + ao_lco_drag_beep_time = ao_time() + AO_LCO_DRAG_BEEP_TIME; +} + +static void +ao_lco_drag_beep_stop(void) +{ + ao_beep(0); + PRINTD("beep stop\n"); + ao_lco_drag_beep_on = 0; + if (ao_lco_drag_beep_count) { + --ao_lco_drag_beep_count; + if (ao_lco_drag_beep_count) + ao_lco_drag_beep_time = ao_time() + AO_LCO_DRAG_BEEP_TIME; + } +} + +static void +ao_lco_drag_beep(uint8_t beeps) +{ + PRINTD("beep %d\n", beeps); + if (!ao_lco_drag_beep_count) + ao_lco_drag_beep_start(); + ao_lco_drag_beep_count += beeps; +} + +static uint16_t +ao_lco_drag_beep_check(uint16_t now, uint16_t delay) +{ + PRINTD("beep check count %d delta %d\n", + ao_lco_drag_beep_count, + (int16_t) (now - ao_lco_drag_beep_time)); + if (ao_lco_drag_beep_count) { + if ((int16_t) (now - ao_lco_drag_beep_time) >= 0) { + if (ao_lco_drag_beep_on) + ao_lco_drag_beep_stop(); + else + ao_lco_drag_beep_start(); + } + } + + if (ao_lco_drag_beep_count) { + if (delay > AO_LCO_DRAG_BEEP_TIME) + delay = AO_LCO_DRAG_BEEP_TIME; + } + return delay; +} + +static void +ao_lco_drag_enable(void) +{ + PRINTD("Drag enable\n"); + ao_lco_drag_race = 1; + memset(ao_lco_selected, 0, sizeof (ao_lco_selected)); + ao_lco_drag_beep(5); + ao_lco_set_display(); + ao_lco_fire_down = 0; +} + +static void +ao_lco_drag_disable(void) +{ + PRINTD("Drag disable\n"); + ao_lco_drag_race = 0; + memset(ao_lco_selected, 0, sizeof (ao_lco_selected)); + ao_lco_drag_beep(2); + ao_lco_set_display(); + ao_lco_fire_down = 0; +} + +static uint16_t +ao_lco_drag_button_check(uint16_t now, uint16_t delay) +{ + uint16_t button_delay = ~0; + + /* + * Check to see if the button has been held down long enough + * to switch in/out of drag race mode + */ + if (ao_lco_fire_down) { + if (ao_lco_drag_race) { + if ((int16_t) (now - ao_lco_fire_tick) >= AO_LCO_DRAG_RACE_STOP_TIME) + ao_lco_drag_disable(); + else + button_delay = ao_lco_fire_tick + AO_LCO_DRAG_RACE_STOP_TIME - now; + } else { + if ((int16_t) (now - ao_lco_fire_tick) >= AO_LCO_DRAG_RACE_START_TIME) + ao_lco_drag_enable(); + else + button_delay = ao_lco_fire_tick + AO_LCO_DRAG_RACE_START_TIME - now; + } + if (delay > button_delay) + delay = button_delay; + } + return delay; +} + +static uint16_t +ao_lco_drag_warn_check(uint16_t now, uint16_t delay) +{ + uint16_t warn_delay = ~0; + + if (ao_lco_drag_race) { + if ((int16_t) (now - ao_lco_drag_warn_time) >= 0) { + ao_lco_drag_beep(1); + ao_lco_drag_warn_time = now + AO_LCO_DRAG_WARN_TIME; + } + warn_delay = ao_lco_drag_warn_time - now; + } + if (delay > warn_delay) + delay = warn_delay; + return delay; +} + +static void +ao_lco_drag_monitor(void) +{ + uint16_t delay = ~0; + uint16_t now; + + for (;;) { + PRINTD("Drag monitor active %d delay %d\n", ao_lco_drag_active, delay); + if (delay == (uint16_t) ~0) + ao_sleep(&ao_lco_drag_active); + else + ao_sleep_for(&ao_lco_drag_active, delay); + + delay = ~0; + if (!ao_lco_drag_active) + continue; + + now = ao_time(); + delay = ao_lco_drag_button_check(now, delay); + delay = ao_lco_drag_warn_check(now, delay); + delay = ao_lco_drag_beep_check(now, delay); + + /* check to see if there's anything left to do here */ + if (!ao_lco_fire_down && !ao_lco_drag_race && !ao_lco_drag_beep_count) { + delay = ~0; + ao_lco_drag_active = 0; + } + } +} + static void ao_lco_input(void) { static struct ao_event event; - int8_t dir, new_box, new_pad; + int8_t dir, new_pad; + int16_t new_box; ao_beep_for(AO_BEEP_MID, AO_MS_TO_TICKS(200)); for (;;) { @@ -148,7 +358,7 @@ ao_lco_input(void) new_pad = AO_PAD_MAX_CHANNELS; if (new_pad == ao_lco_pad) break; - } while (!ao_lco_pad_present(new_pad)); + } while (!ao_lco_pad_present(ao_lco_box, new_pad)); if (new_pad != ao_lco_pad) { ao_lco_pad = new_pad; ao_lco_set_display(); @@ -160,18 +370,26 @@ ao_lco_input(void) dir = (int8_t) event.value; new_box = ao_lco_box; do { - new_box += dir; - if (new_box > ao_lco_max_box) - new_box = ao_lco_min_box; - else if (new_box < ao_lco_min_box) - new_box = ao_lco_max_box; + if (new_box == AO_LCO_BOX_DRAG) { + if (dir < 0) + new_box = ao_lco_max_box; + else + new_box = ao_lco_min_box; + } else { + new_box += dir; + if (new_box > ao_lco_max_box) + new_box = AO_LCO_BOX_DRAG; + else if (new_box < ao_lco_min_box) + new_box = AO_LCO_BOX_DRAG; + } if (new_box == ao_lco_box) break; } while (!ao_lco_box_present(new_box)); if (ao_lco_box != new_box) { ao_lco_box = new_box; ao_lco_pad = 1; - ao_lco_got_channels = 0; + if (ao_lco_box != AO_LCO_BOX_DRAG) + ao_lco_channels[ao_lco_box] = 0; ao_lco_set_display(); } } @@ -183,13 +401,53 @@ ao_lco_input(void) case AO_BUTTON_ARM: ao_lco_armed = event.value; PRINTD("Armed %d\n", ao_lco_armed); + if (ao_lco_armed) { + if (ao_lco_drag_race) { + uint8_t box; + + for (box = ao_lco_min_box; box <= ao_lco_max_box; box++) { + if (ao_lco_selected[box]) { + ao_wakeup(&ao_lco_armed); + break; + } + } + } else { + memset(ao_lco_selected, 0, sizeof (ao_lco_selected)); + if (ao_lco_pad != 0 && ao_lco_box != AO_LCO_BOX_DRAG) + ao_lco_selected[ao_lco_box] = (1 << (ao_lco_pad - 1)); + else + ao_lco_armed = 0; + } + } ao_wakeup(&ao_lco_armed); break; case AO_BUTTON_FIRE: if (ao_lco_armed) { + ao_lco_fire_down = 0; ao_lco_firing = event.value; PRINTD("Firing %d\n", ao_lco_firing); ao_wakeup(&ao_lco_armed); + } else { + if (event.value) { + if (ao_lco_box == AO_LCO_BOX_DRAG) { + ao_lco_fire_down = 1; + ao_lco_fire_tick = ao_time(); + ao_lco_drag_active = 1; + } + if (ao_lco_drag_race) { + if (ao_lco_pad != 0 && ao_lco_box != AO_LCO_BOX_DRAG) { + ao_lco_selected[ao_lco_box] ^= (1 << (ao_lco_pad - 1)); + PRINTD("Toggle box %d pad %d (pads now %x) to drag race\n", + ao_lco_pad, ao_lco_box, ao_lco_selected[ao_lco_box]); + ao_lco_drag_beep(ao_lco_pad); + } + } + ao_wakeup(&ao_lco_drag_active); + } else { + ao_lco_fire_down = 0; + if (ao_lco_drag_active) + ao_wakeup(&ao_lco_drag_active); + } } break; } @@ -225,37 +483,38 @@ static AO_LED_TYPE continuity_led[AO_LED_CONTINUITY_NUM] = { #endif }; -static void -ao_lco_update(void) +static uint8_t +ao_lco_get_channels(uint8_t box, struct ao_pad_query *query) { int8_t r; - uint8_t c; - r = ao_lco_query(ao_lco_box, &ao_pad_query, &ao_lco_tick_offset); + r = ao_lco_query(box, query, &ao_lco_tick_offset[box]); if (r == AO_RADIO_CMAC_OK) { - c = ao_lco_got_channels; - ao_lco_got_channels = 1; - ao_lco_valid = 1; - if (!c) { - if (ao_lco_pad != 0) - ao_lco_pad = ao_lco_pad_first(); - ao_lco_set_display(); - } - if (ao_lco_pad == 0) - ao_lco_set_display(); + ao_lco_channels[box] = query->channels; + ao_lco_valid[box] = AO_LCO_VALID_LAST | AO_LCO_VALID_EVER; } else - ao_lco_valid = 0; - -#if 0 - PRINTD("lco_query success arm_status %d i0 %d i1 %d i2 %d i3 %d\n", - query.arm_status, - query.igniter_status[0], - query.igniter_status[1], - query.igniter_status[2], - query.igniter_status[3]); -#endif - PRINTD("ao_lco_update valid %d\n", ao_lco_valid); + ao_lco_valid[box] &= ~AO_LCO_VALID_LAST; + PRINTD("ao_lco_get_channels(%d) rssi %d valid %d ret %d offset %d\n", box, ao_radio_cmac_rssi, ao_lco_valid[box], r, ao_lco_tick_offset[box]); ao_wakeup(&ao_pad_query); + return ao_lco_valid[box]; +} + +static void +ao_lco_update(void) +{ + if (ao_lco_box != AO_LCO_BOX_DRAG) { + uint8_t previous_valid = ao_lco_valid[ao_lco_box]; + + if (ao_lco_get_channels(ao_lco_box, &ao_pad_query) & AO_LCO_VALID_LAST) { + if (!(previous_valid & AO_LCO_VALID_EVER)) { + if (ao_lco_pad != 0) + ao_lco_pad = ao_lco_pad_first(ao_lco_box); + ao_lco_set_display(); + } + if (ao_lco_pad == 0) + ao_lco_set_display(); + } + } } static void @@ -281,7 +540,6 @@ ao_lco_box_set_present(uint8_t box) static void ao_lco_search(void) { - uint16_t tick_offset; int8_t r; int8_t try; uint8_t box; @@ -293,9 +551,9 @@ ao_lco_search(void) if ((box % 10) == 0) ao_lco_set_box(box); for (try = 0; try < 3; try++) { - tick_offset = 0; - r = ao_lco_query(box, &ao_pad_query, &tick_offset); - PRINTD("box %d result %d\n", box, r); + ao_lco_tick_offset[box] = 0; + r = ao_lco_query(box, &ao_pad_query, &ao_lco_tick_offset[box]); + PRINTD("box %d result %d offset %d\n", box, r, ao_lco_tick_offset[box]); if (r == AO_RADIO_CMAC_OK) { ++boxes; ao_lco_box_set_present(box); @@ -309,8 +567,8 @@ ao_lco_search(void) ao_lco_box = ao_lco_min_box; else ao_lco_min_box = ao_lco_max_box = ao_lco_box = 0; - ao_lco_valid = 0; - ao_lco_got_channels = 0; + memset(ao_lco_valid, 0, sizeof (ao_lco_valid)); + memset(ao_lco_channels, 0, sizeof (ao_lco_channels)); ao_lco_pad = 1; ao_lco_set_display(); } @@ -319,37 +577,53 @@ static void ao_lco_igniter_status(void) { uint8_t c; + uint8_t t = 0; for (;;) { ao_sleep(&ao_pad_query); - PRINTD("RSSI %d VALID %d\n", ao_radio_cmac_rssi, ao_lco_valid); - if (!ao_lco_valid) { - ao_led_on(AO_LED_RED); - ao_led_off(AO_LED_GREEN|AO_LED_AMBER); - continue; - } - if (ao_radio_cmac_rssi < -90) { - ao_led_on(AO_LED_AMBER); - ao_led_off(AO_LED_RED|AO_LED_GREEN); + PRINTD("RSSI %d VALID %d\n", ao_radio_cmac_rssi, ao_lco_box == AO_LCO_BOX_DRAG ? -1 : ao_lco_valid[ao_lco_box]); + if (ao_lco_box == AO_LCO_BOX_DRAG) { + ao_led_off(AO_LED_RED|AO_LED_GREEN|AO_LED_AMBER); + for (c = 0; c < AO_LED_CONTINUITY_NUM; c++) + ao_led_off(continuity_led[c]); } else { - ao_led_on(AO_LED_GREEN); - ao_led_off(AO_LED_RED|AO_LED_AMBER); - } - if (ao_pad_query.arm_status) - ao_led_on(AO_LED_REMOTE_ARM); - else - ao_led_off(AO_LED_REMOTE_ARM); - for (c = 0; c < AO_LED_CONTINUITY_NUM; c++) { - uint8_t status; - - if (ao_pad_query.channels & (1 << c)) - status = ao_pad_query.igniter_status[c]; - else - status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN; - if (status == AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN) - ao_led_on(continuity_led[c]); + if (!(ao_lco_valid[ao_lco_box] & AO_LCO_VALID_LAST)) { + ao_led_on(AO_LED_RED); + ao_led_off(AO_LED_GREEN|AO_LED_AMBER); + continue; + } + if (ao_radio_cmac_rssi < -90) { + ao_led_on(AO_LED_AMBER); + ao_led_off(AO_LED_RED|AO_LED_GREEN); + } else { + ao_led_on(AO_LED_GREEN); + ao_led_off(AO_LED_RED|AO_LED_AMBER); + } + if (ao_pad_query.arm_status) + ao_led_on(AO_LED_REMOTE_ARM); else - ao_led_off(continuity_led[c]); + ao_led_off(AO_LED_REMOTE_ARM); + + for (c = 0; c < AO_LED_CONTINUITY_NUM; c++) { + uint8_t status; + + if (ao_lco_drag_race) { + if (ao_lco_selected[ao_lco_box] & (1 << c) && t) + ao_led_on(continuity_led[c]); + else + ao_led_off(continuity_led[c]); + } else { + if (ao_pad_query.channels & (1 << c)) + status = ao_pad_query.igniter_status[c]; + else + status = AO_PAD_IGNITER_STATUS_NO_IGNITER_RELAY_OPEN; + if (status == AO_PAD_IGNITER_STATUS_GOOD_IGNITER_RELAY_OPEN) + ao_led_on(continuity_led[c]); + else + ao_led_off(continuity_led[c]); + } + } + t = 1-t; } } } @@ -374,34 +648,33 @@ static void ao_lco_monitor(void) { uint16_t delay; + uint8_t box; ao_lco_search(); ao_add_task(&ao_lco_input_task, ao_lco_input, "lco input"); ao_add_task(&ao_lco_arm_warn_task, ao_lco_arm_warn, "lco arm warn"); ao_add_task(&ao_lco_igniter_status_task, ao_lco_igniter_status, "lco igniter status"); + ao_add_task(&ao_lco_drag_task, ao_lco_drag_monitor, "drag race"); for (;;) { - PRINTD("monitor armed %d firing %d offset %d\n", - ao_lco_armed, ao_lco_firing, ao_lco_tick_offset); + PRINTD("monitor armed %d firing %d\n", + ao_lco_armed, ao_lco_firing); if (ao_lco_armed && ao_lco_firing) { - PRINTD("Firing box %d pad %d: valid %d\n", - ao_lco_box, ao_lco_pad, ao_lco_valid); - if (!ao_lco_valid) - ao_lco_update(); - if (ao_lco_valid && ao_lco_pad) - ao_lco_ignite(ao_lco_box, 1 << (ao_lco_pad - 1), ao_lco_tick_offset); - } else if (ao_lco_armed) { - PRINTD("Arming box %d pad %d\n", - ao_lco_box, ao_lco_pad); - if (!ao_lco_valid) - ao_lco_update(); - if (ao_lco_pad) { - ao_lco_arm(ao_lco_box, 1 << (ao_lco_pad - 1), ao_lco_tick_offset); - ao_delay(AO_MS_TO_TICKS(30)); - ao_lco_update(); - } + ao_lco_ignite(); } else { ao_lco_update(); + if (ao_lco_armed) { + for (box = ao_lco_min_box; box <= ao_lco_max_box; box++) { + if (ao_lco_selected[box]) { + PRINTD("Arming box %d pads %x\n", + box, ao_lco_selected[box]); + if (ao_lco_valid[box] & AO_LCO_VALID_EVER) { + ao_lco_arm(box, ao_lco_selected[box], ao_lco_tick_offset[box]); + ao_delay(AO_MS_TO_TICKS(10)); + } + } + } + } } if (ao_lco_armed && ao_lco_firing) delay = AO_MS_TO_TICKS(100); diff --git a/src/drivers/ao_lco_cmd.c b/src/drivers/ao_lco_cmd.c index acbf589a..6a365687 100644 --- a/src/drivers/ao_lco_cmd.c +++ b/src/drivers/ao_lco_cmd.c @@ -62,7 +62,7 @@ lco_arm(void) static void lco_ignite(void) { - ao_lco_ignite(lco_box, lco_channels, tick_offset); + ao_lco_ignite(); } static void diff --git a/src/drivers/ao_lco_func.c b/src/drivers/ao_lco_func.c index 32c00068..08d45467 100644 --- a/src/drivers/ao_lco_func.c +++ b/src/drivers/ao_lco_func.c @@ -44,7 +44,7 @@ ao_lco_query(uint16_t box, struct ao_pad_query *query, uint16_t *tick_offset) } #endif ao_mutex_get(&ao_lco_mutex); - command.tick = ao_time() - *tick_offset; + command.tick = ao_time(); command.box = box; command.cmd = AO_LAUNCH_QUERY; command.channels = 0; @@ -70,14 +70,13 @@ ao_lco_arm(uint16_t box, uint8_t channels, uint16_t tick_offset) } void -ao_lco_ignite(uint16_t box, uint8_t channels, uint16_t tick_offset) +ao_lco_ignite(void) { ao_mutex_get(&ao_lco_mutex); - command.tick = ao_time() - tick_offset; - command.box = box; + command.tick = 0; + command.box = 0; command.cmd = AO_LAUNCH_FIRE; - command.channels = channels; + command.channels = 0; ao_radio_cmac_send(&command, sizeof (command)); ao_mutex_put(&ao_lco_mutex); } - diff --git a/src/drivers/ao_lco_func.h b/src/drivers/ao_lco_func.h index dccf602a..42754352 100644 --- a/src/drivers/ao_lco_func.h +++ b/src/drivers/ao_lco_func.h @@ -27,6 +27,6 @@ void ao_lco_arm(uint16_t box, uint8_t channels, uint16_t tick_offset); void -ao_lco_ignite(uint16_t box, uint8_t channels, uint16_t tick_offset); +ao_lco_ignite(void); #endif /* _AO_LCO_FUNC_H_ */ diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c index ffe46c68..419ea8d3 100644 --- a/src/drivers/ao_pad.c +++ b/src/drivers/ao_pad.c @@ -288,8 +288,7 @@ ao_pad(void) PRINTD ("armed\n"); ao_pad_armed = command.channels; ao_pad_arm_time = ao_time(); - - /* fall through ... */ + break; case AO_LAUNCH_QUERY: if (command.box != ao_pad_box) { @@ -320,13 +319,6 @@ ao_pad(void) ao_pad_arm_time, ao_time()); break; } - time_difference = command.tick - ao_time(); - if (time_difference < 0) - time_difference = -time_difference; - if (time_difference > 10) { - PRINTD ("time different too large %d\n", time_difference); - break; - } PRINTD ("ignite\n"); ao_pad_ignite = ao_pad_armed; ao_pad_arm_time = ao_time(); diff --git a/src/drivers/ao_pwm.h b/src/drivers/ao_pwm.h new file mode 100644 index 00000000..2dd2ffd5 --- /dev/null +++ b/src/drivers/ao_pwm.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2015 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; 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_PWM_H_ +#define _AO_PWM_H_ + +#include <stdint.h> + +void +ao_pwm_set(uint8_t pwm, uint16_t value); + +void +ao_pwm_init(void); + +#endif /* _AO_PWM_H_ */ diff --git a/src/drivers/ao_seven_segment.c b/src/drivers/ao_seven_segment.c index 961fbb84..f1339ee5 100644 --- a/src/drivers/ao_seven_segment.c +++ b/src/drivers/ao_seven_segment.c @@ -168,10 +168,20 @@ static const uint8_t ao_segments[] = { (0 << 6), /* F */ }; + void -ao_seven_segment_set(uint8_t digit, uint8_t value) +ao_seven_segment_direct(uint8_t digit, uint8_t segments) { uint8_t s; + + for (s = 0; s <= 7; s++) + ao_lcd_set(digit, s, !!(segments & (1 << s))); + ao_lcd_flush(); +} + +void +ao_seven_segment_set(uint8_t digit, uint8_t value) +{ uint8_t segments; if (value == AO_SEVEN_SEGMENT_CLEAR) @@ -183,10 +193,7 @@ ao_seven_segment_set(uint8_t digit, uint8_t value) if (value & 0x10) segments |= (1 << 7); } - - for (s = 0; s <= 7; s++) - ao_lcd_set(digit, s, !!(segments & (1 << s))); - ao_lcd_flush(); + ao_seven_segment_direct(digit, segments); } void diff --git a/src/drivers/ao_seven_segment.h b/src/drivers/ao_seven_segment.h index 5b29deaf..f997f3b5 100644 --- a/src/drivers/ao_seven_segment.h +++ b/src/drivers/ao_seven_segment.h @@ -23,6 +23,9 @@ #define AO_SEVEN_SEGMENT_CLEAR 0xff void +ao_seven_segment_direct(uint8_t digit, uint8_t segments); + +void ao_seven_segment_set(uint8_t digit, uint8_t value); void diff --git a/src/easymega-v1.0/ao_pins.h b/src/easymega-v1.0/ao_pins.h index d6490ba5..a5e55638 100644 --- a/src/easymega-v1.0/ao_pins.h +++ b/src/easymega-v1.0/ao_pins.h @@ -78,6 +78,7 @@ #define HAS_RADIO 0 #define HAS_TELEMETRY 0 #define HAS_APRS 0 +#define HAS_COMPANION 1 #define HAS_SPI_1 1 #define SPI_1_PA5_PA6_PA7 1 /* Barometer */ diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c index 854ac898..16363f75 100644 --- a/src/kernel/ao_telemetry.c +++ b/src/kernel/ao_telemetry.c @@ -75,6 +75,13 @@ static __pdata uint16_t ao_aprs_time; static __xdata union ao_telemetry_all telemetry; +static void +ao_telemetry_send(void) +{ + ao_radio_send(&telemetry, sizeof (telemetry)); + ao_delay(1); +} + #if defined AO_TELEMETRY_SENSOR /* Send sensor packet */ static void @@ -117,7 +124,7 @@ ao_send_sensor(void) telemetry.sensor.accel_minus_g = 0; #endif - ao_radio_send(&telemetry, sizeof (telemetry)); + ao_telemetry_send(); } #endif @@ -156,7 +163,7 @@ ao_send_mega_sensor(void) telemetry.mega_sensor.mag_z = packet->hmc5883.z; #endif - ao_radio_send(&telemetry, sizeof (telemetry)); + ao_telemetry_send(); } static __pdata int8_t ao_telemetry_mega_data_max; @@ -190,8 +197,8 @@ ao_send_mega_data(void) telemetry.mega_data.speed = ao_speed; telemetry.mega_data.height = ao_height; - ao_radio_send(&telemetry, sizeof (telemetry)); ao_telemetry_mega_data_cur = ao_telemetry_mega_data_max; + ao_telemetry_send(); } } #endif /* AO_SEND_MEGA */ @@ -221,7 +228,7 @@ ao_send_metrum_sensor(void) telemetry.metrum_sensor.sense_a = packet->adc.sense_a; telemetry.metrum_sensor.sense_m = packet->adc.sense_m; - ao_radio_send(&telemetry, sizeof (telemetry)); + ao_telemetry_send(); } static __pdata int8_t ao_telemetry_metrum_data_max; @@ -248,8 +255,8 @@ ao_send_metrum_data(void) telemetry.metrum_data.accel_minus_g = 2; #endif - ao_radio_send(&telemetry, sizeof (telemetry)); ao_telemetry_metrum_data_cur = ao_telemetry_metrum_data_max; + ao_telemetry_send(); } } #endif /* AO_SEND_METRUM */ @@ -279,7 +286,7 @@ ao_send_mini(void) telemetry.mini.ground_pres = ao_ground_pres; - ao_radio_send(&telemetry, sizeof (telemetry)); + ao_telemetry_send(); } #endif /* AO_SEND_MINI */ @@ -316,8 +323,8 @@ ao_send_configuration(void) ao_xmemcpy (telemetry.configuration.version, CODE_TO_XDATA(ao_version), AO_MAX_VERSION); - ao_radio_send(&telemetry, sizeof (telemetry)); ao_telemetry_config_cur = ao_telemetry_config_max; + ao_telemetry_send(); } } @@ -339,8 +346,8 @@ ao_send_location(void) 27); telemetry.location.tick = ao_gps_tick; ao_mutex_put(&ao_gps_mutex); - ao_radio_send(&telemetry, sizeof (telemetry)); ao_telemetry_loc_cur = ao_telemetry_gps_max; + ao_telemetry_send(); } } @@ -356,8 +363,8 @@ ao_send_satellite(void) &ao_gps_tracking_data.sats, 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_gps_max; + ao_telemetry_send(); } } #endif @@ -380,8 +387,8 @@ ao_send_companion(void) ao_companion_data, ao_companion_setup.channels * 2); ao_mutex_put(&ao_companion_mutex); - ao_radio_send(&telemetry, sizeof (telemetry)); ao_telemetry_companion_cur = ao_telemetry_companion_max; + ao_telemetry_send(); } } #endif diff --git a/src/stm/ao_pwm_stm.c b/src/stm/ao_pwm_stm.c new file mode 100644 index 00000000..ce1fa6f3 --- /dev/null +++ b/src/stm/ao_pwm_stm.c @@ -0,0 +1,192 @@ +/* + * Copyright © 2015 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; 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 "ao.h" +#include "ao_pwm.h" + +static uint8_t pwm_running; + +static uint16_t pwm_value[NUM_PWM]; + +static void +ao_pwm_up(void) +{ + if (pwm_running++ == 0) { + struct stm_tim234 *tim = &AO_PWM_TIMER; + + tim->ccr1 = 0; + tim->ccr2 = 0; + tim->ccr3 = 0; + tim->ccr4 = 0; + tim->arr = PWM_MAX - 1; /* turn on the timer */ + tim->cr1 = ((STM_TIM234_CR1_CKD_1 << STM_TIM234_CR1_CKD) | + (0 << STM_TIM234_CR1_ARPE) | + (STM_TIM234_CR1_CMS_EDGE << STM_TIM234_CR1_CMS) | + (STM_TIM234_CR1_DIR_UP << STM_TIM234_CR1_DIR) | + (0 << STM_TIM234_CR1_OPM) | + (0 << STM_TIM234_CR1_URS) | + (0 << STM_TIM234_CR1_UDIS) | + (1 << STM_TIM234_CR1_CEN)); + + /* Set the timer running */ + tim->egr = (1 << STM_TIM234_EGR_UG); + } +} + +static void +ao_pwm_down(void) +{ + if (--pwm_running == 0) { + struct stm_tim234 *tim = &AO_PWM_TIMER; + + tim->arr = 0; + tim->cr1 = ((STM_TIM234_CR1_CKD_1 << STM_TIM234_CR1_CKD) | + (0 << STM_TIM234_CR1_ARPE) | + (STM_TIM234_CR1_CMS_EDGE << STM_TIM234_CR1_CMS) | + (STM_TIM234_CR1_DIR_UP << STM_TIM234_CR1_DIR) | + (0 << STM_TIM234_CR1_OPM) | + (0 << STM_TIM234_CR1_URS) | + (0 << STM_TIM234_CR1_UDIS) | + (0 << STM_TIM234_CR1_CEN)); + + /* Stop the timer */ + tim->egr = (1 << STM_TIM234_EGR_UG); + } +} + +void +ao_pwm_set(uint8_t pwm, uint16_t value) +{ + struct stm_tim234 *tim = &AO_PWM_TIMER; + + if (value > PWM_MAX) + value = PWM_MAX; + if (value != 0) { + if (pwm_value[pwm] == 0) + ao_pwm_up(); + } + switch (pwm) { + case 0: + tim->ccr1 = value; + break; + case 1: + tim->ccr2 = value; + break; + case 2: + tim->ccr3 = value; + break; + case 3: + tim->ccr4 = value; + break; + } + if (value == 0) { + if (pwm_value[pwm] != 0) + ao_pwm_down(); + } + pwm_value[pwm] = value; +} + +static void +ao_pwm_cmd(void) +{ + uint8_t ch; + uint16_t val; + + ao_cmd_decimal(); + ch = ao_cmd_lex_u32; + ao_cmd_decimal(); + val = ao_cmd_lex_u32; + if (ao_cmd_status != ao_cmd_success) + return; + + printf("Set channel %d to %d\n", ch, val); + ao_pwm_set(ch, val); +} + +static const struct ao_cmds ao_pwm_cmds[] = { + { ao_pwm_cmd, "P <ch> <val>\0Set PWM ch to val" }, + { 0, NULL }, +}; + +void +ao_pwm_init(void) +{ + struct stm_tim234 *tim = &AO_PWM_TIMER; + + stm_rcc.apb1enr |= (1 << AO_PWM_TIMER_ENABLE); + + tim->cr1 = 0; + tim->psc = AO_PWM_TIMER_SCALE - 1; + tim->cnt = 0; + tim->ccer = ((1 << STM_TIM234_CCER_CC1E) | + (0 << STM_TIM234_CCER_CC1P) | + (1 << STM_TIM234_CCER_CC2E) | + (0 << STM_TIM234_CCER_CC2P) | + (1 << STM_TIM234_CCER_CC3E) | + (0 << STM_TIM234_CCER_CC3P) | + (1 << STM_TIM234_CCER_CC4E) | + (0 << STM_TIM234_CCER_CC4P)); + + tim->ccmr1 = ((0 << STM_TIM234_CCMR1_OC2CE) | + (STM_TIM234_CCMR1_OC2M_PWM_MODE_1 << STM_TIM234_CCMR1_OC2M) | + (0 << STM_TIM234_CCMR1_OC2PE) | + (0 << STM_TIM234_CCMR1_OC2FE) | + (STM_TIM234_CCMR1_CC2S_OUTPUT << STM_TIM234_CCMR1_CC2S) | + + (0 << STM_TIM234_CCMR1_OC1CE) | + (STM_TIM234_CCMR1_OC1M_PWM_MODE_1 << STM_TIM234_CCMR1_OC1M) | + (0 << STM_TIM234_CCMR1_OC1PE) | + (0 << STM_TIM234_CCMR1_OC1FE) | + (STM_TIM234_CCMR1_CC1S_OUTPUT << STM_TIM234_CCMR1_CC1S)); + + + tim->ccmr2 = ((0 << STM_TIM234_CCMR2_OC4CE) | + (STM_TIM234_CCMR2_OC4M_PWM_MODE_1 << STM_TIM234_CCMR2_OC4M) | + (0 << STM_TIM234_CCMR2_OC4PE) | + (0 << STM_TIM234_CCMR2_OC4FE) | + (STM_TIM234_CCMR2_CC4S_OUTPUT << STM_TIM234_CCMR2_CC4S) | + + (0 << STM_TIM234_CCMR2_OC3CE) | + (STM_TIM234_CCMR2_OC3M_PWM_MODE_1 << STM_TIM234_CCMR2_OC3M) | + (0 << STM_TIM234_CCMR2_OC3PE) | + (0 << STM_TIM234_CCMR2_OC3FE) | + (STM_TIM234_CCMR2_CC3S_OUTPUT << STM_TIM234_CCMR2_CC3S)); + tim->egr = 0; + + tim->sr = 0; + tim->dier = 0; + tim->smcr = 0; + tim->cr2 = ((0 << STM_TIM234_CR2_TI1S) | + (STM_TIM234_CR2_MMS_RESET<< STM_TIM234_CR2_MMS) | + (0 << STM_TIM234_CR2_CCDS)); + + stm_afr_set(AO_PWM_0_GPIO, AO_PWM_0_PIN, STM_AFR_AF2); + stm_ospeedr_set(AO_PWM_0_GPIO, AO_PWM_0_PIN, STM_OSPEEDR_40MHz); +#if NUM_PWM > 1 + stm_afr_set(AO_PWM_1_GPIO, AO_PWM_1_PIN, STM_AFR_AF2); + stm_ospeedr_set(AO_PWM_1_GPIO, AO_PWM_1_PIN, STM_OSPEEDR_40MHz); +#endif +#if NUM_PWM > 2 + stm_afr_set(AO_PWM_2_GPIO, AO_PWM_2_PIN, STM_AFR_AF2); + stm_ospeedr_set(AO_PWM_2_GPIO, AO_PWM_2_PIN, STM_OSPEEDR_40MHz); +#endif +#if NUM_PWM > 3 + stm_afr_set(AO_PWM_3_GPIO, AO_PWM_3_PIN, STM_AFR_AF2); + stm_ospeedr_set(AO_PWM_3_GPIO, AO_PWM_3_PIN, STM_OSPEEDR_40MHz); +#endif + ao_cmd_register(&ao_pwm_cmds[0]); +} diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 799cccbd..01afedc6 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -1775,7 +1775,7 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4; #define STM_TIM234_CCMR1_OC1M_PWM_MODE_1 6 #define STM_TIM234_CCMR1_OC1M_PWM_MODE_2 7 #define STM_TIM234_CCMR1_OC1M_MASK 7 -#define STM_TIM234_CCMR1_OC1PE 11 +#define STM_TIM234_CCMR1_OC1PE 3 #define STM_TIM234_CCMR1_OC1FE 2 #define STM_TIM234_CCMR1_CC1S 0 #define STM_TIM234_CCMR1_CC1S_OUTPUT 0 @@ -1815,7 +1815,7 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4; #define STM_TIM234_CCMR2_OC3M_PWM_MODE_1 6 #define STM_TIM234_CCMR2_OC3M_PWM_MODE_2 7 #define STM_TIM234_CCMR2_OC3M_MASK 7 -#define STM_TIM234_CCMR2_OC3PE 11 +#define STM_TIM234_CCMR2_OC3PE 3 #define STM_TIM234_CCMR2_OC3FE 2 #define STM_TIM234_CCMR2_CC3S 0 #define STM_TIM234_CCMR2_CC3S_OUTPUT 0 diff --git a/src/teleballoon-v2.0/ao_pins.h b/src/teleballoon-v2.0/ao_pins.h index a369070f..b62b5580 100644 --- a/src/teleballoon-v2.0/ao_pins.h +++ b/src/teleballoon-v2.0/ao_pins.h @@ -75,6 +75,7 @@ #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 */ diff --git a/src/telemega-v0.1/ao_pins.h b/src/telemega-v0.1/ao_pins.h index 2616e906..7ccc6085 100644 --- a/src/telemega-v0.1/ao_pins.h +++ b/src/telemega-v0.1/ao_pins.h @@ -79,6 +79,7 @@ #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 */ diff --git a/src/telemega-v1.0/ao_pins.h b/src/telemega-v1.0/ao_pins.h index 77b753d1..664546c2 100644 --- a/src/telemega-v1.0/ao_pins.h +++ b/src/telemega-v1.0/ao_pins.h @@ -79,6 +79,7 @@ #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 */ diff --git a/src/telemega-v2.0/.gitignore b/src/telemega-v2.0/.gitignore new file mode 100644 index 00000000..e67759a2 --- /dev/null +++ b/src/telemega-v2.0/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telemega-*.elf diff --git a/src/telemega-v2.0/Makefile b/src/telemega-v2.0/Makefile new file mode 100644 index 00000000..6a1c05b0 --- /dev/null +++ b/src/telemega-v2.0/Makefile @@ -0,0 +1,156 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_boot.h \ + ao_companion.h \ + ao_data.h \ + ao_sample.h \ + ao_pins.h \ + altitude-pa.h \ + ao_kalman.h \ + ao_product.h \ + ao_ms5607.h \ + ao_hmc5883.h \ + ao_mpu6000.h \ + ao_mma655x.h \ + ao_cc1200_CC1200.h \ + ao_profile.h \ + ao_task.h \ + ao_whiten.h \ + ao_sample_profile.h \ + ao_quaternion.h \ + math.h \ + ao_mpu.h \ + stm32l.h \ + math.h \ + ao_ms5607_convert.c \ + Makefile + +# +# Common AltOS sources +# +# ao_hmc5883.c + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +#SAMPLE_PROFILE=ao_sample_profile.c \ +# ao_sample_profile_timer.c +#SAMPLE_PROFILE_DEF=-DHAS_SAMPLE_PROFILE=1 + +#STACK_GUARD=ao_mpu_stm.c +#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 + +MATH_SRC=\ + ef_acos.c \ + ef_sqrt.c \ + ef_rem_pio2.c \ + kf_cos.c \ + kf_sin.c \ + kf_rem_pio2.c \ + sf_copysign.c \ + sf_cos.c \ + sf_fabs.c \ + sf_floor.c \ + sf_scalbn.c \ + sf_sin.c \ + ef_log.c + +ALTOS_SRC = \ + ao_boot_chain.c \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_led.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer.c \ + ao_mutex.c \ + ao_serial_stm.c \ + ao_gps_ublox.c \ + ao_gps_show.c \ + ao_gps_report_mega.c \ + ao_ignite.c \ + ao_freq.c \ + ao_dma_stm.c \ + ao_spi_stm.c \ + ao_cc1200.c \ + ao_data.c \ + ao_ms5607.c \ + ao_mma655x.c \ + ao_hmc5883.c \ + ao_adc_stm.c \ + ao_beep_stm.c \ + ao_eeprom_stm.c \ + ao_storage.c \ + ao_m25.c \ + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_report.c \ + ao_i2c_stm.c \ + ao_mpu6000.c \ + ao_convert_pa.c \ + ao_convert_volt.c \ + ao_log.c \ + ao_log_mega.c \ + ao_sample.c \ + ao_kalman.c \ + ao_flight.c \ + ao_telemetry.c \ + ao_packet_slave.c \ + ao_packet.c \ + ao_companion.c \ + ao_pyro.c \ + ao_aprs.c \ + ao_pwm_stm.c \ + $(MATH_SRC) \ + $(PROFILE) \ + $(SAMPLE_PROFILE) \ + $(STACK_GUARD) + +PRODUCT=TeleMega-v2.0 +PRODUCT_DEF=-DTELEMEGA +IDPRODUCT=0x0023 + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=telemega-v2.0 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_telemega.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +../altitude-pa.h: make-altitude-pa + nickle $< > $@ + +$(OBJ): $(INC) + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean: clean + +clean: + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telemega-v2.0/ao_pins.h b/src/telemega-v2.0/ao_pins.h new file mode 100644 index 00000000..9095a350 --- /dev/null +++ b/src/telemega-v2.0/ao_pins.h @@ -0,0 +1,407 @@ +/* + * Copyright © 2012 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; 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 0 +#define USE_SERIAL_2_STDIN 0 +#define SERIAL_2_PA2_PA3 0 +#define SERIAL_2_PD5_PD6 0 + +#define HAS_SERIAL_3 1 +#define USE_SERIAL_3_STDIN 0 +#define SERIAL_3_PB10_PB11 0 +#define SERIAL_3_PC10_PC11 1 +#define SERIAL_3_PD8_PD9 0 + +#define ao_gps_getchar ao_serial3_getchar +#define ao_gps_putchar ao_serial3_putchar +#define ao_gps_set_speed ao_serial3_set_speed +#define ao_gps_fifo (ao_stm_usart3.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 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 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 0 +#define SPI_1_PE13_PE14_PE15 1 /* Accelerometer, Gyro */ +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_SPI_2 1 +#define SPI_2_PB13_PB14_PB15 1 /* Flash, Companion */ +#define SPI_2_PD1_PD3_PD4 0 +#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz + +#define SPI_2_PORT (&stm_gpiob) +#define SPI_2_SCK_PIN 13 +#define SPI_2_MISO_PIN 14 +#define SPI_2_MOSI_PIN 15 + +#define HAS_I2C_1 1 +#define I2C_1_PB8_PB9 1 + +#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_gpiob) +#define AO_PYRO_PIN_2 5 + +/* Pyro D */ +#define AO_PYRO_PORT_3 (&stm_gpioe) +#define AO_PYRO_PIN_3 4 + +/* 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 + +#define AO_IGNITER_SET_DROGUE(v) stm_gpio_set(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, v) +#define AO_IGNITER_SET_MAIN(v) stm_gpio_set(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, v) + +/* + * 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: %5u 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 2 +#define AO_ADC_SENSE_C_PORT (&stm_gpioa) +#define AO_ADC_SENSE_C_PIN 2 + +#define AO_ADC_SENSE_D 3 +#define AO_ADC_SENSE_D_PORT (&stm_gpioa) +#define AO_ADC_SENSE_D_PIN 3 + +#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 << 3) +#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15 + +/* + * Radio (cc1120) + */ + +/* 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_gpioe) +#define AO_CC1200_INT_PIN 1 +#define AO_CC1200_MCU_WAKEUP_PORT (&stm_gpioc) +#define AO_CC1200_MCU_WAKEUP_PIN (0) + +#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 + +/* + * Mag sensor (hmc5883) + */ + +#define HAS_HMC5883 1 +#define AO_HMC5883_INT_PORT (&stm_gpioc) +#define AO_HMC5883_INT_PIN 12 +#define AO_HMC5883_I2C_INDEX STM_I2C_INDEX(1) + +/* + * mpu6000 + */ + +#define HAS_MPU6000 1 +#define AO_MPU6000_INT_PORT (&stm_gpioe) +#define AO_MPU6000_INT_PIN 0 +#define AO_MPU6000_SPI_BUS AO_SPI_1_PE13_PE14_PE15 +#define AO_MPU6000_SPI_CS_PORT (&stm_gpiod) +#define AO_MPU6000_SPI_CS_PIN 2 +#define HAS_IMU 1 + +/* + * mma655x + */ + +#define HAS_MMA655X 1 +#define AO_MMA655X_SPI_INDEX AO_SPI_1_PE13_PE14_PE15 +#define AO_MMA655X_CS_PORT (&stm_gpiod) +#define AO_MMA655X_CS_PIN 4 + +#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 14 + +#define AO_PWM_3_GPIO (&stm_gpiod) +#define AO_PWM_3_PIN 15 + +#endif /* _AO_PINS_H_ */ diff --git a/src/telemega-v2.0/ao_telemega.c b/src/telemega-v2.0/ao_telemega.c new file mode 100644 index 00000000..86427107 --- /dev/null +++ b/src/telemega-v2.0/ao_telemega.c @@ -0,0 +1,105 @@ +/* + * Copyright © 2011 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; 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 <ao.h> +#include <ao_hmc5883.h> +#include <ao_mpu6000.h> +#include <ao_mma655x.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> +#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(LEDS_AVAILABLE); + ao_led_on(AO_LED_GREEN); + ao_timer_init(); + + ao_i2c_init(); + ao_spi_init(); + ao_dma_init(); + ao_exti_init(); + + ao_adc_init(); +#if HAS_BEEP + ao_beep_init(); +#endif + ao_cmd_init(); + +#if HAS_MS5607 + ao_ms5607_init(); +#endif +#if HAS_HMC5883 + ao_hmc5883_init(); +#endif +#if HAS_MPU6000 + ao_mpu6000_init(); +#endif +#if HAS_MMA655X + ao_mma655x_init(); +#endif + + 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_start_scheduler(); + return 0; +} diff --git a/src/telemega-v2.0/flash-loader/Makefile b/src/telemega-v2.0/flash-loader/Makefile new file mode 100644 index 00000000..d667c18e --- /dev/null +++ b/src/telemega-v2.0/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=telemega-v2.0 +include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/telemega-v2.0/flash-loader/ao_pins.h b/src/telemega-v2.0/flash-loader/ao_pins.h new file mode 100644 index 00000000..304bb7c3 --- /dev/null +++ b/src/telemega-v2.0/flash-loader/ao_pins.h @@ -0,0 +1,34 @@ +/* + * Copyright © 2013 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; 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 <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_ */ diff --git a/src/telemetrum-v2.0/ao_pins.h b/src/telemetrum-v2.0/ao_pins.h index a9a4b243..fbb38df2 100644 --- a/src/telemetrum-v2.0/ao_pins.h +++ b/src/telemetrum-v2.0/ao_pins.h @@ -75,6 +75,7 @@ #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 */ |