diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/avr/ao_adc_avr.c | 7 | ||||
-rw-r--r-- | src/avr/ao_arch.h | 2 | ||||
-rw-r--r-- | src/avr/ao_pins.h | 9 | ||||
-rw-r--r-- | src/avr/ao_pwmin.c | 90 | ||||
-rw-r--r-- | src/avr/ao_pwmin.h | 20 | ||||
-rw-r--r-- | src/core/ao_log.h | 6 | ||||
-rw-r--r-- | src/core/ao_pyro.c | 19 | ||||
-rw-r--r-- | src/core/ao_pyro.h | 4 | ||||
-rw-r--r-- | src/product/ao_telescience.c | 6 | ||||
-rw-r--r-- | src/stm/ao_timer.c | 2 | ||||
-rw-r--r-- | src/telepyro-v0.1/Makefile | 2 | ||||
-rw-r--r-- | src/telescience-pwm/.gitignore | 2 | ||||
-rw-r--r-- | src/telescience-pwm/Makefile | 116 | ||||
-rw-r--r-- | src/test/ao_flight_test.c | 5 | ||||
-rwxr-xr-x | src/test/run-mm | 41 | ||||
-rwxr-xr-x[-rw-r--r--] | src/util/check-avr-mem | 0 |
17 files changed, 327 insertions, 6 deletions
diff --git a/src/Makefile b/src/Makefile index b8828d46..1949e554 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,7 +27,7 @@ ifneq ($(shell which sdcc),) endif ifneq ($(shell which avr-gcc),) - SUBDIRS += telescience-v0.1 telepyro-v0.1 + SUBDIRS += telescience-v0.1 telescience-pwm telepyro-v0.1 endif ifneq ($(shell which arm-none-eabi-gcc),) diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 3a262977..231512b2 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_pwmin.h" volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; volatile __data uint8_t ao_data_head; @@ -93,9 +94,13 @@ ISR(ADC_vect) value = ADCL; value |= (ADCH << 8); ao_data_ring[ao_data_head].adc.adc[ao_adc_channel] = value; - if (++ao_adc_channel < NUM_ADC) + if (++ao_adc_channel < NUM_ADC - HAS_ICP3_COUNT) ao_adc_start(); else { +#if HAS_ICP3_COUNT + /* steal last adc channel for pwm input */ + ao_data_ring[ao_data_head].adc.adc[ao_adc_channel] = ao_icp3_count; +#endif ADCSRA = ADCSRA_INIT; ao_data_ring[ao_data_head].tick = ao_time(); ao_data_head = ao_data_ring_next(ao_data_head); diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index a14d0ade..96659aaf 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -37,7 +37,9 @@ * AVR definitions and code fragments for AltOS */ +#ifndef AO_STACK_SIZE #define AO_STACK_SIZE 116 +#endif /* Various definitions to make GCC look more like SDCC */ diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index bc423ff7..a08e87fa 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -32,7 +32,7 @@ #define HAS_BEEP 0 #endif -#ifdef TELESCIENCE +#if defined(TELESCIENCE) || defined(TELESCIENCE_PWM) #define LEDS_AVAILABLE 0 #define HAS_USB 1 #define HAS_LOG 1 @@ -47,6 +47,11 @@ #define AVR_VCC_5V 0 #define AVR_VCC_3V3 1 #define AVR_CLOCK 8000000UL +#ifdef TELESCIENCE_PWM + #define HAS_ICP3_COUNT 1 +#else + #define HAS_ICP3_COUNT 0 +#endif #define SPI_CS_PORT PORTE #define SPI_CS_DIR DDRE @@ -64,6 +69,7 @@ #endif #ifdef TELEPYRO + #define AO_STACK_SIZE 104 #define LEDS_AVAILABLE 0 #define HAS_USB 1 #define HAS_LOG 0 @@ -81,6 +87,7 @@ #define IS_COMPANION 1 #define HAS_ORIENT 0 #define ao_storage_pos_t uint16_t + #define HAS_ICP3_COUNT 0 #define AVR_VCC_5V 0 #define AVR_VCC_3V3 1 diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c new file mode 100644 index 00000000..84397357 --- /dev/null +++ b/src/avr/ao_pwmin.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2012 Robert D. Garbee <robert@gag.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_pwmin.h" + +/* + * This code implements a PWM input using ICP3. + * + * The initial use is to measure wind speed in the ULA/Ball summer intern + * project payload developed at Challenger Middle School. + */ + +volatile __data uint16_t ao_icp3_count = 0; +volatile __data uint16_t ao_icp3_last = 0; + +uint16_t ao_icp3(void) +{ + uint16_t v; + ao_arch_critical( + v = ao_icp3_count; + ); + return v; +} + +static void +ao_pwmin_display(void) __reentrant +{ + /* display the most recent value */ + printf("icp 3: %5u\n", ao_icp3()); + +} + + +ISR(TIMER3_CAPT_vect) +{ + + uint8_t lo = ICR3L; + uint8_t hi = ICR3H; + uint16_t ao_icp3_this = (hi <<8) | lo; + + /* handling counter rollovers */ + if (ao_icp3_this >= ao_icp3_last) + ao_icp3_count = ao_icp3_this - ao_icp3_last; + else + ao_icp3_count = ao_icp3_this + (65536 - ao_icp3_last); + ao_icp3_last = ao_icp3_this; +} + +__code struct ao_cmds ao_pwmin_cmds[] = { + { ao_pwmin_display, "p\0PWM input" }, + { 0, NULL }, +}; + +void +ao_pwmin_init(void) +{ + /* do hardware setup here */ + TCCR3A = ((0 << WGM31) | /* normal mode, OCR3A */ + (0 << WGM30)); /* normal mode, OCR3A */ + TCCR3B = ((1 << ICNC3) | /* input capture noise canceler on */ + (0 << ICES3) | /* input capture on falling edge (don't care) */ + (0 << WGM33) | /* normal mode, OCR3A */ + (0 << WGM32) | /* normal mode, OCR3A */ + (3 << CS30)); /* clk/64 from prescaler */ + + + + TIMSK3 = (1 << ICIE3); /* Interrupt on input compare */ + + /* set the spike filter bit in the TCCR3B register */ + + ao_cmd_register(&ao_pwmin_cmds[0]); +} + + diff --git a/src/avr/ao_pwmin.h b/src/avr/ao_pwmin.h new file mode 100644 index 00000000..8097d399 --- /dev/null +++ b/src/avr/ao_pwmin.h @@ -0,0 +1,20 @@ +/* + * Copyright © 2012 Robert D. Garbee <robert@gag.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. + */ + +void ao_pwmin_init(void); + +extern volatile __data uint16_t ao_icp3_count; diff --git a/src/core/ao_log.h b/src/core/ao_log.h index eaaca444..4eaed420 100644 --- a/src/core/ao_log.h +++ b/src/core/ao_log.h @@ -197,15 +197,18 @@ struct ao_log_mega { uint8_t csum; /* 1 */ uint16_t tick; /* 2 */ union { /* 4 */ + /* AO_LOG_FLIGHT */ struct { uint16_t flight; /* 4 */ int16_t ground_accel; /* 6 */ uint32_t ground_pres; /* 8 */ } flight; /* 12 */ + /* AO_LOG_STATE */ struct { uint16_t state; uint16_t reason; } state; + /* AO_LOG_SENSOR */ struct { uint32_t pres; /* 4 */ uint32_t temp; /* 8 */ @@ -220,12 +223,14 @@ struct ao_log_mega { int16_t mag_z; /* 28 */ int16_t accel; /* 30 */ } sensor; /* 32 */ + /* AO_LOG_TEMP_VOLT */ struct { int16_t v_batt; /* 4 */ int16_t v_pbatt; /* 6 */ int16_t n_sense; /* 8 */ int16_t sense[10]; /* 10 */ } volt; /* 30 */ + /* AO_LOG_GPS_TIME */ struct { int32_t latitude; /* 4 */ int32_t longitude; /* 8 */ @@ -239,6 +244,7 @@ struct ao_log_mega { uint8_t day; /* 20 */ uint8_t pad; /* 21 */ } gps; /* 22 */ + /* AO_LOG_GPS_SAT */ struct { uint16_t channels; /* 4 */ struct { diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index 4f37e979..aac8fda5 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -113,6 +113,15 @@ ao_pyro_ready(struct ao_pyro *pyro) /* handled separately */ continue; + case ao_pyro_state_less: + if (ao_flight_state < pyro->state_less) + continue; + break; + case ao_pyro_state_greater_or_equal: + if (ao_flight_state >= pyro->state_greater_or_equal) + continue; + break; + default: continue; } @@ -166,7 +175,7 @@ uint8_t ao_pyro_wakeup; static void ao_pyro(void) { - uint8_t p; + uint8_t p, any_waiting; struct ao_pyro *pyro; ao_config_get(); @@ -177,6 +186,7 @@ ao_pyro(void) ao_alarm(AO_MS_TO_TICKS(100)); ao_sleep(&ao_pyro_wakeup); ao_clear_alarm(); + any_waiting = 0; for (p = 0; p < AO_PYRO_NUM; p++) { pyro = &ao_config.pyro[p]; @@ -190,6 +200,7 @@ ao_pyro(void) if (!pyro->flags) continue; + any_waiting = 1; /* Check pyro state to see if it shoule fire */ if (!pyro->delay_done) { @@ -213,7 +224,10 @@ ao_pyro(void) ao_pyro_fire(p); } + if (!any_waiting) + break; } + ao_exit(); } __xdata struct ao_task ao_pyro_task; @@ -257,6 +271,9 @@ const struct { { "t<", ao_pyro_time_less, offsetof(struct ao_pyro, time_less), HELP("time less (s * 100)") }, { "t>", ao_pyro_time_greater, offsetof(struct ao_pyro, time_greater), HELP("time greater (s * 100)") }, + { "f<", ao_pyro_state_less, offsetof(struct ao_pyro, state_less), HELP("state less") }, + { "f>=",ao_pyro_state_greater_or_equal, offsetof(struct ao_pyro, state_greater_or_equal), HELP("state greater or equal") }, + { "A", ao_pyro_ascending, NO_VALUE, HELP("ascending") }, { "D", ao_pyro_descending, NO_VALUE, HELP("descending") }, diff --git a/src/core/ao_pyro.h b/src/core/ao_pyro.h index 5deb69d0..cde850ad 100644 --- a/src/core/ao_pyro.h +++ b/src/core/ao_pyro.h @@ -42,6 +42,9 @@ enum ao_pyro_flag { ao_pyro_after_motor = 0x00001000, ao_pyro_delay = 0x00002000, + + ao_pyro_state_less = 0x00004000, + ao_pyro_state_greater_or_equal = 0x00008000, }; struct ao_pyro { @@ -52,6 +55,7 @@ struct ao_pyro { int16_t orient_less, orient_greater; int16_t time_less, time_greater; int16_t delay; + uint8_t state_less, state_greater_or_equal; int16_t motor; uint16_t delay_done; uint8_t fired; diff --git a/src/product/ao_telescience.c b/src/product/ao_telescience.c index 45b6d40e..d448d318 100644 --- a/src/product/ao_telescience.c +++ b/src/product/ao_telescience.c @@ -16,6 +16,9 @@ */ #include "ao.h" +#if HAS_ICP3_COUNT +#include "ao_pwmin.h" +#endif int main(void) @@ -34,6 +37,9 @@ main(void) ao_usb_init(); ao_adc_init(); ao_log_single_init(); +#if HAS_ICP3_COUNT + ao_pwmin_init(); +#endif ao_start_scheduler(); return 0; } diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index 1132f748..f3011d3f 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -266,6 +266,7 @@ ao_clock_init(void) stm_rcc.csr |= (1 << STM_RCC_CSR_RMVF); +#if DEBUG_THE_CLOCK /* Output SYSCLK on PA8 for measurments */ stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); @@ -276,4 +277,5 @@ ao_clock_init(void) stm_rcc.cfgr |= (STM_RCC_CFGR_MCOPRE_DIV_1 << STM_RCC_CFGR_MCOPRE); stm_rcc.cfgr |= (STM_RCC_CFGR_MCOSEL_HSE << STM_RCC_CFGR_MCOSEL); +#endif } diff --git a/src/telepyro-v0.1/Makefile b/src/telepyro-v0.1/Makefile index 2ccd565f..6743ba66 100644 --- a/src/telepyro-v0.1/Makefile +++ b/src/telepyro-v0.1/Makefile @@ -96,7 +96,7 @@ ao_product.o: ao_product.c ao_product.h distclean: clean clean: - rm -f $(OBJ) + rm -f $(OBJ) $(PROG) $(PROG).hex rm -f ao_product.h install: diff --git a/src/telescience-pwm/.gitignore b/src/telescience-pwm/.gitignore new file mode 100644 index 00000000..dfccadf8 --- /dev/null +++ b/src/telescience-pwm/.gitignore @@ -0,0 +1,2 @@ +telescience-v0.1* +ao_product.h diff --git a/src/telescience-pwm/Makefile b/src/telescience-pwm/Makefile new file mode 100644 index 00000000..43d77e2e --- /dev/null +++ b/src/telescience-pwm/Makefile @@ -0,0 +1,116 @@ +# +# AltOS build +# +# +vpath % ..:../core:../product:../drivers:../avr +vpath ao-make-product.5c ../util + +MCU=atmega32u4 +DUDECPUTYPE=m32u4 +#PROGRAMMER=stk500v2 -P usb +PROGRAMMER=usbtiny +LOADCMD=avrdude +LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: +CC=avr-gcc +OBJCOPY=avr-objcopy + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_arch.h \ + ao_usb.h \ + ao_pins.h \ + ao_product.h + +# +# Common AltOS sources +# +TELESCIENCE_STORAGE= \ + ao_m25.c \ + ao_spi_usart.c \ + ao_storage.c + +TELESCIENCE_LOG= \ + ao_log_single.c \ + ao_log_telescience.c + +ALTOS_SRC = \ + ao_clock.c \ + ao_cmd.c \ + ao_mutex.c \ + ao_panic.c \ + ao_product.c \ + ao_stdio.c \ + ao_task.c \ + ao_timer.c \ + ao_led.c \ + ao_avr_stdio.c \ + ao_romconfig.c \ + ao_usb_avr.c \ + ao_adc_avr.c \ + ao_science_slave.c \ + ao_spi_slave.c \ + ao_pwmin.c \ + $(TELESCIENCE_STORAGE)\ + $(TELESCIENCE_LOG) + +PRODUCT=TeleScience-PWM +MCU=atmega32u4 +PRODUCT_DEF=-DTELESCIENCE -DTELESCIENCE_PWM +IDPRODUCT=0x0011 +CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I.. +CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR + +NICKLE=nickle + +PROG=telescience-pwm + +SRC=$(ALTOS_SRC) ao_telescience.c +OBJ=$(SRC:.c=.o) + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: $(PROG) + +CHECK=sh ../util/check-avr-mem + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) + $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) + +$(PROG).hex: $(PROG) + avr-size $(PROG) + $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ + + +load: $(PROG).hex + $(LOADCMD) $(LOADARG)$(PROG).hex + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +ao_product.o: ao_product.c ao_product.h + +%.o : %.c $(INC) + $(call quiet,CC) -c $(CFLAGS) $< + +distclean: clean + +clean: + rm -f *.o $(PROG) $(PROG).hex + rm -f ao_product.h + +install: + +uninstall: + +$(OBJ): ao_product.h $(INC) diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 0df9a5d7..7180f02d 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -39,7 +39,7 @@ #define AO_ADC_NUM_SENSE 6 #define HAS_MS5607 1 #define HAS_MPU6000 1 -#define HAS_MMA655X 0 +#define HAS_MMA655X 1 struct ao_adc { int16_t sense[AO_ADC_NUM_SENSE]; @@ -622,6 +622,9 @@ ao_sleep(void *wchan) ao_data_static.mpu6000.gyro_x = int16(bytes, 14); ao_data_static.mpu6000.gyro_y = -int16(bytes, 16); ao_data_static.mpu6000.gyro_z = int16(bytes, 18); +#if HAS_MMA655X + ao_data_static.mma655x = int16(bytes, 26); +#endif if (ao_records_read == 0) ao_ground_mpu6000 = ao_data_static.mpu6000; else if (ao_records_read < 10) { diff --git a/src/test/run-mm b/src/test/run-mm new file mode 100755 index 00000000..6f3d97a2 --- /dev/null +++ b/src/test/run-mm @@ -0,0 +1,41 @@ +#!/bin/sh + +DIR=~/misc/rockets/flights + +for i in "$@"; do +case "$i" in + */*) + file="$i" + ;; + *) + file="$DIR/$i" + ;; +esac +./ao_flight_test_mm "$file" > run-out.mm + +#./ao_flight_test_accel "$file" > run-out.accel +#"run-out.accel" using 1:9 with lines lt 4 axes x1y1 title "accel height",\ +#"run-out.accel" using 1:11 with lines lt 4 axes x1y2 title "accel speed",\ +#"run-out.accel" using 1:13 with lines lt 4 axes x1y2 title "accel accel",\ +#"run-out.accel" using 1:15 with lines lt 4 axes x1y1 title "accel drogue",\ +#"run-out.accel" using 1:17 with lines lt 4 axes x1y1 title "accel main",\ +# + +gnuplot << EOF +set ylabel "altitude (m)" +set y2label "velocity (m/s), acceleration(m/s²)" +set xlabel "time (s)" +set xtics border out nomirror +set ytics border out nomirror +set y2tics border out nomirror +set title "$i" +plot "run-out.mm" using 1:3 with lines lw 2 lt 1 axes x1y1 title "raw height",\ +"run-out.mm" using 1:5 with lines lw 2 lt 1 axes x1y2 title "raw accel",\ +"run-out.mm" using 1:21 with lines lt 2 axes x1y1 title "mm height",\ +"run-out.mm" using 1:23 with lines lt 2 axes x1y2 title "mm speed",\ +"run-out.mm" using 1:25 with lines lt 2 axes x1y2 title "mm accel",\ +"run-out.mm" using 1:29 with lines lt 2 axes x1y1 title "mm drogue",\ +"run-out.mm" using 1:31 with lines lt 2 axes x1y1 title "mm main" +pause mouse close +EOF +done
\ No newline at end of file diff --git a/src/util/check-avr-mem b/src/util/check-avr-mem index 7956f0aa..7956f0aa 100644..100755 --- a/src/util/check-avr-mem +++ b/src/util/check-avr-mem |