From a588092a7d76dab92e4ab11e0fdb457d2ddc9025 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 25 Aug 2011 21:10:56 -0700 Subject: altos: AVR changes - create ao_arch.h files, define ao_arch_reboot Start pulling changes needed for avr port; architecture-specific code will live in /ao_arch.h. This first change defines the ao_arch_reboot macro to reboot the microcontroller. Signed-off-by: Keith Packard --- src/avr/ao_arch.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/avr/ao_arch.h (limited to 'src/avr') diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h new file mode 100644 index 00000000..2b566814 --- /dev/null +++ b/src/avr/ao_arch.h @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#ifndef _AO_ARCH_H_ +#define _AO_ARCH_H_ + +#include "avr.h" + + +/* + * AVR definitions and code fragments for AltOS + */ + +#define AO_STACK_SIZE 128 + +/* Various definitions to make GCC look more like SDCC */ + +#define __naked __attribute__((naked)) + +#define ao_arch_reboot() /* XXX */ + +#endif /* _AO_ARCH_H_ */ -- cgit v1.2.3 From e9fab7dc99a0e7c22b511c5919adf7df85213252 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 25 Aug 2011 22:04:36 -0700 Subject: altos: add GCC/SDCC compat macros, init_stack, save_context and GCC stdio hooks More arch-indepdency bits. GCC stdio is different from SDCC, so create suitable code in avr/ao_avr_stdio.c Create macros to initialize the task stack frame and save the task context. Add GCC/SDCC type definition compatibility macros Signed-off-by: Keith Packard --- src/avr-demo/Makefile | 102 ++++++++++ src/avr/ao_arch.h | 67 ++++++- src/avr/ao_avr_stdio.c | 52 +++++ src/avr/ao_pins.h | 31 +++ src/cc1111/ao_arch.h | 99 ++++++++++ src/cc1111/ao_pins.h | 425 ++++++++++++++++++++++++++++++++++++++++ src/core/ao.h | 76 ++----- src/core/ao_panic.c | 2 +- src/core/ao_pins.h | 408 -------------------------------------- src/core/ao_task.c | 60 +----- src/product/Makefile.telebt | 2 +- src/product/Makefile.teledongle | 2 +- src/product/Makefile.telemetrum | 2 +- src/product/Makefile.telemini | 2 +- src/product/Makefile.telenano | 2 +- src/tidongle/Makefile | 2 +- 16 files changed, 805 insertions(+), 529 deletions(-) create mode 100644 src/avr-demo/Makefile create mode 100644 src/avr/ao_avr_stdio.c create mode 100644 src/avr/ao_pins.h create mode 100644 src/cc1111/ao_pins.h delete mode 100644 src/core/ao_pins.h (limited to 'src/avr') diff --git a/src/avr-demo/Makefile b/src/avr-demo/Makefile new file mode 100644 index 00000000..ea356654 --- /dev/null +++ b/src/avr-demo/Makefile @@ -0,0 +1,102 @@ +# +# AltOS build +# +# +vpath % ..:../core:../product:../driver +vpath make-altitude .. +vpath make-kalman .. +vpath kalman.5c ../kalman +vpath kalman_filter.5c ../kalman +vpath load_csv.5c ../kalman +vpath matrix.5c ../kalman +vpath ao-make-product.5c ../util + +MCU=atmega32u4 +DUDECPUTYPE=m32u4 +#PROGRAMMER=stk500v2 -P usb +PROGRAMMER=usbtiny +LOADCMD=avrdude +LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: +CC=avr-gcc +OBJCOPY=avr-objcopy + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_pins.h \ + altitude.h \ + ao_kalman.h + +# +# Common AltOS sources +# +ALTOS_SRC = \ + ao_cmd.c \ + ao_mutex.c \ + ao_panic.c \ + ao_product.c \ + ao_serial_avr.c \ + ao_avr_stdio.c \ + ao_stdio.c \ + ao_task.c \ + ao_timer.c \ + ao_led.c + +PRODUCT=AvrDemo-v0.0 +MCU=atmega32u4 +PRODUCT_DEF=-DAVR_DEMO +IDPRODUCT=0x000a +CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I.. +CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -Os -mcall-prologues + +NICKLE=nickle + +PROG=avr-demo + +SRC=$(ALTOS_SRC) ao_demo.c ao_debug_avr.c +OBJ=$(SRC:.c=.o) + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: $(PROG) + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) + +$(PROG).hex: $(PROG) + avr-size $(PROG) + $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ + + +load: $(PROG).hex + $(LOADCMD) $(LOADARG)$(PROG).hex + +../altitude.h: make-altitude + nickle $< > $@ + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +ao_product.rel: ao_product.c ao_product.h + $(call quiet,CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"ao_product.h\"' -o$@ $< + +distclean: clean + +clean: + rm -f $(OBJ) + rm -f ao_product.h + +install: + +uninstall: + +$(OBJ): ao.h ao_product.h \ No newline at end of file diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index 2b566814..51a65880 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -18,8 +18,18 @@ #ifndef _AO_ARCH_H_ #define _AO_ARCH_H_ -#include "avr.h" +#include +#include +#ifdef AVR_DEMO +#define TEENSY 1 +#endif + +#if TEENSY +#define F_CPU 16000000UL // 16 MHz +#else +#define F_CPU 8000000UL // 8 MHz +#endif /* * AVR definitions and code fragments for AltOS @@ -29,8 +39,61 @@ /* Various definitions to make GCC look more like SDCC */ -#define __naked __attribute__((naked)) +#define ao_arch_naked_declare __attribute__((naked)) +#define ao_arch_naked_define +#define __pdata +#define __data +#define __xdata +#define __code const +#define __reentrant +#define __critical +#define __interrupt(n) #define ao_arch_reboot() /* XXX */ +#define ao_arch_nop() asm("nop") + +#define ao_arch_interrupt(n) /* nothing */ + +#undef putchar +#undef getchar +#define putchar(c) ao_putchar(c) +#define getchar ao_getchar + +extern void putchar(char c); +extern char getchar(void); + +extern int ao_serial_number; + +#define ao_arch_init_stack(task, start) do { \ + uint8_t *sp = task->stack + AO_STACK_SIZE - 1; \ + uint16_t a = (uint16_t) start; \ + int i; \ + \ + /* Return address */ \ + PUSH8(sp, a); \ + PUSH8(sp, (a >> 8)); \ + \ + /* Clear register values */ \ + i = 32; \ + while (i--) \ + PUSH8(sp, 0); \ + \ + /* SREG with interrupts enabled */ \ + PUSH8(sp, 0x80); \ + task->sp = sp; \ +} while (0); + +#define ao_arch_save_context() do { \ + asm("push r31" "\n\t" "push r30"); \ + asm("push r29" "\n\t" "push r28" "\n\t" "push r27" "\n\t" "push r26" "\n\t" "push r25"); \ + asm("push r24" "\n\t" "push r23" "\n\t" "push r22" "\n\t" "push r21" "\n\t" "push r20"); \ + asm("push r19" "\n\t" "push r18" "\n\t" "push r17" "\n\t" "push r16" "\n\t" "push r15"); \ + asm("push r14" "\n\t" "push r13" "\n\t" "push r12" "\n\t" "push r11" "\n\t" "push r10"); \ + asm("push r9" "\n\t" "push r8" "\n\t" "push r7" "\n\t" "push r6" "\n\t" "push r5"); \ + asm("push r4" "\n\t" "push r3" "\n\t" "push r2" "\n\t" "push r1" "\n\t" "push r0"); \ + asm("in r0, __SREG__" "\n\t" "push r0"); \ + sei(); \ + } while (0) + #endif /* _AO_ARCH_H_ */ diff --git a/src/avr/ao_avr_stdio.c b/src/avr/ao_avr_stdio.c new file mode 100644 index 00000000..2f358eb5 --- /dev/null +++ b/src/avr/ao_avr_stdio.c @@ -0,0 +1,52 @@ +/* + * 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" + +int +stdio_put(char c, FILE *stream) +{ + if (ao_cur_task && ao_num_stdios) + putchar(c); + else + { + if (c == '\n') + stdio_put('\r', stream); + loop_until_bit_is_set(UCSR1A, UDRE1); + UDR1 = c; + } + + return 0; +} + +int +stdio_get(FILE *stream) +{ + return (int) getchar() & 0xff; +} + +static FILE mystdout = FDEV_SETUP_STREAM(stdio_put, NULL, _FDEV_SETUP_WRITE); + +static FILE mystdin = FDEV_SETUP_STREAM(NULL, stdio_get, _FDEV_SETUP_READ); + +void +ao_stdio_init(void) +{ + stdout = &mystdout; + stdin = &mystdin; + printf("%d stdios registered\n", ao_num_stdios); +} diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h new file mode 100644 index 00000000..ef41b59c --- /dev/null +++ b/src/avr/ao_pins.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#ifdef AVR_DEMO + #define AO_LED_RED (1<<7) + #define LEDS_AVAILABLE (AO_LED_RED) + #define USE_SERIAL_STDIN 1 + #define HAS_USB 0 + #define PACKET_HAS_SLAVE 0 + #define HAS_SERIAL_1 1 + #define HAS_BEEP 0 +#endif + +#endif /* _AO_PINS_H_ */ diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index 585fffe5..35fd66f8 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -24,9 +24,108 @@ #include "cc1111.h" +/* Convert a __data pointer into an __xdata pointer */ +#define DATA_TO_XDATA(a) ((void __xdata *) ((uint8_t) (a) | 0xff00)) + +/* Stack runs from above the allocated __data space to 0xfe, which avoids + * writing to 0xff as that triggers the stack overflow indicator + */ +#define AO_STACK_START 0x90 +#define AO_STACK_END 0xfe +#define AO_STACK_SIZE (AO_STACK_END - AO_STACK_START + 1) + #define ao_arch_reboot() do { \ WDCTL = WDCTL_EN | WDCTL_MODE_WATCHDOG | WDCTL_INT_64; \ ao_delay(AO_SEC_TO_TICKS(2)); \ } while (0) +#define ao_arch_nop() _asm nop _endasm +#define ao_arch_interrupt(n) __interrupt n + +#define ao_arch_naked_declare __naked +#define ao_arch_naked_define __naked + +/* CC1111-specific drivers */ + +/* + * ao_romconfig.c + */ + +#define AO_ROMCONFIG_VERSION 2 + +extern __code __at (0x00a0) uint16_t ao_romconfig_version; +extern __code __at (0x00a2) uint16_t ao_romconfig_check; +extern __code __at (0x00a4) uint16_t ao_serial_number; +extern __code __at (0x00a6) uint32_t ao_radio_cal; + +#ifndef HAS_USB +#error Please define HAS_USB +#endif + +#if HAS_USB +extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; +#endif + +/* Initialize stack */ +#define ao_arch_init_stack(task, start) { \ + uint8_t __xdata *stack = task->stack; \ + uint8_t t; \ + *stack++ = ((uint16_t) start); /* 0 */ \ + *stack++ = ((uint16_t) start) >> 8; /* 1 */ \ + \ + /* and the stuff saved by ao_switch */ \ + *stack++ = 0; /* 2 acc */ \ + *stack++ = 0x80; /* 3 IE */ \ + \ + /* 4 DPL \ + * 5 DPH \ + * 6 B \ + * 7 R2 \ + * 8 R3 \ + * 9 R4 \ + * 10 R5 \ + * 11 R6 \ + * 12 R7 \ + * 13 R0 \ + * 14 R1 \ + * 15 PSW \ + * 16 BP \ + */ \ + for (t = 0; t < 13; t++) \ + *stack++ = 0; \ + task->stack_count = 17; \ + } + + + +/* Save current context */ + +#define ao_arch_save_context() \ + _asm \ + /* Push ACC first, as when restoring the context it must be restored \ + * last (it is used to set the IE register). */ \ + push ACC \ + /* Store the IE register then enable interrupts. */ \ + push _IEN0 \ + setb _EA \ + push DPL \ + push DPH \ + push b \ + push ar2 \ + push ar3 \ + push ar4 \ + push ar5 \ + push ar6 \ + push ar7 \ + push ar0 \ + push ar1 \ + push PSW \ + _endasm; \ + PSW = 0; \ + _asm \ + push _bp \ + _endasm + + + #endif /* _AO_ARCH_H_ */ diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h new file mode 100644 index 00000000..4ac6a84b --- /dev/null +++ b/src/cc1111/ao_pins.h @@ -0,0 +1,425 @@ +/* + * 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_ + +#if defined(TELEMETRUM_V_1_0) + #define HAS_FLIGHT 1 + #define HAS_USB 1 + #define HAS_BEEP 1 + #define HAS_GPS 1 + #define HAS_SERIAL_1 1 + #define HAS_ADC 1 + #define USE_SERIAL_STDIN 0 + #define HAS_EEPROM 1 + #define USE_INTERNAL_FLASH 0 + #define HAS_DBG 1 + #define DBG_ON_P1 1 + #define DBG_ON_P0 0 + #define IGNITE_ON_P2 1 + #define IGNITE_ON_P0 0 + #define PACKET_HAS_MASTER 0 + #define PACKET_HAS_SLAVE 1 + + #define HAS_COMPANION 1 + #define COMPANION_CS_ON_P1 1 + #define COMPANION_CS_MASK 0x4 /* CS1 is P1_2 */ + #define COMPANION_CS P1_2 + + #define AO_LED_RED 1 + #define LEDS_AVAILABLE (AO_LED_RED) + #define HAS_EXTERNAL_TEMP 0 + #define HAS_ACCEL_REF 0 + #define HAS_ACCEL 1 + #define HAS_IGNITE 1 + #define HAS_MONITOR 0 +#endif + +#if defined(TELEMETRUM_V_1_1) + #define HAS_FLIGHT 1 + #define HAS_USB 1 + #define HAS_BEEP 1 + #define HAS_GPS 1 + #define HAS_SERIAL_1 1 + #define USE_SERIAL_STDIN 0 + #define HAS_ADC 1 + #define HAS_EEPROM 1 + #define USE_INTERNAL_FLASH 0 + #define HAS_DBG 1 + #define DBG_ON_P1 1 + #define DBG_ON_P0 0 + #define IGNITE_ON_P2 1 + #define IGNITE_ON_P0 0 + #define PACKET_HAS_MASTER 0 + #define PACKET_HAS_SLAVE 1 + + #define HAS_COMPANION 1 + #define COMPANION_CS_ON_P1 1 + #define COMPANION_CS_MASK 0x4 /* CS1 is P1_2 */ + #define COMPANION_CS P1_2 + + #define AO_LED_RED 1 + #define LEDS_AVAILABLE (AO_LED_RED) + #define HAS_EXTERNAL_TEMP 0 + #define HAS_ACCEL_REF 1 + #define SPI_CS_ON_P1 1 + #define SPI_CS_ON_P0 0 + #define M25_CS_MASK 0x02 /* CS0 is P1_1 */ + #define M25_MAX_CHIPS 1 + #define HAS_ACCEL 1 + #define HAS_IGNITE 1 + #define HAS_MONITOR 0 +#endif + +#if defined(TELEDONGLE_V_0_2) + #define HAS_FLIGHT 0 + #define HAS_USB 1 + #define HAS_BEEP 0 + #define HAS_SERIAL_1 0 + #define USE_SERIAL_STDIN 0 + #define HAS_ADC 0 + #define HAS_DBG 1 + #define HAS_EEPROM 0 + #define DBG_ON_P1 1 + #define DBG_ON_P0 0 + #define IGNITE_ON_P2 0 + #define IGNITE_ON_P0 0 + #define PACKET_HAS_MASTER 1 + #define PACKET_HAS_SLAVE 0 + #define AO_LED_RED 1 + #define AO_LED_GREEN 2 + #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) + #define SPI_CS_ON_P1 1 + #define SPI_CS_ON_P0 0 + #define HAS_IGNITE 0 + #define HAS_MONITOR 1 +#endif + +#if defined(TELEMINI_V_1_0) + #define HAS_FLIGHT 1 + #define HAS_USB 0 + #define HAS_BEEP 0 + #define HAS_GPS 0 + #define HAS_SERIAL_1 0 + #define USE_SERIAL_STDIN 0 + #define HAS_ADC 1 + #define HAS_EEPROM 1 + #define USE_INTERNAL_FLASH 1 + #define HAS_DBG 0 + #define IGNITE_ON_P2 0 + #define IGNITE_ON_P0 1 + #define PACKET_HAS_MASTER 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_MONITOR 0 +#endif + +#if defined(TELENANO_V_0_1) + #define HAS_FLIGHT 1 + #define HAS_USB 0 + #define HAS_BEEP 0 + #define HAS_GPS 0 + #define HAS_SERIAL_1 0 + #define USE_SERIAL_STDIN 0 + #define HAS_ADC 1 + #define HAS_EEPROM 1 + #define USE_INTERNAL_FLASH 1 + #define HAS_DBG 0 + #define IGNITE_ON_P2 0 + #define IGNITE_ON_P0 1 + #define PACKET_HAS_MASTER 0 + #define PACKET_HAS_SLAVE 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 0 + #define HAS_MONITOR 0 +#endif + +#if defined(TELEMETRUM_V_0_1) + #define HAS_FLIGHT 1 + #define HAS_USB 1 + #define HAS_BEEP 1 + #define HAS_GPS 1 + #define HAS_SERIAL_1 1 + #define USE_SERIAL_STDIN 0 + #define HAS_ADC 1 + #define HAS_DBG 0 + #define HAS_EEPROM 1 + #define USE_INTERNAL_FLASH 0 + #define DBG_ON_P1 0 + #define DBG_ON_P0 1 + #define IGNITE_ON_P2 1 + #define IGNITE_ON_P0 0 + #define PACKET_HAS_MASTER 0 + #define PACKET_HAS_SLAVE 1 + #define AO_LED_RED 2 + #define AO_LED_GREEN 1 + #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) + #define HAS_EXTERNAL_TEMP 1 + #define HAS_ACCEL_REF 0 + #define SPI_CS_ON_P1 1 + #define SPI_CS_ON_P0 0 + #define HAS_ACCEL 1 + #define HAS_IGNITE 1 + #define HAS_MONITOR 0 +#endif + +#if defined(TELEDONGLE_V_0_1) + #define HAS_FLIGHT 0 + #define HAS_USB 1 + #define HAS_BEEP 0 + #define HAS_SERIAL_1 0 + #define USE_SERIAL_STDIN 0 + #define HAS_ADC 0 + #define HAS_DBG 0 + #define HAS_EEPROM 0 + #define DBG_ON_P1 0 + #define DBG_ON_P0 1 + #define IGNITE_ON_P2 0 + #define IGNITE_ON_P0 0 + #define PACKET_HAS_MASTER 1 + #define PACKET_HAS_SLAVE 0 + #define AO_LED_RED 2 + #define AO_LED_GREEN 1 + #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) + #define SPI_CS_ON_P1 0 + #define SPI_CS_ON_P0 1 + #define HAS_IGNITE 0 + #define HAS_MONITOR 1 +#endif + +#if defined(TIDONGLE) + #define HAS_FLIGHT 0 + #define HAS_USB 1 + #define HAS_BEEP 0 + #define HAS_SERIAL_1 0 + #define USE_SERIAL_STDIN 0 + #define HAS_ADC 0 + #define HAS_DBG 1 + #define HAS_EEPROM 0 + #define DBG_ON_P1 0 + #define DBG_ON_P0 1 + #define IGNITE_ON_P2 0 + #define IGNITE_ON_P0 0 + #define PACKET_HAS_MASTER 1 + #define PACKET_HAS_SLAVE 0 + #define AO_LED_RED 2 + #define LEDS_AVAILABLE (AO_LED_RED) + #define SPI_CS_ON_P1 0 + #define SPI_CS_ON_P0 1 + #define HAS_IGNITE 0 + #define HAS_MONITOR 1 +#endif + +#if defined(TELEBT_V_0_0) + #define HAS_FLIGHT 0 + #define HAS_USB 1 + #define HAS_BEEP 0 + #define HAS_SERIAL_1 1 + #define USE_SERIAL_STDIN 1 + #define HAS_ADC 0 + #define HAS_DBG 1 + #define HAS_EEPROM 0 + #define HAS_BTM 1 + #define DBG_ON_P1 0 + #define DBG_ON_P0 1 + #define IGNITE_ON_P2 0 + #define IGNITE_ON_P0 0 + #define PACKET_HAS_MASTER 1 + #define PACKET_HAS_SLAVE 0 + #define AO_LED_RED 2 + #define AO_LED_GREEN 1 + #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) + #define SPI_CS_ON_P1 1 + #define SPI_CS_ON_P0 0 + #define HAS_IGNITE 0 + #define BT_LINK_ON_P2 1 + #define BT_LINK_ON_P1 0 + #define BT_LINK_PIN_INDEX 7 + #define BT_LINK_PIN P2_1 + #define HAS_MONITOR 1 +#endif + +#if defined(TELEBT_V_0_1) + #define HAS_FLIGHT 0 + #define HAS_USB 1 + #define HAS_BEEP 1 + #define HAS_SERIAL_1 1 + #define HAS_SERIAL_1_ALT_1 1 + #define HAS_SERIAL_1_ALT_2 0 + #define HAS_SERIAL_1_HW_FLOW 1 + #define USE_SERIAL_STDIN 1 + #define HAS_ADC 0 + #define HAS_DBG 1 + #define HAS_EEPROM 1 + #define USE_INTERNAL_FLASH 0 + #define HAS_BTM 1 + #define DBG_ON_P1 1 + #define DBG_ON_P0 0 + #define IGNITE_ON_P2 0 + #define IGNITE_ON_P0 0 + #define PACKET_HAS_MASTER 1 + #define PACKET_HAS_SLAVE 0 + #define AO_LED_RED 1 + #define AO_LED_GREEN 2 + #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) + #define SPI_CS_ON_P1 1 + #define SPI_CS_ON_P0 0 + #define M25_CS_MASK 0x04 /* CS0 is P1_2 */ + #define M25_MAX_CHIPS 1 + #define HAS_ACCEL 0 + #define HAS_IGNITE 0 + #define BT_LINK_ON_P2 0 + #define BT_LINK_ON_P1 1 + #define BT_LINK_PIN_INDEX 7 + #define BT_LINK_PIN P1_7 + #define HAS_MONITOR 1 +#endif + +#if DBG_ON_P1 + + #define DBG_CLOCK (1 << 4) /* mi0 */ + #define DBG_DATA (1 << 5) /* mo0 */ + #define DBG_RESET_N (1 << 3) /* c0 */ + + #define DBG_CLOCK_PIN (P1_4) + #define DBG_DATA_PIN (P1_5) + #define DBG_RESET_N_PIN (P1_3) + + #define DBG_PORT_NUM 1 + #define DBG_PORT P1 + #define DBG_PORT_SEL P1SEL + #define DBG_PORT_INP P1INP + #define DBG_PORT_DIR P1DIR + +#endif /* DBG_ON_P1 */ + +#if DBG_ON_P0 + + #define DBG_CLOCK (1 << 3) + #define DBG_DATA (1 << 4) + #define DBG_RESET_N (1 << 5) + + #define DBG_CLOCK_PIN (P0_3) + #define DBG_DATA_PIN (P0_4) + #define DBG_RESET_N_PIN (P0_5) + + #define DBG_PORT_NUM 0 + #define DBG_PORT P0 + #define DBG_PORT_SEL P0SEL + #define DBG_PORT_INP P0INP + #define DBG_PORT_DIR P0DIR + +#endif /* DBG_ON_P0 */ + +#if COMPANION_CS_ON_P1 + #define COMPANION_CS_PORT P1 + #define COMPANION_CS_SEL P1SEL + #define COMPANION_CS_DIR P1DIR +#endif + +#if SPI_CS_ON_P1 + #define SPI_CS_PORT P1 + #define SPI_CS_SEL P1SEL + #define SPI_CS_DIR P1DIR +#endif + +#if SPI_CS_ON_P0 + #define SPI_CS_PORT P0 + #define SPI_CS_SEL P0SEL + #define SPI_CS_DIR P0DIR +#endif + +#ifndef IGNITE_ON_P2 +#error Please define IGNITE_ON_P2 +#endif + +#ifndef IGNITE_ON_P0 +#error Please define IGNITE_ON_P0 +#endif + +#ifndef HAS_SERIAL_1 +#error Please define HAS_SERIAL_1 +#endif + +#ifndef USE_SERIAL_STDIN +#error Please define USE_SERIAL_STDIN +#endif + +#ifndef HAS_ADC +#error Please define HAS_ADC +#endif + +#ifndef HAS_EEPROM +#error Please define HAS_EEPROM +#endif + +#if HAS_EEPROM +#ifndef USE_INTERNAL_FLASH +#error Please define USE_INTERNAL_FLASH +#endif +#endif + +#ifndef HAS_DBG +#error Please define HAS_DBG +#endif + +#ifndef HAS_IGNITE +#error Please define HAS_IGNITE +#endif + +#ifndef PACKET_HAS_MASTER +#error Please define PACKET_HAS_MASTER +#endif + +#ifndef PACKET_HAS_SLAVE +#error Please define PACKET_HAS_SLAVE +#endif + +#ifndef HAS_MONITOR +#error Please define HAS_MONITOR +#endif + +#ifndef HAS_ADC +#error Please define HAS_ADC +#endif + +#if HAS_ADC + +#if HAS_ACCEL +#ifndef HAS_ACCEL_REF +#error Please define HAS_ACCEL_REF +#endif +#else +#define HAS_ACCEL_REF 0 +#endif + +#endif /* HAS_ADC */ + +#endif /* _AO_PINS_H_ */ diff --git a/src/core/ao.h b/src/core/ao.h index 0f1a24ad..9b0bb545 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -22,21 +22,16 @@ #include #include #include -#include #include "ao_pins.h" +#include #define TRUE 1 #define FALSE 0 /* Convert a __data pointer into an __xdata pointer */ -#define DATA_TO_XDATA(a) ((void __xdata *) ((uint8_t) (a) | 0xff00)) - -/* Stack runs from above the allocated __data space to 0xfe, which avoids - * writing to 0xff as that triggers the stack overflow indicator - */ -#define AO_STACK_START 0x90 -#define AO_STACK_END 0xfe -#define AO_STACK_SIZE (AO_STACK_END - AO_STACK_START + 1) +#ifndef DATA_TO_XDATA +#define DATA_TO_XDATA(a) (a) +#endif /* An AltOS task */ struct ao_task { @@ -75,7 +70,7 @@ ao_alarm(uint16_t delay); /* Yield the processor to another task */ void -ao_yield(void) __naked; +ao_yield(void) ao_arch_naked_declare; /* Add a task to the run queue */ void @@ -136,7 +131,7 @@ ao_timer_set_adc_interval(uint8_t interval) __critical; /* Timer interrupt */ void -ao_timer_isr(void) __interrupt 9; +ao_timer_isr(void) ao_arch_interrupt(9); /* Initialize the timer */ void @@ -159,20 +154,8 @@ struct ao_adc { int16_t sense_m; /* main continuity sense */ }; -#ifndef HAS_ADC -#error Please define HAS_ADC -#endif - #if HAS_ADC -#if HAS_ACCEL -#ifndef HAS_ACCEL_REF -#error Please define HAS_ACCEL_REF -#endif -#else -#define HAS_ACCEL_REF 0 -#endif - /* * ao_adc.c */ @@ -207,7 +190,7 @@ ao_adc_get(__xdata struct ao_adc *packet); /* The A/D interrupt handler */ void -ao_adc_isr(void) __interrupt 1; +ao_adc_isr(void) ao_arch_interrupt(1); /* Initialize the A/D converter */ void @@ -298,25 +281,6 @@ ao_led_for(uint8_t colors, uint16_t ticks) __reentrant; void ao_led_init(uint8_t enable); -/* - * ao_romconfig.c - */ - -#define AO_ROMCONFIG_VERSION 2 - -extern __code __at (0x00a0) uint16_t ao_romconfig_version; -extern __code __at (0x00a2) uint16_t ao_romconfig_check; -extern __code __at (0x00a4) uint16_t ao_serial_number; -extern __code __at (0x00a6) uint32_t ao_radio_cal; - -#ifndef HAS_USB -#error Please define HAS_USB -#endif - -#if HAS_USB -extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; -#endif - /* * ao_usb.c */ @@ -342,7 +306,7 @@ ao_usb_flush(void); #if HAS_USB /* USB interrupt handler */ void -ao_usb_isr(void) __interrupt 6; +ao_usb_isr(void) ao_arch_interrupt(6); #endif /* Enable the USB controller */ @@ -446,7 +410,7 @@ ao_dma_abort(uint8_t id); /* DMA interrupt routine */ void -ao_dma_isr(void) __interrupt 8; +ao_dma_isr(void) ao_arch_interrupt(8); /* * ao_mutex.c @@ -927,10 +891,10 @@ ao_dbg_init(void); #endif void -ao_serial_rx1_isr(void) __interrupt 3; +ao_serial_rx1_isr(void) ao_arch_interrupt(3); void -ao_serial_tx1_isr(void) __interrupt 14; +ao_serial_tx1_isr(void) ao_arch_interrupt(14); char ao_serial_getchar(void) __critical; @@ -1251,14 +1215,6 @@ struct ao_telemetry_tiny { char callsign[AO_MAX_CALLSIGN]; }; -/* - * ao_radio_recv tacks on rssi and status bytes - */ - -struct ao_telemetry_raw_recv { - uint8_t packet[AO_MAX_TELEMETRY + 2]; -}; - struct ao_telemetry_orig_recv { struct ao_telemetry_orig telemetry_orig; int8_t rssi; @@ -1271,6 +1227,14 @@ struct ao_telemetry_tiny_recv { uint8_t status; }; +/* + * ao_radio_recv tacks on rssi and status bytes + */ + +struct ao_telemetry_raw_recv { + uint8_t packet[AO_MAX_TELEMETRY + 2]; +}; + /* Set delay between telemetry reports (0 to disable) */ #define AO_TELEMETRY_INTERVAL_PAD AO_MS_TO_TICKS(1000) @@ -1302,7 +1266,7 @@ extern __xdata uint8_t ao_radio_done; extern __xdata uint8_t ao_radio_mutex; void -ao_radio_general_isr(void) __interrupt 16; +ao_radio_general_isr(void) ao_arch_interrupt(16); void ao_radio_get(uint8_t len); diff --git a/src/core/ao_panic.c b/src/core/ao_panic.c index fdada201..cbfdf399 100644 --- a/src/core/ao_panic.c +++ b/src/core/ao_panic.c @@ -33,7 +33,7 @@ ao_panic_delay(uint8_t n) while (n--) while (--j) while (--i) - _asm nop _endasm; + ao_arch_nop(); } void diff --git a/src/core/ao_pins.h b/src/core/ao_pins.h deleted file mode 100644 index e1f5459f..00000000 --- a/src/core/ao_pins.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * 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_ - -#if defined(TELEMETRUM_V_1_0) - #define HAS_FLIGHT 1 - #define HAS_USB 1 - #define HAS_BEEP 1 - #define HAS_GPS 1 - #define HAS_SERIAL_1 1 - #define HAS_ADC 1 - #define USE_SERIAL_STDIN 0 - #define HAS_EEPROM 1 - #define USE_INTERNAL_FLASH 0 - #define HAS_DBG 1 - #define DBG_ON_P1 1 - #define DBG_ON_P0 0 - #define IGNITE_ON_P2 1 - #define IGNITE_ON_P0 0 - #define PACKET_HAS_MASTER 0 - #define PACKET_HAS_SLAVE 1 - - #define HAS_COMPANION 1 - #define COMPANION_CS_ON_P1 1 - #define COMPANION_CS_MASK 0x4 /* CS1 is P1_2 */ - #define COMPANION_CS P1_2 - - #define AO_LED_RED 1 - #define LEDS_AVAILABLE (AO_LED_RED) - #define HAS_EXTERNAL_TEMP 0 - #define HAS_ACCEL_REF 0 - #define HAS_ACCEL 1 - #define HAS_IGNITE 1 - #define HAS_MONITOR 0 -#endif - -#if defined(TELEMETRUM_V_1_1) - #define HAS_FLIGHT 1 - #define HAS_USB 1 - #define HAS_BEEP 1 - #define HAS_GPS 1 - #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 0 - #define HAS_ADC 1 - #define HAS_EEPROM 1 - #define USE_INTERNAL_FLASH 0 - #define HAS_DBG 1 - #define DBG_ON_P1 1 - #define DBG_ON_P0 0 - #define IGNITE_ON_P2 1 - #define IGNITE_ON_P0 0 - #define PACKET_HAS_MASTER 0 - #define PACKET_HAS_SLAVE 1 - - #define HAS_COMPANION 1 - #define COMPANION_CS_ON_P1 1 - #define COMPANION_CS_MASK 0x4 /* CS1 is P1_2 */ - #define COMPANION_CS P1_2 - - #define AO_LED_RED 1 - #define LEDS_AVAILABLE (AO_LED_RED) - #define HAS_EXTERNAL_TEMP 0 - #define HAS_ACCEL_REF 1 - #define SPI_CS_ON_P1 1 - #define SPI_CS_ON_P0 0 - #define M25_CS_MASK 0x02 /* CS0 is P1_1 */ - #define M25_MAX_CHIPS 1 - #define HAS_ACCEL 1 - #define HAS_IGNITE 1 - #define HAS_MONITOR 0 -#endif - -#if defined(TELEDONGLE_V_0_2) - #define HAS_FLIGHT 0 - #define HAS_USB 1 - #define HAS_BEEP 0 - #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 - #define HAS_ADC 0 - #define HAS_DBG 1 - #define HAS_EEPROM 0 - #define DBG_ON_P1 1 - #define DBG_ON_P0 0 - #define IGNITE_ON_P2 0 - #define IGNITE_ON_P0 0 - #define PACKET_HAS_MASTER 1 - #define PACKET_HAS_SLAVE 0 - #define AO_LED_RED 1 - #define AO_LED_GREEN 2 - #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) - #define SPI_CS_ON_P1 1 - #define SPI_CS_ON_P0 0 - #define HAS_IGNITE 0 - #define HAS_MONITOR 1 -#endif - -#if defined(TELEMINI_V_1_0) - #define HAS_FLIGHT 1 - #define HAS_USB 0 - #define HAS_BEEP 0 - #define HAS_GPS 0 - #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 - #define HAS_ADC 1 - #define HAS_EEPROM 1 - #define USE_INTERNAL_FLASH 1 - #define HAS_DBG 0 - #define IGNITE_ON_P2 0 - #define IGNITE_ON_P0 1 - #define PACKET_HAS_MASTER 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_MONITOR 0 -#endif - -#if defined(TELENANO_V_0_1) - #define HAS_FLIGHT 1 - #define HAS_USB 0 - #define HAS_BEEP 0 - #define HAS_GPS 0 - #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 - #define HAS_ADC 1 - #define HAS_EEPROM 1 - #define USE_INTERNAL_FLASH 1 - #define HAS_DBG 0 - #define IGNITE_ON_P2 0 - #define IGNITE_ON_P0 1 - #define PACKET_HAS_MASTER 0 - #define PACKET_HAS_SLAVE 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 0 - #define HAS_MONITOR 0 -#endif - -#if defined(TELEMETRUM_V_0_1) - #define HAS_FLIGHT 1 - #define HAS_USB 1 - #define HAS_BEEP 1 - #define HAS_GPS 1 - #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 0 - #define HAS_ADC 1 - #define HAS_DBG 0 - #define HAS_EEPROM 1 - #define USE_INTERNAL_FLASH 0 - #define DBG_ON_P1 0 - #define DBG_ON_P0 1 - #define IGNITE_ON_P2 1 - #define IGNITE_ON_P0 0 - #define PACKET_HAS_MASTER 0 - #define PACKET_HAS_SLAVE 1 - #define AO_LED_RED 2 - #define AO_LED_GREEN 1 - #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) - #define HAS_EXTERNAL_TEMP 1 - #define HAS_ACCEL_REF 0 - #define SPI_CS_ON_P1 1 - #define SPI_CS_ON_P0 0 - #define HAS_ACCEL 1 - #define HAS_IGNITE 1 - #define HAS_MONITOR 0 -#endif - -#if defined(TELEDONGLE_V_0_1) - #define HAS_FLIGHT 0 - #define HAS_USB 1 - #define HAS_BEEP 0 - #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 - #define HAS_ADC 0 - #define HAS_DBG 0 - #define HAS_EEPROM 0 - #define DBG_ON_P1 0 - #define DBG_ON_P0 1 - #define IGNITE_ON_P2 0 - #define IGNITE_ON_P0 0 - #define PACKET_HAS_MASTER 1 - #define PACKET_HAS_SLAVE 0 - #define AO_LED_RED 2 - #define AO_LED_GREEN 1 - #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) - #define SPI_CS_ON_P1 0 - #define SPI_CS_ON_P0 1 - #define HAS_IGNITE 0 - #define HAS_MONITOR 1 -#endif - -#if defined(TIDONGLE) - #define HAS_FLIGHT 0 - #define HAS_USB 1 - #define HAS_BEEP 0 - #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 - #define HAS_ADC 0 - #define HAS_DBG 1 - #define HAS_EEPROM 0 - #define DBG_ON_P1 0 - #define DBG_ON_P0 1 - #define IGNITE_ON_P2 0 - #define IGNITE_ON_P0 0 - #define PACKET_HAS_MASTER 1 - #define PACKET_HAS_SLAVE 0 - #define AO_LED_RED 2 - #define LEDS_AVAILABLE (AO_LED_RED) - #define SPI_CS_ON_P1 0 - #define SPI_CS_ON_P0 1 - #define HAS_IGNITE 0 - #define HAS_MONITOR 1 -#endif - -#if defined(TELEBT_V_0_0) - #define HAS_FLIGHT 0 - #define HAS_USB 1 - #define HAS_BEEP 0 - #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 1 - #define HAS_ADC 0 - #define HAS_DBG 1 - #define HAS_EEPROM 0 - #define HAS_BTM 1 - #define DBG_ON_P1 0 - #define DBG_ON_P0 1 - #define IGNITE_ON_P2 0 - #define IGNITE_ON_P0 0 - #define PACKET_HAS_MASTER 1 - #define PACKET_HAS_SLAVE 0 - #define AO_LED_RED 2 - #define AO_LED_GREEN 1 - #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) - #define SPI_CS_ON_P1 1 - #define SPI_CS_ON_P0 0 - #define HAS_IGNITE 0 - #define BT_LINK_ON_P2 1 - #define BT_LINK_ON_P1 0 - #define BT_LINK_PIN_INDEX 7 - #define BT_LINK_PIN P2_1 - #define HAS_MONITOR 1 -#endif - -#if defined(TELEBT_V_0_1) - #define HAS_FLIGHT 0 - #define HAS_USB 1 - #define HAS_BEEP 1 - #define HAS_SERIAL_1 1 - #define HAS_SERIAL_1_ALT_1 1 - #define HAS_SERIAL_1_ALT_2 0 - #define HAS_SERIAL_1_HW_FLOW 1 - #define USE_SERIAL_STDIN 1 - #define HAS_ADC 0 - #define HAS_DBG 1 - #define HAS_EEPROM 1 - #define USE_INTERNAL_FLASH 0 - #define HAS_BTM 1 - #define DBG_ON_P1 1 - #define DBG_ON_P0 0 - #define IGNITE_ON_P2 0 - #define IGNITE_ON_P0 0 - #define PACKET_HAS_MASTER 1 - #define PACKET_HAS_SLAVE 0 - #define AO_LED_RED 1 - #define AO_LED_GREEN 2 - #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) - #define SPI_CS_ON_P1 1 - #define SPI_CS_ON_P0 0 - #define M25_CS_MASK 0x04 /* CS0 is P1_2 */ - #define M25_MAX_CHIPS 1 - #define HAS_ACCEL 0 - #define HAS_IGNITE 0 - #define BT_LINK_ON_P2 0 - #define BT_LINK_ON_P1 1 - #define BT_LINK_PIN_INDEX 7 - #define BT_LINK_PIN P1_7 - #define HAS_MONITOR 1 -#endif - -#if DBG_ON_P1 - - #define DBG_CLOCK (1 << 4) /* mi0 */ - #define DBG_DATA (1 << 5) /* mo0 */ - #define DBG_RESET_N (1 << 3) /* c0 */ - - #define DBG_CLOCK_PIN (P1_4) - #define DBG_DATA_PIN (P1_5) - #define DBG_RESET_N_PIN (P1_3) - - #define DBG_PORT_NUM 1 - #define DBG_PORT P1 - #define DBG_PORT_SEL P1SEL - #define DBG_PORT_INP P1INP - #define DBG_PORT_DIR P1DIR - -#endif /* DBG_ON_P1 */ - -#if DBG_ON_P0 - - #define DBG_CLOCK (1 << 3) - #define DBG_DATA (1 << 4) - #define DBG_RESET_N (1 << 5) - - #define DBG_CLOCK_PIN (P0_3) - #define DBG_DATA_PIN (P0_4) - #define DBG_RESET_N_PIN (P0_5) - - #define DBG_PORT_NUM 0 - #define DBG_PORT P0 - #define DBG_PORT_SEL P0SEL - #define DBG_PORT_INP P0INP - #define DBG_PORT_DIR P0DIR - -#endif /* DBG_ON_P0 */ - -#if COMPANION_CS_ON_P1 - #define COMPANION_CS_PORT P1 - #define COMPANION_CS_SEL P1SEL - #define COMPANION_CS_DIR P1DIR -#endif - -#if SPI_CS_ON_P1 - #define SPI_CS_PORT P1 - #define SPI_CS_SEL P1SEL - #define SPI_CS_DIR P1DIR -#endif - -#if SPI_CS_ON_P0 - #define SPI_CS_PORT P0 - #define SPI_CS_SEL P0SEL - #define SPI_CS_DIR P0DIR -#endif - -#ifndef IGNITE_ON_P2 -#error Please define IGNITE_ON_P2 -#endif - -#ifndef IGNITE_ON_P0 -#error Please define IGNITE_ON_P0 -#endif - -#ifndef HAS_SERIAL_1 -#error Please define HAS_SERIAL_1 -#endif - -#ifndef USE_SERIAL_STDIN -#error Please define USE_SERIAL_STDIN -#endif - -#ifndef HAS_ADC -#error Please define HAS_ADC -#endif - -#ifndef HAS_EEPROM -#error Please define HAS_EEPROM -#endif - -#if HAS_EEPROM -#ifndef USE_INTERNAL_FLASH -#error Please define USE_INTERNAL_FLASH -#endif -#endif - -#ifndef HAS_DBG -#error Please define HAS_DBG -#endif - -#ifndef HAS_IGNITE -#error Please define HAS_IGNITE -#endif - -#ifndef PACKET_HAS_MASTER -#error Please define PACKET_HAS_MASTER -#endif - -#ifndef PACKET_HAS_SLAVE -#error Please define PACKET_HAS_SLAVE -#endif - -#ifndef HAS_MONITOR -#error Please define HAS_MONITOR -#endif -#endif /* _AO_PINS_H_ */ diff --git a/src/core/ao_task.c b/src/core/ao_task.c index f5850fa4..41520476 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -27,7 +27,6 @@ __xdata struct ao_task *__data ao_cur_task; void ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant { - uint8_t __xdata *stack; uint8_t task_id; uint8_t t; if (ao_num_tasks == AO_NUM_TASKS) @@ -42,70 +41,19 @@ ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *nam ao_tasks[ao_num_tasks++] = task; task->task_id = task_id; task->name = name; + task->wchan = NULL; /* * Construct a stack frame so that it will 'return' * to the start of the task */ - stack = task->stack; - - *stack++ = ((uint16_t) start); /* 0 */ - *stack++ = ((uint16_t) start) >> 8; /* 1 */ - - /* and the stuff saved by ao_switch */ - *stack++ = 0; /* 2 acc */ - *stack++ = 0x80; /* 3 IE */ - - /* 4 DPL - * 5 DPH - * 6 B - * 7 R2 - * 8 R3 - * 9 R4 - * 10 R5 - * 11 R6 - * 12 R7 - * 13 R0 - * 14 R1 - * 15 PSW - * 16 BP - */ - for (t = 0; t < 13; t++) - *stack++ = 0; - - task->stack_count = 17; - task->wchan = NULL; + ao_arch_init_stack(task, start); } /* Task switching function. This must not use any stack variables */ void -ao_yield(void) __naked +ao_yield(void) ao_arch_naked_define { - - /* Save current context */ - _asm - /* Push ACC first, as when restoring the context it must be restored - * last (it is used to set the IE register). */ - push ACC - /* Store the IE register then enable interrupts. */ - push _IEN0 - setb _EA - push DPL - push DPH - push b - push ar2 - push ar3 - push ar4 - push ar5 - push ar6 - push ar7 - push ar0 - push ar1 - push PSW - _endasm; - PSW = 0; - _asm - push _bp - _endasm; + ao_arch_save_context(); if (ao_cur_task_index == AO_NO_TASK_INDEX) ao_cur_task_index = ao_num_tasks-1; diff --git a/src/product/Makefile.telebt b/src/product/Makefile.telebt index 99730b9f..d9ef1ea7 100644 --- a/src/product/Makefile.telebt +++ b/src/product/Makefile.telebt @@ -79,7 +79,7 @@ all: ../$(PROG) ../$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. - $(call quiet,CHECK_STACK) ../core/ao.h $(PMEM) + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ diff --git a/src/product/Makefile.teledongle b/src/product/Makefile.teledongle index f32c037f..cfd9b806 100644 --- a/src/product/Makefile.teledongle +++ b/src/product/Makefile.teledongle @@ -78,7 +78,7 @@ all: ../$(PROG) ../$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. - $(call quiet,CHECK_STACK) ../core/ao.h $(PMEM) + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ diff --git a/src/product/Makefile.telemetrum b/src/product/Makefile.telemetrum index fd958aea..2759ac52 100644 --- a/src/product/Makefile.telemetrum +++ b/src/product/Makefile.telemetrum @@ -93,7 +93,7 @@ all: ../$(PROG) ../$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. - $(call quiet,CHECK_STACK) ../core/ao.h $(PMEM) + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ diff --git a/src/product/Makefile.telemini b/src/product/Makefile.telemini index 3bd14226..7f251897 100644 --- a/src/product/Makefile.telemini +++ b/src/product/Makefile.telemini @@ -82,7 +82,7 @@ all: ../$(PROG) ../$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. - $(call quiet,CHECK_STACK) ../core/ao.h $(PMEM) + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ diff --git a/src/product/Makefile.telenano b/src/product/Makefile.telenano index 72043044..c47e95ff 100644 --- a/src/product/Makefile.telenano +++ b/src/product/Makefile.telenano @@ -81,7 +81,7 @@ all: ../$(PROG) ../$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. - $(call quiet,CHECK_STACK) ../core/ao.h $(PMEM) + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ diff --git a/src/tidongle/Makefile b/src/tidongle/Makefile index fc8df1f4..247f4fe0 100644 --- a/src/tidongle/Makefile +++ b/src/tidongle/Makefile @@ -73,7 +73,7 @@ all: ../$(PROG) ../$(PROG): $(REL) Makefile $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(REL) && cp $(PROG) $(PMAP) .. - $(call quiet,CHECK_STACK) ../core/ao.h $(PMEM) + $(call quiet,CHECK_STACK) ../cc1111/ao_arch.h $(PMEM) ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ -- cgit v1.2.3 From 8125acc030574afed6f23aa8aa302d9c768bb04e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 25 Aug 2011 22:55:33 -0700 Subject: altos: get avr-demo to build. Pull in AVR drivers and LCD driver This completes the basic task of making an AVR version of altos by getting the Teensy 'avr-demo' program to build. Signed-off-by: Keith Packard --- src/avr-demo/Makefile | 7 +- src/avr-demo/ao_demo.c | 52 ++++ src/avr/ao_arch.h | 80 ++++-- src/avr/ao_avr_stdio.c | 2 +- src/avr/ao_debug_avr.c | 78 ++++++ src/avr/ao_led.c | 67 +++++ src/avr/ao_pins.h | 28 +- src/avr/ao_romconfig.c | 20 ++ src/avr/ao_serial_avr.c | 166 ++++++++++++ src/avr/ao_timer.c | 147 +++++++++++ src/avr/ao_usb.h | 100 +++++++ src/avr/ao_usb_avr.c | 688 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cc1111/ao_arch.h | 118 +++++++-- src/core/ao.h | 11 +- src/core/ao_panic.c | 2 +- src/core/ao_task.c | 99 ++----- 16 files changed, 1542 insertions(+), 123 deletions(-) create mode 100644 src/avr-demo/ao_demo.c create mode 100644 src/avr/ao_debug_avr.c create mode 100644 src/avr/ao_led.c create mode 100644 src/avr/ao_romconfig.c create mode 100644 src/avr/ao_serial_avr.c create mode 100644 src/avr/ao_timer.c create mode 100644 src/avr/ao_usb.h create mode 100644 src/avr/ao_usb_avr.c (limited to 'src/avr') diff --git a/src/avr-demo/Makefile b/src/avr-demo/Makefile index ea356654..93295166 100644 --- a/src/avr-demo/Makefile +++ b/src/avr-demo/Makefile @@ -2,7 +2,7 @@ # AltOS build # # -vpath % ..:../core:../product:../driver +vpath % ..:../core:../product:../drivers:../avr vpath make-altitude .. vpath make-kalman .. vpath kalman.5c ../kalman @@ -38,12 +38,15 @@ ALTOS_SRC = \ ao_mutex.c \ ao_panic.c \ ao_product.c \ + ao_romconfig.c \ ao_serial_avr.c \ ao_avr_stdio.c \ ao_stdio.c \ ao_task.c \ ao_timer.c \ - ao_led.c + ao_led.c \ + ao_usb_avr.c \ + ao_lcd.c PRODUCT=AvrDemo-v0.0 MCU=atmega32u4 diff --git a/src/avr-demo/ao_demo.c b/src/avr-demo/ao_demo.c new file mode 100644 index 00000000..756dd0d4 --- /dev/null +++ b/src/avr-demo/ao_demo.c @@ -0,0 +1,52 @@ +/* + * 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" + +struct ao_task demo_task; + +void +ao_demo(void) +{ + for (;;) { + ao_led_toggle(AO_LED_RED); + printf ("hello %d\n", ao_time()); + ao_delay(AO_MS_TO_TICKS(200)); + } +} + +int +main(void) +{ + ao_clock_init(); + + ao_serial_init(); + + ao_led_init(LEDS_AVAILABLE); + ao_avr_stdio_init(); + printf ("stdio initialized\n"); +// ao_debug_init(); + ao_timer_init(); + ao_cmd_init(); + ao_usb_init(); + ao_lcd_init(); + +// ao_add_task(&demo_task, ao_demo, "demo"); + /* Turn on the LED until the system is stable */ + ao_start_scheduler(); + return 0; +} diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index 51a65880..0ed97361 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -18,8 +18,10 @@ #ifndef _AO_ARCH_H_ #define _AO_ARCH_H_ +#include #include #include +#include #ifdef AVR_DEMO #define TEENSY 1 @@ -48,6 +50,7 @@ #define __reentrant #define __critical #define __interrupt(n) +#define __at(n) #define ao_arch_reboot() /* XXX */ @@ -62,8 +65,18 @@ extern void putchar(char c); extern char getchar(void); +extern void ao_avr_stdio_init(void); -extern int ao_serial_number; +extern const uint16_t ao_serial_number; + +#define AVR_PUSH8(stack, val) (*((stack)--) = (val)) + +extern uint8_t ao_cpu_sleep_disable; + +#define ao_arch_task_globals uint8_t ao_cpu_sleep_disable; + +#define ao_arch_task_members\ + uint8_t *sp; /* saved stack pointer */ #define ao_arch_init_stack(task, start) do { \ uint8_t *sp = task->stack + AO_STACK_SIZE - 1; \ @@ -71,29 +84,66 @@ extern int ao_serial_number; int i; \ \ /* Return address */ \ - PUSH8(sp, a); \ - PUSH8(sp, (a >> 8)); \ + AVR_PUSH8(sp, a); \ + AVR_PUSH8(sp, (a >> 8)); \ \ /* Clear register values */ \ i = 32; \ while (i--) \ - PUSH8(sp, 0); \ + AVR_PUSH8(sp, 0); \ \ /* SREG with interrupts enabled */ \ - PUSH8(sp, 0x80); \ + AVR_PUSH8(sp, 0x80); \ task->sp = sp; \ } while (0); -#define ao_arch_save_context() do { \ - asm("push r31" "\n\t" "push r30"); \ - asm("push r29" "\n\t" "push r28" "\n\t" "push r27" "\n\t" "push r26" "\n\t" "push r25"); \ - asm("push r24" "\n\t" "push r23" "\n\t" "push r22" "\n\t" "push r21" "\n\t" "push r20"); \ - asm("push r19" "\n\t" "push r18" "\n\t" "push r17" "\n\t" "push r16" "\n\t" "push r15"); \ - asm("push r14" "\n\t" "push r13" "\n\t" "push r12" "\n\t" "push r11" "\n\t" "push r10"); \ - asm("push r9" "\n\t" "push r8" "\n\t" "push r7" "\n\t" "push r6" "\n\t" "push r5"); \ - asm("push r4" "\n\t" "push r3" "\n\t" "push r2" "\n\t" "push r1" "\n\t" "push r0"); \ - asm("in r0, __SREG__" "\n\t" "push r0"); \ - sei(); \ +#define ao_arch_save_regs() do { \ + asm("push r31" "\n\t" "push r30"); \ + asm("push r29" "\n\t" "push r28" "\n\t" "push r27" "\n\t" "push r26" "\n\t" "push r25"); \ + asm("push r24" "\n\t" "push r23" "\n\t" "push r22" "\n\t" "push r21" "\n\t" "push r20"); \ + asm("push r19" "\n\t" "push r18" "\n\t" "push r17" "\n\t" "push r16" "\n\t" "push r15"); \ + asm("push r14" "\n\t" "push r13" "\n\t" "push r12" "\n\t" "push r11" "\n\t" "push r10"); \ + asm("push r9" "\n\t" "push r8" "\n\t" "push r7" "\n\t" "push r6" "\n\t" "push r5"); \ + asm("push r4" "\n\t" "push r3" "\n\t" "push r2" "\n\t" "push r1" "\n\t" "push r0"); \ + cli(); \ + asm("in r0, __SREG__" "\n\t" "push r0"); \ + sei(); \ + } while (0) + +#define ao_arch_save_stack() do { \ + uint8_t sp_l, sp_h; \ + asm("in %0,__SP_L__" : "=&r" (sp_l) ); \ + asm("in %0,__SP_H__" : "=&r" (sp_h) ); \ + ao_cur_task->sp = (uint8_t *) ((uint16_t) sp_l | ((uint16_t) sp_h << 8)); \ } while (0) +#define ao_arch_isr_stack() /* nothing */ + +#define ao_arch_cpu_idle() do { \ + if (!ao_cpu_sleep_disable) \ + sleep_cpu(); \ + } while (0) + +#define ao_arch_restore_stack() do { \ + uint8_t sp_l, sp_h; \ + sp_l = (uint16_t) ao_cur_task->sp; \ + sp_h = ((uint16_t) ao_cur_task->sp) >> 8; \ + cli(); \ + asm("out __SP_H__,%0" : : "r" (sp_h) ); \ + asm("out __SP_L__,%0" : : "r" (sp_l) ); \ + asm("pop r0" "\n\t" \ + "out __SREG__, r0"); \ + asm("pop r0" "\n\t" "pop r1" "\n\t" "pop r2" "\n\t" "pop r3" "\n\t" "pop r4"); \ + asm("pop r5" "\n\t" "pop r6" "\n\t" "pop r7" "\n\t" "pop r8" "\n\t" "pop r9"); \ + asm("pop r10" "\n\t" "pop r11" "\n\t" "pop r12" "\n\t" "pop r13" "\n\t" "pop r14"); \ + asm("pop r15" "\n\t" "pop r16" "\n\t" "pop r17" "\n\t" "pop r18" "\n\t" "pop r19"); \ + asm("pop r20" "\n\t" "pop r21" "\n\t" "pop r22" "\n\t" "pop r23" "\n\t" "pop r24"); \ + asm("pop r25" "\n\t" "pop r26" "\n\t" "pop r27" "\n\t" "pop r28" "\n\t" "pop r29"); \ + asm("pop r30" "\n\t" "pop r31"); \ + asm("ret"); \ + } while(0) + +#define ao_arch_critical(b) do { cli(); b; sei(); } while (0) + #endif /* _AO_ARCH_H_ */ + diff --git a/src/avr/ao_avr_stdio.c b/src/avr/ao_avr_stdio.c index 2f358eb5..ba562dbf 100644 --- a/src/avr/ao_avr_stdio.c +++ b/src/avr/ao_avr_stdio.c @@ -44,7 +44,7 @@ static FILE mystdout = FDEV_SETUP_STREAM(stdio_put, NULL, _FDEV_SETUP_WRITE); static FILE mystdin = FDEV_SETUP_STREAM(NULL, stdio_get, _FDEV_SETUP_READ); void -ao_stdio_init(void) +ao_avr_stdio_init(void) { stdout = &mystdout; stdin = &mystdin; diff --git a/src/avr/ao_debug_avr.c b/src/avr/ao_debug_avr.c new file mode 100644 index 00000000..2e41e15a --- /dev/null +++ b/src/avr/ao_debug_avr.c @@ -0,0 +1,78 @@ +/* + * 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" + +void +uart_send(char c) +{ + loop_until_bit_is_set(UCSR1A, UDRE1); + UDR1 = c; +} + +int +uart_put(char c, FILE *stream) +{ + if (c == '\n') + uart_send('\r'); + uart_send(c); + return 0; +} + +int +uart_get(FILE *stream) +{ + loop_until_bit_is_set(UCSR1A, RXC1); + return (int) UDR1 & 0xff; +} + +void +uart_init(uint16_t baud) +{ + PRR1 &= ~(1 << PRUSART1); + UBRR1L = baud; + UBRR1H = baud >> 8; + UCSR1A = 0; + UCSR1B = ((1 << RXEN1) | /* Enable receiver */ + (1 << TXEN1)); /* Enable transmitter */ + UCSR1C = ((0 << UMSEL10) | /* Asynchronous mode */ + (0 << UPM10) | /* No parity */ + (0 << USBS1) | /* 1 stop bit */ + (3 << UCSZ10) | /* 8 bit characters */ + (0 << UCPOL1)); /* MBZ for async mode */ +} + +static FILE mystdout = FDEV_SETUP_STREAM(uart_put, NULL, _FDEV_SETUP_WRITE); + +static FILE mystdin = FDEV_SETUP_STREAM(NULL, uart_get, _FDEV_SETUP_READ); + +void ao_debug_init(void) +{ + uart_init(F_CPU / (16UL * 9600UL) - 1); + + stdout = &mystdout; + stdin = &mystdin; + + if (DDRB & AO_LED_RED) { + printf ("oops, starting all over\n"); + for (;;) + ; + } + DDRB |= (1 << 7); + PORTB |= (1 << 7); + printf ("debug initialized\n"); +} diff --git a/src/avr/ao_led.c b/src/avr/ao_led.c new file mode 100644 index 00000000..91dfb85e --- /dev/null +++ b/src/avr/ao_led.c @@ -0,0 +1,67 @@ +/* + * 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; 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" + +__pdata uint8_t ao_led_enable; + +#define LED_PORT PORTB +#define LED_DDR DDRB + +void +ao_led_on(uint8_t colors) +{ + LED_PORT |= (colors & ao_led_enable); +} + +void +ao_led_off(uint8_t colors) +{ + LED_PORT &= ~(colors & ao_led_enable); +} + +void +ao_led_set(uint8_t colors) +{ + LED_PORT = (LED_PORT & ~(ao_led_enable)) | (colors & ao_led_enable); +} + +void +ao_led_toggle(uint8_t colors) +{ + LED_PORT ^= (colors & ao_led_enable); +} + +void +ao_led_for(uint8_t colors, uint16_t ticks) __reentrant +{ + ao_led_on(colors); + ao_delay(ticks); + ao_led_off(colors); +} + +void +ao_led_init(uint8_t enable) +{ + ao_led_enable = enable; + if ((LED_DDR & enable)) { + printf ("oops! restarted\n"); + ao_panic(AO_PANIC_REBOOT); + } + LED_PORT &= ~enable; + LED_DDR |= enable; +} diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index ef41b59c..56435f18 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -22,10 +22,36 @@ #define AO_LED_RED (1<<7) #define LEDS_AVAILABLE (AO_LED_RED) #define USE_SERIAL_STDIN 1 - #define HAS_USB 0 + #define HAS_USB 1 #define PACKET_HAS_SLAVE 0 #define HAS_SERIAL_1 1 + #define TEENSY 1 + #define AVR_VCC_5V 1 + #define AVR_VCC_3V3 0 + #define AVR_CLOCK 16000000UL #define HAS_BEEP 0 #endif +#ifdef TELESCIENCE + #define LEDS_AVAILABLE 0 + #define HAS_USB 1 + #define HAS_LOG 1 + #define TEENSY 0 + #define USE_SERIAL_STDIN 1 + #define HAS_SERIAL_1 1 + #define HAS_USB 1 + #define HAS_ADC 1 + #define PACKET_HAS_SLAVE 0 + #define HAS_BEEP 0 + + #define AVR_VCC_5V 0 + #define AVR_VCC_3V3 1 + #define AVR_CLOCK 8000000UL + + #define SPI_CS_PORT PORTE + #define SPI_CS_DIR DDRE + #define M25_CS_MASK (1 << PORTE6) + #define M25_MAX_CHIPS 1 +#endif + #endif /* _AO_PINS_H_ */ diff --git a/src/avr/ao_romconfig.c b/src/avr/ao_romconfig.c new file mode 100644 index 00000000..bbb677e2 --- /dev/null +++ b/src/avr/ao_romconfig.c @@ -0,0 +1,20 @@ +/* + * 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" + +const uint16_t ao_serial_number = 0; diff --git a/src/avr/ao_serial_avr.c b/src/avr/ao_serial_avr.c new file mode 100644 index 00000000..2fe39755 --- /dev/null +++ b/src/avr/ao_serial_avr.c @@ -0,0 +1,166 @@ +/* + * 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" + +__xdata struct ao_fifo ao_usart1_rx_fifo; +__xdata struct ao_fifo ao_usart1_tx_fifo; + +void +ao_debug_out(char c) +{ + if (c == '\n') + ao_debug_out('\r'); + loop_until_bit_is_set(UCSR1A, UDRE1); + UDR1 = c; +} + +ISR(USART1_RX_vect) +{ + if (!ao_fifo_full(ao_usart1_rx_fifo)) + ao_fifo_insert(ao_usart1_rx_fifo, UDR1); + ao_wakeup(&ao_usart1_rx_fifo); +#if USE_SERIAL_STDIN + ao_wakeup(&ao_stdin_ready); +#endif +} + +static __xdata uint8_t ao_serial_tx1_started; + +static void +ao_serial_tx1_start(void) +{ + if (!ao_fifo_empty(ao_usart1_tx_fifo) && + !ao_serial_tx1_started) + { + ao_serial_tx1_started = 1; + ao_fifo_remove(ao_usart1_tx_fifo, UDR1); + } +} + +ISR(USART1_UDRE_vect) +{ + ao_serial_tx1_started = 0; + ao_serial_tx1_start(); + ao_wakeup(&ao_usart1_tx_fifo); +} + +char +ao_serial_getchar(void) __critical +{ + char c; + cli(); + while (ao_fifo_empty(ao_usart1_rx_fifo)) + ao_sleep(&ao_usart1_rx_fifo); + ao_fifo_remove(ao_usart1_rx_fifo, c); + sei(); + return c; +} + +#if USE_SERIAL_STDIN +char +ao_serial_pollchar(void) __critical +{ + char c; + cli(); + if (ao_fifo_empty(ao_usart1_rx_fifo)) { + sei(); + return AO_READ_AGAIN; + } + ao_fifo_remove(ao_usart1_rx_fifo,c); + sei(); + return c; +} +#endif + +void +ao_serial_putchar(char c) __critical +{ + cli(); + while (ao_fifo_full(ao_usart1_tx_fifo)) + ao_sleep(&ao_usart1_tx_fifo); + ao_fifo_insert(ao_usart1_tx_fifo, c); + ao_serial_tx1_start(); + sei(); +} + +void +ao_serial_drain(void) __critical +{ + cli(); + while (!ao_fifo_empty(ao_usart1_tx_fifo)) + ao_sleep(&ao_usart1_tx_fifo); + sei(); +} + +static const struct { + uint16_t ubrr; +} ao_serial_speeds[] = { + /* [AO_SERIAL_SPEED_4800] = */ { + F_CPU / (16UL * 4800UL) - 1 + }, + /* [AO_SERIAL_SPEED_9600] = */ { + F_CPU / (16UL * 9600UL) - 1 + }, + /* [AO_SERIAL_SPEED_19200] = */ { + F_CPU / (16UL * 19200UL) - 1 + }, + /* [AO_SERIAL_SPEED_57600] = */ { + F_CPU / (16UL * 57600UL) - 1 + }, +}; + +void +ao_serial_set_speed(uint8_t speed) +{ + ao_serial_drain(); + if (speed > AO_SERIAL_SPEED_57600) + return; + UBRR1L = ao_serial_speeds[speed].ubrr; + UBRR1H = ao_serial_speeds[speed].ubrr >> 8; +} + +void +ao_serial_init(void) +{ + /* Ensure the uart is powered up */ + + PRR1 &= ~(1 << PRUSART1); + + /* Pick a 9600 baud rate */ + ao_serial_set_speed(AO_SERIAL_SPEED_9600); + + UCSR1A = 0; + UCSR1C = ((0 << UMSEL10) | /* Asynchronous mode */ + (0 << UPM10) | /* No parity */ + (0 << USBS1) | /* 1 stop bit */ + (3 << UCSZ10) | /* 8 bit characters */ + (0 << UCPOL1)); /* MBZ for async mode */ + UCSR1B = ((1 << RXEN1) | /* Enable receiver */ + (1 << TXEN1) | /* Enable transmitter */ + (1 << RXCIE1) | /* Enable receive interrupts */ + (1 << UDRIE1)); /* Enable transmit empty interrupts */ +#if 0 +#if USE_SERIAL_STDIN + int8_t i; + i = ao_add_stdio(ao_serial_pollchar, + ao_serial_putchar, + NULL); + printf("Register serial stdio as %d\n", i); +#endif +#endif +} diff --git a/src/avr/ao_timer.c b/src/avr/ao_timer.c new file mode 100644 index 00000000..1e374c75 --- /dev/null +++ b/src/avr/ao_timer.c @@ -0,0 +1,147 @@ +/* + * 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; 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" + +static volatile __data uint16_t ao_tick_count; + +uint16_t ao_time(void) +{ + uint16_t v; + ao_arch_critical( + v = ao_tick_count; + ); + return v; +} + +static __xdata uint8_t ao_forever; + +void +ao_delay(uint16_t ticks) +{ + ao_alarm(ticks); + ao_sleep(&ao_forever); +} + +#define T1_CLOCK_DIVISOR 8 /* 24e6/8 = 3e6 */ +#define T1_SAMPLE_TIME 30000 /* 3e6/30000 = 100 */ + +#if HAS_ADC +volatile __data uint8_t ao_adc_interval = 1; +volatile __data uint8_t ao_adc_count; +#endif + +void +ao_debug_out(char c); + +ISR(TIMER1_COMPA_vect) +{ + ++ao_tick_count; +#if HAS_ADC + if (++ao_adc_count == ao_adc_interval) { + ao_adc_count = 0; + ao_adc_poll(); + } +#endif +} + +#if HAS_ADC +void +ao_timer_set_adc_interval(uint8_t interval) __critical +{ + ao_adc_interval = interval; + ao_adc_count = 0; +} +#endif + +void +ao_timer_init(void) +{ + TCCR1A = ((0 << WGM11) | /* CTC mode, OCR1A */ + (0 << WGM10)); /* CTC mode, OCR1A */ + TCCR1B = ((0 << ICNC1) | /* no input capture noise canceler */ + (0 << ICES1) | /* input capture on falling edge (don't care) */ + (0 << WGM13) | /* CTC mode, OCR1A */ + (1 << WGM12) | /* CTC mode, OCR1A */ + (3 << CS10)); /* clk/64 from prescaler */ + +#if TEENSY + OCR1A = 2500; /* 16MHz clock */ +#else + OCR1A = 1250; /* 8MHz clock */ +#endif + + TIMSK1 = (1 << OCIE1A); /* Interrupt on compare match */ +} + +/* + * AltOS always cranks the clock to the max frequency + */ +void +ao_clock_init(void) +{ + /* disable RC clock */ + CLKSEL0 &= ~(1 << RCE); + + /* Disable PLL */ + PLLCSR &= ~(1 << PLLE); + + /* Enable external clock */ + CLKSEL0 |= (1 << EXTE); + + /* wait for external clock to be ready */ + while ((CLKSTA & (1 << EXTON)) == 0) + ; + + /* select external clock */ + CLKSEL0 |= (1 << CLKS); + + /* Disable the clock prescaler */ + cli(); + CLKPR = (1 << CLKPCE); + + /* Always run the system clock at 8MHz */ +#if AVR_CLOCK > 12000000UL + CLKPR = 1; +#else + CLKPR = 0; +#endif + sei(); + + /* Set up the PLL to use the crystal */ + + /* Use primary system clock as PLL source */ + PLLFRQ = ((0 << PINMUX) | /* Use primary clock */ + (0 << PLLUSB) | /* No divide by 2 for USB */ + (0 << PLLTM0) | /* Disable high speed timer */ + (0x4 << PDIV0)); /* 48MHz PLL clock */ + + /* Set the frequency of the crystal */ +#if AVR_CLOCK > 12000000UL + PLLCSR |= (1 << PINDIV); /* For 16MHz crystal on Teensy board */ +#else + PLLCSR &= ~(1 << PINDIV); /* For 8MHz crystal on TeleScience board */ +#endif + + /* Enable the PLL */ + PLLCSR |= (1 << PLLE); + while (!(PLLCSR & (1 << PLOCK))) + ; + + set_sleep_mode(SLEEP_MODE_IDLE); + sleep_enable(); +} diff --git a/src/avr/ao_usb.h b/src/avr/ao_usb.h new file mode 100644 index 00000000..6633dafc --- /dev/null +++ b/src/avr/ao_usb.h @@ -0,0 +1,100 @@ +/* + * 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; 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_USB_H_ +#define _AO_USB_H_ + +#define AO_USB_SETUP_DIR_MASK (0x01 << 7) +#define AO_USB_SETUP_TYPE_MASK (0x03 << 5) +#define AO_USB_SETUP_RECIP_MASK (0x1f) + +#define AO_USB_DIR_OUT 0 +#define AO_USB_DIR_IN (1 << 7) + +#define AO_USB_TYPE_STANDARD 0 +#define AO_USB_TYPE_CLASS (1 << 5) +#define AO_USB_TYPE_VENDOR (2 << 5) +#define AO_USB_TYPE_RESERVED (3 << 5) + +#define AO_USB_RECIP_DEVICE 0 +#define AO_USB_RECIP_INTERFACE 1 +#define AO_USB_RECIP_ENDPOINT 2 +#define AO_USB_RECIP_OTHER 3 + +/* standard requests */ +#define AO_USB_REQ_GET_STATUS 0x00 +#define AO_USB_REQ_CLEAR_FEATURE 0x01 +#define AO_USB_REQ_SET_FEATURE 0x03 +#define AO_USB_REQ_SET_ADDRESS 0x05 +#define AO_USB_REQ_GET_DESCRIPTOR 0x06 +#define AO_USB_REQ_SET_DESCRIPTOR 0x07 +#define AO_USB_REQ_GET_CONFIGURATION 0x08 +#define AO_USB_REQ_SET_CONFIGURATION 0x09 +#define AO_USB_REQ_GET_INTERFACE 0x0A +#define AO_USB_REQ_SET_INTERFACE 0x0B +#define AO_USB_REQ_SYNCH_FRAME 0x0C + +#define AO_USB_DESC_DEVICE 1 +#define AO_USB_DESC_CONFIGURATION 2 +#define AO_USB_DESC_STRING 3 +#define AO_USB_DESC_INTERFACE 4 +#define AO_USB_DESC_ENDPOINT 5 +#define AO_USB_DESC_DEVICE_QUALIFIER 6 +#define AO_USB_DESC_OTHER_SPEED 7 +#define AO_USB_DESC_INTERFACE_POWER 8 + +#define AO_USB_GET_DESC_TYPE(x) (((x)>>8)&0xFF) +#define AO_USB_GET_DESC_INDEX(x) ((x)&0xFF) + +#define AO_USB_CONTROL_EP 0 +#define AO_USB_INT_EP 1 +#define AO_USB_OUT_EP 4 +#define AO_USB_IN_EP 5 +#define AO_USB_CONTROL_SIZE 32 +/* + * Double buffer IN and OUT EPs, so each + * gets half of the available space + * + * Ah, but USB bulk packets can only come in 8, 16, 32 and 64 + * byte sizes, so we'll use 64 for everything + */ +#define AO_USB_IN_SIZE 64 +#define AO_USB_OUT_SIZE 64 + +#define AO_USB_EP0_IDLE 0 +#define AO_USB_EP0_DATA_IN 1 +#define AO_USB_EP0_DATA_OUT 2 + +#define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) + +/* CDC definitions */ +#define CS_INTERFACE 0x24 +#define CS_ENDPOINT 0x25 + +#define SET_LINE_CODING 0x20 +#define GET_LINE_CODING 0x21 +#define SET_CONTROL_LINE_STATE 0x22 + +/* Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */ +struct ao_usb_line_coding { + uint32_t rate; + uint8_t char_format; + uint8_t parity; + uint8_t data_bits; +} ; + +#endif /* _AO_USB_H_ */ diff --git a/src/avr/ao_usb_avr.c b/src/avr/ao_usb_avr.c new file mode 100644 index 00000000..74bdea23 --- /dev/null +++ b/src/avr/ao_usb_avr.c @@ -0,0 +1,688 @@ +/* + * 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_usb.h" + +#define USB_DEBUG 0 + +#if USB_DEBUG +#define debug(format, args...) printf(format, ## args) +#else +#define debug(format, args...) +#endif + +struct ao_task __xdata ao_usb_task; + +struct ao_usb_setup { + uint8_t dir_type_recip; + uint8_t request; + uint16_t value; + uint16_t index; + uint16_t length; +} __xdata ao_usb_setup; + +static __xdata uint8_t ao_usb_ep0_state; +static const uint8_t * __xdata ao_usb_ep0_in_data; +static __xdata uint8_t ao_usb_ep0_in_len; +static __xdata uint8_t ao_usb_ep0_in_pending; +static __xdata uint8_t ao_usb_addr_pending; +static __xdata uint8_t ao_usb_ep0_in_buf[2]; +static __xdata uint8_t ao_usb_ep0_out_len; +static __xdata uint8_t *__xdata ao_usb_ep0_out_data; + +static __xdata uint8_t ao_usb_in_flushed; +static __xdata uint8_t ao_usb_running; +static __xdata uint8_t ao_usb_configuration; +static __xdata uint8_t ueienx_0; + +void +ao_usb_set_address(uint8_t address) +{ + UDADDR = (0 << ADDEN) | address; + ao_usb_addr_pending = 1; +} + +#define EP_SIZE(s) ((s) == 64 ? 0x30 : \ + ((s) == 32 ? 0x20 : \ + ((s) == 16 ? 0x10 : \ + 0x00))) + +static void +ao_usb_dump_ep(uint8_t ep) +{ + UENUM = ep; + debug ("EP %d: UECONX %02x UECFG0X %02x UECFG1X %02x UEIENX %02x UESTA0X %02x UESTA1X %02X\n", + ep, UECONX, UECFG0X, UECFG1X, UEIENX, UESTA0X, UESTA1X); +} + +static void +ao_usb_set_ep0(void) +{ + debug ("set_ep0\n"); + /* Set the CONTROL max packet size, single buffered */ + UENUM = 0; + UECONX = (1 << EPEN); /* Enable */ + + UECFG0X = ((0 << EPTYPE0) | /* Control */ + (0 << EPDIR)); /* Out (ish) */ + + UECFG1X = (EP_SIZE(AO_USB_CONTROL_SIZE) | /* Size */ + (0 << EPBK0) | /* Single bank */ + (1 << ALLOC)); + + ueienx_0 = ((1 << RXSTPE) | /* Enable SETUP interrupt */ + (1 << RXOUTE)); /* Enable OUT interrupt */ + +// ao_usb_dump_ep(0); + ao_usb_addr_pending = 0; +} + +static void +ao_usb_set_configuration(void) +{ + /* Set the IN max packet size, double buffered */ + UENUM = AO_USB_IN_EP; + UECONX = (1 << EPEN); /* Enable */ + + UECFG0X = ((2 << EPTYPE0) | /* Bulk */ + (1 << EPDIR)); /* In */ + + UECFG1X = (EP_SIZE(AO_USB_IN_SIZE) | /* Size */ + (1 << EPBK0) | /* Double bank */ + (1 << ALLOC)); /* Allocate */ + +#if 0 + UEIENX = ((1 << TXINE)); /* Enable IN complete interrupt */ +#endif + + ao_usb_dump_ep(AO_USB_IN_EP); + + /* Set the OUT max packet size, double buffered */ + UENUM = AO_USB_OUT_EP; + UECONX |= (1 << EPEN); /* Enable */ + + UECFG0X = ((2 << EPTYPE0) | /* Bulk */ + (0 << EPDIR)); /* Out */ + + UECFG1X = (EP_SIZE(AO_USB_OUT_SIZE) | /* Size */ + (1 << EPBK0) | /* Double bank */ + (1 << ALLOC)); /* Allocate */ + + UEIENX = ((1 << RXOUTE)); /* Enable OUT complete interrupt */ + + ao_usb_dump_ep(AO_USB_OUT_EP); + ao_usb_running = 1; +} + +ISR(USB_GEN_vect) +{ + ao_wakeup(&ao_usb_task); +} + + +__xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8}; + +/* Walk through the list of descriptors and find a match + */ +static void +ao_usb_get_descriptor(uint16_t value) +{ + const uint8_t *__xdata descriptor; + __xdata uint8_t type = value >> 8; + __xdata uint8_t index = value; + + descriptor = ao_usb_descriptors; + while (descriptor[0] != 0) { + if (descriptor[1] == type && index-- == 0) { + if (type == AO_USB_DESC_CONFIGURATION) + ao_usb_ep0_in_len = descriptor[2]; + else + ao_usb_ep0_in_len = descriptor[0]; + ao_usb_ep0_in_data = descriptor; + break; + } + descriptor += descriptor[0]; + } +} + +static void +ao_usb_ep0_set_in_pending(uint8_t in_pending) +{ + ao_usb_ep0_in_pending = in_pending; + + if (in_pending) + ueienx_0 = ((1 << RXSTPE) | (1 << RXOUTE) | (1 << TXINE)); /* Enable IN interrupt */ +} + +/* Send an IN data packet */ +static void +ao_usb_ep0_flush(void) +{ + __xdata uint8_t this_len; + + cli(); + UENUM = 0; + if (!(UEINTX & (1 << TXINI))) { + debug("EP0 not accepting IN data\n"); + ao_usb_ep0_set_in_pending(1); + } else { + this_len = ao_usb_ep0_in_len; + if (this_len > AO_USB_CONTROL_SIZE) + this_len = AO_USB_CONTROL_SIZE; + + ao_usb_ep0_in_len -= this_len; + + /* Set IN interrupt enable */ + if (ao_usb_ep0_in_len == 0 && this_len != AO_USB_CONTROL_SIZE) + ao_usb_ep0_set_in_pending(0); + else + ao_usb_ep0_set_in_pending(1); + + debug ("Flush EP0 len %d:", this_len); + while (this_len--) { + uint8_t c = *ao_usb_ep0_in_data++; + debug(" %02x", c); + UEDATX = c; + } + debug ("\n"); + + /* Clear the TXINI bit to send the packet */ + UEINTX &= ~(1 << TXINI); + } + sei(); +} + +/* Read data from the ep0 OUT fifo */ +static void +ao_usb_ep0_fill(uint8_t len, uint8_t ack) +{ + if (len > ao_usb_ep0_out_len) + len = ao_usb_ep0_out_len; + ao_usb_ep0_out_len -= len; + +// debug ("EP0 UEINTX %02x UEBCLX %d UEBCHX %d\n", +// UEINTX, UEBCLX, UEBCHX); + /* Pull all of the data out of the packet */ + debug ("Fill EP0 len %d:", len); + UENUM = 0; + while (len--) { + uint8_t c = UEDATX; + *ao_usb_ep0_out_data++ = c; + debug (" %02x", c); + } + debug ("\n"); + + /* ACK the packet */ + UEINTX &= ~ack; +} + +void +ao_usb_ep0_queue_byte(uint8_t a) +{ + ao_usb_ep0_in_buf[ao_usb_ep0_in_len++] = a; +} + +static void +ao_usb_ep0_setup(void) +{ + /* Pull the setup packet out of the fifo */ + ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_setup; + ao_usb_ep0_out_len = 8; + ao_usb_ep0_fill(8, (1 << RXSTPI) | (1 << RXOUTI) | (1 << TXINI)); + if (ao_usb_ep0_out_len != 0) { + debug ("invalid setup packet length\n"); + 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; + } +/* + UENUM = 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) { + case AO_USB_TYPE_STANDARD: + debug ("Standard setup packet\n"); + switch(ao_usb_setup.dir_type_recip & AO_USB_SETUP_RECIP_MASK) { + case AO_USB_RECIP_DEVICE: + debug ("Device setup packet\n"); + switch(ao_usb_setup.request) { + case AO_USB_REQ_GET_STATUS: + debug ("get status\n"); + ao_usb_ep0_queue_byte(0); + ao_usb_ep0_queue_byte(0); + break; + case AO_USB_REQ_SET_ADDRESS: + debug ("set address %d\n", ao_usb_setup.value); + ao_usb_set_address(ao_usb_setup.value); + break; + case AO_USB_REQ_GET_DESCRIPTOR: + debug ("get descriptor %d\n", ao_usb_setup.value); + ao_usb_get_descriptor(ao_usb_setup.value); + break; + case AO_USB_REQ_GET_CONFIGURATION: + debug ("get configuration %d\n", ao_usb_configuration); + ao_usb_ep0_queue_byte(ao_usb_configuration); + break; + case AO_USB_REQ_SET_CONFIGURATION: + ao_usb_configuration = ao_usb_setup.value; + debug ("set configuration %d\n", ao_usb_configuration); + ao_usb_set_configuration(); + break; + } + break; + case AO_USB_RECIP_INTERFACE: +#ifndef AVR + #pragma disable_warning 110 +#endif + debug ("Interface setup packet\n"); + switch(ao_usb_setup.request) { + case AO_USB_REQ_GET_STATUS: + ao_usb_ep0_queue_byte(0); + ao_usb_ep0_queue_byte(0); + break; + case AO_USB_REQ_GET_INTERFACE: + ao_usb_ep0_queue_byte(0); + break; + case AO_USB_REQ_SET_INTERFACE: + break; + } + break; + case AO_USB_RECIP_ENDPOINT: + debug ("Endpoint setup packet\n"); + switch(ao_usb_setup.request) { + case AO_USB_REQ_GET_STATUS: + ao_usb_ep0_queue_byte(0); + ao_usb_ep0_queue_byte(0); + break; + } + break; + } + break; + case AO_USB_TYPE_CLASS: + debug ("Class setup packet\n"); + switch (ao_usb_setup.request) { + case SET_LINE_CODING: + debug ("set line coding\n"); + ao_usb_ep0_out_len = 7; + ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_line_coding; + break; + case GET_LINE_CODING: + debug ("get line coding\n"); + ao_usb_ep0_in_len = 7; + ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding; + break; + case SET_CONTROL_LINE_STATE: + break; + } + break; + } + if (ao_usb_ep0_state != AO_USB_EP0_DATA_OUT) { + if (ao_usb_setup.length < ao_usb_ep0_in_len) + ao_usb_ep0_in_len = ao_usb_setup.length; + debug ("Start ep0 in delivery %d\n", ao_usb_ep0_in_len); + ao_usb_ep0_set_in_pending(1); + } +} + +/* End point 0 receives all of the control messages. */ +static void +ao_usb_ep0(void) +{ + uint8_t intx, udint; + + debug ("usb task started\n"); + ao_usb_ep0_state = AO_USB_EP0_IDLE; + for (;;) { + cli(); + for (;;) { + udint = UDINT; + UDINT = 0; +// debug ("UDINT %02x\n", udint); + if (udint & (1 << EORSTI)) { + ao_usb_configuration = 0; + ao_usb_set_ep0(); + } + UENUM = 0; + intx = UEINTX; +// debug ("UEINTX %02x\n", intx); + if (intx & ((1 << RXSTPI) | (1 << RXOUTI))) + break; + if ((intx & (1 << TXINI))) { + if (ao_usb_ep0_in_pending) + break; + else + { + if (ao_usb_addr_pending) { + UDADDR |= (1 << ADDEN); + ao_usb_addr_pending = 0; + } + ueienx_0 = ((1 << RXSTPE) | (1 << RXOUTE)); /* Disable IN interrupt */ + } + } +// debug ("usb task sleeping...\n"); + UENUM = 0; + UEIENX = ueienx_0; + ao_sleep(&ao_usb_task); + } + sei(); +// debug ("UEINTX for ep0 is %02x\n", intx); + if (intx & (1 << RXSTPI)) { + ao_usb_ep0_setup(); + } + if (intx & (1 << RXOUTI)) { + ao_usb_ep0_fill(UEBCLX, (1 << RXOUTI)); + ao_usb_ep0_set_in_pending(1); + } + if (intx & (1 << TXINI) && ao_usb_ep0_in_pending) { + debug ("continue sending ep0 IN data\n"); + ao_usb_ep0_flush(); + } + } +} + +/* Wait for a free IN buffer */ +static void +ao_usb_in_wait(void) +{ + for (;;) { + /* Check if the current buffer is writable */ + UENUM = AO_USB_IN_EP; + if (UEINTX & (1 << RWAL)) + break; + + cli(); + /* Wait for an IN buffer to be ready */ + for (;;) { + UENUM = AO_USB_IN_EP; + if ((UEINTX & (1 << TXINI))) + break; + UEIENX = (1 << TXINE); + ao_sleep(&ao_usb_in_flushed); + } + /* Ack the interrupt */ + UEINTX &= ~(1 << TXINI); + sei(); + } +} + +/* Queue the current IN buffer for transmission */ +static void +ao_usb_in_send(void) +{ + UENUM = AO_USB_IN_EP; + UEINTX &= ~(1 << FIFOCON); +} + +void +ao_usb_flush(void) __critical +{ + if (!ao_usb_running) + return; + + /* Anytime we've sent a character since + * the last time we flushed, we'll need + * to send a packet -- the only other time + * we would send a packet is when that + * packet was full, in which case we now + * want to send an empty packet + */ + if (!ao_usb_in_flushed) { + ao_usb_in_flushed = 1; + ao_usb_in_wait(); + ao_usb_in_send(); + } +} + +void +ao_usb_putchar(char c) __critical __reentrant +{ + if (!ao_usb_running) + return; + + ao_usb_in_wait(); + + /* Queue a byte */ + UENUM = AO_USB_IN_EP; + UEDATX = c; + + /* Send the packet when full */ + if ((UEINTX & (1 << RWAL)) == 0) + ao_usb_in_send(); + ao_usb_in_flushed = 0; +} + +static char +_ao_usb_pollchar(void) +{ + char c; + uint8_t intx; + + if (!ao_usb_running) + return AO_READ_AGAIN; + + for (;;) { + UENUM = AO_USB_OUT_EP; + intx = UEINTX; + debug("usb_pollchar UEINTX %02d\n", intx); + if (intx & (1 << RWAL)) + break; + + if (intx & (1 << FIFOCON)) { + /* Ack the last packet */ + UEINTX = (uint8_t) ~(1 << FIFOCON); + } + + /* Check to see if a packet has arrived */ + if ((intx & (1 << RXOUTI)) == 0) { + UENUM = AO_USB_OUT_EP; + UEIENX = (1 << RXOUTE); + return AO_READ_AGAIN; + } + + /* Ack the interrupt */ + UEINTX = ~(1 << RXOUTI); + } + + /* Pull a character out of the fifo */ + c = UEDATX; + return c; +} + +char +ao_usb_pollchar(void) +{ + char c; + cli(); + c = _ao_usb_pollchar(); + sei(); + return c; +} + +char +ao_usb_getchar(void) __critical +{ + char c; + + cli(); + while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN) + ao_sleep(&ao_stdin_ready); + sei(); + return c; +} + +uint16_t control_count; +uint16_t in_count; +uint16_t out_count; + +/* Endpoint interrupt */ +ISR(USB_COM_vect) +{ + uint8_t old_num = UENUM; + uint8_t i = UEINT; + +#ifdef AO_LED_RED + ao_led_toggle(AO_LED_RED); +#endif + UEINT = 0; + if (i & (1 << 0)) { + UENUM = 0; + UEIENX = 0; + ao_wakeup(&ao_usb_task); + ++control_count; + } + if (i & (1 << AO_USB_IN_EP)) { + UENUM = AO_USB_IN_EP; + UEIENX = 0; + ao_wakeup(&ao_usb_in_flushed); + in_count++; + } + if (i & (1 << AO_USB_OUT_EP)) { + UENUM = AO_USB_OUT_EP; + UEIENX = 0; + ao_wakeup(&ao_stdin_ready); + ++out_count; + } + UENUM = old_num; +} + +#if AVR_VCC_5V +#define AO_PAD_REGULATOR_INIT (1 << UVREGE) /* Turn on pad regulator */ +#endif +#if AVR_VCC_3V3 +/* TeleScience V0.1 has a hardware bug -- UVcc is hooked up, but UCap is not + * Make this work by running power through UVcc to the USB system + */ +#define AO_PAD_REGULATOR_INIT (1 << UVREGE) /* Turn off pad regulator */ +#endif + +#if AVR_CLOCK == 16000000UL +#define AO_USB_PLL_INPUT_PRESCALER (1 << PINDIV) /* Divide 16MHz clock by 2 */ +#endif +#if AVR_CLOCK == 8000000UL +#define AO_USB_PLL_INPUT_PRESCALER 0 /* Don't divide clock */ +#endif + +void +ao_usb_disable(void) +{ + /* Unplug from the bus */ + UDCON = (1 << DETACH); + + /* Disable the interface */ + USBCON = 0; + + /* Disable the PLL */ + PLLCSR = 0; + + /* Turn off the pad regulator */ + UHWCON = 0; +} + +#define AO_USB_CON ((1 << USBE) | /* USB enable */ \ + (0 << RSTCPU) | /* do not reset CPU */ \ + (0 << LSM) | /* Full speed mode */ \ + (0 << RMWKUP)) /* no remote wake-up */ \ + +void +ao_usb_enable(void) +{ + /* Configure pad regulator */ + UHWCON = AO_PAD_REGULATOR_INIT; + + /* Enable USB device, but freeze the clocks until initialized */ + USBCON = AO_USB_CON | (1 <stack_count = stack_len; \ + stack_ptr = (uint8_t __data *) AO_STACK_START; \ + save_ptr = (uint8_t __xdata *) ao_cur_task->stack; \ + do \ + *save_ptr++ = *stack_ptr++; \ + while (--stack_len); \ + } +#define ao_arch_isr_stack() \ + /* Empty the stack; might as well let interrupts have the whole thing */ \ + (SP = AO_STACK_START - 1) + +#define ao_arch_cpu_idle() (PCON = PCON_IDLE) + +#define ao_arch_restore_stack() { \ + uint8_t stack_len; \ + __data uint8_t *stack_ptr; \ + __xdata uint8_t *save_ptr; \ + \ + /* Restore the old stack */ \ + stack_len = ao_cur_task->stack_count; \ + SP = AO_STACK_START - 1 + stack_len; \ + \ + stack_ptr = (uint8_t __data *) AO_STACK_START; \ + save_ptr = (uint8_t __xdata *) ao_cur_task->stack; \ + do \ + *stack_ptr++ = *save_ptr++; \ + while (--stack_len); \ + \ + _asm \ + pop _bp \ + pop PSW \ + pop ar1 \ + pop ar0 \ + pop ar7 \ + pop ar6 \ + pop ar5 \ + pop ar4 \ + pop ar3 \ + pop ar2 \ + pop b \ + pop DPH \ + pop DPL \ + /* The next byte of the stack is the IE register. Only the global \ + enable bit forms part of the task context. Pop off the IE then set \ + the global enable bit to match that of the stored IE register. */ \ + pop ACC \ + JB ACC.7,0098$ \ + CLR _EA \ + LJMP 0099$ \ + 0098$: \ + SETB _EA \ + 0099$: \ + /* Finally pop off the ACC, which was the first register saved. */ \ + pop ACC \ + ret \ + _endasm; \ +} + +#define ao_arch_critical(b) __critical { b } #endif /* _AO_ARCH_H_ */ diff --git a/src/core/ao.h b/src/core/ao.h index 9b0bb545..98a01a4a 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -37,9 +37,9 @@ struct ao_task { __xdata void *wchan; /* current wait channel (NULL if running) */ uint16_t alarm; /* abort ao_sleep time */ - uint8_t stack_count; /* amount of saved stack */ uint8_t task_id; /* unique id */ __code char *name; /* task name */ + ao_arch_task_members /* any architecture-specific fields */ uint8_t stack[AO_STACK_SIZE]; /* saved stack */ }; @@ -321,6 +321,10 @@ ao_usb_disable(void); void ao_usb_init(void); +#if HAS_USB +extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; +#endif + /* * ao_cmd.c */ @@ -1571,4 +1575,9 @@ extern __xdata uint16_t ao_companion_data[AO_COMPANION_MAX_CHANNELS]; void ao_companion_init(void); +/* ao_lcd.c */ + +void +ao_lcd_init(void); + #endif /* _AO_H_ */ diff --git a/src/core/ao_panic.c b/src/core/ao_panic.c index cbfdf399..0668dad2 100644 --- a/src/core/ao_panic.c +++ b/src/core/ao_panic.c @@ -53,7 +53,7 @@ ao_panic(uint8_t reason) } ao_beep(AO_BEEP_OFF); ao_panic_delay(2); -#pragma disable_warning 126 + for (n = 0; n < reason; n++) { ao_led_on(AO_LED_RED); ao_beep(AO_BEEP_MID); diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 41520476..32826114 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -24,6 +24,10 @@ __data uint8_t ao_num_tasks; __data uint8_t ao_cur_task_index; __xdata struct ao_task *__data ao_cur_task; +#ifdef ao_arch_task_globals +ao_arch_task_globals +#endif + void ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant { @@ -53,27 +57,16 @@ ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *nam void ao_yield(void) ao_arch_naked_define { - ao_arch_save_context(); + ao_arch_save_regs(); if (ao_cur_task_index == AO_NO_TASK_INDEX) ao_cur_task_index = ao_num_tasks-1; else { - uint8_t stack_len; - __data uint8_t *stack_ptr; - __xdata uint8_t *save_ptr; - /* Save the current stack */ - stack_len = SP - (AO_STACK_START - 1); - ao_cur_task->stack_count = stack_len; - stack_ptr = (uint8_t __data *) AO_STACK_START; - save_ptr = (uint8_t __xdata *) ao_cur_task->stack; - do - *save_ptr++ = *stack_ptr++; - while (--stack_len); + ao_arch_save_stack(); } - /* Empty the stack; might as well let interrupts have the whole thing */ - SP = AO_STACK_START - 1; + ao_arch_isr_stack(); /* Find a task to run. If there isn't any runnable task, * this loop will run forever, which is just fine @@ -99,63 +92,20 @@ ao_yield(void) ao_arch_naked_define } /* Enter lower power mode when there isn't anything to do */ - if (ao_next_task_index == ao_cur_task_index) - PCON = PCON_IDLE; + if (ao_next_task_index == ao_cur_task_index) { + ao_arch_cpu_idle(); + } } } - - { - uint8_t stack_len; - __data uint8_t *stack_ptr; - __xdata uint8_t *save_ptr; - - /* Restore the old stack */ - stack_len = ao_cur_task->stack_count; - SP = AO_STACK_START - 1 + stack_len; - - stack_ptr = (uint8_t __data *) AO_STACK_START; - save_ptr = (uint8_t __xdata *) ao_cur_task->stack; - do - *stack_ptr++ = *save_ptr++; - while (--stack_len); - } - - _asm - pop _bp - pop PSW - pop ar1 - pop ar0 - pop ar7 - pop ar6 - pop ar5 - pop ar4 - pop ar3 - pop ar2 - pop b - pop DPH - pop DPL - /* The next byte of the stack is the IE register. Only the global - enable bit forms part of the task context. Pop off the IE then set - the global enable bit to match that of the stored IE register. */ - pop ACC - JB ACC.7,0098$ - CLR _EA - LJMP 0099$ - 0098$: - SETB _EA - 0099$: - /* Finally pop off the ACC, which was the first register saved. */ - pop ACC - ret - _endasm; + ao_arch_restore_stack(); } uint8_t ao_sleep(__xdata void *wchan) { - __critical { + ao_arch_critical( ao_cur_task->wchan = wchan; - } + ); ao_yield(); ao_cur_task->alarm = 0; if (ao_cur_task->wchan) { @@ -186,14 +136,16 @@ ao_alarm(uint16_t delay) } void -ao_exit(void) __critical +ao_exit(void) { - uint8_t i; - ao_num_tasks--; - for (i = ao_cur_task_index; i < ao_num_tasks; i++) - ao_tasks[i] = ao_tasks[i+1]; - ao_cur_task_index = AO_NO_TASK_INDEX; - ao_yield(); + ao_arch_critical( + uint8_t i; + ao_num_tasks--; + for (i = ao_cur_task_index; i < ao_num_tasks; i++) + ao_tasks[i] = ao_tasks[i+1]; + ao_cur_task_index = AO_NO_TASK_INDEX; + ao_yield(); + ); /* we'll never get back here */ } @@ -201,16 +153,13 @@ void ao_task_info(void) { uint8_t i; - uint8_t pc_loc; __xdata struct ao_task *task; for (i = 0; i < ao_num_tasks; i++) { task = ao_tasks[i]; - pc_loc = task->stack_count - 17; - printf("%12s: wchan %04x pc %04x\n", + printf("%12s: wchan %04x\n", task->name, - (int16_t) task->wchan, - (task->stack[pc_loc]) | (task->stack[pc_loc+1] << 8)); + (int16_t) task->wchan); } } -- cgit v1.2.3 From c32893ce79835a8f861d6ef414644c2ff9769ff6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 26 Aug 2011 15:02:43 -0700 Subject: altos: Integrate telescience support Adds a few drivers including an LCD driver Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/avr/ao_adc_avr.c | 129 +++++++++++++++++++ src/avr/ao_arch.h | 9 ++ src/avr/ao_spi_slave.c | 142 +++++++++++++++++++++ src/avr/ao_spi_usart.c | 112 +++++++++++++++++ src/cc1111/ao_arch.h | 12 ++ src/core/ao.h | 40 ++++-- src/core/ao_log_telescience.c | 274 ++++++++++++++++++++++++++++++++++++++++ src/core/ao_panic.c | 4 + src/drivers/ao_companion.c | 2 +- src/drivers/ao_lcd.c | 281 ++++++++++++++++++++++++++++++++++++++++++ src/drivers/ao_m25.c | 2 + src/product/ao_telescience.c | 39 ++++++ src/telescience-v0.1/Makefile | 109 ++++++++++++++++ src/util/check-avr-mem | 9 ++ 15 files changed, 1153 insertions(+), 13 deletions(-) create mode 100644 src/avr/ao_adc_avr.c create mode 100644 src/avr/ao_spi_slave.c create mode 100644 src/avr/ao_spi_usart.c create mode 100644 src/core/ao_log_telescience.c create mode 100644 src/drivers/ao_lcd.c create mode 100644 src/product/ao_telescience.c create mode 100644 src/telescience-v0.1/Makefile create mode 100644 src/util/check-avr-mem (limited to 'src/avr') diff --git a/src/Makefile b/src/Makefile index 4e40c2bf..caa91e83 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,7 +18,7 @@ SUBDIRS=\ telemini-v1.0 telenano-v0.1 \ telebt-v0.0 telebt-v0.1 \ telemetrum-v0.1-sky telemetrum-v0.1-sirf \ - tidongle test + tidongle test telescience-v0.1 all: all-local all-recursive diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c new file mode 100644 index 00000000..5afced74 --- /dev/null +++ b/src/avr/ao_adc_avr.c @@ -0,0 +1,129 @@ +/* + * 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" + +volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING]; +volatile __data uint8_t ao_adc_head; + +const uint8_t adc_channels[AO_LOG_TELESCIENCE_NUM_ADC] = { + 0x00, + 0x01, + 0x04, + 0x05, + 0x06, + 0x07, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, +}; + +static uint8_t ao_adc_channel; + +#define ADC_CHANNEL_LOW(c) (((c) & 0x1f) << MUX0) +#define ADC_CHANNEL_HIGH(c) ((((c) & 0x20) >> 5) << MUX5) + +#define ADCSRA_INIT ((1 << ADEN) | /* Enable ADC */ \ + (0 << ADATE) | /* No auto ADC trigger */ \ + (1 << ADIF) | /* Clear interrupt */ \ + (0 << ADIE) | /* Enable interrupt */ \ + (6 << ADPS0)) /* Prescale clock by 64 */ + +#define ADCSRB_INIT ((0 << ADHSM) | /* No high-speed mode */ \ + (0 << ACME) | /* Some comparitor thing */ \ + (2 << ADTS0)) /* Free running mode (don't care) */ + +static void +ao_adc_start(void) +{ + uint8_t channel = adc_channels[ao_adc_channel]; + ADMUX = ((0 << REFS1) | /* AVcc reference */ + (1 << REFS0) | /* AVcc reference */ + (1 << ADLAR) | /* Left-shift results */ + (ADC_CHANNEL_LOW(channel))); /* Select channel */ + + ADCSRB = (ADCSRB_INIT | + ADC_CHANNEL_HIGH(channel)); /* High channel bit */ + + ADCSRA = (ADCSRA_INIT | + (1 << ADSC) | + (1 << ADIE)); /* Start conversion */ +} + +ISR(ADC_vect) +{ + uint16_t value; + + /* Must read ADCL first or the value there will be lost */ + value = ADCL; + value |= (ADCH << 8); + ao_adc_ring[ao_adc_head].adc[ao_adc_channel] = value; + if (++ao_adc_channel < AO_TELESCIENCE_NUM_ADC) + ao_adc_start(); + else { + ADCSRA = ADCSRA_INIT; + ao_adc_ring[ao_adc_head].tick = ao_time(); + ao_adc_head = ao_adc_ring_next(ao_adc_head); + ao_wakeup((void *) &ao_adc_head); + ao_cpu_sleep_disable = 0; + } +} + +void +ao_adc_poll(void) +{ + ao_cpu_sleep_disable = 1; + ao_adc_channel = 0; + ao_adc_start(); +} + +void +ao_adc_get(__xdata struct ao_adc *packet) +{ + uint8_t i = ao_adc_ring_prev(ao_adc_head); + memcpy(packet, (void *) &ao_adc_ring[i], sizeof (struct ao_adc)); +} + +static void +ao_adc_dump(void) __reentrant +{ + static __xdata struct ao_adc packet; + uint8_t i; + ao_adc_get(&packet); + printf("tick: %5u", packet.tick); + for (i = 0; i < AO_TELESCIENCE_NUM_ADC; i++) + printf (" %2d: %5u", i, packet.adc[i]); + printf ("\n"); +} + +__code struct ao_cmds ao_adc_cmds[] = { + { ao_adc_dump, "a\0Display current ADC values" }, + { 0, NULL }, +}; + +void +ao_adc_init(void) +{ + DIDR0 = 0xf3; + DIDR2 = 0x3f; + ADCSRB = ADCSRB_INIT; + ADCSRA = ADCSRA_INIT; + ao_cmd_register(&ao_adc_cmds[0]); +} diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index 0ed97361..c695a725 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -145,5 +145,14 @@ extern uint8_t ao_cpu_sleep_disable; #define ao_arch_critical(b) do { cli(); b; sei(); } while (0) +#define AO_TELESCIENCE_NUM_ADC 12 + +struct ao_adc { + uint16_t tick; /* tick when the sample was read */ + uint16_t adc[AO_TELESCIENCE_NUM_ADC]; /* samples */ +}; + +#define AO_ADC_RING 16 + #endif /* _AO_ARCH_H_ */ diff --git a/src/avr/ao_spi_slave.c b/src/avr/ao_spi_slave.c new file mode 100644 index 00000000..4dde09f3 --- /dev/null +++ b/src/avr/ao_spi_slave.c @@ -0,0 +1,142 @@ +/* + * 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_product.h" + +struct ao_companion_command ao_companion_command; + +static const struct ao_companion_setup ao_telescience_setup = { + .board_id = AO_idProduct_NUMBER, + .board_id_inverse = ~AO_idProduct_NUMBER, + .update_period = 50, + .channels = AO_LOG_TELESCIENCE_NUM_ADC, +}; + +static uint8_t +ao_spi_read(uint8_t *buf, uint8_t len) +{ + while (len--) { + while (!(SPSR & (1 << SPIF))) + if ((PINB & (1 << PINB0))) + return 0; + *buf++ = SPDR; + } + return 1; +} + +static void +ao_spi_write(uint8_t *buf, uint8_t len) +{ + while (len--) { + SPDR = *buf++; + while (!(SPSR & (1 << SPIF))) + if ((PINB & (1 << PINB0))) + return; + } + /* Clear pending SPIF bit by reading */ + (void) SPDR; +} + +static uint8_t ao_spi_slave_recv(void) +{ + if (!ao_spi_read((uint8_t *) &ao_companion_command, + sizeof (ao_companion_command))) + return 0; + + /* Figure out the outbound data */ + switch (ao_companion_command.command) { + case AO_COMPANION_SETUP: + ao_spi_write((uint8_t *) &ao_telescience_setup, + sizeof (ao_telescience_setup)); + break; + case AO_COMPANION_FETCH: + ao_spi_write((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, + AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); + break; + case AO_COMPANION_NOTIFY: + break; + default: + return 0; + } + + ao_log_store.tm_tick = ao_companion_command.tick; + if (ao_log_store.tm_state != ao_companion_command.flight_state) { + ao_log_store.tm_state = ao_companion_command.flight_state; + return 1; + } + return 0; +} + +static uint8_t ao_spi_slave_running; + +ISR(PCINT0_vect) +{ + if ((PINB & (1 << PINB0)) == 0) { + if (!ao_spi_slave_running) { + uint8_t changed; + ao_spi_slave_running = 1; + cli(); + changed = ao_spi_slave_recv(); + sei(); + if (changed && ao_flight_boost <= ao_log_store.tm_state) { + if (ao_log_store.tm_state < ao_flight_landed) + ao_log_start(); + else + ao_log_stop(); + } + } + } else { + ao_spi_slave_running = 0; + } +} + +void ao_spi_slave_debug(void) { + printf ("slave running %d\n", ao_spi_slave_running); +} + +void +ao_spi_slave_init(void) +{ + PCMSK0 |= (1 << PCINT0); /* Enable PCINT0 pin change */ + PCICR |= (1 << PCIE0); /* Enable pin change interrupt */ + + DDRB = ((DDRB & 0xf0) | + (1 << 3) | /* MISO, output */ + (0 << 2) | /* MOSI, input */ + (0 << 1) | /* SCK, input */ + (0 << 0)); /* SS, input */ + + /* We'd like to have a pull-up on SS so that disconnecting the + * TM would cause any SPI transaction to abort. However, when + * I tried that, SPI transactions would spontaneously abort, + * making me assume that we needed a less aggressive pull-up + * than is offered inside the AVR + */ + PORTB = ((PORTB & 0xf0) | + (1 << 3) | /* MISO, output */ + (0 << 2) | /* MOSI, no pull-up */ + (0 << 1) | /* SCK, no pull-up */ + (0 << 0)); /* SS, no pull-up */ + + SPCR = (0 << SPIE) | /* Disable SPI interrupts */ + (1 << SPE) | /* Enable SPI */ + (0 << DORD) | /* MSB first */ + (0 << MSTR) | /* Slave mode */ + (0 << CPOL) | /* Clock low when idle */ + (0 << CPHA); /* Sample at leading clock edge */ +} diff --git a/src/avr/ao_spi_usart.c b/src/avr/ao_spi_usart.c new file mode 100644 index 00000000..6ed708ff --- /dev/null +++ b/src/avr/ao_spi_usart.c @@ -0,0 +1,112 @@ +/* + * 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" + +/* + * Atmega32u4 USART in MSPIM (master SPI mode) + */ + +__xdata uint8_t ao_spi_mutex; + +/* Send bytes over SPI. + * + * This just polls; the SPI is set to go as fast as possible, + * so using interrupts would take way too long + */ +void +ao_spi_send(void __xdata *block, uint16_t len) __reentrant +{ + uint8_t *d = block; + + ao_mutex_get(&ao_spi_mutex); + while (len--) { + while (!(UCSR1A & (1 << UDRE1))); + UDR1 = *d++; + while (!(UCSR1A & (1 << RXC1))); + (void) UDR1; + } + ao_mutex_put(&ao_spi_mutex); +} + +/* Receive bytes over SPI. + * + * This sets up tow DMA engines, one reading the data and another + * writing constant values to the SPI transmitter as that is what + * clocks the data coming in. + */ +void +ao_spi_recv(void __xdata *block, uint16_t len) __reentrant +{ + uint8_t *d = block; + + ao_mutex_get(&ao_spi_mutex); + while (len--) { + while (!(UCSR1A & (1 << UDRE1))); + UDR1 = 0; + while (!(UCSR1A & (1 << RXC1))); + *d++ = UDR1; + } + ao_mutex_put(&ao_spi_mutex); +} + +/* + * Initialize USART0 for SPI using config alt 2 + * + * MO P1_5 + * MI P1_4 + * CLK P1_3 + * + * Chip select is the responsibility of the caller + */ + +#define XCK1_DDR DDRD +#define XCK1_PORT PORTD +#define XCK1 PORTD5 +#define XMS1_DDR DDRE +#define XMS1_PORT PORTE +#define XMS1 PORTE6 + +void +ao_spi_init(void) +{ + /* Ensure the USART is powered */ + PRR1 &= ~(1 << PRUSART1); + + /* + * Set pin directions + */ + XCK1_DDR |= (1 << XCK1); + + /* Clear chip select (which is negated) */ + XMS1_PORT |= (1 < XMS1); + XMS1_DDR |= (1 << XMS1); + + /* Set baud register to zero (required before turning transmitter on) */ + UBRR1 = 0; + + UCSR1C = ((0x3 << UMSEL10) | /* Master SPI mode */ + (0 << UCSZ10) | /* SPI mode 0 */ + (0 << UCPOL1)); /* SPI mode 0 */ + + /* Enable transmitter and receiver */ + UCSR1B = ((1 << RXEN1) | + (1 << TXEN1)); + + /* It says that 0 is a legal value; we'll see... */ + UBRR1 = 0; +} diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index c4972819..8a41791f 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -192,4 +192,16 @@ extern __code __at (0x00a6) uint32_t ao_radio_cal; #define ao_arch_critical(b) __critical { b } +struct ao_adc { + uint16_t tick; /* tick when the sample was read */ + int16_t accel; /* accelerometer */ + int16_t pres; /* pressure sensor */ + int16_t temp; /* temperature sensor */ + int16_t v_batt; /* battery voltage */ + int16_t sense_d; /* drogue continuity sense */ + int16_t sense_m; /* main continuity sense */ +}; + +#define AO_ADC_RING 32 + #endif /* _AO_ARCH_H_ */ diff --git a/src/core/ao.h b/src/core/ao.h index 98a01a4a..05f056fd 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -144,15 +144,6 @@ ao_clock_init(void); /* * One set of samples read from the A/D converter or telemetry */ -struct ao_adc { - uint16_t tick; /* tick when the sample was read */ - int16_t accel; /* accelerometer */ - int16_t pres; /* pressure sensor */ - int16_t temp; /* temperature sensor */ - int16_t v_batt; /* battery voltage */ - int16_t sense_d; /* drogue continuity sense */ - int16_t sense_m; /* main continuity sense */ -}; #if HAS_ADC @@ -160,7 +151,6 @@ struct ao_adc { * ao_adc.c */ -#define AO_ADC_RING 32 #define ao_adc_ring_next(n) (((n) + 1) & (AO_ADC_RING - 1)) #define ao_adc_ring_prev(n) (((n) - 1) & (AO_ADC_RING - 1)) @@ -505,6 +495,23 @@ extern __pdata uint32_t ao_log_start_pos; extern __xdata uint8_t ao_log_running; extern __pdata enum flight_state ao_log_state; +#define AO_LOG_TELESCIENCE_START ((uint8_t) 's') +#define AO_LOG_TELESCIENCE_DATA ((uint8_t) 'd') + +#define AO_LOG_TELESCIENCE_NUM_ADC 12 + +struct ao_log_telescience { + uint8_t type; + uint8_t csum; + uint16_t tick; + uint16_t tm_tick; + uint8_t tm_state; + uint8_t unused; + uint16_t adc[AO_LOG_TELESCIENCE_NUM_ADC]; +}; + +extern struct ao_log_telescience ao_log_store; + /* required functions from the underlying log system */ #define AO_LOG_FORMAT_UNKNOWN 0 /* unknown; altosui will have to guess */ @@ -970,6 +977,16 @@ ao_spi_recv(void __xdata *block, uint16_t len) __reentrant; void ao_spi_init(void); +/* + * ao_spi_slave.c + */ + +void +ao_spi_slave_debug(void); + +void +ao_spi_slave_init(void); + /* * ao_telemetry.c */ @@ -1568,8 +1585,9 @@ struct ao_companion_setup { }; extern __pdata uint8_t ao_companion_running; -extern __xdata struct ao_companion_setup ao_companion_setup; extern __xdata uint8_t ao_companion_mutex; +extern __xdata struct ao_companion_command ao_companion_command; +extern __xdata struct ao_companion_setup ao_companion_setup; extern __xdata uint16_t ao_companion_data[AO_COMPANION_MAX_CHANNELS]; void diff --git a/src/core/ao_log_telescience.c b/src/core/ao_log_telescience.c new file mode 100644 index 00000000..aac780fa --- /dev/null +++ b/src/core/ao_log_telescience.c @@ -0,0 +1,274 @@ +/* + * 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_product.h" + +static struct ao_task ao_log_task; +//static struct ao_task ao_spi_task; + +uint8_t ao_log_running; +uint8_t ao_log_mutex; +uint32_t ao_log_start_pos; +uint32_t ao_log_end_pos; +uint32_t ao_log_current_pos; + +#define AO_LOG_TELESCIENCE_START ((uint8_t) 's') +#define AO_LOG_TELESCIENCE_DATA ((uint8_t) 'd') + +struct ao_log_telescience ao_log_store; +struct ao_log_telescience ao_log_fetch; + +static uint8_t ao_log_adc_pos; + +__code uint8_t ao_log_format = AO_LOG_FORMAT_TELESCIENCE; + +static uint8_t +ao_log_csum(__xdata uint8_t *b) __reentrant +{ + uint8_t sum = 0x5a; + uint8_t i; + + for (i = 0; i < sizeof (struct ao_log_telescience); i++) + sum += *b++; + return -sum; +} + +static uint8_t +ao_log_telescience_write(void) +{ + uint8_t wrote = 0; + + ao_log_store.csum = 0; + ao_log_store.csum = ao_log_csum((__xdata uint8_t *) &ao_log_store); + ao_mutex_get(&ao_log_mutex); { + if (ao_log_current_pos >= ao_log_end_pos && ao_log_running) + ao_log_stop(); + if (ao_log_running) { + wrote = 1; + ao_storage_write(ao_log_current_pos, + (__xdata uint8_t *) &ao_log_store, + sizeof (struct ao_log_telescience)); + ao_log_current_pos += sizeof (struct ao_log_telescience); + } + } ao_mutex_put(&ao_log_mutex); + return wrote; +} + +static uint8_t +ao_log_valid(struct ao_log_telescience *log) +{ + uint8_t *d; + uint8_t i; + d = (uint8_t *) log; + for (i = 0; i < sizeof (struct ao_log_telescience); i++) + if (d[i] != 0xff) + return 1; + return 0; +} + +static uint8_t +ao_log_telescience_read(uint32_t pos) +{ + if (!ao_storage_read(pos, &ao_log_fetch, sizeof (struct ao_log_telescience))) + return 0; + return ao_log_valid(&ao_log_fetch); +} + +void +ao_log_start(void) +{ + if (!ao_log_running) { + ao_log_running = 1; + ao_wakeup(&ao_log_running); + } +} + +void +ao_log_stop(void) +{ + if (ao_log_running) { + ao_log_running = 0; + } +} + +void +ao_log_restart(void) +{ + /* Find end of data */ + ao_log_end_pos = ao_storage_config; + for (ao_log_current_pos = 0; + ao_log_current_pos < ao_storage_config; + ao_log_current_pos += ao_storage_block) + { + if (!ao_log_telescience_read(ao_log_current_pos)) + break; + } + if (ao_log_current_pos > 0) { + ao_log_current_pos -= ao_storage_block; + for (; ao_log_current_pos < ao_storage_config; + ao_log_current_pos += sizeof (struct ao_log_telescience)) + { + if (!ao_log_telescience_read(ao_log_current_pos)) + break; + } + } +} + +void +ao_log_telescience(void) +{ + ao_storage_setup(); + + /* This can take a while, so let the rest + * of the system finish booting before we start + */ + ao_delay(AO_SEC_TO_TICKS(10)); + + ao_log_restart(); + for (;;) { + while (!ao_log_running) + ao_sleep(&ao_log_running); + + ao_log_start_pos = ao_log_current_pos; + ao_log_store.type = AO_LOG_TELESCIENCE_START; + ao_log_store.tick = ao_time(); + ao_log_store.adc[0] = ao_companion_command.serial; + ao_log_store.adc[1] = ao_companion_command.flight; + ao_log_telescience_write(); + /* Write the whole contents of the ring to the log + * when starting up. + */ + ao_log_adc_pos = ao_adc_ring_next(ao_adc_head); + ao_log_store.type = AO_LOG_TELESCIENCE_DATA; + while (ao_log_running) { + /* Write samples to EEPROM */ + while (ao_log_adc_pos != ao_adc_head) { + ao_log_store.tick = ao_adc_ring[ao_log_adc_pos].tick; + memcpy(&ao_log_store.adc, (void *) ao_adc_ring[ao_log_adc_pos].adc, + AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); + ao_log_telescience_write(); + ao_log_adc_pos = ao_adc_ring_next(ao_log_adc_pos); + } + /* Wait for more ADC data to arrive */ + ao_sleep((void *) &ao_adc_head); + } + memset(&ao_log_store.adc, '\0', sizeof (ao_log_store.adc)); + } +} + +void +ao_log_set(void) +{ + printf("Logging currently %s\n", ao_log_running ? "on" : "off"); + ao_cmd_hex(); + if (ao_cmd_status == ao_cmd_success) { + if (ao_cmd_lex_i) { + printf("Logging from %ld to %ld\n", ao_log_current_pos, ao_log_end_pos); + ao_log_start(); + } else { + printf ("Log stopped at %ld\n", ao_log_current_pos); + ao_log_stop(); + } + } + ao_cmd_status = ao_cmd_success; +} + +void +ao_log_list(void) +{ + uint32_t pos; + uint32_t start = 0; + uint8_t flight = 0; + + for (pos = 0; ; pos += sizeof (struct ao_log_telescience)) { + if (pos >= ao_storage_config || + !ao_log_telescience_read(pos) || + ao_log_fetch.type == AO_LOG_TELESCIENCE_START) + { + if (pos != start) { + printf("flight %d start %x end %x\n", + flight, + (uint16_t) (start >> 8), + (uint16_t) ((pos + 0xff) >> 8)); flush(); + } + if (ao_log_fetch.type != AO_LOG_TELESCIENCE_START) + break; + start = pos; + flight++; + } + } + printf ("done\n"); +} + +void +ao_log_delete(void) +{ + uint32_t pos; + + ao_cmd_hex(); + if (ao_cmd_status != ao_cmd_success) + return; + if (ao_cmd_lex_i != 1) { + ao_cmd_status = ao_cmd_syntax_error; + printf("No such flight: %d\n", ao_cmd_lex_i); + return; + } + ao_log_stop(); + for (pos = 0; pos < ao_storage_config; pos += ao_storage_block) { + if (!ao_log_telescience_read(pos)) + break; + ao_storage_erase(pos); + } + ao_log_current_pos = ao_log_start_pos = 0; + if (pos == 0) + printf("No such flight: %d\n", ao_cmd_lex_i); + else + printf ("Erased\n"); +} + +static void +ao_log_query(void) +{ + printf("Logging enabled: %d\n", ao_log_running); + printf("Log start: %ld\n", ao_log_start_pos); + printf("Log cur: %ld\n", ao_log_current_pos); + printf("Log end: %ld\n", ao_log_end_pos); + printf("log data tick: %04x\n", ao_log_store.tick); + printf("TM data tick: %04x\n", ao_log_store.tm_tick); + printf("TM state: %d\n", ao_log_store.tm_state); + printf("TM serial: %d\n", ao_companion_command.serial); + printf("TM flight: %d\n", ao_companion_command.flight); +} + +const struct ao_cmds ao_log_cmds[] = { + { ao_log_set, "L <0 off, 1 on>\0Set logging mode" }, + { ao_log_list, "l\0List stored flight logs" }, + { ao_log_delete, "d 1\0Delete all stored flights" }, + { ao_log_query, "q\0Query log status" }, + { 0, NULL }, +}; + +void +ao_log_init(void) +{ + ao_log_running = 0; + + ao_cmd_register(&ao_log_cmds[0]); + + ao_add_task(&ao_log_task, ao_log_telescience, "log"); +} diff --git a/src/core/ao_panic.c b/src/core/ao_panic.c index 0668dad2..b6ff65cc 100644 --- a/src/core/ao_panic.c +++ b/src/core/ao_panic.c @@ -24,6 +24,10 @@ #if !HAS_BEEP #define ao_beep(x) #endif +#if !LEDS_AVAILABLE +#define ao_led_on(x) +#define ao_led_off(x) +#endif static void ao_panic_delay(uint8_t n) diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index 4c8f4269..2e587f8e 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -30,7 +30,7 @@ #define COMPANION_SELECT() do { ao_spi_get_bit(COMPANION_CS); ao_spi_slow(); } while (0) #define COMPANION_DESELECT() do { ao_spi_fast(); ao_spi_put_bit(COMPANION_CS); } while (0) -static __xdata struct ao_companion_command ao_companion_command; +__xdata struct ao_companion_command ao_companion_command; __xdata struct ao_companion_setup ao_companion_setup; __xdata uint16_t ao_companion_data[AO_COMPANION_MAX_CHANNELS]; diff --git a/src/drivers/ao_lcd.c b/src/drivers/ao_lcd.c new file mode 100644 index 00000000..5bc89bbd --- /dev/null +++ b/src/drivers/ao_lcd.c @@ -0,0 +1,281 @@ +/* + * 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" + +#define LCD_PORT PORTB +#define LCD_DDR DDRB + +#define PIN_RS 4 +#define PIN_E 5 +#define PIN_RW 6 + +void +ao_lcd_set_bits(uint8_t bits) +{ +#if 0 + printf("\tLCD data %x RS %d R/W %d E %d\n", + bits & 0xf, + (bits & (1 << PIN_RS)) ? 1 : 0, + (bits & (1 << PIN_RW)) ? 1 : 0, + (bits & (1 << PIN_E)) ? 1 : 0); +#endif + LCD_PORT = bits; +#if 0 + ao_delay(1); + if (bits & (1 << PIN_RW)) + printf("\tLCD input %x\n", PINB); +#endif +} + +uint8_t +ao_lcd_get_nibble(uint8_t rs) +{ + uint8_t data = (rs ? (1 << PIN_RS) : 0) | (1 << PIN_RW); + uint8_t n; + + DDRB = (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); + ao_lcd_set_bits(data); + ao_lcd_set_bits(data | (1 << PIN_E)); + n = PINB & 0xf; + ao_lcd_set_bits(data); + return n; +} + +uint8_t +ao_lcd_get_status(void) +{ + uint8_t high, low; + uint8_t data; + + high = ao_lcd_get_nibble(0); + low = ao_lcd_get_nibble(0); + data = (high << 4) | low; + printf ("\tLCD status %02x\n", data); + return data; +} + +uint8_t +ao_lcd_get_data(void) +{ + uint8_t high, low; + uint8_t data; + + high = ao_lcd_get_nibble(1); + low = ao_lcd_get_nibble(1); + data = (high << 4) | low; + printf ("\tLCD data %02x\n", data); + return data; +} + +void +ao_lcd_wait_idle(void) +{ + uint8_t status; + uint8_t count = 0; + + do { + status = ao_lcd_get_status(); + count++; + if (count > 100) { + printf("idle timeout\n"); + break; + } + } while (0); /* status & 0x80); */ +} + +void +ao_lcd_send_nibble(uint8_t rs, uint8_t data) +{ + data = (data & 0xf) | (rs ? (1 << PIN_RS) : 0); + DDRB = (0xf) | (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); + ao_lcd_set_bits(data); + ao_lcd_set_bits(data | (1 << PIN_E)); + ao_lcd_set_bits(data); +} + +static uint16_t ao_lcd_time = 3; + +void +ao_lcd_delay(void) +{ + volatile uint16_t count; + + for (count = 0; count < ao_lcd_time; count++) + ; +} + +void +ao_lcd_send_ins(uint8_t data) +{ +// printf("send ins %02x\n", data); +// ao_lcd_wait_idle(); +// ao_delay(1); + ao_lcd_delay(); + ao_lcd_send_nibble(0, data >> 4); + ao_lcd_send_nibble(0, data & 0xf); +} + +void +ao_lcd_send_data(uint8_t data) +{ +// printf ("send data %02x\n", data); +// ao_lcd_wait_idle(); + ao_lcd_delay(); + ao_lcd_send_nibble(1, data >> 4); + ao_lcd_send_nibble(1, data & 0x0f); +} + +void +ao_lcd_send_string(char *string) +{ + uint8_t c; + + while ((c = (uint8_t) *string++)) + ao_lcd_send_data(c); +} + +#define AO_LCD_POWER_CONTROL 0x54 + +void +ao_lcd_contrast_set(uint8_t contrast) +{ + ao_lcd_send_ins(AO_LCD_POWER_CONTROL | ((contrast >> 4) & 0x3)); + ao_lcd_send_ins(0x70 | (contrast & 0xf)); +} + +void +ao_lcd_clear(void) +{ + ao_lcd_send_ins(0x01); + ao_delay(1); + /* Entry mode */ + ao_lcd_send_ins(0x04 | 0x02); +} + +void +ao_lcd_start(void) +{ + /* get to 4bit mode */ + ao_lcd_send_nibble(0, 0x3); + ao_lcd_send_nibble(0, 0x3); + ao_lcd_send_nibble(0, 0x3); + ao_lcd_send_nibble(0, 0x2); + + /* function set */ + ao_lcd_send_ins(0x28); + /* function set, instruction table 1 */ + ao_lcd_send_ins(0x29); + + /* freq set */ + ao_lcd_send_ins(0x14); + + /* Power/icon/contrast control*/ + ao_lcd_send_ins(AO_LCD_POWER_CONTROL); + + /* Follower control */ + ao_lcd_send_ins(0x6d); + ao_delay(AO_MS_TO_TICKS(200)); + + /* contrast set */ + ao_lcd_contrast_set(0x18); + + /* Display on */ + ao_lcd_send_ins(0x08 | 0x04); + + /* Clear */ + ao_lcd_clear(); + +} + +void +ao_lcd_contrast(void) +{ + ao_cmd_hex(); + if (ao_cmd_status == ao_cmd_success) { + printf("setting contrast to %02x\n", ao_cmd_lex_i); + ao_lcd_contrast_set(ao_cmd_lex_i & 0x3f); + } +} + +static uint8_t +ao_cmd_hex_nibble(void) +{ + if ('0' <= ao_cmd_lex_c && ao_cmd_lex_c <= '9') + return ao_cmd_lex_c - '0'; + if ('a' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'f') + return ao_cmd_lex_c - ('a' - 10); + if ('A' <= ao_cmd_lex_c && ao_cmd_lex_c <= 'F') + return ao_cmd_lex_c - ('A' - 10); + ao_cmd_status = ao_cmd_syntax_error; + return 0; +} + +void +ao_lcd_string(void) +{ + uint8_t col = 0; + uint8_t c; + + ao_cmd_decimal(); + if (ao_cmd_status != ao_cmd_success) + return; + ao_lcd_send_ins(0x80 | (ao_cmd_lex_i ? 0x40 : 0x00)); + ao_cmd_white(); + while (ao_cmd_lex_c != '\n') { + c = ao_cmd_lex_c; + if (c == '\\') { + ao_cmd_lex(); + c = ao_cmd_hex_nibble() << 4; + ao_cmd_lex(); + c |= ao_cmd_hex_nibble(); + } + ao_lcd_send_data(c); + ao_cmd_lex(); + col++; + } + while (col < 16) { + ao_lcd_send_data(' '); + col++; + } +} + +void +ao_lcd_delay_set(void) +{ + ao_cmd_decimal(); + if (ao_cmd_status == ao_cmd_success) { + printf("setting LCD delay to %d\n", ao_cmd_lex_i); + ao_lcd_time = ao_cmd_lex_i; + } +} + +__code struct ao_cmds ao_lcd_cmds[] = { + { ao_lcd_start, "S\0Start LCD" }, + { ao_lcd_contrast, "C \0Set LCD contrast" }, + { ao_lcd_string, "s \0Send string to LCD" }, + { ao_lcd_delay_set, "t \0Set LCD delay" }, + { 0, NULL }, +}; + +void +ao_lcd_init(void) +{ + DDRB = (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); + PORTB = 0; + ao_cmd_register(&ao_lcd_cmds[0]); +} diff --git a/src/drivers/ao_m25.c b/src/drivers/ao_m25.c index d7208273..28cb1dd7 100644 --- a/src/drivers/ao_m25.c +++ b/src/drivers/ao_m25.c @@ -376,5 +376,7 @@ ao_storage_device_init(void) /* Set up chip select wires */ SPI_CS_PORT |= M25_CS_MASK; /* raise all CS pins */ SPI_CS_DIR |= M25_CS_MASK; /* set CS pins as outputs */ +#ifdef SPI_CS_SEL SPI_CS_SEL &= ~M25_CS_MASK; /* set CS pins as GPIO */ +#endif } diff --git a/src/product/ao_telescience.c b/src/product/ao_telescience.c new file mode 100644 index 00000000..4dec3a18 --- /dev/null +++ b/src/product/ao_telescience.c @@ -0,0 +1,39 @@ +/* + * 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" + +int +main(void) +{ + ao_clock_init(); + + PORTE |= (1 << 6); + DDRE |= (1 << 6); + + ao_avr_stdio_init(); + ao_timer_init(); + ao_cmd_init(); + ao_spi_init(); + ao_spi_slave_init(); + ao_storage_init(); + ao_usb_init(); + ao_adc_init(); + ao_log_init(); + ao_start_scheduler(); + return 0; +} diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile new file mode 100644 index 00000000..3ccbb787 --- /dev/null +++ b/src/telescience-v0.1/Makefile @@ -0,0 +1,109 @@ +# +# AltOS build +# +# +vpath % ..:../core:../product:../drivers:../avr +vpath ao-make-product.5c ../util + +MCU=atmega32u4 +DUDECPUTYPE=m32u4 +#PROGRAMMER=stk500v2 -P usb +PROGRAMMER=usbtiny +LOADCMD=avrdude +LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: +CC=avr-gcc +OBJCOPY=avr-objcopy + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_usb.h \ + ao_pins.h \ + altitude.h + +# +# Common AltOS sources +# +TELESCIENCE_STORAGE= \ + ao_m25.c \ + ao_spi_usart.c \ + ao_storage.c \ + +ALTOS_SRC = \ + ao_cmd.c \ + ao_mutex.c \ + ao_panic.c \ + ao_product.c \ + ao_stdio.c \ + ao_task.c \ + ao_timer.c \ + ao_led.c \ + ao_avr_stdio.c \ + ao_romconfig.c \ + ao_usb_avr.c \ + ao_adc_avr.c \ + ao_spi_slave.c \ + ao_log_telescience.c \ + $(TELESCIENCE_STORAGE) + +PRODUCT=TeleScience-v0.1 +MCU=atmega32u4 +PRODUCT_DEF=-DTELESCIENCE +IDPRODUCT=0x0011 +CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I.. +CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR + +NICKLE=nickle + +PROG=telescience-v0.1 + +SRC=$(ALTOS_SRC) ao_telescience.c +OBJ=$(SRC:.c=.o) + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: $(PROG) + +CHECK=sh ../util/check-avr-mem + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) + $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) + +$(PROG).hex: $(PROG) + avr-size $(PROG) + $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ + + +load: $(PROG).hex + $(LOADCMD) $(LOADARG)$(PROG).hex + +../altitude.h: make-altitude + nickle $< > $@ + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +ao_product.rel: ao_product.c ao_product.h + $(call quiet,CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"ao_product.h\"' -o$@ $< + +distclean: clean + +clean: + rm -f $(OBJ) + rm -f ao_product.h + +install: + +uninstall: + +$(OBJ): ao.h ao_product.h ao_usb.h diff --git a/src/util/check-avr-mem b/src/util/check-avr-mem new file mode 100644 index 00000000..c73edbd1 --- /dev/null +++ b/src/util/check-avr-mem @@ -0,0 +1,9 @@ +#!/bin/sh +nm "$@" | +grep ' N _end' | +awk '{ iram = strtonum("0x" $1) % 0x10000; +if ( iram > 0xaff) { + printf ("%d bytes of ram more than %d available\n", iram, 0xaff); + exit(1); +} else + exit(0); }' -- cgit v1.2.3 From b33a92e372327158ab21c1bb2d091c58761efe10 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 27 Aug 2011 15:19:43 -0700 Subject: altos: Share log code between telescience and telebt. Add telebt log Telescience and telebt both log data in 32-byte chunks, so share some code which manages that between the two products. Add simple telemetry logging to telebt. Signed-off-by: Keith Packard --- src/avr/ao_spi_slave.c | 14 +-- src/core/ao.h | 97 +++++++++++++++---- src/core/ao_log_telem.c | 48 +++++++++- src/core/ao_log_telescience.c | 211 ++++++------------------------------------ src/core/ao_monitor.c | 10 +- src/product/ao_telebt.c | 3 + src/product/ao_telescience.c | 2 +- src/telebt-v0.1/Makefile | 1 + src/telescience-v0.1/Makefile | 1 + 9 files changed, 164 insertions(+), 223 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_spi_slave.c b/src/avr/ao_spi_slave.c index 4dde09f3..e4d866a8 100644 --- a/src/avr/ao_spi_slave.c +++ b/src/avr/ao_spi_slave.c @@ -74,9 +74,9 @@ static uint8_t ao_spi_slave_recv(void) return 0; } - ao_log_store.tm_tick = ao_companion_command.tick; - if (ao_log_store.tm_state != ao_companion_command.flight_state) { - ao_log_store.tm_state = ao_companion_command.flight_state; + ao_log_single_write_data.telescience.tm_tick = ao_companion_command.tick; + if (ao_log_single_write_data.telescience.tm_state != ao_companion_command.flight_state) { + ao_log_single_write_data.telescience.tm_state = ao_companion_command.flight_state; return 1; } return 0; @@ -93,11 +93,11 @@ ISR(PCINT0_vect) cli(); changed = ao_spi_slave_recv(); sei(); - if (changed && ao_flight_boost <= ao_log_store.tm_state) { - if (ao_log_store.tm_state < ao_flight_landed) - ao_log_start(); + if (changed && ao_flight_boost <= ao_log_single_write_data.telescience.tm_state) { + if (ao_log_single_write_data.telescience.tm_state < ao_flight_landed) + ao_log_single_start(); else - ao_log_stop(); + ao_log_single_stop(); } } } else { diff --git a/src/core/ao.h b/src/core/ao.h index a5bbb6f1..8b978272 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -505,23 +505,6 @@ extern __pdata uint32_t ao_log_start_pos; extern __xdata uint8_t ao_log_running; extern __pdata enum flight_state ao_log_state; -#define AO_LOG_TELESCIENCE_START ((uint8_t) 's') -#define AO_LOG_TELESCIENCE_DATA ((uint8_t) 'd') - -#define AO_LOG_TELESCIENCE_NUM_ADC 12 - -struct ao_log_telescience { - uint8_t type; - uint8_t csum; - uint16_t tick; - uint16_t tm_tick; - uint8_t tm_state; - uint8_t unused; - uint16_t adc[AO_LOG_TELESCIENCE_NUM_ADC]; -}; - -extern struct ao_log_telescience ao_log_store; - /* required functions from the underlying log system */ #define AO_LOG_FORMAT_UNKNOWN 0 /* unknown; altosui will have to guess */ @@ -1365,6 +1348,20 @@ ao_radio_init(void); extern const char const * const ao_state_names[]; +#define AO_MONITOR_RING 8 + +union ao_monitor { + struct ao_telemetry_raw_recv raw; + struct ao_telemetry_orig_recv orig; + struct ao_telemetry_tiny_recv tiny; +}; + +extern __xdata union ao_monitor ao_monitor_ring[AO_MONITOR_RING]; + +#define ao_monitor_ring_next(n) (((n) + 1) & (AO_MONITOR_RING - 1)) + +extern __data uint8_t ao_monitor_head; + void ao_monitor(void); @@ -1724,4 +1721,70 @@ struct ao_launch_query { void ao_launch_init(void); +/* + * ao_log_single.c + */ + +#define AO_LOG_TELESCIENCE_START ((uint8_t) 's') +#define AO_LOG_TELESCIENCE_DATA ((uint8_t) 'd') + +#define AO_LOG_TELESCIENCE_NUM_ADC 12 + +struct ao_log_telescience { + uint8_t type; + uint8_t csum; + uint16_t tick; + uint16_t tm_tick; + uint8_t tm_state; + uint8_t unused; + uint16_t adc[AO_LOG_TELESCIENCE_NUM_ADC]; +}; + +#define AO_LOG_SINGLE_SIZE 32 + +union ao_log_single { + struct ao_log_telescience telescience; + union ao_telemetry_all telemetry; + uint8_t bytes[AO_LOG_SINGLE_SIZE]; +}; + +extern __xdata union ao_log_single ao_log_single_write_data; +extern __xdata union ao_log_single ao_log_single_read_data; + +void +ao_log_single_extra_query(void); + +void +ao_log_single_list(void); + +void +ao_log_single_main(void); + +uint8_t +ao_log_single_write(void); + +uint8_t +ao_log_single_read(uint32_t pos); + +void +ao_log_single_start(void); + +void +ao_log_single_stop(void); + +void +ao_log_single_restart(void); + +void +ao_log_single_set(void); + +void +ao_log_single_delete(void); + +void +ao_log_single_init(void); + +void +ao_log_single(void); + #endif /* _AO_H_ */ diff --git a/src/core/ao_log_telem.c b/src/core/ao_log_telem.c index 1b472efe..34abe879 100644 --- a/src/core/ao_log_telem.c +++ b/src/core/ao_log_telem.c @@ -17,14 +17,52 @@ #include "ao.h" +__code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMETRY; + +static __data uint8_t ao_log_monitor_pos; + +void +ao_log_single(void) +{ + ao_storage_setup(); + + /* This can take a while, so let the rest + * of the system finish booting before we start + */ + ao_delay(AO_SEC_TO_TICKS(2)); + + ao_log_single_restart(); + for (;;) { + while (!ao_log_running) + ao_sleep(&ao_log_running); + + ao_log_monitor_pos = ao_monitor_head; + while (ao_log_running) { + /* Write samples to EEPROM */ + while (ao_log_monitor_pos != ao_monitor_head) { + memcpy(&ao_log_single_write_data.telemetry, + &ao_monitor_ring[ao_log_monitor_pos], + AO_LOG_SINGLE_SIZE); + ao_log_single_write(); + ao_log_monitor_pos = ao_monitor_ring_next(ao_log_monitor_pos); + } + /* Wait for more ADC data to arrive */ + ao_sleep(DATA_TO_XDATA(&ao_monitor_head)); + } + } +} + void -ao_log_write_erase(uint8_t pos) +ao_log_single_list(void) { - (void) pos; + if (ao_log_current_pos != 0) + printf("flight 1 start %x end %x\n", + 0, + (uint16_t) ((ao_log_current_pos + 0xff) >> 8)); + printf ("done\n"); } -uint8_t -ao_log_present(void) +void +ao_log_single_extra_query(void) { - return 0; } diff --git a/src/core/ao_log_telescience.c b/src/core/ao_log_telescience.c index aac780fa..31eda381 100644 --- a/src/core/ao_log_telescience.c +++ b/src/core/ao_log_telescience.c @@ -18,119 +18,25 @@ #include "ao.h" #include "ao_product.h" -static struct ao_task ao_log_task; -//static struct ao_task ao_spi_task; - -uint8_t ao_log_running; -uint8_t ao_log_mutex; -uint32_t ao_log_start_pos; -uint32_t ao_log_end_pos; -uint32_t ao_log_current_pos; - -#define AO_LOG_TELESCIENCE_START ((uint8_t) 's') -#define AO_LOG_TELESCIENCE_DATA ((uint8_t) 'd') - -struct ao_log_telescience ao_log_store; -struct ao_log_telescience ao_log_fetch; - static uint8_t ao_log_adc_pos; __code uint8_t ao_log_format = AO_LOG_FORMAT_TELESCIENCE; -static uint8_t -ao_log_csum(__xdata uint8_t *b) __reentrant +static void +ao_log_telescience_csum(void) __reentrant { + __xdata uint8_t *b = ao_log_single_write_data.bytes; uint8_t sum = 0x5a; uint8_t i; + ao_log_single_write_data.telescience.csum = 0; for (i = 0; i < sizeof (struct ao_log_telescience); i++) sum += *b++; - return -sum; -} - -static uint8_t -ao_log_telescience_write(void) -{ - uint8_t wrote = 0; - - ao_log_store.csum = 0; - ao_log_store.csum = ao_log_csum((__xdata uint8_t *) &ao_log_store); - ao_mutex_get(&ao_log_mutex); { - if (ao_log_current_pos >= ao_log_end_pos && ao_log_running) - ao_log_stop(); - if (ao_log_running) { - wrote = 1; - ao_storage_write(ao_log_current_pos, - (__xdata uint8_t *) &ao_log_store, - sizeof (struct ao_log_telescience)); - ao_log_current_pos += sizeof (struct ao_log_telescience); - } - } ao_mutex_put(&ao_log_mutex); - return wrote; -} - -static uint8_t -ao_log_valid(struct ao_log_telescience *log) -{ - uint8_t *d; - uint8_t i; - d = (uint8_t *) log; - for (i = 0; i < sizeof (struct ao_log_telescience); i++) - if (d[i] != 0xff) - return 1; - return 0; -} - -static uint8_t -ao_log_telescience_read(uint32_t pos) -{ - if (!ao_storage_read(pos, &ao_log_fetch, sizeof (struct ao_log_telescience))) - return 0; - return ao_log_valid(&ao_log_fetch); -} - -void -ao_log_start(void) -{ - if (!ao_log_running) { - ao_log_running = 1; - ao_wakeup(&ao_log_running); - } -} - -void -ao_log_stop(void) -{ - if (ao_log_running) { - ao_log_running = 0; - } -} - -void -ao_log_restart(void) -{ - /* Find end of data */ - ao_log_end_pos = ao_storage_config; - for (ao_log_current_pos = 0; - ao_log_current_pos < ao_storage_config; - ao_log_current_pos += ao_storage_block) - { - if (!ao_log_telescience_read(ao_log_current_pos)) - break; - } - if (ao_log_current_pos > 0) { - ao_log_current_pos -= ao_storage_block; - for (; ao_log_current_pos < ao_storage_config; - ao_log_current_pos += sizeof (struct ao_log_telescience)) - { - if (!ao_log_telescience_read(ao_log_current_pos)) - break; - } - } + ao_log_single_write_data.telescience.csum = -sum; } void -ao_log_telescience(void) +ao_log_single(void) { ao_storage_setup(); @@ -139,57 +45,42 @@ ao_log_telescience(void) */ ao_delay(AO_SEC_TO_TICKS(10)); - ao_log_restart(); + ao_log_single_restart(); for (;;) { while (!ao_log_running) ao_sleep(&ao_log_running); ao_log_start_pos = ao_log_current_pos; - ao_log_store.type = AO_LOG_TELESCIENCE_START; - ao_log_store.tick = ao_time(); - ao_log_store.adc[0] = ao_companion_command.serial; - ao_log_store.adc[1] = ao_companion_command.flight; - ao_log_telescience_write(); + ao_log_single_write_data.telescience.type = AO_LOG_TELESCIENCE_START; + ao_log_single_write_data.telescience.tick = ao_time(); + ao_log_single_write_data.telescience.adc[0] = ao_companion_command.serial; + ao_log_single_write_data.telescience.adc[1] = ao_companion_command.flight; + ao_log_telescience_csum(); + ao_log_single_write(); /* Write the whole contents of the ring to the log * when starting up. */ ao_log_adc_pos = ao_adc_ring_next(ao_adc_head); - ao_log_store.type = AO_LOG_TELESCIENCE_DATA; + ao_log_single_write_data.telescience.type = AO_LOG_TELESCIENCE_DATA; while (ao_log_running) { /* Write samples to EEPROM */ while (ao_log_adc_pos != ao_adc_head) { - ao_log_store.tick = ao_adc_ring[ao_log_adc_pos].tick; - memcpy(&ao_log_store.adc, (void *) ao_adc_ring[ao_log_adc_pos].adc, + ao_log_single_write_data.telescience.tick = ao_adc_ring[ao_log_adc_pos].tick; + memcpy(&ao_log_single_write_data.telescience.adc, (void *) ao_adc_ring[ao_log_adc_pos].adc, AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); - ao_log_telescience_write(); + ao_log_telescience_csum(); + ao_log_single_write(); ao_log_adc_pos = ao_adc_ring_next(ao_log_adc_pos); } /* Wait for more ADC data to arrive */ ao_sleep((void *) &ao_adc_head); } - memset(&ao_log_store.adc, '\0', sizeof (ao_log_store.adc)); + memset(&ao_log_single_write_data.telescience.adc, '\0', sizeof (ao_log_single_write_data.telescience.adc)); } } void -ao_log_set(void) -{ - printf("Logging currently %s\n", ao_log_running ? "on" : "off"); - ao_cmd_hex(); - if (ao_cmd_status == ao_cmd_success) { - if (ao_cmd_lex_i) { - printf("Logging from %ld to %ld\n", ao_log_current_pos, ao_log_end_pos); - ao_log_start(); - } else { - printf ("Log stopped at %ld\n", ao_log_current_pos); - ao_log_stop(); - } - } - ao_cmd_status = ao_cmd_success; -} - -void -ao_log_list(void) +ao_log_single_list(void) { uint32_t pos; uint32_t start = 0; @@ -197,8 +88,8 @@ ao_log_list(void) for (pos = 0; ; pos += sizeof (struct ao_log_telescience)) { if (pos >= ao_storage_config || - !ao_log_telescience_read(pos) || - ao_log_fetch.type == AO_LOG_TELESCIENCE_START) + !ao_log_single_read(pos) || + ao_log_single_read_data.telescience.type == AO_LOG_TELESCIENCE_START) { if (pos != start) { printf("flight %d start %x end %x\n", @@ -206,7 +97,7 @@ ao_log_list(void) (uint16_t) (start >> 8), (uint16_t) ((pos + 0xff) >> 8)); flush(); } - if (ao_log_fetch.type != AO_LOG_TELESCIENCE_START) + if (ao_log_single_read_data.telescience.type != AO_LOG_TELESCIENCE_START) break; start = pos; flight++; @@ -216,59 +107,11 @@ ao_log_list(void) } void -ao_log_delete(void) +ao_log_single_extra_query(void) { - uint32_t pos; - - ao_cmd_hex(); - if (ao_cmd_status != ao_cmd_success) - return; - if (ao_cmd_lex_i != 1) { - ao_cmd_status = ao_cmd_syntax_error; - printf("No such flight: %d\n", ao_cmd_lex_i); - return; - } - ao_log_stop(); - for (pos = 0; pos < ao_storage_config; pos += ao_storage_block) { - if (!ao_log_telescience_read(pos)) - break; - ao_storage_erase(pos); - } - ao_log_current_pos = ao_log_start_pos = 0; - if (pos == 0) - printf("No such flight: %d\n", ao_cmd_lex_i); - else - printf ("Erased\n"); -} - -static void -ao_log_query(void) -{ - printf("Logging enabled: %d\n", ao_log_running); - printf("Log start: %ld\n", ao_log_start_pos); - printf("Log cur: %ld\n", ao_log_current_pos); - printf("Log end: %ld\n", ao_log_end_pos); - printf("log data tick: %04x\n", ao_log_store.tick); - printf("TM data tick: %04x\n", ao_log_store.tm_tick); - printf("TM state: %d\n", ao_log_store.tm_state); + printf("log data tick: %04x\n", ao_log_single_write_data.telescience.tick); + printf("TM data tick: %04x\n", ao_log_single_write_data.telescience.tm_tick); + printf("TM state: %d\n", ao_log_single_write_data.telescience.tm_state); printf("TM serial: %d\n", ao_companion_command.serial); printf("TM flight: %d\n", ao_companion_command.flight); } - -const struct ao_cmds ao_log_cmds[] = { - { ao_log_set, "L <0 off, 1 on>\0Set logging mode" }, - { ao_log_list, "l\0List stored flight logs" }, - { ao_log_delete, "d 1\0Delete all stored flights" }, - { ao_log_query, "q\0Query log status" }, - { 0, NULL }, -}; - -void -ao_log_init(void) -{ - ao_log_running = 0; - - ao_cmd_register(&ao_log_cmds[0]); - - ao_add_task(&ao_log_task, ao_log_telescience, "log"); -} diff --git a/src/core/ao_monitor.c b/src/core/ao_monitor.c index 69eb58e8..6f2d9dbb 100644 --- a/src/core/ao_monitor.c +++ b/src/core/ao_monitor.c @@ -25,15 +25,7 @@ __xdata uint8_t ao_monitoring; __pdata uint8_t ao_monitor_led; -#define AO_MONITOR_RING 8 - -__xdata union ao_monitor { - struct ao_telemetry_raw_recv raw; - struct ao_telemetry_orig_recv orig; - struct ao_telemetry_tiny_recv tiny; -} ao_monitor_ring[AO_MONITOR_RING]; - -#define ao_monitor_ring_next(n) (((n) + 1) & (AO_MONITOR_RING - 1)) +__xdata union ao_monitor ao_monitor_ring[AO_MONITOR_RING]; __data uint8_t ao_monitor_head; diff --git a/src/product/ao_telebt.c b/src/product/ao_telebt.c index 5bbbf71b..cb23f391 100644 --- a/src/product/ao_telebt.c +++ b/src/product/ao_telebt.c @@ -42,6 +42,9 @@ main(void) ao_radio_init(); ao_packet_master_init(); ao_btm_init(); +#if HAS_LOG + ao_log_single_init(); +#endif #if HAS_DBG ao_dbg_init(); #endif diff --git a/src/product/ao_telescience.c b/src/product/ao_telescience.c index 4dec3a18..45b6d40e 100644 --- a/src/product/ao_telescience.c +++ b/src/product/ao_telescience.c @@ -33,7 +33,7 @@ main(void) ao_storage_init(); ao_usb_init(); ao_adc_init(); - ao_log_init(); + ao_log_single_init(); ao_start_scheduler(); return 0; } diff --git a/src/telebt-v0.1/Makefile b/src/telebt-v0.1/Makefile index a34e8912..01fbaf52 100644 --- a/src/telebt-v0.1/Makefile +++ b/src/telebt-v0.1/Makefile @@ -10,6 +10,7 @@ TELEBT_INC = \ TELEBT_SRC = \ ao_beep.c \ + ao_log_single.c \ ao_log_telem.c \ ao_spi.c \ ao_storage.c \ diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index 3ccbb787..282829e7 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -46,6 +46,7 @@ ALTOS_SRC = \ ao_usb_avr.c \ ao_adc_avr.c \ ao_spi_slave.c \ + ao_log_single.c \ ao_log_telescience.c \ $(TELESCIENCE_STORAGE) -- cgit v1.2.3 From b2d4e49bfe88aa61ca36fb1af8f3088c5754304c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 29 Aug 2011 14:22:19 -0700 Subject: altos: Split avr clock initialization to ao_clock.c This will be shared with the attiny code for TeleTerra v0.1 Signed-off-by: Keith Packard --- src/avr/ao_clock.c | 77 +++++++++++++++++++++++++++++++++++++++++++ src/avr/ao_timer.c | 58 -------------------------------- src/telescience-v0.1/Makefile | 1 + 3 files changed, 78 insertions(+), 58 deletions(-) create mode 100644 src/avr/ao_clock.c (limited to 'src/avr') diff --git a/src/avr/ao_clock.c b/src/avr/ao_clock.c new file mode 100644 index 00000000..0d42b6d5 --- /dev/null +++ b/src/avr/ao_clock.c @@ -0,0 +1,77 @@ +/* + * 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" + +/* + * AltOS always cranks the clock to the max frequency + */ + +void +ao_clock_init(void) +{ + /* disable RC clock */ + CLKSEL0 &= ~(1 << RCE); + + /* Disable PLL */ + PLLCSR &= ~(1 << PLLE); + + /* Enable external clock */ + CLKSEL0 |= (1 << EXTE); + + /* wait for external clock to be ready */ + while ((CLKSTA & (1 << EXTON)) == 0) + ; + + /* select external clock */ + CLKSEL0 |= (1 << CLKS); + + /* Disable the clock prescaler */ + cli(); + CLKPR = (1 << CLKPCE); + + /* Always run the system clock at 8MHz */ +#if AVR_CLOCK > 12000000UL + CLKPR = 1; +#else + CLKPR = 0; +#endif + sei(); + + /* Set up the PLL to use the crystal */ + + /* Use primary system clock as PLL source */ + PLLFRQ = ((0 << PINMUX) | /* Use primary clock */ + (0 << PLLUSB) | /* No divide by 2 for USB */ + (0 << PLLTM0) | /* Disable high speed timer */ + (0x4 << PDIV0)); /* 48MHz PLL clock */ + + /* Set the frequency of the crystal */ +#if AVR_CLOCK > 12000000UL + PLLCSR |= (1 << PINDIV); /* For 16MHz crystal on Teensy board */ +#else + PLLCSR &= ~(1 << PINDIV); /* For 8MHz crystal on TeleScience board */ +#endif + + /* Enable the PLL */ + PLLCSR |= (1 << PLLE); + while (!(PLLCSR & (1 << PLOCK))) + ; + + set_sleep_mode(SLEEP_MODE_IDLE); + sleep_enable(); +} diff --git a/src/avr/ao_timer.c b/src/avr/ao_timer.c index 1e374c75..eef14345 100644 --- a/src/avr/ao_timer.c +++ b/src/avr/ao_timer.c @@ -87,61 +87,3 @@ ao_timer_init(void) TIMSK1 = (1 << OCIE1A); /* Interrupt on compare match */ } - -/* - * AltOS always cranks the clock to the max frequency - */ -void -ao_clock_init(void) -{ - /* disable RC clock */ - CLKSEL0 &= ~(1 << RCE); - - /* Disable PLL */ - PLLCSR &= ~(1 << PLLE); - - /* Enable external clock */ - CLKSEL0 |= (1 << EXTE); - - /* wait for external clock to be ready */ - while ((CLKSTA & (1 << EXTON)) == 0) - ; - - /* select external clock */ - CLKSEL0 |= (1 << CLKS); - - /* Disable the clock prescaler */ - cli(); - CLKPR = (1 << CLKPCE); - - /* Always run the system clock at 8MHz */ -#if AVR_CLOCK > 12000000UL - CLKPR = 1; -#else - CLKPR = 0; -#endif - sei(); - - /* Set up the PLL to use the crystal */ - - /* Use primary system clock as PLL source */ - PLLFRQ = ((0 << PINMUX) | /* Use primary clock */ - (0 << PLLUSB) | /* No divide by 2 for USB */ - (0 << PLLTM0) | /* Disable high speed timer */ - (0x4 << PDIV0)); /* 48MHz PLL clock */ - - /* Set the frequency of the crystal */ -#if AVR_CLOCK > 12000000UL - PLLCSR |= (1 << PINDIV); /* For 16MHz crystal on Teensy board */ -#else - PLLCSR &= ~(1 << PINDIV); /* For 8MHz crystal on TeleScience board */ -#endif - - /* Enable the PLL */ - PLLCSR |= (1 << PLLE); - while (!(PLLCSR & (1 << PLOCK))) - ; - - set_sleep_mode(SLEEP_MODE_IDLE); - sleep_enable(); -} diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index 282829e7..28620242 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -33,6 +33,7 @@ TELESCIENCE_STORAGE= \ ao_storage.c \ ALTOS_SRC = \ + ao_clock.c \ ao_cmd.c \ ao_mutex.c \ ao_panic.c \ -- cgit v1.2.3 From abf17522c206b465375b73a004a6d67bfa714ba3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 21 Sep 2011 11:36:11 -0700 Subject: altos: SPI slave code is now per-product We can't write general purpose SPI slave code as we must eliminate any latency because the SPI ports have no buffering. Signed-off-by: Keith Packard --- src/avr/ao_pins.h | 7 +++ src/avr/ao_spi_slave.c | 99 +++++++++++++++--------------------------- src/core/ao.h | 13 +++++- src/drivers/ao_science_slave.c | 62 ++++++++++++++++++++++++++ src/telescience-v0.1/Makefile | 1 + 5 files changed, 118 insertions(+), 64 deletions(-) create mode 100644 src/drivers/ao_science_slave.c (limited to 'src/avr') diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index 56435f18..88f03829 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -52,6 +52,13 @@ #define SPI_CS_DIR DDRE #define M25_CS_MASK (1 << PORTE6) #define M25_MAX_CHIPS 1 + + #define SPI_SLAVE_CS_PORT PORTB + #define SPI_SLAVE_CS_PIN PINB + #define SPI_SLAVE_CS_PIN_NO PINB0 + + #define SPI_SLAVE_PIN_0_3 1 + #define SPI_SLAVE_PIN_2_5 0 #endif #endif /* _AO_PINS_H_ */ diff --git a/src/avr/ao_spi_slave.c b/src/avr/ao_spi_slave.c index e4d866a8..76f574c6 100644 --- a/src/avr/ao_spi_slave.c +++ b/src/avr/ao_spi_slave.c @@ -16,18 +16,8 @@ */ #include "ao.h" -#include "ao_product.h" -struct ao_companion_command ao_companion_command; - -static const struct ao_companion_setup ao_telescience_setup = { - .board_id = AO_idProduct_NUMBER, - .board_id_inverse = ~AO_idProduct_NUMBER, - .update_period = 50, - .channels = AO_LOG_TELESCIENCE_NUM_ADC, -}; - -static uint8_t +uint8_t ao_spi_read(uint8_t *buf, uint8_t len) { while (len--) { @@ -39,7 +29,7 @@ ao_spi_read(uint8_t *buf, uint8_t len) return 1; } -static void +void ao_spi_write(uint8_t *buf, uint8_t len) { while (len--) { @@ -52,66 +42,38 @@ ao_spi_write(uint8_t *buf, uint8_t len) (void) SPDR; } -static uint8_t ao_spi_slave_recv(void) -{ - if (!ao_spi_read((uint8_t *) &ao_companion_command, - sizeof (ao_companion_command))) - return 0; - - /* Figure out the outbound data */ - switch (ao_companion_command.command) { - case AO_COMPANION_SETUP: - ao_spi_write((uint8_t *) &ao_telescience_setup, - sizeof (ao_telescience_setup)); - break; - case AO_COMPANION_FETCH: - ao_spi_write((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, - AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); - break; - case AO_COMPANION_NOTIFY: - break; - default: - return 0; - } - - ao_log_single_write_data.telescience.tm_tick = ao_companion_command.tick; - if (ao_log_single_write_data.telescience.tm_state != ao_companion_command.flight_state) { - ao_log_single_write_data.telescience.tm_state = ao_companion_command.flight_state; - return 1; - } - return 0; -} - static uint8_t ao_spi_slave_running; ISR(PCINT0_vect) { - if ((PINB & (1 << PINB0)) == 0) { + cli(); +#if SPI_SLAVE_PIN_0_3 + if ((PINB & (1 << PORTB0)) == 0) +#endif +#if SPI_SLAVE_PIN_2_5 + if ((PINB & (1 << PORTB2)) == 0) +#endif + { if (!ao_spi_slave_running) { - uint8_t changed; ao_spi_slave_running = 1; - cli(); - changed = ao_spi_slave_recv(); - sei(); - if (changed && ao_flight_boost <= ao_log_single_write_data.telescience.tm_state) { - if (ao_log_single_write_data.telescience.tm_state < ao_flight_landed) - ao_log_single_start(); - else - ao_log_single_stop(); - } + ao_spi_slave(); } } else { ao_spi_slave_running = 0; } -} - -void ao_spi_slave_debug(void) { - printf ("slave running %d\n", ao_spi_slave_running); + sei(); } void ao_spi_slave_init(void) { + /* We'd like to have a pull-up on SS so that disconnecting the + * TM would cause any SPI transaction to abort. However, when + * I tried that, SPI transactions would spontaneously abort, + * making me assume that we needed a less aggressive pull-up + * than is offered inside the AVR + */ +#if SPI_SLAVE_PIN_0_3 PCMSK0 |= (1 << PCINT0); /* Enable PCINT0 pin change */ PCICR |= (1 << PCIE0); /* Enable pin change interrupt */ @@ -121,17 +83,28 @@ ao_spi_slave_init(void) (0 << 1) | /* SCK, input */ (0 << 0)); /* SS, input */ - /* We'd like to have a pull-up on SS so that disconnecting the - * TM would cause any SPI transaction to abort. However, when - * I tried that, SPI transactions would spontaneously abort, - * making me assume that we needed a less aggressive pull-up - * than is offered inside the AVR - */ PORTB = ((PORTB & 0xf0) | (1 << 3) | /* MISO, output */ (0 << 2) | /* MOSI, no pull-up */ (0 << 1) | /* SCK, no pull-up */ (0 << 0)); /* SS, no pull-up */ +#endif +#if SPI_SLAVE_PIN_2_5 + PCMSK0 |= (1 << PCINT2); /* Enable PCINT2 pin change */ + PCICR |= (1 << PCIE0); /* Enable pin change interrupt */ + + DDRB = ((DDRB & 0xf0) | + (0 << 5) | /* SCK, input */ + (1 << 4) | /* MISO, output */ + (0 << 3) | /* MOSI, input */ + (0 << 2)); /* SS, input */ + + PORTB = ((PORTB & 0xf0) | + (0 << 5) | /* SCK, no pull-up */ + (1 << 4) | /* MISO, output */ + (0 << 3) | /* MOSI, no pull-up */ + (0 << 2)); /* SS, no pull-up */ +#endif SPCR = (0 << SPIE) | /* Disable SPI interrupts */ (1 << SPE) | /* Enable SPI */ diff --git a/src/core/ao.h b/src/core/ao.h index a541d8ac..1d5769cb 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -974,12 +974,23 @@ ao_spi_init(void); * ao_spi_slave.c */ +uint8_t +ao_spi_read(uint8_t *buf, uint8_t len); + void -ao_spi_slave_debug(void); +ao_spi_write(uint8_t *buf, uint8_t len); void ao_spi_slave_init(void); +/* This must be defined by the product; it will get called when chip + * select goes low, at which point it should use ao_spi_read and + * ao_spi_write to deal with the request + */ + +void +ao_spi_slave(void); + /* * ao_telemetry.c */ diff --git a/src/drivers/ao_science_slave.c b/src/drivers/ao_science_slave.c new file mode 100644 index 00000000..e902318f --- /dev/null +++ b/src/drivers/ao_science_slave.c @@ -0,0 +1,62 @@ +/* + * 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_product.h" + +struct ao_companion_command ao_companion_command; + +static const struct ao_companion_setup ao_telescience_setup = { + .board_id = AO_idProduct_NUMBER, + .board_id_inverse = ~AO_idProduct_NUMBER, + .update_period = 50, + .channels = AO_LOG_TELESCIENCE_NUM_ADC, +}; + +void ao_spi_slave(void) +{ + if (!ao_spi_read((uint8_t *) &ao_companion_command, + sizeof (ao_companion_command))) + return; + + /* Figure out the outbound data */ + switch (ao_companion_command.command) { + case AO_COMPANION_SETUP: + ao_spi_write((uint8_t *) &ao_telescience_setup, + sizeof (ao_telescience_setup)); + break; + case AO_COMPANION_FETCH: + ao_spi_write((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, + AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); + break; + case AO_COMPANION_NOTIFY: + break; + default: + return; + } + + ao_log_single_write_data.telescience.tm_tick = ao_companion_command.tick; + if (ao_log_single_write_data.telescience.tm_state != ao_companion_command.flight_state) { + ao_log_single_write_data.telescience.tm_state = ao_companion_command.flight_state; + if (ao_flight_boost <= ao_log_single_write_data.telescience.tm_state) { + if (ao_log_single_write_data.telescience.tm_state < ao_flight_landed) + ao_log_single_start(); + else + ao_log_single_stop(); + } + } +} diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index 28620242..a6797cbe 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -46,6 +46,7 @@ ALTOS_SRC = \ ao_romconfig.c \ ao_usb_avr.c \ ao_adc_avr.c \ + ao_science_slave.c \ ao_spi_slave.c \ ao_log_single.c \ ao_log_telescience.c \ -- cgit v1.2.3 From 7a02d4bace05cc829522933b9df6b82a9e17336f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 21 Sep 2011 11:30:43 -0700 Subject: altos: Add TelePyro v0.1 support Signed-off-by: Keith Packard --- src/Makefile | 2 +- src/avr/ao_adc_avr.c | 21 ++++++++- src/avr/ao_pins.h | 24 +++++++++++ src/core/ao.h | 6 +++ src/drivers/ao_pyro_slave.c | 51 ++++++++++++++++++++++ src/product/ao_telepyro.c | 36 ++++++++++++++++ src/telepyro-v0.1/Makefile | 101 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 238 insertions(+), 3 deletions(-) create mode 100644 src/drivers/ao_pyro_slave.c create mode 100644 src/product/ao_telepyro.c create mode 100644 src/telepyro-v0.1/Makefile (limited to 'src/avr') diff --git a/src/Makefile b/src/Makefile index 9ef5ae0a..91d3f035 100644 --- a/src/Makefile +++ b/src/Makefile @@ -19,7 +19,7 @@ SUBDIRS=\ telebt-v0.0 telebt-v0.1 \ telemetrum-v0.1-sky telemetrum-v0.1-sirf \ telelaunch-v0.1 \ - tidongle test telescience-v0.1 + tidongle test telescience-v0.1 telepyro-v0.1 all: all-local all-recursive diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 5afced74..9f45acaf 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -20,6 +20,7 @@ volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING]; volatile __data uint8_t ao_adc_head; +#ifdef TELESCIENCE const uint8_t adc_channels[AO_LOG_TELESCIENCE_NUM_ADC] = { 0x00, 0x01, @@ -34,6 +35,22 @@ const uint8_t adc_channels[AO_LOG_TELESCIENCE_NUM_ADC] = { 0x24, 0x25, }; +#endif + +#ifdef TELEPYRO +const uint8_t adc_channels[AO_TELEPYRO_NUM_ADC] = { + 0x00, /* ADC0 v_batt */ + 0x04, /* ADC4 sense_a */ + 0x05, /* ADC5 sense_b */ + 0x06, /* ADC6 sense_c */ + 0x07, /* ADC7 sense_d */ + 0x23, /* ADC11 sense_e */ + 0x22, /* ADC10 sense_f */ + 0x21, /* ADC9 sense_g */ +}; +#endif + +#define NUM_ADC (sizeof (adc_channels) / sizeof (adc_channels[0])) static uint8_t ao_adc_channel; @@ -75,7 +92,7 @@ ISR(ADC_vect) value = ADCL; value |= (ADCH << 8); ao_adc_ring[ao_adc_head].adc[ao_adc_channel] = value; - if (++ao_adc_channel < AO_TELESCIENCE_NUM_ADC) + if (++ao_adc_channel < NUM_ADC) ao_adc_start(); else { ADCSRA = ADCSRA_INIT; @@ -108,7 +125,7 @@ ao_adc_dump(void) __reentrant uint8_t i; ao_adc_get(&packet); printf("tick: %5u", packet.tick); - for (i = 0; i < AO_TELESCIENCE_NUM_ADC; i++) + for (i = 0; i < NUM_ADC; i++) printf (" %2d: %5u", i, packet.adc[i]); printf ("\n"); } diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index 88f03829..6b72530b 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -61,4 +61,28 @@ #define SPI_SLAVE_PIN_2_5 0 #endif +#ifdef TELEPYRO + #define LEDS_AVAILABLE 0 + #define HAS_USB 1 + #define HAS_LOG 0 + #define TEENSY 0 + #define USE_SERIAL_STDIN 1 + #define HAS_SERIAL_1 1 + #define HAS_USB 1 + #define HAS_ADC 1 + #define PACKET_HAS_SLAVE 0 + #define HAS_BEEP 0 + + #define AVR_VCC_5V 0 + #define AVR_VCC_3V3 1 + #define AVR_CLOCK 8000000UL + + #define SPI_SLAVE_CS_PORT PORTB + #define SPI_SLAVE_CS_PIN PINB + #define SPI_SLAVE_CS_PIN_NO PINB0 + + #define SPI_SLAVE_PIN_0_3 1 + #define SPI_SLAVE_PIN_2_5 0 +#endif + #endif /* _AO_PINS_H_ */ diff --git a/src/core/ao.h b/src/core/ao.h index c28c4549..04610fea 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -1811,4 +1811,10 @@ ao_log_single_init(void); void ao_log_single(void); +/* + * ao_pyro_slave.c + */ + +#define AO_TELEPYRO_NUM_ADC 9 + #endif /* _AO_H_ */ diff --git a/src/drivers/ao_pyro_slave.c b/src/drivers/ao_pyro_slave.c new file mode 100644 index 00000000..e6c73a3c --- /dev/null +++ b/src/drivers/ao_pyro_slave.c @@ -0,0 +1,51 @@ +/* + * 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_product.h" + +struct ao_companion_command ao_companion_command; + +static const struct ao_companion_setup ao_telepyro_setup = { + .board_id = AO_idProduct_NUMBER, + .board_id_inverse = ~AO_idProduct_NUMBER, + .update_period = 50, + .channels = AO_TELEPYRO_NUM_ADC, +}; + +void ao_spi_slave(void) +{ + if (!ao_spi_read((uint8_t *) &ao_companion_command, + sizeof (ao_companion_command))) + return; + + /* Figure out the outbound data */ + switch (ao_companion_command.command) { + case AO_COMPANION_SETUP: + ao_spi_write((uint8_t *) &ao_telepyro_setup, + sizeof (ao_telepyro_setup)); + break; + case AO_COMPANION_FETCH: + ao_spi_write((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, + AO_TELEPYRO_NUM_ADC * sizeof (uint16_t)); + break; + case AO_COMPANION_NOTIFY: + break; + default: + return; + } +} diff --git a/src/product/ao_telepyro.c b/src/product/ao_telepyro.c new file mode 100644 index 00000000..a2b8f83c --- /dev/null +++ b/src/product/ao_telepyro.c @@ -0,0 +1,36 @@ +/* + * 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" + +int +main(void) +{ + ao_clock_init(); + + PORTE |= (1 << 6); + DDRE |= (1 << 6); + + ao_avr_stdio_init(); + ao_timer_init(); + ao_cmd_init(); + ao_spi_slave_init(); + ao_usb_init(); + ao_adc_init(); + ao_start_scheduler(); + return 0; +} diff --git a/src/telepyro-v0.1/Makefile b/src/telepyro-v0.1/Makefile new file mode 100644 index 00000000..2f664fcb --- /dev/null +++ b/src/telepyro-v0.1/Makefile @@ -0,0 +1,101 @@ +# +# AltOS build +# +# +vpath % ..:../core:../product:../drivers:../avr +vpath ao-make-product.5c ../util + +MCU=atmega32u4 +DUDECPUTYPE=m32u4 +#PROGRAMMER=stk500v2 -P usb +PROGRAMMER=usbtiny +LOADCMD=avrdude +LOADARG=-p $(DUDECPUTYPE) -c $(PROGRAMMER) -e -U flash:w: +CC=avr-gcc +OBJCOPY=avr-objcopy + +ifndef VERSION +include ../Version +endif + +INC = \ + ao.h \ + ao_usb.h \ + ao_pins.h \ + altitude.h + +ALTOS_SRC = \ + ao_clock.c \ + ao_cmd.c \ + ao_mutex.c \ + ao_panic.c \ + ao_product.c \ + ao_stdio.c \ + ao_task.c \ + ao_timer.c \ + ao_led.c \ + ao_avr_stdio.c \ + ao_romconfig.c \ + ao_usb_avr.c \ + ao_adc_avr.c \ + ao_pyro_slave.c \ + ao_spi_slave.c + +PRODUCT=TelePyro-v0.1 +MCU=atmega32u4 +PRODUCT_DEF=-DTELEPYRO +IDPRODUCT=0x0011 +CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I.. +CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR + +NICKLE=nickle + +PROG=telepyro-v0.1 + +SRC=$(ALTOS_SRC) ao_telepyro.c +OBJ=$(SRC:.c=.o) + +V=0 +# The user has explicitly enabled quiet compilation. +ifeq ($(V),0) +quiet = @printf " $1 $2 $@\n"; $($1) +endif +# Otherwise, print the full command line. +quiet ?= $($1) + +all: $(PROG) + +CHECK=sh ../util/check-avr-mem + +$(PROG): Makefile $(OBJ) + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) + $(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1) + +$(PROG).hex: $(PROG) + avr-size $(PROG) + $(OBJCOPY) -R .eeprom -O ihex $(PROG) $@ + + +load: $(PROG).hex + $(LOADCMD) $(LOADARG)$(PROG).hex + +../altitude.h: make-altitude + nickle $< > $@ + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +ao_product.rel: ao_product.c ao_product.h + $(call quiet,CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"ao_product.h\"' -o$@ $< + +distclean: clean + +clean: + rm -f $(OBJ) + rm -f ao_product.h + +install: + +uninstall: + +$(OBJ): ao.h ao_product.h ao_usb.h -- cgit v1.2.3 From f68f22f527104cdffa1f5e398a51a466a13ff1fb Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 21 Sep 2011 16:42:22 -0600 Subject: add missing sense_h entry in TelePyro table --- src/avr/ao_adc_avr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/avr') diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 9f45acaf..4c4bcbda 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -47,6 +47,7 @@ const uint8_t adc_channels[AO_TELEPYRO_NUM_ADC] = { 0x23, /* ADC11 sense_e */ 0x22, /* ADC10 sense_f */ 0x21, /* ADC9 sense_g */ + 0x20, /* ADC8 sense_h */ }; #endif -- cgit v1.2.3 From 9b498a6b1327f543c73145e02ff16e76d09f2fe4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 21 Sep 2011 22:54:56 -0700 Subject: Dump ADC registers --- src/avr/ao_adc_avr.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/avr') diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 4c4bcbda..06284d68 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -125,6 +125,14 @@ ao_adc_dump(void) __reentrant static __xdata struct ao_adc packet; uint8_t i; ao_adc_get(&packet); + printf("ADMUX: %02x\n", ADMUX); + printf("ADCSRA: %02x\n", ADCSRA); + printf("ADCSRB: %02x\n", ADCSRB); + printf("DIDR0: %02x\n", DIDR0); + printf("DIDR2: %02x\n", DIDR2); + printf("PORTF: %02x\n", PORTF); + printf("DDRF: %02x\n", DDRF); + printf("PINF: %02x\n", PINF); printf("tick: %5u", packet.tick); for (i = 0; i < NUM_ADC; i++) printf (" %2d: %5u", i, packet.adc[i]); -- cgit v1.2.3 From f1328d22aab4378c4fb6f0c24dbee95948ca836c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 21 Sep 2011 23:21:04 -0700 Subject: Dump test conversion of ADC0 --- src/avr/ao_adc_avr.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/avr') diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 06284d68..a47703e5 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -66,7 +66,7 @@ static uint8_t ao_adc_channel; #define ADCSRB_INIT ((0 << ADHSM) | /* No high-speed mode */ \ (0 << ACME) | /* Some comparitor thing */ \ - (2 << ADTS0)) /* Free running mode (don't care) */ + (0 << ADTS0)) /* Free running mode (don't care) */ static void ao_adc_start(void) @@ -136,6 +136,15 @@ ao_adc_dump(void) __reentrant printf("tick: %5u", packet.tick); for (i = 0; i < NUM_ADC; i++) printf (" %2d: %5u", i, packet.adc[i]); + + + ADMUX = 0x60; + ADCSRB = 0x00; + ADCSRA = 0xc6; + while (ADCSRA & 0x40) + ; + printf ("ADCL: %02x\n", ADCL); + printf ("ADCH: %02x\n", ADCH); printf ("\n"); } -- cgit v1.2.3 From 4ed53ef838afd4e922deb1c721a311974527525a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 23 Sep 2011 10:24:33 -0700 Subject: altos: Debug code for telepyro doesn't fit in telescience Just too many strings. Signed-off-by: Keith Packard --- src/avr/ao_adc_avr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/avr') diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index a47703e5..8c0cade0 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -125,6 +125,7 @@ ao_adc_dump(void) __reentrant static __xdata struct ao_adc packet; uint8_t i; ao_adc_get(&packet); +#ifdef TELEPYRO printf("ADMUX: %02x\n", ADMUX); printf("ADCSRA: %02x\n", ADCSRA); printf("ADCSRB: %02x\n", ADCSRB); @@ -133,11 +134,13 @@ ao_adc_dump(void) __reentrant printf("PORTF: %02x\n", PORTF); printf("DDRF: %02x\n", DDRF); printf("PINF: %02x\n", PINF); +#endif printf("tick: %5u", packet.tick); for (i = 0; i < NUM_ADC; i++) printf (" %2d: %5u", i, packet.adc[i]); +#ifdef TELEPYRO ADMUX = 0x60; ADCSRB = 0x00; ADCSRA = 0xc6; @@ -146,6 +149,7 @@ ao_adc_dump(void) __reentrant printf ("ADCL: %02x\n", ADCL); printf ("ADCH: %02x\n", ADCH); printf ("\n"); +#endif } __code struct ao_cmds ao_adc_cmds[] = { -- cgit v1.2.3 From 06b044629951b06c7ec9b0105b89f51b2880ebd0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 16:03:04 -0600 Subject: altos/avr: SPI mutex is now held by the caller, not the SPI driver SPI transactions generally require a read followed by a write, with the chip select held the whole time. As a result, the SPI bus must be held across multiple transactions. To make this reliable, the caller must hold the SPI mutex, instead of the underlying SPI driver. Signed-off-by: Keith Packard --- src/avr/ao_spi_usart.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_spi_usart.c b/src/avr/ao_spi_usart.c index 6ed708ff..1996fcd9 100644 --- a/src/avr/ao_spi_usart.c +++ b/src/avr/ao_spi_usart.c @@ -33,14 +33,12 @@ ao_spi_send(void __xdata *block, uint16_t len) __reentrant { uint8_t *d = block; - ao_mutex_get(&ao_spi_mutex); while (len--) { while (!(UCSR1A & (1 << UDRE1))); UDR1 = *d++; while (!(UCSR1A & (1 << RXC1))); (void) UDR1; } - ao_mutex_put(&ao_spi_mutex); } /* Receive bytes over SPI. @@ -54,14 +52,12 @@ ao_spi_recv(void __xdata *block, uint16_t len) __reentrant { uint8_t *d = block; - ao_mutex_get(&ao_spi_mutex); while (len--) { while (!(UCSR1A & (1 << UDRE1))); UDR1 = 0; while (!(UCSR1A & (1 << RXC1))); *d++ = UDR1; } - ao_mutex_put(&ao_spi_mutex); } /* -- cgit v1.2.3 From f3453068b0feb640b9d11dbeb021c535ce8b4a31 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 17:39:06 -0600 Subject: altos/avr: Print newline after dumping ADC values Cleans up the formating a bit. Signed-off-by: Keith Packard --- src/avr/ao_adc_avr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/avr') diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 8c0cade0..4f6f0e60 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -138,6 +138,7 @@ ao_adc_dump(void) __reentrant printf("tick: %5u", packet.tick); for (i = 0; i < NUM_ADC; i++) printf (" %2d: %5u", i, packet.adc[i]); + printf("\n"); #ifdef TELEPYRO -- cgit v1.2.3 From 0a186e92c5773c5d908e9cee889d645a8172dcdc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 17:39:35 -0600 Subject: altos/avr: Make ao_arch_critical argument be a statement Wrap the argument to ao_arch_critical in do { } while (0); to make sure it gets correctly checked as a statement. Signed-off-by: Keith Packard --- src/avr/ao_arch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/avr') diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index c695a725..2be4abee 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -143,7 +143,7 @@ extern uint8_t ao_cpu_sleep_disable; asm("ret"); \ } while(0) -#define ao_arch_critical(b) do { cli(); b; sei(); } while (0) +#define ao_arch_critical(b) do { cli(); do { b } while (0); sei(); } while (0) #define AO_TELESCIENCE_NUM_ADC 12 -- cgit v1.2.3 From 3bda859caf1501f8408703dca81412d70ba00e04 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 17:42:24 -0600 Subject: altos/avr: telescience does not have a serial port The USART is used for SPI to talk to the flash part. Signed-off-by: Keith Packard --- src/avr/ao_pins.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index 6b72530b..ddd37a7b 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -37,12 +37,12 @@ #define HAS_USB 1 #define HAS_LOG 1 #define TEENSY 0 - #define USE_SERIAL_STDIN 1 - #define HAS_SERIAL_1 1 - #define HAS_USB 1 + #define USE_SERIAL_STDIN 0 + #define HAS_SERIAL_1 0 #define HAS_ADC 1 #define PACKET_HAS_SLAVE 0 #define HAS_BEEP 0 + #define HAS_STORAGE_DEBUG 1 #define AVR_VCC_5V 0 #define AVR_VCC_3V3 1 -- cgit v1.2.3 From af4470f8025116179ef83726a8287e47c465907b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 17:44:02 -0600 Subject: altos/avr: Register stdio handler when using serial for stdin This code was left in a bit of a mess; just clean it up. Signed-off-by: Keith Packard --- src/avr/ao_serial_avr.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_serial_avr.c b/src/avr/ao_serial_avr.c index 2fe39755..6885c339 100644 --- a/src/avr/ao_serial_avr.c +++ b/src/avr/ao_serial_avr.c @@ -154,13 +154,9 @@ ao_serial_init(void) (1 << TXEN1) | /* Enable transmitter */ (1 << RXCIE1) | /* Enable receive interrupts */ (1 << UDRIE1)); /* Enable transmit empty interrupts */ -#if 0 #if USE_SERIAL_STDIN - int8_t i; - i = ao_add_stdio(ao_serial_pollchar, - ao_serial_putchar, - NULL); - printf("Register serial stdio as %d\n", i); -#endif + ao_add_stdio(ao_serial_pollchar, + ao_serial_putchar, + NULL); #endif } -- cgit v1.2.3 From e60c470b426b7be08a33133e7d8c94201d7e96d4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 17:44:40 -0600 Subject: altos/avr: Pull-up on the SPI slave select pin This makes the board work even when disconnected from TeleMetrum. Signed-off-by: Keith Packard --- src/avr/ao_spi_slave.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_spi_slave.c b/src/avr/ao_spi_slave.c index 76f574c6..3aa0b97f 100644 --- a/src/avr/ao_spi_slave.c +++ b/src/avr/ao_spi_slave.c @@ -87,7 +87,7 @@ ao_spi_slave_init(void) (1 << 3) | /* MISO, output */ (0 << 2) | /* MOSI, no pull-up */ (0 << 1) | /* SCK, no pull-up */ - (0 << 0)); /* SS, no pull-up */ + (1 << 0)); /* SS, pull-up */ #endif #if SPI_SLAVE_PIN_2_5 PCMSK0 |= (1 << PCINT2); /* Enable PCINT2 pin change */ @@ -103,7 +103,7 @@ ao_spi_slave_init(void) (0 << 5) | /* SCK, no pull-up */ (1 << 4) | /* MISO, output */ (0 << 3) | /* MOSI, no pull-up */ - (0 << 2)); /* SS, no pull-up */ + (1 << 2)); /* SS, pull-up */ #endif SPCR = (0 << SPIE) | /* Disable SPI interrupts */ -- cgit v1.2.3 From 3a28846d3ff8f82b0e97c211b9debf6d67ee5af5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 18:10:45 -0600 Subject: altos/avr: Clear SPI receive buffer before clocking new data in I don't know why this is necessary, but the receive buffer gets 'extra' data added somehow. Signed-off-by: Keith Packard --- src/avr/ao_spi_usart.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_spi_usart.c b/src/avr/ao_spi_usart.c index 1996fcd9..5ea11da6 100644 --- a/src/avr/ao_spi_usart.c +++ b/src/avr/ao_spi_usart.c @@ -43,15 +43,17 @@ ao_spi_send(void __xdata *block, uint16_t len) __reentrant /* Receive bytes over SPI. * - * This sets up tow DMA engines, one reading the data and another - * writing constant values to the SPI transmitter as that is what - * clocks the data coming in. + * Poll, sending zeros and reading data back */ void ao_spi_recv(void __xdata *block, uint16_t len) __reentrant { uint8_t *d = block; + /* Clear any pending data */ + while (UCSR1A & (1 << RXC1)) + (void) UDR1; + while (len--) { while (!(UCSR1A & (1 << UDRE1))); UDR1 = 0; -- cgit v1.2.3 From f1573a752425121d4c6a14285f1eb0fef3a8bea5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 18:44:48 -0600 Subject: altos/avr: Shrink default stack size to use less ram Not that we have any way of knowing how much stack we're using, but at least this seems to work. Signed-off-by: Keith Packard --- src/avr/ao_arch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/avr') diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index 2be4abee..c189ccba 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -37,7 +37,7 @@ * AVR definitions and code fragments for AltOS */ -#define AO_STACK_SIZE 128 +#define AO_STACK_SIZE 116 /* Various definitions to make GCC look more like SDCC */ -- cgit v1.2.3 From 75960500d1f290fa9f82183431443ac122f12c19 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 18:48:11 -0600 Subject: altos/avr: telescience doesn't have room for the flash write code This is useful for debugging the SPI and flash drivers, but not necessary in production code. Signed-off-by: Keith Packard --- src/avr/ao_pins.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/avr') diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index ddd37a7b..bf02db1b 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -42,7 +42,7 @@ #define HAS_ADC 1 #define PACKET_HAS_SLAVE 0 #define HAS_BEEP 0 - #define HAS_STORAGE_DEBUG 1 + #define HAS_STORAGE_DEBUG 0 #define AVR_VCC_5V 0 #define AVR_VCC_3V3 1 -- cgit v1.2.3 From 47c2c0b79dc516d2566ae149605b7d70ef2dca98 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 20:58:04 -0600 Subject: Bump to 1.0.9.3 TeleScience and TelePyro now work. Signed-off-by: Keith Packard --- configure.ac | 2 +- src/avr/ao_spi_slave.c | 4 ++-- src/avr/ao_usb_avr.c | 3 --- src/core/ao.h | 4 ++-- src/drivers/ao_pyro_slave.c | 12 ++++++------ src/drivers/ao_science_slave.c | 12 ++++++------ 6 files changed, 17 insertions(+), 20 deletions(-) (limited to 'src/avr') diff --git a/configure.ac b/configure.ac index 57d2f196..19db6d27 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.0.9.2) +AC_INIT([altos], 1.0.9.3) AC_CONFIG_SRCDIR([src/core/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE diff --git a/src/avr/ao_spi_slave.c b/src/avr/ao_spi_slave.c index 3aa0b97f..b742d29a 100644 --- a/src/avr/ao_spi_slave.c +++ b/src/avr/ao_spi_slave.c @@ -18,7 +18,7 @@ #include "ao.h" uint8_t -ao_spi_read(uint8_t *buf, uint8_t len) +ao_spi_slave_recv(uint8_t *buf, uint8_t len) { while (len--) { while (!(SPSR & (1 << SPIF))) @@ -30,7 +30,7 @@ ao_spi_read(uint8_t *buf, uint8_t len) } void -ao_spi_write(uint8_t *buf, uint8_t len) +ao_spi_slave_send(uint8_t *buf, uint8_t len) { while (len--) { SPDR = *buf++; diff --git a/src/avr/ao_usb_avr.c b/src/avr/ao_usb_avr.c index 74bdea23..fc8899d8 100644 --- a/src/avr/ao_usb_avr.c +++ b/src/avr/ao_usb_avr.c @@ -303,9 +303,6 @@ ao_usb_ep0_setup(void) } break; case AO_USB_RECIP_INTERFACE: -#ifndef AVR - #pragma disable_warning 110 -#endif debug ("Interface setup packet\n"); switch(ao_usb_setup.request) { case AO_USB_REQ_GET_STATUS: diff --git a/src/core/ao.h b/src/core/ao.h index c0474729..94526bc3 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -975,10 +975,10 @@ ao_spi_init(void); */ uint8_t -ao_spi_read(uint8_t *buf, uint8_t len); +ao_spi_slave_recv(uint8_t *buf, uint8_t len); void -ao_spi_write(uint8_t *buf, uint8_t len); +ao_spi_slave_send(uint8_t *buf, uint8_t len); void ao_spi_slave_init(void); diff --git a/src/drivers/ao_pyro_slave.c b/src/drivers/ao_pyro_slave.c index e6c73a3c..5ef42b5a 100644 --- a/src/drivers/ao_pyro_slave.c +++ b/src/drivers/ao_pyro_slave.c @@ -29,19 +29,19 @@ static const struct ao_companion_setup ao_telepyro_setup = { void ao_spi_slave(void) { - if (!ao_spi_read((uint8_t *) &ao_companion_command, - sizeof (ao_companion_command))) + if (!ao_spi_slave_recv((uint8_t *) &ao_companion_command, + sizeof (ao_companion_command))) return; /* Figure out the outbound data */ switch (ao_companion_command.command) { case AO_COMPANION_SETUP: - ao_spi_write((uint8_t *) &ao_telepyro_setup, - sizeof (ao_telepyro_setup)); + ao_spi_slave_send((uint8_t *) &ao_telepyro_setup, + sizeof (ao_telepyro_setup)); break; case AO_COMPANION_FETCH: - ao_spi_write((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, - AO_TELEPYRO_NUM_ADC * sizeof (uint16_t)); + ao_spi_slave_send((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, + AO_TELEPYRO_NUM_ADC * sizeof (uint16_t)); break; case AO_COMPANION_NOTIFY: break; diff --git a/src/drivers/ao_science_slave.c b/src/drivers/ao_science_slave.c index 78941255..1ebb1480 100644 --- a/src/drivers/ao_science_slave.c +++ b/src/drivers/ao_science_slave.c @@ -29,19 +29,19 @@ static const struct ao_companion_setup ao_telescience_setup = { void ao_spi_slave(void) { - if (!ao_spi_read((uint8_t *) &ao_companion_command, - sizeof (ao_companion_command))) + if (!ao_spi_slave_recv((uint8_t *) &ao_companion_command, + sizeof (ao_companion_command))) return; /* Figure out the outbound data */ switch (ao_companion_command.command) { case AO_COMPANION_SETUP: - ao_spi_write((uint8_t *) &ao_telescience_setup, - sizeof (ao_telescience_setup)); + ao_spi_slave_send((uint8_t *) &ao_telescience_setup, + sizeof (ao_telescience_setup)); break; case AO_COMPANION_FETCH: - ao_spi_write((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, - AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); + ao_spi_slave_send((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, + AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); break; case AO_COMPANION_NOTIFY: break; -- cgit v1.2.3 From badda0d910c56135401dce9adc9e6abebdba2ad7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 11 Oct 2011 23:28:02 -0600 Subject: altos: Split out arch-specific bits of LCD driver The arch-specific section just puts a single nibble to the device. Signed-off-by: Keith Packard --- src/avr/ao_lcd_port.c | 74 ++++++++++++++++++++++++ src/cc1111/ao_lcd_port.c | 41 ++++++++++++++ src/cc1111/ao_packet.c | 4 ++ src/core/ao.h | 28 ++++++++++ src/core/ao_monitor.c | 13 ++++- src/drivers/ao_lcd.c | 142 ++++++++++------------------------------------- 6 files changed, 186 insertions(+), 116 deletions(-) create mode 100644 src/avr/ao_lcd_port.c create mode 100644 src/cc1111/ao_lcd_port.c (limited to 'src/avr') diff --git a/src/avr/ao_lcd_port.c b/src/avr/ao_lcd_port.c new file mode 100644 index 00000000..b1e8aa17 --- /dev/null +++ b/src/avr/ao_lcd_port.c @@ -0,0 +1,74 @@ +/* + * 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" + +#define LCD_PORT PORTB +#define LCD_DDR DDRB + +#define PIN_RS 4 +#define PIN_E 5 +#define PIN_RW 6 + +static void +ao_lcd_port_set_bits(uint8_t bits) +{ +#if 0 + printf("\tLCD data %x RS %d R/W %d E %d\n", + bits & 0xf, + (bits & (1 << PIN_RS)) ? 1 : 0, + (bits & (1 << PIN_RW)) ? 1 : 0, + (bits & (1 << PIN_E)) ? 1 : 0); +#endif + LCD_PORT = bits; +#if 0 + ao_delay(1); + if (bits & (1 << PIN_RW)) + printf("\tLCD input %x\n", PINB); +#endif +} + +uint8_t +ao_lcd_port_get_nibble(uint8_t rs) +{ + uint8_t data = (rs ? (1 << PIN_RS) : 0) | (1 << PIN_RW); + uint8_t n; + + DDRB = (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); + ao_lcd_port_set_bits(data); + ao_lcd_port_set_bits(data | (1 << PIN_E)); + n = PINB & 0xf; + ao_lcd_port_set_bits(data); + return n; +} + +void +ao_lcd_port_put_nibble(uint8_t rs, uint8_t data) +{ + data = (data & 0xf) | (rs ? (1 << PIN_RS) : 0); + DDRB = (0xf) | (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); + ao_lcd_port_set_bits(data); + ao_lcd_port_set_bits(data | (1 << PIN_E)); + ao_lcd_port_set_bits(data); +} + +void +ao_lcd_port_init(void) +{ + DDRB = (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); + PORTB = 0; +} diff --git a/src/cc1111/ao_lcd_port.c b/src/cc1111/ao_lcd_port.c new file mode 100644 index 00000000..324cc3d3 --- /dev/null +++ b/src/cc1111/ao_lcd_port.c @@ -0,0 +1,41 @@ +/* + * 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" + +void +ao_lcd_port_put_nibble(uint8_t rs, uint8_t nibble) +{ + P0 = (P0 & 0xf0) | (nibble & 0x0f); + P1_1 = rs; + P1_0 = 1; + ao_delay(1); + P1_0 = 0; + ao_delay(1); +} + +void +ao_lcd_port_init(void) +{ + /* LCD_E and LCD_RS are GPIO outputs */ + P1DIR |= 0x03; + P1SEL &= ~0x03; + + /* LCD D4-D7 are GPIO outputs */ + P0DIR |= 0x0f; + P0SEL &= ~0x0f; +} diff --git a/src/cc1111/ao_packet.c b/src/cc1111/ao_packet.c index 37ba92e0..f502d67c 100644 --- a/src/cc1111/ao_packet.c +++ b/src/cc1111/ao_packet.c @@ -32,7 +32,9 @@ __xdata uint8_t ao_packet_master_sleeping; void ao_packet_send(void) { +#ifdef AO_LED_RED ao_led_on(AO_LED_RED); +#endif /* If any tx data is pending then copy it into the tx packet */ if (ao_packet_tx_used && ao_tx_packet.len == 0) { ao_xmemcpy(&ao_tx_packet.d, tx_data, ao_packet_tx_used); @@ -42,7 +44,9 @@ ao_packet_send(void) ao_wakeup(&tx_data); } ao_radio_send(&ao_tx_packet, sizeof (ao_tx_packet)); +#ifdef AO_LED_RED ao_led_off(AO_LED_RED); +#endif } uint8_t diff --git a/src/core/ao.h b/src/core/ao.h index 94526bc3..c800f1fc 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -1667,9 +1667,37 @@ ao_companion_init(void); /* ao_lcd.c */ +void +ao_lcd_putchar(uint8_t data); + +void +ao_lcd_putstring(char *string); + +void +ao_lcd_contrast_set(uint8_t contrast); + +void +ao_lcd_clear(void); + +#define AO_LCD_ADDR(row,col) ((row << 6) | (col)) + +void +ao_lcd_goto(uint8_t addr); + +void +ao_lcd_start(void); + void ao_lcd_init(void); +/* ao_lcd_port.c */ + +void +ao_lcd_port_put_nibble(uint8_t rs, uint8_t data); + +void +ao_lcd_port_init(void); + /* ao_aes.c */ __xdata uint8_t ao_aes_mutex; diff --git a/src/core/ao_monitor.c b/src/core/ao_monitor.c index 1a8bb52a..5a6f61dd 100644 --- a/src/core/ao_monitor.c +++ b/src/core/ao_monitor.c @@ -22,6 +22,10 @@ #error Must define HAS_MONITOR to 1 #endif +#ifndef LEGACY_MONITOR +#error Must define LEGACY_MONITOR +#endif + __data uint8_t ao_monitoring; __pdata uint8_t ao_monitor_led; @@ -39,12 +43,14 @@ ao_monitor_get(void) case 0: ao_sleep(DATA_TO_XDATA(&ao_monitoring)); continue; +#if LEGACY_MONITOR case AO_MONITORING_ORIG: size = sizeof (struct ao_telemetry_orig_recv); break; case AO_MONITORING_TINY: size = sizeof (struct ao_telemetry_tiny_recv); break; +#endif default: if (ao_monitoring > AO_MAX_TELEMETRY) ao_monitoring = AO_MAX_TELEMETRY; @@ -70,12 +76,13 @@ ao_monitor_blink(void) void ao_monitor_put(void) { +#if LEGACY_MONITOR __xdata char callsign[AO_MAX_CALLSIGN+1]; - + int16_t rssi; +#endif uint8_t ao_monitor_tail; uint8_t state; uint8_t sum, byte; - int16_t rssi; __xdata union ao_monitor *m; #define recv_raw ((m->raw)) @@ -89,6 +96,7 @@ ao_monitor_put(void) m = &ao_monitor_ring[ao_monitor_tail]; ao_monitor_tail = ao_monitor_ring_next(ao_monitor_tail); switch (ao_monitoring) { +#if LEGACY_MONITOR case AO_MONITORING_ORIG: state = recv_orig.telemetry_orig.flight_state; @@ -231,6 +239,7 @@ ao_monitor_put(void) printf("CRC INVALID RSSI %3d\n", rssi); } break; +#endif /* LEGACY_MONITOR */ default: printf ("TELEM %02x", ao_monitoring + 2); sum = 0x5a; diff --git a/src/drivers/ao_lcd.c b/src/drivers/ao_lcd.c index 5bc89bbd..e62247ae 100644 --- a/src/drivers/ao_lcd.c +++ b/src/drivers/ao_lcd.c @@ -17,100 +17,9 @@ #include "ao.h" -#define LCD_PORT PORTB -#define LCD_DDR DDRB - -#define PIN_RS 4 -#define PIN_E 5 -#define PIN_RW 6 - -void -ao_lcd_set_bits(uint8_t bits) -{ -#if 0 - printf("\tLCD data %x RS %d R/W %d E %d\n", - bits & 0xf, - (bits & (1 << PIN_RS)) ? 1 : 0, - (bits & (1 << PIN_RW)) ? 1 : 0, - (bits & (1 << PIN_E)) ? 1 : 0); -#endif - LCD_PORT = bits; -#if 0 - ao_delay(1); - if (bits & (1 << PIN_RW)) - printf("\tLCD input %x\n", PINB); -#endif -} - -uint8_t -ao_lcd_get_nibble(uint8_t rs) -{ - uint8_t data = (rs ? (1 << PIN_RS) : 0) | (1 << PIN_RW); - uint8_t n; - - DDRB = (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); - ao_lcd_set_bits(data); - ao_lcd_set_bits(data | (1 << PIN_E)); - n = PINB & 0xf; - ao_lcd_set_bits(data); - return n; -} - -uint8_t -ao_lcd_get_status(void) -{ - uint8_t high, low; - uint8_t data; - - high = ao_lcd_get_nibble(0); - low = ao_lcd_get_nibble(0); - data = (high << 4) | low; - printf ("\tLCD status %02x\n", data); - return data; -} - -uint8_t -ao_lcd_get_data(void) -{ - uint8_t high, low; - uint8_t data; - - high = ao_lcd_get_nibble(1); - low = ao_lcd_get_nibble(1); - data = (high << 4) | low; - printf ("\tLCD data %02x\n", data); - return data; -} - -void -ao_lcd_wait_idle(void) -{ - uint8_t status; - uint8_t count = 0; - - do { - status = ao_lcd_get_status(); - count++; - if (count > 100) { - printf("idle timeout\n"); - break; - } - } while (0); /* status & 0x80); */ -} - -void -ao_lcd_send_nibble(uint8_t rs, uint8_t data) -{ - data = (data & 0xf) | (rs ? (1 << PIN_RS) : 0); - DDRB = (0xf) | (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); - ao_lcd_set_bits(data); - ao_lcd_set_bits(data | (1 << PIN_E)); - ao_lcd_set_bits(data); -} - static uint16_t ao_lcd_time = 3; -void +static void ao_lcd_delay(void) { volatile uint16_t count; @@ -119,34 +28,34 @@ ao_lcd_delay(void) ; } -void -ao_lcd_send_ins(uint8_t data) +static void +ao_lcd_send_ins(uint8_t ins) { -// printf("send ins %02x\n", data); +// printf("send ins %02x\n", ins); // ao_lcd_wait_idle(); // ao_delay(1); ao_lcd_delay(); - ao_lcd_send_nibble(0, data >> 4); - ao_lcd_send_nibble(0, data & 0xf); + ao_lcd_port_put_nibble(0, ins >> 4); + ao_lcd_port_put_nibble(0, ins & 0xf); } void -ao_lcd_send_data(uint8_t data) +ao_lcd_put_byte(uint8_t c) { -// printf ("send data %02x\n", data); +// printf ("send data %02x\n", c); // ao_lcd_wait_idle(); ao_lcd_delay(); - ao_lcd_send_nibble(1, data >> 4); - ao_lcd_send_nibble(1, data & 0x0f); + ao_lcd_port_put_nibble(1, c >> 4); + ao_lcd_port_put_nibble(1, c & 0x0f); } void -ao_lcd_send_string(char *string) +ao_lcd_putstring(char *string) { - uint8_t c; + char c; while ((c = (uint8_t) *string++)) - ao_lcd_send_data(c); + ao_lcd_put_byte((uint8_t) c); } #define AO_LCD_POWER_CONTROL 0x54 @@ -167,14 +76,21 @@ ao_lcd_clear(void) ao_lcd_send_ins(0x04 | 0x02); } +void +ao_lcd_goto(uint8_t addr) +{ + ao_lcd_send_ins(0x80 | addr); + ao_lcd_send_ins(0x04 | 0x02); +} + void ao_lcd_start(void) { /* get to 4bit mode */ - ao_lcd_send_nibble(0, 0x3); - ao_lcd_send_nibble(0, 0x3); - ao_lcd_send_nibble(0, 0x3); - ao_lcd_send_nibble(0, 0x2); + ao_lcd_port_put_nibble(0, 0x3); + ao_lcd_port_put_nibble(0, 0x3); + ao_lcd_port_put_nibble(0, 0x3); + ao_lcd_port_put_nibble(0, 0x2); /* function set */ ao_lcd_send_ins(0x28); @@ -199,7 +115,6 @@ ao_lcd_start(void) /* Clear */ ao_lcd_clear(); - } void @@ -229,7 +144,7 @@ void ao_lcd_string(void) { uint8_t col = 0; - uint8_t c; + char c; ao_cmd_decimal(); if (ao_cmd_status != ao_cmd_success) @@ -244,12 +159,12 @@ ao_lcd_string(void) ao_cmd_lex(); c |= ao_cmd_hex_nibble(); } - ao_lcd_send_data(c); + ao_lcd_put_byte(c); ao_cmd_lex(); col++; } while (col < 16) { - ao_lcd_send_data(' '); + ao_lcd_put_byte(' '); col++; } } @@ -275,7 +190,6 @@ __code struct ao_cmds ao_lcd_cmds[] = { void ao_lcd_init(void) { - DDRB = (1 << PIN_RS) | (1 << PIN_E) | (1 << PIN_RW); - PORTB = 0; + ao_lcd_port_init(); ao_cmd_register(&ao_lcd_cmds[0]); } -- cgit v1.2.3 From a7b285ec0945830b8b31877115157ddd12d6a9fb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 27 Oct 2011 00:57:45 -0700 Subject: altos: Add i2c driver for avr chip Signed-off-by: Keith Packard --- src/avr/ao_i2c_usart.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/avr/ao_i2c_usart.c (limited to 'src/avr') diff --git a/src/avr/ao_i2c_usart.c b/src/avr/ao_i2c_usart.c new file mode 100644 index 00000000..60e35f8c --- /dev/null +++ b/src/avr/ao_i2c_usart.c @@ -0,0 +1,101 @@ +/* + * 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" + +/* + * Atmega32u4 TWI master mode (I2C) + */ + +__xdata uint8_t ao_i2c_mutex; + +/* Send bytes over I2C. + * + * This just polls; the I2C is set to go as fast as possible, + * so using interrupts would take way too long + */ +void +ao_i2c_send(void __xdata *block, uint16_t len) __reentrant +{ + uint8_t *d = block; + + ao_mutex_get(&ao_i2c_mutex); + while (len--) { + while (!(UCSR1A & (1 << UDRE1))); + UDR1 = *d++; + while (!(UCSR1A & (1 << RXC1))); + (void) UDR1; + } + ao_mutex_put(&ao_i2c_mutex); +} + +/* Receive bytes over I2C. + * + * This sets up tow DMA engines, one reading the data and another + * writing constant values to the I2C transmitter as that is what + * clocks the data coming in. + */ +void +ao_i2c_recv(void __xdata *block, uint16_t len) __reentrant +{ + uint8_t *d = block; + + ao_mutex_get(&ao_i2c_mutex); + while (len--) { + while (!(UCSR1A & (1 << UDRE1))); + UDR1 = 0; + while (!(UCSR1A & (1 << RXC1))); + *d++ = UDR1; + } + ao_mutex_put(&ao_i2c_mutex); +} + +#define XCK1_DDR DDRD +#define XCK1_PORT PORTD +#define XCK1 PORTD5 +#define XMS1_DDR DDRE +#define XMS1_PORT PORTE +#define XMS1 PORTE6 + +void +ao_i2c_init(void) +{ + /* Ensure the TWI is powered */ + + /* + * Set pin directions + */ + XCK1_DDR |= (1 << XCK1); + + /* Clear chip select (which is negated) */ + XMS1_PORT |= (1 < XMS1); + XMS1_DDR |= (1 << XMS1); + + /* Set baud register to zero (required before turning transmitter on) */ + UBRR1 = 0; + + UCSR1C = ((0x3 << UMSEL10) | /* Master I2C mode */ + (0 << UCSZ10) | /* I2C mode 0 */ + (0 << UCPOL1)); /* I2C mode 0 */ + + /* Enable transmitter and receiver */ + UCSR1B = ((1 << RXEN1) | + (1 << TXEN1)); + + /* It says that 0 is a legal value; we'll see... */ + UBRR1 = 0; +} -- cgit v1.2.3 From 6a14bee42a8431c909bcd74b0acec57329bc0284 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 19 Mar 2012 11:24:43 -0700 Subject: Don't disable interrupts before saving interrupt flag on AVR This ignores the interrupt disabled state, so we'd always leave ao_yield with interrupts disabled. Signed-off-by: Keith Packard --- src/avr/ao_arch.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/avr') diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index c189ccba..b816279e 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -105,7 +105,6 @@ extern uint8_t ao_cpu_sleep_disable; asm("push r14" "\n\t" "push r13" "\n\t" "push r12" "\n\t" "push r11" "\n\t" "push r10"); \ asm("push r9" "\n\t" "push r8" "\n\t" "push r7" "\n\t" "push r6" "\n\t" "push r5"); \ asm("push r4" "\n\t" "push r3" "\n\t" "push r2" "\n\t" "push r1" "\n\t" "push r0"); \ - cli(); \ asm("in r0, __SREG__" "\n\t" "push r0"); \ sei(); \ } while (0) -- cgit v1.2.3 From cf1e4d60e1fcd75fa734365a2666ea8930938128 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 2 Apr 2012 22:58:54 -0700 Subject: altos: Move SPI functions to architecture-specific location Some architecture specific stuff needs to use core altos code, so create new ao_arch_funcs.h files per architecture that get pulled in at the end of ao.h Signed-off-by: Keith Packard --- src/avr/ao_arch_funcs.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++ src/cc1111/ao_arch_funcs.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++ src/core/ao.h | 43 ++-------------------------------- src/stm/ao_arch_funcs.h | 35 ++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 41 deletions(-) create mode 100644 src/avr/ao_arch_funcs.h create mode 100644 src/cc1111/ao_arch_funcs.h create mode 100644 src/stm/ao_arch_funcs.h (limited to 'src/avr') diff --git a/src/avr/ao_arch_funcs.h b/src/avr/ao_arch_funcs.h new file mode 100644 index 00000000..9ad14fbb --- /dev/null +++ b/src/avr/ao_arch_funcs.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +/* + * ao_spi.c + */ + +extern __xdata uint8_t ao_spi_mutex; + +#define ao_spi_get_mask(reg,mask) do {\ + ao_mutex_get(&ao_spi_mutex); \ + (reg) &= ~(mask); \ + } while (0) + +#define ao_spi_put_mask(reg,mask) do { \ + (reg) |= (mask); \ + ao_mutex_put(&ao_spi_mutex); \ + } while (0) + +#define ao_spi_get_bit(bit) do {\ + ao_mutex_get(&ao_spi_mutex); \ + (bit) = 0; \ + } while (0) + +#define ao_spi_put_bit(bit) do { \ + (bit) = 1; \ + ao_mutex_put(&ao_spi_mutex); \ + } while (0) + +/* + * The SPI mutex must be held to call either of these + * functions -- this mutex covers the entire SPI operation, + * from chip select low to chip select high + */ + +void +ao_spi_send(void __xdata *block, uint16_t len) __reentrant; + +void +ao_spi_recv(void __xdata *block, uint16_t len) __reentrant; + +void +ao_spi_init(void); + diff --git a/src/cc1111/ao_arch_funcs.h b/src/cc1111/ao_arch_funcs.h new file mode 100644 index 00000000..9ad14fbb --- /dev/null +++ b/src/cc1111/ao_arch_funcs.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +/* + * ao_spi.c + */ + +extern __xdata uint8_t ao_spi_mutex; + +#define ao_spi_get_mask(reg,mask) do {\ + ao_mutex_get(&ao_spi_mutex); \ + (reg) &= ~(mask); \ + } while (0) + +#define ao_spi_put_mask(reg,mask) do { \ + (reg) |= (mask); \ + ao_mutex_put(&ao_spi_mutex); \ + } while (0) + +#define ao_spi_get_bit(bit) do {\ + ao_mutex_get(&ao_spi_mutex); \ + (bit) = 0; \ + } while (0) + +#define ao_spi_put_bit(bit) do { \ + (bit) = 1; \ + ao_mutex_put(&ao_spi_mutex); \ + } while (0) + +/* + * The SPI mutex must be held to call either of these + * functions -- this mutex covers the entire SPI operation, + * from chip select low to chip select high + */ + +void +ao_spi_send(void __xdata *block, uint16_t len) __reentrant; + +void +ao_spi_recv(void __xdata *block, uint16_t len) __reentrant; + +void +ao_spi_init(void); + diff --git a/src/core/ao.h b/src/core/ao.h index 8263a529..080cadb2 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -940,47 +940,6 @@ ao_serial0_init(void); #endif -/* - * ao_spi.c - */ - -extern __xdata uint8_t ao_spi_mutex; - -#define ao_spi_get_mask(reg,mask) do {\ - ao_mutex_get(&ao_spi_mutex); \ - (reg) &= ~(mask); \ - } while (0) - -#define ao_spi_put_mask(reg,mask) do { \ - (reg) |= (mask); \ - ao_mutex_put(&ao_spi_mutex); \ - } while (0) - -#define ao_spi_get_bit(bit) do {\ - ao_mutex_get(&ao_spi_mutex); \ - (bit) = 0; \ - } while (0) - -#define ao_spi_put_bit(bit) do { \ - (bit) = 1; \ - ao_mutex_put(&ao_spi_mutex); \ - } while (0) - -/* - * The SPI mutex must be held to call either of these - * functions -- this mutex covers the entire SPI operation, - * from chip select low to chip select high - */ - -void -ao_spi_send(void __xdata *block, uint16_t len) __reentrant; - -void -ao_spi_recv(void __xdata *block, uint16_t len) __reentrant; - -void -ao_spi_init(void); - /* * ao_spi_slave.c */ @@ -1934,4 +1893,6 @@ ao_sqrt(uint32_t op); int32_t ao_freq_to_set(int32_t freq, int32_t cal); +#include + #endif /* _AO_H_ */ diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h new file mode 100644 index 00000000..9b68f19a --- /dev/null +++ b/src/stm/ao_arch_funcs.h @@ -0,0 +1,35 @@ +/* + * 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_ARCH_FUNCS_H_ +#define _AO_ARCH_FUNCS_H_ + +extern uint8_t ao_spi_mutex[STM_NUM_SPI]; + +static inline void ao_spi_get(uint8_t spi_index) { ao_mutex_get(&ao_spi_mutex[spi_index]); } +static inline void ao_spi_put(uint8_t spi_index) { ao_mutex_put(&ao_spi_mutex[spi_index]); } + +void +ao_spi_send(void *block, uint16_t len, uint8_t spi_index); + +void +ao_spi_recv(void *block, uint16_t len, uint8_t spi_index); + +void +ao_spi_init(uint8_t spi_index); + +#endif /* _AO_ARCH_FUNCS_H_ */ -- cgit v1.2.3 From 0dd9e1dd62656a931f9559af6da9131f704f83f9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 9 Apr 2012 23:27:43 -0700 Subject: altos: Add support for multiple SPI busses and sharing device drivers The STM32L151 has several SPI busses, and we want to use more than one, so add a 'bus' parameter to the SPI interfaces. To avoid wasting time on AVR and CC1111 processors which only use one SPI bus, elide those parameters from the actual functions by wrapping them with macros. Configuring chip select is now all macroized so that each chip can have its own version, allowing the STM to share the various SPI device drivers with the cc1111 and avr processors. Note that only the M25 driver has been ported; porting the others is 'trivial', but not necessary at this point. Signed-off-by: Keith Packard --- src/avr/ao_arch_funcs.h | 35 +++++++++++++++----------- src/avr/ao_pins.h | 3 +++ src/avr/ao_spi_usart.c | 4 +-- src/cc1111/ao_arch_funcs.h | 21 +++++++++++----- src/cc1111/ao_pins.h | 8 +++--- src/cc1111/ao_spi.c | 4 +-- src/drivers/ao_25lc1024.c | 20 +++++++-------- src/drivers/ao_at45db161d.c | 18 +++++++------- src/drivers/ao_companion.c | 10 ++++---- src/drivers/ao_m25.c | 43 ++++++++++++++------------------ src/drivers/ao_ms5607.c | 5 +--- src/megametrum-v0.1/Makefile | 4 ++- src/megametrum-v0.1/ao_megametrum.c | 1 + src/megametrum-v0.1/ao_pins.h | 9 +++++++ src/stm/ao_arch_funcs.h | 49 +++++++++++++++++++++++++++++++++++++ src/teleterra-v0.2/ao_pins.h | 3 +++ 16 files changed, 157 insertions(+), 80 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_arch_funcs.h b/src/avr/ao_arch_funcs.h index 9ad14fbb..1eeca6cc 100644 --- a/src/avr/ao_arch_funcs.h +++ b/src/avr/ao_arch_funcs.h @@ -21,24 +21,24 @@ extern __xdata uint8_t ao_spi_mutex; -#define ao_spi_get_mask(reg,mask) do {\ - ao_mutex_get(&ao_spi_mutex); \ - (reg) &= ~(mask); \ +#define ao_spi_get_mask(reg,mask,bus) do { \ + ao_mutex_get(&ao_spi_mutex); \ + (reg) &= ~(mask); \ } while (0) -#define ao_spi_put_mask(reg,mask) do { \ - (reg) |= (mask); \ - ao_mutex_put(&ao_spi_mutex); \ +#define ao_spi_put_mask(reg,mask,bus) do { \ + (reg) |= (mask); \ + ao_mutex_put(&ao_spi_mutex); \ } while (0) -#define ao_spi_get_bit(bit) do {\ - ao_mutex_get(&ao_spi_mutex); \ - (bit) = 0; \ +#define ao_spi_get_bit(bit) do { \ + ao_mutex_get(&ao_spi_mutex); \ + (bit) = 0; \ } while (0) -#define ao_spi_put_bit(bit) do { \ - (bit) = 1; \ - ao_mutex_put(&ao_spi_mutex); \ +#define ao_spi_put_bit(bit) do { \ + (bit) = 1; \ + ao_mutex_put(&ao_spi_mutex); \ } while (0) /* @@ -48,11 +48,18 @@ extern __xdata uint8_t ao_spi_mutex; */ void -ao_spi_send(void __xdata *block, uint16_t len) __reentrant; +ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant; void -ao_spi_recv(void __xdata *block, uint16_t len) __reentrant; +ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant; + +#define ao_spi_send(block, len, bus) ao_spi_send_bus(block, len) +#define ao_spi_recv(block, len, bus) ao_spi_recv_bus(block, len) void ao_spi_init(void); +#define ao_spi_init_cs(port, mask) do { \ + SPI_CS_PORT |= (mask); \ + SPI_CS_DIR |= (mask); \ + } while (0) diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index bf02db1b..6a63468f 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -85,4 +85,7 @@ #define SPI_SLAVE_PIN_2_5 0 #endif +#define AO_M25_SPI_CS_PORT SPI_CS_PORT +#define AO_M25_SPI_CS_MASK M25_CS_MASK + #endif /* _AO_PINS_H_ */ diff --git a/src/avr/ao_spi_usart.c b/src/avr/ao_spi_usart.c index 5ea11da6..7c41042a 100644 --- a/src/avr/ao_spi_usart.c +++ b/src/avr/ao_spi_usart.c @@ -29,7 +29,7 @@ __xdata uint8_t ao_spi_mutex; * so using interrupts would take way too long */ void -ao_spi_send(void __xdata *block, uint16_t len) __reentrant +ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant { uint8_t *d = block; @@ -46,7 +46,7 @@ ao_spi_send(void __xdata *block, uint16_t len) __reentrant * Poll, sending zeros and reading data back */ void -ao_spi_recv(void __xdata *block, uint16_t len) __reentrant +ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant { uint8_t *d = block; diff --git a/src/cc1111/ao_arch_funcs.h b/src/cc1111/ao_arch_funcs.h index 9ad14fbb..d9f5955a 100644 --- a/src/cc1111/ao_arch_funcs.h +++ b/src/cc1111/ao_arch_funcs.h @@ -21,26 +21,27 @@ extern __xdata uint8_t ao_spi_mutex; -#define ao_spi_get_mask(reg,mask) do {\ +#define ao_spi_get_mask(reg,mask,bus) do { \ ao_mutex_get(&ao_spi_mutex); \ (reg) &= ~(mask); \ } while (0) -#define ao_spi_put_mask(reg,mask) do { \ +#define ao_spi_put_mask(reg,mask,bus) do { \ (reg) |= (mask); \ ao_mutex_put(&ao_spi_mutex); \ } while (0) -#define ao_spi_get_bit(bit) do {\ +#define ao_spi_get_bit(bit,bus) do { \ ao_mutex_get(&ao_spi_mutex); \ (bit) = 0; \ } while (0) -#define ao_spi_put_bit(bit) do { \ +#define ao_spi_put_bit(bit,bus) do { \ (bit) = 1; \ ao_mutex_put(&ao_spi_mutex); \ } while (0) + /* * The SPI mutex must be held to call either of these * functions -- this mutex covers the entire SPI operation, @@ -48,11 +49,19 @@ extern __xdata uint8_t ao_spi_mutex; */ void -ao_spi_send(void __xdata *block, uint16_t len) __reentrant; +ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant; void -ao_spi_recv(void __xdata *block, uint16_t len) __reentrant; +ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant; + +#define ao_spi_send(block, len, bus) ao_spi_send_bus(block, len) +#define ao_spi_recv(block, len, bus) ao_spi_recv_bus(block, len) void ao_spi_init(void); +#define ao_spi_init_cs(port, mask) do { \ + SPI_CS_PORT |= mask; \ + SPI_CS_DIR |= mask; \ + SPI_CS_SEL &= ~mask; \ + } while (0) diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index a18c74c8..5c0cb7df 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -82,7 +82,7 @@ #define HAS_ACCEL_REF 1 #define SPI_CS_ON_P1 1 #define SPI_CS_ON_P0 0 - #define M25_CS_MASK 0x02 /* CS0 is P1_1 */ + #define AO_M25_SPI_CS_MASK 0x02 /* CS0 is P1_1 */ #define M25_MAX_CHIPS 1 #define HAS_ACCEL 1 #define HAS_IGNITE 1 @@ -119,7 +119,7 @@ #define HAS_ACCEL_REF 1 #define SPI_CS_ON_P1 1 #define SPI_CS_ON_P0 0 - #define M25_CS_MASK 0x02 /* CS0 is P1_1 */ + #define AO_M25_SPI_CS_MASK 0x02 /* CS0 is P1_1 */ #define M25_MAX_CHIPS 1 #define HAS_ACCEL 1 #define HAS_IGNITE 1 @@ -358,7 +358,7 @@ #define LEDS_AVAILABLE (AO_LED_RED|AO_LED_GREEN) #define SPI_CS_ON_P1 1 #define SPI_CS_ON_P0 0 - #define M25_CS_MASK 0x04 /* CS0 is P1_2 */ + #define AO_M25_SPI_CS_MASK 0x04 /* CS0 is P1_2 */ #define M25_MAX_CHIPS 1 #define HAS_ACCEL 0 #define HAS_IGNITE 0 @@ -458,6 +458,8 @@ #define SPI_CS_DIR P0DIR #endif +#define AO_M25_SPI_CS_PORT SPI_CS_PORT + #ifndef IGNITE_ON_P2 #error Please define IGNITE_ON_P2 #endif diff --git a/src/cc1111/ao_spi.c b/src/cc1111/ao_spi.c index 1fa8e128..1bf5e155 100644 --- a/src/cc1111/ao_spi.c +++ b/src/cc1111/ao_spi.c @@ -38,7 +38,7 @@ static __xdata uint8_t ao_spi_const; * completion one byte before the transfer is actually complete */ void -ao_spi_send(void __xdata *block, uint16_t len) __reentrant +ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant { ao_dma_set_transfer(ao_spi_dma_in_id, &U0DBUFXADDR, @@ -76,7 +76,7 @@ ao_spi_send(void __xdata *block, uint16_t len) __reentrant * clocks the data coming in. */ void -ao_spi_recv(void __xdata *block, uint16_t len) __reentrant +ao_spi_recv_bus(void __xdata *block, uint16_t len) __reentrant { ao_dma_set_transfer(ao_spi_dma_in_id, &U0DBUFXADDR, diff --git a/src/drivers/ao_25lc1024.c b/src/drivers/ao_25lc1024.c index 2d047a44..f0fb13c9 100644 --- a/src/drivers/ao_25lc1024.c +++ b/src/drivers/ao_25lc1024.c @@ -49,9 +49,9 @@ static __xdata uint8_t ao_ee_mutex; _asm nop _endasm; \ } while(0) -#define ao_ee_cs_low() ao_spi_get_bit(EE_CS) +#define ao_ee_cs_low() ao_spi_get_bit(EE_CS, AO_EE_SPI_BUS) -#define ao_ee_cs_high() ao_spi_put_bit(EE_CS) +#define ao_ee_cs_high() ao_spi_put_bit(EE_CS, AO_EE_SPI_BUS) struct ao_ee_instruction { uint8_t instruction; @@ -63,7 +63,7 @@ ao_ee_write_enable(void) { ao_ee_cs_low(); ao_ee_instruction.instruction = EE_WREN; - ao_spi_send(&ao_ee_instruction, 1); + ao_spi_send(&ao_ee_instruction, 1, AO_EE_SPI_BUS); ao_ee_cs_high(); } @@ -72,8 +72,8 @@ ao_ee_rdsr(void) { ao_ee_cs_low(); ao_ee_instruction.instruction = EE_RDSR; - ao_spi_send(&ao_ee_instruction, 1); - ao_spi_recv(&ao_ee_instruction, 1); + ao_spi_send(&ao_ee_instruction, 1, AO_EE_SPI_BUS); + ao_spi_recv(&ao_ee_instruction, 1, AO_EE_SPI_BUS); ao_ee_cs_high(); return ao_ee_instruction.instruction; } @@ -84,7 +84,7 @@ ao_ee_wrsr(uint8_t status) ao_ee_cs_low(); ao_ee_instruction.instruction = EE_WRSR; ao_ee_instruction.address[0] = status; - ao_spi_send(&ao_ee_instruction, 2); + ao_spi_send(&ao_ee_instruction, 2, AO_EE_SPI_BUS); ao_ee_cs_high(); } @@ -111,8 +111,8 @@ ao_ee_write_block(void) ao_ee_instruction.address[0] = ao_ee_block >> 8; ao_ee_instruction.address[1] = ao_ee_block; ao_ee_instruction.address[2] = 0; - ao_spi_send(&ao_ee_instruction, 4); - ao_spi_send(ao_ee_data, EE_BLOCK_SIZE); + ao_spi_send(&ao_ee_instruction, 4, AO_EE_SPI_BUS); + ao_spi_send(ao_ee_data, EE_BLOCK_SIZE, AO_EE_SPI_BUS); ao_ee_cs_high(); for (;;) { uint8_t status = ao_ee_rdsr(); @@ -130,8 +130,8 @@ ao_ee_read_block(void) ao_ee_instruction.address[0] = ao_ee_block >> 8; ao_ee_instruction.address[1] = ao_ee_block; ao_ee_instruction.address[2] = 0; - ao_spi_send(&ao_ee_instruction, 4); - ao_spi_recv(ao_ee_data, EE_BLOCK_SIZE); + ao_spi_send(&ao_ee_instruction, 4, AO_EE_SPI_BUS); + ao_spi_recv(ao_ee_data, EE_BLOCK_SIZE, AO_EE_SPI_BUS); ao_ee_cs_high(); } diff --git a/src/drivers/ao_at45db161d.c b/src/drivers/ao_at45db161d.c index 6cd689e5..afe0080b 100644 --- a/src/drivers/ao_at45db161d.c +++ b/src/drivers/ao_at45db161d.c @@ -43,9 +43,9 @@ __xdata uint8_t ao_flash_mutex; _asm nop _endasm; \ } while(0) -#define ao_flash_cs_low() ao_spi_get_bit(FLASH_CS) +#define ao_flash_cs_low() ao_spi_get_bit(FLASH_CS, AO_FLASH_SPI_BUS) -#define ao_flash_cs_high() ao_spi_put_bit(FLASH_CS) +#define ao_flash_cs_high() ao_spi_put_bit(FLASH_CS, AO_FLASH_SPI_BUS) struct ao_flash_instruction { uint8_t instruction; @@ -60,7 +60,7 @@ ao_flash_set_pagesize_512(void) ao_flash_instruction.address[0] = FLASH_SET_512_BYTE_0; ao_flash_instruction.address[1] = FLASH_SET_512_BYTE_1; ao_flash_instruction.address[2] = FLASH_SET_512_BYTE_2; - ao_spi_send(&ao_flash_instruction, 4); + ao_spi_send(&ao_flash_instruction, 4, AO_FLASH_SPI_BUS); ao_flash_cs_high(); } @@ -70,8 +70,8 @@ ao_flash_read_status(void) { ao_flash_cs_low(); ao_flash_instruction.instruction = FLASH_READ_STATUS; - ao_spi_send(&ao_flash_instruction, 1); - ao_spi_recv(&ao_flash_instruction, 1); + ao_spi_send(&ao_flash_instruction, 1, AO_FLASH_SPI_BUS); + ao_spi_recv(&ao_flash_instruction, 1, AO_FLASH_SPI_BUS); ao_flash_cs_high(); return ao_flash_instruction.instruction; } @@ -190,8 +190,8 @@ ao_flash_write_block(void) ao_flash_instruction.address[0] = ao_flash_block >> (16 - ao_flash_block_shift); ao_flash_instruction.address[1] = ao_flash_block << (ao_flash_block_shift - 8); ao_flash_instruction.address[2] = 0; - ao_spi_send(&ao_flash_instruction, 4); - ao_spi_send(ao_flash_data, ao_storage_block); + ao_spi_send(&ao_flash_instruction, 4, AO_FLASH_SPI_BUS); + ao_spi_send(ao_flash_data, ao_storage_block, AO_FLASH_SPI_BUS); ao_flash_cs_high(); ao_flash_write_pending = 1; } @@ -208,8 +208,8 @@ ao_flash_read_block(void) ao_flash_instruction.address[0] = ao_flash_block >> (16 - ao_flash_block_shift); ao_flash_instruction.address[1] = ao_flash_block << (ao_flash_block_shift - 8); ao_flash_instruction.address[2] = 0; - ao_spi_send(&ao_flash_instruction, 4); - ao_spi_recv(ao_flash_data, ao_flash_block_size); + ao_spi_send(&ao_flash_instruction, 4, AO_FLASH_SPI_BUS); + ao_spi_recv(ao_flash_data, ao_flash_block_size, AO_FLASH_SPI_BUS); ao_flash_cs_high(); } diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index 2e587f8e..fe88e998 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -27,8 +27,8 @@ UxGCR_ORDER_MSB | \ (17 << UxGCR_BAUD_E_SHIFT))) -#define COMPANION_SELECT() do { ao_spi_get_bit(COMPANION_CS); ao_spi_slow(); } while (0) -#define COMPANION_DESELECT() do { ao_spi_fast(); ao_spi_put_bit(COMPANION_CS); } while (0) +#define COMPANION_SELECT() do { ao_spi_get_bit(COMPANION_CS, AO_COMPANION_BUS); ao_spi_slow(); } while (0) +#define COMPANION_DESELECT() do { ao_spi_fast(); ao_spi_put_bit(COMPANION_CS, AO_COMPANION_BUS); } while (0) __xdata struct ao_companion_command ao_companion_command; __xdata struct ao_companion_setup ao_companion_setup; @@ -45,7 +45,7 @@ ao_companion_send_command(uint8_t command) ao_companion_command.tick = ao_time(); ao_companion_command.serial = ao_serial_number; ao_companion_command.flight = ao_flight_number; - ao_spi_send(&ao_companion_command, sizeof (ao_companion_command)); + ao_spi_send(&ao_companion_command, sizeof (ao_companion_command), AO_COMPANION_SPI_BUS); } static uint8_t @@ -53,7 +53,7 @@ ao_companion_get_setup(void) { COMPANION_SELECT(); ao_companion_send_command(AO_COMPANION_SETUP); - ao_spi_recv(&ao_companion_setup, sizeof (ao_companion_setup)); + ao_spi_recv(&ao_companion_setup, sizeof (ao_companion_setup), AO_COMPANION_SPI_BUS); COMPANION_DESELECT(); return (ao_companion_setup.board_id == ~ao_companion_setup.board_id_inverse); @@ -65,7 +65,7 @@ ao_companion_get_data(void) COMPANION_SELECT(); ao_companion_send_command(AO_COMPANION_FETCH); ao_mutex_get(&ao_companion_mutex); - ao_spi_recv(&ao_companion_data, ao_companion_setup.channels * 2); + ao_spi_recv(&ao_companion_data, ao_companion_setup.channels * 2, AO_COMPANION_SPI_BUS); ao_mutex_put(&ao_companion_mutex); COMPANION_DESELECT(); } diff --git a/src/drivers/ao_m25.c b/src/drivers/ao_m25.c index 28cb1dd7..c807cd68 100644 --- a/src/drivers/ao_m25.c +++ b/src/drivers/ao_m25.c @@ -99,8 +99,8 @@ static __xdata uint8_t ao_m25_mutex; static __xdata uint8_t ao_m25_instruction[4]; -#define M25_SELECT(cs) ao_spi_get_mask(SPI_CS_PORT,cs) -#define M25_DESELECT(cs) ao_spi_put_mask(SPI_CS_PORT,cs) +#define M25_SELECT(cs) ao_spi_get_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS) +#define M25_DESELECT(cs) ao_spi_put_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS) #define M25_BLOCK_SHIFT 16 #define M25_BLOCK 65536L @@ -116,9 +116,9 @@ ao_m25_wait_wip(uint8_t cs) if (ao_m25_wip & cs) { M25_SELECT(cs); ao_m25_instruction[0] = M25_RDSR; - ao_spi_send(ao_m25_instruction, 1); + ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS); do { - ao_spi_recv(ao_m25_instruction, 1); + ao_spi_recv(ao_m25_instruction, 1, AO_M25_SPI_BUS); } while (ao_m25_instruction[0] & M25_STATUS_WIP); M25_DESELECT(cs); ao_m25_wip &= ~cs; @@ -135,7 +135,7 @@ ao_m25_write_enable(uint8_t cs) { M25_SELECT(cs); ao_m25_instruction[0] = M25_WREN; - ao_spi_send(&ao_m25_instruction, 1); + ao_spi_send(&ao_m25_instruction, 1, AO_M25_SPI_BUS); M25_DESELECT(cs); ao_m25_wip |= cs; } @@ -150,8 +150,8 @@ ao_m25_read_capacity(uint8_t cs) uint8_t capacity; M25_SELECT(cs); ao_m25_instruction[0] = M25_RDID; - ao_spi_send(ao_m25_instruction, 1); - ao_spi_recv(ao_m25_instruction, M25_RDID_LEN); + ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS); + ao_spi_recv(ao_m25_instruction, M25_RDID_LEN, AO_M25_SPI_BUS); M25_DESELECT(cs); /* Check to see if the chip is present */ @@ -183,7 +183,7 @@ ao_m25_set_address(uint32_t pos) chip = ao_m25_pin[chip]; #else - chip = M25_CS_MASK; + chip = AO_M25_SPI_CS_MASK; #endif ao_m25_wait_wip(chip); @@ -210,7 +210,7 @@ ao_m25_scan(void) #if M25_MAX_CHIPS > 1 ao_m25_numchips = 0; for (pin = 1; pin != 0; pin <<= 1) { - if (M25_CS_MASK & pin) { + if (AO_M25_SPI_CS_MASK & pin) { size = ao_m25_read_capacity(pin); if (size != 0) { ao_m25_size[ao_m25_numchips] = size; @@ -221,7 +221,7 @@ ao_m25_scan(void) } } #else - ao_m25_total = ao_m25_read_capacity(M25_CS_MASK); + ao_m25_total = ao_m25_read_capacity(AO_M25_SPI_CS_MASK); #endif if (!ao_m25_total) return 0; @@ -253,7 +253,7 @@ ao_storage_erase(uint32_t pos) __reentrant ao_m25_instruction[0] = M25_SE; M25_SELECT(cs); - ao_spi_send(ao_m25_instruction, 4); + ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS); M25_DESELECT(cs); ao_m25_wip |= cs; @@ -280,8 +280,8 @@ ao_storage_device_write(uint32_t pos, __xdata void *d, uint16_t len) __reentrant ao_m25_instruction[0] = M25_PP; M25_SELECT(cs); - ao_spi_send(ao_m25_instruction, 4); - ao_spi_send(d, len); + ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS); + ao_spi_send(d, len, AO_M25_SPI_BUS); M25_DESELECT(cs); ao_mutex_put(&ao_m25_mutex); @@ -306,8 +306,8 @@ ao_storage_device_read(uint32_t pos, __xdata void *d, uint16_t len) __reentrant /* No need to use the FAST_READ as we're running at only 8MHz */ ao_m25_instruction[0] = M25_READ; M25_SELECT(cs); - ao_spi_send(ao_m25_instruction, 4); - ao_spi_recv(d, len); + ao_spi_send(ao_m25_instruction, 4, AO_M25_SPI_BUS); + ao_spi_recv(d, len, AO_M25_SPI_BUS); M25_DESELECT(cs); ao_mutex_put(&ao_m25_mutex); @@ -350,14 +350,14 @@ ao_storage_device_info(void) __reentrant printf ("Available chips:\n"); for (cs = 1; cs != 0; cs <<= 1) { - if ((M25_CS_MASK & cs) == 0) + if ((AO_M25_SPI_CS_MASK & cs) == 0) continue; ao_mutex_get(&ao_m25_mutex); M25_SELECT(cs); ao_m25_instruction[0] = M25_RDID; - ao_spi_send(ao_m25_instruction, 1); - ao_spi_recv(ao_m25_instruction, M25_RDID_LEN); + ao_spi_send(ao_m25_instruction, 1, AO_M25_SPI_BUS); + ao_spi_recv(ao_m25_instruction, M25_RDID_LEN, AO_M25_SPI_BUS); M25_DESELECT(cs); printf ("Select %02x manf %02x type %02x cap %02x uid %02x\n", @@ -373,10 +373,5 @@ ao_storage_device_info(void) __reentrant void ao_storage_device_init(void) { - /* Set up chip select wires */ - SPI_CS_PORT |= M25_CS_MASK; /* raise all CS pins */ - SPI_CS_DIR |= M25_CS_MASK; /* set CS pins as outputs */ -#ifdef SPI_CS_SEL - SPI_CS_SEL &= ~M25_CS_MASK; /* set CS pins as GPIO */ -#endif + ao_spi_init_cs (AO_M25_SPI_CS_PORT, AO_M25_SPI_CS_MASK); } diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index 87748272..3c0a310d 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -155,8 +155,5 @@ void ao_ms5607_init(void) { ao_cmd_register(&ao_ms5607_cmds[0]); - - stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOCEN); - stm_gpio_set(&AO_MS5607_CS_GPIO, AO_MS5607_CS, 1); - stm_moder_set(&AO_MS5607_CS_GPIO, AO_MS5607_CS, STM_MODER_OUTPUT); + ao_spi_init_cs(AO_MS5607_CS_GPIO, (1 << AO_MS5607_CS)); } diff --git a/src/megametrum-v0.1/Makefile b/src/megametrum-v0.1/Makefile index 5b20a8a5..b0f2a612 100644 --- a/src/megametrum-v0.1/Makefile +++ b/src/megametrum-v0.1/Makefile @@ -38,7 +38,9 @@ ALTOS_SRC = \ ao_spi_stm.c \ ao_ms5607.c \ ao_adc_stm.c \ - ao_beep_stm.c + ao_beep_stm.c \ + ao_storage.c \ + ao_m25.c PRODUCT=MegaMetrum-v0.1 PRODUCT_DEF=-DMEGAMETRUM diff --git a/src/megametrum-v0.1/ao_megametrum.c b/src/megametrum-v0.1/ao_megametrum.c index eaab9b50..77a2bf0a 100644 --- a/src/megametrum-v0.1/ao_megametrum.c +++ b/src/megametrum-v0.1/ao_megametrum.c @@ -49,6 +49,7 @@ main(void) ao_ms5607_init(); ao_beep_init(); ao_adc_init(); + ao_storage_init(); ao_cmd_register(&ao_mm_cmds[0]); ao_start_scheduler(); diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index e200a692..46098d34 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -182,4 +182,13 @@ struct ao_adc { #define AO_MS5607_CS_MASK (1 << AO_MS5607_CS) #define AO_MS5607_SPI_INDEX (STM_SPI_INDEX(1)) +/* + * SPI Flash memory + */ + +#define M25_MAX_CHIPS 1 +#define AO_M25_SPI_CS_PORT stm_gpiod +#define AO_M25_SPI_CS_MASK (1 << 3) +#define AO_M25_SPI_BUS STM_SPI_INDEX(2) + #endif /* _AO_PINS_H_ */ diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 052abb65..309937d5 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -37,6 +37,55 @@ ao_spi_recv(void *block, uint16_t len, uint8_t spi_index); void ao_spi_init(void); +#define ao_spi_get_mask(reg,mask,bus) do { \ + ao_spi_get(bus); \ + (reg).bsrr = ((uint32_t) mask) << 16; \ + } while (0) + +#define ao_spi_put_mask(reg,mask,bus) do { \ + (reg).bsrr = mask; \ + ao_spi_put(bus); \ + } while (0) + +#define ao_stm_enable_port(port) do { \ + if (&(port) == &stm_gpioa) \ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); \ + else if (&(port) == &stm_gpiob) \ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); \ + else if (&(port) == &stm_gpioc) \ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOCEN); \ + else if (&(port) == &stm_gpiod) \ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIODEN); \ + else if (&(port) == &stm_gpioe) \ + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOEEN); \ + } while (0) + + +#define ao_stm_enable_cs(port,bit) do { \ + stm_gpio_set(&(port), bit, 1); \ + stm_moder_set(&(port), bit, STM_MODER_OUTPUT); \ + } while (0) + +#define ao_spi_init_cs(port, mask) do { \ + ao_stm_enable_port(port); \ + if (mask & 0x0001) ao_stm_enable_cs(port, 0); \ + if (mask & 0x0002) ao_stm_enable_cs(port, 1); \ + if (mask & 0x0004) ao_stm_enable_cs(port, 2); \ + if (mask & 0x0008) ao_stm_enable_cs(port, 3); \ + if (mask & 0x0010) ao_stm_enable_cs(port, 4); \ + if (mask & 0x0020) ao_stm_enable_cs(port, 5); \ + if (mask & 0x0040) ao_stm_enable_cs(port, 6); \ + if (mask & 0x0080) ao_stm_enable_cs(port, 7); \ + if (mask & 0x0100) ao_stm_enable_cs(port, 8); \ + if (mask & 0x0200) ao_stm_enable_cs(port, 9); \ + if (mask & 0x0400) ao_stm_enable_cs(port, 10); \ + if (mask & 0x0800) ao_stm_enable_cs(port, 11); \ + if (mask & 0x1000) ao_stm_enable_cs(port, 12); \ + if (mask & 0x2000) ao_stm_enable_cs(port, 13); \ + if (mask & 0x4000) ao_stm_enable_cs(port, 14); \ + if (mask & 0x8000) ao_stm_enable_cs(port, 15); \ + } while (0) + /* ao_dma_stm.c */ diff --git a/src/teleterra-v0.2/ao_pins.h b/src/teleterra-v0.2/ao_pins.h index 44a372cc..29b97385 100644 --- a/src/teleterra-v0.2/ao_pins.h +++ b/src/teleterra-v0.2/ao_pins.h @@ -229,4 +229,7 @@ #define AO_IGNITER_FIRE_TIME AO_MS_TO_TICKS(50) #define AO_IGNITER_CHARGE_TIME AO_MS_TO_TICKS(2000) +#define AO_M25_SPI_CS_PORT SPI_CS_PORT +#define AO_M25_SPI_CS_MASK M25_CS_MASK + #endif /* _AO_PINS_H_ */ -- cgit v1.2.3 From 040a6eb119451026e1ec7c3a6a8e76b439c632d5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 12 Apr 2012 14:51:07 -0700 Subject: altos: Massive product config cleanup Support multiple serial ports more cleanly Split out parts of ao.h into separate feature header files Signed-off-by: Keith Packard --- src/avr/ao_arch.h | 7 - src/avr/ao_pins.h | 15 +- src/avr/ao_serial_avr.c | 62 +-- src/avr/ao_usb.h | 100 ----- src/avr/ao_usb_avr.c | 6 +- src/cc1111/ao_arch.h | 30 ++ src/cc1111/ao_pins.h | 24 +- src/cc1111/ao_serial.c | 227 +++++++++-- src/cc1111/ao_serial0.c | 152 -------- src/cc1111/ao_usb.c | 6 +- src/cc1111/ao_usb.h | 100 ----- src/core/ao.h | 704 ++--------------------------------- src/core/ao_adc.h | 62 +++ src/core/ao_beep.h | 74 ++++ src/core/ao_dbg.h | 62 +++ src/core/ao_flight.h | 59 +++ src/core/ao_led.h | 55 +++ src/core/ao_log.h | 196 ++++++++++ src/core/ao_log_telem.c | 4 +- src/core/ao_product.c | 8 +- src/core/ao_report.c | 2 + src/core/ao_sample.h | 137 +++++++ src/core/ao_serial.h | 86 +++++ src/core/ao_stdio.c | 6 + src/core/ao_storage.c | 2 +- src/core/ao_storage.h | 84 +++++ src/core/ao_usb.h | 136 +++++++ src/drivers/ao_btm.c | 30 +- src/drivers/ao_gps_sirf.c | 36 +- src/drivers/ao_gps_skytraq.c | 6 +- src/drivers/ao_science_slave.c | 1 + src/megametrum-v0.1/ao_pins.h | 2 + src/product/ao_telebt.c | 2 + src/product/ao_terraui.c | 1 + src/stm/ao_arch.h | 2 - src/stm/ao_serial_stm.c | 2 +- src/stm/ao_usb.h | 101 ----- src/stm/ao_usb_stm.c | 6 +- src/teleballoon-v1.1/ao_pins.h | 5 - src/telepyro-v0.1/Makefile | 6 +- src/telescience-v0.1/Makefile | 9 +- src/teleshield-v0.1/Makefile | 1 - src/teleshield-v0.1/ao_ardu_serial.c | 3 +- src/teleshield-v0.1/ao_pins.h | 8 +- src/teleshield-v0.1/ao_teleshield.c | 3 + src/teleterra-v0.1/ao_pins.h | 5 - src/teleterra-v0.2/ao_pins.h | 5 - src/test/ao_gps_test.c | 6 +- src/test/ao_gps_test_skytraq.c | 6 +- 49 files changed, 1342 insertions(+), 1310 deletions(-) delete mode 100644 src/avr/ao_usb.h delete mode 100644 src/cc1111/ao_serial0.c delete mode 100644 src/cc1111/ao_usb.h create mode 100644 src/core/ao_adc.h create mode 100644 src/core/ao_beep.h create mode 100644 src/core/ao_dbg.h create mode 100644 src/core/ao_flight.h create mode 100644 src/core/ao_led.h create mode 100644 src/core/ao_log.h create mode 100644 src/core/ao_sample.h create mode 100644 src/core/ao_serial.h create mode 100644 src/core/ao_storage.h create mode 100644 src/core/ao_usb.h delete mode 100644 src/stm/ao_usb.h (limited to 'src/avr') diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index b816279e..c775dab6 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -146,12 +146,5 @@ extern uint8_t ao_cpu_sleep_disable; #define AO_TELESCIENCE_NUM_ADC 12 -struct ao_adc { - uint16_t tick; /* tick when the sample was read */ - uint16_t adc[AO_TELESCIENCE_NUM_ADC]; /* samples */ -}; - -#define AO_ADC_RING 16 - #endif /* _AO_ARCH_H_ */ diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index 6a63468f..f2b40fb4 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -21,7 +21,7 @@ #ifdef AVR_DEMO #define AO_LED_RED (1<<7) #define LEDS_AVAILABLE (AO_LED_RED) - #define USE_SERIAL_STDIN 1 + #define USE_SERIAL_1_STDIN 1 #define HAS_USB 1 #define PACKET_HAS_SLAVE 0 #define HAS_SERIAL_1 1 @@ -37,11 +37,11 @@ #define HAS_USB 1 #define HAS_LOG 1 #define TEENSY 0 - #define USE_SERIAL_STDIN 0 #define HAS_SERIAL_1 0 #define HAS_ADC 1 #define PACKET_HAS_SLAVE 0 #define HAS_BEEP 0 + #define HAS_EEPROM 1 #define HAS_STORAGE_DEBUG 0 #define AVR_VCC_5V 0 @@ -66,7 +66,7 @@ #define HAS_USB 1 #define HAS_LOG 0 #define TEENSY 0 - #define USE_SERIAL_STDIN 1 + #define USE_SERIAL_1_STDIN 1 #define HAS_SERIAL_1 1 #define HAS_USB 1 #define HAS_ADC 1 @@ -88,4 +88,13 @@ #define AO_M25_SPI_CS_PORT SPI_CS_PORT #define AO_M25_SPI_CS_MASK M25_CS_MASK +#define AO_TELESCIENCE_NUM_ADC 12 + +struct ao_adc { + uint16_t tick; /* tick when the sample was read */ + uint16_t adc[AO_TELESCIENCE_NUM_ADC]; /* samples */ +}; + +#define AO_ADC_RING 16 + #endif /* _AO_PINS_H_ */ diff --git a/src/avr/ao_serial_avr.c b/src/avr/ao_serial_avr.c index 6885c339..dcee246c 100644 --- a/src/avr/ao_serial_avr.c +++ b/src/avr/ao_serial_avr.c @@ -17,8 +17,8 @@ #include "ao.h" -__xdata struct ao_fifo ao_usart1_rx_fifo; -__xdata struct ao_fifo ao_usart1_tx_fifo; +__xdata struct ao_fifo ao_serial1_rx_fifo; +__xdata struct ao_fifo ao_serial1_tx_fifo; void ao_debug_out(char c) @@ -31,10 +31,10 @@ ao_debug_out(char c) ISR(USART1_RX_vect) { - if (!ao_fifo_full(ao_usart1_rx_fifo)) - ao_fifo_insert(ao_usart1_rx_fifo, UDR1); - ao_wakeup(&ao_usart1_rx_fifo); -#if USE_SERIAL_STDIN + if (!ao_fifo_full(ao_serial1_rx_fifo)) + ao_fifo_insert(ao_serial1_rx_fifo, UDR1); + ao_wakeup(&ao_serial1_rx_fifo); +#if USE_SERIAL_1_STDIN ao_wakeup(&ao_stdin_ready); #endif } @@ -42,68 +42,68 @@ ISR(USART1_RX_vect) static __xdata uint8_t ao_serial_tx1_started; static void -ao_serial_tx1_start(void) +ao_serial1_tx_start(void) { - if (!ao_fifo_empty(ao_usart1_tx_fifo) && + if (!ao_fifo_empty(ao_serial1_tx_fifo) && !ao_serial_tx1_started) { ao_serial_tx1_started = 1; - ao_fifo_remove(ao_usart1_tx_fifo, UDR1); + ao_fifo_remove(ao_serial1_tx_fifo, UDR1); } } ISR(USART1_UDRE_vect) { - ao_serial_tx1_started = 0; - ao_serial_tx1_start(); - ao_wakeup(&ao_usart1_tx_fifo); + ao_serial1_tx_started = 0; + ao_serial1_tx_start(); + ao_wakeup(&ao_serial1_tx_fifo); } char -ao_serial_getchar(void) __critical +ao_serial1_getchar(void) __critical { char c; cli(); - while (ao_fifo_empty(ao_usart1_rx_fifo)) - ao_sleep(&ao_usart1_rx_fifo); - ao_fifo_remove(ao_usart1_rx_fifo, c); + while (ao_fifo_empty(ao_serial1_rx_fifo)) + ao_sleep(&ao_serial1_rx_fifo); + ao_fifo_remove(ao_serial1_rx_fifo, c); sei(); return c; } -#if USE_SERIAL_STDIN +#if USE_SERIAL_1_STDIN char -ao_serial_pollchar(void) __critical +ao_serial1_pollchar(void) __critical { char c; cli(); - if (ao_fifo_empty(ao_usart1_rx_fifo)) { + if (ao_fifo_empty(ao_serial1_rx_fifo)) { sei(); return AO_READ_AGAIN; } - ao_fifo_remove(ao_usart1_rx_fifo,c); + ao_fifo_remove(ao_serial1_rx_fifo,c); sei(); return c; } #endif void -ao_serial_putchar(char c) __critical +ao_serial1_putchar(char c) __critical { cli(); - while (ao_fifo_full(ao_usart1_tx_fifo)) - ao_sleep(&ao_usart1_tx_fifo); - ao_fifo_insert(ao_usart1_tx_fifo, c); + while (ao_fifo_full(ao_serial1_tx_fifo)) + ao_sleep(&ao_serial1_tx_fifo); + ao_fifo_insert(ao_serial1_tx_fifo, c); ao_serial_tx1_start(); sei(); } void -ao_serial_drain(void) __critical +ao_serial1_drain(void) __critical { cli(); - while (!ao_fifo_empty(ao_usart1_tx_fifo)) - ao_sleep(&ao_usart1_tx_fifo); + while (!ao_fifo_empty(ao_serial1_tx_fifo)) + ao_sleep(&ao_serial1_tx_fifo); sei(); } @@ -125,7 +125,7 @@ static const struct { }; void -ao_serial_set_speed(uint8_t speed) +ao_serial1_set_speed(uint8_t speed) { ao_serial_drain(); if (speed > AO_SERIAL_SPEED_57600) @@ -154,9 +154,9 @@ ao_serial_init(void) (1 << TXEN1) | /* Enable transmitter */ (1 << RXCIE1) | /* Enable receive interrupts */ (1 << UDRIE1)); /* Enable transmit empty interrupts */ -#if USE_SERIAL_STDIN - ao_add_stdio(ao_serial_pollchar, - ao_serial_putchar, +#if USE_SERIAL_1_STDIN + ao_add_stdio(ao_serial1_pollchar, + ao_serial1_putchar, NULL); #endif } diff --git a/src/avr/ao_usb.h b/src/avr/ao_usb.h deleted file mode 100644 index 6633dafc..00000000 --- a/src/avr/ao_usb.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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; 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_USB_H_ -#define _AO_USB_H_ - -#define AO_USB_SETUP_DIR_MASK (0x01 << 7) -#define AO_USB_SETUP_TYPE_MASK (0x03 << 5) -#define AO_USB_SETUP_RECIP_MASK (0x1f) - -#define AO_USB_DIR_OUT 0 -#define AO_USB_DIR_IN (1 << 7) - -#define AO_USB_TYPE_STANDARD 0 -#define AO_USB_TYPE_CLASS (1 << 5) -#define AO_USB_TYPE_VENDOR (2 << 5) -#define AO_USB_TYPE_RESERVED (3 << 5) - -#define AO_USB_RECIP_DEVICE 0 -#define AO_USB_RECIP_INTERFACE 1 -#define AO_USB_RECIP_ENDPOINT 2 -#define AO_USB_RECIP_OTHER 3 - -/* standard requests */ -#define AO_USB_REQ_GET_STATUS 0x00 -#define AO_USB_REQ_CLEAR_FEATURE 0x01 -#define AO_USB_REQ_SET_FEATURE 0x03 -#define AO_USB_REQ_SET_ADDRESS 0x05 -#define AO_USB_REQ_GET_DESCRIPTOR 0x06 -#define AO_USB_REQ_SET_DESCRIPTOR 0x07 -#define AO_USB_REQ_GET_CONFIGURATION 0x08 -#define AO_USB_REQ_SET_CONFIGURATION 0x09 -#define AO_USB_REQ_GET_INTERFACE 0x0A -#define AO_USB_REQ_SET_INTERFACE 0x0B -#define AO_USB_REQ_SYNCH_FRAME 0x0C - -#define AO_USB_DESC_DEVICE 1 -#define AO_USB_DESC_CONFIGURATION 2 -#define AO_USB_DESC_STRING 3 -#define AO_USB_DESC_INTERFACE 4 -#define AO_USB_DESC_ENDPOINT 5 -#define AO_USB_DESC_DEVICE_QUALIFIER 6 -#define AO_USB_DESC_OTHER_SPEED 7 -#define AO_USB_DESC_INTERFACE_POWER 8 - -#define AO_USB_GET_DESC_TYPE(x) (((x)>>8)&0xFF) -#define AO_USB_GET_DESC_INDEX(x) ((x)&0xFF) - -#define AO_USB_CONTROL_EP 0 -#define AO_USB_INT_EP 1 -#define AO_USB_OUT_EP 4 -#define AO_USB_IN_EP 5 -#define AO_USB_CONTROL_SIZE 32 -/* - * Double buffer IN and OUT EPs, so each - * gets half of the available space - * - * Ah, but USB bulk packets can only come in 8, 16, 32 and 64 - * byte sizes, so we'll use 64 for everything - */ -#define AO_USB_IN_SIZE 64 -#define AO_USB_OUT_SIZE 64 - -#define AO_USB_EP0_IDLE 0 -#define AO_USB_EP0_DATA_IN 1 -#define AO_USB_EP0_DATA_OUT 2 - -#define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) - -/* CDC definitions */ -#define CS_INTERFACE 0x24 -#define CS_ENDPOINT 0x25 - -#define SET_LINE_CODING 0x20 -#define GET_LINE_CODING 0x21 -#define SET_CONTROL_LINE_STATE 0x22 - -/* Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */ -struct ao_usb_line_coding { - uint32_t rate; - uint8_t char_format; - uint8_t parity; - uint8_t data_bits; -} ; - -#endif /* _AO_USB_H_ */ diff --git a/src/avr/ao_usb_avr.c b/src/avr/ao_usb_avr.c index fc8899d8..23a27c73 100644 --- a/src/avr/ao_usb_avr.c +++ b/src/avr/ao_usb_avr.c @@ -330,17 +330,17 @@ ao_usb_ep0_setup(void) case AO_USB_TYPE_CLASS: debug ("Class setup packet\n"); switch (ao_usb_setup.request) { - case SET_LINE_CODING: + case AO_USB_SET_LINE_CODING: debug ("set line coding\n"); ao_usb_ep0_out_len = 7; ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_line_coding; break; - case GET_LINE_CODING: + case AO_USB_GET_LINE_CODING: debug ("get line coding\n"); ao_usb_ep0_in_len = 7; ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding; break; - case SET_CONTROL_LINE_STATE: + case AO_USB_SET_CONTROL_LINE_STATE: break; } break; diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index 847ac1a6..9d0643b4 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -294,4 +294,34 @@ ao_dma_abort(uint8_t id); void ao_dma_isr(void) ao_arch_interrupt(8); +/* ao_adc.c */ + +#if HAS_ADC +/* The A/D interrupt handler */ +void +ao_adc_isr(void) ao_arch_interrupt(1); +#endif + +#if HAS_USB +/* USB interrupt handler */ +void +ao_usb_isr(void) ao_arch_interrupt(6); +#endif + +#if HAS_SERIAL_0 +void +ao_serial0_rx_isr(void) ao_arch_interrupt(2); + +void +ao_serial0_tx_isr(void) ao_arch_interrupt(7); +#endif + +#if HAS_SERIAL_1 +void +ao_serial1_rx_isr(void) ao_arch_interrupt(3); + +void +ao_serial1_tx_isr(void) ao_arch_interrupt(14); +#endif + #endif /* _AO_ARCH_H_ */ diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index 5c0cb7df..4f6edd37 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -25,7 +25,6 @@ #define HAS_GPS 1 #define HAS_SERIAL_1 1 #define HAS_ADC 1 - #define USE_SERIAL_STDIN 0 #define HAS_EEPROM 1 #define HAS_LOG 1 #define USE_INTERNAL_FLASH 0 @@ -58,7 +57,6 @@ #define HAS_BEEP 1 #define HAS_GPS 1 #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 1 #define HAS_EEPROM 1 #define HAS_LOG 1 @@ -95,7 +93,6 @@ #define HAS_BEEP 1 #define HAS_GPS 1 #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 1 #define HAS_EEPROM 1 #define HAS_LOG 1 @@ -131,7 +128,6 @@ #define HAS_USB 1 #define HAS_BEEP 0 #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 0 #define HAS_DBG 1 #define HAS_EEPROM 0 @@ -161,7 +157,6 @@ #define HAS_BEEP 0 #define HAS_GPS 0 #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 1 #define HAS_EEPROM 1 #define HAS_LOG 1 @@ -188,7 +183,6 @@ #define HAS_BEEP 0 #define HAS_GPS 0 #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 1 #define HAS_EEPROM 1 #define HAS_LOG 1 @@ -214,7 +208,6 @@ #define HAS_BEEP 1 #define HAS_GPS 1 #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 1 #define HAS_DBG 0 #define HAS_EEPROM 1 @@ -244,7 +237,6 @@ #define HAS_USB 1 #define HAS_BEEP 0 #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 0 #define HAS_DBG 0 #define HAS_EEPROM 0 @@ -273,7 +265,6 @@ #define HAS_USB 1 #define HAS_BEEP 0 #define HAS_SERIAL_1 0 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 0 #define HAS_DBG 1 #define HAS_EEPROM 0 @@ -301,7 +292,8 @@ #define HAS_USB 1 #define HAS_BEEP 0 #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 1 + #define USE_SERIAL_1_STDIN 1 + #define DELAY_SERIAL_1_STDIN 1 #define HAS_ADC 0 #define HAS_DBG 1 #define HAS_EEPROM 0 @@ -339,7 +331,8 @@ #define HAS_SERIAL_1_ALT_1 1 #define HAS_SERIAL_1_ALT_2 0 #define HAS_SERIAL_1_HW_FLOW 1 - #define USE_SERIAL_STDIN 1 + #define USE_SERIAL_1_STDIN 1 + #define DELAY_SERIAL_1_STDIN 1 #define HAS_ADC 0 #define HAS_DBG 1 #define HAS_EEPROM 1 @@ -379,7 +372,6 @@ #define HAS_BEEP 1 #define HAS_GPS 0 #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 1 #define HAS_DBG 0 #define HAS_EEPROM 1 @@ -468,14 +460,6 @@ #error Please define IGNITE_ON_P0 #endif -#ifndef HAS_SERIAL_1 -#error Please define HAS_SERIAL_1 -#endif - -#ifndef USE_SERIAL_STDIN -#error Please define USE_SERIAL_STDIN -#endif - #ifndef HAS_ADC #error Please define HAS_ADC #endif diff --git a/src/cc1111/ao_serial.c b/src/cc1111/ao_serial.c index 4d5b9abd..00c85ff3 100644 --- a/src/cc1111/ao_serial.c +++ b/src/cc1111/ao_serial.c @@ -17,78 +17,168 @@ #include "ao.h" -volatile __xdata struct ao_fifo ao_usart1_rx_fifo; -volatile __xdata struct ao_fifo ao_usart1_tx_fifo; +#if HAS_SERIAL_0 + +volatile __xdata struct ao_fifo ao_serial0_rx_fifo; +volatile __xdata struct ao_fifo ao_serial0_tx_fifo; + +void +ao_serial0_rx_isr(void) __interrupt 2 +{ + if (!ao_fifo_full(ao_serial0_rx_fifo)) + ao_fifo_insert(ao_serial0_rx_fifo, U0DBUF); + ao_wakeup(&ao_serial0_rx_fifo); +#if USE_SERIAL_0_STDIN + ao_wakeup(&ao_stdin_ready); +#endif +} + +static __xdata uint8_t ao_serial0_tx_started; + +static void +ao_serial0_tx_start(void) +{ + if (!ao_fifo_empty(ao_serial0_tx_fifo) && + !ao_serial0_tx_started) + { + ao_serial0_tx_started = 1; + ao_fifo_remove(ao_serial0_tx_fifo, U0DBUF); + } +} + +void +ao_serial0_tx_isr(void) __interrupt 7 +{ + UTX0IF = 0; + ao_serial0_tx_started = 0; + ao_serial0_tx_start(); + ao_wakeup(&ao_serial0_tx_fifo); +} + +char +ao_serial0_getchar(void) __critical +{ + char c; + while (ao_fifo_empty(ao_serial0_rx_fifo)) + ao_sleep(&ao_serial0_rx_fifo); + ao_fifo_remove(ao_serial0_rx_fifo, c); + return c; +} + +#if USE_SERIAL_0_STDIN +char +ao_serial0_pollchar(void) __critical +{ + char c; + if (ao_fifo_empty(ao_serial0_rx_fifo)) + return AO_READ_AGAIN; + ao_fifo_remove(ao_serial0_rx_fifo,c); + return c; +} +#endif + +void +ao_serial0_putchar(char c) __critical +{ + while (ao_fifo_full(ao_serial0_tx_fifo)) + ao_sleep(&ao_serial0_tx_fifo); + ao_fifo_insert(ao_serial0_tx_fifo, c); + ao_serial0_tx_start(); +} + +void +ao_serial0_drain(void) __critical +{ + while (!ao_fifo_empty(ao_serial0_tx_fifo)) + ao_sleep(&ao_serial0_tx_fifo); +} + +void +ao_serial0_set_speed(uint8_t speed) +{ + ao_serial0_drain(); + if (speed > AO_SERIAL_SPEED_57600) + return; + U0UCR |= UxUCR_FLUSH; + U0BAUD = ao_serial_speeds[speed].baud; + U0GCR = ao_serial_speeds[speed].gcr; +} +#endif /* HAS_SERIAL_0 */ + +#if HAS_SERIAL_1 + +volatile __xdata struct ao_fifo ao_serial1_rx_fifo; +volatile __xdata struct ao_fifo ao_serial1_tx_fifo; void -ao_serial_rx1_isr(void) __interrupt 3 +ao_serial1_rx_isr(void) __interrupt 3 { - if (!ao_fifo_full(ao_usart1_rx_fifo)) - ao_fifo_insert(ao_usart1_rx_fifo, U1DBUF); - ao_wakeup(&ao_usart1_rx_fifo); -#if USE_SERIAL_STDIN + if (!ao_fifo_full(ao_serial1_rx_fifo)) + ao_fifo_insert(ao_serial1_rx_fifo, U1DBUF); + ao_wakeup(&ao_serial1_rx_fifo); +#if USE_SERIAL1_STDIN ao_wakeup(&ao_stdin_ready); #endif } -static __xdata uint8_t ao_serial_tx1_started; +static __xdata uint8_t ao_serial1_tx_started; static void -ao_serial_tx1_start(void) +ao_serial1_tx_start(void) { - if (!ao_fifo_empty(ao_usart1_tx_fifo) && - !ao_serial_tx1_started) + if (!ao_fifo_empty(ao_serial1_tx_fifo) && + !ao_serial1_tx_started) { - ao_serial_tx1_started = 1; - ao_fifo_remove(ao_usart1_tx_fifo, U1DBUF); + ao_serial1_tx_started = 1; + ao_fifo_remove(ao_serial1_tx_fifo, U1DBUF); } } void -ao_serial_tx1_isr(void) __interrupt 14 +ao_serial1_tx_isr(void) __interrupt 14 { UTX1IF = 0; - ao_serial_tx1_started = 0; - ao_serial_tx1_start(); - ao_wakeup(&ao_usart1_tx_fifo); + ao_serial1_tx_started = 0; + ao_serial1_tx_start(); + ao_wakeup(&ao_serial1_tx_fifo); } char -ao_serial_getchar(void) __critical +ao_serial1_getchar(void) __critical { char c; - while (ao_fifo_empty(ao_usart1_rx_fifo)) - ao_sleep(&ao_usart1_rx_fifo); - ao_fifo_remove(ao_usart1_rx_fifo, c); + while (ao_fifo_empty(ao_serial1_rx_fifo)) + ao_sleep(&ao_serial1_rx_fifo); + ao_fifo_remove(ao_serial1_rx_fifo, c); return c; } -#if USE_SERIAL_STDIN +#if USE_SERIAL_1_STDIN char -ao_serial_pollchar(void) __critical +ao_serial1_pollchar(void) __critical { char c; - if (ao_fifo_empty(ao_usart1_rx_fifo)) + if (ao_fifo_empty(ao_serial1_rx_fifo)) return AO_READ_AGAIN; - ao_fifo_remove(ao_usart1_rx_fifo,c); + ao_fifo_remove(ao_serial1_rx_fifo,c); return c; } #endif void -ao_serial_putchar(char c) __critical +ao_serial1_putchar(char c) __critical { - while (ao_fifo_full(ao_usart1_tx_fifo)) - ao_sleep(&ao_usart1_tx_fifo); - ao_fifo_insert(ao_usart1_tx_fifo, c); - ao_serial_tx1_start(); + while (ao_fifo_full(ao_serial1_tx_fifo)) + ao_sleep(&ao_serial1_tx_fifo); + ao_fifo_insert(ao_serial1_tx_fifo, c); + ao_serial1_tx_start(); } void -ao_serial_drain(void) __critical +ao_serial1_drain(void) __critical { - while (!ao_fifo_empty(ao_usart1_tx_fifo)) - ao_sleep(&ao_usart1_tx_fifo); + while (!ao_fifo_empty(ao_serial1_tx_fifo)) + ao_sleep(&ao_serial1_tx_fifo); } const __code struct ao_serial_speed ao_serial_speeds[] = { @@ -111,9 +201,9 @@ const __code struct ao_serial_speed ao_serial_speeds[] = { }; void -ao_serial_set_speed(uint8_t speed) +ao_serial1_set_speed(uint8_t speed) { - ao_serial_drain(); + ao_serial1_drain(); if (speed > AO_SERIAL_SPEED_57600) return; U1UCR |= UxUCR_FLUSH; @@ -121,9 +211,67 @@ ao_serial_set_speed(uint8_t speed) U1GCR = ao_serial_speeds[speed].gcr; } +#endif /* HAS_SERIAL_1 */ + void ao_serial_init(void) { +#if HAS_SERIAL_0 +#if HAS_SERIAL_0_ALT_1 + /* Set up the USART pin assignment */ + PERCFG = (PERCFG & ~PERCFG_U0CFG_ALT_MASK) | PERCFG_U0CFG_ALT_1; + + P2DIR = (P2DIR & ~P2DIR_PRIP0_MASK) | P2DIR_PRIP0_USART0_USART1; + + /* Make the USART pins be controlled by the USART */ + P0SEL |= (1 << 2) | (1 << 3); +#if HAS_SERIAL_0_HW_FLOW + P0SEL |= (1 << 4) | (1 << 5); +#endif +#else + /* Set up the USART pin assignment */ + PERCFG = (PERCFG & ~PERCFG_U0CFG_ALT_MASK) | PERCFG_U0CFG_ALT_2; + + P2SEL = (P2SEL & ~(P2SEL_PRI3P1_MASK | P2SEL_PRI0P1_MASK)) | + (P2SEL_PRI3P1_USART0 | P2SEL_PRI0P1_USART0); + + /* Make the USART pins be controlled by the USART */ + P1SEL |= (1 << 2) | (1 << 3); +#if HAS_SERIAL_0_HW_FLOW + P1SEL |= (1 << 5) | (1 << 4); +#endif +#endif + + /* UART mode with receiver enabled */ + U0CSR = (UxCSR_MODE_UART | UxCSR_RE); + + /* Pick a 9600 baud rate */ + ao_serial0_set_speed(AO_SERIAL_SPEED_9600); + + /* Reasonable serial parameters */ + U0UCR = (UxUCR_FLUSH | +#if HAS_SERIAL_0_HW_FLOW + UxUCR_FLOW_ENABLE | +#else + UxUCR_FLOW_DISABLE | +#endif + UxUCR_D9_EVEN_PARITY | + UxUCR_BIT9_8_BITS | + UxUCR_PARITY_DISABLE | + UxUCR_SPB_1_STOP_BIT | + UxUCR_STOP_HIGH | + UxUCR_START_LOW); + + IEN0 |= IEN0_URX0IE; + IEN2 |= IEN2_UTX0IE; +#if USE_SERIAL_0_STDIN && !DELAY_SERIAL_0_STDIN + ao_add_stdio(ao_serial0_pollchar, + ao_serial0_putchar, + NULL); +#endif +#endif /* HAS_SERIAL_0 */ + +#if HAS_SERIAL_1 #if HAS_SERIAL_1_ALT_1 /* Set up the USART pin assignment */ PERCFG = (PERCFG & ~PERCFG_U1CFG_ALT_MASK) | PERCFG_U1CFG_ALT_1; @@ -151,7 +299,7 @@ ao_serial_init(void) U1CSR = (UxCSR_MODE_UART | UxCSR_RE); /* Pick a 4800 baud rate */ - ao_serial_set_speed(AO_SERIAL_SPEED_4800); + ao_serial1_set_speed(AO_SERIAL_SPEED_4800); /* Reasonable serial parameters */ U1UCR = (UxUCR_FLUSH | @@ -169,4 +317,11 @@ ao_serial_init(void) IEN0 |= IEN0_URX1IE; IEN2 |= IEN2_UTX1IE; + +#if USE_SERIAL_1_STDIN && !DELAY_SERIAL_1_STDIN + ao_add_stdio(ao_serial1_pollchar, + ao_serial1_putchar, + NULL); +#endif +#endif /* HAS_SERIAL_1 */ } diff --git a/src/cc1111/ao_serial0.c b/src/cc1111/ao_serial0.c deleted file mode 100644 index e8c1eb35..00000000 --- a/src/cc1111/ao_serial0.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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; 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" - -volatile __xdata struct ao_fifo ao_usart0_rx_fifo; -volatile __xdata struct ao_fifo ao_usart0_tx_fifo; - -void -ao_serial0_rx0_isr(void) __interrupt 2 -{ - if (!ao_fifo_full(ao_usart0_rx_fifo)) - ao_fifo_insert(ao_usart0_rx_fifo, U0DBUF); - ao_wakeup(&ao_usart0_rx_fifo); -} - -static __xdata uint8_t ao_serial0_tx0_started; - -static void -ao_serial0_tx0_start(void) -{ - if (!ao_fifo_empty(ao_usart0_tx_fifo) && - !ao_serial0_tx0_started) - { - ao_serial0_tx0_started = 1; - ao_fifo_remove(ao_usart0_tx_fifo, U0DBUF); - } -} - -void -ao_serial0_tx0_isr(void) __interrupt 7 -{ - UTX0IF = 0; - ao_serial0_tx0_started = 0; - ao_serial0_tx0_start(); - ao_wakeup(&ao_usart0_tx_fifo); -} - -char -ao_serial0_getchar(void) __critical -{ - char c; - while (ao_fifo_empty(ao_usart0_rx_fifo)) - ao_sleep(&ao_usart0_rx_fifo); - ao_fifo_remove(ao_usart0_rx_fifo, c); - return c; -} - -#if USE_SERIAL_STDIN -char -ao_serial0_pollchar(void) __critical -{ - char c; - if (ao_fifo_empty(ao_usart0_rx_fifo)) - return AO_READ_AGAIN; - ao_fifo_remove(ao_usart0_rx_fifo,c); - return c; -} -#endif - -void -ao_serial0_putchar(char c) __critical -{ - while (ao_fifo_full(ao_usart0_tx_fifo)) - ao_sleep(&ao_usart0_tx_fifo); - ao_fifo_insert(ao_usart0_tx_fifo, c); - ao_serial0_tx0_start(); -} - -void -ao_serial0_drain(void) __critical -{ - while (!ao_fifo_empty(ao_usart0_tx_fifo)) - ao_sleep(&ao_usart0_tx_fifo); -} - -void -ao_serial0_set_speed(uint8_t speed) -{ - ao_serial0_drain(); - if (speed > AO_SERIAL_SPEED_57600) - return; - U0UCR |= UxUCR_FLUSH; - U0BAUD = ao_serial_speeds[speed].baud; - U0GCR = ao_serial_speeds[speed].gcr; -} - -void -ao_serial0_init(void) -{ -#if HAS_SERIAL_0_ALT_1 - /* Set up the USART pin assignment */ - PERCFG = (PERCFG & ~PERCFG_U0CFG_ALT_MASK) | PERCFG_U0CFG_ALT_1; - - P2DIR = (P2DIR & ~P2DIR_PRIP0_MASK) | P2DIR_PRIP0_USART0_USART1; - - /* Make the USART pins be controlled by the USART */ - P0SEL |= (1 << 2) | (1 << 3); -#if HAS_SERIAL_0_HW_FLOW - P0SEL |= (1 << 4) | (1 << 5); -#endif -#else - /* Set up the USART pin assignment */ - PERCFG = (PERCFG & ~PERCFG_U0CFG_ALT_MASK) | PERCFG_U0CFG_ALT_2; - - P2SEL = (P2SEL & ~(P2SEL_PRI3P1_MASK | P2SEL_PRI0P1_MASK)) | - (P2SEL_PRI3P1_USART0 | P2SEL_PRI0P1_USART0); - - /* Make the USART pins be controlled by the USART */ - P1SEL |= (1 << 2) | (1 << 3); -#if HAS_SERIAL_0_HW_FLOW - P1SEL |= (1 << 5) | (1 << 4); -#endif -#endif - - /* UART mode with receiver enabled */ - U0CSR = (UxCSR_MODE_UART | UxCSR_RE); - - /* Pick a 9600 baud rate */ - ao_serial0_set_speed(AO_SERIAL_SPEED_9600); - - /* Reasonable serial parameters */ - U0UCR = (UxUCR_FLUSH | -#if HAS_SERIAL_0_HW_FLOW - UxUCR_FLOW_ENABLE | -#else - UxUCR_FLOW_DISABLE | -#endif - UxUCR_D9_EVEN_PARITY | - UxUCR_BIT9_8_BITS | - UxUCR_PARITY_DISABLE | - UxUCR_SPB_1_STOP_BIT | - UxUCR_STOP_HIGH | - UxUCR_START_LOW); - - IEN0 |= IEN0_URX0IE; - IEN2 |= IEN2_UTX0IE; -} diff --git a/src/cc1111/ao_usb.c b/src/cc1111/ao_usb.c index 35c9ac20..ce26e808 100644 --- a/src/cc1111/ao_usb.c +++ b/src/cc1111/ao_usb.c @@ -261,15 +261,15 @@ ao_usb_ep0_setup(void) break; case AO_USB_TYPE_CLASS: switch (ao_usb_setup.request) { - case SET_LINE_CODING: + case AO_USB_SET_LINE_CODING: ao_usb_ep0_out_len = 7; ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_line_coding; break; - case GET_LINE_CODING: + case AO_USB_GET_LINE_CODING: ao_usb_ep0_in_len = 7; ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding; break; - case SET_CONTROL_LINE_STATE: + case AO_USB_SET_CONTROL_LINE_STATE: break; } break; diff --git a/src/cc1111/ao_usb.h b/src/cc1111/ao_usb.h deleted file mode 100644 index 6633dafc..00000000 --- a/src/cc1111/ao_usb.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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; 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_USB_H_ -#define _AO_USB_H_ - -#define AO_USB_SETUP_DIR_MASK (0x01 << 7) -#define AO_USB_SETUP_TYPE_MASK (0x03 << 5) -#define AO_USB_SETUP_RECIP_MASK (0x1f) - -#define AO_USB_DIR_OUT 0 -#define AO_USB_DIR_IN (1 << 7) - -#define AO_USB_TYPE_STANDARD 0 -#define AO_USB_TYPE_CLASS (1 << 5) -#define AO_USB_TYPE_VENDOR (2 << 5) -#define AO_USB_TYPE_RESERVED (3 << 5) - -#define AO_USB_RECIP_DEVICE 0 -#define AO_USB_RECIP_INTERFACE 1 -#define AO_USB_RECIP_ENDPOINT 2 -#define AO_USB_RECIP_OTHER 3 - -/* standard requests */ -#define AO_USB_REQ_GET_STATUS 0x00 -#define AO_USB_REQ_CLEAR_FEATURE 0x01 -#define AO_USB_REQ_SET_FEATURE 0x03 -#define AO_USB_REQ_SET_ADDRESS 0x05 -#define AO_USB_REQ_GET_DESCRIPTOR 0x06 -#define AO_USB_REQ_SET_DESCRIPTOR 0x07 -#define AO_USB_REQ_GET_CONFIGURATION 0x08 -#define AO_USB_REQ_SET_CONFIGURATION 0x09 -#define AO_USB_REQ_GET_INTERFACE 0x0A -#define AO_USB_REQ_SET_INTERFACE 0x0B -#define AO_USB_REQ_SYNCH_FRAME 0x0C - -#define AO_USB_DESC_DEVICE 1 -#define AO_USB_DESC_CONFIGURATION 2 -#define AO_USB_DESC_STRING 3 -#define AO_USB_DESC_INTERFACE 4 -#define AO_USB_DESC_ENDPOINT 5 -#define AO_USB_DESC_DEVICE_QUALIFIER 6 -#define AO_USB_DESC_OTHER_SPEED 7 -#define AO_USB_DESC_INTERFACE_POWER 8 - -#define AO_USB_GET_DESC_TYPE(x) (((x)>>8)&0xFF) -#define AO_USB_GET_DESC_INDEX(x) ((x)&0xFF) - -#define AO_USB_CONTROL_EP 0 -#define AO_USB_INT_EP 1 -#define AO_USB_OUT_EP 4 -#define AO_USB_IN_EP 5 -#define AO_USB_CONTROL_SIZE 32 -/* - * Double buffer IN and OUT EPs, so each - * gets half of the available space - * - * Ah, but USB bulk packets can only come in 8, 16, 32 and 64 - * byte sizes, so we'll use 64 for everything - */ -#define AO_USB_IN_SIZE 64 -#define AO_USB_OUT_SIZE 64 - -#define AO_USB_EP0_IDLE 0 -#define AO_USB_EP0_DATA_IN 1 -#define AO_USB_EP0_DATA_OUT 2 - -#define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) - -/* CDC definitions */ -#define CS_INTERFACE 0x24 -#define CS_ENDPOINT 0x25 - -#define SET_LINE_CODING 0x20 -#define GET_LINE_CODING 0x21 -#define SET_CONTROL_LINE_STATE 0x22 - -/* Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */ -struct ao_usb_line_coding { - uint32_t rate; - uint8_t char_format; - uint8_t parity; - uint8_t data_bits; -} ; - -#endif /* _AO_USB_H_ */ diff --git a/src/core/ao.h b/src/core/ao.h index 9a3b5829..28d0ba87 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -154,182 +154,14 @@ void ao_clock_init(void); /* - * One set of samples read from the A/D converter or telemetry - */ - -#if HAS_ADC - -/* - * ao_adc.c - */ - -#define ao_adc_ring_next(n) (((n) + 1) & (AO_ADC_RING - 1)) -#define ao_adc_ring_prev(n) (((n) - 1) & (AO_ADC_RING - 1)) - - -/* - * A/D data is stored in a ring, with the next sample to be written - * at ao_adc_head - */ -extern volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING]; -extern volatile __data uint8_t ao_adc_head; -#if HAS_ACCEL_REF -extern volatile __xdata uint16_t ao_accel_ref[AO_ADC_RING]; -#endif - -/* Trigger a conversion sequence (called from the timer interrupt) */ -void -ao_adc_poll(void); - -/* Suspend the current task until another A/D sample is converted */ -void -ao_adc_sleep(void); - -/* Get a copy of the last complete A/D sample set */ -void -ao_adc_get(__xdata struct ao_adc *packet); - -/* The A/D interrupt handler */ - -void -ao_adc_isr(void) ao_arch_interrupt(1); - -/* Initialize the A/D converter */ -void -ao_adc_init(void); - -#endif /* HAS_ADC */ - -/* - * ao_beep.c - */ - -/* - * Various pre-defined beep frequencies - * - * frequency = 1/2 (24e6/32) / beep - */ - -#define AO_BEEP_LOW 150 /* 2500Hz */ -#define AO_BEEP_MID 94 /* 3989Hz */ -#define AO_BEEP_HIGH 75 /* 5000Hz */ -#define AO_BEEP_OFF 0 /* off */ - -#define AO_BEEP_g 240 /* 1562.5Hz */ -#define AO_BEEP_gs 227 /* 1652Hz (1655Hz) */ -#define AO_BEEP_aa 214 /* 1752Hz (1754Hz) */ -#define AO_BEEP_bbf 202 /* 1856Hz (1858Hz) */ -#define AO_BEEP_bb 190 /* 1974Hz (1969Hz) */ -#define AO_BEEP_cc 180 /* 2083Hz (2086Hz) */ -#define AO_BEEP_ccs 170 /* 2205Hz (2210Hz) */ -#define AO_BEEP_dd 160 /* 2344Hz (2341Hz) */ -#define AO_BEEP_eef 151 /* 2483Hz (2480Hz) */ -#define AO_BEEP_ee 143 /* 2622Hz (2628Hz) */ -#define AO_BEEP_ff 135 /* 2778Hz (2784Hz) */ -#define AO_BEEP_ffs 127 /* 2953Hz (2950Hz) */ -#define AO_BEEP_gg 120 /* 3125Hz */ -#define AO_BEEP_ggs 113 /* 3319Hz (3311Hz) */ -#define AO_BEEP_aaa 107 /* 3504Hz (3508Hz) */ -#define AO_BEEP_bbbf 101 /* 3713Hz (3716Hz) */ -#define AO_BEEP_bbb 95 /* 3947Hz (3937Hz) */ -#define AO_BEEP_ccc 90 /* 4167Hz (4171Hz) */ -#define AO_BEEP_cccs 85 /* 4412Hz (4419Hz) */ -#define AO_BEEP_ddd 80 /* 4688Hz (4682Hz) */ -#define AO_BEEP_eeef 76 /* 4934Hz (4961Hz) */ -#define AO_BEEP_eee 71 /* 5282Hz (5256Hz) */ -#define AO_BEEP_fff 67 /* 5597Hz (5568Hz) */ -#define AO_BEEP_fffs 64 /* 5859Hz (5899Hz) */ -#define AO_BEEP_ggg 60 /* 6250Hz */ - -/* Set the beeper to the specified tone */ -void -ao_beep(uint8_t beep); - -/* Turn on the beeper for the specified time */ -void -ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant; - -/* Initialize the beeper */ -void -ao_beep_init(void); - -/* - * ao_led.c - */ - -#define AO_LED_NONE 0 - -#ifndef AO_LED_TYPE -#define AO_LED_TYPE uint8_t -#endif - -/* Turn on the specified LEDs */ -void -ao_led_on(AO_LED_TYPE colors); - -/* Turn off the specified LEDs */ -void -ao_led_off(AO_LED_TYPE colors); - -/* Set all of the LEDs to the specified state */ -void -ao_led_set(AO_LED_TYPE colors); - -/* Toggle the specified LEDs */ -void -ao_led_toggle(AO_LED_TYPE colors); - -/* Turn on the specified LEDs for the indicated interval */ -void -ao_led_for(AO_LED_TYPE colors, uint16_t ticks) __reentrant; - -/* Initialize the LEDs */ -void -ao_led_init(AO_LED_TYPE enable); - -/* - * ao_usb.c - */ - -/* Put one character to the USB output queue */ -void -ao_usb_putchar(char c); - -/* Get one character from the USB input queue */ -char -ao_usb_getchar(void); - -/* Poll for a charcter on the USB input queue. - * returns AO_READ_AGAIN if none are available + * ao_mutex.c */ -char -ao_usb_pollchar(void); - -/* Flush the USB output queue */ -void -ao_usb_flush(void); - -#if HAS_USB -/* USB interrupt handler */ -void -ao_usb_isr(void) ao_arch_interrupt(6); -#endif -/* Enable the USB controller */ void -ao_usb_enable(void); - -/* Disable the USB controller */ -void -ao_usb_disable(void); +ao_mutex_get(__xdata uint8_t *ao_mutex) __reentrant; -/* Initialize the USB system */ void -ao_usb_init(void); - -#if HAS_USB -extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; -#endif +ao_mutex_put(__xdata uint8_t *ao_mutex) __reentrant; /* * ao_cmd.c @@ -396,405 +228,36 @@ ao_cmd_filter(void); #endif /* - * ao_mutex.c - */ - -void -ao_mutex_get(__xdata uint8_t *ao_mutex) __reentrant; - -void -ao_mutex_put(__xdata uint8_t *ao_mutex) __reentrant; - -/* - * Storage interface, provided by one of the eeprom or flash - * drivers - */ - -/* Total bytes of available storage */ -extern __pdata uint32_t ao_storage_total; - -/* Block size - device is erased in these units. At least 256 bytes */ -extern __pdata uint32_t ao_storage_block; - -/* Byte offset of config block. Will be ao_storage_block bytes long */ -extern __pdata uint32_t ao_storage_config; - -/* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */ -extern __pdata uint16_t ao_storage_unit; - -#define AO_STORAGE_ERASE_LOG (ao_storage_config + AO_CONFIG_MAX_SIZE) - -/* Initialize above values. Can only be called once the OS is running */ -void -ao_storage_setup(void) __reentrant; - -/* Write data. Returns 0 on failure, 1 on success */ -uint8_t -ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; - -/* Read data. Returns 0 on failure, 1 on success */ -uint8_t -ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; - -/* Erase a block of storage. This always clears ao_storage_block bytes */ -uint8_t -ao_storage_erase(uint32_t pos) __reentrant; - -/* Flush any pending writes to stable storage */ -void -ao_storage_flush(void) __reentrant; - -/* Initialize the storage code */ -void -ao_storage_init(void); - -/* - * Low-level functions wrapped by ao_storage.c - */ - -/* Read data within a storage unit */ -uint8_t -ao_storage_device_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; - -/* Write data within a storage unit */ -uint8_t -ao_storage_device_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; - -/* Initialize low-level device bits */ -void -ao_storage_device_init(void); - -/* Print out information about flash chips */ -void -ao_storage_device_info(void) __reentrant; - -/* - * ao_log.c - */ - -/* We record flight numbers in the first record of - * the log. Tasks may wait for this to be initialized - * by sleeping on this variable. - */ -extern __xdata uint16_t ao_flight_number; - -extern __pdata uint32_t ao_log_current_pos; -extern __pdata uint32_t ao_log_end_pos; -extern __pdata uint32_t ao_log_start_pos; -extern __xdata uint8_t ao_log_running; -extern __pdata enum flight_state ao_log_state; - -/* required functions from the underlying log system */ - -#define AO_LOG_FORMAT_UNKNOWN 0 /* unknown; altosui will have to guess */ -#define AO_LOG_FORMAT_FULL 1 /* 8 byte typed log records */ -#define AO_LOG_FORMAT_TINY 2 /* two byte state/baro records */ -#define AO_LOG_FORMAT_TELEMETRY 3 /* 32 byte ao_telemetry records */ -#define AO_LOG_FORMAT_TELESCIENCE 4 /* 32 byte typed telescience records */ -#define AO_LOG_FORMAT_NONE 127 /* No log at all */ - -extern __code uint8_t ao_log_format; - -/* Return the flight number from the given log slot, 0 if none */ -uint16_t -ao_log_flight(uint8_t slot); - -/* Flush the log */ -void -ao_log_flush(void); - -/* Logging thread main routine */ -void -ao_log(void); - -/* functions provided in ao_log.c */ - -/* Figure out the current flight number */ -void -ao_log_scan(void) __reentrant; - -/* Return the position of the start of the given log slot */ -uint32_t -ao_log_pos(uint8_t slot); - -/* Start logging to eeprom */ -void -ao_log_start(void); - -/* Stop logging */ -void -ao_log_stop(void); - -/* Initialize the logging system */ -void -ao_log_init(void); - -/* Write out the current flight number to the erase log */ -void -ao_log_write_erase(uint8_t pos); - -/* Returns true if there are any logs stored in eeprom */ -uint8_t -ao_log_present(void); - -/* Returns true if there is no more storage space available */ -uint8_t -ao_log_full(void); - -/* - * ao_log_big.c + * Various drivers */ - -/* - * The data log is recorded in the eeprom as a sequence - * of data packets. - * - * Each packet starts with a 4-byte header that has the - * packet type, the packet checksum and the tick count. Then - * they all contain 2 16 bit values which hold packet-specific - * data. - * - * For each flight, the first packet - * is FLIGHT packet, indicating the serial number of the - * device and a unique number marking the number of flights - * recorded by this device. - * - * During flight, data from the accelerometer and barometer - * are recorded in SENSOR packets, using the raw 16-bit values - * read from the A/D converter. - * - * Also during flight, but at a lower rate, the deployment - * sensors are recorded in DEPLOY packets. The goal here is to - * detect failure in the deployment circuits. - * - * STATE packets hold state transitions as the flight computer - * transitions through different stages of the flight. - */ -#define AO_LOG_FLIGHT 'F' -#define AO_LOG_SENSOR 'A' -#define AO_LOG_TEMP_VOLT 'T' -#define AO_LOG_DEPLOY 'D' -#define AO_LOG_STATE 'S' -#define AO_LOG_GPS_TIME 'G' -#define AO_LOG_GPS_LAT 'N' -#define AO_LOG_GPS_LON 'W' -#define AO_LOG_GPS_ALT 'H' -#define AO_LOG_GPS_SAT 'V' -#define AO_LOG_GPS_DATE 'Y' - -#define AO_LOG_POS_NONE (~0UL) - -struct ao_log_record { - char type; - uint8_t csum; - uint16_t tick; - union { - struct { - int16_t ground_accel; - uint16_t flight; - } flight; - struct { - int16_t accel; - int16_t pres; - } sensor; - struct { - int16_t temp; - int16_t v_batt; - } temp_volt; - struct { - int16_t drogue; - int16_t main; - } deploy; - struct { - uint16_t state; - uint16_t reason; - } state; - struct { - uint8_t hour; - uint8_t minute; - uint8_t second; - uint8_t flags; - } gps_time; - int32_t gps_latitude; - int32_t gps_longitude; - struct { - int16_t altitude; - uint16_t unused; - } gps_altitude; - struct { - uint16_t svid; - uint8_t unused; - uint8_t c_n; - } gps_sat; - struct { - uint8_t year; - uint8_t month; - uint8_t day; - uint8_t extra; - } gps_date; - struct { - uint16_t d0; - uint16_t d1; - } anon; - } u; -}; - -/* Write a record to the eeprom log */ -uint8_t -ao_log_data(__xdata struct ao_log_record *log) __reentrant; - -/* - * ao_flight.c - */ - -enum ao_flight_state { - ao_flight_startup = 0, - ao_flight_idle = 1, - ao_flight_pad = 2, - ao_flight_boost = 3, - ao_flight_fast = 4, - ao_flight_coast = 5, - ao_flight_drogue = 6, - ao_flight_main = 7, - ao_flight_landed = 8, - ao_flight_invalid = 9 -}; - -extern __pdata enum ao_flight_state ao_flight_state; - -extern __pdata uint16_t ao_launch_time; -extern __pdata uint8_t ao_flight_force_idle; - -/* Flight thread */ -void -ao_flight(void); - -/* Initialize flight thread */ -void -ao_flight_init(void); - -/* - * ao_flight_nano.c - */ - -void -ao_flight_nano_init(void); - -/* - * ao_sample.c - */ - -/* - * Barometer calibration - * - * We directly sample the barometer. The specs say: - * - * Pressure range: 15-115 kPa - * Voltage at 115kPa: 2.82 - * Output scale: 27mV/kPa - * - * If we want to detect launch with the barometer, we need - * a large enough bump to not be fooled by noise. At typical - * launch elevations (0-2000m), a 200Pa pressure change cooresponds - * to about a 20m elevation change. This is 5.4mV, or about 3LSB. - * As all of our calculations are done in 16 bits, we'll actually see a change - * of 16 times this though - * - * 27 mV/kPa * 32767 / 3300 counts/mV = 268.1 counts/kPa - */ - -/* Accelerometer calibration - * - * We're sampling the accelerometer through a resistor divider which - * consists of 5k and 10k resistors. This multiplies the values by 2/3. - * That goes into the cc1111 A/D converter, which is running at 11 bits - * of precision with the bits in the MSB of the 16 bit value. Only positive - * values are used, so values should range from 0-32752 for 0-3.3V. The - * specs say we should see 40mV/g (uncalibrated), multiply by 2/3 for what - * the A/D converter sees (26.67 mV/g). We should see 32752/3300 counts/mV, - * for a final computation of: - * - * 26.67 mV/g * 32767/3300 counts/mV = 264.8 counts/g - * - * Zero g was measured at 16000 (we would expect 16384). - * Note that this value is only require to tell if the - * rocket is standing upright. Once that is determined, - * the value of the accelerometer is averaged for 100 samples - * to find the resting accelerometer value, which is used - * for all further flight computations - */ - -#define GRAVITY 9.80665 - -/* - * Above this height, the baro sensor doesn't work - */ -#define AO_MAX_BARO_HEIGHT 12000 - -/* - * Above this speed, baro measurements are unreliable - */ -#define AO_MAX_BARO_SPEED 200 - -#define ACCEL_NOSE_UP (ao_accel_2g >> 2) - -/* - * Speed and acceleration are scaled by 16 to provide a bit more - * resolution while still having reasonable range. Note that this - * limits speed to 2047m/s (around mach 6) and acceleration to - * 2047m/s² (over 200g) - */ - -#define AO_M_TO_HEIGHT(m) ((int16_t) (m)) -#define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16)) -#define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16)) - -extern __pdata uint16_t ao_sample_tick; /* time of last data */ -extern __pdata int16_t ao_sample_pres; /* most recent pressure sensor reading */ -extern __pdata int16_t ao_sample_alt; /* MSL of ao_sample_pres */ -extern __pdata int16_t ao_sample_height; /* AGL of ao_sample_pres */ -extern __data uint8_t ao_sample_adc; /* Ring position of last processed sample */ - -#if HAS_ACCEL -extern __pdata int16_t ao_sample_accel; /* most recent accel sensor reading */ +#if HAS_ADC +#include #endif -extern __pdata int16_t ao_ground_pres; /* startup pressure */ -extern __pdata int16_t ao_ground_height; /* MSL of ao_ground_pres */ - -#if HAS_ACCEL -extern __pdata int16_t ao_ground_accel; /* startup acceleration */ -extern __pdata int16_t ao_accel_2g; /* factory accel calibration */ -extern __pdata int32_t ao_accel_scale; /* sensor to m/s² conversion */ +#if HAS_BEEP +#include #endif -void ao_sample_init(void); - -/* returns FALSE in preflight mode, TRUE in flight mode */ -uint8_t ao_sample(void); - -/* - * ao_kalman.c - */ - -#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) -#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) -#define from_fix(x) ((x) >> 16) +#if LEDS_AVAILABLE +#include +#endif -extern __pdata int16_t ao_height; /* meters */ -extern __pdata int16_t ao_speed; /* m/s * 16 */ -extern __pdata int16_t ao_accel; /* m/s² * 16 */ -extern __pdata int16_t ao_max_height; /* max of ao_height */ -extern __pdata int16_t ao_avg_height; /* running average of height */ +#if HAS_USB +#include +#endif -extern __pdata int16_t ao_error_h; -extern __pdata int16_t ao_error_h_sq_avg; +#if HAS_EEPROM +#include +#endif -#if HAS_ACCEL -extern __pdata int16_t ao_error_a; +#if HAS_LOG +#include #endif -void ao_kalman(void); +#if HAS_FLIGHT +#include +#include +#endif /* * ao_report.c @@ -819,125 +282,12 @@ ao_altitude_to_pres(int16_t alt) __reentrant; int16_t ao_temp_to_dC(int16_t temp) __reentrant; -/* - * ao_dbg.c - * - * debug another telemetrum board - */ - -/* Send a byte to the dbg target */ -void -ao_dbg_send_byte(uint8_t byte); - -/* Receive a byte from the dbg target */ -uint8_t -ao_dbg_recv_byte(void); - -/* Start a bulk transfer to/from dbg target memory */ -void -ao_dbg_start_transfer(uint16_t addr); - -/* End a bulk transfer to/from dbg target memory */ -void -ao_dbg_end_transfer(void); - -/* Write a byte to dbg target memory */ -void -ao_dbg_write_byte(uint8_t byte); - -/* Read a byte from dbg target memory */ -uint8_t -ao_dbg_read_byte(void); - -/* Enable dbg mode, switching use of the pins */ -void -ao_dbg_debug_mode(void); - -/* Reset the dbg target */ -void -ao_dbg_reset(void); - -void -ao_dbg_init(void); - -/* - * ao_serial.c - */ - -#ifndef HAS_SERIAL_1 -#error Please define HAS_SERIAL_1 +#if HAS_DBG +#include #endif -#if HAS_SERIAL_1 | HAS_SERIAL_2 | HAS_SERIAL_3 -#ifndef USE_SERIAL_STDIN -#error Please define USE_SERIAL_STDIN -#endif - -void -ao_serial_rx1_isr(void) ao_arch_interrupt(3); - -void -ao_serial_tx1_isr(void) ao_arch_interrupt(14); - -char -ao_serial_getchar(void) __critical; - -#if USE_SERIAL_STDIN -char -ao_serial_pollchar(void) __critical; - -void -ao_serial_set_stdin(uint8_t in); -#endif - -void -ao_serial_putchar(char c) __critical; - -void -ao_serial_drain(void) __critical; - -#define AO_SERIAL_SPEED_4800 0 -#define AO_SERIAL_SPEED_9600 1 -#define AO_SERIAL_SPEED_19200 2 -#define AO_SERIAL_SPEED_57600 3 - -void -ao_serial_set_speed(uint8_t speed); - -void -ao_serial_init(void); -#endif - -#ifndef HAS_SERIAL_0 -#define HAS_SERIAL_0 0 -#endif - -#if HAS_SERIAL_0 - -extern volatile __xdata struct ao_fifo ao_usart0_rx_fifo; -extern volatile __xdata struct ao_fifo ao_usart0_tx_fifo; - -void -ao_serial0_rx0_isr(void) ao_arch_interrupt(2); - -void -ao_serial0_tx0_isr(void) ao_arch_interrupt(7); - -char -ao_serial0_getchar(void) __critical; - -void -ao_serial0_putchar(char c) __critical; - -void -ao_serial0_drain(void) __critical; - -void -ao_serial0_set_speed(uint8_t speed); - -void -ao_serial0_init(void); - +#if HAS_SERIAL_0 || HAS_SERIAL_1 || HAS_SERIAL_2 || HAS_SERIAL_3 +#include #endif diff --git a/src/core/ao_adc.h b/src/core/ao_adc.h new file mode 100644 index 00000000..db5bfab3 --- /dev/null +++ b/src/core/ao_adc.h @@ -0,0 +1,62 @@ +/* + * 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_ADC_H_ +#define _AO_ADC_H_ + + + +/* + * One set of samples read from the A/D converter or telemetry + */ + + +/* + * ao_adc.c + */ + +#define ao_adc_ring_next(n) (((n) + 1) & (AO_ADC_RING - 1)) +#define ao_adc_ring_prev(n) (((n) - 1) & (AO_ADC_RING - 1)) + + +/* + * A/D data is stored in a ring, with the next sample to be written + * at ao_adc_head + */ +extern volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING]; +extern volatile __data uint8_t ao_adc_head; +#if HAS_ACCEL_REF +extern volatile __xdata uint16_t ao_accel_ref[AO_ADC_RING]; +#endif + +/* Trigger a conversion sequence (called from the timer interrupt) */ +void +ao_adc_poll(void); + +/* Suspend the current task until another A/D sample is converted */ +void +ao_adc_sleep(void); + +/* Get a copy of the last complete A/D sample set */ +void +ao_adc_get(__xdata struct ao_adc *packet); + +/* Initialize the A/D converter */ +void +ao_adc_init(void); + +#endif /* _AO_ADC_H_ */ diff --git a/src/core/ao_beep.h b/src/core/ao_beep.h new file mode 100644 index 00000000..55f61171 --- /dev/null +++ b/src/core/ao_beep.h @@ -0,0 +1,74 @@ +/* + * 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_BEEP_H_ +#define _AO_BEEP_H_ + +/* + * ao_beep.c + */ + +/* + * Various pre-defined beep frequencies + * + * frequency = 1/2 (24e6/32) / beep + */ + +#define AO_BEEP_LOW 150 /* 2500Hz */ +#define AO_BEEP_MID 94 /* 3989Hz */ +#define AO_BEEP_HIGH 75 /* 5000Hz */ +#define AO_BEEP_OFF 0 /* off */ + +#define AO_BEEP_g 240 /* 1562.5Hz */ +#define AO_BEEP_gs 227 /* 1652Hz (1655Hz) */ +#define AO_BEEP_aa 214 /* 1752Hz (1754Hz) */ +#define AO_BEEP_bbf 202 /* 1856Hz (1858Hz) */ +#define AO_BEEP_bb 190 /* 1974Hz (1969Hz) */ +#define AO_BEEP_cc 180 /* 2083Hz (2086Hz) */ +#define AO_BEEP_ccs 170 /* 2205Hz (2210Hz) */ +#define AO_BEEP_dd 160 /* 2344Hz (2341Hz) */ +#define AO_BEEP_eef 151 /* 2483Hz (2480Hz) */ +#define AO_BEEP_ee 143 /* 2622Hz (2628Hz) */ +#define AO_BEEP_ff 135 /* 2778Hz (2784Hz) */ +#define AO_BEEP_ffs 127 /* 2953Hz (2950Hz) */ +#define AO_BEEP_gg 120 /* 3125Hz */ +#define AO_BEEP_ggs 113 /* 3319Hz (3311Hz) */ +#define AO_BEEP_aaa 107 /* 3504Hz (3508Hz) */ +#define AO_BEEP_bbbf 101 /* 3713Hz (3716Hz) */ +#define AO_BEEP_bbb 95 /* 3947Hz (3937Hz) */ +#define AO_BEEP_ccc 90 /* 4167Hz (4171Hz) */ +#define AO_BEEP_cccs 85 /* 4412Hz (4419Hz) */ +#define AO_BEEP_ddd 80 /* 4688Hz (4682Hz) */ +#define AO_BEEP_eeef 76 /* 4934Hz (4961Hz) */ +#define AO_BEEP_eee 71 /* 5282Hz (5256Hz) */ +#define AO_BEEP_fff 67 /* 5597Hz (5568Hz) */ +#define AO_BEEP_fffs 64 /* 5859Hz (5899Hz) */ +#define AO_BEEP_ggg 60 /* 6250Hz */ + +/* Set the beeper to the specified tone */ +void +ao_beep(uint8_t beep); + +/* Turn on the beeper for the specified time */ +void +ao_beep_for(uint8_t beep, uint16_t ticks) __reentrant; + +/* Initialize the beeper */ +void +ao_beep_init(void); + +#endif /* _AO_BEEP_H_ */ diff --git a/src/core/ao_dbg.h b/src/core/ao_dbg.h new file mode 100644 index 00000000..181e6ec2 --- /dev/null +++ b/src/core/ao_dbg.h @@ -0,0 +1,62 @@ +/* + * 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_DBG_H_ +#define _AO_DBG_H_ + +/* + * ao_dbg.c + * + * debug another telemetrum board + */ + +/* Send a byte to the dbg target */ +void +ao_dbg_send_byte(uint8_t byte); + +/* Receive a byte from the dbg target */ +uint8_t +ao_dbg_recv_byte(void); + +/* Start a bulk transfer to/from dbg target memory */ +void +ao_dbg_start_transfer(uint16_t addr); + +/* End a bulk transfer to/from dbg target memory */ +void +ao_dbg_end_transfer(void); + +/* Write a byte to dbg target memory */ +void +ao_dbg_write_byte(uint8_t byte); + +/* Read a byte from dbg target memory */ +uint8_t +ao_dbg_read_byte(void); + +/* Enable dbg mode, switching use of the pins */ +void +ao_dbg_debug_mode(void); + +/* Reset the dbg target */ +void +ao_dbg_reset(void); + +void +ao_dbg_init(void); + +#endif /* _AO_DBG_H_ */ diff --git a/src/core/ao_flight.h b/src/core/ao_flight.h new file mode 100644 index 00000000..aa5ab60d --- /dev/null +++ b/src/core/ao_flight.h @@ -0,0 +1,59 @@ +/* + * 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_FLIGHT_H_ +#define _AO_FLIGHT_H_ + + +/* + * ao_flight.c + */ + +enum ao_flight_state { + ao_flight_startup = 0, + ao_flight_idle = 1, + ao_flight_pad = 2, + ao_flight_boost = 3, + ao_flight_fast = 4, + ao_flight_coast = 5, + ao_flight_drogue = 6, + ao_flight_main = 7, + ao_flight_landed = 8, + ao_flight_invalid = 9 +}; + +extern __pdata enum ao_flight_state ao_flight_state; + +extern __pdata uint16_t ao_launch_time; +extern __pdata uint8_t ao_flight_force_idle; + +/* Flight thread */ +void +ao_flight(void); + +/* Initialize flight thread */ +void +ao_flight_init(void); + +/* + * ao_flight_nano.c + */ + +void +ao_flight_nano_init(void); + +#endif /* _AO_FLIGHT_H_ */ diff --git a/src/core/ao_led.h b/src/core/ao_led.h new file mode 100644 index 00000000..edc5fd1f --- /dev/null +++ b/src/core/ao_led.h @@ -0,0 +1,55 @@ +/* + * 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_LED_H_ +#define _AO_LED_H_ + +/* + * ao_led.c + */ + +#define AO_LED_NONE 0 + +#ifndef AO_LED_TYPE +#define AO_LED_TYPE uint8_t +#endif + +/* Turn on the specified LEDs */ +void +ao_led_on(AO_LED_TYPE colors); + +/* Turn off the specified LEDs */ +void +ao_led_off(AO_LED_TYPE colors); + +/* Set all of the LEDs to the specified state */ +void +ao_led_set(AO_LED_TYPE colors); + +/* Toggle the specified LEDs */ +void +ao_led_toggle(AO_LED_TYPE colors); + +/* Turn on the specified LEDs for the indicated interval */ +void +ao_led_for(AO_LED_TYPE colors, uint16_t ticks) __reentrant; + +/* Initialize the LEDs */ +void +ao_led_init(AO_LED_TYPE enable); + +#endif /* _AO_LED_H_ */ diff --git a/src/core/ao_log.h b/src/core/ao_log.h new file mode 100644 index 00000000..611c00d5 --- /dev/null +++ b/src/core/ao_log.h @@ -0,0 +1,196 @@ +/* + * 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_LOG_H_ +#define _AO_LOG_H_ + +/* + * ao_log.c + */ + +/* We record flight numbers in the first record of + * the log. Tasks may wait for this to be initialized + * by sleeping on this variable. + */ +extern __xdata uint16_t ao_flight_number; + +extern __pdata uint32_t ao_log_current_pos; +extern __pdata uint32_t ao_log_end_pos; +extern __pdata uint32_t ao_log_start_pos; +extern __xdata uint8_t ao_log_running; +extern __pdata enum flight_state ao_log_state; + +/* required functions from the underlying log system */ + +#define AO_LOG_FORMAT_UNKNOWN 0 /* unknown; altosui will have to guess */ +#define AO_LOG_FORMAT_FULL 1 /* 8 byte typed log records */ +#define AO_LOG_FORMAT_TINY 2 /* two byte state/baro records */ +#define AO_LOG_FORMAT_TELEMETRY 3 /* 32 byte ao_telemetry records */ +#define AO_LOG_FORMAT_TELESCIENCE 4 /* 32 byte typed telescience records */ +#define AO_LOG_FORMAT_NONE 127 /* No log at all */ + +extern __code uint8_t ao_log_format; + +/* Return the flight number from the given log slot, 0 if none */ +uint16_t +ao_log_flight(uint8_t slot); + +/* Flush the log */ +void +ao_log_flush(void); + +/* Logging thread main routine */ +void +ao_log(void); + +/* functions provided in ao_log.c */ + +/* Figure out the current flight number */ +void +ao_log_scan(void) __reentrant; + +/* Return the position of the start of the given log slot */ +uint32_t +ao_log_pos(uint8_t slot); + +/* Start logging to eeprom */ +void +ao_log_start(void); + +/* Stop logging */ +void +ao_log_stop(void); + +/* Initialize the logging system */ +void +ao_log_init(void); + +/* Write out the current flight number to the erase log */ +void +ao_log_write_erase(uint8_t pos); + +/* Returns true if there are any logs stored in eeprom */ +uint8_t +ao_log_present(void); + +/* Returns true if there is no more storage space available */ +uint8_t +ao_log_full(void); + +/* + * ao_log_big.c + */ + +/* + * The data log is recorded in the eeprom as a sequence + * of data packets. + * + * Each packet starts with a 4-byte header that has the + * packet type, the packet checksum and the tick count. Then + * they all contain 2 16 bit values which hold packet-specific + * data. + * + * For each flight, the first packet + * is FLIGHT packet, indicating the serial number of the + * device and a unique number marking the number of flights + * recorded by this device. + * + * During flight, data from the accelerometer and barometer + * are recorded in SENSOR packets, using the raw 16-bit values + * read from the A/D converter. + * + * Also during flight, but at a lower rate, the deployment + * sensors are recorded in DEPLOY packets. The goal here is to + * detect failure in the deployment circuits. + * + * STATE packets hold state transitions as the flight computer + * transitions through different stages of the flight. + */ +#define AO_LOG_FLIGHT 'F' +#define AO_LOG_SENSOR 'A' +#define AO_LOG_TEMP_VOLT 'T' +#define AO_LOG_DEPLOY 'D' +#define AO_LOG_STATE 'S' +#define AO_LOG_GPS_TIME 'G' +#define AO_LOG_GPS_LAT 'N' +#define AO_LOG_GPS_LON 'W' +#define AO_LOG_GPS_ALT 'H' +#define AO_LOG_GPS_SAT 'V' +#define AO_LOG_GPS_DATE 'Y' + +#define AO_LOG_POS_NONE (~0UL) + +struct ao_log_record { + char type; + uint8_t csum; + uint16_t tick; + union { + struct { + int16_t ground_accel; + uint16_t flight; + } flight; + struct { + int16_t accel; + int16_t pres; + } sensor; + struct { + int16_t temp; + int16_t v_batt; + } temp_volt; + struct { + int16_t drogue; + int16_t main; + } deploy; + struct { + uint16_t state; + uint16_t reason; + } state; + struct { + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t flags; + } gps_time; + int32_t gps_latitude; + int32_t gps_longitude; + struct { + int16_t altitude; + uint16_t unused; + } gps_altitude; + struct { + uint16_t svid; + uint8_t unused; + uint8_t c_n; + } gps_sat; + struct { + uint8_t year; + uint8_t month; + uint8_t day; + uint8_t extra; + } gps_date; + struct { + uint16_t d0; + uint16_t d1; + } anon; + } u; +}; + +/* Write a record to the eeprom log */ +uint8_t +ao_log_data(__xdata struct ao_log_record *log) __reentrant; + +#endif /* _AO_LOG_H_ */ diff --git a/src/core/ao_log_telem.c b/src/core/ao_log_telem.c index 9e1b06d3..18ab85dd 100644 --- a/src/core/ao_log_telem.c +++ b/src/core/ao_log_telem.c @@ -15,7 +15,9 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "ao.h" +#include +#include +#include __code uint8_t ao_log_format = AO_LOG_FORMAT_TELEMETRY; diff --git a/src/core/ao_product.c b/src/core/ao_product.c index fb59580b..f79922f5 100644 --- a/src/core/ao_product.c +++ b/src/core/ao_product.c @@ -70,26 +70,26 @@ __code __at(0x00aa) uint8_t ao_usb_descriptors [] = /* Header functional descriptor */ 0x05, - CS_INTERFACE, + AO_USB_CS_INTERFACE, 0x00, /* bDescriptor SubType Header */ LE_WORD(0x0110), /* CDC version 1.1 */ /* Call management functional descriptor */ 0x05, - CS_INTERFACE, + AO_USB_CS_INTERFACE, 0x01, /* bDescriptor SubType Call Management */ 0x01, /* bmCapabilities = device handles call management */ 0x01, /* bDataInterface call management interface number */ /* ACM functional descriptor */ 0x04, - CS_INTERFACE, + AO_USB_CS_INTERFACE, 0x02, /* bDescriptor SubType Abstract Control Management */ 0x02, /* bmCapabilities = D1 (Set_line_Coding, Set_Control_Line_State, Get_Line_Coding and Serial_State) */ /* Union functional descriptor */ 0x05, - CS_INTERFACE, + AO_USB_CS_INTERFACE, 0x06, /* bDescriptor SubType Union Functional descriptor */ 0x00, /* bMasterInterface */ 0x01, /* bSlaveInterface0 */ diff --git a/src/core/ao_report.c b/src/core/ao_report.c index 7c928792..eb90a4f8 100644 --- a/src/core/ao_report.c +++ b/src/core/ao_report.c @@ -16,6 +16,8 @@ */ #include "ao.h" +#include +#include #define BIT(i,x) ((x) ? (1 << (i)) : 0) #define MORSE1(a) (1 | BIT(3,a)) diff --git a/src/core/ao_sample.h b/src/core/ao_sample.h new file mode 100644 index 00000000..fb0e69e8 --- /dev/null +++ b/src/core/ao_sample.h @@ -0,0 +1,137 @@ +/* + * 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_SAMPLE_H_ +#define _AO_SAMPLE_H_ + +/* + * ao_sample.c + */ + +/* + * Barometer calibration + * + * We directly sample the barometer. The specs say: + * + * Pressure range: 15-115 kPa + * Voltage at 115kPa: 2.82 + * Output scale: 27mV/kPa + * + * If we want to detect launch with the barometer, we need + * a large enough bump to not be fooled by noise. At typical + * launch elevations (0-2000m), a 200Pa pressure change cooresponds + * to about a 20m elevation change. This is 5.4mV, or about 3LSB. + * As all of our calculations are done in 16 bits, we'll actually see a change + * of 16 times this though + * + * 27 mV/kPa * 32767 / 3300 counts/mV = 268.1 counts/kPa + */ + +/* Accelerometer calibration + * + * We're sampling the accelerometer through a resistor divider which + * consists of 5k and 10k resistors. This multiplies the values by 2/3. + * That goes into the cc1111 A/D converter, which is running at 11 bits + * of precision with the bits in the MSB of the 16 bit value. Only positive + * values are used, so values should range from 0-32752 for 0-3.3V. The + * specs say we should see 40mV/g (uncalibrated), multiply by 2/3 for what + * the A/D converter sees (26.67 mV/g). We should see 32752/3300 counts/mV, + * for a final computation of: + * + * 26.67 mV/g * 32767/3300 counts/mV = 264.8 counts/g + * + * Zero g was measured at 16000 (we would expect 16384). + * Note that this value is only require to tell if the + * rocket is standing upright. Once that is determined, + * the value of the accelerometer is averaged for 100 samples + * to find the resting accelerometer value, which is used + * for all further flight computations + */ + +#define GRAVITY 9.80665 + +/* + * Above this height, the baro sensor doesn't work + */ +#define AO_MAX_BARO_HEIGHT 12000 + +/* + * Above this speed, baro measurements are unreliable + */ +#define AO_MAX_BARO_SPEED 200 + +#define ACCEL_NOSE_UP (ao_accel_2g >> 2) + +/* + * Speed and acceleration are scaled by 16 to provide a bit more + * resolution while still having reasonable range. Note that this + * limits speed to 2047m/s (around mach 6) and acceleration to + * 2047m/s² (over 200g) + */ + +#define AO_M_TO_HEIGHT(m) ((int16_t) (m)) +#define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16)) +#define AO_MSS_TO_ACCEL(mss) ((int16_t) ((mss) * 16)) + +extern __pdata uint16_t ao_sample_tick; /* time of last data */ +extern __pdata int16_t ao_sample_pres; /* most recent pressure sensor reading */ +extern __pdata int16_t ao_sample_alt; /* MSL of ao_sample_pres */ +extern __pdata int16_t ao_sample_height; /* AGL of ao_sample_pres */ +extern __data uint8_t ao_sample_adc; /* Ring position of last processed sample */ + +#if HAS_ACCEL +extern __pdata int16_t ao_sample_accel; /* most recent accel sensor reading */ +#endif + +extern __pdata int16_t ao_ground_pres; /* startup pressure */ +extern __pdata int16_t ao_ground_height; /* MSL of ao_ground_pres */ + +#if HAS_ACCEL +extern __pdata int16_t ao_ground_accel; /* startup acceleration */ +extern __pdata int16_t ao_accel_2g; /* factory accel calibration */ +extern __pdata int32_t ao_accel_scale; /* sensor to m/s² conversion */ +#endif + +void ao_sample_init(void); + +/* returns FALSE in preflight mode, TRUE in flight mode */ +uint8_t ao_sample(void); + +/* + * ao_kalman.c + */ + +#define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) +#define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) +#define from_fix(x) ((x) >> 16) + +extern __pdata int16_t ao_height; /* meters */ +extern __pdata int16_t ao_speed; /* m/s * 16 */ +extern __pdata int16_t ao_accel; /* m/s² * 16 */ +extern __pdata int16_t ao_max_height; /* max of ao_height */ +extern __pdata int16_t ao_avg_height; /* running average of height */ + +extern __pdata int16_t ao_error_h; +extern __pdata int16_t ao_error_h_sq_avg; + +#if HAS_ACCEL +extern __pdata int16_t ao_error_a; +#endif + +void ao_kalman(void); + +#endif /* _AO_SAMPLE_H_ */ diff --git a/src/core/ao_serial.h b/src/core/ao_serial.h new file mode 100644 index 00000000..53aa8a89 --- /dev/null +++ b/src/core/ao_serial.h @@ -0,0 +1,86 @@ +/* + * 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_SERIAL_H_ +#define _AO_SERIAL_H_ + +#define AO_SERIAL_SPEED_4800 0 +#define AO_SERIAL_SPEED_9600 1 +#define AO_SERIAL_SPEED_19200 2 +#define AO_SERIAL_SPEED_57600 3 + +#if HAS_SERIAL_0 +extern volatile __xdata struct ao_fifo ao_serial0_rx_fifo; +extern volatile __xdata struct ao_fifo ao_serial0_tx_fifo; + +char +ao_serial0_getchar(void); + +void +ao_serial0_putchar(char c); + +void +ao_serial0_drain(void); + +void +ao_serial0_set_speed(uint8_t speed); +#endif + +#if HAS_SERIAL_1 +extern volatile __xdata struct ao_fifo ao_serial1_rx_fifo; +extern volatile __xdata struct ao_fifo ao_serial1_tx_fifo; + +char +ao_serial1_getchar(void); + +char +ao_serial1_pollchar(void); + +void +ao_serial1_putchar(char c); + +void +ao_serial1_drain(void); + +void +ao_serial1_set_speed(uint8_t speed); +#endif + +#if HAS_SERIAL_2 +extern volatile __xdata struct ao_fifo ao_serial2_rx_fifo; +extern volatile __xdata struct ao_fifo ao_serial2_tx_fifo; + +char +ao_serial2_getchar(void); + +char +ao_serial2_pollchar(void); + +void +ao_serial2_putchar(char c); + +void +ao_serial2_drain(void); + +void +ao_serial2_set_speed(uint8_t speed); +#endif + +void +ao_serial_init(void); + +#endif /* _AO_SERIAL_H_ */ diff --git a/src/core/ao_stdio.c b/src/core/ao_stdio.c index 2967e705..18fa913e 100644 --- a/src/core/ao_stdio.c +++ b/src/core/ao_stdio.c @@ -21,6 +21,12 @@ * Basic I/O functions to support SDCC stdio package */ +#ifdef SERIAL_STDIN_PORT +#define USE_SERIAL_STDIN 1 +#else +#define USE_SERIAL_STDIN 0 +#endif + #define AO_NUM_STDIOS (HAS_USB + PACKET_HAS_SLAVE + USE_SERIAL_STDIN) __xdata struct ao_stdio ao_stdios[AO_NUM_STDIOS]; diff --git a/src/core/ao_storage.c b/src/core/ao_storage.c index ff4747d0..66394e01 100644 --- a/src/core/ao_storage.c +++ b/src/core/ao_storage.c @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "ao.h" +#include uint8_t ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant diff --git a/src/core/ao_storage.h b/src/core/ao_storage.h new file mode 100644 index 00000000..873fe097 --- /dev/null +++ b/src/core/ao_storage.h @@ -0,0 +1,84 @@ +/* + * 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_STORAGE_H_ +#define _AO_STORAGE_H_ + +/* + * Storage interface, provided by one of the eeprom or flash + * drivers + */ + +/* Total bytes of available storage */ +extern __pdata uint32_t ao_storage_total; + +/* Block size - device is erased in these units. At least 256 bytes */ +extern __pdata uint32_t ao_storage_block; + +/* Byte offset of config block. Will be ao_storage_block bytes long */ +extern __pdata uint32_t ao_storage_config; + +/* Storage unit size - device reads and writes must be within blocks of this size. Usually 256 bytes. */ +extern __pdata uint16_t ao_storage_unit; + +#define AO_STORAGE_ERASE_LOG (ao_storage_config + AO_CONFIG_MAX_SIZE) + +/* Initialize above values. Can only be called once the OS is running */ +void +ao_storage_setup(void) __reentrant; + +/* Write data. Returns 0 on failure, 1 on success */ +uint8_t +ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; + +/* Read data. Returns 0 on failure, 1 on success */ +uint8_t +ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; + +/* Erase a block of storage. This always clears ao_storage_block bytes */ +uint8_t +ao_storage_erase(uint32_t pos) __reentrant; + +/* Flush any pending writes to stable storage */ +void +ao_storage_flush(void) __reentrant; + +/* Initialize the storage code */ +void +ao_storage_init(void); + +/* + * Low-level functions wrapped by ao_storage.c + */ + +/* Read data within a storage unit */ +uint8_t +ao_storage_device_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; + +/* Write data within a storage unit */ +uint8_t +ao_storage_device_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; + +/* Initialize low-level device bits */ +void +ao_storage_device_init(void); + +/* Print out information about flash chips */ +void +ao_storage_device_info(void) __reentrant; + +#endif /* _AO_STORAGE_H_ */ diff --git a/src/core/ao_usb.h b/src/core/ao_usb.h new file mode 100644 index 00000000..e051db93 --- /dev/null +++ b/src/core/ao_usb.h @@ -0,0 +1,136 @@ +/* + * 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_USB_H_ +#define _AO_USB_H_ + +/* + * ao_usb.c + */ + +/* Put one character to the USB output queue */ +void +ao_usb_putchar(char c); + +/* Get one character from the USB input queue */ +char +ao_usb_getchar(void); + +/* Poll for a charcter on the USB input queue. + * returns AO_READ_AGAIN if none are available + */ +char +ao_usb_pollchar(void); + +/* Flush the USB output queue */ +void +ao_usb_flush(void); + +/* Enable the USB controller */ +void +ao_usb_enable(void); + +/* Disable the USB controller */ +void +ao_usb_disable(void); + +/* Initialize the USB system */ +void +ao_usb_init(void); + +extern __code __at (0x00aa) uint8_t ao_usb_descriptors []; + +#define AO_USB_SETUP_DIR_MASK (0x01 << 7) +#define AO_USB_SETUP_TYPE_MASK (0x03 << 5) +#define AO_USB_SETUP_RECIP_MASK (0x1f) + +#define AO_USB_DIR_OUT 0 +#define AO_USB_DIR_IN (1 << 7) + +#define AO_USB_TYPE_STANDARD 0 +#define AO_USB_TYPE_CLASS (1 << 5) +#define AO_USB_TYPE_VENDOR (2 << 5) +#define AO_USB_TYPE_RESERVED (3 << 5) + +#define AO_USB_RECIP_DEVICE 0 +#define AO_USB_RECIP_INTERFACE 1 +#define AO_USB_RECIP_ENDPOINT 2 +#define AO_USB_RECIP_OTHER 3 + +/* standard requests */ +#define AO_USB_REQ_GET_STATUS 0x00 +#define AO_USB_REQ_CLEAR_FEATURE 0x01 +#define AO_USB_REQ_SET_FEATURE 0x03 +#define AO_USB_REQ_SET_ADDRESS 0x05 +#define AO_USB_REQ_GET_DESCRIPTOR 0x06 +#define AO_USB_REQ_SET_DESCRIPTOR 0x07 +#define AO_USB_REQ_GET_CONFIGURATION 0x08 +#define AO_USB_REQ_SET_CONFIGURATION 0x09 +#define AO_USB_REQ_GET_INTERFACE 0x0A +#define AO_USB_REQ_SET_INTERFACE 0x0B +#define AO_USB_REQ_SYNCH_FRAME 0x0C + +#define AO_USB_DESC_DEVICE 1 +#define AO_USB_DESC_CONFIGURATION 2 +#define AO_USB_DESC_STRING 3 +#define AO_USB_DESC_INTERFACE 4 +#define AO_USB_DESC_ENDPOINT 5 +#define AO_USB_DESC_DEVICE_QUALIFIER 6 +#define AO_USB_DESC_OTHER_SPEED 7 +#define AO_USB_DESC_INTERFACE_POWER 8 + +#define AO_USB_GET_DESC_TYPE(x) (((x)>>8)&0xFF) +#define AO_USB_GET_DESC_INDEX(x) ((x)&0xFF) + +#define AO_USB_CONTROL_EP 0 +#define AO_USB_CONTROL_SIZE 32 + +#define AO_USB_INT_EP 1 +#define AO_USB_INT_SIZE 8 + +#define AO_USB_OUT_EP 4 +#define AO_USB_IN_EP 5 +/* + * USB bulk packets can only come in 8, 16, 32 and 64 + * byte sizes, so we'll use 64 for everything + */ +#define AO_USB_IN_SIZE 64 +#define AO_USB_OUT_SIZE 64 + +#define AO_USB_EP0_IDLE 0 +#define AO_USB_EP0_DATA_IN 1 +#define AO_USB_EP0_DATA_OUT 2 + +#define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) + +/* CDC definitions */ +#define AO_USB_CS_INTERFACE 0x24 +#define AO_USB_CS_ENDPOINT 0x25 + +#define AO_USB_SET_LINE_CODING 0x20 +#define AO_USB_GET_LINE_CODING 0x21 +#define AO_USB_SET_CONTROL_LINE_STATE 0x22 + +/* Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */ +struct ao_usb_line_coding { + uint32_t rate; + uint8_t char_format; + uint8_t parity; + uint8_t data_bits; +} ; + +#endif /* _AO_USB_H_ */ diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c index 5eb78815..f193ac8e 100644 --- a/src/drivers/ao_btm.c +++ b/src/drivers/ao_btm.c @@ -17,6 +17,13 @@ #include "ao.h" +#ifndef ao_serial_btm_getchar +#define ao_serial_btm_putchar ao_serial1_putchar +#define ao_serial_btm_pollchar ao_serial1_pollchar +#define ao_serial_btm_set_speed ao_serial1_set_speed +#define ao_serial_btm_drain ao_serial1_drain +#endif + int8_t ao_btm_stdio; __xdata uint8_t ao_btm_connected; @@ -80,9 +87,9 @@ ao_btm_speed(void) { ao_cmd_decimal(); if (ao_cmd_lex_u32 == 57600) - ao_serial_set_speed(AO_SERIAL_SPEED_57600); + ao_serial_btm_set_speed(AO_SERIAL_SPEED_57600); else if (ao_cmd_lex_u32 == 19200) - ao_serial_set_speed(AO_SERIAL_SPEED_19200); + ao_serial_btm_set_speed(AO_SERIAL_SPEED_19200); else ao_cmd_status = ao_cmd_syntax_error; } @@ -104,8 +111,6 @@ __code struct ao_cmds ao_btm_cmds[] = { #define AO_BTM_MAX_REPLY 16 __xdata char ao_btm_reply[AO_BTM_MAX_REPLY]; -extern volatile __xdata struct ao_fifo ao_usart1_rx_fifo; - /* * Read a line of data from the serial port, truncating * it after a few characters. @@ -119,7 +124,7 @@ ao_btm_get_line(void) for (;;) { - while ((c = ao_serial_pollchar()) != AO_READ_AGAIN) { + while ((c = ao_serial_btm_pollchar()) != AO_READ_AGAIN) { ao_btm_log_in_char(c); if (ao_btm_reply_len < sizeof (ao_btm_reply)) ao_btm_reply[ao_btm_reply_len++] = c; @@ -128,7 +133,7 @@ ao_btm_get_line(void) } for (c = 0; c < 10; c++) { ao_delay(AO_MS_TO_TICKS(10)); - if (!ao_fifo_empty(ao_usart1_rx_fifo)) + if (!ao_fifo_empty(ao_serial1_rx_fifo)) break; } if (c == 10) @@ -168,7 +173,7 @@ void ao_btm_putchar(char c) { ao_btm_log_out_char(c); - ao_serial_putchar(c); + ao_serial_btm_putchar(c); ao_delay(1); } @@ -229,8 +234,8 @@ ao_btm_set_name(void) uint8_t ao_btm_try_speed(uint8_t speed) { - ao_serial_set_speed(speed); - ao_btm_drain(); + ao_serial_btm_set_speed(speed); + ao_serial_btm_drain(); (void) ao_btm_cmd("\rATE0\rATQ0\r"); if (ao_btm_cmd("AT\r") == 1) return 1; @@ -274,8 +279,8 @@ ao_btm(void) /* Turn off status reporting */ ao_btm_cmd("ATQ1\r"); - ao_btm_stdio = ao_add_stdio(ao_serial_pollchar, - ao_serial_putchar, + ao_btm_stdio = ao_add_stdio(ao_serial_btm_pollchar, + ao_serial_btm_putchar, NULL); ao_btm_echo(0); @@ -341,7 +346,8 @@ void ao_btm_init (void) { ao_serial_init(); - ao_serial_set_speed(AO_SERIAL_SPEED_19200); + + ao_serial_btm_set_speed(AO_SERIAL_SPEED_19200); #if BT_LINK_ON_P1 /* diff --git a/src/drivers/ao_gps_sirf.c b/src/drivers/ao_gps_sirf.c index f2abbf84..91fc948b 100644 --- a/src/drivers/ao_gps_sirf.c +++ b/src/drivers/ao_gps_sirf.c @@ -124,7 +124,13 @@ static __xdata struct sirf_measured_tracker_data ao_sirf_tracker_data; static __pdata uint16_t ao_sirf_cksum; static __pdata uint16_t ao_sirf_len; -#define ao_sirf_byte() ((uint8_t) ao_serial_getchar()) +#ifndef ao_sirf_getchar +#define ao_sirf_getchar ao_serial1_getchar +#define ao_sirf_putchar ao_serial1_putchar +#define ao_sirf_set_speed ao_serial1_set_speed +#endif + +#define ao_sirf_byte() ((uint8_t) ao_sirf_getchar()) static uint8_t data_byte(void) { @@ -283,15 +289,15 @@ static void ao_gps_setup(void) __reentrant { uint8_t i, k; - ao_serial_set_speed(AO_SERIAL_SPEED_4800); + ao_sirf_set_speed(AO_SERIAL_SPEED_4800); for (i = 0; i < 64; i++) - ao_serial_putchar(0x00); + ao_sirf_putchar(0x00); for (k = 0; k < 3; k++) for (i = 0; i < sizeof (ao_gps_set_nmea); i++) - ao_serial_putchar(ao_gps_set_nmea[i]); - ao_serial_set_speed(AO_SERIAL_SPEED_57600); + ao_sirf_putchar(ao_gps_set_nmea[i]); + ao_sirf_set_speed(AO_SERIAL_SPEED_57600); for (i = 0; i < 64; i++) - ao_serial_putchar(0x00); + ao_sirf_putchar(0x00); } static const char ao_gps_set_message_rate[] = { @@ -307,16 +313,16 @@ ao_sirf_set_message_rate(uint8_t msg, uint8_t rate) __reentrant uint8_t i; for (i = 0; i < sizeof (ao_gps_set_message_rate); i++) - ao_serial_putchar(ao_gps_set_message_rate[i]); - ao_serial_putchar(msg); - ao_serial_putchar(rate); + ao_sirf_putchar(ao_gps_set_message_rate[i]); + ao_sirf_putchar(msg); + ao_sirf_putchar(rate); cksum = 0xa6 + msg + rate; for (i = 0; i < 4; i++) - ao_serial_putchar(0); - ao_serial_putchar((cksum >> 8) & 0x7f); - ao_serial_putchar(cksum & 0xff); - ao_serial_putchar(0xb0); - ao_serial_putchar(0xb3); + ao_sirf_putchar(0); + ao_sirf_putchar((cksum >> 8) & 0x7f); + ao_sirf_putchar(cksum & 0xff); + ao_sirf_putchar(0xb0); + ao_sirf_putchar(0xb3); } static const uint8_t sirf_disable[] = { @@ -338,7 +344,7 @@ ao_gps(void) __reentrant for (k = 0; k < 5; k++) { for (i = 0; i < sizeof (ao_gps_config); i++) - ao_serial_putchar(ao_gps_config[i]); + ao_sirf_putchar(ao_gps_config[i]); for (i = 0; i < sizeof (sirf_disable); i++) ao_sirf_set_message_rate(sirf_disable[i], 0); ao_sirf_set_message_rate(41, 1); diff --git a/src/drivers/ao_gps_skytraq.c b/src/drivers/ao_gps_skytraq.c index 39e36cc8..84616a05 100644 --- a/src/drivers/ao_gps_skytraq.c +++ b/src/drivers/ao_gps_skytraq.c @@ -20,15 +20,15 @@ #endif #ifndef ao_gps_getchar -#define ao_gps_getchar ao_serial_getchar +#define ao_gps_getchar ao_serial1_getchar #endif #ifndef ao_gps_putchar -#define ao_gps_putchar ao_serial_putchar +#define ao_gps_putchar ao_serial1_putchar #endif #ifndef ao_gps_set_speed -#define ao_gps_set_speed ao_serial_set_speed +#define ao_gps_set_speed ao_serial1_set_speed #endif __xdata uint8_t ao_gps_mutex; diff --git a/src/drivers/ao_science_slave.c b/src/drivers/ao_science_slave.c index 1ebb1480..fa9db98b 100644 --- a/src/drivers/ao_science_slave.c +++ b/src/drivers/ao_science_slave.c @@ -17,6 +17,7 @@ #include "ao.h" #include "ao_product.h" +#include "ao_flight.h" struct ao_companion_command ao_companion_command; diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index e4e5def6..f761e5c3 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -61,6 +61,8 @@ #define ao_gps_putchar ao_serial3_putchar #define ao_gps_set_speed ao_serial3_set_speed +#define HAS_EEPROM 1 +#define USE_INTERNAL_FLASH 0 #define HAS_USB 1 #define HAS_BEEP 1 diff --git a/src/product/ao_telebt.c b/src/product/ao_telebt.c index 97c9d792..46c63418 100644 --- a/src/product/ao_telebt.c +++ b/src/product/ao_telebt.c @@ -17,7 +17,9 @@ #include "ao.h" +#if HAS_LOG __code uint8_t ao_log_format = AO_LOG_FORMAT_NONE; /* until we actually log stuff */ +#endif void main(void) diff --git a/src/product/ao_terraui.c b/src/product/ao_terraui.c index 8875ff48..963c7be4 100644 --- a/src/product/ao_terraui.c +++ b/src/product/ao_terraui.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include #include static __xdata struct ao_telemetry_sensor ao_tel_sensor; diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h index adb6eb94..62af86f7 100644 --- a/src/stm/ao_arch.h +++ b/src/stm/ao_arch.h @@ -181,8 +181,6 @@ void ao_lcd_font_init(void); void ao_lcd_font_string(char *s); -#define USE_SERIAL_STDIN (USE_SERIAL_1_STDIN + USE_SERIAL_2_STDIN + USE_SERIAL_3_STDIN) - char ao_serial1_getchar(void); diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c index 3cebc094..406da9fb 100644 --- a/src/stm/ao_serial_stm.c +++ b/src/stm/ao_serial_stm.c @@ -249,7 +249,7 @@ ao_serial2_set_speed(uint8_t speed) struct ao_stm_usart ao_stm_usart3; -void stm_usart3_isr(void) { ao_usart_isr(&ao_stm_usart3, USE_SERIAL_3_STDIN); } +void stm_usart3_isr(void) { ao_usart_isr(&ao_stm_usart3, USE_SERIAL_2_STDIN); } char ao_serial3_getchar(void) diff --git a/src/stm/ao_usb.h b/src/stm/ao_usb.h deleted file mode 100644 index d3129d34..00000000 --- a/src/stm/ao_usb.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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; 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_USB_H_ -#define _AO_USB_H_ - -#define AO_USB_SETUP_DIR_MASK (0x01 << 7) -#define AO_USB_SETUP_TYPE_MASK (0x03 << 5) -#define AO_USB_SETUP_RECIP_MASK (0x1f) - -#define AO_USB_DIR_OUT 0 -#define AO_USB_DIR_IN (1 << 7) - -#define AO_USB_TYPE_STANDARD 0 -#define AO_USB_TYPE_CLASS (1 << 5) -#define AO_USB_TYPE_VENDOR (2 << 5) -#define AO_USB_TYPE_RESERVED (3 << 5) - -#define AO_USB_RECIP_DEVICE 0 -#define AO_USB_RECIP_INTERFACE 1 -#define AO_USB_RECIP_ENDPOINT 2 -#define AO_USB_RECIP_OTHER 3 - -/* standard requests */ -#define AO_USB_REQ_GET_STATUS 0x00 -#define AO_USB_REQ_CLEAR_FEATURE 0x01 -#define AO_USB_REQ_SET_FEATURE 0x03 -#define AO_USB_REQ_SET_ADDRESS 0x05 -#define AO_USB_REQ_GET_DESCRIPTOR 0x06 -#define AO_USB_REQ_SET_DESCRIPTOR 0x07 -#define AO_USB_REQ_GET_CONFIGURATION 0x08 -#define AO_USB_REQ_SET_CONFIGURATION 0x09 -#define AO_USB_REQ_GET_INTERFACE 0x0A -#define AO_USB_REQ_SET_INTERFACE 0x0B -#define AO_USB_REQ_SYNCH_FRAME 0x0C - -#define AO_USB_DESC_DEVICE 1 -#define AO_USB_DESC_CONFIGURATION 2 -#define AO_USB_DESC_STRING 3 -#define AO_USB_DESC_INTERFACE 4 -#define AO_USB_DESC_ENDPOINT 5 -#define AO_USB_DESC_DEVICE_QUALIFIER 6 -#define AO_USB_DESC_OTHER_SPEED 7 -#define AO_USB_DESC_INTERFACE_POWER 8 - -#define AO_USB_GET_DESC_TYPE(x) (((x)>>8)&0xFF) -#define AO_USB_GET_DESC_INDEX(x) ((x)&0xFF) - -#define AO_USB_CONTROL_EP 0 -#define AO_USB_INT_EP 1 -#define AO_USB_OUT_EP 4 -#define AO_USB_IN_EP 5 -#define AO_USB_CONTROL_SIZE 32 -/* - * Double buffer IN and OUT EPs, so each - * gets half of the available space - * - * Ah, but USB bulk packets can only come in 8, 16, 32 and 64 - * byte sizes, so we'll use 64 for everything - */ -#define AO_USB_INT_SIZE 8 -#define AO_USB_IN_SIZE 64 -#define AO_USB_OUT_SIZE 64 - -#define AO_USB_EP0_IDLE 0 -#define AO_USB_EP0_DATA_IN 1 -#define AO_USB_EP0_DATA_OUT 2 - -#define LE_WORD(x) ((x)&0xFF),((uint8_t) (((uint16_t) (x))>>8)) - -/* CDC definitions */ -#define CS_INTERFACE 0x24 -#define CS_ENDPOINT 0x25 - -#define SET_LINE_CODING 0x20 -#define GET_LINE_CODING 0x21 -#define SET_CONTROL_LINE_STATE 0x22 - -/* Data structure for GET_LINE_CODING / SET_LINE_CODING class requests */ -struct ao_usb_line_coding { - uint32_t rate; - uint8_t char_format; - uint8_t parity; - uint8_t data_bits; -} ; - -#endif /* _AO_USB_H_ */ diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c index 5a447d43..586f1e33 100644 --- a/src/stm/ao_usb_stm.c +++ b/src/stm/ao_usb_stm.c @@ -717,17 +717,17 @@ ao_usb_ep0_setup(void) case AO_USB_TYPE_CLASS: debug ("Class setup packet\n"); switch (ao_usb_setup.request) { - case SET_LINE_CODING: + case AO_USB_SET_LINE_CODING: debug ("set line coding\n"); ao_usb_ep0_out_len = 7; ao_usb_ep0_out_data = (uint8_t *) &ao_usb_line_coding; break; - case GET_LINE_CODING: + case AO_USB_GET_LINE_CODING: debug ("get line coding\n"); ao_usb_ep0_in_len = 7; ao_usb_ep0_in_data = (uint8_t *) &ao_usb_line_coding; break; - case SET_CONTROL_LINE_STATE: + case AO_USB_SET_CONTROL_LINE_STATE: break; } break; diff --git a/src/teleballoon-v1.1/ao_pins.h b/src/teleballoon-v1.1/ao_pins.h index a96c6f2b..3305719a 100644 --- a/src/teleballoon-v1.1/ao_pins.h +++ b/src/teleballoon-v1.1/ao_pins.h @@ -30,7 +30,6 @@ #define HAS_BEEP 1 #define HAS_GPS 1 #define HAS_SERIAL_1 1 - #define USE_SERIAL_STDIN 0 #define HAS_ADC 1 #define HAS_EEPROM 1 #define HAS_LOG 1 @@ -127,10 +126,6 @@ #error Please define HAS_SERIAL_1 #endif -#ifndef USE_SERIAL_STDIN -#error Please define USE_SERIAL_STDIN -#endif - #ifndef HAS_ADC #error Please define HAS_ADC #endif diff --git a/src/telepyro-v0.1/Makefile b/src/telepyro-v0.1/Makefile index 2f664fcb..2ac7e747 100644 --- a/src/telepyro-v0.1/Makefile +++ b/src/telepyro-v0.1/Makefile @@ -85,8 +85,10 @@ load: $(PROG).hex ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ -ao_product.rel: ao_product.c ao_product.h - $(call quiet,CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"ao_product.h\"' -o$@ $< +ao_product.o: ao_product.c ao_product.h + +%.o : %.c + $(call quiet,CC) -c $(CFLAGS) $< distclean: clean diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index be99f10d..10e4a2a3 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -22,7 +22,8 @@ INC = \ ao.h \ ao_arch.h \ ao_usb.h \ - ao_pins.h + ao_pins.h \ + ao_product.h # # Common AltOS sources @@ -96,8 +97,10 @@ load: $(PROG).hex ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ -ao_product.rel: ao_product.c ao_product.h - $(call quiet,CC) -c $(CFLAGS) -D PRODUCT_DEFS='\"ao_product.h\"' -o$@ $< +ao_product.o: ao_product.c ao_product.h + +%.o : %.c $(INC) + $(call quiet,CC) -c $(CFLAGS) $< distclean: clean diff --git a/src/teleshield-v0.1/Makefile b/src/teleshield-v0.1/Makefile index 44780476..c1f45f37 100644 --- a/src/teleshield-v0.1/Makefile +++ b/src/teleshield-v0.1/Makefile @@ -54,7 +54,6 @@ CC1111_SRC = \ ao_radio.c \ ao_romconfig.c \ ao_serial.c \ - ao_serial0.c \ ao_string.c \ ao_timer.c \ ao_usb.c \ diff --git a/src/teleshield-v0.1/ao_ardu_serial.c b/src/teleshield-v0.1/ao_ardu_serial.c index 7ff859af..e6e19f67 100644 --- a/src/teleshield-v0.1/ao_ardu_serial.c +++ b/src/teleshield-v0.1/ao_ardu_serial.c @@ -23,7 +23,7 @@ ao_ardu_serial_recv(void) char c; for (;;) { - if (ao_fifo_empty(ao_usart0_rx_fifo)) + if (ao_fifo_empty(ao_serial0_rx_fifo)) flush(); c = ao_serial0_getchar(); putchar (c); @@ -35,6 +35,5 @@ static __xdata struct ao_task ao_ardu_serial_recv_task; void ao_ardu_serial_init (void) { - ao_serial0_init(); ao_add_task(&ao_ardu_serial_recv_task, ao_ardu_serial_recv, "recv"); } diff --git a/src/teleshield-v0.1/ao_pins.h b/src/teleshield-v0.1/ao_pins.h index a907e2a5..701e25fc 100644 --- a/src/teleshield-v0.1/ao_pins.h +++ b/src/teleshield-v0.1/ao_pins.h @@ -26,14 +26,14 @@ #define HAS_SERIAL_1_ALT_1 1 #define HAS_SERIAL_1_ALT_2 0 #define HAS_SERIAL_1_HW_FLOW 1 - #define USE_SERIAL_STDIN 1 + #define USE_SERIAL_1_STDIN 1 #define HAS_SERIAL_0 1 #define HAS_SERIAL_0_ALT_1 0 #define HAS_SERIAL_0_ALT_2 1 #define HAS_SERIAL_0_HW_FLOW 0 #define HAS_ADC 0 #define HAS_DBG 1 - #define HAS_EEPROM 0 + #define HAS_EEPROM 1 #define HAS_LOG 0 #define USE_INTERNAL_FLASH 1 #define HAS_BTM 1 @@ -128,10 +128,6 @@ #error Please define HAS_SERIAL_1 #endif -#ifndef USE_SERIAL_STDIN -#error Please define USE_SERIAL_STDIN -#endif - #ifndef HAS_ADC #error Please define HAS_ADC #endif diff --git a/src/teleshield-v0.1/ao_teleshield.c b/src/teleshield-v0.1/ao_teleshield.c index fd12ce7a..4c32817a 100644 --- a/src/teleshield-v0.1/ao_teleshield.c +++ b/src/teleshield-v0.1/ao_teleshield.c @@ -17,7 +17,9 @@ #include "ao.h" +#if 0 __code uint8_t ao_log_format = AO_LOG_FORMAT_NONE; /* until we actually log stuff */ +#endif void main(void) @@ -43,6 +45,7 @@ main(void) ao_aes_init(); ao_radio_cmac_init(); #endif + ao_serial_init(); ao_ardu_serial_init(); ao_config_init(); ao_start_scheduler(); diff --git a/src/teleterra-v0.1/ao_pins.h b/src/teleterra-v0.1/ao_pins.h index 33de055e..ba7177af 100644 --- a/src/teleterra-v0.1/ao_pins.h +++ b/src/teleterra-v0.1/ao_pins.h @@ -25,7 +25,6 @@ #define HAS_GPS 0 #define HAS_SERIAL_1 0 #define HAS_ADC 0 - #define USE_SERIAL_STDIN 0 #define HAS_EEPROM 1 #define HAS_LOG 1 #define USE_INTERNAL_FLASH 0 @@ -124,10 +123,6 @@ #error Please define HAS_SERIAL_1 #endif -#ifndef USE_SERIAL_STDIN -#error Please define USE_SERIAL_STDIN -#endif - #ifndef HAS_ADC #error Please define HAS_ADC #endif diff --git a/src/teleterra-v0.2/ao_pins.h b/src/teleterra-v0.2/ao_pins.h index 29b97385..2bea4e04 100644 --- a/src/teleterra-v0.2/ao_pins.h +++ b/src/teleterra-v0.2/ao_pins.h @@ -25,7 +25,6 @@ #define HAS_GPS 1 #define HAS_SERIAL_1 1 #define HAS_ADC 0 - #define USE_SERIAL_STDIN 0 #define HAS_EEPROM 1 #define HAS_LOG 1 #define USE_INTERNAL_FLASH 0 @@ -139,10 +138,6 @@ #error Please define HAS_SERIAL_1 #endif -#ifndef USE_SERIAL_STDIN -#error Please define USE_SERIAL_STDIN -#endif - #ifndef HAS_ADC #error Please define HAS_ADC #endif diff --git a/src/test/ao_gps_test.c b/src/test/ao_gps_test.c index 93d7a9ab..4d4012df 100644 --- a/src/test/ao_gps_test.c +++ b/src/test/ao_gps_test.c @@ -317,7 +317,7 @@ static uint8_t sirf_in_message[4096]; static int sirf_in_len; char -ao_serial_getchar(void) +ao_serial1_getchar(void) { char c; uint8_t uc; @@ -351,7 +351,7 @@ ao_serial_getchar(void) void -ao_serial_putchar(char c) +ao_serial1_putchar(char c) { int i; uint8_t uc = (uint8_t) c; @@ -388,7 +388,7 @@ ao_serial_putchar(char c) #define AO_SERIAL_SPEED_57600 1 static void -ao_serial_set_speed(uint8_t speed) +ao_serial1_set_speed(uint8_t speed) { int fd = ao_gps_fd; struct termios termios; diff --git a/src/test/ao_gps_test_skytraq.c b/src/test/ao_gps_test_skytraq.c index a78fae0f..88bed305 100644 --- a/src/test/ao_gps_test_skytraq.c +++ b/src/test/ao_gps_test_skytraq.c @@ -319,7 +319,7 @@ static uint8_t skytraq_in_message[4096]; static int skytraq_in_len; char -ao_serial_getchar(void) +ao_serial1_getchar(void) { char c; uint8_t uc; @@ -354,7 +354,7 @@ ao_serial_getchar(void) void -ao_serial_putchar(char c) +ao_serial1_putchar(char c) { int i; uint8_t uc = (uint8_t) c; @@ -392,7 +392,7 @@ ao_serial_putchar(char c) #define AO_SERIAL_SPEED_57600 2 static void -ao_serial_set_speed(uint8_t speed) +ao_serial1_set_speed(uint8_t speed) { int fd = ao_gps_fd; struct termios termios; -- cgit v1.2.3 From 29edf6d901432a1afc65900ff599c963edac5a2b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 27 May 2012 17:44:01 -0600 Subject: altos: Make telescience-v0.1 build with new ao_data struct Signed-off-by: Keith Packard --- src/avr/ao_adc_avr.c | 24 ++++++++--------- src/avr/ao_pins.h | 3 +-- src/core/ao_log_telescience.c | 14 +++++----- src/core/ao_stdio.c | 16 ++++++------ src/drivers/ao_science_slave.c | 2 +- src/test/Makefile | 4 +-- src/test/ao_flight_test.c | 58 ++++++++++++++++++++++-------------------- 7 files changed, 61 insertions(+), 60 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 4f6f0e60..928cd3e1 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -17,8 +17,8 @@ #include "ao.h" -volatile __xdata struct ao_adc ao_adc_ring[AO_ADC_RING]; -volatile __data uint8_t ao_adc_head; +volatile __xdata struct ao_data ao_data_ring[AO_DATA_RING]; +volatile __data uint8_t ao_data_head; #ifdef TELESCIENCE const uint8_t adc_channels[AO_LOG_TELESCIENCE_NUM_ADC] = { @@ -92,14 +92,14 @@ ISR(ADC_vect) /* Must read ADCL first or the value there will be lost */ value = ADCL; value |= (ADCH << 8); - ao_adc_ring[ao_adc_head].adc[ao_adc_channel] = value; + ao_data_ring[ao_data_head].adc.adc[ao_adc_channel] = value; if (++ao_adc_channel < NUM_ADC) ao_adc_start(); else { ADCSRA = ADCSRA_INIT; - ao_adc_ring[ao_adc_head].tick = ao_time(); - ao_adc_head = ao_adc_ring_next(ao_adc_head); - ao_wakeup((void *) &ao_adc_head); + ao_data_ring[ao_data_head].tick = ao_time(); + ao_data_head = ao_data_ring_next(ao_data_head); + ao_wakeup((void *) &ao_data_head); ao_cpu_sleep_disable = 0; } } @@ -113,18 +113,18 @@ ao_adc_poll(void) } void -ao_adc_get(__xdata struct ao_adc *packet) +ao_data_get(__xdata struct ao_data *packet) { - uint8_t i = ao_adc_ring_prev(ao_adc_head); - memcpy(packet, (void *) &ao_adc_ring[i], sizeof (struct ao_adc)); + uint8_t i = ao_data_ring_prev(ao_data_head); + memcpy(packet, (void *) &ao_data_ring[i], sizeof (struct ao_data)); } static void ao_adc_dump(void) __reentrant { - static __xdata struct ao_adc packet; + static __xdata struct ao_data packet; uint8_t i; - ao_adc_get(&packet); + ao_data_get(&packet); #ifdef TELEPYRO printf("ADMUX: %02x\n", ADMUX); printf("ADCSRA: %02x\n", ADCSRA); @@ -137,7 +137,7 @@ ao_adc_dump(void) __reentrant #endif printf("tick: %5u", packet.tick); for (i = 0; i < NUM_ADC; i++) - printf (" %2d: %5u", i, packet.adc[i]); + printf (" %2d: %5u", i, packet.adc.adc[i]); printf("\n"); diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index f2b40fb4..850a08ec 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -91,10 +91,9 @@ #define AO_TELESCIENCE_NUM_ADC 12 struct ao_adc { - uint16_t tick; /* tick when the sample was read */ uint16_t adc[AO_TELESCIENCE_NUM_ADC]; /* samples */ }; -#define AO_ADC_RING 16 +#define AO_DATA_RING 16 #endif /* _AO_PINS_H_ */ diff --git a/src/core/ao_log_telescience.c b/src/core/ao_log_telescience.c index ae045281..002a10bd 100644 --- a/src/core/ao_log_telescience.c +++ b/src/core/ao_log_telescience.c @@ -20,7 +20,7 @@ #include "ao_log.h" #include "ao_companion.h" -static uint8_t ao_log_adc_pos; +static uint8_t ao_log_data_pos; __code uint8_t ao_log_format = AO_LOG_FORMAT_TELESCIENCE; @@ -62,20 +62,20 @@ ao_log_single(void) /* Write the whole contents of the ring to the log * when starting up. */ - ao_log_adc_pos = ao_adc_ring_next(ao_adc_head); + ao_log_data_pos = ao_data_ring_next(ao_data_head); ao_log_single_write_data.telescience.type = AO_LOG_TELESCIENCE_DATA; while (ao_log_running) { /* Write samples to EEPROM */ - while (ao_log_adc_pos != ao_adc_head) { - ao_log_single_write_data.telescience.tick = ao_adc_ring[ao_log_adc_pos].tick; - memcpy(&ao_log_single_write_data.telescience.adc, (void *) ao_adc_ring[ao_log_adc_pos].adc, + while (ao_log_data_pos != ao_data_head) { + ao_log_single_write_data.telescience.tick = ao_data_ring[ao_log_data_pos].tick; + memcpy(&ao_log_single_write_data.telescience.adc, (void *) ao_data_ring[ao_log_data_pos].adc.adc, AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); ao_log_telescience_csum(); ao_log_single_write(); - ao_log_adc_pos = ao_adc_ring_next(ao_log_adc_pos); + ao_log_data_pos = ao_data_ring_next(ao_log_data_pos); } /* Wait for more ADC data to arrive */ - ao_sleep((void *) &ao_adc_head); + ao_sleep((void *) &ao_data_head); } memset(&ao_log_single_write_data.telescience.adc, '\0', sizeof (ao_log_single_write_data.telescience.adc)); } diff --git a/src/core/ao_stdio.c b/src/core/ao_stdio.c index 9b4ea473..656b23c9 100644 --- a/src/core/ao_stdio.c +++ b/src/core/ao_stdio.c @@ -53,14 +53,14 @@ #endif #define USE_SERIAL_STDIN (USE_SERIAL_0_STDIN + \ - USE_SERIAL_1_STDIN | \ - USE_SERIAL_2_STDIN | \ - USE_SERIAL_3_STDIN | \ - USE_SERIAL_4_STDIN | \ - USE_SERIAL_5_STDIN | \ - USE_SERIAL_6_STDIN | \ - USE_SERIAL_7_STDIN | \ - USE_SERIAL_8_STDIN | \ + USE_SERIAL_1_STDIN + \ + USE_SERIAL_2_STDIN + \ + USE_SERIAL_3_STDIN + \ + USE_SERIAL_4_STDIN + \ + USE_SERIAL_5_STDIN + \ + USE_SERIAL_6_STDIN + \ + USE_SERIAL_7_STDIN + \ + USE_SERIAL_8_STDIN + \ USE_SERIAL_9_STDIN) #define AO_NUM_STDIOS (HAS_USB + PACKET_HAS_SLAVE + USE_SERIAL_STDIN) diff --git a/src/drivers/ao_science_slave.c b/src/drivers/ao_science_slave.c index a86b5151..996e98d9 100644 --- a/src/drivers/ao_science_slave.c +++ b/src/drivers/ao_science_slave.c @@ -42,7 +42,7 @@ void ao_spi_slave(void) sizeof (ao_telescience_setup)); break; case AO_COMPANION_FETCH: - ao_spi_slave_send((uint8_t *) &ao_adc_ring[ao_adc_ring_prev(ao_adc_head)].adc, + ao_spi_slave_send((uint8_t *) &ao_data_ring[ao_data_ring_prev(ao_data_head)].adc, AO_LOG_TELESCIENCE_NUM_ADC * sizeof (uint16_t)); break; case AO_COMPANION_NOTIFY: diff --git a/src/test/Makefile b/src/test/Makefile index 3c2b8732..1e54f5e0 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -13,10 +13,10 @@ clean: install: -ao_flight_test: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c altitude.h ao_kalman.h +ao_flight_test: ao_flight_test.c ao_host.h ao_flight_mm.c ao_sample_mm.c ao_kalman.c altitude.h ao_kalman.h cc $(CFLAGS) -o $@ $< -ao_flight_test_noisy_accel: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c altitude.h ao_kalman.h +ao_flight_test_noisy_accel: ao_flight_test.c ao_host.h ao_flight_mm.c ao_sample_mm.c ao_kalman.c altitude.h ao_kalman.h cc -DNOISY_ACCEL=1 $(CFLAGS) -o $@ $< ao_flight_test_baro: ao_flight_test.c ao_host.h ao_flight.c ao_sample.c ao_kalman.c altitude.h ao_kalman.h diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c index 4a8625cf..baf2ad1d 100644 --- a/src/test/ao_flight_test.c +++ b/src/test/ao_flight_test.c @@ -26,9 +26,10 @@ #define AO_HERTZ 100 -#define AO_ADC_RING 64 -#define ao_adc_ring_next(n) (((n) + 1) & (AO_ADC_RING - 1)) -#define ao_adc_ring_prev(n) (((n) - 1) & (AO_ADC_RING - 1)) +#define HAS_ADC 1 +#define AO_DATA_RING 64 +#define ao_data_ring_next(n) (((n) + 1) & (AO_DATA_RING - 1)) +#define ao_data_ring_prev(n) (((n) - 1) & (AO_DATA_RING - 1)) #define AO_M_TO_HEIGHT(m) ((int16_t) (m)) #define AO_MS_TO_SPEED(ms) ((int16_t) ((ms) * 16)) @@ -38,7 +39,6 @@ * One set of samples read from the A/D converter */ struct ao_adc { - uint16_t tick; /* tick when the sample was read */ int16_t accel; /* accelerometer */ int16_t pres; /* pressure sensor */ int16_t pres_real; /* unclipped */ @@ -54,6 +54,8 @@ struct ao_adc { #define __code #define __reentrant +#include + #define to_fix16(x) ((int16_t) ((x) * 65536.0 + 0.5)) #define to_fix32(x) ((int32_t) ((x) * 65536.0 + 0.5)) #define from_fix(x) ((x) >> 16) @@ -90,8 +92,8 @@ extern enum ao_flight_state ao_flight_state; #define FALSE 0 #define TRUE 1 -struct ao_adc ao_adc_ring[AO_ADC_RING]; -uint8_t ao_adc_head; +volatile struct ao_data ao_data_ring[AO_DATA_RING]; +volatile uint8_t ao_data_head; int ao_summary = 0; #define ao_led_on(l) @@ -110,7 +112,7 @@ enum ao_igniter { ao_igniter_main = 1 }; -struct ao_adc ao_adc_static; +struct ao_data ao_data_static; int drogue_height; double drogue_time; @@ -124,7 +126,7 @@ static int32_t ao_k_height; void ao_ignite(enum ao_igniter igniter) { - double time = (double) (ao_adc_static.tick + tick_offset) / 100; + double time = (double) (ao_data_static.tick + tick_offset) / 100; if (igniter == ao_igniter_drogue) { drogue_time = time; @@ -221,8 +223,8 @@ int ao_sample_prev_tick; uint16_t prev_tick; #include "ao_kalman.c" -#include "ao_sample.c" -#include "ao_flight.c" +#include "ao_sample_mm.c" +#include "ao_flight_mm.c" #define to_double(f) ((f) / 65536.0) @@ -282,19 +284,19 @@ ao_insert(void) { double time; - ao_adc_ring[ao_adc_head] = ao_adc_static; - ao_adc_head = ao_adc_ring_next(ao_adc_head); + ao_data_ring[ao_data_head] = ao_data_static; + ao_data_head = ao_data_ring_next(ao_data_head); if (ao_flight_state != ao_flight_startup) { - double height = ao_pres_to_altitude(ao_adc_static.pres_real) - ao_ground_height; - double accel = ((ao_flight_ground_accel - ao_adc_static.accel) * GRAVITY * 2.0) / + double height = ao_pres_to_altitude(ao_data_static.adc.pres_real) - ao_ground_height; + double accel = ((ao_flight_ground_accel - ao_data_static.adc.accel) * GRAVITY * 2.0) / (ao_config.accel_minus_g - ao_config.accel_plus_g); if (!tick_offset) - tick_offset = -ao_adc_static.tick; - if ((prev_tick - ao_adc_static.tick) > 0x400) + tick_offset = -ao_data_static.tick; + if ((prev_tick - ao_data_static.tick) > 0x400) tick_offset += 65536; - prev_tick = ao_adc_static.tick; - time = (double) (ao_adc_static.tick + tick_offset) / 100; + prev_tick = ao_data_static.tick; + time = (double) (ao_data_static.tick + tick_offset) / 100; if (ao_test_max_height < height) { ao_test_max_height = height; @@ -474,7 +476,7 @@ int16(uint8_t *bytes, int off) void ao_sleep(void *wchan) { - if (wchan == &ao_adc_head) { + if (wchan == &ao_data_head) { char type; uint16_t tick; uint16_t a, b; @@ -490,7 +492,7 @@ ao_sleep(void *wchan) for (;;) { if (ao_records_read > 2 && ao_flight_state == ao_flight_startup) { - ao_adc_static.accel = ao_flight_ground_accel; + ao_data_static.adc.accel = ao_flight_ground_accel; ao_insert(); return; } @@ -501,7 +503,7 @@ ao_sleep(void *wchan) printf ("no more data, exiting simulation\n"); ao_test_exit(); } - ao_adc_static.tick += 10; + ao_data_static.tick += 10; ao_insert(); return; } @@ -639,19 +641,19 @@ ao_sleep(void *wchan) case 'S': break; case 'A': - ao_adc_static.tick = tick; - ao_adc_static.accel = a; - ao_adc_static.pres_real = b; + ao_data_static.tick = tick; + ao_data_static.adc.accel = a; + ao_data_static.adc.pres_real = b; if (b < AO_MIN_BARO_VALUE) b = AO_MIN_BARO_VALUE; - ao_adc_static.pres = b; + ao_data_static.adc.pres = b; ao_records_read++; ao_insert(); return; case 'T': - ao_adc_static.tick = tick; - ao_adc_static.temp = a; - ao_adc_static.v_batt = b; + ao_data_static.tick = tick; + ao_data_static.adc.temp = a; + ao_data_static.adc.v_batt = b; break; case 'D': case 'G': -- cgit v1.2.3 From 08a4ed8fe794a2b2b52147bd5535fe0954822e95 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 27 Jun 2012 14:34:53 -0700 Subject: altos: include targe SPI speed in get request STM needs it to be provided when enabling the SPI device, so just fix AVR and cc1111 to do the same. Signed-off-by: Keith Packard --- src/avr/ao_arch_funcs.h | 10 +++++----- src/cc1111/ao_arch_funcs.h | 19 +++++++++++++++---- src/drivers/ao_25lc1024.c | 2 +- src/drivers/ao_at45db161d.c | 2 +- src/drivers/ao_cc1120.c | 2 +- src/drivers/ao_companion.c | 18 +++++------------- src/drivers/ao_m25.c | 2 +- src/drivers/ao_ms5607.c | 2 +- src/stm-demo/ao_demo.c | 4 ++-- src/stm/ao_arch_funcs.h | 19 ++++++++----------- src/stm/ao_spi_stm.c | 6 ++---- 11 files changed, 42 insertions(+), 44 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_arch_funcs.h b/src/avr/ao_arch_funcs.h index 1eeca6cc..e400c98b 100644 --- a/src/avr/ao_arch_funcs.h +++ b/src/avr/ao_arch_funcs.h @@ -21,7 +21,7 @@ extern __xdata uint8_t ao_spi_mutex; -#define ao_spi_get_mask(reg,mask,bus) do { \ +#define ao_spi_get_mask(reg,mask,bus,speed) do { \ ao_mutex_get(&ao_spi_mutex); \ (reg) &= ~(mask); \ } while (0) @@ -31,13 +31,13 @@ extern __xdata uint8_t ao_spi_mutex; ao_mutex_put(&ao_spi_mutex); \ } while (0) -#define ao_spi_get_bit(bit) do { \ +#define ao_spi_get_bit(reg,bit,pin,bus,speed) do { \ ao_mutex_get(&ao_spi_mutex); \ - (bit) = 0; \ + (pin) = 0; \ } while (0) -#define ao_spi_put_bit(bit) do { \ - (bit) = 1; \ +#define ao_spi_put_bit(reg,bit,pin,bus) do { \ + (pin) = 1; \ ao_mutex_put(&ao_spi_mutex); \ } while (0) diff --git a/src/cc1111/ao_arch_funcs.h b/src/cc1111/ao_arch_funcs.h index 728f1f76..0a322961 100644 --- a/src/cc1111/ao_arch_funcs.h +++ b/src/cc1111/ao_arch_funcs.h @@ -21,9 +21,18 @@ extern __xdata uint8_t ao_spi_mutex; -#define ao_spi_get_mask(reg,mask,bus) do { \ - ao_mutex_get(&ao_spi_mutex); \ - (reg) &= ~(mask); \ +#define AO_SPI_SPEED_FAST 17 +#define AO_SPI_SPEED_200kHz 13 + +#define ao_spi_set_speed(speed) (U0GCR = (UxGCR_CPOL_NEGATIVE | \ + UxGCR_CPHA_FIRST_EDGE | \ + UxGCR_ORDER_MSB | \ + ((speed) << UxGCR_BAUD_E_SHIFT))) + +#define ao_spi_get_mask(reg,mask,bus,speed) do { \ + ao_mutex_get(&ao_spi_mutex); \ + ao_spi_set_speed(speed); \ + (reg) &= ~(mask); \ } while (0) #define ao_spi_put_mask(reg,mask,bus) do { \ @@ -31,8 +40,10 @@ extern __xdata uint8_t ao_spi_mutex; ao_mutex_put(&ao_spi_mutex); \ } while (0) -#define ao_spi_get_bit(reg,bit,pin,bus) do { \ + +#define ao_spi_get_bit(reg,bit,pin,bus,speed) do { \ ao_mutex_get(&ao_spi_mutex); \ + ao_spi_set_speed(speed); \ pin = 0; \ } while (0) diff --git a/src/drivers/ao_25lc1024.c b/src/drivers/ao_25lc1024.c index b25d52c4..c5d811f7 100644 --- a/src/drivers/ao_25lc1024.c +++ b/src/drivers/ao_25lc1024.c @@ -50,7 +50,7 @@ static __xdata uint8_t ao_ee_mutex; _asm nop _endasm; \ } while(0) -#define ao_ee_cs_low() ao_spi_get_bit(EE_CS_PORT, EE_CS_PIN, EE_CS, AO_EE_SPI_BUS) +#define ao_ee_cs_low() ao_spi_get_bit(EE_CS_PORT, EE_CS_PIN, EE_CS, AO_EE_SPI_BUS, AO_SPI_SPEED_FAST) #define ao_ee_cs_high() ao_spi_put_bit(EE_CS_PORT, EE_CS_PIN, EE_CS, AO_EE_SPI_BUS) diff --git a/src/drivers/ao_at45db161d.c b/src/drivers/ao_at45db161d.c index 5eb25acf..e7e74153 100644 --- a/src/drivers/ao_at45db161d.c +++ b/src/drivers/ao_at45db161d.c @@ -43,7 +43,7 @@ __xdata uint8_t ao_flash_mutex; _asm nop _endasm; \ } while(0) -#define ao_flash_cs_low() ao_spi_get_bit(FLASH_CS_PORT, FLASH_CS_PIN, FLASH_CS, AO_FLASH_SPI_BUS) +#define ao_flash_cs_low() ao_spi_get_bit(FLASH_CS_PORT, FLASH_CS_PIN, FLASH_CS, AO_FLASH_SPI_BUS, AO_SPI_SPEED_FAST) #define ao_flash_cs_high() ao_spi_put_bit(FLASH_CS_PORT, FLASH_CS_PIN, FLASH_CS, AO_FLASH_SPI_BUS) diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index cc9ebd30..c974613e 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -33,7 +33,7 @@ const uint32_t ao_radio_cal = 0x6ca333; #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) +#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_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) diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index a31cc2ea..85d68c44 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -18,28 +18,20 @@ #include #include -#ifndef ao_spi_slow -#define ao_spi_slow(bus) (U0GCR = (UxGCR_CPOL_NEGATIVE | \ - UxGCR_CPHA_FIRST_EDGE | \ - UxGCR_ORDER_MSB | \ - (13 << UxGCR_BAUD_E_SHIFT))) - -#define ao_spi_fast(bus) (U0GCR = (UxGCR_CPOL_NEGATIVE | \ - UxGCR_CPHA_FIRST_EDGE | \ - UxGCR_ORDER_MSB | \ - (17 << UxGCR_BAUD_E_SHIFT))) +#ifdef MEGAMETRUM +#define ao_spi_slow(b) +#define ao_spi_fast(b) #endif #define COMPANION_SELECT() do { \ ao_spi_get_bit(AO_COMPANION_CS_PORT, \ AO_COMPANION_CS_PIN, \ AO_COMPANION_CS, \ - AO_COMPANION_SPI_BUS); \ - ao_spi_slow(AO_COMPANION_SPI_BUS); \ + AO_COMPANION_SPI_BUS, \ + AO_SPI_SPEED_200kHz); \ } while (0) #define COMPANION_DESELECT() do { \ - ao_spi_fast(AO_COMPANION_SPI_BUS); \ ao_spi_put_bit(AO_COMPANION_CS_PORT, \ AO_COMPANION_CS_PIN, \ AO_COMPANION_CS, \ diff --git a/src/drivers/ao_m25.c b/src/drivers/ao_m25.c index 2983a405..9603c1de 100644 --- a/src/drivers/ao_m25.c +++ b/src/drivers/ao_m25.c @@ -110,7 +110,7 @@ static void ao_boot_radio(void) { #define ao_boot_radio() #endif -#define M25_SELECT(cs) do { ao_boot_radio(); ao_spi_get_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS); } while (0) +#define M25_SELECT(cs) do { ao_boot_radio(); ao_spi_get_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS, AO_SPI_SPEED_FAST); } while (0) #define M25_DESELECT(cs) ao_spi_put_mask(AO_M25_SPI_CS_PORT,cs,AO_M25_SPI_BUS) #define M25_BLOCK_SHIFT 16 diff --git a/src/drivers/ao_ms5607.c b/src/drivers/ao_ms5607.c index e08f4d40..e1d0507e 100644 --- a/src/drivers/ao_ms5607.c +++ b/src/drivers/ao_ms5607.c @@ -24,7 +24,7 @@ static uint8_t ms5607_configured; static void ao_ms5607_start(void) { - ao_spi_get(AO_MS5607_SPI_INDEX); + ao_spi_get(AO_MS5607_SPI_INDEX,AO_SPI_SPEED_FAST); stm_gpio_set(AO_MS5607_CS_GPIO, AO_MS5607_CS, 0); } diff --git a/src/stm-demo/ao_demo.c b/src/stm-demo/ao_demo.c index 73ace558..9a581ff9 100644 --- a/src/stm-demo/ao_demo.c +++ b/src/stm-demo/ao_demo.c @@ -83,7 +83,7 @@ ao_spi_write(void) { int i; for (i = 0; i < 10; i++) { - ao_spi_get(0); + ao_spi_get(0, AO_SPI_SPEED_FAST); stm_gpio_set(&stm_gpioc, 12, 0); ao_spi_send(data, 4, 0); stm_gpio_set(&stm_gpioc, 12, 1); @@ -100,7 +100,7 @@ ao_spi_read(void) { int i; for (i = 0; i < 10; i++) { - ao_spi_get(0); + ao_spi_get(0, AO_SPI_SPEED_FAST); stm_gpio_set(&stm_gpioc, 12, 0); ao_spi_recv(data, 4, 0); stm_gpio_set(&stm_gpioc, 12, 1); diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 62b10063..7820bf79 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -22,8 +22,12 @@ */ extern uint8_t ao_spi_mutex[STM_NUM_SPI]; +#define AO_SPI_SPEED_FAST STM_SPI_CR1_BR_PCLK_4 +#define AO_SPI_SPEED_1MHz STM_SPI_CR1_BR_PCLK_16 +#define AO_SPI_SPEED_200kHz STM_SPI_CR1_BR_PCLK_256 + void -ao_spi_get(uint8_t spi_index); +ao_spi_get(uint8_t spi_index, uint32_t speed); void ao_spi_put(uint8_t spi_index); @@ -40,20 +44,13 @@ ao_spi_recv(void *block, uint16_t len, uint8_t spi_index); void ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index); -#define AO_SPI_SPEED_FAST STM_SPI_CR1_BR_PCLK_16 -#define AO_SPI_SPEED_200kHz STM_SPI_CR1_BR_PCLK_256 - extern uint16_t ao_spi_speed[STM_NUM_SPI]; -#define ao_spi_slow(bus) (ao_spi_speed[bus] = AO_SPI_SPEED_200kHz) - -#define ao_spi_fast(bus) (ao_spi_speed[bus] = AO_SPI_SPEED_FAST) - void ao_spi_init(void); -#define ao_spi_get_mask(reg,mask,bus) do { \ - ao_spi_get(bus); \ +#define ao_spi_get_mask(reg,mask,bus, speed) do { \ + ao_spi_get(bus, speed); \ (reg)->bsrr = ((uint32_t) mask) << 16; \ } while (0) @@ -62,7 +59,7 @@ ao_spi_init(void); ao_spi_put(bus); \ } while (0) -#define ao_spi_get_bit(reg,bit,pin,bus) ao_spi_get_mask(reg,(1< Date: Sat, 14 Jul 2012 02:44:17 -0700 Subject: src: Add explicit 'pin' argument to ao_enable_output This lets the cc1111 use the atomic bit operation instead of a mask, which is immune to interrupt issues as well as being a shorter code sequence. Signed-off-by: Keith Packard --- src/avr/ao_arch_funcs.h | 17 +++++++++++++++++ src/cc1111/ao_arch_funcs.h | 12 ++++++------ src/core/ao_ignite.c | 4 ++-- src/core/ao_pyro.c | 41 +++++++++++++++++++++-------------------- src/drivers/ao_25lc1024.c | 2 +- src/drivers/ao_companion.c | 2 +- src/stm/ao_arch_funcs.h | 8 ++++---- 7 files changed, 52 insertions(+), 34 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_arch_funcs.h b/src/avr/ao_arch_funcs.h index e400c98b..792ff744 100644 --- a/src/avr/ao_arch_funcs.h +++ b/src/avr/ao_arch_funcs.h @@ -41,12 +41,29 @@ extern __xdata uint8_t ao_spi_mutex; ao_mutex_put(&ao_spi_mutex); \ } while (0) + +#define ao_gpio_token_paster(x,y) x ## y +#define ao_gpio_token_evaluator(x,y) ao_gpio_token_paster(x,y) + +#define ao_gpio_set(port, bit, pin, v) do { \ + if (v) \ + (ao_gpio_token_evaluator(PORT,port)) |= (1 << bit); \ + else \ + (ao_gpio_token_evaluator(PORT,port)) &= ~(1 << bit); \ + } while (0) + /* * The SPI mutex must be held to call either of these * functions -- this mutex covers the entire SPI operation, * from chip select low to chip select high */ +#define ao_enable_output(port, bit, pin, v) do { \ + ao_gpio_set(port, bit, pin, v); \ + ao_gpio_token_evaluator(DDR,port) |= (1 << bit); \ + } while (0) + + void ao_spi_send_bus(void __xdata *block, uint16_t len) __reentrant; diff --git a/src/cc1111/ao_arch_funcs.h b/src/cc1111/ao_arch_funcs.h index 0a322961..0737e7ab 100644 --- a/src/cc1111/ao_arch_funcs.h +++ b/src/cc1111/ao_arch_funcs.h @@ -77,14 +77,14 @@ ao_spi_init(void); SPI_CS_SEL &= ~mask; \ } while (0) -#define cc1111_enable_output(port,dir,sel,mask,v) do { \ - port = port & ~(mask) | v; \ - dir |= mask; \ - sel &= ~mask; \ -} while (0) +#define cc1111_enable_output(port,dir,sel,pin,bit,v) do { \ + pin = v; \ + dir |= (1 << bit); \ + sel &= ~(1 << bit); \ + } while (0) #define disable_unreachable _Pragma("disable_warning 126") #define token_paster(x,y) x ## y #define token_evaluator(x,y) token_paster(x,y) -#define ao_enable_output(port,pin,v) cc1111_enable_output(port,token_evaluator(port,DIR), token_evaluator(port,SEL), 1 << pin, 1 << v) +#define ao_enable_output(port,bit,pin,v) cc1111_enable_output(port,token_evaluator(port,DIR), token_evaluator(port,SEL), pin, bit, v) diff --git a/src/core/ao_ignite.c b/src/core/ao_ignite.c index e82de355..c7829fc3 100644 --- a/src/core/ao_ignite.c +++ b/src/core/ao_ignite.c @@ -195,8 +195,8 @@ __xdata struct ao_task ao_igniter_task; void ao_ignite_set_pins(void) { - ao_enable_output(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, 0); - ao_enable_output(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, 0); + ao_enable_output(AO_IGNITER_DROGUE_PORT, AO_IGNITER_DROGUE_PIN, AO_IGNITER_DROGUE, 0); + ao_enable_output(AO_IGNITER_MAIN_PORT, AO_IGNITER_MAIN_PIN, AO_IGNITER_MAIN, 0); } void diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index c060a866..943413e6 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -102,16 +102,18 @@ ao_pyro_ready(struct ao_pyro *pyro) /* handled separately */ continue; + case ao_pyro_none: + break; } return FALSE; } return TRUE; } -#define ao_pyro_fire_port(port, pin) do { \ - ao_gpio_set(port, pin, 1); \ +#define ao_pyro_fire_port(port, bit, pin) do { \ + ao_gpio_set(port, bit, pin, 1); \ ao_delay(AO_MS_TO_TICKS(50)); \ - ao_gpio_set(port, pin, 0); \ + ao_gpio_set(port, bit, pin, 0); \ } while (0) @@ -120,28 +122,28 @@ ao_pyro_fire(uint8_t p) { switch (p) { #if AO_PYRO_NUM > 0 - case 0: ao_pyro_fire_port(AO_PYRO_PORT_0, AO_PYRO_PIN_0); break; + case 0: ao_pyro_fire_port(AO_PYRO_PORT_0, AO_PYRO_PIN_0, AO_PYRO_0); break; #endif #if AO_PYRO_NUM > 1 - case 1: ao_pyro_fire_port(AO_PYRO_PORT_1, AO_PYRO_PIN_1); break; + case 1: ao_pyro_fire_port(AO_PYRO_PORT_1, AO_PYRO_PIN_1, AO_PYRO_1); break; #endif #if AO_PYRO_NUM > 2 - case 2: ao_pyro_fire_port(AO_PYRO_PORT_2, AO_PYRO_PIN_2); break; + case 2: ao_pyro_fire_port(AO_PYRO_PORT_2, AO_PYRO_PIN_2, AO_PYRO_2); break; #endif #if AO_PYRO_NUM > 3 - case 3: ao_pyro_fire_port(AO_PYRO_PORT_3, AO_PYRO_PIN_3); break; + case 3: ao_pyro_fire_port(AO_PYRO_PORT_3, AO_PYRO_PIN_3, AO_PYRO_3); break; #endif #if AO_PYRO_NUM > 4 - case 4: ao_pyro_fire_port(AO_PYRO_PORT_4, AO_PYRO_PIN_4); break; + case 4: ao_pyro_fire_port(AO_PYRO_PORT_4, AO_PYRO_PIN_4, AO_PYRO_4); break; #endif #if AO_PYRO_NUM > 5 - case 5: ao_pyro_fire_port(AO_PYRO_PORT_5, AO_PYRO_PIN_5); break; + case 5: ao_pyro_fire_port(AO_PYRO_PORT_5, AO_PYRO_PIN_5, AO_PYRO_5); break; #endif #if AO_PYRO_NUM > 6 - case 6: ao_pyro_fire_port(AO_PYRO_PORT_6, AO_PYRO_PIN_6); break; + case 6: ao_pyro_fire_port(AO_PYRO_PORT_6, AO_PYRO_PIN_6, AO_PYRO_6); break; #endif #if AO_PYRO_NUM > 7 - case 7: ao_pyro_fire_port(AO_PYRO_PORT_7, AO_PYRO_PIN_7); break; + case 7: ao_pyro_fire_port(AO_PYRO_PORT_7, AO_PYRO_PIN_7, AO_PYRO_7); break; #endif default: break; } @@ -291,7 +293,6 @@ void ao_pyro_set(void) { uint8_t p; - struct ao_pyro *pyro; struct ao_pyro pyro_tmp; char name[AO_PYRO_NAME_LEN]; uint8_t c; @@ -351,28 +352,28 @@ void ao_pyro_init(void) { #if AO_PYRO_NUM > 0 - ao_enable_output(AO_PYRO_PORT_0, AO_PYRO_PIN_0, 0); + ao_enable_output(AO_PYRO_PORT_0, AO_PYRO_PIN_0, AO_PYRO_0, 0); #endif #if AO_PYRO_NUM > 1 - ao_enable_output(AO_PYRO_PORT_1, AO_PYRO_PIN_1, 0); + ao_enable_output(AO_PYRO_PORT_1, AO_PYRO_PIN_1, AO_PYRO_1, 0); #endif #if AO_PYRO_NUM > 2 - ao_enable_output(AO_PYRO_PORT_2, AO_PYRO_PIN_2, 0); + ao_enable_output(AO_PYRO_PORT_2, AO_PYRO_PIN_2, AO_PYRO_2, 0); #endif #if AO_PYRO_NUM > 3 - ao_enable_output(AO_PYRO_PORT_3, AO_PYRO_PIN_3, 0); + ao_enable_output(AO_PYRO_PORT_3, AO_PYRO_PIN_3, AO_PYRO_3, 0); #endif #if AO_PYRO_NUM > 4 - ao_enable_output(AO_PYRO_PORT_4, AO_PYRO_PIN_4, 0); + ao_enable_output(AO_PYRO_PORT_4, AO_PYRO_PIN_4, AO_PYRO_4, 0); #endif #if AO_PYRO_NUM > 5 - ao_enable_output(AO_PYRO_PORT_5, AO_PYRO_PIN_5, 0); + ao_enable_output(AO_PYRO_PORT_5, AO_PYRO_PIN_5, AO_PYRO_5, 0); #endif #if AO_PYRO_NUM > 6 - ao_enable_output(AO_PYRO_PORT_6, AO_PYRO_PIN_6, 0); + ao_enable_output(AO_PYRO_PORT_6, AO_PYRO_PIN_6, AO_PYRO_6, 0); #endif #if AO_PYRO_NUM > 7 - ao_enable_output(AO_PYRO_PORT_7, AO_PYRO_PIN_7, 0); + ao_enable_output(AO_PYRO_PORT_7, AO_PYRO_PIN_7, AO_PYRO_7, 0); #endif ao_add_task(&ao_pyro_task, ao_pyro, "pyro"); } diff --git a/src/drivers/ao_25lc1024.c b/src/drivers/ao_25lc1024.c index c5d811f7..fac0a430 100644 --- a/src/drivers/ao_25lc1024.c +++ b/src/drivers/ao_25lc1024.c @@ -236,5 +236,5 @@ void ao_storage_device_init(void) { /* set up CS */ - ao_enable_output(EE_CS_PORT, EE_CS_PIN,1); + ao_enable_output(EE_CS_PORT, EE_CS_PIN, EE_CS, 1); } diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index 85d68c44..a3167956 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -131,7 +131,7 @@ static __xdata struct ao_task ao_companion_task; void ao_companion_init(void) { - ao_enable_output(AO_COMPANION_CS_PORT, AO_COMPANION_CS_PIN, 1); + ao_enable_output(AO_COMPANION_CS_PORT, AO_COMPANION_CS_PIN, AO_COMPANION_CS, 1); ao_cmd_register(&ao_companion_cmds[0]); ao_add_task(&ao_companion_task, ao_companion, "companion"); } diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 4416bbab..d2c973f5 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -76,12 +76,12 @@ ao_spi_init(void); } while (0) -#define ao_gpio_set(port, pin, v) stm_gpio_set(port, pin, v) +#define ao_gpio_set(port, bit, pin, v) stm_gpio_set(port, bit, v) -#define ao_enable_output(port,pin,v) do { \ +#define ao_enable_output(port,bit,pin,v) do { \ ao_enable_port(port); \ - ao_gpio_set(port, pin, v); \ - stm_moder_set(port, pin, STM_MODER_OUTPUT); \ + ao_gpio_set(port, bit, pin, v); \ + stm_moder_set(port, bit, STM_MODER_OUTPUT);\ } while (0) #define ao_enable_cs(port,bit) do { \ -- cgit v1.2.3 From 42a51becf4b76f23dbd4f5f80f8879ce696aa543 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Jul 2012 14:36:51 -0700 Subject: altos/avr: Remove debugging printf in avr stdio startup Signed-off-by: Keith Packard --- src/avr/ao_avr_stdio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/avr') diff --git a/src/avr/ao_avr_stdio.c b/src/avr/ao_avr_stdio.c index ba562dbf..2765853a 100644 --- a/src/avr/ao_avr_stdio.c +++ b/src/avr/ao_avr_stdio.c @@ -48,5 +48,4 @@ ao_avr_stdio_init(void) { stdout = &mystdout; stdin = &mystdin; - printf("%d stdios registered\n", ao_num_stdios); } -- cgit v1.2.3 From 81b7b58c9df01847fa47747deeff8c3c91304ad1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Jul 2012 14:37:58 -0700 Subject: altos/avr: Remove debugging command from USB driver Signed-off-by: Keith Packard --- src/avr/ao_usb_avr.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_usb_avr.c b/src/avr/ao_usb_avr.c index 23a27c73..9ba407af 100644 --- a/src/avr/ao_usb_avr.c +++ b/src/avr/ao_usb_avr.c @@ -658,18 +658,6 @@ ao_usb_echo(void) } #endif -static void -ao_usb_irq(void) -{ - printf ("control: %d out: %d in: %d\n", - control_count, out_count, in_count); -} - -__code struct ao_cmds ao_usb_cmds[] = { - { ao_usb_irq, "i\0Show USB interrupt counts" }, - { 0, NULL } -}; - void ao_usb_init(void) { @@ -680,6 +668,5 @@ ao_usb_init(void) #if USB_DEBUG ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo"); #endif - ao_cmd_register(&ao_usb_cmds[0]); ao_add_stdio(ao_usb_pollchar, ao_usb_putchar, ao_usb_flush); } -- cgit v1.2.3 From 84d5e00d417af4924594908d19346bb965089cdd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Jul 2012 14:44:40 -0700 Subject: src: Add driver for AVR internal eeprom. Use for telepyro config. Signed-off-by: Keith Packard --- src/avr/ao_eeprom_avr.c | 133 +++++++++++++++++++++++++++++++++++++++++++++ src/avr/ao_pins.h | 6 ++ src/telepyro-v0.1/Makefile | 16 +++--- 3 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 src/avr/ao_eeprom_avr.c (limited to 'src/avr') diff --git a/src/avr/ao_eeprom_avr.c b/src/avr/ao_eeprom_avr.c new file mode 100644 index 00000000..2451fa8a --- /dev/null +++ b/src/avr/ao_eeprom_avr.c @@ -0,0 +1,133 @@ +/* + * Copyright © 2012 Keith Packard + * Copyright © 2011 Anthony Towns + * + * 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 + +/* Total bytes of available storage */ +__pdata ao_pos_t ao_storage_total = 1024; + +/* Block size - device is erased in these units. */ +__pdata ao_pos_t ao_storage_block = 1024; + +/* Byte offset of config block. Will be ao_storage_block bytes long */ +__pdata ao_pos_t ao_storage_config = 0; + +/* Storage unit size - device reads and writes must be within blocks of this size. */ +__pdata uint16_t ao_storage_unit = 1024; + +/* + * The internal flash chip is arranged in 8 byte sectors; the + * chip cannot erase in units smaller than that. + * + * Writing happens in units of 2 bytes and + * can only change bits from 1 to 0. So, you can rewrite + * the same contents, or append to an existing page easily enough + */ + +/* + * Erase the specified sector + */ +uint8_t +ao_storage_erase(ao_pos_t pos) __reentrant +{ + /* Not necessary */ + return 1; +} + +#define ao_intflash_wait_idle() do { \ + /* Wait for any outstanding writes to complete */ \ + while (EECR & (1 << EEPE)) \ + ; \ + } while (0) \ + +static void +ao_intflash_write(uint16_t pos, uint8_t d) +{ + ao_intflash_wait_idle(); + EEAR = pos; + EEDR = d; + ao_arch_critical( + EECR |= (1 << EEMPE); + EECR |= (1 << EEPE); + ); +} + +static uint8_t +ao_intflash_read(uint16_t pos) +{ + ao_intflash_wait_idle(); + EEAR = pos; + + EECR |= (1 << EERE); + return EEDR; +} +/* + * Write to flash + */ + +uint8_t +ao_storage_device_write(ao_pos_t pos32, __xdata void *v, uint16_t len) __reentrant +{ + uint16_t pos = pos32; + __xdata uint8_t *d = v; + + if (pos >= ao_storage_total || pos + len > ao_storage_total) + return 0; + + while (len--) + ao_intflash_write(pos++, *d++); + + return 1; +} + +/* + * Read from flash + */ +uint8_t +ao_storage_device_read(ao_pos_t pos, __xdata void *v, uint16_t len) __reentrant +{ + uint8_t *d = v; + + if (pos >= ao_storage_total || pos + len > ao_storage_total) + return 0; + while (len--) + *d++ = ao_intflash_read(pos++); + return 1; +} + +void +ao_storage_flush(void) __reentrant +{ +} + +void +ao_storage_setup(void) +{ +} + +void +ao_storage_device_info(void) __reentrant +{ + printf ("Using internal flash\n"); +} + +void +ao_storage_device_init(void) +{ +} diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index 850a08ec..3c9010a8 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -72,6 +72,12 @@ #define HAS_ADC 1 #define PACKET_HAS_SLAVE 0 #define HAS_BEEP 0 + #define HAS_EEPROM 1 + #define USE_INTERNAL_FLASH 1 + #define DISABLE_HELP 1 + #define HAS_STORAGE_DEBUG 0 + #define IS_COMPANION 1 + #define ao_storage_pos_t uint16_t #define AVR_VCC_5V 0 #define AVR_VCC_3V3 1 diff --git a/src/telepyro-v0.1/Makefile b/src/telepyro-v0.1/Makefile index 2ac7e747..bc57b9d7 100644 --- a/src/telepyro-v0.1/Makefile +++ b/src/telepyro-v0.1/Makefile @@ -22,7 +22,8 @@ INC = \ ao.h \ ao_usb.h \ ao_pins.h \ - altitude.h + ao_arch.h \ + ao_arch_funcs.h ALTOS_SRC = \ ao_clock.c \ @@ -39,14 +40,18 @@ ALTOS_SRC = \ ao_usb_avr.c \ ao_adc_avr.c \ ao_pyro_slave.c \ - ao_spi_slave.c + ao_spi_slave.c \ + ao_eeprom_avr.c \ + ao_storage.c \ + ao_config.c \ + ao_pyro.c PRODUCT=TelePyro-v0.1 MCU=atmega32u4 PRODUCT_DEF=-DTELEPYRO IDPRODUCT=0x0011 CFLAGS = $(PRODUCT_DEF) -I. -I../avr -I../core -I.. -CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR +CFLAGS += -mmcu=$(MCU) -Wall -Wstrict-prototypes -O3 -mcall-prologues -DAVR NICKLE=nickle @@ -79,9 +84,6 @@ $(PROG).hex: $(PROG) load: $(PROG).hex $(LOADCMD) $(LOADARG)$(PROG).hex -../altitude.h: make-altitude - nickle $< > $@ - ao_product.h: ao-make-product.5c ../Version $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ @@ -100,4 +102,4 @@ install: uninstall: -$(OBJ): ao.h ao_product.h ao_usb.h +$(OBJ): $(INC) -- cgit v1.2.3 From 184e2ff4790974733df57facdeeb96bfe692ab54 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Jul 2012 15:21:21 -0700 Subject: altos: Remove some debug code from avr ADC driver Signed-off-by: Keith Packard --- src/avr/ao_adc_avr.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_adc_avr.c b/src/avr/ao_adc_avr.c index 928cd3e1..3a262977 100644 --- a/src/avr/ao_adc_avr.c +++ b/src/avr/ao_adc_avr.c @@ -125,42 +125,21 @@ ao_adc_dump(void) __reentrant static __xdata struct ao_data packet; uint8_t i; ao_data_get(&packet); -#ifdef TELEPYRO - printf("ADMUX: %02x\n", ADMUX); - printf("ADCSRA: %02x\n", ADCSRA); - printf("ADCSRB: %02x\n", ADCSRB); - printf("DIDR0: %02x\n", DIDR0); - printf("DIDR2: %02x\n", DIDR2); - printf("PORTF: %02x\n", PORTF); - printf("DDRF: %02x\n", DDRF); - printf("PINF: %02x\n", PINF); -#endif printf("tick: %5u", packet.tick); for (i = 0; i < NUM_ADC; i++) printf (" %2d: %5u", i, packet.adc.adc[i]); printf("\n"); - - -#ifdef TELEPYRO - ADMUX = 0x60; - ADCSRB = 0x00; - ADCSRA = 0xc6; - while (ADCSRA & 0x40) - ; - printf ("ADCL: %02x\n", ADCL); - printf ("ADCH: %02x\n", ADCH); - printf ("\n"); -#endif } __code struct ao_cmds ao_adc_cmds[] = { - { ao_adc_dump, "a\0Display current ADC values" }, + { ao_adc_dump, "a\0ADC" }, { 0, NULL }, }; void ao_adc_init(void) { + PRR0 &= ~(1 << PRADC); DIDR0 = 0xf3; DIDR2 = 0x3f; ADCSRB = ADCSRB_INIT; -- cgit v1.2.3 From 90507d4f7ef77b0870a032b1d9809898c2924721 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Jul 2012 15:24:21 -0700 Subject: altos: Make ao_tick_count visible Necessary to fetch it when interrupts are already disabled as we can't call ao_time then. Signed-off-by: Keith Packard --- src/avr/ao_timer.c | 2 +- src/cc1111/ao_timer.c | 2 +- src/core/ao.h | 2 ++ src/stm/ao_timer.c | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_timer.c b/src/avr/ao_timer.c index eef14345..cd81b163 100644 --- a/src/avr/ao_timer.c +++ b/src/avr/ao_timer.c @@ -17,7 +17,7 @@ #include "ao.h" -static volatile __data uint16_t ao_tick_count; +volatile __data uint16_t ao_tick_count; uint16_t ao_time(void) { diff --git a/src/cc1111/ao_timer.c b/src/cc1111/ao_timer.c index aadee71e..602f98c8 100644 --- a/src/cc1111/ao_timer.c +++ b/src/cc1111/ao_timer.c @@ -17,7 +17,7 @@ #include "ao.h" -static volatile __data uint16_t ao_tick_count; +volatile __data uint16_t ao_tick_count; uint16_t ao_time(void) __critical { diff --git a/src/core/ao.h b/src/core/ao.h index d4be3be4..65b9eb18 100644 --- a/src/core/ao.h +++ b/src/core/ao.h @@ -125,6 +125,8 @@ ao_panic(uint8_t reason); * ao_timer.c */ +extern volatile __data uint16_t ao_tick_count; + /* Our timer runs at 100Hz */ #define AO_HERTZ 100 #define AO_MS_TO_TICKS(ms) ((ms) / (1000 / AO_HERTZ)) diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index 936dc881..ebe75366 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -17,7 +17,7 @@ #include "ao.h" -static volatile __data uint16_t ao_tick_count; +volatile __data uint16_t ao_tick_count; uint16_t ao_time(void) { -- cgit v1.2.3 From 5860f75677ee20fcf35ab89a6b62f3e14a1c32f5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 16 Jul 2012 15:32:26 -0700 Subject: altos: Enable pyro channel control in telepyro This should make the board actually work now. Signed-off-by: Keith Packard --- src/avr/ao_pins.h | 30 ++++++++++++++++++++++++++++++ src/core/ao_pyro.c | 15 ++++++++++++++- src/core/ao_pyro.h | 2 ++ src/drivers/ao_pyro_slave.c | 11 +++++++++++ src/product/ao_telepyro.c | 3 +++ 5 files changed, 60 insertions(+), 1 deletion(-) (limited to 'src/avr') diff --git a/src/avr/ao_pins.h b/src/avr/ao_pins.h index 3c9010a8..bc423ff7 100644 --- a/src/avr/ao_pins.h +++ b/src/avr/ao_pins.h @@ -59,6 +59,8 @@ #define SPI_SLAVE_PIN_0_3 1 #define SPI_SLAVE_PIN_2_5 0 + + #define IS_COMPANION 1 #endif #ifdef TELEPYRO @@ -77,6 +79,7 @@ #define DISABLE_HELP 1 #define HAS_STORAGE_DEBUG 0 #define IS_COMPANION 1 + #define HAS_ORIENT 0 #define ao_storage_pos_t uint16_t #define AVR_VCC_5V 0 @@ -89,6 +92,33 @@ #define SPI_SLAVE_PIN_0_3 1 #define SPI_SLAVE_PIN_2_5 0 + + #define AO_PYRO_NUM 8 + + #define AO_PYRO_PORT_0 B + #define AO_PYRO_PIN_0 5 + + #define AO_PYRO_PORT_1 B + #define AO_PYRO_PIN_1 6 + + #define AO_PYRO_PORT_2 B + #define AO_PYRO_PIN_2 7 + + #define AO_PYRO_PORT_3 C + #define AO_PYRO_PIN_3 6 + + #define AO_PYRO_PORT_4 C + #define AO_PYRO_PIN_4 7 + + #define AO_PYRO_PORT_5 D + #define AO_PYRO_PIN_5 5 + + #define AO_PYRO_PORT_6 D + #define AO_PYRO_PIN_6 3 + + #define AO_PYRO_PORT_7 D + #define AO_PYRO_PIN_7 2 + #endif #define AO_M25_SPI_CS_PORT SPI_CS_PORT diff --git a/src/core/ao_pyro.c b/src/core/ao_pyro.c index a1377d21..4f37e979 100644 --- a/src/core/ao_pyro.c +++ b/src/core/ao_pyro.c @@ -20,6 +20,15 @@ #include #include +#if IS_COMPANION +#include +#define ao_accel ao_companion_command.accel +#define ao_speed ao_companion_command.speed +#define ao_height ao_companion_command.height +#define ao_flight_state ao_companion_command.flight_state +#define ao_motor_number ao_companion_command.motor_number +#endif + #define ao_lowbit(x) ((x) & (-x)) /* @@ -152,6 +161,8 @@ ao_pyro_fire(uint8_t p) ao_delay(AO_MS_TO_TICKS(50)); } +uint8_t ao_pyro_wakeup; + static void ao_pyro(void) { @@ -163,7 +174,9 @@ ao_pyro(void) ao_sleep(&ao_flight_state); for (;;) { - ao_delay(AO_MS_TO_TICKS(100)); + ao_alarm(AO_MS_TO_TICKS(100)); + ao_sleep(&ao_pyro_wakeup); + ao_clear_alarm(); for (p = 0; p < AO_PYRO_NUM; p++) { pyro = &ao_config.pyro[p]; diff --git a/src/core/ao_pyro.h b/src/core/ao_pyro.h index 1989a9e5..5deb69d0 100644 --- a/src/core/ao_pyro.h +++ b/src/core/ao_pyro.h @@ -57,6 +57,8 @@ struct ao_pyro { uint8_t fired; }; +extern uint8_t ao_pyro_wakeup; + void ao_pyro_set(void); diff --git a/src/drivers/ao_pyro_slave.c b/src/drivers/ao_pyro_slave.c index 70206a00..f07c2cba 100644 --- a/src/drivers/ao_pyro_slave.c +++ b/src/drivers/ao_pyro_slave.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include struct ao_companion_command ao_companion_command; @@ -28,6 +30,11 @@ static const struct ao_companion_setup ao_telepyro_setup = { .channels = AO_TELEPYRO_NUM_ADC, }; +struct ao_config ao_config; + +extern volatile __data uint16_t ao_tick_count; +uint16_t ao_boost_tick; + void ao_spi_slave(void) { if (!ao_spi_slave_recv((uint8_t *) &ao_companion_command, @@ -45,6 +52,10 @@ void ao_spi_slave(void) AO_TELEPYRO_NUM_ADC * sizeof (uint16_t)); break; case AO_COMPANION_NOTIFY: + /* Can't use ao_time because we have interrupts suspended */ + if (ao_companion_command.flight_state < ao_flight_boost && ao_companion_command.flight_state >= ao_flight_boost) + ao_boost_tick = ao_tick_count; + ao_wakeup(&ao_pyro_wakeup); break; default: return; diff --git a/src/product/ao_telepyro.c b/src/product/ao_telepyro.c index a2b8f83c..79454fb7 100644 --- a/src/product/ao_telepyro.c +++ b/src/product/ao_telepyro.c @@ -31,6 +31,9 @@ main(void) ao_spi_slave_init(); ao_usb_init(); ao_adc_init(); + ao_storage_init(); + ao_config_init(); + ao_pyro_init(); ao_start_scheduler(); return 0; } -- cgit v1.2.3 From a5d873d47b3b16ca32559b4de668bf07b25eddb0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 17 Jul 2012 01:24:52 -0700 Subject: altos: Place STM config values at fixed addresses for re-use Just like cc1111, stick the serial number and radio calibration values at known fixed addresses so that when re-flashing the board, we can go find the existing values. Signed-off-by: Keith Packard --- ao-tools/ao-load/ao-load.c | 2 +- src/avr/ao_arch.h | 6 +++++- src/avr/ao_romconfig.c | 2 +- src/cc1111/ao_arch.h | 10 ++++++---- src/core/ao_product.c | 2 +- src/drivers/ao_cc1120.c | 2 +- src/drivers/ao_companion.c | 4 +++- src/megametrum-v0.1/Makefile | 2 +- src/megametrum-v0.1/ao_pins.h | 4 ++++ src/stm-bringup/Makefile | 4 ++-- src/stm/altos.ld | 21 +++++++++++---------- src/stm/ao_arch.h | 12 ++++++++++++ src/stm/ao_romconfig.c | 7 ++++++- 13 files changed, 54 insertions(+), 24 deletions(-) (limited to 'src/avr') diff --git a/ao-tools/ao-load/ao-load.c b/ao-tools/ao-load/ao-load.c index 1b729d39..e3cef4a5 100644 --- a/ao-tools/ao-load/ao-load.c +++ b/ao-tools/ao-load/ao-load.c @@ -197,7 +197,7 @@ main (int argc, char **argv) serial = strtoul(serial_string, NULL, 0); if (!serial) -(argv[0]); + usage(argv[0]); serial_int[0] = serial & 0xff; serial_int[1] = (serial >> 8) & 0xff; diff --git a/src/avr/ao_arch.h b/src/avr/ao_arch.h index c775dab6..a14d0ade 100644 --- a/src/avr/ao_arch.h +++ b/src/avr/ao_arch.h @@ -67,7 +67,11 @@ extern void putchar(char c); extern char getchar(void); extern void ao_avr_stdio_init(void); -extern const uint16_t ao_serial_number; +#define AO_ROMCONFIG_VERSION 2 + +#define AO_ROMCONFIG_SYMBOL(a) const + +extern AO_ROMCONFIG_SYMBOL(0) uint16_t ao_serial_number; #define AVR_PUSH8(stack, val) (*((stack)--) = (val)) diff --git a/src/avr/ao_romconfig.c b/src/avr/ao_romconfig.c index bbb677e2..ecc19c76 100644 --- a/src/avr/ao_romconfig.c +++ b/src/avr/ao_romconfig.c @@ -17,4 +17,4 @@ #include "ao.h" -const uint16_t ao_serial_number = 0; +AO_ROMCONFIG_SYMBOL (0) uint16_t ao_serial_number = 0; diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h index 8d9e4952..06b04b93 100644 --- a/src/cc1111/ao_arch.h +++ b/src/cc1111/ao_arch.h @@ -59,10 +59,12 @@ #define AO_ROMCONFIG_VERSION 2 -extern __code __at (0x00a0) uint16_t ao_romconfig_version; -extern __code __at (0x00a2) uint16_t ao_romconfig_check; -extern __code __at (0x00a4) uint16_t ao_serial_number; -extern __code __at (0x00a6) uint32_t ao_radio_cal; +#define AO_ROMCONFIG_SYMBOL(a) __code __at(a) + +extern AO_ROMCONFIG_SYMBOL(0x00a0) uint16_t ao_romconfig_version; +extern AO_ROMCONFIG_SYMBOL(0x00a2) uint16_t ao_romconfig_check; +extern AO_ROMCONFIG_SYMBOL(0x00a4) uint16_t ao_serial_number; +extern AO_ROMCONFIG_SYMBOL(0x00a6) uint32_t ao_radio_cal; #ifndef HAS_USB #error Please define HAS_USB diff --git a/src/core/ao_product.c b/src/core/ao_product.c index 67ec6793..ec91b978 100644 --- a/src/core/ao_product.c +++ b/src/core/ao_product.c @@ -29,7 +29,7 @@ const char ao_product[] = AO_iProduct_STRING; #if HAS_USB #include "ao_usb.h" /* USB descriptors in one giant block of bytes */ -__code __at(0x00aa) uint8_t ao_usb_descriptors [] = +AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] = { /* Device descriptor */ 0x12, diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 569df3b7..97a434d8 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -29,7 +29,7 @@ uint8_t ao_radio_in_recv; #define CC1120_DEBUG AO_FEC_DEBUG #define CC1120_TRACE 0 -const uint32_t ao_radio_cal = 0x6ca333; +extern const uint32_t ao_radio_cal; #define FOSC 32000000 diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c index 6e0bd2ec..c749adea 100644 --- a/src/drivers/ao_companion.c +++ b/src/drivers/ao_companion.c @@ -68,7 +68,7 @@ ao_companion_get_setup(void) ao_spi_recv(&ao_companion_setup, sizeof (ao_companion_setup), AO_COMPANION_SPI_BUS); COMPANION_DESELECT(); return (ao_companion_setup.board_id == - ~ao_companion_setup.board_id_inverse); + (uint16_t) ~ao_companion_setup.board_id_inverse); } static void @@ -116,6 +116,8 @@ ao_companion_status(void) __reentrant { uint8_t i; printf("Companion running: %d\n", ao_companion_running); + if (!ao_companion_running) + return; printf("device: %d\n", ao_companion_setup.board_id); printf("update period: %d\n", ao_companion_setup.update_period); printf("channels: %d\n", ao_companion_setup.channels); diff --git a/src/megametrum-v0.1/Makefile b/src/megametrum-v0.1/Makefile index a519609e..4a4c983a 100644 --- a/src/megametrum-v0.1/Makefile +++ b/src/megametrum-v0.1/Makefile @@ -92,7 +92,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) -$(PROG): Makefile $(OBJ) +$(PROG): Makefile $(OBJ) altos.ld $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc ../altitude.h: make-altitude diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index 2c438f6c..6b0f9832 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -268,6 +268,10 @@ struct ao_adc { * Radio (cc1120) */ +/* gets pretty close to 434.550 */ + +#define AO_RADIO_CAL_DEFAULT 0x6ca333 + #define AO_FEC_DEBUG 0 #define AO_CC1120_SPI_CS_PORT (&stm_gpioc) #define AO_CC1120_SPI_CS_PIN 5 diff --git a/src/stm-bringup/Makefile b/src/stm-bringup/Makefile index 01c80614..d45e836d 100644 --- a/src/stm-bringup/Makefile +++ b/src/stm-bringup/Makefile @@ -16,7 +16,7 @@ DEF_CFLAGS=-g -std=gnu99 -Os -mlittle-endian -mthumb -ffreestanding -nostdlib -I # to run from SRAM LD_FLAGS_RAM=-L../stm -Wl,-Taltos-ram.ld -LD_FLAGS=-L../stm -Wl,-Taltos.ld +LD_FLAGS=-L../stm -Wl,-Tbringup.ld CFLAGS=$(DEF_CFLAGS) -mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY @@ -28,7 +28,7 @@ all: bringup-ram.elf bringup.elf %.bin: %.elf $(OBJCOPY) -O binary $^ $@ -bringup.elf: $(OBJ) $(C_LIB) altos.ld +bringup.elf: $(OBJ) $(C_LIB) bringup.ld $(CC) $(CFLAGS) $(LD_FLAGS) -o $@ $(OBJ) $(C_LIB) -lgcc bringup-ram.elf: $(OBJ) $(C_LIB) altos-ram.ld diff --git a/src/stm/altos.ld b/src/stm/altos.ld index f5a84f4c..f78a45d6 100644 --- a/src/stm/altos.ld +++ b/src/stm/altos.ld @@ -25,18 +25,22 @@ INCLUDE registers.ld EXTERN (stm_interrupt_vector) SECTIONS { - . = ORIGIN(rom); - /* * Rom contents */ - __text_start__ = .; - - .text : { + .text ORIGIN(rom) : { + __text_start__ = .; *(.interrupt) /* Interrupt vectors */ + + . = ORIGIN(rom) + 0x100; + + ao_romconfig.o(.romconfig*) + ao_product.o(.romconfig*) + *(.text*) /* Executable code */ *(.rodata*) /* Constants */ + } > rom .ARM.exidx : { @@ -44,12 +48,10 @@ SECTIONS { __text_end__ = .; } > rom - . = ORIGIN(ram); - __data_start__ = .; - /* Data -- relocated to RAM, but written to ROM */ - .data : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + __data_start__ = .; *(.data) /* initialized data */ __data_end__ = .; __bss_start__ = .; @@ -63,7 +65,6 @@ SECTIONS { PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram)); PROVIDE(end = .); - } ENTRY(start); diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h index d8fa3e89..484ce89e 100644 --- a/src/stm/ao_arch.h +++ b/src/stm/ao_arch.h @@ -59,7 +59,19 @@ extern void putchar(char c); extern char getchar(void); extern void ao_avr_stdio_init(void); + +/* + * ao_romconfig.c + */ + +#define AO_ROMCONFIG_VERSION 2 + +#define AO_ROMCONFIG_SYMBOL(a) __attribute__((section(".romconfig"))) const + +extern const uint16_t ao_romconfig_version; +extern const uint16_t ao_romconfig_check; extern const uint16_t ao_serial_number; +extern const uint32_t ao_radio_cal; #define ARM_PUSH32(stack, val) (*(--(stack)) = (val)) diff --git a/src/stm/ao_romconfig.c b/src/stm/ao_romconfig.c index 84317458..cbb922ec 100644 --- a/src/stm/ao_romconfig.c +++ b/src/stm/ao_romconfig.c @@ -17,4 +17,9 @@ #include "ao.h" -const uint16_t ao_serial_number = 58; +AO_ROMCONFIG_SYMBOL (0) uint16_t ao_romconfig_version = AO_ROMCONFIG_VERSION; +AO_ROMCONFIG_SYMBOL (0) uint16_t ao_romconfig_check = ~AO_ROMCONFIG_VERSION; +AO_ROMCONFIG_SYMBOL (0) uint16_t ao_serial_number = 0; +#ifdef AO_RADIO_CAL_DEFAULT +AO_ROMCONFIG_SYMBOL (0) uint32_t ao_radio_cal = AO_RADIO_CAL_DEFAULT; +#endif -- cgit v1.2.3 From e93c6bcc799d76d4ff425815e2601a25e6796229 Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Tue, 17 Jul 2012 13:23:48 -0600 Subject: first work on PWM input to TeleScience, 'p' command displays timer 1 --- src/avr/ao_pwmin.c | 54 +++++++++++++++++++++++++++++++++++++++++++ src/avr/ao_pwmin.h | 18 +++++++++++++++ src/product/ao_telescience.c | 2 ++ src/telescience-v0.1/Makefile | 1 + 4 files changed, 75 insertions(+) create mode 100644 src/avr/ao_pwmin.c create mode 100644 src/avr/ao_pwmin.h (limited to 'src/avr') diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c new file mode 100644 index 00000000..4d96404d --- /dev/null +++ b/src/avr/ao_pwmin.c @@ -0,0 +1,54 @@ +/* + * Copyright © 2012 Robert D. Garbee + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" +#include "ao_pwmin.h" + +/* + * This code implements a PWM input using ICP3. + * + * The initial use is to measure wind speed in the ULA/Ball summer intern + * project payload developed at Challenger Middle School. + */ + +static void +ao_pwmin_display(void) __reentrant +{ + uint8_t lo = TCNT1L; + uint8_t hi = TCNT1H; + uint16_t value = (hi <<8) | lo; + + /* now display the value we read */ + printf("timer 1: %5u", value); + +} + +__code struct ao_cmds ao_pwmin_cmds[] = { + { ao_pwmin_display, "p\0PWM input" }, + { 0, NULL }, +}; + +void +ao_pwmin_init(void) +{ + /* do hardware setup here */ + /* set the spike filter bit in the TCCR3B register */ + + ao_cmd_register(&ao_pwmin_cmds[0]); +} + + diff --git a/src/avr/ao_pwmin.h b/src/avr/ao_pwmin.h new file mode 100644 index 00000000..bbab4ddc --- /dev/null +++ b/src/avr/ao_pwmin.h @@ -0,0 +1,18 @@ +/* + * Copyright © 2012 Robert D. Garbee + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +void ao_pwmin_init(void); diff --git a/src/product/ao_telescience.c b/src/product/ao_telescience.c index 45b6d40e..2d594d7f 100644 --- a/src/product/ao_telescience.c +++ b/src/product/ao_telescience.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_pwmin.h" int main(void) @@ -34,6 +35,7 @@ main(void) ao_usb_init(); ao_adc_init(); ao_log_single_init(); + ao_pwmin_init(); ao_start_scheduler(); return 0; } diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index d24128ef..5542913d 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -53,6 +53,7 @@ ALTOS_SRC = \ ao_adc_avr.c \ ao_science_slave.c \ ao_spi_slave.c \ + ao_pwmin.c \ $(TELESCIENCE_STORAGE)\ $(TELESCIENCE_LOG) -- cgit v1.2.3 From 49b1ff4c614d24977b33cd17b583acc87acff476 Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Wed, 18 Jul 2012 13:41:27 -0600 Subject: Timer 3 working with slower clock and all 16 bits. --- src/avr/ao_pwmin.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/avr') diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index 4d96404d..edcb1636 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,6 +25,8 @@ * project payload developed at Challenger Middle School. */ +volatile __data uint16_t ao_tick3_count; + static void ao_pwmin_display(void) __reentrant { @@ -32,10 +34,19 @@ ao_pwmin_display(void) __reentrant uint8_t hi = TCNT1H; uint16_t value = (hi <<8) | lo; + uint8_t lo3 = TCNT3L; + uint8_t hi3 = TCNT3H; + uint16_t value3 = (hi3 <<8) | lo3; + /* now display the value we read */ - printf("timer 1: %5u", value); + printf("timer 1: %5u %2x %2x\n", value, hi, lo); + printf("timer 3: %5u %2x %2x\n", value3, hi3, lo3); } +ISR(TIMER3_COMPA_vect) +{ + ++ao_tick3_count; +} __code struct ao_cmds ao_pwmin_cmds[] = { { ao_pwmin_display, "p\0PWM input" }, @@ -46,6 +57,18 @@ void ao_pwmin_init(void) { /* do hardware setup here */ + TCCR3A = ((0 << WGM31) | /* normal mode, OCR3A */ + (0 << WGM30)); /* normal mode, OCR3A */ + TCCR3B = ((0 << ICNC3) | /* no input capture noise canceler */ + (0 << ICES3) | /* input capture on falling edge (don't care) */ + (0 << WGM33) | /* normal mode, OCR3A */ + (0 << WGM32) | /* normal mode, OCR3A */ + (4 << CS30)); /* clk/256 from prescaler */ + + OCR3A = 1250; /* 8MHz clock */ + + TIMSK3 = (1 << OCIE3A); /* Interrupt on compare match */ + /* set the spike filter bit in the TCCR3B register */ ao_cmd_register(&ao_pwmin_cmds[0]); -- cgit v1.2.3 From 75d6aa6f798606f1a6c5a46542065dda81e63b2a Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Wed, 18 Jul 2012 14:24:05 -0600 Subject: ICP3 working --- src/avr/ao_pwmin.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index edcb1636..73a153b2 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,27 +25,20 @@ * project payload developed at Challenger Middle School. */ -volatile __data uint16_t ao_tick3_count; +volatile __data uint16_t ao_icp3_count; static void ao_pwmin_display(void) __reentrant { - uint8_t lo = TCNT1L; - uint8_t hi = TCNT1H; - uint16_t value = (hi <<8) | lo; - - uint8_t lo3 = TCNT3L; - uint8_t hi3 = TCNT3H; - uint16_t value3 = (hi3 <<8) | lo3; - - /* now display the value we read */ - printf("timer 1: %5u %2x %2x\n", value, hi, lo); - printf("timer 3: %5u %2x %2x\n", value3, hi3, lo3); + /* display the most recent value */ + printf("icp 3: %5u\n", ao_icp3_count); } -ISR(TIMER3_COMPA_vect) +ISR(TIMER3_CAPT_vect) { - ++ao_tick3_count; + uint8_t lo = ICR3L; + uint8_t hi = ICR3H; + ao_icp3_count = (hi <<8) | lo; } __code struct ao_cmds ao_pwmin_cmds[] = { @@ -59,15 +52,15 @@ ao_pwmin_init(void) /* do hardware setup here */ TCCR3A = ((0 << WGM31) | /* normal mode, OCR3A */ (0 << WGM30)); /* normal mode, OCR3A */ - TCCR3B = ((0 << ICNC3) | /* no input capture noise canceler */ + TCCR3B = ((1 << ICNC3) | /* input capture noise canceler on */ (0 << ICES3) | /* input capture on falling edge (don't care) */ (0 << WGM33) | /* normal mode, OCR3A */ (0 << WGM32) | /* normal mode, OCR3A */ (4 << CS30)); /* clk/256 from prescaler */ - OCR3A = 1250; /* 8MHz clock */ + - TIMSK3 = (1 << OCIE3A); /* Interrupt on compare match */ + TIMSK3 = (1 << ICIE3); /* Interrupt on input compare */ /* set the spike filter bit in the TCCR3B register */ -- cgit v1.2.3 From ada6f2dfc045e77cb9499f20cdec1b4a54ef0db1 Mon Sep 17 00:00:00 2001 From: Robert Garbee Date: Wed, 18 Jul 2012 18:41:00 -0600 Subject: telescience: correctly calculating rate values with higher resolution --- src/avr/ao_pwmin.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index 73a153b2..84397357 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,20 +25,40 @@ * project payload developed at Challenger Middle School. */ -volatile __data uint16_t ao_icp3_count; +volatile __data uint16_t ao_icp3_count = 0; +volatile __data uint16_t ao_icp3_last = 0; + +uint16_t ao_icp3(void) +{ + uint16_t v; + ao_arch_critical( + v = ao_icp3_count; + ); + return v; +} static void ao_pwmin_display(void) __reentrant { /* display the most recent value */ - printf("icp 3: %5u\n", ao_icp3_count); + printf("icp 3: %5u\n", ao_icp3()); } + + ISR(TIMER3_CAPT_vect) { + uint8_t lo = ICR3L; uint8_t hi = ICR3H; - ao_icp3_count = (hi <<8) | lo; + uint16_t ao_icp3_this = (hi <<8) | lo; + + /* handling counter rollovers */ + if (ao_icp3_this >= ao_icp3_last) + ao_icp3_count = ao_icp3_this - ao_icp3_last; + else + ao_icp3_count = ao_icp3_this + (65536 - ao_icp3_last); + ao_icp3_last = ao_icp3_this; } __code struct ao_cmds ao_pwmin_cmds[] = { @@ -56,7 +76,7 @@ ao_pwmin_init(void) (0 << ICES3) | /* input capture on falling edge (don't care) */ (0 << WGM33) | /* normal mode, OCR3A */ (0 << WGM32) | /* normal mode, OCR3A */ - (4 << CS30)); /* clk/256 from prescaler */ + (3 << CS30)); /* clk/64 from prescaler */ -- cgit v1.2.3 From 31b42b99edbb976534ac432c07e218f13d1f5f9b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Aug 2012 18:03:52 -0700 Subject: altos: Fix ao_delay function and move from per-chip code to ao_task.c ao_delay hasn't been chip-specific for a long time, and it had a bug in not calling ao_clear_alarm. Signed-off-by: Keith Packard --- src/avr/ao_timer.c | 9 --------- src/cc1111/ao_timer.c | 10 ---------- src/core/ao_task.c | 11 +++++++++++ src/stm/ao_timer.c | 9 --------- 4 files changed, 11 insertions(+), 28 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_timer.c b/src/avr/ao_timer.c index cd81b163..d2ea2be7 100644 --- a/src/avr/ao_timer.c +++ b/src/avr/ao_timer.c @@ -28,15 +28,6 @@ uint16_t ao_time(void) return v; } -static __xdata uint8_t ao_forever; - -void -ao_delay(uint16_t ticks) -{ - ao_alarm(ticks); - ao_sleep(&ao_forever); -} - #define T1_CLOCK_DIVISOR 8 /* 24e6/8 = 3e6 */ #define T1_SAMPLE_TIME 30000 /* 3e6/30000 = 100 */ diff --git a/src/cc1111/ao_timer.c b/src/cc1111/ao_timer.c index 602f98c8..a64b5aba 100644 --- a/src/cc1111/ao_timer.c +++ b/src/cc1111/ao_timer.c @@ -24,16 +24,6 @@ uint16_t ao_time(void) __critical return ao_tick_count; } -static __xdata uint8_t ao_forever; - -void -ao_delay(uint16_t ticks) -{ - ao_alarm(ticks); - ao_sleep(&ao_forever); - ao_clear_alarm(); -} - #define T1_CLOCK_DIVISOR 8 /* 24e6/8 = 3e6 */ #define T1_SAMPLE_TIME 30000 /* 3e6/30000 = 100 */ diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 4593bd79..65654731 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -125,6 +125,7 @@ ao_sleep(__xdata void *wchan) ao_yield(); if (ao_cur_task->wchan) { ao_cur_task->wchan = NULL; + ao_cur_task->alarm = 0; return 1; } return 0; @@ -157,6 +158,16 @@ ao_clear_alarm(void) ao_cur_task->alarm = 0; } +static __xdata uint8_t ao_forever; + +void +ao_delay(uint16_t ticks) +{ + ao_alarm(ticks); + ao_sleep(&ao_forever); + ao_clear_alarm(); +} + void ao_exit(void) { diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index 78228e65..f561e6b5 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -28,15 +28,6 @@ uint16_t ao_time(void) return v; } -static __xdata uint8_t ao_forever; - -void -ao_delay(uint16_t ticks) -{ - ao_alarm(ticks); - ao_sleep(&ao_forever); -} - #if AO_DATA_ALL volatile __data uint8_t ao_data_interval = 1; volatile __data uint8_t ao_data_count; -- cgit v1.2.3 From 294b1ec85a37e375a0ac70cbffc6398309d63a7f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 1 Sep 2012 00:14:27 -0500 Subject: Revert "telescience: correctly calculating rate values with higher resolution" PWM bits not suitable for master This reverts commit ada6f2dfc045e77cb9499f20cdec1b4a54ef0db1. --- src/avr/ao_pwmin.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index 84397357..73a153b2 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,40 +25,20 @@ * project payload developed at Challenger Middle School. */ -volatile __data uint16_t ao_icp3_count = 0; -volatile __data uint16_t ao_icp3_last = 0; - -uint16_t ao_icp3(void) -{ - uint16_t v; - ao_arch_critical( - v = ao_icp3_count; - ); - return v; -} +volatile __data uint16_t ao_icp3_count; static void ao_pwmin_display(void) __reentrant { /* display the most recent value */ - printf("icp 3: %5u\n", ao_icp3()); + printf("icp 3: %5u\n", ao_icp3_count); } - - ISR(TIMER3_CAPT_vect) { - uint8_t lo = ICR3L; uint8_t hi = ICR3H; - uint16_t ao_icp3_this = (hi <<8) | lo; - - /* handling counter rollovers */ - if (ao_icp3_this >= ao_icp3_last) - ao_icp3_count = ao_icp3_this - ao_icp3_last; - else - ao_icp3_count = ao_icp3_this + (65536 - ao_icp3_last); - ao_icp3_last = ao_icp3_this; + ao_icp3_count = (hi <<8) | lo; } __code struct ao_cmds ao_pwmin_cmds[] = { @@ -76,7 +56,7 @@ ao_pwmin_init(void) (0 << ICES3) | /* input capture on falling edge (don't care) */ (0 << WGM33) | /* normal mode, OCR3A */ (0 << WGM32) | /* normal mode, OCR3A */ - (3 << CS30)); /* clk/64 from prescaler */ + (4 << CS30)); /* clk/256 from prescaler */ -- cgit v1.2.3 From 8c743857525eff778d067068356dec486b9fefa2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 1 Sep 2012 00:14:49 -0500 Subject: Revert "ICP3 working" PWM bits not suitable for master This reverts commit 75d6aa6f798606f1a6c5a46542065dda81e63b2a. --- src/avr/ao_pwmin.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index 73a153b2..edcb1636 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,20 +25,27 @@ * project payload developed at Challenger Middle School. */ -volatile __data uint16_t ao_icp3_count; +volatile __data uint16_t ao_tick3_count; static void ao_pwmin_display(void) __reentrant { - /* display the most recent value */ - printf("icp 3: %5u\n", ao_icp3_count); + uint8_t lo = TCNT1L; + uint8_t hi = TCNT1H; + uint16_t value = (hi <<8) | lo; + + uint8_t lo3 = TCNT3L; + uint8_t hi3 = TCNT3H; + uint16_t value3 = (hi3 <<8) | lo3; + + /* now display the value we read */ + printf("timer 1: %5u %2x %2x\n", value, hi, lo); + printf("timer 3: %5u %2x %2x\n", value3, hi3, lo3); } -ISR(TIMER3_CAPT_vect) +ISR(TIMER3_COMPA_vect) { - uint8_t lo = ICR3L; - uint8_t hi = ICR3H; - ao_icp3_count = (hi <<8) | lo; + ++ao_tick3_count; } __code struct ao_cmds ao_pwmin_cmds[] = { @@ -52,15 +59,15 @@ ao_pwmin_init(void) /* do hardware setup here */ TCCR3A = ((0 << WGM31) | /* normal mode, OCR3A */ (0 << WGM30)); /* normal mode, OCR3A */ - TCCR3B = ((1 << ICNC3) | /* input capture noise canceler on */ + TCCR3B = ((0 << ICNC3) | /* no input capture noise canceler */ (0 << ICES3) | /* input capture on falling edge (don't care) */ (0 << WGM33) | /* normal mode, OCR3A */ (0 << WGM32) | /* normal mode, OCR3A */ (4 << CS30)); /* clk/256 from prescaler */ - + OCR3A = 1250; /* 8MHz clock */ - TIMSK3 = (1 << ICIE3); /* Interrupt on input compare */ + TIMSK3 = (1 << OCIE3A); /* Interrupt on compare match */ /* set the spike filter bit in the TCCR3B register */ -- cgit v1.2.3 From 3ccc4a13e3f76bec864d61b0cdfd57c76c6baadb Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 1 Sep 2012 00:15:02 -0500 Subject: Revert "Timer 3 working with slower clock and all 16 bits." PWM bits not suitable for master This reverts commit 49b1ff4c614d24977b33cd17b583acc87acff476. --- src/avr/ao_pwmin.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'src/avr') diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c index edcb1636..4d96404d 100644 --- a/src/avr/ao_pwmin.c +++ b/src/avr/ao_pwmin.c @@ -25,8 +25,6 @@ * project payload developed at Challenger Middle School. */ -volatile __data uint16_t ao_tick3_count; - static void ao_pwmin_display(void) __reentrant { @@ -34,19 +32,10 @@ ao_pwmin_display(void) __reentrant uint8_t hi = TCNT1H; uint16_t value = (hi <<8) | lo; - uint8_t lo3 = TCNT3L; - uint8_t hi3 = TCNT3H; - uint16_t value3 = (hi3 <<8) | lo3; - /* now display the value we read */ - printf("timer 1: %5u %2x %2x\n", value, hi, lo); - printf("timer 3: %5u %2x %2x\n", value3, hi3, lo3); + printf("timer 1: %5u", value); } -ISR(TIMER3_COMPA_vect) -{ - ++ao_tick3_count; -} __code struct ao_cmds ao_pwmin_cmds[] = { { ao_pwmin_display, "p\0PWM input" }, @@ -57,18 +46,6 @@ void ao_pwmin_init(void) { /* do hardware setup here */ - TCCR3A = ((0 << WGM31) | /* normal mode, OCR3A */ - (0 << WGM30)); /* normal mode, OCR3A */ - TCCR3B = ((0 << ICNC3) | /* no input capture noise canceler */ - (0 << ICES3) | /* input capture on falling edge (don't care) */ - (0 << WGM33) | /* normal mode, OCR3A */ - (0 << WGM32) | /* normal mode, OCR3A */ - (4 << CS30)); /* clk/256 from prescaler */ - - OCR3A = 1250; /* 8MHz clock */ - - TIMSK3 = (1 << OCIE3A); /* Interrupt on compare match */ - /* set the spike filter bit in the TCCR3B register */ ao_cmd_register(&ao_pwmin_cmds[0]); -- cgit v1.2.3 From 01820c3e95fe85d2bee648d41809f1a753f81020 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 1 Sep 2012 00:15:16 -0500 Subject: Revert "first work on PWM input to TeleScience, 'p' command displays timer 1" PWM bits not suitable for master This reverts commit e93c6bcc799d76d4ff425815e2601a25e6796229. --- src/avr/ao_pwmin.c | 54 ------------------------------------------- src/avr/ao_pwmin.h | 18 --------------- src/product/ao_telescience.c | 2 -- src/telescience-v0.1/Makefile | 1 - 4 files changed, 75 deletions(-) delete mode 100644 src/avr/ao_pwmin.c delete mode 100644 src/avr/ao_pwmin.h (limited to 'src/avr') diff --git a/src/avr/ao_pwmin.c b/src/avr/ao_pwmin.c deleted file mode 100644 index 4d96404d..00000000 --- a/src/avr/ao_pwmin.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright © 2012 Robert D. Garbee - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include "ao.h" -#include "ao_pwmin.h" - -/* - * This code implements a PWM input using ICP3. - * - * The initial use is to measure wind speed in the ULA/Ball summer intern - * project payload developed at Challenger Middle School. - */ - -static void -ao_pwmin_display(void) __reentrant -{ - uint8_t lo = TCNT1L; - uint8_t hi = TCNT1H; - uint16_t value = (hi <<8) | lo; - - /* now display the value we read */ - printf("timer 1: %5u", value); - -} - -__code struct ao_cmds ao_pwmin_cmds[] = { - { ao_pwmin_display, "p\0PWM input" }, - { 0, NULL }, -}; - -void -ao_pwmin_init(void) -{ - /* do hardware setup here */ - /* set the spike filter bit in the TCCR3B register */ - - ao_cmd_register(&ao_pwmin_cmds[0]); -} - - diff --git a/src/avr/ao_pwmin.h b/src/avr/ao_pwmin.h deleted file mode 100644 index bbab4ddc..00000000 --- a/src/avr/ao_pwmin.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright © 2012 Robert D. Garbee - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -void ao_pwmin_init(void); diff --git a/src/product/ao_telescience.c b/src/product/ao_telescience.c index 2d594d7f..45b6d40e 100644 --- a/src/product/ao_telescience.c +++ b/src/product/ao_telescience.c @@ -16,7 +16,6 @@ */ #include "ao.h" -#include "ao_pwmin.h" int main(void) @@ -35,7 +34,6 @@ main(void) ao_usb_init(); ao_adc_init(); ao_log_single_init(); - ao_pwmin_init(); ao_start_scheduler(); return 0; } diff --git a/src/telescience-v0.1/Makefile b/src/telescience-v0.1/Makefile index 5542913d..d24128ef 100644 --- a/src/telescience-v0.1/Makefile +++ b/src/telescience-v0.1/Makefile @@ -53,7 +53,6 @@ ALTOS_SRC = \ ao_adc_avr.c \ ao_science_slave.c \ ao_spi_slave.c \ - ao_pwmin.c \ $(TELESCIENCE_STORAGE)\ $(TELESCIENCE_LOG) -- cgit v1.2.3