From 7883744526156879ad63256ab12d959df56d5252 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 12 Jan 2013 20:11:38 -0800 Subject: altos: Initial telescience bits These might do something, and should at least bring up USB Signed-off-by: Keith Packard --- src/stm/ao_spi_stm_slave.c | 339 ++++++++++++++++++++++++++++++++++ src/telescience-v0.2/.gitignore | 2 + src/telescience-v0.2/Makefile | 85 +++++++++ src/telescience-v0.2/ao_pins.h | 141 ++++++++++++++ src/telescience-v0.2/ao_telescience.c | 51 +++++ 5 files changed, 618 insertions(+) create mode 100644 src/stm/ao_spi_stm_slave.c create mode 100644 src/telescience-v0.2/.gitignore create mode 100644 src/telescience-v0.2/Makefile create mode 100644 src/telescience-v0.2/ao_pins.h create mode 100644 src/telescience-v0.2/ao_telescience.c diff --git a/src/stm/ao_spi_stm_slave.c b/src/stm/ao_spi_stm_slave.c new file mode 100644 index 00000000..98022442 --- /dev/null +++ b/src/stm/ao_spi_stm_slave.c @@ -0,0 +1,339 @@ +/* + * 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 + +struct ao_spi_stm_slave_info { + uint8_t miso_dma_index; + uint8_t mosi_dma_index; + struct stm_spi *stm_spi; +}; + +static uint8_t ao_spi_slave_mutex[STM_NUM_SPI]; +static uint8_t ao_spi_slave_index[STM_NUM_SPI]; + +static const struct ao_spi_stm_slave_info ao_spi_stm_slave_info[STM_NUM_SPI] = { + { + .miso_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI1_RX), + .mosi_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI1_TX), + &stm_spi1 + }, + { + .miso_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI2_RX), + .mosi_dma_index = STM_DMA_INDEX(STM_DMA_CHANNEL_SPI2_TX), + &stm_spi2 + } +}; + +static uint8_t spi_dev_null; + +void +ao_spi_slave_send(void *block, uint16_t len) +{ + struct stm_spi *stm_spi = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].stm_spi; + uint8_t mosi_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].mosi_dma_index; + uint8_t miso_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].miso_dma_index; + + /* Set up the transmit DMA to deliver data */ + ao_dma_set_transfer(mosi_dma_index, + &stm_spi->dr, + block, + len, + (0 << STM_DMA_CCR_MEM2MEM) | + (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | + (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | + (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | + (1 << STM_DMA_CCR_MINC) | + (0 << STM_DMA_CCR_PINC) | + (0 << STM_DMA_CCR_CIRC) | + (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); + + /* Clear RXNE */ + (void) stm_spi->dr; + + /* Set up the receive DMA -- when this is done, we know the SPI unit + * is idle. Without this, we'd have to poll waiting for the BSY bit to + * be cleared + */ + ao_dma_set_transfer(miso_dma_index, + &stm_spi->dr, + &spi_dev_null, + len, + (0 << STM_DMA_CCR_MEM2MEM) | + (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | + (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | + (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | + (0 << STM_DMA_CCR_MINC) | + (0 << STM_DMA_CCR_PINC) | + (0 << STM_DMA_CCR_CIRC) | + (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); + stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (1 << STM_SPI_CR2_TXDMAEN) | + (1 << STM_SPI_CR2_RXDMAEN)); + ao_dma_start(miso_dma_index); + ao_dma_start(mosi_dma_index); + ao_arch_critical( + while (!ao_dma_done[miso_dma_index]) + ao_sleep(&ao_dma_done[miso_dma_index]); + ); + ao_dma_done_transfer(mosi_dma_index); + ao_dma_done_transfer(miso_dma_index); +} + + +uint8_t +ao_spi_slave_recv(void *block, uint16_t len) +{ + struct stm_spi *stm_spi = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].stm_spi; + uint8_t mosi_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].mosi_dma_index; + uint8_t miso_dma_index = ao_spi_stm_slave_info[AO_SPI_INDEX(SPI_SLAVE_INDEX)].miso_dma_index; + + /* Set up transmit DMA to make the SPI hardware actually run */ + ao_dma_set_transfer(mosi_dma_index, + &stm_spi->dr, + &spi_dev_null, + len, + (0 << STM_DMA_CCR_MEM2MEM) | + (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | + (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | + (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | + (0 << STM_DMA_CCR_MINC) | + (0 << STM_DMA_CCR_PINC) | + (0 << STM_DMA_CCR_CIRC) | + (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); + + /* Clear RXNE */ + (void) stm_spi->dr; + + /* Set up the receive DMA to capture data */ + ao_dma_set_transfer(miso_dma_index, + &stm_spi->dr, + block, + len, + (0 << STM_DMA_CCR_MEM2MEM) | + (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) | + (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) | + (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) | + (1 << STM_DMA_CCR_MINC) | + (0 << STM_DMA_CCR_PINC) | + (0 << STM_DMA_CCR_CIRC) | + (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); + + stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (1 << STM_SPI_CR2_TXDMAEN) | + (1 << STM_SPI_CR2_RXDMAEN)); + ao_dma_start(miso_dma_index); + ao_dma_start(mosi_dma_index); + + /* Wait until the SPI unit is done */ + ao_arch_critical( + while (!ao_dma_done[miso_dma_index]) + ao_sleep(&ao_dma_done[miso_dma_index]); + ); + + ao_dma_done_transfer(mosi_dma_index); + ao_dma_done_transfer(miso_dma_index); +} + +static void +ao_spi_slave_disable_index(uint8_t spi_index) +{ + /* Disable current config + */ + switch (AO_SPI_INDEX(spi_index)) { + case STM_SPI_INDEX(1): + switch (spi_index) { + case AO_SPI_1_PA5_PA6_PA7: + stm_gpio_set(&stm_gpioa, 5, 1); + stm_moder_set(&stm_gpioa, 5, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpioa, 6, STM_MODER_INPUT); + stm_moder_set(&stm_gpioa, 7, STM_MODER_OUTPUT); + break; + case AO_SPI_1_PB3_PB4_PB5: + stm_gpio_set(&stm_gpiob, 3, 1); + stm_moder_set(&stm_gpiob, 3, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpiob, 4, STM_MODER_INPUT); + stm_moder_set(&stm_gpiob, 5, STM_MODER_OUTPUT); + break; + case AO_SPI_1_PE13_PE14_PE15: + stm_gpio_set(&stm_gpioe, 13, 1); + stm_moder_set(&stm_gpioe, 13, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpioe, 14, STM_MODER_INPUT); + stm_moder_set(&stm_gpioe, 15, STM_MODER_OUTPUT); + break; + } + break; + case STM_SPI_INDEX(2): + switch (spi_index) { + case AO_SPI_2_PB13_PB14_PB15: + stm_gpio_set(&stm_gpiob, 13, 1); + stm_moder_set(&stm_gpiob, 13, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpiob, 14, STM_MODER_INPUT); + stm_moder_set(&stm_gpiob, 15, STM_MODER_OUTPUT); + break; + case AO_SPI_2_PD1_PD3_PD4: + stm_gpio_set(&stm_gpiod, 1, 1); + stm_moder_set(&stm_gpiod, 1, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpiod, 3, STM_MODER_INPUT); + stm_moder_set(&stm_gpiod, 4, STM_MODER_OUTPUT); + break; + } + break; + } +} + +static void +ao_spi_slave_enable_index(uint8_t spi_index) +{ + switch (AO_SPI_INDEX(spi_index)) { + case STM_SPI_INDEX(1): + switch (spi_index) { + case AO_SPI_1_PA5_PA6_PA7: + stm_afr_set(&stm_gpioa, 5, STM_AFR_AF5); + stm_afr_set(&stm_gpioa, 6, STM_AFR_AF5); + stm_afr_set(&stm_gpioa, 7, STM_AFR_AF5); + break; + case AO_SPI_1_PB3_PB4_PB5: + stm_afr_set(&stm_gpiob, 3, STM_AFR_AF5); + stm_afr_set(&stm_gpiob, 4, STM_AFR_AF5); + stm_afr_set(&stm_gpiob, 5, STM_AFR_AF5); + break; + case AO_SPI_1_PE13_PE14_PE15: + stm_afr_set(&stm_gpioe, 13, STM_AFR_AF5); + stm_afr_set(&stm_gpioe, 14, STM_AFR_AF5); + stm_afr_set(&stm_gpioe, 15, STM_AFR_AF5); + break; + } + break; + case STM_SPI_INDEX(2): + switch (spi_index) { + case AO_SPI_2_PB13_PB14_PB15: + stm_afr_set(&stm_gpiob, 13, STM_AFR_AF5); + stm_afr_set(&stm_gpiob, 14, STM_AFR_AF5); + stm_afr_set(&stm_gpiob, 15, STM_AFR_AF5); + break; + case AO_SPI_2_PD1_PD3_PD4: + stm_afr_set(&stm_gpiod, 1, STM_AFR_AF5); + stm_afr_set(&stm_gpiod, 3, STM_AFR_AF5); + stm_afr_set(&stm_gpiod, 4, STM_AFR_AF5); + break; + } + break; + } +} + +void +ao_spi_slave_get(uint8_t spi_index, uint32_t speed) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_slave_info[id].stm_spi; + + ao_mutex_get(&ao_spi_slave_mutex[id]); + stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) | /* Three wire mode */ + (0 << STM_SPI_CR1_BIDIOE) | + (0 << STM_SPI_CR1_CRCEN) | /* CRC disabled */ + (0 << STM_SPI_CR1_CRCNEXT) | + (0 << STM_SPI_CR1_DFF) | + (0 << STM_SPI_CR1_RXONLY) | + (1 << STM_SPI_CR1_SSM) | /* Software SS handling */ + (1 << STM_SPI_CR1_SSI) | /* ... */ + (0 << STM_SPI_CR1_LSBFIRST) | /* Big endian */ + (1 << STM_SPI_CR1_SPE) | /* Enable SPI unit */ + (speed << STM_SPI_CR1_BR) | /* baud rate to pclk/4 */ + (1 << STM_SPI_CR1_MSTR) | + (0 << STM_SPI_CR1_CPOL) | /* Format 0 */ + (0 << STM_SPI_CR1_CPHA)); + if (spi_index != ao_spi_slave_index[id]) { + + /* Disable old config + */ + ao_spi_slave_disable_index(ao_spi_slave_index[id]); + + /* Enable new config + */ + ao_spi_slave_enable_index(spi_index); + + /* Remember current config + */ + ao_spi_slave_index[id] = spi_index; + } +} + +void +ao_spi_slave_put(uint8_t spi_index) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_slave_info[id].stm_spi; + + stm_spi->cr1 = 0; + ao_mutex_put(&ao_spi_slave_mutex[id]); +} + +static void +ao_spi_channel_init(uint8_t spi_index) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_slave_info[id].stm_spi; + + ao_spi_slave_disable_index(spi_index); + + stm_spi->cr1 = 0; + (void) stm_spi->sr; + stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (0 << STM_SPI_CR2_TXDMAEN) | + (0 << STM_SPI_CR2_RXDMAEN)); +} + +void +ao_spi_slave_init(void) +{ +#if HAS_SPI_SLAVE_1 +# if SPI_1_PA5_PA6_PA7 + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); +# endif +# if SPI_1_PB3_PB4_PB5 + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +# endif +# if SPI_1_PE13_PE14_PE15 + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); +# endif + stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN); + ao_spi_slave_index[0] = AO_SPI_CONFIG_NONE; + ao_spi_channel_init(0); +#endif + +#if HAS_SPI_SLAVE_2 +# if SPI_2_PB13_PB14_PB15 + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); +# endif +# if SPI_2_PD1_PD3_PD4 + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); +# endif + stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN); + ao_spi_slave_index[1] = AO_SPI_CONFIG_NONE; + ao_spi_channel_init(1); +#endif +} diff --git a/src/telescience-v0.2/.gitignore b/src/telescience-v0.2/.gitignore new file mode 100644 index 00000000..cc1f8b73 --- /dev/null +++ b/src/telescience-v0.2/.gitignore @@ -0,0 +1,2 @@ +ao_product.h +telescience-*.elf diff --git a/src/telescience-v0.2/Makefile b/src/telescience-v0.2/Makefile new file mode 100644 index 00000000..fbeeb75c --- /dev/null +++ b/src/telescience-v0.2/Makefile @@ -0,0 +1,85 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_pins.h \ + ao_product.h \ + ao_cc1120_CC1120.h \ + ao_task.h \ + ao_whiten.h \ + stm32l.h \ + Makefile + +#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 + +ALTOS_SRC = \ + 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_dma_stm.c \ + ao_spi_stm.c \ + ao_usb_stm.c \ + ao_adc_stm.c \ + ao_data.c \ + ao_exti_stm.c \ + ao_storage.c \ + ao_m25.c \ + ao_science_slave.c \ + ao_spi_stm_slave.c \ + ao_log_telescience.c \ + ao_log_single.c + +PRODUCT=TeleScience-v0.2 +PRODUCT_DEF=-DTELESCIENCE +IDPRODUCT=0x0011 + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=telescience-v0.2 +PROG=$(PROGNAME)-$(VERSION).elf + +SRC=$(ALTOS_SRC) ao_telescience.c +OBJ=$(SRC:.c=.o) + +all: $(PROG) + +$(PROG): Makefile $(OBJ) altos.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc + +$(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 + rm -f ao_product.h + +install: + +uninstall: diff --git a/src/telescience-v0.2/ao_pins.h b/src/telescience-v0.2/ao_pins.h new file mode 100644 index 00000000..cb86fcb6 --- /dev/null +++ b/src/telescience-v0.2/ao_pins.h @@ -0,0 +1,141 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define HAS_TASK_QUEUE 1 + +/* 8MHz High speed external crystal */ +#define AO_HSE 8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL 12 +#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV 3 +#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER 2 +#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER 2 +#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2 + +#define HAS_SERIAL_1 0 +#define USE_SERIAL_1_STDIN 0 +#define SERIAL_1_PB6_PB7 0 +#define SERIAL_1_PA9_PA10 1 + +#define HAS_SERIAL_2 0 +#define USE_SERIAL_2_STDIN 0 +#define SERIAL_2_PA2_PA3 0 +#define SERIAL_2_PD5_PD6 0 + +#define HAS_SERIAL_3 0 +#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 HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 +#define HAS_USB 1 +#define HAS_BEEP 0 +#define HAS_RADIO 0 +#define HAS_TELEMETRY 0 +#define PACKET_HAS_SLAVE 0 + +#define HAS_SPI_1 1 +#define SPI_1_PA5_PA6_PA7 1 +#define SPI_1_PB3_PB4_PB5 0 +#define SPI_1_PE13_PE14_PE15 0 + +#define HAS_SPI_2 1 +#define SPI_2_PB13_PB14_PB15 1 +#define SPI_2_PD1_PD3_PD4 0 + +#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 SPI_SLAVE_INDEX 1 + +#define HAS_I2C_1 0 +#define I2C_1_PB8_PB9 0 + +#define HAS_I2C_2 0 +#define I2C_2_PB10_PB11 0 + +#define LOW_LEVEL_DEBUG 0 + +#define LED_PORT_0_ENABLE STM_RCC_AHBENR_GPIOAEN + +#define LED_PORT_0 (&stm_gpioa) +#define LED_PORT_0_MASK (0xff) +#define LED_PORT_0_SHIFT 0 +#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 0 +#define HAS_FLIGHT 0 +#define HAS_ADC 1 +#define HAS_LOG 1 + +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT (&stm_gpioa) +#define AO_M25_SPI_CS_MASK (1 << 3) +#define AO_M25_SPI_BUS AO_SPI_2_PB13_PB14_PB15 + +/* + * ADC + */ + +#define AO_DATA_RING 32 +#define AO_ADC_NUM 1 + +struct ao_adc { + int16_t adc[AO_ADC_NUM]; +}; + +#define AO_ADC_TEMP 16 + +#define AO_ADC_RCC_AHBENR 0 + +#define AO_NUM_ADC_PIN 0 + +#define AO_NUM_ADC 1 + +#define AO_ADC_SQ1 AO_ADC_TEMP + + +#endif /* _AO_PINS_H_ */ diff --git a/src/telescience-v0.2/ao_telescience.c b/src/telescience-v0.2/ao_telescience.c new file mode 100644 index 00000000..2fb3186a --- /dev/null +++ b/src/telescience-v0.2/ao_telescience.c @@ -0,0 +1,51 @@ +/* + * 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 +#include +#include +#include + +int +main(void) +{ + ao_clock_init(); + +#if HAS_STACK_GUARD + ao_mpu_init(); +#endif + + ao_task_init(); + ao_led_init(LEDS_AVAILABLE); + ao_led_on(AO_LED_GREEN); + ao_timer_init(); + + ao_spi_init(); + ao_spi_slave_init(); + ao_dma_init(); + ao_exti_init(); + + ao_cmd_init(); + + ao_usb_init(); + ao_config_init(); + + ao_storage_init(); + + ao_start_scheduler(); + return 0; +} -- cgit v1.2.3 From 3645cb6578ec2a11ab7b0f6d435c6de22ca02a9f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jan 2013 10:31:59 -0800 Subject: Update avr ao_spi_slave code to match API changes Made the interface use void * for pointers and uint16_t for lengths Signed-off-by: Keith Packard --- src/avr/ao_spi_slave.c | 10 ++++++---- src/core/ao.h | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/avr/ao_spi_slave.c b/src/avr/ao_spi_slave.c index a400b8a0..15e9924d 100644 --- a/src/avr/ao_spi_slave.c +++ b/src/avr/ao_spi_slave.c @@ -18,22 +18,24 @@ #include "ao.h" uint8_t -ao_spi_slave_recv(uint8_t *buf, uint8_t len) +ao_spi_slave_recv(void *buf, uint16_t len) { + uint8_t *b = buf; while (len--) { while (!(SPSR & (1 << SPIF))) if ((PINB & (1 << PINB0))) return 0; - *buf++ = SPDR; + *b++ = SPDR; } return 1; } void -ao_spi_slave_send(uint8_t *buf, uint8_t len) +ao_spi_slave_send(void *buf, uint16_t len) { + uint8_t *b = buf; while (len--) { - SPDR = *buf++; + SPDR = *b++; while (!(SPSR & (1 << SPIF))) if ((PINB & (1 << PINB0))) return; diff --git a/src/core/ao.h b/src/core/ao.h index df5bbf48..ce0bf5d1 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -299,10 +299,10 @@ ao_altitude_to_pa(alt_t alt); */ uint8_t -ao_spi_slave_recv(uint8_t *buf, uint8_t len); +ao_spi_slave_recv(void *buf, uint16_t len); void -ao_spi_slave_send(uint8_t *buf, uint8_t len); +ao_spi_slave_send(void *buf, uint16_t len); void ao_spi_slave_init(void); -- cgit v1.2.3 From f2810aa33fc6fe254761a0044c62c7b23e59e6bc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jan 2013 20:48:08 -0800 Subject: altos: Build telescience-v0.2 Signed-off-by: Keith Packard --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 473cc60a..a17f51ac 100644 --- a/src/Makefile +++ b/src/Makefile @@ -22,7 +22,7 @@ SDCCDIRS=\ telelaunch-v0.1 tidongle test \ teleterra-v0.2 teleshield-v0.1 \ telefire-v0.1 \ - spiradio-v0.1 + spiradio-v0.1 telescience-v0.2 AVRDIRS=\ telescience-v0.1 telescience-pwm telepyro-v0.1 micropeak -- cgit v1.2.3 From 8d885616e2e522b8aea5e7d5398f16d330a0cffa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jan 2013 20:48:47 -0800 Subject: altos: Set STM GPIO output speed for SPI pins correctly The GPIO pin settings affect the output impedence, and hence the maximum speed for SPI. Cranking these to suitable values allows SPI to run at full speed. Signed-off-by: Keith Packard --- src/megadongle-v0.1/ao_pins.h | 1 + src/megametrum-v0.1/ao_pins.h | 2 ++ src/stm-demo/ao_pins.h | 1 + src/stm/ao_spi_stm.c | 15 +++++++++++++++ src/telelco-v0.1/ao_pins.h | 7 ++++--- src/telescience-v0.2/ao_pins.h | 7 +++++-- 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/megadongle-v0.1/ao_pins.h b/src/megadongle-v0.1/ao_pins.h index c766a48c..d460a490 100644 --- a/src/megadongle-v0.1/ao_pins.h +++ b/src/megadongle-v0.1/ao_pins.h @@ -78,6 +78,7 @@ #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 diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index 64da41a9..4c645871 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -76,10 +76,12 @@ #define SPI_1_PA5_PA6_PA7 1 /* Barometer */ #define SPI_1_PB3_PB4_PB5 0 #define SPI_1_PE13_PE14_PE15 1 /* Accelerometer */ +#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 diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index c9c7446e..07b4a19d 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -60,6 +60,7 @@ #define HAS_SPI_1 1 #define SPI_1_PB3_PB4_PB5 1 +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz #define HAS_SPI_2 0 diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 599d7ee0..7b4af964 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -425,12 +425,21 @@ ao_spi_init(void) #if HAS_SPI_1 # if SPI_1_PA5_PA6_PA7 stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); + stm_ospeedr_set(&stm_gpioa, 5, SPI_1_OSPEEDR); + stm_ospeedr_set(&stm_gpioa, 6, SPI_1_OSPEEDR); + stm_ospeedr_set(&stm_gpioa, 7, SPI_1_OSPEEDR); # endif # if SPI_1_PB3_PB4_PB5 stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); + stm_ospeedr_set(&stm_gpiob, 3, SPI_1_OSPEEDR); + stm_ospeedr_set(&stm_gpiob, 4, SPI_1_OSPEEDR); + stm_ospeedr_set(&stm_gpiob, 5, SPI_1_OSPEEDR); # endif # if SPI_1_PE13_PE14_PE15 stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); + stm_ospeedr_set(&stm_gpioe, 13, SPI_1_OSPEEDR); + stm_ospeedr_set(&stm_gpioe, 14, SPI_1_OSPEEDR); + stm_ospeedr_set(&stm_gpioe, 15, SPI_1_OSPEEDR); # endif stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN); ao_spi_index[0] = AO_SPI_CONFIG_NONE; @@ -440,9 +449,15 @@ ao_spi_init(void) #if HAS_SPI_2 # if SPI_2_PB13_PB14_PB15 stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); + stm_ospeedr_set(&stm_gpiob, 13, SPI_2_OSPEEDR); + stm_ospeedr_set(&stm_gpiob, 14, SPI_2_OSPEEDR); + stm_ospeedr_set(&stm_gpiob, 15, SPI_2_OSPEEDR); # endif # if SPI_2_PD1_PD3_PD4 stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); + stm_ospeedr_set(&stm_gpiod, 1, SPI_2_OSPEEDR); + stm_ospeedr_set(&stm_gpiod, 3, SPI_2_OSPEEDR); + stm_ospeedr_set(&stm_gpiod, 4, SPI_2_OSPEEDR); # endif stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN); ao_spi_index[1] = AO_SPI_CONFIG_NONE; diff --git a/src/telelco-v0.1/ao_pins.h b/src/telelco-v0.1/ao_pins.h index 60cf018f..970f9bd1 100644 --- a/src/telelco-v0.1/ao_pins.h +++ b/src/telelco-v0.1/ao_pins.h @@ -49,18 +49,19 @@ #define HAS_TELEMETRY 0 #define HAS_AES 1 -#define HAS_SPI_1 1 -#define SPI_1_PA5_PA6_PA7 1 +#define HAS_SPI_1 0 +#define SPI_1_PA5_PA6_PA7 0 #define SPI_1_PB3_PB4_PB5 0 #define SPI_1_PE13_PE14_PE15 0 -#define HAS_SPI_2 1 +#define HAS_SPI_2 1 /* CC1111 */ #define SPI_2_PB13_PB14_PB15 1 #define SPI_2_PD1_PD3_PD4 0 #define SPI_2_GPIO (&stm_gpiob) #define SPI_2_SCK 13 #define SPI_2_MISO 14 #define SPI_2_MOSI 15 +#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz #define HAS_I2C_1 0 diff --git a/src/telescience-v0.2/ao_pins.h b/src/telescience-v0.2/ao_pins.h index cb86fcb6..7b974506 100644 --- a/src/telescience-v0.2/ao_pins.h +++ b/src/telescience-v0.2/ao_pins.h @@ -67,14 +67,17 @@ #define HAS_TELEMETRY 0 #define PACKET_HAS_SLAVE 0 -#define HAS_SPI_1 1 -#define SPI_1_PA5_PA6_PA7 1 +#define HAS_SPI_1 0 +#define HAS_SPI_SLAVE_1 1 +#define SPI_1_PA5_PA6_PA7 1 #define SPI_1_PB3_PB4_PB5 0 #define SPI_1_PE13_PE14_PE15 0 +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz #define HAS_SPI_2 1 #define SPI_2_PB13_PB14_PB15 1 #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 -- cgit v1.2.3 From a866431e9a063830b407f749ff97a730831e5e4e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jan 2013 20:50:10 -0800 Subject: altos: Crank fast SPI on STM to 8MHz With the GPIO pins set to 10MHz now, we can run SPI at the maximum possible speed (8MHz). Signed-off-by: Keith Packard --- src/stm/ao_arch_funcs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 87bbe73e..d1779307 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -23,7 +23,7 @@ /* PCLK is set to 16MHz (HCLK 32MHz, APB prescaler 2) */ -#define AO_SPI_SPEED_8MHz STM_SPI_CR1_BR_PCLK_2 /* This doesn't appear to work */ +#define AO_SPI_SPEED_8MHz STM_SPI_CR1_BR_PCLK_2 #define AO_SPI_SPEED_4MHz STM_SPI_CR1_BR_PCLK_4 #define AO_SPI_SPEED_2MHz STM_SPI_CR1_BR_PCLK_8 #define AO_SPI_SPEED_1MHz STM_SPI_CR1_BR_PCLK_16 @@ -32,7 +32,7 @@ #define AO_SPI_SPEED_125kHz STM_SPI_CR1_BR_PCLK_128 #define AO_SPI_SPEED_62500Hz STM_SPI_CR1_BR_PCLK_256 -#define AO_SPI_SPEED_FAST AO_SPI_SPEED_4MHz +#define AO_SPI_SPEED_FAST AO_SPI_SPEED_8MHz /* Companion bus wants something no faster than 200kHz */ -- cgit v1.2.3 From f24c4219de9563cf0ef24b763ce54d961c182696 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 13 Jan 2013 21:38:26 -0800 Subject: altos: Change CC1120 SPI speed to 4MHz. Most of the chip can run at 8MHz, but extended register access is limited to 6.1MHz. Instead of pushing things, just run the SPI bus at 4MHz. Signed-off-by: Keith Packard --- src/drivers/ao_cc1120.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 8068740f..53bb5a62 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -38,7 +38,7 @@ extern const uint32_t ao_radio_cal; #define FOSC 32000000 -#define ao_radio_select() ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_1MHz) +#define ao_radio_select() ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz) #define ao_radio_deselect() ao_spi_put_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS) #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1120_SPI_BUS) #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1120_SPI_BUS) -- cgit v1.2.3 From f2b59cf3d30425bc4b12f37e86832e40b7702d3d Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 16 Jan 2013 10:46:04 -0700 Subject: document what the 'Age' value in the AltosUI display means --- doc/altusmetrum.xsl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index e7ab353b..0fd19e60 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -769,6 +769,15 @@ NAR #88757, TRA #12200 incorrect data from being reported. + + + The age of the displayed data, in seconds since the last + successfully received telemetry packet. In normal operation + this will stay in the low single digits. If the number starts + counting up, then you are no longer receiving data over the radio + link from the flight computer. + + Finally, the largest portion of the window contains a set of -- cgit v1.2.3 From 25435dcbc6416935aa432fc090ea977bfff5d153 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Feb 2013 00:19:49 -0800 Subject: altos/stm: Add more bits to NVIC register definitions This cleans up a few values, adds more comments and a few more NVIC fields. Signed-off-by: Keith Packard --- src/stm/stm32l.h | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 0dbfae39..1d636037 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -811,30 +811,41 @@ extern struct stm_lcd stm_lcd; #define STM_LCD_CLR_UDDC (3) #define STM_LCD_CLR_SOFC (1) +/* The NVIC starts at 0xe000e100, so add that to the offsets to find the absolute address */ + struct stm_nvic { - vuint32_t iser[3]; /* 0x000 */ + vuint32_t iser[8]; /* 0x000 0xe000e100 Set Enable Register */ + + uint8_t _unused020[0x080 - 0x020]; + + vuint32_t icer[8]; /* 0x080 0xe000e180 Clear Enable Register */ - uint8_t _unused00c[0x080 - 0x00c]; + uint8_t _unused0a0[0x100 - 0x0a0]; - vuint32_t icer[3]; /* 0x080 */ + vuint32_t ispr[8]; /* 0x100 0xe000e200 Set Pending Register */ - uint8_t _unused08c[0x100 - 0x08c]; + uint8_t _unused120[0x180 - 0x120]; - vuint32_t ispr[3]; /* 0x100 */ + vuint32_t icpr[8]; /* 0x180 0xe000e280 Clear Pending Register */ - uint8_t _unused10c[0x180 - 0x10c]; + uint8_t _unused1a0[0x200 - 0x1a0]; - vuint32_t icpr[3]; /* 0x180 */ + vuint32_t iabr[8]; /* 0x200 0xe000e300 Active Bit Register */ - uint8_t _unused18c[0x200 - 0x18c]; + uint8_t _unused220[0x300 - 0x220]; - vuint32_t iabr[3]; /* 0x200 */ + vuint32_t ipr[60]; /* 0x300 0xe000e400 Priority Register */ - uint8_t _unused20c[0x300 - 0x20c]; + uint8_t _unused3f0[0xc00 - 0x3f0]; - vuint32_t ipr[21]; /* 0x300 */ + vuint32_t cpuid_base; /* 0xc00 0xe000ed00 CPUID Base Register */ + vuint32_t ics; /* 0xc04 0xe000ed04 Interrupt Control State Register */ + vuint32_t vto; /* 0xc08 0xe000ed08 Vector Table Offset Register */ + vuint32_t ai_rc; /* 0xc0c 0xe000ed0c Application Interrupt/Reset Control Register */ + vuint32_t sc; /* 0xc10 0xe000ed10 System Control Register */ + vuint32_t cc; /* 0xc14 0xe000ed14 Configuration Control Register */ - uint8_t _unused324[0xe00 - 0x324]; + uint8_t _unusedc18[0xe00 - 0xc18]; vuint32_t stir; /* 0xe00 */ }; -- cgit v1.2.3 From 5246acb70b79980de36bd5d0ba0d017529ae9a78 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Feb 2013 00:20:36 -0800 Subject: Update build version to 1.2 Prepare for 1.2 release Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a1c8c4fc..448df6a4 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.1.9.3) +AC_INIT([altos], 1.2) AC_CONFIG_SRCDIR([src/core/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From 9230f0a5b119044235c0c419e85a83115aae924d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Feb 2013 01:20:16 -0800 Subject: altos/driver: Make HMC5883 driver build again Adapt to changes in OS interfaces Signed-off-by: Keith Packard --- src/drivers/ao_hmc5883.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c index 059fc2c8..782d03f4 100644 --- a/src/drivers/ao_hmc5883.c +++ b/src/drivers/ao_hmc5883.c @@ -77,11 +77,11 @@ ao_hmc5883_sample(struct ao_hmc5883_sample *sample) ao_hmc5883_reg_write(HMC5883_MODE, HMC5883_MODE_SINGLE); ao_alarm(AO_MS_TO_TICKS(10)); - cli(); + ao_arch_block_interrupts(); while (!ao_hmc5883_done) if (ao_sleep(&ao_hmc5883_done)) ++ao_hmc5883_missed_irq; - sei(); + ao_arch_release_interrupts(); ao_clear_alarm(); ao_hmc5883_read(HMC5883_X_MSB, (uint8_t *) sample, sizeof (struct ao_hmc5883_sample)); @@ -109,7 +109,7 @@ ao_hmc5883_setup(void) ao_i2c_put(AO_HMC5883_I2C_INDEX); if (!present) - ao_panic(AO_PANIC_SELF_TEST); + ao_panic(AO_PANIC_SELF_TEST_HMC5883); ao_hmc5883_reg_write(HMC5883_CONFIG_A, (HMC5883_CONFIG_A_MA_8 << HMC5883_CONFIG_A_MA) | -- cgit v1.2.3 From d0bd0093a65b73a178da6ddcafcc4dbaa3caca39 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 24 Feb 2013 01:20:41 -0800 Subject: altos: telescience-v0.2 is an ARM product Move it from SDCC to ARM targets as Jenkins doesn't have an ARM compiler. Signed-off-by: Keith Packard --- src/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index e4b11039..9e31e3ea 100644 --- a/src/Makefile +++ b/src/Makefile @@ -23,13 +23,14 @@ SDCCDIRS=\ telelaunch-v0.1 tidongle test \ teleterra-v0.2 teleshield-v0.1 \ telefire-v0.1 \ - spiradio-v0.1 telescience-v0.2 + spiradio-v0.1 AVRDIRS=\ telescience-v0.1 telescience-pwm telepyro-v0.1 micropeak ARMDIRS=\ - megametrum-v0.1 megadongle-v0.1 stm-bringup stm-demo telelco-v0.1 + megametrum-v0.1 megadongle-v0.1 stm-bringup stm-demo telelco-v0.1 \ + telescience-v0.2 ifneq ($(shell which sdcc),) SUBDIRS += $(SDCCDIRS) -- cgit v1.2.3 From 351e4110f519d18bb36747955578e9e5b9aeec7b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 1 Mar 2013 12:28:34 -0800 Subject: altosuilib: Add setNotify/fireSeriesChanged methods to AltosUIGrapher This will let the data adding functions disable notifications while adding all of the graph data, and then send a single notification when the data sets are complete, which speeds up creating of the graph elements quite a bit. Signed-off-by: Keith Packard --- altosuilib/AltosUIGrapher.java | 4 ++++ altosuilib/AltosUIMarker.java | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/altosuilib/AltosUIGrapher.java b/altosuilib/AltosUIGrapher.java index c627fec5..8f0ce801 100644 --- a/altosuilib/AltosUIGrapher.java +++ b/altosuilib/AltosUIGrapher.java @@ -43,4 +43,8 @@ interface AltosUIGrapher { public abstract void add(AltosUIDataPoint dataPoint); public abstract void set_enable(boolean enable); + + public abstract void setNotify(boolean notify); + + public abstract void fireSeriesChanged(); } diff --git a/altosuilib/AltosUIMarker.java b/altosuilib/AltosUIMarker.java index e2eb9028..0949be6f 100644 --- a/altosuilib/AltosUIMarker.java +++ b/altosuilib/AltosUIMarker.java @@ -100,6 +100,12 @@ public class AltosUIMarker implements AltosUIGrapher { this.enabled = enable; } + public void setNotify(boolean notify) { + } + + public void fireSeriesChanged() { + } + public AltosUIMarker (int fetch, Color color, XYPlot plot) { this(fetch, color, plot, true); } -- cgit v1.2.3 From 113b1146f6ac0ecd423f3fb409e02730604b8aca Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 1 Mar 2013 12:34:04 -0800 Subject: altosuilib: Disable graph element notifies for each add() This reduces the number of notify calls made and dramatically speeds up graph creation. Signed-off-by: Keith Packard --- altosuilib/AltosUIGraph.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/altosuilib/AltosUIGraph.java b/altosuilib/AltosUIGraph.java index 5c589c02..5f3a2eef 100644 --- a/altosuilib/AltosUIGraph.java +++ b/altosuilib/AltosUIGraph.java @@ -91,13 +91,19 @@ public class AltosUIGraph implements AltosUnitsListener { } public void resetData() { - for (AltosUIGrapher g : graphers) + for (AltosUIGrapher g : graphers) { g.clear(); + g.setNotify(false); + } if (dataSet != null) { for (AltosUIDataPoint dataPoint : dataSet.dataPoints()) for (AltosUIGrapher g : graphers) g.add(dataPoint); } + for (AltosUIGrapher g : graphers) { + g.setNotify(true); + g.fireSeriesChanged(); + } } public void units_changed(boolean imperial_units) { -- cgit v1.2.3 From c9cba68049f957d69a88150470c086dd6f4a42c0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 1 Mar 2013 20:45:43 -0800 Subject: doc: Document how to get TeleMini to 'emergency recovery' mode TeleMini needs emergency recovery mode in case you forget the radio parameters and need to get things back to a known state. Add documentation to describe what this does and how to get it enabled. Signed-off-by: Keith Packard --- doc/altusmetrum.xsl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index 9fdd6b07..e696da79 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -386,6 +386,36 @@ NAR #88757, TRA #12200 tower with a screw-driver trying to turn on your avionics before installing igniters! + + TeleMini is configured via the radio link. Of course, that + means you need to know the TeleMini radio configuration values + or you won't be able to communicate with it. For situations + when you don't have the radio configuration values, TeleMini + offers an 'emergency recovery' mode. In this mode, TeleMini is + configured as follows: + + + Sets the radio frequency to 434.550MHz + + + Sets the radio calibration back to the factory value. + + + Sets the callsign to N0CALL + + + Does not go to 'pad' mode after five seconds. + + + + + To get into 'emergency recovery' mode, first find the row of + four small holes opposite the switch wiring. Using a short + piece of small gauge wire, connect the outer two holes + together, then power TeleMini up. Once the red LED is lit, + disconnect the wire and the board should signal that it's in + 'idle' mode after the initial five second startup period. +
GPS -- cgit v1.2.3 From cb09076fe16d28e25f5b20b2178cfad10adbeddb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 1 Mar 2013 20:48:28 -0800 Subject: doc: Add version 1.2 release notes Signed-off-by: Keith Packard --- doc/Makefile | 3 +- doc/altusmetrum.xsl | 1 + doc/release-notes-1.2.xsl | 94 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 doc/release-notes-1.2.xsl diff --git a/doc/Makefile b/doc/Makefile index 59fd4ebb..7c4da29e 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -8,8 +8,9 @@ RELNOTES=\ release-notes-0.9.html \ release-notes-0.9.2.html \ release-notes-1.0.1.html \ + release-notes-1.1.html \ release-notes-1.1.1.html \ - release-notes-1.1.html + release-notes-1.2.html RELNOTES_XSL=$(RELNOTES:.html=.xsl) HTML=altusmetrum.html altos.html telemetry.html companion.html micropeak.html $(RELNOTES) diff --git a/doc/altusmetrum.xsl b/doc/altusmetrum.xsl index e696da79..c5c08d4e 100644 --- a/doc/altusmetrum.xsl +++ b/doc/altusmetrum.xsl @@ -2679,6 +2679,7 @@ NAR #88757, TRA #12200 Release Notes + Version 1.2 Version 1.1.1 Version 1.1 Version 1.0.1 diff --git a/doc/release-notes-1.2.xsl b/doc/release-notes-1.2.xsl new file mode 100644 index 00000000..610fa1a2 --- /dev/null +++ b/doc/release-notes-1.2.xsl @@ -0,0 +1,94 @@ + + + +
+ + Version 1.2 is a minor release. It provides a few new features in AltosUI + and the AltOS firmware and fixes bugs. + + + AltOS Firmware Changes + + + In TeleMini recovery mode (when booted with the outer two + debug pins connected together), the radio parameters are also + set back to defaults (434.550MHz, N0CALL, factory radio cal). + + + Add support for reflashing the SkyTraq GPS chips. This + requires special host-side code which currently only exists + for Linux. + + + Add MicroPeak support. This includes support for the ATtiny85 + processor and adaptations to the core code to allow for + devices too small to run the multi-tasking scheduler. + + + Correct Kalman filter model error covariance matrix. The + values used previously assumed continuous measurements instead + of discrete measurements. + + + + + AltosUI Changes + + + Handle missing GPS lock in 'Descent' tab. Previously, if the + GPS position of the pad was unknown, an exception would be + raised, breaking the Descent tab contents. + + + Add preliminary MegaMetrum support, including configuration, + data download and analysis. + + + Improve the graph, adding tool-tips to show values near the + cursor and making the displayed set of values configurable, + adding all of the flight data as options while leaving the + default settings alone so that the graph starts by showing + height, speed and acceleration. + + + Make the initial position of the AltosUI top level window + configurable. Along with this change, the other windows will + pop up at 'sensible' places now, instead of on top of one + another. + + + Add callsign to Monitor idle window and connecting + dialogs. This makes it clear which callsign is being used so + that the operator will be aware that it must match the flight + computer value or no communication will work. + + + When downloading flight data, display the block number so that + the user has some sense of progress. Unfortunately, we don't + know how many blocks will need to be downloaded, but at least + it isn't just sitting there doing nothing for a long time. + + + Add GPS data and a map to the graph window. This lets you see + a complete summary of the flight without needing to 'replay' + the whole thing. + + + + + Distribution Changes + + + Distribute Mac OS X packages in disk image ('.dmg') format to + greatly simplify installation. + + + Provide version numbers for the shared Java libraries to + ensure that upgrades work properly, and to allow for multiple + Altus Metrum software packages to be installed in the same + directory at the same time. + + + +
-- cgit v1.2.3 From 784edcda52d681bbc9302fbc7efb80cb214f71b8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 2 Mar 2013 17:46:29 -0800 Subject: libaltos: Open FTDI serial devices twice on Windows. Looks like the Windows FTDI driver has 'issues' and opening it only once doesn't work correctly. Just close and re-open the device and it seems to be perfectly happy. Who knows? Signed-off-by: Keith Packard --- libaltos/libaltos.c | 116 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 24 deletions(-) diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index ca56746a..2a41ef80 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -977,6 +977,24 @@ struct altos_file { OVERLAPPED ov_write; }; +#include + +static void +log_message(char *fmt, ...) +{ + static FILE *log = NULL; + va_list a; + + if (!log) + log = fopen("\\temp\\altos.txt", "w"); + if (log) { + va_start(a, fmt); + vfprintf(log, fmt, a); + va_end(a); + fflush(log); + } +} + static void _altos_set_last_windows_error(char *file, int line) { @@ -990,7 +1008,7 @@ _altos_set_last_windows_error(char *file, int line) sizeof (message) / sizeof (TCHAR), NULL); if (error != ERROR_SUCCESS) - printf ("%s:%d %s\n", file, line, message); + log_message ("%s:%d %s\n", file, line, message); altos_set_last_error(error, message); } @@ -1061,7 +1079,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device) KEY_READ); if (dev_key == INVALID_HANDLE_VALUE) { altos_set_last_windows_error(); - printf("cannot open device registry key\n"); continue; } @@ -1077,7 +1094,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device) symbolic, &symbolic_len); if (result != 0) { altos_set_last_windows_error(); - printf("cannot find SymbolicName value\n"); RegCloseKey(dev_key); continue; } @@ -1097,7 +1113,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device) RegCloseKey(dev_key); if (result != 0) { altos_set_last_windows_error(); - printf("failed to get PortName\n"); continue; } @@ -1113,7 +1128,6 @@ altos_list_next(struct altos_list *list, struct altos_device *device) &friendlyname_len)) { altos_set_last_windows_error(); - printf("Failed to get friendlyname\n"); continue; } device->vendor = vid; @@ -1125,10 +1139,8 @@ altos_list_next(struct altos_list *list, struct altos_device *device) return 1; } result = GetLastError(); - if (result != ERROR_NO_MORE_ITEMS) { + if (result != ERROR_NO_MORE_ITEMS) altos_set_last_windows_error(); - printf ("SetupDiEnumDeviceInfo failed error %d\n", (int) result); - } return 0; } @@ -1187,6 +1199,7 @@ altos_wait_read(struct altos_file *file, int timeout) return LIBALTOS_TIMEOUT; break; default: + altos_set_last_windows_error(); return LIBALTOS_ERROR; } return LIBALTOS_SUCCESS; @@ -1224,7 +1237,6 @@ altos_flush(struct altos_file *file) if (!WriteFile(file->handle, data, used, &put, &file->ov_write)) { if (GetLastError() != ERROR_IO_PENDING) { altos_set_last_windows_error(); - printf ("\tflush write error\n"); return LIBALTOS_ERROR; } ret = WaitForSingleObject(file->ov_write.hEvent, INFINITE); @@ -1232,13 +1244,11 @@ altos_flush(struct altos_file *file) case WAIT_OBJECT_0: if (!GetOverlappedResult(file->handle, &file->ov_write, &put, FALSE)) { altos_set_last_windows_error(); - printf ("\tflush result error\n"); return LIBALTOS_ERROR; } break; default: altos_set_last_windows_error(); - printf ("\tflush wait error\n"); return LIBALTOS_ERROR; } } @@ -1249,30 +1259,88 @@ altos_flush(struct altos_file *file) return LIBALTOS_SUCCESS; } +static HANDLE +open_serial(char *full_name) +{ + HANDLE handle; + DCB dcb; + + handle = CreateFile(full_name, GENERIC_READ|GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + + if (handle == INVALID_HANDLE_VALUE) { + altos_set_last_windows_error(); + return INVALID_HANDLE_VALUE; + } + + if (!GetCommState(handle, &dcb)) { + altos_set_last_windows_error(); + CloseHandle(handle); + return INVALID_HANDLE_VALUE; + } + dcb.BaudRate = CBR_9600; + dcb.fBinary = TRUE; + dcb.fParity = FALSE; + dcb.fOutxCtsFlow = FALSE; + dcb.fOutxDsrFlow = FALSE; + dcb.fDtrControl = DTR_CONTROL_ENABLE; + dcb.fDsrSensitivity = FALSE; + dcb.fTXContinueOnXoff = FALSE; + dcb.fOutX = FALSE; + dcb.fInX = FALSE; + dcb.fErrorChar = FALSE; + dcb.fNull = FALSE; + dcb.fRtsControl = RTS_CONTROL_ENABLE; + dcb.fAbortOnError = FALSE; + dcb.XonLim = 10; + dcb.XoffLim = 10; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + dcb.XonChar = 17; + dcb.XoffChar = 19; +#if 0 + dcb.ErrorChar = 0; + dcb.EofChar = 0; + dcb.EvtChar = 0; +#endif + if (!SetCommState(handle, &dcb)) { + altos_set_last_windows_error(); + CloseHandle(handle); + return INVALID_HANDLE_VALUE; + } + return handle; +} + PUBLIC struct altos_file * altos_open(struct altos_device *device) { struct altos_file *file = calloc (1, sizeof (struct altos_file)); char full_name[64]; COMMTIMEOUTS timeouts; - DCB dcb; if (!file) return NULL; strcpy(full_name, "\\\\.\\"); strcat(full_name, device->path); - file->handle = CreateFile(full_name, GENERIC_READ|GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, NULL); + + file->handle = open_serial(full_name); if (file->handle == INVALID_HANDLE_VALUE) { - altos_set_last_windows_error(); - printf ("cannot open %s\n", full_name); free(file); return NULL; } - file->ov_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - file->ov_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + /* The FTDI driver doesn't appear to work right unless you open it twice */ + if (device->vendor == 0x0403) { + CloseHandle(file->handle); + file->handle = open_serial(full_name); + if (file->handle == INVALID_HANDLE_VALUE) { + free(file); + return NULL; + } + } timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; @@ -1281,10 +1349,8 @@ altos_open(struct altos_device *device) timeouts.WriteTotalTimeoutConstant = 0; SetCommTimeouts(file->handle, &timeouts); - if (GetCommState(file->handle, &dcb)) { - dcb.BaudRate = CBR_9600; - (void) SetCommState(file->handle, &dcb); - } + file->ov_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + file->ov_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); return file; } @@ -1330,8 +1396,10 @@ altos_getchar(struct altos_file *file, int timeout) { int ret; while (file->in_read == file->in_used) { - if (file->handle == INVALID_HANDLE_VALUE) + if (file->handle == INVALID_HANDLE_VALUE) { + altos_set_last_windows_error(); return LIBALTOS_ERROR; + } ret = altos_fill(file, timeout); if (ret) return ret; -- cgit v1.2.3 From 3605e97ee918b3f87e4c471906f708c3ea027eef Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 3 Mar 2013 16:53:52 -0800 Subject: ao-tools: Add ao-dumpflash program This program dumps the entire flash contents of an AltOS device to allow for external analysis. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 4 +- ao-tools/ao-dumpflash/.gitignore | 1 + ao-tools/ao-dumpflash/Makefile.am | 12 +++ ao-tools/ao-dumpflash/ao-dumpflash.1 | 71 ++++++++++++++ ao-tools/ao-dumpflash/ao-dumpflash.c | 175 +++++++++++++++++++++++++++++++++++ ao-tools/lib/cc-usb.c | 7 +- ao-tools/lib/cc-usb.h | 2 +- ao-tools/lib/ccdbg-flash.c | 5 - configure.ac | 1 + 9 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 ao-tools/ao-dumpflash/.gitignore create mode 100644 ao-tools/ao-dumpflash/Makefile.am create mode 100644 ao-tools/ao-dumpflash/ao-dumpflash.1 create mode 100644 ao-tools/ao-dumpflash/ao-dumpflash.c diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 871b8205..139eea3f 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1 +1,3 @@ -SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash +SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ + ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ + ao-dumpflash diff --git a/ao-tools/ao-dumpflash/.gitignore b/ao-tools/ao-dumpflash/.gitignore new file mode 100644 index 00000000..bbce511a --- /dev/null +++ b/ao-tools/ao-dumpflash/.gitignore @@ -0,0 +1 @@ +ao-dumpflash diff --git a/ao-tools/ao-dumpflash/Makefile.am b/ao-tools/ao-dumpflash/Makefile.am new file mode 100644 index 00000000..db99f5ae --- /dev/null +++ b/ao-tools/ao-dumpflash/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS=ao-dumpflash + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) +AO_DUMPLOG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a + +ao_dumpflash_DEPENDENCIES = $(AO_DUMPLOG_LIBS) + +ao_dumpflash_LDADD=$(AO_DUMPLOG_LIBS) $(LIBUSB_LIBS) + +ao_dumpflash_SOURCES = ao-dumpflash.c + +man_MANS = ao-dumpflash.1 diff --git a/ao-tools/ao-dumpflash/ao-dumpflash.1 b/ao-tools/ao-dumpflash/ao-dumpflash.1 new file mode 100644 index 00000000..07a08ba8 --- /dev/null +++ b/ao-tools/ao-dumpflash/ao-dumpflash.1 @@ -0,0 +1,71 @@ +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; 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. +.\" +.\" +.TH AO-DUMPFLASH 1 "ao-dumpflash" "" +.SH NAME +ao-dumpflash \- Fetch flash memory contents from AltOS device +.SH SYNOPSIS +.B "ao-dumpflash" +[\--tty \fItty-device\fP] +[\--device \fIaltos-device\fP] +[\--output \fIoutput-file\fP] +[\--remote\fP] +[\--frequency \fIfrequency\fP] +[\--call \fIcallsign\fP] +.SH OPTIONS +.TP +\-T tty-device | --tty tty-device +This selects which tty device ao-dumpflash uses to communicate with +the target device. +.TP +\-D AltOS-device | --device AltOS-device +Search for a connected device. This requires an argument of one of the +following forms: +.IP +TeleMetrum:2 +.br +TeleMetrum +.br +2 +.IP +Leaving out the product name will cause the tool to select a suitable +product, leaving out the serial number will cause the tool to match +one of the available devices. +.TP +\-o output-file | --output output-file +Write flash contents to the specified file rather than stdout. +.TP +\-R | --remote +This uses the command radio link to download the flash from TeleMetrum +through a TeleDongle. +.TP +\-F frequency | --frequency frequency +Specifies the radio frequency to use for remote communications in +kHz. Default is 434550. +.TP +\-C callsign | --call callsign +Specifies the callsign to use for remote communications. Default is N0CALL. +.SH DESCRIPTION +.I ao-dumpflash +downloads the entire flash memory contents from a connected AltOS device and writes +it to either stdout or the specified output file. +.SH USAGE +.I ao-dumpflash +connects to the specified target device and dumps the flash. +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-dumpflash/ao-dumpflash.c b/ao-tools/ao-dumpflash/ao-dumpflash.c new file mode 100644 index 00000000..3cd21e66 --- /dev/null +++ b/ao-tools/ao-dumpflash/ao-dumpflash.c @@ -0,0 +1,175 @@ +/* + * Copyright © 2009 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; 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 +#include +#include +#include +#include +#include "cc-usb.h" +#include "cc.h" + +#define NUM_BLOCK 512 + +static const struct option options[] = { + { .name = "tty", .has_arg = 1, .val = 'T' }, + { .name = "device", .has_arg = 1, .val = 'D' }, + { .name = "remote", .has_arg = 0, .val = 'R' }, + { .name = "frequency", .has_arg = 1, .val = 'F' }, + { .name = "call", .has_arg = 1, .val = 'C' }, + { .name = "output", .has_arg = 1, .val = 'o' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--tty ] [--device ] [--remote] [--frequency ] [--call ]\n", program); + exit(1); +} + +int +main (int argc, char **argv) +{ + struct cc_usb *cc; + char *tty = NULL; + char *device = NULL; + int c; + char line[8192]; + FILE *out; + char *filename; + int serial_number = 0; + int freq = 434550; + char *call = "N0CALL"; + int flight = 0; + char cmd; + int block; + int addr; + int received_addr; + int data[8]; + int done; + int i; + int column; + int remote = 0; + int any_valid; + int invalid; + int storage_size = 0; + char *out_name; + + while ((c = getopt_long(argc, argv, "T:D:F:C:o:R", options, NULL)) != -1) { + switch (c) { + case 'T': + tty = optarg; + break; + case 'D': + device = optarg; + break; + case 'R': + remote = 1; + break; + case 'F': + freq = atoi(optarg); + break; + case 'C': + call = optarg; + break; + case 'o': + out_name = optarg; + break; + default: + usage(argv[0]); + break; + } + } + if (!tty) { + if (remote) + tty = cc_usbdevs_find_by_arg(device, "TeleDongle"); + else + tty = cc_usbdevs_find_by_arg(device, "TeleMetrum"); + } + if (!tty) + tty = getenv("ALTOS_TTY"); + if (!tty) + tty="/dev/ttyACM0"; + + cc = cc_usb_open(tty); + if (!cc) + exit(1); + if (remote) + cc_usb_open_remote(cc, freq, call); + + if (out_name) { + out = fopen(out_name, "w"); + if (!out) { + perror(out_name); + cc_usb_close(cc); + exit(1); + } + } else + out = stdout; + + /* send a 'version' command followed by a 'flash' command */ + cc_usb_printf(cc, "f\nv\n"); + for (;;) { + cc_usb_getline(cc, line, sizeof (line)); + if (sscanf(line, "serial-number %u", &serial_number) == 1) + continue; + if (sscanf(line, "Storage size: %u", &storage_size) == 1) + continue; + if (!strncmp(line, "software-version", 16)) + break; + } + if (!serial_number) { + fprintf(stderr, "no serial number found\n"); + cc_usb_close(cc); + exit(1); + } + if (!storage_size) { + fprintf(stderr, "no storage size found\n"); + cc_usb_close(cc); + exit(1); + } + printf ("Serial number: %d\n", serial_number); + printf ("Storage size: %d\n", storage_size); + fprintf (stderr, "%7d of %7d", 0, storage_size/256); + for (block = 0; block < storage_size / 256; block++) { + cc_usb_printf(cc, "e %x\n", block); + fprintf (stderr, "\r%7d of %7d", block + 1, storage_size/256); fflush(stderr); + for (addr = 0; addr < 0x100;) { + cc_usb_getline(cc, line, sizeof (line)); + if (sscanf(line, "00%x %x %x %x %x %x %x %x %x", + &received_addr, + &data[0], &data[1], &data[2], &data[3], + &data[4], &data[5], &data[6], &data[7]) == 9) + { + if (received_addr != addr) + fprintf(stderr, "data out of sync at 0x%x\n", + block * 256 + received_addr); + + fprintf (out, "%08x", block * 256 + addr); + for (i = 0; i < 8; i++) + fprintf (out, " %02x", data[i]); + fprintf (out, "\n"); + + addr += 8; + } + } + } + fprintf(stderr, "\n"); + cc_usb_close(cc); + exit (0); +} diff --git a/ao-tools/lib/cc-usb.c b/ao-tools/lib/cc-usb.c index 1580c6d9..9f07e662 100644 --- a/ao-tools/lib/cc-usb.c +++ b/ao-tools/lib/cc-usb.c @@ -375,11 +375,12 @@ cc_usb_reset(struct cc_usb *cc) } void -cc_usb_open_remote(struct cc_usb *cc, int channel) +cc_usb_open_remote(struct cc_usb *cc, int freq, char *call) { if (!cc->remote) { - printf ("channel %d\n", channel); - cc_usb_printf(cc, "\nc r %d\np\nE 0\n", channel); + fprintf (stderr, "freq %dkHz\n", freq); + fprintf (stderr, "call %s\n", call); + cc_usb_printf(cc, "\nc F %d\nc c %s\np\nE 0\n", freq, call); do { cc->in_count = cc->in_pos = 0; _cc_usb_sync(cc, 100); diff --git a/ao-tools/lib/cc-usb.h b/ao-tools/lib/cc-usb.h index d3539281..e90e1195 100644 --- a/ao-tools/lib/cc-usb.h +++ b/ao-tools/lib/cc-usb.h @@ -63,7 +63,7 @@ void cc_usb_printf(struct cc_usb *cc, char *format, ...); void -cc_usb_open_remote(struct cc_usb *cc, int channel); +cc_usb_open_remote(struct cc_usb *cc, int freq, char *call); void cc_usb_close_remote(struct cc_usb *cc); diff --git a/ao-tools/lib/ccdbg-flash.c b/ao-tools/lib/ccdbg-flash.c index 3e672985..1b46870b 100644 --- a/ao-tools/lib/ccdbg-flash.c +++ b/ao-tools/lib/ccdbg-flash.c @@ -240,7 +240,6 @@ ccdbg_flash_lock(struct ccdbg *dbg, uint8_t lock) uint8_t ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) { - uint16_t offset; uint16_t flash_prog; uint16_t flash_len; uint8_t fwt; @@ -249,7 +248,6 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) uint16_t flash_words; uint8_t flash_words_high, flash_words_low; uint16_t ram_addr; - uint16_t pc; uint8_t status; uint16_t remain, this_time, start; uint8_t verify[0x400]; @@ -284,8 +282,6 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) if (this_time > 0x400) this_time = 0x400; - offset = ram_addr - (image->address + start); - ccdbg_debug(CC_DEBUG_FLASH, "Upload %d bytes at 0x%04x\n", this_time, ram_addr); ccdbg_write_memory(dbg, ram_addr, image->data + start, this_time); #if 0 @@ -319,7 +315,6 @@ ccdbg_flash_hex_image(struct ccdbg *dbg, struct hex_image *image) ccdbg_write_uint8(dbg, flash_prog + FLASH_WORDS_LOW, flash_words_low); ccdbg_set_pc(dbg, flash_prog); - pc = ccdbg_get_pc(dbg); ccdbg_debug(CC_DEBUG_FLASH, "Flashing %d bytes at 0x%04x\n", this_time, flash_addr); status = ccdbg_resume(dbg); diff --git a/configure.ac b/configure.ac index 448df6a4..9e5dcaa7 100644 --- a/configure.ac +++ b/configure.ac @@ -181,6 +181,7 @@ ao-tools/ao-telem/Makefile ao-tools/ao-stmload/Makefile ao-tools/ao-send-telem/Makefile ao-tools/ao-sky-flash/Makefile +ao-tools/ao-dumpflash/Makefile ao-utils/Makefile src/Version ]) -- cgit v1.2.3 From afd2674261e128a0ecff8fbf5dd6a64196b026f6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 4 Mar 2013 19:44:30 -0800 Subject: altoslib: Invalidate GPS new data bit when updating state Somehow this line got lost when the GPS ground altitude fix was made. Signed-off-by: Keith Packard --- altoslib/AltosState.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/altoslib/AltosState.java b/altoslib/AltosState.java index 32d02f21..5598a603 100644 --- a/altoslib/AltosState.java +++ b/altoslib/AltosState.java @@ -205,6 +205,8 @@ public class AltosState { pad_alt = ground_altitude; } + data.new_gps = false; + gps_waiting = MIN_PAD_SAMPLES - npad; if (gps_waiting < 0) gps_waiting = 0; -- cgit v1.2.3 From 0803da851e2e061affc172fdde6301652d1be755 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 9 Mar 2013 20:37:38 -0800 Subject: altosui: Add N/S and E/W to info table lat/lon values Signed-off-by: Keith Packard --- altosui/AltosInfoTable.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/altosui/AltosInfoTable.java b/altosui/AltosInfoTable.java index c06f57ec..2facf38a 100644 --- a/altosui/AltosInfoTable.java +++ b/altosui/AltosInfoTable.java @@ -85,15 +85,15 @@ public class AltosInfoTable extends JTable { } void info_add_deg(int col, String name, double v, int pos, int neg) { - //int c = pos; + int c = pos; if (v < 0) { - //c = neg; + c = neg; v = -v; } double deg = Math.floor(v); double min = (v - deg) * 60; - info_add_row(col, name, String.format("%3.0f°%08.5f'", deg, min)); + info_add_row(col, name, String.format("%c %3.0f°%08.5f'", c, deg, min)); } void info_finish() { -- cgit v1.2.3 From 9b460d38bc2685bca7f530b7749c0e0381f6264c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 9 Mar 2013 20:39:31 -0800 Subject: ao-tools/lib: Add cc_telemetry_unparse This takes a telemetry structure and generates a string version Signed-off-by: Keith Packard --- ao-tools/lib/cc-telemetry.c | 30 ++++++++++++++++++++++++++++++ ao-tools/lib/cc-telemetry.h | 12 ++++++++++++ 2 files changed, 42 insertions(+) diff --git a/ao-tools/lib/cc-telemetry.c b/ao-tools/lib/cc-telemetry.c index 99da2680..88da7f03 100644 --- a/ao-tools/lib/cc-telemetry.c +++ b/ao-tools/lib/cc-telemetry.c @@ -60,3 +60,33 @@ cc_telemetry_parse(const char *input_line, union ao_telemetry_all *telemetry) memcpy(telemetry, hex+1, 34); return TRUE; } + +uint8_t +cc_telemetry_cksum(const union ao_telemetry_all *telemetry) +{ + const uint8_t *x = (const uint8_t *) telemetry; + int i; + uint8_t sum = 0x5a; + for (i = 0; i < 34; i++) + sum += x[i]; + return sum; +} + +void +cc_telemetry_unparse(const union ao_telemetry_all *telemetry, char output_line[CC_TELEMETRY_BUFSIZE]) +{ + uint8_t hex[36]; + int i; + int p; + + hex[0] = 34; + memcpy(hex+1, telemetry, 34); + hex[35] = cc_telemetry_cksum(telemetry); + strcpy(output_line, "TELEM "); + p = strlen(output_line); + for (i = 0; i < 36; i++) { + sprintf(output_line + p, "%02x", hex[i]); + p += 2; + } +} + diff --git a/ao-tools/lib/cc-telemetry.h b/ao-tools/lib/cc-telemetry.h index e849cd3b..9a5be49f 100644 --- a/ao-tools/lib/cc-telemetry.h +++ b/ao-tools/lib/cc-telemetry.h @@ -237,7 +237,19 @@ union ao_telemetry_all { struct ao_telemetry_baro baro; }; +#define CC_TELEMETRY_HEADER "TELEM" + +/* "TELEM " 1 byte length 32 data bytes 1 rssi 1 status 1 checksum 1 null */ + +#define CC_TELEMETRY_BUFSIZE (6 + (1 + 32 + 3) * 2 + 1) + int cc_telemetry_parse(const char *input_line, union ao_telemetry_all *telemetry); +uint8_t +cc_telemetry_cksum(const union ao_telemetry_all *telemetry); + +void +cc_telemetry_unparse(const union ao_telemetry_all *telemetry, char output_line[CC_TELEMETRY_BUFSIZE]); + #endif -- cgit v1.2.3 From 72c5b1429bdfd6e9d2185bad7d0adb281fdf659a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 9 Mar 2013 20:40:52 -0800 Subject: ao-tools: Add ao-edit-telem This lets you edit a telemetry file. The only current editing available is to change the pad location, allowing a flight to be replayed anywhere in the world. Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- ao-tools/ao-edit-telem/Makefile.am | 12 +++ ao-tools/ao-edit-telem/ao-edit-telem.1 | 33 ++++++ ao-tools/ao-edit-telem/ao-edit-telem.c | 192 +++++++++++++++++++++++++++++++++ configure.ac | 1 + 5 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 ao-tools/ao-edit-telem/Makefile.am create mode 100644 ao-tools/ao-edit-telem/ao-edit-telem.1 create mode 100644 ao-tools/ao-edit-telem/ao-edit-telem.c diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 139eea3f..e4df2e63 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1,3 +1,3 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ - ao-dumpflash + ao-dumpflash ao-edit-telem diff --git a/ao-tools/ao-edit-telem/Makefile.am b/ao-tools/ao-edit-telem/Makefile.am new file mode 100644 index 00000000..c5965c47 --- /dev/null +++ b/ao-tools/ao-edit-telem/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS=ao-edit-telem + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) +AO_POSTFLIGHT_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a + +ao_edit_telem_DEPENDENCIES = $(AO_POSTFLIGHT_LIBS) + +ao_edit_telem_LDADD=$(AO_POSTFLIGHT_LIBS) $(LIBUSB_LIBS) + +ao_edit_telem_SOURCES = ao-edit-telem.c + +man_MANS = ao-edit-telem.1 diff --git a/ao-tools/ao-edit-telem/ao-edit-telem.1 b/ao-tools/ao-edit-telem/ao-edit-telem.1 new file mode 100644 index 00000000..8f125878 --- /dev/null +++ b/ao-tools/ao-edit-telem/ao-edit-telem.1 @@ -0,0 +1,33 @@ +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" This program is free software; you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; 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. +.\" +.\" +.TH AO-EDIT-TELEM 1 "ao-edit-telem" "" +.SH NAME +ao-edit-telem \- Edit telemetry file, creating new telemetry stream +.SH SYNOPSIS +.B "ao-edit-telem" +[\--lat=] +[\--lon=] +{flight.telem} +.SH DESCRIPTION +.I ao-edit-telem +reads the specified telemetry log and produces a new telemetry log, +changed as directed by the options provided. +output. +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-edit-telem/ao-edit-telem.c b/ao-tools/ao-edit-telem/ao-edit-telem.c new file mode 100644 index 00000000..3f6830e7 --- /dev/null +++ b/ao-tools/ao-edit-telem/ao-edit-telem.c @@ -0,0 +1,192 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include "cc.h" + +static const struct option options[] = { + { .name = "lat", .has_arg = 1, .val = 'L' }, + { .name = "lon", .has_arg = 1, .val = 'l' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--lat ] [--lon ]\n" + "\t{flight-log} ...\n", program); + exit(1); +} + +#define bool(b) ((b) ? "true" : "false") + +struct telem_ent { + struct telem_ent *next; + union ao_telemetry_all telem; +}; + +static struct telem_ent *pad, **last = &pad; + +static void +save_telem(union ao_telemetry_all *telem) +{ + struct telem_ent *t = malloc (sizeof *t); + t->telem = *telem; + t->next = NULL; + *last = t; + last = &t->next; +} + +static void +dump_telem(union ao_telemetry_all *telem) +{ + char s[CC_TELEMETRY_BUFSIZE]; + + cc_telemetry_unparse(telem, s); + printf("%s\n", s); +} + +double pad_lat = 0, pad_lon = 0; +double target_pad_lat = 0, target_pad_lon = 0; +double lat_off = 0, lon_off = 0; +int pending = 1; + +static void +dump_saved(void); + +void +doit(union ao_telemetry_all *telem) +{ + double lat, lon; + + switch (telem->generic.type) { + case AO_TELEMETRY_SENSOR_TELEMETRUM: + case AO_TELEMETRY_SENSOR_TELEMINI: + case AO_TELEMETRY_SENSOR_TELENANO: + if (telem->sensor.state > ao_flight_pad && pad) { + pending = 0; + if (target_pad_lat) + lat_off = target_pad_lat - pad_lat; + if (target_pad_lon) + lon_off = target_pad_lon - pad_lon; + dump_saved(); + } + break; + case AO_TELEMETRY_LOCATION: { + lat = telem->location.latitude / 1.0e7; + lon = telem->location.longitude / 1.0e7; + if (pending) { + if (telem->location.flags & (1 << 4)) { + if (pad_lat) { + pad_lat = pad_lat - pad_lat / 32 + lat / 32.0; + pad_lon = pad_lon - pad_lon / 32 + lon / 32.0; + } else { + pad_lat = lat; + pad_lon = lon; + } + } + } else { + lat += lat_off; + lon += lon_off; + if (lat > 90) + lat = 90; + if (lat < -90) + lat = -90; + while (lon > 180) + lon -= 360; + while (lon < -180) + lon += 360; + telem->location.latitude = lat * 1.0e7; + telem->location.longitude = lon * 1.0e7; + } + break; + } + } +} + +static void +dump_saved(void) +{ + struct telem_ent *t, *n; + + for (t = pad; t; t = n) { + n = t->next; + doit(&t->telem); + dump_telem(&t->telem); + free(t); + } + pad = NULL; + last = &pad; +} + +int +main (int argc, char **argv) +{ + char line[80]; + int c, i, ret; + char *s; + FILE *file; + int serial; + while ((c = getopt_long(argc, argv, "l:L:", options, NULL)) != -1) { + switch (c) { + case 'L': + target_pad_lat = strtod(optarg, NULL); + break; + case 'l': + target_pad_lon = strtod(optarg, NULL); + break; + default: + usage(argv[0]); + break; + } + } + for (i = optind; i < argc; i++) { + file = fopen(argv[i], "r"); + if (!file) { + perror(argv[i]); + ret++; + continue; + } + s = strstr(argv[i], "-serial-"); + if (s) + serial = atoi(s + 8); + else + serial = 0; + while (fgets(line, sizeof (line), file)) { + union ao_telemetry_all telem; + + if (cc_telemetry_parse(line, &telem)) { + if ((telem.generic.status & (1 << 7)) == 0) { + dump_telem(&telem); + continue; + } + doit (&telem); + if (pending) + save_telem(&telem); + else + dump_telem(&telem); + } + } + fclose (file); + + } + return ret; +} diff --git a/configure.ac b/configure.ac index 9e5dcaa7..f9a892df 100644 --- a/configure.ac +++ b/configure.ac @@ -182,6 +182,7 @@ ao-tools/ao-stmload/Makefile ao-tools/ao-send-telem/Makefile ao-tools/ao-sky-flash/Makefile ao-tools/ao-dumpflash/Makefile +ao-tools/ao-edit-telem/Makefile ao-utils/Makefile src/Version ]) -- cgit v1.2.3