From 8a19805a6b079450b5afd5fa2334cede8495ae4a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 May 2013 03:21:08 -0700 Subject: altos/cc1111: Hack on USB driver to make Windows happy The Windows modem driver is quite chatty at startup time, getting and setting the comm parameters each time the device is opened. Sometimes, when setting the parameters, the cc1111 would STALL EP0. Most of the time, Windows would happily pass this as an error back to AltosUI which would then re-try the open (and succeed, most of the time). Sometimes, Windows would stall for 30 seconds before passing the error back. This made the whole UI freeze, and I suspect most people assumed our app had died. A bit of analysis with the beagle USB sniffer and I discovered the STALL settings, but there wasn't any correlation between the data on the wire and when the STALL would be generated. So, I found a couple of other cc1111 USB stacks on the net and just looked to see how our driver differed. There wasn't anything clearly related, but there were a list of small differences: 1) Other drivers didn't bother waiting for the hardware to ack the USBADDR setting; doing it this way means we can set the address *before* acking the setup packet. It'll get set eventually, at which point the device will start responding to packets again. Easy to fix, and saves a bit of code space too. 2) The other drivers set the STALL bit for setup packets which aren't understood. This shouldn't have any effect on 'good' systems as those shouldn't ever be generating bogus setup packets anyways. The driver already handled the STALL state in the interrupt handler, the only requirement was to figure out when to explicitly set the STALL bit. That required moving the state updating code from the start of the ep0 setup handling to the end, after the setup packet had been examined and data queued in or out as appropriate. 3) Our driver explicitly queued an IN packet for any setup request that wasn't waiting for an OUT pack. This appears to tie in with the USBADDR change above as before I made that change, this change caused the driver to fail to respond to most setup packets. This was simple once the above change was made, just move the generation of the IN packet inside the code that switched to the IN state. Signed-off-by: Keith Packard --- src/cc1111/ao_usb.c | 68 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 30 deletions(-) (limited to 'src/cc1111/ao_usb.c') diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c index 8bd2efdf..a655d1be 100644 --- a/src/cc1111/ao_usb.c +++ b/src/cc1111/ao_usb.c @@ -152,19 +152,17 @@ ao_usb_ep0_fill(void) *ao_usb_ep0_out_data++ = USBFIFO[0]; } -void +static void ao_usb_ep0_queue_byte(uint8_t a) { ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a; } -void +static void ao_usb_set_address(uint8_t address) { ao_usb_running = 1; - USBADDR = address | 0x80; - while (USBADDR & 0x80) - ; + USBADDR = address; } static void @@ -191,24 +189,6 @@ ao_usb_ep0_setup(void) if (ao_usb_ep0_out_len != 0) return; - /* Figure out how to ACK the setup packet */ - if (ao_usb_setup.dir_type_recip & AO_USB_DIR_IN) { - if (ao_usb_setup.length) - ao_usb_ep0_state = AO_USB_EP0_DATA_IN; - else - ao_usb_ep0_state = AO_USB_EP0_IDLE; - } else { - if (ao_usb_setup.length) - ao_usb_ep0_state = AO_USB_EP0_DATA_OUT; - else - ao_usb_ep0_state = AO_USB_EP0_IDLE; - } - USBINDEX = 0; - if (ao_usb_ep0_state == AO_USB_EP0_IDLE) - USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END; - else - USBCS0 = USBCS0_CLR_OUTPKT_RDY; - ao_usb_ep0_in_data = ao_usb_ep0_in_buf; ao_usb_ep0_in_len = 0; switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_TYPE_MASK) { @@ -274,10 +254,39 @@ ao_usb_ep0_setup(void) } break; } - if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) { + + /* Figure out how to ACK the setup packet and the + * next state + */ + USBINDEX = 0; + if (ao_usb_ep0_in_len) { + + /* Sending data back to the host + */ + ao_usb_ep0_state = AO_USB_EP0_DATA_IN; + USBCS0 = USBCS0_CLR_OUTPKT_RDY; if (ao_usb_setup.length < ao_usb_ep0_in_len) ao_usb_ep0_in_len = ao_usb_setup.length; ao_usb_ep0_flush(); + } else if (ao_usb_ep0_out_len) { + + /* Receiving data from the host + */ + ao_usb_ep0_state = AO_USB_EP0_DATA_OUT; + USBCS0 = USBCS0_CLR_OUTPKT_RDY; + } else if (ao_usb_setup.length) { + + /* Uh-oh, the host expected to send or receive data + * and we don't know what to do. + */ + ao_usb_ep0_state = AO_USB_EP0_STALL; + USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_SEND_STALL; + } else { + + /* Simple setup packet with no data + */ + ao_usb_ep0_state = AO_USB_EP0_IDLE; + USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END; } } @@ -299,12 +308,12 @@ ao_usb_ep0(void) USBINDEX = 0; cs0 = USBCS0; if (cs0 & USBCS0_SETUP_END) { - ao_usb_ep0_state = AO_USB_EP0_IDLE; USBCS0 = USBCS0_CLR_SETUP_END; + ao_usb_ep0_state = AO_USB_EP0_IDLE; } if (cs0 & USBCS0_SENT_STALL) { + USBCS0 = 0; ao_usb_ep0_state = AO_USB_EP0_IDLE; - USBCS0 &= ~USBCS0_SENT_STALL; } if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN && (cs0 & USBCS0_INPKT_RDY) == 0) @@ -318,12 +327,11 @@ ao_usb_ep0(void) break; case AO_USB_EP0_DATA_OUT: ao_usb_ep0_fill(); - if (ao_usb_ep0_out_len == 0) - ao_usb_ep0_state = AO_USB_EP0_IDLE; USBINDEX = 0; - if (ao_usb_ep0_state == AO_USB_EP0_IDLE) + if (ao_usb_ep0_out_len == 0) { + ao_usb_ep0_state = AO_USB_EP0_IDLE; USBCS0 = USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END; - else + } else USBCS0 = USBCS0_CLR_OUTPKT_RDY; break; } -- cgit v1.2.3 From d0b4e926ecececa7499a301b6135189be119512e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 May 2013 13:03:06 -0700 Subject: Initial TeleMini bits Signed-off-by: Keith Packard --- src/cc1111/ao_adc.c | 5 ++ src/cc1111/ao_usb.c | 5 ++ src/core/ao_data.c | 2 + src/core/ao_data.h | 2 +- src/core/ao_log_mini.c | 1 - src/core/ao_telemetry.c | 40 +++++++++- src/core/ao_telemetry.h | 27 +++++++ src/drivers/ao_ms5607.c | 40 +++++----- src/drivers/ao_ms5607.h | 2 +- src/drivers/ao_ms5607_convert_8051.c | 60 +++++++++++++++ src/telemini-v2.0/Makefile | 108 +++++++++++++++++++++++++++ src/telemini-v2.0/ao_pins.h | 140 +++++++++++++++++++++++++++++++++++ src/telemini-v2.0/ao_telemini.c | 54 ++++++++++++++ src/test/Makefile | 5 +- 14 files changed, 466 insertions(+), 25 deletions(-) create mode 100644 src/drivers/ao_ms5607_convert_8051.c create mode 100644 src/telemini-v2.0/Makefile create mode 100644 src/telemini-v2.0/ao_pins.h create mode 100644 src/telemini-v2.0/ao_telemini.c (limited to 'src/cc1111/ao_usb.c') diff --git a/src/cc1111/ao_adc.c b/src/cc1111/ao_adc.c index 4a58023d..6cc08399 100644 --- a/src/cc1111/ao_adc.c +++ b/src/cc1111/ao_adc.c @@ -162,6 +162,11 @@ ao_adc_isr(void) __interrupt 1 #define GOT_ADC #endif +#ifdef FETCH_ADC + FETCH_ADC() +#define GOT_ADC +#endif + #ifndef GOT_ADC #error No known ADC configuration set #endif diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c index a655d1be..b0ab409d 100644 --- a/src/cc1111/ao_usb.c +++ b/src/cc1111/ao_usb.c @@ -201,6 +201,11 @@ ao_usb_ep0_setup(void) ao_usb_ep0_queue_byte(0); break; case AO_USB_REQ_SET_ADDRESS: +#if USB_FORCE_FLIGHT_IDLE + /* Go to idle mode if USB is connected + */ + ao_flight_force_idle = 1; +#endif ao_usb_set_address(ao_usb_setup.value); break; case AO_USB_REQ_GET_DESCRIPTOR: diff --git a/src/core/ao_data.c b/src/core/ao_data.c index 38d2f7ff..6a3d02a1 100644 --- a/src/core/ao_data.c +++ b/src/core/ao_data.c @@ -22,6 +22,7 @@ volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; volatile __data uint8_t ao_data_head; volatile __data uint8_t ao_data_present; +#ifndef ao_data_count void ao_data_get(__xdata struct ao_data *packet) { @@ -32,3 +33,4 @@ ao_data_get(__xdata struct ao_data *packet) #endif memcpy(packet, (void *) &ao_data_ring[i], sizeof (struct ao_data)); } +#endif diff --git a/src/core/ao_data.h b/src/core/ao_data.h index b0f086f8..080a534f 100644 --- a/src/core/ao_data.h +++ b/src/core/ao_data.h @@ -101,7 +101,7 @@ extern volatile __data uint8_t ao_data_count; * signaled by the timer tick */ #define AO_DATA_WAIT() do { \ - ao_sleep((void *) &ao_data_count); \ + ao_sleep(DATA_TO_XDATA ((void *) &ao_data_count)); \ } while (0) #endif /* AO_DATA_RING */ diff --git a/src/core/ao_log_mini.c b/src/core/ao_log_mini.c index 1273b0e3..46b285f3 100644 --- a/src/core/ao_log_mini.c +++ b/src/core/ao_log_mini.c @@ -79,7 +79,6 @@ void ao_log(void) { __pdata uint16_t next_sensor, next_other; - uint8_t i; ao_storage_setup(); diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 03a8a273..9c673030 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -171,6 +171,36 @@ ao_send_mega_data(void) } #endif /* AO_SEND_MEGA */ +#ifdef AO_SEND_MINI + +static void +ao_send_mini(void) +{ + __xdata struct ao_data *packet = (__xdata struct ao_data *) &ao_data_ring[ao_data_ring_prev(ao_sample_data)]; + + telemetry.generic.tick = packet->tick; + telemetry.generic.type = AO_TELEMETRY_MINI; + + telemetry.mini.state = ao_flight_state; + + telemetry.mini.v_batt = packet->adc.v_batt; + telemetry.mini.sense_a = packet->adc.sense_a; + telemetry.mini.sense_m = packet->adc.sense_m; + + telemetry.mini.pres = ao_data_pres(packet); + telemetry.mini.temp = ao_data_temp(packet); + + telemetry.mini.acceleration = ao_accel; + telemetry.mini.speed = ao_speed; + telemetry.mini.height = ao_height; + + telemetry.mini.ground_pres = ao_ground_pres; + + ao_radio_send(&telemetry, sizeof (telemetry)); +} + +#endif + #ifdef AO_SEND_ALL_BARO static uint8_t ao_baro_sample; @@ -323,12 +353,16 @@ ao_telemetry(void) ao_send_baro(); #endif #if HAS_FLIGHT -#ifdef AO_SEND_MEGA +# ifdef AO_SEND_MEGA ao_send_mega_sensor(); ao_send_mega_data(); -#else +# else +# ifdef AO_SEND_MINI + ao_send_mini(); +# else ao_send_sensor(); -#endif +# endif +# endif #endif #if HAS_COMPANION diff --git a/src/core/ao_telemetry.h b/src/core/ao_telemetry.h index f2d201de..77601529 100644 --- a/src/core/ao_telemetry.h +++ b/src/core/ao_telemetry.h @@ -207,6 +207,32 @@ struct ao_telemetry_mega_data { }; +#define AO_TELEMETRY_MINI 0x10 + +struct ao_telemetry_mini { + uint16_t serial; /* 0 */ + uint16_t tick; /* 2 */ + uint8_t type; /* 4 */ + + uint8_t state; /* 5 flight state */ + + int16_t v_batt; /* 6 battery voltage */ + int16_t sense_a; /* 8 apogee continuity */ + int16_t sense_m; /* 10 main continuity */ + + int32_t pres; /* 12 Pa * 10 */ + int16_t temp; /* 16 °C * 100 */ + + int16_t acceleration; /* 18 m/s² * 16 */ + int16_t speed; /* 20 m/s * 16 */ + int16_t height; /* 22 m */ + + int32_t ground_pres; /* 24 average pres on pad */ + + int32_t pad28; /* 28 */ + /* 32 */ +}; + /* #define AO_SEND_ALL_BARO */ #define AO_TELEMETRY_BARO 0x80 @@ -240,6 +266,7 @@ union ao_telemetry_all { struct ao_telemetry_companion companion; struct ao_telemetry_mega_sensor mega_sensor; struct ao_telemetry_mega_data mega_data; + struct ao_telemetry_mini mini; struct ao_telemetry_baro baro; }; diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 8f1dcbe1..5259b265 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -21,7 +21,7 @@ #if HAS_MS5607 || HAS_MS5611 -static struct ao_ms5607_prom ms5607_prom; +static __xdata struct ao_ms5607_prom ms5607_prom; static uint8_t ms5607_configured; static void @@ -40,7 +40,7 @@ ao_ms5607_reset(void) { cmd = AO_MS5607_RESET; ao_ms5607_start(); - ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX); + ao_spi_send(DATA_TO_XDATA(&cmd), 1, AO_MS5607_SPI_INDEX); ao_delay(AO_MS_TO_TICKS(10)); ao_ms5607_stop(); } @@ -69,17 +69,17 @@ ao_ms5607_crc(uint8_t *prom) } static void -ao_ms5607_prom_read(struct ao_ms5607_prom *prom) +ao_ms5607_prom_read(__xdata struct ao_ms5607_prom *prom) { - uint8_t addr; - uint8_t crc; - uint16_t *r; + uint8_t addr; + uint8_t crc; + __xdata uint16_t *r; - r = (uint16_t *) prom; + r = (__xdata uint16_t *) prom; for (addr = 0; addr < 8; addr++) { uint8_t cmd = AO_MS5607_PROM_READ(addr); ao_ms5607_start(); - ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX); + ao_spi_send(DATA_TO_XDATA(&cmd), 1, AO_MS5607_SPI_INDEX); ao_spi_recv(r, 2, AO_MS5607_SPI_INDEX); ao_ms5607_stop(); r++; @@ -114,25 +114,25 @@ ao_ms5607_setup(void) ao_ms5607_prom_read(&ms5607_prom); } -static volatile uint8_t ao_ms5607_done; +static __xdata volatile uint8_t ao_ms5607_done; 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); + ao_wakeup((__xdata void *) &ao_ms5607_done); } static uint32_t ao_ms5607_get_sample(uint8_t cmd) { - uint8_t reply[3]; - uint8_t read; + __xdata uint8_t reply[3]; + __xdata uint8_t read; ao_ms5607_done = 0; ao_ms5607_start(); - ao_spi_send(&cmd, 1, AO_MS5607_SPI_INDEX); + ao_spi_send(DATA_TO_XDATA(&cmd), 1, AO_MS5607_SPI_INDEX); ao_exti_enable(AO_MS5607_MISO_PORT, AO_MS5607_MISO_PIN); @@ -179,10 +179,14 @@ ao_ms5607_sample(struct ao_ms5607_sample *sample) sample->temp = ao_ms5607_get_sample(AO_CONVERT_D2); } +#ifdef _CC1111_H_ +#include "ao_ms5607_convert_8051.c" +#else #include "ao_ms5607_convert.c" +#endif #if HAS_TASK -struct ao_ms5607_sample ao_ms5607_current; +__xdata struct ao_ms5607_sample ao_ms5607_current; static void ao_ms5607(void) @@ -191,10 +195,10 @@ ao_ms5607(void) for (;;) { ao_ms5607_sample(&ao_ms5607_current); - ao_arch_critical( - AO_DATA_PRESENT(AO_DATA_MS5607); - AO_DATA_WAIT(); - ); + ao_arch_block_interrupts(); + AO_DATA_PRESENT(AO_DATA_MS5607); + AO_DATA_WAIT(); + ao_arch_release_interrupts(); } } diff --git a/src/drivers/ao_ms5607.h b/src/drivers/ao_ms5607.h index b2f98a59..3fd43fd4 100644 --- a/src/drivers/ao_ms5607.h +++ b/src/drivers/ao_ms5607.h @@ -56,7 +56,7 @@ struct ao_ms5607_value { int32_t temp; /* in °C * 100 */ }; -extern struct ao_ms5607_sample ao_ms5607_current; +extern __xdata struct ao_ms5607_sample ao_ms5607_current; void ao_ms5607_setup(void); diff --git a/src/drivers/ao_ms5607_convert_8051.c b/src/drivers/ao_ms5607_convert_8051.c new file mode 100644 index 00000000..f47972c9 --- /dev/null +++ b/src/drivers/ao_ms5607_convert_8051.c @@ -0,0 +1,60 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include + +void +ao_ms5607_convert(struct ao_ms5607_sample *sample, struct ao_ms5607_value *value) +{ +#if 0 + int32_t dT; + int32_t TEMP; + int64_t OFF; + int64_t SENS; + + dT = sample->temp - ((int32_t) ms5607_prom.tref << 8); + + TEMP = 2000 + (((int64_t) dT * ms5607_prom.tempsens) >> 23); + +#if HAS_MS5611 + OFF = ((int64_t) ms5607_prom.off << 16) + (((int64_t) ms5607_prom.tco * dT) >> 7); + SENS = ((int64_t) ms5607_prom.sens << 15) + (((int64_t) ms5607_prom.tcs * dT) >> 8); +#else + OFF = ((int64_t) ms5607_prom.off << 17) + (((int64_t) ms5607_prom.tco * dT) >> 6); + SENS = ((int64_t) ms5607_prom.sens << 16) + (((int64_t) ms5607_prom.tcs * dT) >> 7); +#endif + + if (TEMP < 2000) { + int32_t T2 = ((int64_t) dT * (int64_t) dT) >> 31; + int32_t TEMPM = TEMP - 2000; + int64_t OFF2 = (61 * (int64_t) TEMPM * (int64_t) TEMPM) >> 4; + int64_t SENS2 = 2 * (int64_t) TEMPM * (int64_t) TEMPM; + if (TEMP < 1500) { + int32_t TEMPP = TEMP + 1500; + int64_t TEMPP2 = TEMPP * TEMPP; + OFF2 = OFF2 + 15 * TEMPP2; + SENS2 = SENS2 + 8 * TEMPP2; + } + TEMP -= T2; + OFF -= OFF2; + SENS -= SENS2; + } + + value->pres = ((((int64_t) sample->pres * SENS) >> 21) - OFF) >> 15; + value->temp = TEMP; +#endif +} diff --git a/src/telemini-v2.0/Makefile b/src/telemini-v2.0/Makefile new file mode 100644 index 00000000..afd529f0 --- /dev/null +++ b/src/telemini-v2.0/Makefile @@ -0,0 +1,108 @@ +# +# TeleMini build file +# + +TELEMINI_VER=2.0 +TELEMINI_DEF=2_0 + +vpath %.c ..:../core:../cc1111:../drivers:../product +vpath %.h ..:../core:../cc1111:../drivers:../product +vpath ao-make-product.5c ../util + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_pins.h \ + ao_arch.h \ + ao_arch_funcs.h \ + cc1111.h \ + ao_product.h + +CORE_SRC = \ + ao_cmd.c \ + ao_config.c \ + ao_convert.c \ + ao_flight.c \ + ao_kalman.c \ + ao_log.c \ + ao_log_mini.c \ + ao_mutex.c \ + ao_panic.c \ + ao_report.c \ + ao_sample.c \ + ao_stdio.c \ + ao_storage.c \ + ao_task.c \ + ao_telemetry.c \ + ao_freq.c + +CC1111_SRC = \ + ao_adc.c \ + ao_dma.c \ + ao_ignite.c \ + ao_led.c \ + ao_packet.c \ + ao_packet_slave.c \ + ao_radio.c \ + ao_romconfig.c \ + ao_string.c \ + ao_spi.c \ + ao_usb.c \ + ao_convert_pa.c \ + ao_data.c \ + ao_beep.c \ + ao_timer.c \ + _bp.c + +DRIVER_SRC = \ + ao_ms5607.c \ + ao_m25.c + +PRODUCT_SRC = \ + ao_telemini.c + +SRC = \ + $(CORE_SRC) \ + $(CC1111_SRC) \ + $(DRIVER_SRC) \ + $(PRODUCT_SRC) + +PROGNAME = telemini-v$(TELEMINI_VER) +PROG = $(PROGNAME)-$(VERSION).ihx +PRODUCT=TeleMini-v$(TELEMINI_VER) +PRODUCT_DEF=-DTELEMINI_V_$(TELEMINI_DEF) +IDPRODUCT=0x000a + +include ../cc1111/Makefile.cc1111 + +NICKLE=nickle +CHECK_STACK=sh ../util/check-stack + +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) + +../$(PROG): $(REL) Makefile + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) || rm $@ + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean: clean + +clean: clean-cc1111 + +install: + +uninstall: + diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h new file mode 100644 index 00000000..386c8dc3 --- /dev/null +++ b/src/telemini-v2.0/ao_pins.h @@ -0,0 +1,140 @@ +/* + * Copyright © 2010 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define HAS_RADIO 1 + +#define HAS_FLIGHT 1 +#define HAS_USB 1 +#define USB_FORCE_FLIGHT_IDLE 1 +#define HAS_BEEP 1 +#define HAS_GPS 0 +#define HAS_SERIAL_1 0 +#define HAS_EEPROM 1 +#define HAS_LOG 1 +#define USE_INTERNAL_FLASH 0 +#define HAS_DBG 0 +#define PACKET_HAS_SLAVE 1 +#define USE_FAST_ASCENT_LOG 1 + +#define AO_LED_GREEN 1 +#define AO_LED_RED 2 +#define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) +#define HAS_EXTERNAL_TEMP 0 +#define HAS_ACCEL 0 +#define HAS_IGNITE 1 +#define HAS_IGNITE_REPORT 1 +#define HAS_MONITOR 0 + +/* + * SPI + */ + +#define SPI_CS_PORT P1 +#define SPI_CS_SEL P1SEL +#define SPI_CS_DIR P1DIR + +/* + * Flash + */ +#define AO_M25_SPI_CS_PORT SPI_CS_PORT +#define AO_M25_SPI_CS_MASK 0x04 /* cs_flash is P1_2 */ +#define M25_MAX_CHIPS 1 + +/* + * MS5607 + */ + +#define HAS_MS5607 1 +#define HAS_MS5611 0 +#define AO_MS5607_PRIVATE_PINS 0 +#define AO_MS5607_CS_PORT P1 +#define AO_MS5607_CS_PIN 3 +#define AO_MS5607_CS P1_3 +#define AO_MS5607_CS_MASK (1 << AO_MS5607_CS_PIN) +#define AO_MS5607_MISO_PORT P0 +#define AO_MS5607_MISO_PIN 2 +#define AO_MS5607_MISO_MASK (1 << AO_MS5607_MISO_PIN) +#define AO_MS5607_SPI_INDEX 0 + +/* + * Igniters + */ +#define AO_IGNITER_PORT P2 +#define AO_IGNITER_DROGUE_PORT AO_IGNITER_PORT +#define AO_IGNITER_DROGUE P2_3 +#define AO_IGNITER_MAIN P2_4 +#define AO_IGNITER_DIR P2DIR +#define AO_IGNITER_DROGUE_BIT (1 << 3) +#define AO_IGNITER_MAIN_BIT (1 << 4) +#define AO_IGNITER_DROGUE_PIN 3 +#define AO_IGNITER_MAIN_PIN 4 + +#define AO_IGNITER_DROGUE_PORT AO_IGNITER_PORT +#define AO_IGNITER_MAIN_PORT AO_IGNITER_PORT + +/* test these values with real igniters */ +#define AO_IGNITER_OPEN 1000 +#define AO_IGNITER_CLOSED 7000 +#define AO_IGNITER_FIRE_TIME AO_MS_TO_TICKS(50) +#define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000) + +#define AO_SEND_MINI + +/* + * ADC + */ + +#define HAS_ADC 1 +#define AO_ADC_FIRST_PIN 0 + +struct ao_adc { + int16_t sense_a; /* apogee continuity sense */ + int16_t sense_m; /* main continuity sense */ + int16_t v_batt; /* battery voltage */ +}; + +#define ao_data_count ao_adc_count + +#define AO_SENSE_DROGUE(p) ((p)->adc.sense_a) +#define AO_SENSE_MAIN(p) ((p)->adc.sense_m) + +#define AO_ADC_DUMP(p) \ + printf("tick: %5u apogee: %5d main: %5d batt: %5d\n", \ + (p)->tick, (p)->adc.sense_a, (p)->adc.sense_m, (p)->adc.v_batt) + +#define FETCH_ADC() \ + a = (uint8_t __xdata *) (&ao_data_ring[ao_data_head].adc); \ + switch (sequence) { \ + case 4: \ + a += 4; \ + sequence = 0; \ + break; \ + case 1: \ + a += 2; \ + sequence = 4; \ + break; \ + case 0: \ + sequence = 1; \ + break; \ + } \ + if (sequence) \ + ; + +#endif /* _AO_PINS_H_ */ diff --git a/src/telemini-v2.0/ao_telemini.c b/src/telemini-v2.0/ao_telemini.c new file mode 100644 index 00000000..84df2b8c --- /dev/null +++ b/src/telemini-v2.0/ao_telemini.c @@ -0,0 +1,54 @@ +/* + * Copyright © 2011 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" +#include "ao_pins.h" + +__xdata uint8_t ao_force_freq; + +void +main(void) +{ + /* + * Reduce the transient on the ignite pins at startup by + * pulling the pins low as soon as possible at power up + */ + ao_ignite_set_pins(); + + ao_clock_init(); + + /* Turn on the red LED until the system is stable */ + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_RED); + + ao_task_init(); + + ao_timer_init(); + ao_adc_init(); + ao_cmd_init(); + ao_storage_init(); + ao_ms5607_init(); + ao_flight_init(); + ao_log_init(); + ao_report_init(); + ao_telemetry_init(); + ao_radio_init(); + ao_packet_slave_init(TRUE); + ao_igniter_init(); + ao_config_init(); + ao_start_scheduler(); +} diff --git a/src/test/Makefile b/src/test/Makefile index 75b1f848..9c304318 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -2,7 +2,7 @@ vpath % ..:../core:../drivers:../util:../micropeak:../aes PROGS=ao_flight_test ao_flight_test_baro ao_flight_test_accel ao_flight_test_noisy_accel ao_flight_test_mm \ ao_gps_test ao_gps_test_skytraq ao_gps_test_ublox ao_convert_test ao_convert_pa_test ao_fec_test \ - ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test + ao_aprs_test ao_micropeak_test ao_fat_test ao_aes_test ao_int64_test INCS=ao_kalman.h ao_ms5607.h ao_log.h ao_data.h altitude-pa.h altitude.h @@ -73,3 +73,6 @@ ao_fat_test: ao_fat_test.c ao_fat.c ao_bufio.c ao_aes_test: ao_aes_test.c ao_aes.c ao_aes_tables.c cc $(CFLAGS) -o $@ ao_aes_test.c + +ao_int64_test: ao_int64_test.c ao_int64.c ao_int64.h + cc $(CFLAGS) -o $@ ao_int64_test.c -- cgit v1.2.3