summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBdale Garbee <bdale@gag.com>2015-07-16 13:36:59 -0600
committerBdale Garbee <bdale@gag.com>2015-07-16 13:36:59 -0600
commitf4f0f044df1251d64d44bf62d25b488fd04a05c8 (patch)
tree12efee1447a67d8cf37b6f447c011708264b8266 /src
parentb25690062ac04a588ad4d11740597c20e516eb1a (diff)
parent570daace9caf7647a09c53d5c75593cc4c98b93b (diff)
Merge branch 'branch-1.6' into debian
Diffstat (limited to 'src')
-rw-r--r--src/Makefile4
-rw-r--r--src/cc1111/ao_arch.h2
-rw-r--r--src/cc1111/ao_button.c4
-rw-r--r--src/cc1111/ao_radio.c6
-rw-r--r--src/chaoskey-v0.1/.gitignore2
-rw-r--r--src/chaoskey-v0.1/Makefile70
-rw-r--r--src/chaoskey-v0.1/ao_chaoskey.c41
-rw-r--r--src/chaoskey-v0.1/ao_pins.h67
-rw-r--r--src/chaoskey-v0.1/flash-loader/.gitignore2
-rw-r--r--src/chaoskey-v0.1/flash-loader/Makefile8
-rw-r--r--src/chaoskey-v0.1/flash-loader/ao_pins.h36
-rw-r--r--src/drivers/ao_aprs.c104
-rw-r--r--src/drivers/ao_btm.c27
-rw-r--r--src/drivers/ao_cc1120.c16
-rw-r--r--src/drivers/ao_cc1200.c26
-rw-r--r--src/drivers/ao_cc1200.h32
-rw-r--r--src/drivers/ao_cc1200_CC1200.h9
-rw-r--r--src/drivers/ao_companion.c3
-rw-r--r--src/drivers/ao_hmc5883.c4
-rw-r--r--src/drivers/ao_lco.c (renamed from src/telelco-v0.2/ao_lco.c)78
-rw-r--r--src/drivers/ao_lco.h (renamed from src/telelco-v0.2/ao_lco.h)0
-rw-r--r--src/drivers/ao_packet.c4
-rw-r--r--src/drivers/ao_packet_master.c8
-rw-r--r--src/drivers/ao_packet_slave.c2
-rw-r--r--src/drivers/ao_pad.c14
-rw-r--r--src/drivers/ao_pad.h1
-rw-r--r--src/drivers/ao_trng.c79
-rw-r--r--src/drivers/ao_trng.h24
-rw-r--r--src/drivers/ao_trng_send.c65
-rw-r--r--src/drivers/ao_trng_send.h24
-rw-r--r--src/kernel/ao_config.c23
-rw-r--r--src/kernel/ao_config.h9
-rw-r--r--src/kernel/ao_packet.h2
-rw-r--r--src/kernel/ao_product.c8
-rw-r--r--src/kernel/ao_pyro.c4
-rw-r--r--src/kernel/ao_radio_cmac.c6
-rw-r--r--src/kernel/ao_serial.h8
-rw-r--r--src/kernel/ao_task.c48
-rw-r--r--src/kernel/ao_task.h10
-rw-r--r--src/kernel/ao_telemetry.c4
-rw-r--r--src/kernel/ao_telemetry.h7
-rw-r--r--src/micropeak/micropeak-load.tmpl7
-rw-r--r--src/microsplash/.gitignore3
-rw-r--r--src/microsplash/Makefile43
-rw-r--r--src/microsplash/microsplash-load.tmpl21
-rw-r--r--src/product/ao_terraui.c4
-rw-r--r--src/stm/ao_i2c_stm.c18
-rw-r--r--src/stm/ao_serial_stm.c16
-rw-r--r--src/stmf0/ao_adc_fast.c34
-rw-r--r--src/stmf0/ao_adc_fast.h49
-rw-r--r--src/stmf0/ao_crc_stm.c90
-rw-r--r--src/stmf0/ao_exti.h48
-rw-r--r--src/stmf0/ao_usb_stm.c87
-rw-r--r--src/telebt-v3.0/ao_pins.h4
-rw-r--r--src/telelco-v0.1/ao_lco.c6
-rw-r--r--src/telelco-v0.3/.gitignore2
-rw-r--r--src/telelco-v0.3/Makefile108
-rw-r--r--src/telelco-v0.3/ao_pins.h269
-rw-r--r--src/telelco-v0.3/ao_telelco.c70
-rw-r--r--src/telelco-v0.3/flash-loader/Makefile8
-rw-r--r--src/telelco-v0.3/flash-loader/ao_pins.h34
-rw-r--r--src/test/ao_flight_test.c5
-rw-r--r--src/usbtrng-v2.0/Makefile2
-rw-r--r--src/usbtrng-v2.0/ao_pins.h4
-rw-r--r--src/usbtrng-v2.0/ao_usbtrng.c56
-rw-r--r--src/util/ao-make-product.5c49
66 files changed, 1602 insertions, 326 deletions
diff --git a/src/Makefile b/src/Makefile
index 05e99c7f..dc74bf8c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -34,13 +34,15 @@ ARMM3DIRS=\
telegps-v0.3 telegps-v0.3/flash-loader \
telegps-v1.0 telegps-v1.0/flash-loader \
telelco-v0.2 telelco-v0.2/flash-loader \
+ telelco-v0.3 telelco-v0.3/flash-loader \
telescience-v0.2 telescience-v0.2/flash-loader \
teledongle-v3.0 teledongle-v3.0/flash-loader \
teleballoon-v2.0 \
telebt-v3.0 telebt-v3.0/flash-loader
ARMM0DIRS=\
- easymini-v1.0 easymini-v1.0/flash-loader
+ easymini-v1.0 easymini-v1.0/flash-loader \
+ chaoskey-v0.1 chaoskey-v0.1/flash-loader
AVRDIRS=\
telescience-v0.1 telescience-pwm micropeak nanopeak-v0.1 microkite
diff --git a/src/cc1111/ao_arch.h b/src/cc1111/ao_arch.h
index b3c6b5dc..6eb1a111 100644
--- a/src/cc1111/ao_arch.h
+++ b/src/cc1111/ao_arch.h
@@ -228,7 +228,7 @@ void
ao_button_init(void);
char
-ao_button_get(void) __critical;
+ao_button_get(uint16_t timeout) __critical;
void
ao_button_clear(void) __critical;
diff --git a/src/cc1111/ao_button.c b/src/cc1111/ao_button.c
index 69f3475f..a0f221c2 100644
--- a/src/cc1111/ao_button.c
+++ b/src/cc1111/ao_button.c
@@ -72,12 +72,12 @@ ao_button_mask(uint8_t reg)
}
char
-ao_button_get(void) __critical
+ao_button_get(uint16_t timeout) __critical
{
char b;
while (ao_fifo_empty(ao_button_fifo))
- if (ao_sleep(&ao_button_fifo))
+ if (ao_sleep_for(&ao_button_fifo, timeout))
return 0;
ao_fifo_remove(ao_button_fifo, b);
return b;
diff --git a/src/cc1111/ao_radio.c b/src/cc1111/ao_radio.c
index b9821a42..cead0364 100644
--- a/src/cc1111/ao_radio.c
+++ b/src/cc1111/ao_radio.c
@@ -451,13 +451,9 @@ ao_radio_recv(__xdata void *packet, uint8_t size, uint8_t timeout) __reentrant
/* Wait for DMA to be done, for the radio receive process to
* get aborted or for a receive timeout to fire
*/
- if (timeout)
- ao_alarm(timeout);
__critical while (!ao_radio_dma_done && !ao_radio_abort)
- if (ao_sleep(&ao_radio_dma_done))
+ if (ao_sleep_for(&ao_radio_dma_done, timeout))
break;
- if (timeout)
- ao_clear_alarm();
/* If recv was aborted, clean up by stopping the DMA engine
* and idling the radio
diff --git a/src/chaoskey-v0.1/.gitignore b/src/chaoskey-v0.1/.gitignore
new file mode 100644
index 00000000..b0adba26
--- /dev/null
+++ b/src/chaoskey-v0.1/.gitignore
@@ -0,0 +1,2 @@
+ao_product.h
+chaoskey-*
diff --git a/src/chaoskey-v0.1/Makefile b/src/chaoskey-v0.1/Makefile
new file mode 100644
index 00000000..ac4a6788
--- /dev/null
+++ b/src/chaoskey-v0.1/Makefile
@@ -0,0 +1,70 @@
+#
+# AltOS build
+#
+#
+
+include ../stmf0/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_pins.h \
+ ao_product.h \
+ ao_task.h \
+ ao_adc_fast.h \
+ stm32f0.h
+
+#
+# Common AltOS sources
+#
+ALTOS_SRC = \
+ ao_interrupt.c \
+ ao_timer.c \
+ ao_panic.c \
+ ao_mutex.c \
+ ao_dma_stm.c \
+ ao_adc_fast.c \
+ ao_crc_stm.c \
+ ao_stdio.c \
+ ao_led.c \
+ ao_romconfig.c \
+ ao_boot_chain.c \
+ ao_usb_stm.c \
+ ao_trng_send.c \
+ ao_task.c \
+ ao_product.c
+
+PRODUCT=ChaosKey-v0.1
+PRODUCT_DEF=-DCHAOSKEY_V_0_1
+IDVENDOR=0x1d50
+IDPRODUCT=0x60c6
+
+CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS) -g -Os
+
+PROGNAME=chaoskey-v0.1
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_chaoskey.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -V $(IDVENDOR) -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) -o $@
+
+$(OBJ): $(INC)
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/chaoskey-v0.1/ao_chaoskey.c b/src/chaoskey-v0.1/ao_chaoskey.c
new file mode 100644
index 00000000..48c8bf04
--- /dev/null
+++ b/src/chaoskey-v0.1/ao_chaoskey.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2014 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_adc_fast.h>
+#include <ao_crc.h>
+#include <ao_trng_send.h>
+
+void main(void)
+{
+ ao_led_init(LEDS_AVAILABLE);
+ ao_led_on(AO_LED_RED);
+ ao_clock_init();
+ ao_task_init();
+ ao_timer_init();
+ ao_dma_init();
+ ao_adc_init();
+ ao_crc_init();
+
+ ao_usb_init();
+
+ ao_trng_send_init();
+
+ ao_led_off(AO_LED_RED);
+
+ ao_start_scheduler();
+}
diff --git a/src/chaoskey-v0.1/ao_pins.h b/src/chaoskey-v0.1/ao_pins.h
new file mode 100644
index 00000000..72963dba
--- /dev/null
+++ b/src/chaoskey-v0.1/ao_pins.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2015 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+#define LED_PORT_ENABLE STM_RCC_AHBENR_IOPAEN
+#define LED_PORT (&stm_gpioa)
+#define LED_PIN_RED 2
+#define LED_PIN_GREEN 3
+#define AO_LED_RED (1 << LED_PIN_RED)
+#define AO_LED_GREEN (1 << LED_PIN_GREEN)
+
+#define LEDS_AVAILABLE (AO_LED_RED | AO_LED_GREEN)
+
+#define HAS_BEEP 0
+
+/* 48MHz clock based on USB */
+#define AO_HSI48 1
+
+/* HCLK = 48MHz */
+#define AO_AHB_PRESCALER 1
+#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1
+
+/* APB = 48MHz */
+#define AO_APB_PRESCALER 1
+#define AO_RCC_CFGR_PPRE_DIV STM_RCC_CFGR_PPRE_DIV_1
+
+#define HAS_USB 1
+#define AO_USB_DIRECTIO 1
+#define AO_PA11_PA12_RMP 0
+#define AO_USB_INTERFACE_CLASS 0xff
+
+#define IS_FLASH_LOADER 0
+
+/* ADC */
+
+#define AO_ADC_PIN0_PORT (&stm_gpioa)
+#define AO_ADC_PIN0_PIN 6
+#define AO_ADC_PIN0_CH 6
+
+#define AO_ADC_RCC_AHBENR ((1 << STM_RCC_AHBENR_IOPAEN))
+
+#define AO_NUM_ADC 1
+
+/* CRC */
+#define AO_CRC_WIDTH 32
+#define AO_CRC_INIT 0xffffffff
+
+/* TRNG */
+#define AO_LED_TRNG_ACTIVE AO_LED_GREEN
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/chaoskey-v0.1/flash-loader/.gitignore b/src/chaoskey-v0.1/flash-loader/.gitignore
new file mode 100644
index 00000000..a60a4945
--- /dev/null
+++ b/src/chaoskey-v0.1/flash-loader/.gitignore
@@ -0,0 +1,2 @@
+ao_product.h
+chaoskey*
diff --git a/src/chaoskey-v0.1/flash-loader/Makefile b/src/chaoskey-v0.1/flash-loader/Makefile
new file mode 100644
index 00000000..4f61a240
--- /dev/null
+++ b/src/chaoskey-v0.1/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=chaoskey-v0.1
+include $(TOPDIR)/stmf0/Makefile-flash.defs
diff --git a/src/chaoskey-v0.1/flash-loader/ao_pins.h b/src/chaoskey-v0.1/flash-loader/ao_pins.h
new file mode 100644
index 00000000..295e0258
--- /dev/null
+++ b/src/chaoskey-v0.1/flash-loader/ao_pins.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+#include <ao_flash_stm_pins.h>
+
+/* Pin 5 on debug connector */
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO stm_gpioa
+#define AO_BOOT_APPLICATION_PIN 15
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
+
+/* USB */
+#define HAS_USB 1
+#define AO_USB_DIRECTIO 0
+#define AO_PA11_PA12_RMP 0
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/drivers/ao_aprs.c b/src/drivers/ao_aprs.c
index 19beb78f..a8016673 100644
--- a/src/drivers/ao_aprs.c
+++ b/src/drivers/ao_aprs.c
@@ -707,8 +707,7 @@ static int tncPositionPacket(void)
static int32_t latitude;
static int32_t longitude;
static int32_t altitude;
- int32_t lat, lon, alt;
- uint8_t *buf;
+ uint8_t *buf;
if (ao_gps_data.flags & AO_GPS_VALID) {
latitude = ao_gps_data.latitude;
@@ -719,28 +718,99 @@ static int tncPositionPacket(void)
}
buf = tncBuffer;
- *buf++ = '!';
- /* Symbol table ID */
- *buf++ = '/';
+#ifdef AO_APRS_TEST
+#define AO_APRS_FORMAT_COMPRESSED 0
+#define AO_APRS_FORMAT_UNCOMPRESSED 1
+ switch (AO_APRS_FORMAT_COMPRESSED) {
+#else
+ switch (ao_config.aprs_format) {
+#endif
+ case AO_APRS_FORMAT_COMPRESSED:
+ default:
+ {
+ int32_t lat, lon, alt;
+
+ *buf++ = '!';
+
+ /* Symbol table ID */
+ *buf++ = '/';
+
+ lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000;
+ lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000;
+
+ alt = ao_aprs_encode_altitude(altitude);
- lat = ((uint64_t) 380926 * (900000000 - latitude)) / 10000000;
- lon = ((uint64_t) 190463 * (1800000000 + longitude)) / 10000000;
+ tncCompressInt(buf, lat, 4);
+ buf += 4;
+ tncCompressInt(buf, lon, 4);
+ buf += 4;
- alt = ao_aprs_encode_altitude(altitude);
+ /* Symbol code */
+ *buf++ = '\'';
- tncCompressInt(buf, lat, 4);
- buf += 4;
- tncCompressInt(buf, lon, 4);
- buf += 4;
+ tncCompressInt(buf, alt, 2);
+ buf += 2;
- /* Symbol code */
- *buf++ = '\'';
+ *buf++ = 33 + ((1 << 5) | (2 << 3));
- tncCompressInt(buf, alt, 2);
- buf += 2;
+ break;
+ }
+ case AO_APRS_FORMAT_UNCOMPRESSED:
+ {
+ char lat_sign = 'N', lon_sign = 'E';
+ int32_t lat = latitude;
+ int32_t lon = longitude;
+ int32_t alt = altitude;
+ uint16_t lat_deg;
+ uint16_t lon_deg;
+ uint16_t lat_min;
+ uint16_t lat_frac;
+ uint16_t lon_min;
+ uint16_t lon_frac;
+
+ if (lat < 0) {
+ lat_sign = 'S';
+ lat = -lat;
+ }
- *buf++ = 33 + ((1 << 5) | (2 << 3));
+ if (lon < 0) {
+ lon_sign = 'W';
+ lon = -lon;
+ }
+
+ /* Round latitude and longitude by 0.005 minutes */
+ lat = lat + 833;
+ if (lat > 900000000)
+ lat = 900000000;
+ lon = lon + 833;
+ if (lon > 1800000000)
+ lon = 1800000000;
+
+ lat_deg = lat / 10000000;
+ lat -= lat_deg * 10000000;
+ lat *= 60;
+ lat_min = lat / 10000000;
+ lat -= lat_min * 10000000;
+ lat_frac = lat / 100000;
+
+ lon_deg = lon / 10000000;
+ lon -= lon_deg * 10000000;
+ lon *= 60;
+ lon_min = lon / 10000000;
+ lon -= lon_min * 10000000;
+ lon_frac = lon / 100000;
+
+ /* Convert from meters to feet */
+ alt = (alt * 328 + 50) / 100;
+
+ buf += sprintf((char *) tncBuffer, "!%02u%02u.%02u%c/%03u%02u.%02u%c'/A=%06u ",
+ lat_deg, lat_min, lat_frac, lat_sign,
+ lon_deg, lon_min, lon_frac, lon_sign,
+ alt);
+ break;
+ }
+ }
buf += tncComment(buf);
diff --git a/src/drivers/ao_btm.c b/src/drivers/ao_btm.c
index e6b28688..8e7052cb 100644
--- a/src/drivers/ao_btm.c
+++ b/src/drivers/ao_btm.c
@@ -23,7 +23,7 @@
#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_sleep() ao_sleep((void *) &ao_serial1_rx_fifo)
+#define _ao_serial_btm_sleep_for(timeout) ao_sleep_for((void *) &ao_serial1_rx_fifo, timeout)
#define ao_serial_btm_set_speed ao_serial1_set_speed
#define ao_serial_btm_drain ao_serial1_drain
#endif
@@ -111,7 +111,7 @@ ao_btm_do_echo(void)
while (ao_btm_enable) {
ao_arch_block_interrupts();
while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN && ao_btm_enable)
- _ao_serial_btm_sleep();
+ _ao_serial_btm_sleep_for(0);
ao_arch_release_interrupts();
if (c != AO_READ_AGAIN) {
putchar(c);
@@ -166,9 +166,7 @@ ao_btm_getchar(void)
ao_arch_block_interrupts();
while ((c = _ao_serial_btm_pollchar()) == AO_READ_AGAIN) {
- ao_alarm(AO_MS_TO_TICKS(10));
- c = _ao_serial_btm_sleep();
- ao_clear_alarm();
+ c = _ao_serial_btm_sleep_for(AO_MS_TO_TICKS(10));
if (c) {
c = AO_READ_AGAIN;
break;
@@ -265,6 +263,15 @@ uint8_t
ao_btm_cmd(__code char *cmd)
{
ao_btm_drain();
+
+#ifdef AO_BTM_INT_PORT
+ /* Trust that AltosDroid will eventually disconnect and let us
+ * get things set up. The BTM module doesn't appear to listen
+ * for +++, so we have no way to force a disconnect.
+ */
+ while (ao_btm_connected)
+ ao_sleep(&ao_btm_connected);
+#endif
ao_btm_string(cmd);
return ao_btm_wait_reply();
}
@@ -352,6 +359,10 @@ __xdata struct ao_task ao_btm_task;
void
ao_btm(void)
{
+#ifdef AO_BTM_INT_PORT
+ ao_exti_enable(AO_BTM_INT_PORT, AO_BTM_INT_PIN);
+#endif
+
/*
* Wait for the bluetooth device to boot
*/
@@ -382,6 +393,8 @@ ao_btm(void)
/* Turn off status reporting */
ao_btm_cmd("ATQ1\r");
+ ao_btm_drain();
+
ao_btm_stdio = ao_add_stdio(_ao_serial_btm_pollchar,
ao_serial_btm_putchar,
NULL);
@@ -390,10 +403,6 @@ ao_btm(void)
/* Check current pin state */
ao_btm_check_link();
-#ifdef AO_BTM_INT_PORT
- ao_exti_enable(AO_BTM_INT_PORT, AO_BTM_INT_PIN);
-#endif
-
for (;;) {
while (!ao_btm_connected)
ao_sleep(&ao_btm_connected);
diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c
index 90d6cc75..5b814667 100644
--- a/src/drivers/ao_cc1120.c
+++ b/src/drivers/ao_cc1120.c
@@ -837,15 +837,11 @@ ao_radio_test_cmd(void)
static void
ao_radio_wait_isr(uint16_t timeout)
{
- if (timeout)
- ao_alarm(timeout);
ao_arch_block_interrupts();
while (!ao_radio_wake && !ao_radio_mcu_wake && !ao_radio_abort)
- if (ao_sleep(&ao_radio_wake))
+ if (ao_sleep_for(&ao_radio_wake, timeout))
ao_radio_abort = 1;
ao_arch_release_interrupts();
- if (timeout)
- ao_clear_alarm();
if (ao_radio_mcu_wake)
ao_radio_check_marc_status();
}
@@ -1060,19 +1056,17 @@ ao_radio_rx_isr(void)
static uint16_t
ao_radio_rx_wait(void)
{
- ao_alarm(AO_MS_TO_TICKS(100));
ao_arch_block_interrupts();
rx_waiting = 1;
while (rx_data_cur - rx_data_consumed < AO_FEC_DECODE_BLOCK &&
!ao_radio_abort &&
!ao_radio_mcu_wake)
{
- if (ao_sleep(&ao_radio_wake))
+ if (ao_sleep_for(&ao_radio_wake, AO_MS_TO_TICKS(100)))
ao_radio_abort = 1;
}
rx_waiting = 0;
ao_arch_release_interrupts();
- ao_clear_alarm();
if (ao_radio_abort || ao_radio_mcu_wake)
return 0;
rx_data_consumed += AO_FEC_DECODE_BLOCK;
@@ -1133,19 +1127,15 @@ ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout)
ao_radio_strobe(CC1120_SRX);
- if (timeout)
- ao_alarm(timeout);
ao_arch_block_interrupts();
while (rx_starting && !ao_radio_abort) {
- if (ao_sleep(&ao_radio_wake))
+ if (ao_sleep_for(&ao_radio_wake, timeout))
ao_radio_abort = 1;
}
uint8_t rx_task_id_save = rx_task_id;
rx_task_id = 0;
rx_starting = 0;
ao_arch_release_interrupts();
- if (timeout)
- ao_clear_alarm();
if (ao_radio_abort) {
if (rx_task_id_save == 0)
diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c
index 8546900e..6547be39 100644
--- a/src/drivers/ao_cc1200.c
+++ b/src/drivers/ao_cc1200.c
@@ -41,7 +41,11 @@ int8_t ao_radio_rssi; /* Last received RSSI value */
extern const uint32_t ao_radio_cal;
+#ifdef AO_CC1200_FOSC
+#define FOSC AO_CC1200_FOSC
+#else
#define FOSC 40000000
+#endif
#define ao_radio_select() ao_spi_get_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS,AO_SPI_SPEED_FAST)
#define ao_radio_deselect() ao_spi_put_mask(AO_CC1200_SPI_CS_PORT,(1 << AO_CC1200_SPI_CS_PIN),AO_CC1200_SPI_BUS)
@@ -301,20 +305,28 @@ ao_radio_idle(void)
* CHANBW = 5.0 (round to 9.5)
*/
+#if FOSC == 40000000
#define PACKET_SYMBOL_RATE_M 1013008
-
#define PACKET_SYMBOL_RATE_E_384 8
+#define PACKET_SYMBOL_RATE_E_96 6
+#define PACKET_SYMBOL_RATE_E_24 4
+#endif
+
+#if FOSC == 32000000
+#define PACKET_SYMBOL_RATE_M 239914
+#define PACKET_SYMBOL_RATE_E_384 9
+#define PACKET_SYMBOL_RATE_E_96 7
+#define PACKET_SYMBOL_RATE_E_24 5
+#endif
/* 200 / 2 = 100 */
#define PACKET_CHAN_BW_384 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_12 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
(16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
-#define PACKET_SYMBOL_RATE_E_96 6
/* 200 / 10 = 20 */
#define PACKET_CHAN_BW_96 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
(16 << CC1200_CHAN_BW_BB_CIC_DECFACT))
-#define PACKET_SYMBOL_RATE_E_24 4
/* 200 / 25 = 8 */
#define PACKET_CHAN_BW_24 ((CC1200_CHAN_BW_ADC_CIC_DECFACT_48 << CC1200_CHAN_BW_ADC_CIC_DECFACT) | \
(44 << CC1200_CHAN_BW_BB_CIC_DECFACT))
@@ -715,17 +727,11 @@ ao_radio_show_state(char *where)
static void
ao_radio_wait_isr(uint16_t timeout)
{
- if (timeout)
- ao_alarm(timeout);
-
ao_arch_block_interrupts();
while (!ao_radio_wake && !ao_radio_abort)
- if (ao_sleep(&ao_radio_wake))
+ if (ao_sleep_for(&ao_radio_wake, timeout))
ao_radio_abort = 1;
ao_arch_release_interrupts();
-
- if (timeout)
- ao_clear_alarm();
}
static void
diff --git a/src/drivers/ao_cc1200.h b/src/drivers/ao_cc1200.h
index b04775fd..b2b63cde 100644
--- a/src/drivers/ao_cc1200.h
+++ b/src/drivers/ao_cc1200.h
@@ -438,6 +438,38 @@
#define CC1200_IF_MIX_CFG (CC1200_EXTENDED_BIT | 0x00)
#define CC1200_FREQOFF_CFG (CC1200_EXTENDED_BIT | 0x01)
#define CC1200_TOC_CFG (CC1200_EXTENDED_BIT | 0x02)
+
+#define CC1200_TOC_CFG_TOC_LIMIT 6
+#define CC1200_TOC_CFG_TOC_LIMIT_0_2 0
+#define CC1200_TOC_CFG_TOC_LIMIT_2 1
+#define CC1200_TOC_CFG_TOC_LIMIT_12 3
+
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN 3
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_8 0
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_16 1
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_32 2
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_64 3
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_128 4
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_256 5
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_8_16 0
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_6_16 1
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_2_16 2
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_1_16 3
+#define CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_1_16_SYNC 4
+
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN 0
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_8 0
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_16 1
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_32 2
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_64 3
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_128 4
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_256 5
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_FREEZE 0
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_6_32 1
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_2_32 2
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_1_32 3
+#define CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_1_32_SYNC 4
+
#define CC1200_MARC_SPARE (CC1200_EXTENDED_BIT | 0x03)
#define CC1200_ECG_CFG (CC1200_EXTENDED_BIT | 0x04)
#define CC1200_MDMCFG2 (CC1200_EXTENDED_BIT | 0x05)
diff --git a/src/drivers/ao_cc1200_CC1200.h b/src/drivers/ao_cc1200_CC1200.h
index 35673123..f0214c2a 100644
--- a/src/drivers/ao_cc1200_CC1200.h
+++ b/src/drivers/ao_cc1200_CC1200.h
@@ -101,6 +101,15 @@
(CC1200_MDMCFG2_SYMBOL_MAP_CFG_MODE_0 << CC1200_MDMCFG2_SYMBOL_MAP_CFG) |
(CC1200_MDMCFG2_UPSAMPLER_P_8 << CC1200_MDMCFG2_UPSAMPLER_P) |
(0 << CC1200_MDMCFG2_CFM_DATA_EN)),
+ CC1200_MDMCFG0, /* General Modem Parameter Configuration Reg. 0 */
+ ((0 << CC1200_MDMCFG0_TRANSPARENT_MODE_EN) |
+ (0 << CC1200_MDMCFG0_TRANSPARENT_INTFACT) |
+ (0 << CC1200_MDMCFG0_DATA_FILTER_EN) |
+ (1 << CC1200_MDMCFG0_VITERBI_EN)),
+ CC1200_TOC_CFG, /* Timing Offset Correction Configuration */
+ ((CC1200_TOC_CFG_TOC_LIMIT_2 << CC1200_TOC_CFG_TOC_LIMIT) |
+ (CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN_6_16 << CC1200_TOC_CFG_TOC_PRE_SYNC_BLOCKLEN)|
+ (CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN_2_32 << CC1200_TOC_CFG_TOC_POST_SYNC_BLOCKLEN)),
CC1200_FREQ2, 0x6c, /* Frequency Configuration [23:16] */
CC1200_FREQ1, 0xa3, /* Frequency Configuration [15:8] */
CC1200_FREQ0, 0x33, /* Frequency Configuration [7:0] */
diff --git a/src/drivers/ao_companion.c b/src/drivers/ao_companion.c
index 570b9e40..7e02939b 100644
--- a/src/drivers/ao_companion.c
+++ b/src/drivers/ao_companion.c
@@ -102,8 +102,7 @@ ao_companion(void)
break;
}
while (ao_companion_running) {
- ao_alarm(ao_companion_setup.update_period);
- if (ao_sleep(DATA_TO_XDATA(&ao_flight_state)))
+ if (ao_sleep_for(DATA_TO_XDATA(&ao_flight_state), ao_companion_setup.update_period))
ao_companion_get_data();
else
ao_companion_notify();
diff --git a/src/drivers/ao_hmc5883.c b/src/drivers/ao_hmc5883.c
index 2d217bcf..f761671a 100644
--- a/src/drivers/ao_hmc5883.c
+++ b/src/drivers/ao_hmc5883.c
@@ -75,13 +75,11 @@ ao_hmc5883_sample(struct ao_hmc5883_sample *sample)
ao_exti_enable(AO_HMC5883_INT_PORT, AO_HMC5883_INT_PIN);
ao_hmc5883_reg_write(HMC5883_MODE, HMC5883_MODE_SINGLE);
- ao_alarm(AO_MS_TO_TICKS(10));
ao_arch_block_interrupts();
while (!ao_hmc5883_done)
- if (ao_sleep(&ao_hmc5883_done))
+ if (ao_sleep_for(&ao_hmc5883_done, AO_MS_TO_TICKS(10)))
++ao_hmc5883_missed_irq;
ao_arch_release_interrupts();
- ao_clear_alarm();
ao_hmc5883_read(HMC5883_X_MSB, (uint8_t *) sample, sizeof (struct ao_hmc5883_sample));
#if __BYTE_ORDER == __LITTLE_ENDIAN
diff --git a/src/telelco-v0.2/ao_lco.c b/src/drivers/ao_lco.c
index 4b5f7a9b..b8698a80 100644
--- a/src/telelco-v0.2/ao_lco.c
+++ b/src/drivers/ao_lco.c
@@ -50,7 +50,7 @@ static struct ao_pad_query ao_pad_query;
static void
ao_lco_set_pad(uint8_t pad)
{
- ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad + 1);
+ ao_seven_segment_set(AO_LCO_PAD_DIGIT, pad);
}
static void
@@ -60,6 +60,30 @@ ao_lco_set_box(uint8_t box)
ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, box / 10);
}
+static void
+ao_lco_set_voltage(uint16_t decivolts)
+{
+ uint8_t tens, ones, tenths;
+
+ tenths = decivolts % 10;
+ ones = (decivolts / 10) % 10;
+ tens = (decivolts / 100) % 10;
+ ao_seven_segment_set(AO_LCO_PAD_DIGIT, tenths);
+ ao_seven_segment_set(AO_LCO_BOX_DIGIT_1, ones | 0x10);
+ ao_seven_segment_set(AO_LCO_BOX_DIGIT_10, tens);
+}
+
+static void
+ao_lco_set_display(void)
+{
+ if (ao_lco_pad == 0) {
+ ao_lco_set_voltage(ao_pad_query.battery);
+ } else {
+ ao_lco_set_pad(ao_lco_pad);
+ ao_lco_set_box(ao_lco_box);
+ }
+}
+
#define MASK_SIZE(n) (((n) + 7) >> 3)
#define MASK_ID(n) ((n) >> 3)
#define MASK_SHIFT(n) ((n) & 7)
@@ -79,9 +103,12 @@ ao_lco_pad_present(uint8_t pad)
{
if (!ao_lco_got_channels || !ao_pad_query.channels)
return pad == 0;
- if (pad >= AO_PAD_MAX_CHANNELS)
+ /* voltage measurement is always valid */
+ if (pad == 0)
+ return 1;
+ if (pad > AO_PAD_MAX_CHANNELS)
return 0;
- return (ao_pad_query.channels >> pad) & 1;
+ return (ao_pad_query.channels >> (pad - 1)) & 1;
}
static uint8_t
@@ -89,7 +116,7 @@ ao_lco_pad_first(void)
{
uint8_t pad;
- for (pad = 0; pad < AO_PAD_MAX_CHANNELS; pad++)
+ for (pad = 1; pad <= AO_PAD_MAX_CHANNELS; pad++)
if (ao_lco_pad_present(pad))
return pad;
return 0;
@@ -117,14 +144,14 @@ ao_lco_input(void)
new_pad += dir;
if (new_pad > AO_PAD_MAX_CHANNELS)
new_pad = 0;
- else if (new_pad < 0)
- new_pad = AO_PAD_MAX_CHANNELS - 1;
+ if (new_pad < 0)
+ new_pad = AO_PAD_MAX_CHANNELS;
if (new_pad == ao_lco_pad)
break;
} while (!ao_lco_pad_present(new_pad));
if (new_pad != ao_lco_pad) {
ao_lco_pad = new_pad;
- ao_lco_set_pad(ao_lco_pad);
+ ao_lco_set_display();
}
}
break;
@@ -143,8 +170,9 @@ ao_lco_input(void)
} while (!ao_lco_box_present(new_box));
if (ao_lco_box != new_box) {
ao_lco_box = new_box;
+ ao_lco_pad = 1;
ao_lco_got_channels = 0;
- ao_lco_set_box(ao_lco_box);
+ ao_lco_set_display();
}
}
break;
@@ -209,9 +237,12 @@ ao_lco_update(void)
ao_lco_got_channels = 1;
ao_lco_valid = 1;
if (!c) {
- ao_lco_pad = ao_lco_pad_first();
- ao_lco_set_pad(ao_lco_pad);
+ if (ao_lco_pad != 0)
+ ao_lco_pad = ao_lco_pad_first();
+ ao_lco_set_display();
}
+ if (ao_lco_pad == 0)
+ ao_lco_set_display();
} else
ao_lco_valid = 0;
@@ -223,6 +254,7 @@ ao_lco_update(void)
query.igniter_status[2],
query.igniter_status[3]);
#endif
+ PRINTD("ao_lco_update valid %d\n", ao_lco_valid);
ao_wakeup(&ao_pad_query);
}
@@ -253,8 +285,10 @@ ao_lco_search(void)
int8_t r;
int8_t try;
uint8_t box;
+ uint8_t boxes = 0;
ao_lco_box_reset_present();
+ ao_lco_set_pad(0);
for (box = 0; box < AO_PAD_MAX_BOXES; box++) {
if ((box % 10) == 0)
ao_lco_set_box(box);
@@ -263,7 +297,9 @@ ao_lco_search(void)
r = ao_lco_query(box, &ao_pad_query, &tick_offset);
PRINTD("box %d result %d\n", box, r);
if (r == AO_RADIO_CMAC_OK) {
+ ++boxes;
ao_lco_box_set_present(box);
+ ao_lco_set_pad(boxes % 10);
ao_delay(AO_MS_TO_TICKS(30));
break;
}
@@ -275,9 +311,8 @@ ao_lco_search(void)
ao_lco_min_box = ao_lco_max_box = ao_lco_box = 0;
ao_lco_valid = 0;
ao_lco_got_channels = 0;
- ao_lco_pad = 0;
- ao_lco_set_pad(ao_lco_pad);
- ao_lco_set_box(ao_lco_box);
+ ao_lco_pad = 1;
+ ao_lco_set_display();
}
static void
@@ -287,12 +322,12 @@ ao_lco_igniter_status(void)
for (;;) {
ao_sleep(&ao_pad_query);
+ PRINTD("RSSI %d VALID %d\n", ao_radio_cmac_rssi, ao_lco_valid);
if (!ao_lco_valid) {
ao_led_on(AO_LED_RED);
ao_led_off(AO_LED_GREEN|AO_LED_AMBER);
continue;
}
- PRINTD("RSSI %d\n", ao_radio_cmac_rssi);
if (ao_radio_cmac_rssi < -90) {
ao_led_on(AO_LED_AMBER);
ao_led_off(AO_LED_RED|AO_LED_GREEN);
@@ -353,15 +388,18 @@ ao_lco_monitor(void)
ao_lco_box, ao_lco_pad, ao_lco_valid);
if (!ao_lco_valid)
ao_lco_update();
- if (ao_lco_valid)
- ao_lco_ignite(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset);
+ if (ao_lco_valid && ao_lco_pad)
+ ao_lco_ignite(ao_lco_box, 1 << (ao_lco_pad - 1), ao_lco_tick_offset);
} else if (ao_lco_armed) {
PRINTD("Arming box %d pad %d\n",
ao_lco_box, ao_lco_pad);
if (!ao_lco_valid)
ao_lco_update();
- ao_lco_arm(ao_lco_box, 1 << ao_lco_pad, ao_lco_tick_offset);
- ao_lco_update();
+ if (ao_lco_pad) {
+ ao_lco_arm(ao_lco_box, 1 << (ao_lco_pad - 1), ao_lco_tick_offset);
+ ao_delay(AO_MS_TO_TICKS(30));
+ ao_lco_update();
+ }
} else {
ao_lco_update();
}
@@ -369,9 +407,7 @@ ao_lco_monitor(void)
delay = AO_MS_TO_TICKS(100);
else
delay = AO_SEC_TO_TICKS(1);
- ao_alarm(delay);
- ao_sleep(&ao_lco_armed);
- ao_clear_alarm();
+ ao_sleep_for(&ao_lco_armed, delay);
}
}
diff --git a/src/telelco-v0.2/ao_lco.h b/src/drivers/ao_lco.h
index 253f9702..253f9702 100644
--- a/src/telelco-v0.2/ao_lco.h
+++ b/src/drivers/ao_lco.h
diff --git a/src/drivers/ao_packet.c b/src/drivers/ao_packet.c
index 8cdf85a9..18330ead 100644
--- a/src/drivers/ao_packet.c
+++ b/src/drivers/ao_packet.c
@@ -54,14 +54,14 @@ ao_packet_send(void)
}
uint8_t
-ao_packet_recv(void)
+ao_packet_recv(uint16_t timeout)
{
uint8_t dma_done;
#ifdef AO_LED_GREEN
ao_led_on(AO_LED_GREEN);
#endif
- dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv), 0);
+ dma_done = ao_radio_recv(&ao_rx_packet, sizeof (struct ao_packet_recv), timeout);
#ifdef AO_LED_GREEN
ao_led_off(AO_LED_GREEN);
#endif
diff --git a/src/drivers/ao_packet_master.c b/src/drivers/ao_packet_master.c
index 42a4f5bf..5e440db0 100644
--- a/src/drivers/ao_packet_master.c
+++ b/src/drivers/ao_packet_master.c
@@ -97,9 +97,7 @@ ao_packet_master(void)
if (ao_tx_packet.len)
ao_packet_master_busy();
ao_packet_master_check_busy();
- ao_alarm(AO_PACKET_MASTER_RECV_DELAY);
- r = ao_packet_recv();
- ao_clear_alarm();
+ r = ao_packet_recv(AO_PACKET_MASTER_RECV_DELAY);
if (r) {
/* if we can transmit data, do so */
if (ao_packet_tx_used && ao_tx_packet.len == 0)
@@ -107,9 +105,7 @@ ao_packet_master(void)
if (ao_rx_packet.packet.len)
ao_packet_master_busy();
ao_packet_master_sleeping = 1;
- ao_alarm(ao_packet_master_delay);
- ao_sleep(&ao_packet_master_sleeping);
- ao_clear_alarm();
+ ao_sleep_for(&ao_packet_master_sleeping, ao_packet_master_delay);
ao_packet_master_sleeping = 0;
}
}
diff --git a/src/drivers/ao_packet_slave.c b/src/drivers/ao_packet_slave.c
index e75df0d6..0872682f 100644
--- a/src/drivers/ao_packet_slave.c
+++ b/src/drivers/ao_packet_slave.c
@@ -24,7 +24,7 @@ ao_packet_slave(void)
ao_tx_packet.len = AO_PACKET_SYN;
ao_packet_restart = 1;
while (ao_packet_enable) {
- if (ao_packet_recv()) {
+ if (ao_packet_recv(0)) {
ao_xmemcpy(&ao_tx_packet.callsign, &ao_rx_packet.packet.callsign, AO_MAX_CALLSIGN);
#if HAS_FLIGHT
ao_flight_force_idle = TRUE;
diff --git a/src/drivers/ao_pad.c b/src/drivers/ao_pad.c
index dc2c83fe..ffe46c68 100644
--- a/src/drivers/ao_pad.c
+++ b/src/drivers/ao_pad.c
@@ -29,6 +29,10 @@ static __pdata uint8_t ao_pad_box;
static __xdata uint8_t ao_pad_disabled;
static __pdata uint16_t ao_pad_packet_time;
+#ifndef AO_PAD_RSSI_MINIMUM
+#define AO_PAD_RSSI_MINIMUM -90
+#endif
+
#define DEBUG 1
#if DEBUG
@@ -36,8 +40,8 @@ static __pdata uint8_t ao_pad_debug;
#define PRINTD(...) (ao_pad_debug ? (printf(__VA_ARGS__), 0) : 0)
#define FLUSHD() (ao_pad_debug ? (flush(), 0) : 0)
#else
-#define PRINTD(...)
-#define FLUSHD()
+#define PRINTD(...)
+#define FLUSHD()
#endif
static void
@@ -123,6 +127,8 @@ ao_pad_monitor(void)
#define VOLTS_TO_PYRO(x) ((int16_t) ((x) * 27.0 / 127.0 / 3.3 * 32767.0))
+ /* convert ADC value to voltage in tenths, then add .2 for the diode drop */
+ query.battery = (packet->adc.batt + 96) / 192 + 2;
cur = 0;
if (pyro > VOLTS_TO_PYRO(10)) {
query.arm_status = AO_PAD_ARM_STATUS_ARMED;
@@ -138,7 +144,7 @@ ao_pad_monitor(void)
}
if ((ao_time() - ao_pad_packet_time) > AO_SEC_TO_TICKS(2))
cur |= AO_LED_RED;
- else if (ao_radio_cmac_rssi < -90)
+ else if (ao_radio_cmac_rssi < AO_PAD_RSSI_MINIMUM)
cur |= AO_LED_AMBER;
else
cur |= AO_LED_GREEN;
@@ -255,7 +261,7 @@ ao_pad(void)
if (ret != AO_RADIO_CMAC_OK)
continue;
ao_pad_packet_time = ao_time();
-
+
ao_pad_box = ao_pad_read_box();
PRINTD ("tick %d box %d (me %d) cmd %d channels %02x\n",
diff --git a/src/drivers/ao_pad.h b/src/drivers/ao_pad.h
index 23062899..d77d105a 100644
--- a/src/drivers/ao_pad.h
+++ b/src/drivers/ao_pad.h
@@ -39,6 +39,7 @@ struct ao_pad_query {
uint8_t channels; /* which chanels are present */
uint8_t armed; /* which channels are armed */
uint8_t arm_status; /* status of arming switch */
+ uint8_t battery; /* battery voltage in decivolts */
uint8_t igniter_status[AO_PAD_MAX_CHANNELS]; /* status for each igniter */
};
diff --git a/src/drivers/ao_trng.c b/src/drivers/ao_trng.c
new file mode 100644
index 00000000..e69cd30b
--- /dev/null
+++ b/src/drivers/ao_trng.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2015 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_adc_fast.h>
+#include <ao_crc.h>
+#include <ao_trng.h>
+
+static void
+ao_trng_fetch(void)
+{
+ static uint16_t *buffer[2];
+ uint32_t kbytes = 1;
+ uint32_t count;
+ int usb_buf_id;
+ uint16_t i;
+ uint16_t *buf;
+ uint16_t t;
+ uint32_t *rnd = (uint32_t *) ao_adc_ring;
+
+ if (!buffer[0]) {
+ buffer[0] = ao_usb_alloc();
+ buffer[1] = ao_usb_alloc();
+ if (!buffer[0])
+ return;
+ }
+
+ ao_cmd_decimal();
+ if (ao_cmd_status == ao_cmd_success)
+ kbytes = ao_cmd_lex_u32;
+ else
+ ao_cmd_status = ao_cmd_success;
+ usb_buf_id = 0;
+ count = kbytes * (1024/AO_USB_IN_SIZE);
+
+ ao_crc_reset();
+
+ ao_led_on(AO_LED_TRNG_READ);
+ while (count--) {
+ t = ao_adc_get(AO_USB_IN_SIZE) >> 1; /* one 16-bit value per output byte */
+ buf = buffer[usb_buf_id];
+ for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) {
+ *buf++ = ao_crc_in_32_out_16(rnd[t]);
+ t = (t + 1) & ((AO_ADC_RING_SIZE>>1) - 1);
+ }
+ ao_adc_ack(AO_USB_IN_SIZE);
+ ao_led_toggle(AO_LED_TRNG_READ|AO_LED_TRNG_WRITE);
+ ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE);
+ ao_led_toggle(AO_LED_TRNG_READ|AO_LED_TRNG_WRITE);
+ usb_buf_id = 1-usb_buf_id;
+ }
+ ao_led_off(AO_LED_TRNG_READ|AO_LED_TRNG_WRITE);
+ flush();
+}
+
+static const struct ao_cmds ao_trng_cmds[] = {
+ { ao_trng_fetch, "f <kbytes>\0Fetch a block of numbers" },
+ { 0, NULL },
+};
+
+void
+ao_trng_init(void)
+{
+ ao_cmd_register(ao_trng_cmds);
+}
diff --git a/src/drivers/ao_trng.h b/src/drivers/ao_trng.h
new file mode 100644
index 00000000..78577428
--- /dev/null
+++ b/src/drivers/ao_trng.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2015 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_TRNG_H_
+#define _AO_TRNG_H_
+
+void
+ao_trng_init(void);
+
+#endif /* _AO_TRNG_H_ */
diff --git a/src/drivers/ao_trng_send.c b/src/drivers/ao_trng_send.c
new file mode 100644
index 00000000..bac6035c
--- /dev/null
+++ b/src/drivers/ao_trng_send.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2015 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_adc_fast.h>
+#include <ao_crc.h>
+#include <ao_trng_send.h>
+
+static void
+ao_trng_send(void)
+{
+ static uint16_t *buffer[2];
+ int usb_buf_id;
+ uint16_t i;
+ uint16_t *buf;
+ uint16_t t;
+ uint32_t *rnd = (uint32_t *) ao_adc_ring;
+
+ if (!buffer[0]) {
+ buffer[0] = ao_usb_alloc();
+ buffer[1] = ao_usb_alloc();
+ if (!buffer[0])
+ return;
+ }
+
+ usb_buf_id = 0;
+
+ ao_crc_reset();
+
+ for (;;) {
+ ao_led_on(AO_LED_TRNG_ACTIVE);
+ t = ao_adc_get(AO_USB_IN_SIZE) >> 1; /* one 16-bit value per output byte */
+ buf = buffer[usb_buf_id];
+ for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) {
+ *buf++ = ao_crc_in_32_out_16(rnd[t]);
+ t = (t + 1) & ((AO_ADC_RING_SIZE>>1) - 1);
+ }
+ ao_adc_ack(AO_USB_IN_SIZE);
+ ao_led_off(AO_LED_TRNG_ACTIVE);
+ ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE);
+ usb_buf_id = 1-usb_buf_id;
+ }
+}
+
+static struct ao_task ao_trng_send_task;
+
+void
+ao_trng_send_init(void)
+{
+ ao_add_task(&ao_trng_send_task, ao_trng_send, "trng_send");
+}
diff --git a/src/drivers/ao_trng_send.h b/src/drivers/ao_trng_send.h
new file mode 100644
index 00000000..83312d59
--- /dev/null
+++ b/src/drivers/ao_trng_send.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2015 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_TRNG_SEND_H_
+#define _AO_TRNG_SEND_H_
+
+void
+ao_trng_send_init(void);
+
+#endif /* _AO_TRNG_SEND_H_ */
diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c
index 8dab7c42..b0d3e541 100644
--- a/src/kernel/ao_config.c
+++ b/src/kernel/ao_config.c
@@ -220,6 +220,10 @@ _ao_config_get(void)
if (minor < 21)
ao_config.send_frequency = 434550;
#endif
+#if HAS_APRS
+ if (minor < 22)
+ ao_config.aprs_format = AO_CONFIG_DEFAULT_APRS_FORMAT;
+#endif
ao_config.minor = AO_CONFIG_MINOR;
ao_config_dirty = 1;
}
@@ -876,6 +880,23 @@ ao_config_aprs_ssid_set(void)
ao_config.aprs_ssid = ao_cmd_lex_i;
_ao_config_edit_finish();
}
+
+void
+ao_config_aprs_format_set(void)
+{
+ ao_cmd_decimal();
+ if (ao_cmd_status != ao_cmd_success)
+ return;
+ _ao_config_edit_start();
+ ao_config.aprs_format = ao_cmd_lex_i != 0;
+ _ao_config_edit_finish();
+}
+
+void
+ao_config_aprs_format_show(void)
+{
+ printf ("APRS format: %d\n", ao_config.aprs_format);
+}
#endif /* HAS_APRS */
struct ao_config_var {
@@ -969,6 +990,8 @@ __code struct ao_config_var ao_config_vars[] = {
#if HAS_APRS
{ "S <ssid>\0Set APRS SSID (0-15)",
ao_config_aprs_ssid_set, ao_config_aprs_ssid_show },
+ { "C <0 compressed, 1 uncompressed>\0APRS format",
+ ao_config_aprs_format_set, ao_config_aprs_format_show },
#endif
{ "s\0Show",
ao_config_show, 0 },
diff --git a/src/kernel/ao_config.h b/src/kernel/ao_config.h
index 164584a5..cfe8555c 100644
--- a/src/kernel/ao_config.h
+++ b/src/kernel/ao_config.h
@@ -57,7 +57,7 @@
#endif
#define AO_CONFIG_MAJOR 1
-#define AO_CONFIG_MINOR 21
+#define AO_CONFIG_MINOR 22
#define AO_AES_LEN 16
@@ -115,8 +115,15 @@ struct ao_config {
#if HAS_RADIO_FORWARD
uint32_t send_frequency; /* minor version 21 */
#endif
+#if HAS_APRS
+ uint8_t aprs_format; /* minor version 22 */
+#endif
};
+#define AO_APRS_FORMAT_COMPRESSED 0
+#define AO_APRS_FORMAT_UNCOMPRESSED 1
+#define AO_CONFIG_DEFAULT_APRS_FORMAT AO_APRS_FORMAT_COMPRESSED
+
#if HAS_RADIO_FORWARD
extern __xdata uint32_t ao_send_radio_setting;
#endif
diff --git a/src/kernel/ao_packet.h b/src/kernel/ao_packet.h
index b8426cf9..136609c3 100644
--- a/src/kernel/ao_packet.h
+++ b/src/kernel/ao_packet.h
@@ -54,7 +54,7 @@ void
ao_packet_send(void);
uint8_t
-ao_packet_recv(void);
+ao_packet_recv(uint16_t timeout);
void
ao_packet_flush(void);
diff --git a/src/kernel/ao_product.c b/src/kernel/ao_product.c
index b9327bac..c711a4d2 100644
--- a/src/kernel/ao_product.c
+++ b/src/kernel/ao_product.c
@@ -33,6 +33,10 @@ const char ao_product[] = AO_iProduct_STRING;
#define AO_USB_MAX_POWER 100
#endif
+#ifndef AO_USB_INTERFACE_CLASS
+#define AO_USB_INTERFACE_CLASS 0x02
+#endif
+
#include "ao_usb.h"
/* USB descriptors in one giant block of bytes */
AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =
@@ -45,7 +49,7 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
AO_USB_CONTROL_SIZE, /* bMaxPacketSize */
- LE_WORD(0xFFFE), /* idVendor */
+ LE_WORD(AO_idVendor_NUMBER), /* idVendor */
LE_WORD(AO_idProduct_NUMBER), /* idProduct */
LE_WORD(0x0100), /* bcdDevice */
0x01, /* iManufacturer */
@@ -69,7 +73,7 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndPoints */
- 0x02, /* bInterfaceClass */
+ AO_USB_INTERFACE_CLASS, /* bInterfaceClass */
0x02, /* bInterfaceSubClass */
0x01, /* bInterfaceProtocol, linux requires value of 1 for the cdc_acm module */
0x00, /* iInterface */
diff --git a/src/kernel/ao_pyro.c b/src/kernel/ao_pyro.c
index 3044d565..43e73de4 100644
--- a/src/kernel/ao_pyro.c
+++ b/src/kernel/ao_pyro.c
@@ -375,9 +375,7 @@ ao_pyro(void)
ao_sleep(&ao_flight_state);
for (;;) {
- ao_alarm(AO_MS_TO_TICKS(100));
- ao_sleep(&ao_pyro_wakeup);
- ao_clear_alarm();
+ ao_sleep_for(&ao_pyro_wakeup, AO_MS_TO_TICKS(100));
if (ao_flight_state >= ao_flight_landed)
break;
any_waiting = ao_pyro_check();
diff --git a/src/kernel/ao_radio_cmac.c b/src/kernel/ao_radio_cmac.c
index bff848f6..b6835346 100644
--- a/src/kernel/ao_radio_cmac.c
+++ b/src/kernel/ao_radio_cmac.c
@@ -91,7 +91,6 @@ radio_cmac_recv(uint8_t len, uint16_t timeout) __reentrant
return AO_RADIO_CMAC_TIMEOUT;
}
- ao_radio_cmac_rssi = ao_radio_rssi;
if (!(cmac_data[len + AO_CMAC_KEY_LEN +1] & AO_RADIO_STATUS_CRC_OK))
return AO_RADIO_CMAC_CRC_ERROR;
@@ -114,13 +113,15 @@ radio_cmac_recv(uint8_t len, uint16_t timeout) __reentrant
/* Check the packet signature against the signature provided
* over the link
*/
-
+
if (memcmp(&cmac_data[len],
&cmac_data[len + AO_CMAC_KEY_LEN + 2],
AO_CMAC_KEY_LEN) != 0) {
return AO_RADIO_CMAC_MAC_ERROR;
}
+ ao_radio_cmac_rssi = ao_radio_rssi;
+
return AO_RADIO_CMAC_OK;
}
@@ -161,4 +162,3 @@ ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentr
ao_mutex_put(&ao_radio_cmac_mutex);
return i;
}
-
diff --git a/src/kernel/ao_serial.h b/src/kernel/ao_serial.h
index dbc9f8e4..e21643ac 100644
--- a/src/kernel/ao_serial.h
+++ b/src/kernel/ao_serial.h
@@ -35,7 +35,7 @@ int
_ao_serial0_pollchar(void);
uint8_t
-_ao_serial0_sleep(void);
+_ao_serial0_sleep_for(uint16_t timeout);
void
ao_serial0_putchar(char c);
@@ -58,7 +58,7 @@ int
_ao_serial1_pollchar(void);
uint8_t
-_ao_serial1_sleep(void);
+_ao_serial1_sleep_for(uint16_t timeout);
void
ao_serial1_putchar(char c);
@@ -81,7 +81,7 @@ int
_ao_serial2_pollchar(void);
uint8_t
-_ao_serial2_sleep(void);
+_ao_serial2_sleep_for(uint16_t timeout);
void
ao_serial2_putchar(char c);
@@ -104,7 +104,7 @@ int
_ao_serial3_pollchar(void);
uint8_t
-_ao_serial3_sleep(void);
+_ao_serial3_sleep_for(uint16_t timeout);
void
ao_serial3_putchar(char c);
diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c
index bafb4943..55e423bb 100644
--- a/src/kernel/ao_task.c
+++ b/src/kernel/ao_task.c
@@ -450,37 +450,39 @@ ao_wakeup(__xdata void *wchan) __reentrant
ao_check_stack();
}
-void
-ao_alarm(uint16_t delay)
+uint8_t
+ao_sleep_for(__xdata void *wchan, uint16_t timeout)
{
+ uint8_t ret;
+ if (timeout) {
#if HAS_TASK_QUEUE
- uint32_t flags;
- /* Make sure we sleep *at least* delay ticks, which means adding
- * one to account for the fact that we may be close to the next tick
- */
- flags = ao_arch_irqsave();
+ uint32_t flags;
+ /* Make sure we sleep *at least* delay ticks, which means adding
+ * one to account for the fact that we may be close to the next tick
+ */
+ flags = ao_arch_irqsave();
#endif
- if (!(ao_cur_task->alarm = ao_time() + delay + 1))
- ao_cur_task->alarm = 1;
+ if (!(ao_cur_task->alarm = ao_time() + timeout + 1))
+ ao_cur_task->alarm = 1;
#if HAS_TASK_QUEUE
- ao_task_to_alarm_queue(ao_cur_task);
- ao_arch_irqrestore(flags);
+ ao_task_to_alarm_queue(ao_cur_task);
+ ao_arch_irqrestore(flags);
#endif
-}
-
-void
-ao_clear_alarm(void)
-{
+ }
+ ret = ao_sleep(wchan);
+ if (timeout) {
#if HAS_TASK_QUEUE
- uint32_t flags;
+ uint32_t flags;
- flags = ao_arch_irqsave();
+ flags = ao_arch_irqsave();
#endif
- ao_cur_task->alarm = 0;
+ ao_cur_task->alarm = 0;
#if HAS_TASK_QUEUE
- ao_task_from_alarm_queue(ao_cur_task);
- ao_arch_irqrestore(flags);
+ ao_task_from_alarm_queue(ao_cur_task);
+ ao_arch_irqrestore(flags);
#endif
+ }
+ return ret;
}
static __xdata uint8_t ao_forever;
@@ -488,9 +490,7 @@ static __xdata uint8_t ao_forever;
void
ao_delay(uint16_t ticks)
{
- ao_alarm(ticks);
- ao_sleep(&ao_forever);
- ao_clear_alarm();
+ ao_sleep_for(&ao_forever, ticks);
}
void
diff --git a/src/kernel/ao_task.h b/src/kernel/ao_task.h
index 9c56b480..c6bec0e3 100644
--- a/src/kernel/ao_task.h
+++ b/src/kernel/ao_task.h
@@ -68,10 +68,19 @@ extern __data uint8_t ao_task_minimize_latency; /* Reduce IRQ latency */
uint8_t
ao_sleep(__xdata void *wchan);
+/* Suspend the current task until wchan is awoken or the timeout
+ * expires. returns:
+ * 0 on normal wake
+ * 1 on alarm
+ */
+uint8_t
+ao_sleep_for(__xdata void *wchan, uint16_t timeout);
+
/* Wake all tasks sleeping on wchan */
void
ao_wakeup(__xdata void *wchan) __reentrant;
+#if 0
/* set an alarm to go off in 'delay' ticks */
void
ao_alarm(uint16_t delay);
@@ -79,6 +88,7 @@ ao_alarm(uint16_t delay);
/* Clear any pending alarm */
void
ao_clear_alarm(void);
+#endif
/* Yield the processor to another task */
void
diff --git a/src/kernel/ao_telemetry.c b/src/kernel/ao_telemetry.c
index e2197f7a..854ac898 100644
--- a/src/kernel/ao_telemetry.c
+++ b/src/kernel/ao_telemetry.c
@@ -486,9 +486,7 @@ ao_telemetry(void)
#endif /* HAS_APRS */
delay = time - ao_time();
if (delay > 0) {
- ao_alarm(delay);
- ao_sleep(&telemetry);
- ao_clear_alarm();
+ ao_sleep_for(&telemetry, delay);
}
}
}
diff --git a/src/kernel/ao_telemetry.h b/src/kernel/ao_telemetry.h
index 711e0d36..672d2317 100644
--- a/src/kernel/ao_telemetry.h
+++ b/src/kernel/ao_telemetry.h
@@ -258,13 +258,14 @@ struct ao_telemetry_metrum_data {
uint16_t serial; /* 0 */
uint16_t tick; /* 2 */
uint8_t type; /* 4 */
+ uint8_t pad5[3]; /* 5 */
- int32_t ground_pres; /* 8 average pres on pad */
+ int32_t ground_pres; /* 8 average pres on pad */
int16_t ground_accel; /* 12 average accel on pad */
int16_t accel_plus_g; /* 14 accel calibration at +1g */
int16_t accel_minus_g; /* 16 accel calibration at -1g */
- uint8_t pad[14]; /* 18 */
+ uint8_t pad18[14]; /* 18 */
/* 32 */
};
@@ -332,6 +333,8 @@ union ao_telemetry_all {
struct ao_telemetry_baro baro;
};
+typedef char ao_check_telemetry_size[sizeof(union ao_telemetry_all) == 32 ? 1 : -1];
+
struct ao_telemetry_all_recv {
union ao_telemetry_all telemetry;
int8_t rssi;
diff --git a/src/micropeak/micropeak-load.tmpl b/src/micropeak/micropeak-load.tmpl
index 08236a15..c061559d 100644
--- a/src/micropeak/micropeak-load.tmpl
+++ b/src/micropeak/micropeak-load.tmpl
@@ -8,13 +8,14 @@ LOADSLOW="%LOADSLOW%"
LOADFAST=""
case "$1" in
-fast)
- LOADSPEED="$LOADFAST"
+slow)
+ LOADSPEED="$LOADSLOW"
;;
*)
- LOADSPEED="$LOADSLOW"
+ LOADSPEED="$LOADFAST"
;;
esac
echo ${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX}
${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX}
+/usr/games/xcowsay --cow-size=large --at=1000,500 "${HEX} finished"
diff --git a/src/microsplash/.gitignore b/src/microsplash/.gitignore
index 5f6fe3b2..c2062c34 100644
--- a/src/microsplash/.gitignore
+++ b/src/microsplash/.gitignore
@@ -1,2 +1,3 @@
ao_product.h
-microsplash-*
+microsplash-v*
+microsplash-load
diff --git a/src/microsplash/Makefile b/src/microsplash/Makefile
index 10cb825b..9bb636f1 100644
--- a/src/microsplash/Makefile
+++ b/src/microsplash/Makefile
@@ -8,8 +8,15 @@ vpath make-altitude-pa ../util
include ../avr/Makefile.defs
+PROGNAME=microsplash-v1.0
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SCRIPT=microsplash-load
+
PUBLISH_DIR=$(HOME)/altusmetrumllc/Binaries
-PUBLISH_FILE=$(PUBLISH_DIR)/$(PROG)-$(VERSION).hex
+PUBLISH_HEX=$(PUBLISH_DIR)/$(HEX)
+PUBLISH_SCRIPT=$(PUBLISH_DIR)/$(SCRIPT)
MCU=attiny85
DUDECPUTYPE=t85
@@ -48,15 +55,13 @@ INC=\
altitude-pa.h
IDPRODUCT=0
-PRODUCT=MicroSplash-v0.1
+PRODUCT=MicroSplash-v1.0
PRODUCT_DEF=-DMICROPEAK
CFLAGS = $(PRODUCT_DEF) -I. -I../attiny -I../kernel -I.. -I../drivers -I../product
CFLAGS += -g -mmcu=$(MCU) -Wall -Wstrict-prototypes -O2 -mcall-prologues -DATTINY
NICKLE=nickle
-PROG=microsplash-v1.0
-
SRC=$(ALTOS_SRC)
OBJ=$(SRC:.c=.o)
@@ -68,7 +73,7 @@ endif
# Otherwise, print the full command line.
quiet ?= $($1)
-all: $(PROG) $(PROG).hex
+all: $(PROG) $(HEX) $(SCRIPT)
CHECK=sh ../util/check-avr-mem
@@ -76,16 +81,16 @@ $(PROG): Makefile $(OBJ)
$(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ)
$(call quiet,CHECK) $(PROG) || ($(RM) -f $(PROG); exit 1)
-$(PROG).hex: $(PROG)
+$(HEX): $(PROG)
avr-size $(PROG)
$(OBJCOPY) -R .eeprom -O ihex $(PROG) $@
-load: $(PROG).hex
- $(LOADCMD) $(LOADARG)$(PROG).hex
+load: $(HEX)
+ $(LOADCMD) $(LOADARG)$(HEX)
-load-slow: $(PROG).hex
- $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PROG).hex
+load-slow: $(HEX)
+ $(LOADCMD) $(LOADSLOW) $(LOADARG)$(HEX)
ao_product.h: ao-make-product.5c ../Version
$(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
@@ -98,22 +103,30 @@ ao_product.o: ao_product.c ao_product.h
distclean: clean
clean:
- rm -f *.o $(PROG) $(PROG).hex
+ rm -f *.o $(PROG) $(HEX) $(SCRIPT)
rm -f ao_product.h
+publish: $(PUBLISH_HEX) $(PUBLISH_SCRIPT)
-publish: $(PROG).hex
- cp -a $(PROG).hex $(PUBLISH_FILE)
+$(PUBLISH_HEX): $(HEX)
+ cp -a $(HEX) $@
+
+$(PUBLISH_SCRIPT): $(SCRIPT)
+ cp -a $(SCRIPT) $@
load-product:
- $(LOADCMD) $(LOADARG)$(PUBLISH_FILE)
+ ./$(SCRIPT) fast
load-product-slow:
- $(LOADCMD) $(LOADSLOW) $(LOADARG)$(PUBLISH_FILE)
+ ./$(SCRIPT) slow
../altitude-pa.h: make-altitude-pa
nickle $< > $@
+$(SCRIPT): $(SCRIPT).tmpl Makefile ../Version
+ sed -e 's/%HEX%/$(HEX)/' -e 's/%LOADCMD%/$(LOADCMD)/' -e 's/%LOADARG%/$(LOADARG)/' -e 's/%LOADSLOW%/$(LOADSLOW)/' $(SCRIPT).tmpl > $@ || (rm $@ && exit 1)
+ chmod +x $@
+
install:
uninstall:
diff --git a/src/microsplash/microsplash-load.tmpl b/src/microsplash/microsplash-load.tmpl
new file mode 100644
index 00000000..c061559d
--- /dev/null
+++ b/src/microsplash/microsplash-load.tmpl
@@ -0,0 +1,21 @@
+#!/bin/sh
+dir=`dirname $0`
+
+HEX="$dir"/"%HEX%"
+LOADCMD="%LOADCMD%"
+LOADARG="%LOADARG%"
+LOADSLOW="%LOADSLOW%"
+LOADFAST=""
+
+case "$1" in
+slow)
+ LOADSPEED="$LOADSLOW"
+ ;;
+*)
+ LOADSPEED="$LOADFAST"
+ ;;
+esac
+
+echo ${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX}
+${LOADCMD} ${LOADSPEED} ${LOADARG}${HEX}
+/usr/games/xcowsay --cow-size=large --at=1000,500 "${HEX} finished"
diff --git a/src/product/ao_terraui.c b/src/product/ao_terraui.c
index 8fd97033..1e7b5dcd 100644
--- a/src/product/ao_terraui.c
+++ b/src/product/ao_terraui.c
@@ -539,9 +539,7 @@ ao_terraui(void)
else
ao_terraui_page[ao_current_page]();
- ao_alarm(AO_SEC_TO_TICKS(1));
- b = ao_button_get();
- ao_clear_alarm();
+ b = ao_button_get(AO_SEC_TO_TICKS(1));
if (b > 0) {
ao_beep_for(AO_BEEP_HIGH, AO_MS_TO_TICKS(10));
diff --git a/src/stm/ao_i2c_stm.c b/src/stm/ao_i2c_stm.c
index 1c90cdb8..158f5b21 100644
--- a/src/stm/ao_i2c_stm.c
+++ b/src/stm/ao_i2c_stm.c
@@ -195,15 +195,13 @@ ao_i2c_start(uint8_t index, uint16_t addr)
if (!(stm_i2c->cr1 & (1 << STM_I2C_CR1_START)))
break;
}
- ao_alarm(AO_MS_TO_TICKS(250));
ao_arch_block_interrupts();
stm_i2c->cr2 = AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN);
ao_i2c_ev_isr(index);
while (ao_i2c_state[index] == I2C_IDLE)
- if (ao_sleep(&ao_i2c_state[index]))
+ if (ao_sleep_for(&ao_i2c_state[index], AO_MS_TO_TICKS(250)))
break;
ao_arch_release_interrupts();
- ao_clear_alarm();
return ao_i2c_state[index] == I2C_RUNNING;
}
@@ -258,16 +256,14 @@ ao_i2c_send(void *block, uint16_t len, uint8_t index, uint8_t stop)
(STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR));
ao_dma_start(tx_dma_index);
- ao_alarm(1 + len);
ao_arch_block_interrupts();
while (!ao_dma_done[tx_dma_index])
- if (ao_sleep(&ao_dma_done[tx_dma_index]))
+ if (ao_sleep_for(&ao_dma_done[tx_dma_index], 1 + len))
break;
- ao_clear_alarm();
ao_dma_done_transfer(tx_dma_index);
stm_i2c->cr2 = AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN);
while ((stm_i2c->sr1 & (1 << STM_I2C_SR1_BTF)) == 0)
- if (ao_sleep(&ao_i2c_state[index]))
+ if (ao_sleep_for(&ao_i2c_state[index], 1 + len))
break;
stm_i2c->cr2 = AO_STM_I2C_CR2;
ao_arch_release_interrupts();
@@ -321,14 +317,12 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop)
if (stop)
stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP);
- ao_alarm(1);
ao_arch_block_interrupts();
while (ao_i2c_recv_len[index])
- if (ao_sleep(&ao_i2c_recv_len[index]))
+ if (ao_sleep_for(&ao_i2c_recv_len[index], 1))
break;
ao_arch_release_interrupts();
ret = ao_i2c_recv_len[index] == 0;
- ao_clear_alarm();
} else {
uint8_t rx_dma_index = ao_i2c_stm_info[index].rx_dma_index;
ao_dma_set_transfer(rx_dma_index,
@@ -351,13 +345,11 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop)
ao_i2c_wait_addr(index);
ao_dma_start(rx_dma_index);
- ao_alarm(len);
ao_arch_block_interrupts();
while (!ao_dma_done[rx_dma_index])
- if (ao_sleep(&ao_dma_done[rx_dma_index]))
+ if (ao_sleep_for(&ao_dma_done[rx_dma_index], len))
break;
ao_arch_release_interrupts();
- ao_clear_alarm();
ret = ao_dma_done[rx_dma_index];
ao_dma_done_transfer(rx_dma_index);
stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP);
diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c
index 2568cf43..88f2d029 100644
--- a/src/stm/ao_serial_stm.c
+++ b/src/stm/ao_serial_stm.c
@@ -86,9 +86,9 @@ ao_usart_getchar(struct ao_stm_usart *usart)
}
static inline uint8_t
-_ao_usart_sleep(struct ao_stm_usart *usart)
+_ao_usart_sleep_for(struct ao_stm_usart *usart, uint16_t timeout)
{
- return ao_sleep(&usart->rx_fifo);
+ return ao_sleep_for(&usart->rx_fifo, timeout);
}
void
@@ -217,9 +217,9 @@ _ao_serial1_pollchar(void)
}
uint8_t
-_ao_serial1_sleep(void)
+_ao_serial1_sleep_for(uint16_t timeout)
{
- return _ao_usart_sleep(&ao_stm_usart1);
+ return _ao_usart_sleep_for(&ao_stm_usart1, timeout);
}
void
@@ -260,9 +260,9 @@ _ao_serial2_pollchar(void)
}
uint8_t
-_ao_serial2_sleep(void)
+_ao_serial2_sleep_for(uint16_t timeout)
{
- return _ao_usart_sleep(&ao_stm_usart2);
+ return _ao_usart_sleep_for(&ao_stm_usart2, timeout);
}
void
@@ -303,9 +303,9 @@ _ao_serial3_pollchar(void)
}
uint8_t
-_ao_serial3_sleep(void)
+_ao_serial3_sleep_for(uint16_t timeout)
{
- return _ao_usart_sleep(&ao_stm_usart3);
+ return _ao_usart_sleep_for(&ao_stm_usart3, timeout);
}
void
diff --git a/src/stmf0/ao_adc_fast.c b/src/stmf0/ao_adc_fast.c
index be9b5986..26e6691c 100644
--- a/src/stmf0/ao_adc_fast.c
+++ b/src/stmf0/ao_adc_fast.c
@@ -18,43 +18,53 @@
#include <ao.h>
#include <ao_adc_fast.h>
-uint16_t ao_adc_ring[AO_ADC_RING_SIZE];
+uint16_t ao_adc_ring[AO_ADC_RING_SIZE] __attribute__((aligned(4)));
-uint16_t ao_adc_ring_head, ao_adc_ring_tail;
-uint8_t ao_adc_running;
+/* Maximum number of samples fetched per _ao_adc_start call */
+#define AO_ADC_RING_CHUNK (AO_ADC_RING_SIZE >> 1)
+
+uint16_t ao_adc_ring_head, ao_adc_ring_remain;
+uint16_t ao_adc_running;
/*
* Callback from DMA ISR
*
- * Mark time in ring, shut down DMA engine
+ * Wakeup any waiting processes, mark the DMA as done, start the ADC
+ * if there's still lots of space in the ring
*/
static void ao_adc_dma_done(int index)
{
(void) index;
- ao_adc_ring_head += AO_ADC_RING_CHUNK;
+ ao_adc_ring_head += ao_adc_running;
+ ao_adc_ring_remain += ao_adc_running;
if (ao_adc_ring_head == AO_ADC_RING_SIZE)
ao_adc_ring_head = 0;
ao_adc_running = 0;
ao_wakeup(&ao_adc_ring_head);
ao_dma_done_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1));
+ _ao_adc_start();
}
void
_ao_adc_start(void)
{
uint16_t *buf;
+ uint16_t count;
if (ao_adc_running)
return;
- if (_ao_adc_space() < AO_ADC_RING_CHUNK)
+ count = _ao_adc_space();
+ if (count == 0)
return;
- ao_adc_running = 1;
+ if (count > AO_ADC_RING_CHUNK)
+ count = AO_ADC_RING_CHUNK;
+ ao_adc_running = count;
buf = ao_adc_ring + ao_adc_ring_head;
stm_adc.isr = 0;
ao_dma_set_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1),
&stm_adc.dr,
buf,
- AO_ADC_RING_CHUNK,
+ count,
(0 << STM_DMA_CCR_MEM2MEM) |
(STM_DMA_CCR_PL_HIGH << STM_DMA_CCR_PL) |
(STM_DMA_CCR_MSIZE_16 << STM_DMA_CCR_MSIZE) |
@@ -140,7 +150,6 @@ ao_adc_init(void)
#if AO_NUM_ADC > 8
#error Need more ADC defines
#endif
- stm_adc.chselr = chselr;
/* Set the clock */
stm_adc.cfgr2 = STM_ADC_CFGR2_CKMODE_PCLK_2 << STM_ADC_CFGR2_CKMODE;
@@ -160,14 +169,16 @@ ao_adc_init(void)
while ((stm_adc.isr & (1 << STM_ADC_ISR_ADRDY)) == 0)
;
+ stm_adc.chselr = chselr;
+
stm_adc.cfgr1 = ((0 << STM_ADC_CFGR1_AWDCH) |
(0 << STM_ADC_CFGR1_AWDEN) |
(0 << STM_ADC_CFGR1_AWDSGL) |
(0 << STM_ADC_CFGR1_DISCEN) |
(0 << STM_ADC_CFGR1_AUTOOFF) |
- (1 << STM_ADC_CFGR1_WAIT) |
+ (0 << STM_ADC_CFGR1_WAIT) |
(1 << STM_ADC_CFGR1_CONT) |
- (0 << STM_ADC_CFGR1_OVRMOD) |
+ (1 << STM_ADC_CFGR1_OVRMOD) |
(STM_ADC_CFGR1_EXTEN_DISABLE << STM_ADC_CFGR1_EXTEN) |
(0 << STM_ADC_CFGR1_ALIGN) |
(STM_ADC_CFGR1_RES_12 << STM_ADC_CFGR1_RES) |
@@ -186,5 +197,4 @@ ao_adc_init(void)
stm_syscfg.cfgr1 &= ~(1 << STM_SYSCFG_CFGR1_ADC_DMA_RMP);
ao_dma_alloc(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1));
- ao_dma_set_isr(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1), ao_adc_dma_done);
}
diff --git a/src/stmf0/ao_adc_fast.h b/src/stmf0/ao_adc_fast.h
index eec45505..c6903e9f 100644
--- a/src/stmf0/ao_adc_fast.h
+++ b/src/stmf0/ao_adc_fast.h
@@ -26,62 +26,59 @@ ao_adc_init(void);
/* Total ring size in samples */
#define AO_ADC_RING_SIZE 256
-/* Number of samples fetched per ao_adc_start call */
-#define AO_ADC_RING_CHUNK (AO_ADC_RING_SIZE >> 1)
extern uint16_t ao_adc_ring[AO_ADC_RING_SIZE];
#define ao_adc_ring_step(pos,inc) (((pos) + (inc)) & (AO_ADC_RING_SIZE - 1))
-extern uint16_t ao_adc_ring_head, ao_adc_ring_tail;
-extern uint8_t ao_adc_running;
-
-void
-_ao_adc_start(void);
+extern uint16_t ao_adc_ring_head, ao_adc_ring_remain;
+extern uint16_t ao_adc_running;
+/*
+ * Place to start fetching values from
+ */
static inline uint16_t
-_ao_adc_remain(void)
+ao_adc_ring_tail(void)
{
- if (ao_adc_ring_tail > ao_adc_ring_head)
- return AO_ADC_RING_SIZE - ao_adc_ring_tail;
- return ao_adc_ring_head - ao_adc_ring_tail;
+ return (ao_adc_ring_head - ao_adc_ring_remain) & (AO_ADC_RING_SIZE - 1);
}
+void
+_ao_adc_start(void);
+
+/*
+ * Space available to write ADC values into
+ */
static inline uint16_t
_ao_adc_space(void)
{
- if (ao_adc_ring_head == ao_adc_ring_tail)
- return AO_ADC_RING_SIZE;
- if (ao_adc_ring_head > ao_adc_ring_tail)
+ /* Free to end of buffer? */
+ if (ao_adc_ring_remain <= ao_adc_ring_head)
return AO_ADC_RING_SIZE - ao_adc_ring_head;
- return ao_adc_ring_tail - ao_adc_ring_head;
+
+ /* no, return just the unused entries beyond head */
+ return AO_ADC_RING_SIZE - ao_adc_ring_remain;
}
-static inline uint16_t *
+static inline uint16_t
ao_adc_get(uint16_t n)
{
- if (ao_adc_ring_tail + n > AO_ADC_RING_SIZE)
- ao_panic(AO_PANIC_ADC);
ao_arch_block_interrupts();
- while (_ao_adc_remain() < n) {
+ while (ao_adc_ring_remain < n) {
if (!ao_adc_running)
_ao_adc_start();
ao_sleep(&ao_adc_ring_head);
}
ao_arch_release_interrupts();
- return &ao_adc_ring[ao_adc_ring_tail];
+ return ao_adc_ring_tail();
}
static inline void
ao_adc_ack(uint16_t n)
{
- if (ao_adc_ring_tail + n > AO_ADC_RING_SIZE)
- ao_panic(AO_PANIC_ADC);
ao_arch_block_interrupts();
- ao_adc_ring_tail += n;
- if (ao_adc_ring_tail == AO_ADC_RING_SIZE)
- ao_adc_ring_tail = 0;
- if (!ao_adc_running && _ao_adc_space() >= AO_ADC_RING_CHUNK)
+ ao_adc_ring_remain -= n;
+ if (!ao_adc_running)
_ao_adc_start();
ao_arch_release_interrupts();
}
diff --git a/src/stmf0/ao_crc_stm.c b/src/stmf0/ao_crc_stm.c
new file mode 100644
index 00000000..863f5ef5
--- /dev/null
+++ b/src/stmf0/ao_crc_stm.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2015 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_crc.h>
+
+#ifndef AO_CRC_WIDTH
+#error "Must define AO_CRC_WIDTH"
+#endif
+
+/* Only the STM32F07x and ST32F09x series have
+ * programmable CRC units. Others can only do the ANSI CRC-32 computation
+ */
+
+#if !AO_HAVE_PROGRAMMABLE_CRC_UNIT && AO_CRC_WIDTH != 32
+#error "Target hardware does not have programmable CRC unit"
+#endif
+
+#ifndef AO_CRC_POLY
+#if AO_CRC_WIDTH == 16
+#define AO_CRC_POLY AO_CRC_16_DEFAULT
+#endif
+#if AO_CRC_WIDTH == 32
+#define AO_CRC_POLY AO_CRC_32_DEFAULT
+#endif
+#endif
+
+#if !AO_HAVE_PROGRAMMABLE_CRC_UNIT && (AO_CRC_WIDTH != 32 || AO_CRC_POLY != AO_CRC_32_ANSI)
+#error "Target hardware does not have programmable CRC unit"
+#endif
+
+#if AO_CRC_WIDTH == 32
+#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_32
+#endif
+
+#if AO_CRC_WIDTH == 16
+#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_16
+#endif
+
+#if AO_CRC_WIDTH == 8
+#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_8
+#endif
+
+#if AO_CRC_WIDTH == 7
+#define AO_CRC_CR_POLYSIZE STM_CRC_CR_POLYSIZE_7
+#endif
+
+#ifndef AO_CRC_INIT
+#define AO_CRC_INIT 0xffffffff
+#endif
+
+void
+ao_crc_reset(void)
+{
+ stm_crc.cr |= (1 << STM_CRC_CR_RESET);
+ while ((stm_crc.cr & (1 << STM_CRC_CR_RESET)) != 0)
+ ;
+}
+
+void
+ao_crc_init(void)
+{
+ /* Turn on the CRC clock */
+ stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_CRCEN);
+
+ /* Need to initialize CR even on non-programmable hardware,
+ * the write to the POLYSIZE bits will be ignored in that
+ * case
+ */
+ stm_crc.cr = (AO_CRC_CR_POLYSIZE << STM_CRC_CR_POLYSIZE);
+ stm_crc.init = AO_CRC_INIT;
+#if AO_HAVE_PROGRAMMABLE_CRC_UNIT
+ stm_crc.pol = AO_CRC_POLY;
+#endif
+ ao_crc_reset();
+}
diff --git a/src/stmf0/ao_exti.h b/src/stmf0/ao_exti.h
new file mode 100644
index 00000000..ebea224d
--- /dev/null
+++ b/src/stmf0/ao_exti.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_EXTI_H_
+#define _AO_EXTI_H_
+
+#define AO_EXTI_MODE_RISING 1
+#define AO_EXTI_MODE_FALLING 2
+#define AO_EXTI_MODE_PULL_UP 4
+#define AO_EXTI_MODE_PULL_DOWN 8
+#define AO_EXTI_PRIORITY_LOW 16
+#define AO_EXTI_PRIORITY_MED 0
+#define AO_EXTI_PRIORITY_HIGH 32
+#define AO_EXTI_PIN_NOCONFIGURE 64
+
+void
+ao_exti_setup(struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)());
+
+void
+ao_exti_set_mode(struct stm_gpio *gpio, uint8_t pin, uint8_t mode);
+
+void
+ao_exti_set_callback(struct stm_gpio *gpio, uint8_t pin, void (*callback)());
+
+void
+ao_exti_enable(struct stm_gpio *gpio, uint8_t pin);
+
+void
+ao_exti_disable(struct stm_gpio *gpio, uint8_t pin);
+
+void
+ao_exti_init(void);
+
+#endif /* _AO_EXTI_H_ */
diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c
index 3ea7da5e..b8146c21 100644
--- a/src/stmf0/ao_usb_stm.c
+++ b/src/stmf0/ao_usb_stm.c
@@ -83,9 +83,13 @@ static uint16_t ao_usb_sram_addr;
static uint16_t *ao_usb_ep0_tx_buffer;
static uint16_t *ao_usb_ep0_rx_buffer;
+/* Pointer to interrupt buffer in USB memory */
+static uint16_t ao_usb_int_tx_offset;
+
/* Pointer to bulk data tx/rx buffers in USB memory */
static uint16_t ao_usb_in_tx_offset;
static uint16_t *ao_usb_in_tx_buffer;
+static uint16_t ao_usb_out_rx_offset;
static uint16_t *ao_usb_out_rx_buffer;
/* System ram shadow of USB buffer; writing individual bytes is
@@ -146,12 +150,10 @@ static inline uint16_t *ao_usb_packet_buffer_addr(uint16_t sram_addr)
return (uint16_t *) (stm_usb_sram + sram_addr);
}
-#if AO_USB_DIRECTIO
static inline uint16_t ao_usb_packet_buffer_offset(uint16_t *addr)
{
return (uint16_t) ((uint8_t *) addr - stm_usb_sram);
}
-#endif
static inline uint32_t ao_usb_epr_stat_rx(uint32_t epr) {
return (epr >> STM_USB_EPR_STAT_RX) & STM_USB_EPR_STAT_RX_MASK;
@@ -323,27 +325,42 @@ ao_usb_init_ep(uint8_t ep, uint32_t addr, uint32_t type, uint32_t stat_rx, uint3
}
static void
-ao_usb_init_btable(void)
+ao_usb_alloc_buffers(void)
{
ao_usb_sram_addr = 0;
ao_usb_bdt = (void *) stm_usb_sram;
-
ao_usb_sram_addr += 8 * STM_USB_BDT_SIZE;
- /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */
-
- ao_usb_bdt[0].single.addr_tx = ao_usb_sram_addr;
- ao_usb_bdt[0].single.count_tx = 0;
ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
ao_usb_sram_addr += AO_USB_CONTROL_SIZE;
- ao_usb_bdt[0].single.addr_rx = ao_usb_sram_addr;
- ao_usb_bdt[0].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) |
- (((AO_USB_CONTROL_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK));
ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
ao_usb_sram_addr += AO_USB_CONTROL_SIZE;
+ ao_usb_int_tx_offset = ao_usb_sram_addr;
+ ao_usb_sram_addr += AO_USB_INT_SIZE;
+
+ ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
+ ao_usb_out_rx_offset = ao_usb_sram_addr;
+ ao_usb_sram_addr += AO_USB_OUT_SIZE;
+
+ ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
+ ao_usb_in_tx_offset = ao_usb_sram_addr;
+ ao_usb_sram_addr += AO_USB_IN_SIZE;
+}
+
+static void
+ao_usb_init_btable(void)
+{
+ /* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */
+
+ ao_usb_bdt[0].single.addr_tx = ao_usb_packet_buffer_offset(ao_usb_ep0_tx_buffer);
+ ao_usb_bdt[0].single.count_tx = 0;
+
+ ao_usb_bdt[0].single.addr_rx = ao_usb_packet_buffer_offset(ao_usb_ep0_rx_buffer);
+ ao_usb_bdt[0].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) |
+ (((AO_USB_CONTROL_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK));
}
static void
@@ -370,6 +387,8 @@ ao_usb_set_ep0(void)
}
ao_usb_set_address(0);
+
+ ao_usb_running = 0;
}
static void
@@ -378,9 +397,8 @@ ao_usb_set_configuration(void)
debug ("ao_usb_set_configuration\n");
/* Set up the INT end point */
- ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_sram_addr;
+ ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_int_tx_offset;
ao_usb_bdt[AO_USB_INT_EPR].single.count_tx = 0;
- ao_usb_sram_addr += AO_USB_INT_SIZE;
ao_usb_init_ep(AO_USB_INT_EPR,
AO_USB_INT_EP,
@@ -389,11 +407,9 @@ ao_usb_set_configuration(void)
STM_USB_EPR_STAT_TX_NAK);
/* Set up the OUT end point */
- ao_usb_bdt[AO_USB_OUT_EPR].single.addr_rx = ao_usb_sram_addr;
+ ao_usb_bdt[AO_USB_OUT_EPR].single.addr_rx = ao_usb_out_rx_offset;
ao_usb_bdt[AO_USB_OUT_EPR].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) |
(((AO_USB_OUT_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK));
- ao_usb_out_rx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
- ao_usb_sram_addr += AO_USB_OUT_SIZE;
ao_usb_init_ep(AO_USB_OUT_EPR,
AO_USB_OUT_EP,
@@ -402,11 +418,8 @@ ao_usb_set_configuration(void)
STM_USB_EPR_STAT_TX_DISABLED);
/* Set up the IN end point */
- ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_sram_addr;
+ ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_in_tx_offset;
ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = 0;
- ao_usb_in_tx_offset = ao_usb_sram_addr;
- ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_in_tx_offset);
- ao_usb_sram_addr += AO_USB_IN_SIZE;
ao_usb_init_ep(AO_USB_IN_EPR,
AO_USB_IN_EP,
@@ -415,6 +428,9 @@ ao_usb_set_configuration(void)
STM_USB_EPR_STAT_TX_NAK);
ao_usb_running = 1;
+#if AO_USB_DIRECTIO
+ ao_wakeup(&ao_usb_running);
+#endif
}
static uint16_t control_count;
@@ -916,8 +932,6 @@ ao_usb_alloc(void)
{
uint16_t *buffer;
- if (!ao_usb_running)
- return NULL;
buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
ao_usb_sram_addr += AO_USB_IN_SIZE;
return buffer;
@@ -936,12 +950,28 @@ ao_usb_write(uint16_t *buffer, uint16_t len)
{
ao_arch_block_interrupts();
- /* Flush any pending regular */
- if (ao_usb_tx_count)
- _ao_usb_in_send();
+ /* Wait for everything to be ready at the same time */
+ for (;;) {
+ /* Make sure USB is connected */
+ if (!ao_usb_running) {
+ ao_sleep(&ao_usb_running);
+ continue;
+ }
+
+ /* Flush any pending regular I/O */
+ if (ao_usb_tx_count) {
+ _ao_usb_in_send();
+ continue;
+ }
+
+ /* Wait for an idle IN buffer */
+ if (ao_usb_in_pending) {
+ ao_sleep(&ao_usb_in_pending);
+ continue;
+ }
+ break;
+ }
- while (ao_usb_in_pending)
- ao_sleep(&ao_usb_in_pending);
ao_usb_in_pending = 1;
ao_usb_in_flushed = (len != AO_USB_IN_SIZE);
ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_packet_buffer_offset(buffer);
@@ -1083,6 +1113,9 @@ ao_usb_init(void)
debug ("ao_usb_init\n");
ao_usb_ep0_state = AO_USB_EP0_IDLE;
+
+ ao_usb_alloc_buffers();
+
#if USB_ECHO
ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo");
#endif
diff --git a/src/telebt-v3.0/ao_pins.h b/src/telebt-v3.0/ao_pins.h
index 838f0dfc..a6a01662 100644
--- a/src/telebt-v3.0/ao_pins.h
+++ b/src/telebt-v3.0/ao_pins.h
@@ -130,7 +130,7 @@ struct ao_adc {
};
#define AO_ADC_DUMP(p) \
- printf("tick: %5u %5d batt: %5d\n", \
+ printf("tick: %5u batt %5d\n", \
(p)->tick, \
(p)->adc.v_batt);
@@ -168,7 +168,7 @@ struct ao_adc {
#define ao_serial_btm_getchar ao_serial2_getchar
#define ao_serial_btm_putchar ao_serial2_putchar
#define _ao_serial_btm_pollchar _ao_serial2_pollchar
-#define _ao_serial_btm_sleep _ao_serial2_sleep
+#define _ao_serial_btm_sleep_for _ao_serial2_sleep_for
#define ao_serial_btm_set_speed ao_serial2_set_speed
#define ao_serial_btm_drain ao_serial2_drain
#define ao_serial_btm_rx_fifo (ao_stm_usart2.rx_fifo)
diff --git a/src/telelco-v0.1/ao_lco.c b/src/telelco-v0.1/ao_lco.c
index 79f3896b..cb2195ef 100644
--- a/src/telelco-v0.1/ao_lco.c
+++ b/src/telelco-v0.1/ao_lco.c
@@ -280,9 +280,7 @@ ao_lco_igniter_status(void)
uint16_t delay;
for (;;) {
-// ao_alarm(delay);
ao_sleep(&ao_pad_query);
-// ao_clear_alarm();
if (!ao_lco_valid) {
ao_led_on(AO_LED_RED);
ao_led_off(AO_LED_GREEN);
@@ -364,9 +362,7 @@ ao_lco_monitor(void)
delay = AO_MS_TO_TICKS(100);
else
delay = AO_SEC_TO_TICKS(1);
- ao_alarm(delay);
- ao_sleep(&ao_lco_armed);
- ao_clear_alarm();
+ ao_sleep_for(&ao_lco_armed, delay);
}
}
diff --git a/src/telelco-v0.3/.gitignore b/src/telelco-v0.3/.gitignore
new file mode 100644
index 00000000..a32ec26e
--- /dev/null
+++ b/src/telelco-v0.3/.gitignore
@@ -0,0 +1,2 @@
+ao_product.h
+telelco*.elf
diff --git a/src/telelco-v0.3/Makefile b/src/telelco-v0.3/Makefile
new file mode 100644
index 00000000..83d3fc43
--- /dev/null
+++ b/src/telelco-v0.3/Makefile
@@ -0,0 +1,108 @@
+#
+# AltOS build for TeleLCO
+#
+#
+
+include ../stm/Makefile.defs
+
+INC = \
+ ao.h \
+ ao_arch.h \
+ ao_arch_funcs.h \
+ ao_boot.h \
+ ao_companion.h \
+ ao_data.h \
+ ao_sample.h \
+ ao_pins.h \
+ ao_product.h \
+ ao_seven_segment.h \
+ ao_lco.h \
+ ao_lco_cmd.h \
+ ao_lco_func.h \
+ ao_radio_spi.h \
+ ao_radio_cmac.h \
+ ao_cc1200_CC1200.h \
+ ao_cc1200.h \
+ ao_debounce.h \
+ stm32l.h
+
+#
+# Common AltOS sources
+#
+
+#PROFILE=ao_profile.c
+#PROFILE_DEF=-DAO_PROFILE=1
+
+ALTOS_SRC = \
+ ao_boot_chain.c \
+ ao_interrupt.c \
+ ao_product.c \
+ ao_romconfig.c \
+ ao_cmd.c \
+ ao_config.c \
+ ao_task.c \
+ ao_led.c \
+ ao_stdio.c \
+ ao_panic.c \
+ ao_timer.c \
+ ao_mutex.c \
+ ao_freq.c \
+ ao_dma_stm.c \
+ ao_spi_stm.c \
+ ao_beep_stm.c \
+ ao_eeprom_stm.c \
+ ao_fast_timer.c \
+ ao_lcd_stm.c \
+ ao_usb_stm.c \
+ ao_exti_stm.c \
+ ao_cc1200.c \
+ ao_radio_cmac.c \
+ ao_aes.c \
+ ao_aes_tables.c \
+ ao_fec_tx.c \
+ ao_fec_rx.c \
+ ao_seven_segment.c \
+ ao_debounce.c \
+ ao_quadrature.c \
+ ao_button.c \
+ ao_event.c \
+ ao_lco.c \
+ ao_lco_cmd.c \
+ ao_lco_func.c \
+ ao_radio_cmac_cmd.c
+
+PRODUCT=TeleLCO-v0.3
+PRODUCT_DEF=-DTELELCO
+IDPRODUCT=0x0023
+
+CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) -Os -g
+
+PROGNAME=telelco-v0.3
+PROG=$(PROGNAME)-$(VERSION).elf
+HEX=$(PROGNAME)-$(VERSION).ihx
+
+SRC=$(ALTOS_SRC) ao_telelco.c
+OBJ=$(SRC:.c=.o)
+
+all: $(PROG) $(HEX)
+
+$(PROG): Makefile $(OBJ) altos.ld
+ $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+
+../altitude.h: make-altitude
+ nickle $< > $@
+
+$(OBJ): $(INC)
+
+ao_product.h: ao-make-product.5c ../Version
+ $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@
+
+distclean: clean
+
+clean:
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f ao_product.h
+
+install:
+
+uninstall:
diff --git a/src/telelco-v0.3/ao_pins.h b/src/telelco-v0.3/ao_pins.h
new file mode 100644
index 00000000..92095a7c
--- /dev/null
+++ b/src/telelco-v0.3/ao_pins.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+/* 8MHz High speed external crystal */
+#define AO_HSE 8000000
+
+/* PLLVCO = 96MHz (so that USB will work) */
+#define AO_PLLMUL 12
+#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12)
+
+#define AO_CC1200_FOSC 40000000
+
+/* SYSCLK = 32MHz (no need to go faster than CPU) */
+#define AO_PLLDIV 3
+#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_3)
+
+/* HCLK = 32MHz (CPU clock) */
+#define AO_AHB_PRESCALER 1
+#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1
+
+/* Run APB1 at 16MHz (HCLK/2) */
+#define AO_APB1_PRESCALER 2
+#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE2_DIV_2
+
+/* Run APB2 at 16MHz (HCLK/2) */
+#define AO_APB2_PRESCALER 2
+#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_2
+
+#define HAS_EEPROM 1
+#define USE_INTERNAL_FLASH 1
+#define USE_EEPROM_CONFIG 1
+#define USE_STORAGE_CONFIG 0
+#define HAS_USB 1
+#define HAS_BEEP 1
+#define HAS_RADIO 1
+#define HAS_RADIO_RATE 1
+#define HAS_TELEMETRY 0
+#define HAS_AES 1
+
+#define HAS_SPI_1 0
+#define SPI_1_PA5_PA6_PA7 0
+#define SPI_1_PB3_PB4_PB5 0
+#define SPI_1_PE13_PE14_PE15 0
+
+#define HAS_SPI_2 1 /* CC1120 */
+#define SPI_2_PB13_PB14_PB15 0
+#define SPI_2_PD1_PD3_PD4 1
+#define SPI_2_GPIO (&stm_gpiod)
+#define SPI_2_SCK 1
+#define SPI_2_MISO 3
+#define SPI_2_MOSI 4
+#define SPI_2_OSPEEDR STM_OSPEEDR_10MHz
+
+#define HAS_I2C_1 0
+
+#define HAS_I2C_2 0
+
+#define PACKET_HAS_SLAVE 0
+#define PACKET_HAS_MASTER 0
+
+#define FAST_TIMER_FREQ 10000 /* .1ms for debouncing */
+
+/*
+ * Radio is a cc1200 connected via SPI
+ */
+
+#define AO_RADIO_CAL_DEFAULT 5695733
+
+#define AO_FEC_DEBUG 0
+#define AO_CC1200_SPI_CS_PORT (&stm_gpiod)
+#define AO_CC1200_SPI_CS_PIN 0
+#define AO_CC1200_SPI_BUS AO_SPI_2_PD1_PD3_PD4
+#define AO_CC1200_SPI stm_spi2
+
+#define AO_CC1200_INT_PORT (&stm_gpioc)
+#define AO_CC1200_INT_PIN (15)
+
+#define AO_CC1200_INT_GPIO 2
+#define AO_CC1200_INT_GPIO_IOCFG CC1200_IOCFG2
+
+#define LOW_LEVEL_DEBUG 0
+
+#define LED_PORT_ENABLE STM_RCC_AHBENR_GPIOCEN
+#define LED_PORT (&stm_gpioc)
+#define LED_PIN_RED 7
+#define LED_PIN_AMBER 8
+#define LED_PIN_GREEN 9
+#define LED_PIN_CONTINUITY_3 10
+#define LED_PIN_CONTINUITY_2 11
+#define LED_PIN_CONTINUITY_1 12
+#define LED_PIN_CONTINUITY_0 13
+#define LED_PIN_REMOTE_ARM 14
+#define AO_LED_RED (1 << LED_PIN_RED)
+#define AO_LED_AMBER (1 << LED_PIN_AMBER)
+#define AO_LED_GREEN (1 << LED_PIN_GREEN)
+#define AO_LED_CONTINUITY_3 (1 << LED_PIN_CONTINUITY_3)
+#define AO_LED_CONTINUITY_2 (1 << LED_PIN_CONTINUITY_2)
+#define AO_LED_CONTINUITY_1 (1 << LED_PIN_CONTINUITY_1)
+#define AO_LED_CONTINUITY_0 (1 << LED_PIN_CONTINUITY_0)
+
+#define AO_LED_CONTINUITY_NUM 4
+
+#define AO_LED_REMOTE_ARM (1 << LED_PIN_REMOTE_ARM)
+
+#define LEDS_AVAILABLE (AO_LED_RED | \
+ AO_LED_AMBER | \
+ AO_LED_GREEN | \
+ AO_LED_CONTINUITY_3 | \
+ AO_LED_CONTINUITY_2 | \
+ AO_LED_CONTINUITY_1 | \
+ AO_LED_CONTINUITY_0 | \
+ AO_LED_REMOTE_ARM)
+
+/* LCD displays */
+
+#define LCD_DEBUG 0
+#define SEVEN_SEGMENT_DEBUG 0
+
+#define AO_LCD_STM_SEG_ENABLED_0 ( \
+ (1 << 0) | /* PA1 */ \
+ (1 << 1) | /* PA2 */ \
+ (1 << 2) | /* PA3 */ \
+ (1 << 3) | /* PA6 */ \
+ (1 << 4) | /* PA7 */ \
+ (1 << 5) | /* PB0 */ \
+ (1 << 6) | /* PB1 */ \
+ (1 << 7) | /* PB3 */ \
+ (1 << 8) | /* PB4 */ \
+ (1 << 9) | /* PB5 */ \
+ (1 << 10) | /* PB10 */ \
+ (1 << 11) | /* PB11 */ \
+ (1 << 12) | /* PB12 */ \
+ (1 << 13) | /* PB13 */ \
+ (1 << 14) | /* PB14 */ \
+ (1 << 15) | /* PB15 */ \
+ (1 << 16) | /* PB8 */ \
+ (1 << 17) | /* PA15 */ \
+ (1 << 18) | /* PC0 */ \
+ (1 << 19) | /* PC1 */ \
+ (1 << 20) | /* PC2 */ \
+ (1 << 21) | /* PC3 */ \
+ (1 << 22) | /* PC4 */ \
+ (1 << 23) | /* PC5 */ \
+ (0 << 24) | /* PC6 */ \
+ (0 << 25) | /* PC7 */ \
+ (0 << 26) | /* PC8 */ \
+ (0 << 27) | /* PC9 */ \
+ (0 << 28) | /* PC10 or PD8 */ \
+ (0 << 29) | /* PC11 or PD9 */ \
+ (0 << 30) | /* PC12 or PD10 */ \
+ (0 << 31)) /* PD2 or PD11 */
+
+#define AO_LCD_STM_SEG_ENABLED_1 ( \
+ (0 << 0) | /* PD12 */ \
+ (0 << 1) | /* PD13 */ \
+ (0 << 2) | /* PD14 */ \
+ (0 << 3) | /* PD15 */ \
+ (0 << 4) | /* PE0 */ \
+ (0 << 5) | /* PE1 */ \
+ (0 << 6) | /* PE2 */ \
+ (0 << 7)) /* PE3 */
+
+#define AO_LCD_STM_COM_ENABLED ( \
+ (1 << 0) | /* PA8 */ \
+ (0 << 1) | /* PA9 */ \
+ (0 << 2) | /* PA10 */ \
+ (0 << 3) | /* PB9 */ \
+ (0 << 4) | /* PC10 */ \
+ (0 << 5) | /* PC11 */ \
+ (0 << 6)) /* PC12 */
+
+#define AO_LCD_28_ON_C 0
+
+#define AO_LCD_DUTY STM_LCD_CR_DUTY_STATIC
+
+#define AO_LCD_PER_DIGIT 1
+
+#define AO_LCD_DIGITS 3
+#define AO_LCD_SEGMENTS 8
+
+#define AO_SEGMENT_MAP { \
+ /* pad segments */ \
+ { 0, 14 }, \
+ { 0, 13 }, \
+ { 0, 15 }, \
+ { 0, 17 }, \
+ { 0, 16 }, \
+ { 0, 8 }, \
+ { 0, 9 }, \
+ { 0, 7 }, \
+ /* box1 segments */ \
+ { 0, 10 }, \
+ { 0, 6 }, \
+ { 0, 11 }, \
+ { 0, 12 }, \
+ { 0, 21 }, \
+ { 0, 19 }, \
+ { 0, 20 }, \
+ { 0, 18 }, \
+ /* box0 segments */ \
+ { 0, 22 }, \
+ { 0, 4 }, \
+ { 0, 23 }, \
+ { 0, 5 }, \
+ { 0, 3 }, \
+ { 0, 1 }, \
+ { 0, 2 }, \
+ { 0, 0 }, \
+}
+
+/*
+ * Use event queue for input devices
+ */
+
+#define AO_EVENT 1
+
+/*
+ * Knobs
+ */
+
+#define AO_QUADRATURE_COUNT 2
+
+#define AO_QUADRATURE_0_PORT &stm_gpioe
+#define AO_QUADRATURE_0_A 3
+#define AO_QUADRATURE_0_B 2
+
+#define AO_QUADRATURE_PAD 0
+
+#define AO_QUADRATURE_1_PORT &stm_gpioe
+#define AO_QUADRATURE_1_A 1
+#define AO_QUADRATURE_1_B 0
+
+#define AO_QUADRATURE_BOX 1
+
+/*
+ * Buttons
+ */
+
+#define AO_BUTTON_COUNT 2
+#define AO_BUTTON_MODE AO_EXTI_MODE_PULL_UP
+
+#define AO_BUTTON_0_PORT &stm_gpioe
+#define AO_BUTTON_0 4
+
+#define AO_BUTTON_ARM 0
+
+#define AO_BUTTON_1_PORT &stm_gpioe
+#define AO_BUTTON_1 5
+
+#define AO_BUTTON_FIRE 1
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/telelco-v0.3/ao_telelco.c b/src/telelco-v0.3/ao_telelco.c
new file mode 100644
index 00000000..d9f7c693
--- /dev/null
+++ b/src/telelco-v0.3/ao_telelco.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_exti.h>
+#include <ao_packet.h>
+#include <ao_companion.h>
+#include <ao_profile.h>
+#include <ao_pyro.h>
+#include <ao_aes.h>
+#include <ao_seven_segment.h>
+#include <ao_quadrature.h>
+#include <ao_button.h>
+#include <ao_lco.h>
+#include <ao_lco_cmd.h>
+#include <ao_radio_cmac_cmd.h>
+#include <ao_eeprom.h>
+
+int
+main(void)
+{
+ ao_clock_init();
+
+ ao_led_init(LEDS_AVAILABLE);
+ ao_led_on(AO_LED_GREEN);
+ ao_task_init();
+
+ ao_timer_init();
+
+ ao_spi_init();
+ ao_dma_init();
+ ao_exti_init();
+
+ ao_beep_init();
+ ao_cmd_init();
+
+ ao_lcd_stm_init();
+ ao_seven_segment_init();
+ ao_quadrature_init();
+ ao_button_init();
+
+ ao_eeprom_init();
+
+ ao_radio_init();
+
+ ao_usb_init();
+
+ ao_config_init();
+
+ ao_lco_init();
+ ao_lco_cmd_init();
+// ao_radio_cmac_cmd_init();
+
+ ao_start_scheduler();
+ return 0;
+}
diff --git a/src/telelco-v0.3/flash-loader/Makefile b/src/telelco-v0.3/flash-loader/Makefile
new file mode 100644
index 00000000..679e61ba
--- /dev/null
+++ b/src/telelco-v0.3/flash-loader/Makefile
@@ -0,0 +1,8 @@
+#
+# AltOS flash loader build
+#
+#
+
+TOPDIR=../..
+HARDWARE=telelco-v0.2
+include $(TOPDIR)/stm/Makefile-flash.defs
diff --git a/src/telelco-v0.3/flash-loader/ao_pins.h b/src/telelco-v0.3/flash-loader/ao_pins.h
new file mode 100644
index 00000000..6c8ff7e2
--- /dev/null
+++ b/src/telelco-v0.3/flash-loader/ao_pins.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_PINS_H_
+#define _AO_PINS_H_
+
+/* External crystal at 8MHz */
+#define AO_HSE 8000000
+
+#include <ao_flash_stm_pins.h>
+
+/* Arm switch. Press at power on to get boot loader */
+
+#define AO_BOOT_PIN 1
+#define AO_BOOT_APPLICATION_GPIO stm_gpioe
+#define AO_BOOT_APPLICATION_PIN 4
+#define AO_BOOT_APPLICATION_VALUE 1
+#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP
+
+#endif /* _AO_PINS_H_ */
diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c
index fbbc4bd9..f71c3052 100644
--- a/src/test/ao_flight_test.c
+++ b/src/test/ao_flight_test.c
@@ -554,9 +554,9 @@ ao_insert(void)
ao_quaternion_rotate(&ao_out, &ao_x, &ao_rotation);
+#if 0
int out = floor (atan2(ao_out.y, ao_out.x) * 180 / M_PI);
-#if 0
printf ("%7.2f state %-8.8s height %8.4f tilt %4d rot %4d mag_tilt %4d mag_rot %4d\n",
time,
ao_state_names[ao_flight_state],
@@ -717,7 +717,7 @@ ao_sleep(void *wchan)
break;
}
#if TELEMEGA
- if (log_format == AO_LOG_FORMAT_TELEMEGA && nword == 30 && strlen(words[0]) == 1) {
+ if ((log_format == AO_LOG_FORMAT_TELEMEGA_OLD || log_format == AO_LOG_FORMAT_TELEMEGA) && nword == 30 && strlen(words[0]) == 1) {
int i;
struct ao_ms5607_value value;
@@ -895,7 +895,6 @@ ao_sleep(void *wchan)
ao_config.accel_zero_along = atoi(words[3]);
ao_config.accel_zero_across = atoi(words[5]);
ao_config.accel_zero_through = atoi(words[7]);
- printf ("%d %d %d\n", ao_config.accel_zero_along, ao_config.accel_zero_across, ao_config.accel_zero_through);
#endif
} else if (nword >= 4 && strcmp(words[0], "Main") == 0) {
ao_config.main_deploy = atoi(words[2]);
diff --git a/src/usbtrng-v2.0/Makefile b/src/usbtrng-v2.0/Makefile
index abbdbbcc..49798f1c 100644
--- a/src/usbtrng-v2.0/Makefile
+++ b/src/usbtrng-v2.0/Makefile
@@ -12,6 +12,7 @@ INC = \
ao_pins.h \
ao_product.h \
ao_task.h \
+ ao_adc_fast.h \
stm32f0.h
#
@@ -31,6 +32,7 @@ ALTOS_SRC = \
ao_boot_chain.c \
ao_cmd.c \
ao_usb_stm.c \
+ ao_trng.c \
ao_task.c \
ao_product.c
diff --git a/src/usbtrng-v2.0/ao_pins.h b/src/usbtrng-v2.0/ao_pins.h
index 23759444..1997d205 100644
--- a/src/usbtrng-v2.0/ao_pins.h
+++ b/src/usbtrng-v2.0/ao_pins.h
@@ -60,4 +60,8 @@
#define AO_CRC_WIDTH 32
#define AO_CRC_INIT 0xffffffff
+/* TRNG */
+#define AO_LED_TRNG_READ AO_LED_RED
+#define AO_LED_TRNG_WRITE AO_LED_GREEN
+
#endif /* _AO_PINS_H_ */
diff --git a/src/usbtrng-v2.0/ao_usbtrng.c b/src/usbtrng-v2.0/ao_usbtrng.c
index e1f43cdd..42713b6e 100644
--- a/src/usbtrng-v2.0/ao_usbtrng.c
+++ b/src/usbtrng-v2.0/ao_usbtrng.c
@@ -18,58 +18,7 @@
#include <ao.h>
#include <ao_adc_fast.h>
#include <ao_crc.h>
-
-static void
-ao_trng_fetch(void)
-{
- static uint16_t *buffer[2];
- uint32_t kbytes = 1;
- uint32_t count;
- int usb_buf_id;
- int i;
- uint16_t *buf;
- uint32_t *rnd;
-
- if (!buffer[0]) {
- buffer[0] = ao_usb_alloc();
- buffer[1] = ao_usb_alloc();
- if (!buffer[0])
- return;
- }
-
- ao_cmd_decimal();
- if (ao_cmd_status == ao_cmd_success)
- kbytes = ao_cmd_lex_u32;
- else
- ao_cmd_status = ao_cmd_success;
- usb_buf_id = 0;
- count = kbytes * (1024/AO_USB_IN_SIZE);
-
- ao_crc_reset();
-
- ao_led_on(AO_LED_GREEN);
- while (count--) {
- buf = buffer[usb_buf_id];
-// printf ("before get: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush();
- rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */
-// printf ("after get: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush();
- for (i = 0; i < 32; i++)
- *buf++ = ao_crc_in_32_out_16(*rnd++);
- ao_adc_ack(AO_USB_IN_SIZE);
-// printf ("after ack: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush();
- ao_led_toggle(AO_LED_GREEN|AO_LED_RED);
- ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE);
- ao_led_toggle(AO_LED_GREEN|AO_LED_RED);
- usb_buf_id = 1-usb_buf_id;
- }
- ao_led_off(AO_LED_GREEN|AO_LED_RED);
- flush();
-}
-
-static const struct ao_cmds usbtrng_cmds[] = {
- { ao_trng_fetch, "f <kbytes>\0Fetch a block of numbers" },
- { 0, NULL },
-};
+#include <ao_trng.h>
void main(void)
{
@@ -86,7 +35,8 @@ void main(void)
ao_usb_init();
- ao_cmd_register(usbtrng_cmds);
+ ao_trng_init();
+
ao_led_off(AO_LED_RED);
ao_start_scheduler();
diff --git a/src/util/ao-make-product.5c b/src/util/ao-make-product.5c
index 5f2eb8e8..3ab8d16e 100644
--- a/src/util/ao-make-product.5c
+++ b/src/util/ao-make-product.5c
@@ -1,54 +1,58 @@
-#!/bin/sh
+#!/usr/bin/nickle
autoimport ParseArgs;
+file out = stdout;
+
void
write_ucs2(string a, string description)
{
int len = String::length(a);
- printf("/* %s */\n", description);
- printf("#define AO_%s_LEN 0x%02x\n", description, len * 2 + 2);
- printf("#define AO_%s_STRING \"%s\"\n", description, a);
- printf("#define AO_%s_UCS2", description);
+ File::fprintf(out, "/* %s */\n", description);
+ File::fprintf(out, "#define AO_%s_LEN 0x%02x\n", description, len * 2 + 2);
+ File::fprintf(out, "#define AO_%s_STRING \"%s\"\n", description, a);
+ File::fprintf(out, "#define AO_%s_UCS2", description);
for (int i = 0; i < len; i++) {
int c = a[i];
if (i > 0)
- printf(",");
+ File::fprintf(out, ",");
if (0x20 <= c && c < 128)
- printf(" '%c', 0", c);
+ File::fprintf(out, " '%c', 0", c);
else
- printf(" LE_WORD(0x%04x),", c);
+ File::fprintf(out, " LE_WORD(0x%04x),", c);
}
- printf("\n\n");
+ File::fprintf(out, "\n\n");
}
void
write_string(string a, string description)
{
- printf ("/* %s */\n", description);
- printf ("#define AO_%s_STRING \"%s\"\n", description, a);
+ File::fprintf(out, "/* %s */\n", description);
+ File::fprintf(out, "#define AO_%s_STRING \"%s\"\n", description, a);
}
void
write_int(int a, string description)
{
- printf ("/* %s */\n", description);
- printf ("#define AO_%s_NUMBER %d\n\n", description, a);
+ File::fprintf(out, "/* %s */\n", description);
+ File::fprintf(out, "#define AO_%s_NUMBER %d\n\n", description, a);
}
void
write_hex(int a, string description)
{
- printf ("/* %s */\n", description);
- printf ("#define AO_%s_NUMBER 0x%04x\n\n", description, a);
+ File::fprintf(out, "/* %s */\n", description);
+ File::fprintf(out, "#define AO_%s_NUMBER 0x%04x\n\n", description, a);
}
string manufacturer = "altusmetrum.org";
string product = "TeleMetrum";
string version = "0.0";
+string output = "";
int serial = 1;
int user_argind = 0;
+int id_vendor = 0xfffe;
int id_product = 0x000a;
argdesc argd = {
@@ -66,6 +70,12 @@ argdesc argd = {
.expr_name = "prod",
.desc = "Product name." },
{
+ .var = { .arg_int = &id_vendor },
+ .abbr = 'V',
+ .name = "id_vendor",
+ .expr_name = "id_v",
+ .desc = "Vendor ID." },
+ {
.var = { .arg_int = &id_product },
.abbr = 'i',
.name = "id_product",
@@ -83,6 +93,12 @@ argdesc argd = {
.name = "version",
.expr_name = "string",
.desc = "Program version." },
+ {
+ .var = { .arg_string = &output },
+ .abbr = 'o',
+ .name = "output",
+ .expr_name = "out",
+ .desc = "Output file." },
},
.prog_name = "usb descriptors",
};
@@ -92,11 +108,14 @@ main()
{
string[dim(argv)-1] nargv = {[n] = argv[n+1]};
parseargs(&argd, &nargv);
+ if (output != "")
+ out = File::open(output, "w");
write_ucs2(manufacturer, "iManufacturer");
write_ucs2(product, "iProduct");
write_ucs2(sprintf("%06d", serial), "iSerial");
write_int(serial, "iSerial");
write_hex(id_product, "idProduct");
+ write_hex(id_vendor, "idVendor");
write_string(version, "iVersion");
}