summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chaoskey-v1.0/Makefile4
-rw-r--r--src/chaoskey-v1.0/ao_chaoskey.c2
-rw-r--r--src/chaoskey-v1.0/ao_pins.h4
-rw-r--r--src/kernel/ao_flash_readout.c50
-rw-r--r--src/kernel/ao_flash_readout.h20
-rw-r--r--src/kernel/ao_flight.c4
-rw-r--r--src/kernel/ao_product.c14
-rw-r--r--src/kernel/ao_usb.h21
-rw-r--r--src/stmf0/ao_usb_stm.c162
-rw-r--r--src/test/ao_flight_test.c13
-rwxr-xr-xsrc/test/plottest4
11 files changed, 281 insertions, 17 deletions
diff --git a/src/chaoskey-v1.0/Makefile b/src/chaoskey-v1.0/Makefile
index dea5b483..c6cf45bd 100644
--- a/src/chaoskey-v1.0/Makefile
+++ b/src/chaoskey-v1.0/Makefile
@@ -14,6 +14,7 @@ INC = \
ao_task.h \
ao_adc_fast.h \
ao_power.h \
+ ao_flash_readout.h \
ao_crc.h \
stm32f0.h
@@ -34,6 +35,7 @@ ALTOS_SRC = \
ao_boot_chain.c \
ao_usb_stm.c \
ao_trng_send.c \
+ ao_flash_readout.c \
ao_task.c \
ao_power.c \
ao_gpio.c \
@@ -84,7 +86,7 @@ check: $(METAINFO)
distclean: clean
clean:
- rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx
+ rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx *.bin
rm -f ao_product.h
rm -f *.cab
diff --git a/src/chaoskey-v1.0/ao_chaoskey.c b/src/chaoskey-v1.0/ao_chaoskey.c
index c3acd441..1165e454 100644
--- a/src/chaoskey-v1.0/ao_chaoskey.c
+++ b/src/chaoskey-v1.0/ao_chaoskey.c
@@ -20,6 +20,7 @@
#include <ao_adc_fast.h>
#include <ao_crc.h>
#include <ao_trng_send.h>
+#include <ao_flash_readout.h>
void main(void)
{
@@ -30,6 +31,7 @@ void main(void)
ao_dma_init();
ao_adc_init();
ao_crc_init();
+ ao_flash_readout_init();
ao_usb_init();
diff --git a/src/chaoskey-v1.0/ao_pins.h b/src/chaoskey-v1.0/ao_pins.h
index f2c46d8b..22861d9d 100644
--- a/src/chaoskey-v1.0/ao_pins.h
+++ b/src/chaoskey-v1.0/ao_pins.h
@@ -50,6 +50,7 @@
#define AO_USB_HAS_OUT 0
#define AO_USB_HAS_IN 1
#define AO_USB_HAS_IN2 1
+#define AO_USB_HAS_IN3 1
#define AO_USB_HAS_INT 0
#define AO_USB_SELF_POWER 0
#define AO_USB_DEVICE_ID_SERIAL 1
@@ -58,6 +59,9 @@
#define IS_FLASH_LOADER 0
+#define AO_FLASH_READOUT 1
+#define ao_flash_readout_putchar(c) ao_usb_putchar3(c)
+
/* ADC */
#define AO_ADC_PIN0_PORT (&stm_gpioa)
diff --git a/src/kernel/ao_flash_readout.c b/src/kernel/ao_flash_readout.c
new file mode 100644
index 00000000..46b5ba7a
--- /dev/null
+++ b/src/kernel/ao_flash_readout.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2018 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <ao.h>
+#include <ao_usb.h>
+#include <ao_flash_readout.h>
+
+#ifndef AO_FLASH_READOUT_BASE
+#define AO_FLASH_READOUT_BASE AO_BOOT_LOADER_BASE
+#define AO_FLASH_READOUT_BOUND AO_BOOT_APPLICATION_BOUND
+#endif
+
+static void
+ao_flash_readout(void)
+{
+ uint8_t *base = (uint8_t *) AO_FLASH_READOUT_BASE;
+ uint8_t *bound = (uint8_t *) AO_FLASH_READOUT_BOUND;
+ uint8_t *p = base;
+
+ for (;;) {
+ ao_arch_block_interrupts();
+ while (!ao_usb_running) {
+ p = base;
+ ao_sleep(&ao_usb_running);
+ }
+ ao_arch_release_interrupts();
+ ao_flash_readout_putchar(*p++);
+ if (p == bound)
+ p = base;
+ }
+}
+
+static struct ao_task ao_flash_readout_task;
+
+void
+ao_flash_readout_init(void)
+{
+ ao_add_task(&ao_flash_readout_task, ao_flash_readout, "flash_readout");
+}
diff --git a/src/kernel/ao_flash_readout.h b/src/kernel/ao_flash_readout.h
new file mode 100644
index 00000000..5eee53cc
--- /dev/null
+++ b/src/kernel/ao_flash_readout.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright © 2018 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _AO_FLASH_READOUT_H_
+#define _AO_FLASH_READOUT_H_
+
+void ao_flash_readout_init(void);
+
+#endif /* _AO_FLASH_READOUT_H_ */
diff --git a/src/kernel/ao_flight.c b/src/kernel/ao_flight.c
index cb02c454..7b3cb9fa 100644
--- a/src/kernel/ao_flight.c
+++ b/src/kernel/ao_flight.c
@@ -233,7 +233,7 @@ ao_flight(void)
* deceleration, or by waiting until the maximum burn duration
* (15 seconds) has past.
*/
- if ((ao_accel < AO_MSS_TO_ACCEL(-2.5) && ao_height > AO_M_TO_HEIGHT(100)) ||
+ if ((ao_accel < AO_MSS_TO_ACCEL(-2.5)) ||
(int16_t) (ao_sample_tick - ao_boost_tick) > BOOST_TICKS_MAX)
{
#if HAS_ACCEL
@@ -310,7 +310,7 @@ ao_flight(void)
#if HAS_ACCEL
else {
check_re_boost:
- ao_coast_avg_accel = ao_coast_avg_accel - (ao_coast_avg_accel >> 6) + (ao_accel >> 6);
+ ao_coast_avg_accel = ao_coast_avg_accel + ((ao_accel - ao_coast_avg_accel) >> 5);
if (ao_coast_avg_accel > AO_MSS_TO_ACCEL(20)) {
ao_boost_tick = ao_sample_tick;
ao_flight_state = ao_flight_boost;
diff --git a/src/kernel/ao_product.c b/src/kernel/ao_product.c
index c4df9f26..4c2d83ef 100644
--- a/src/kernel/ao_product.c
+++ b/src/kernel/ao_product.c
@@ -55,7 +55,7 @@ const char ao_product[] = AO_iProduct_STRING;
#define HEADER_LEN 9
#define CONTROL_CLASS_LEN 35
-#define DATA_LEN (9 + 7 * AO_USB_HAS_OUT + 7 * AO_USB_HAS_IN + 7 * AO_USB_HAS_IN2)
+#define DATA_LEN (9 + 7 * AO_USB_HAS_OUT + 7 * AO_USB_HAS_IN + 7 * AO_USB_HAS_IN2 + 7 * AO_USB_HAS_IN3)
#define TOTAL_LENGTH (HEADER_LEN + AO_USB_HAS_INT * CONTROL_CLASS_LEN + DATA_LEN)
#define NUM_INTERFACES (AO_USB_HAS_INT + 1)
@@ -141,7 +141,7 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =
AO_USB_DESC_INTERFACE,
AO_USB_HAS_INT, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
- AO_USB_HAS_OUT + AO_USB_HAS_IN + AO_USB_HAS_IN2, /* bNumEndPoints */
+ AO_USB_HAS_OUT + AO_USB_HAS_IN + AO_USB_HAS_IN2 + AO_USB_HAS_IN3, /* bNumEndPoints */
AO_USB_INTERFACE_CLASS_DATA, /* bInterfaceClass = data */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
@@ -177,6 +177,16 @@ AO_ROMCONFIG_SYMBOL(0x00aa) uint8_t ao_usb_descriptors [] =
0x00, /* bInterval */
#endif
+#if AO_USB_HAS_IN3
+ /* Data EP in 3 */
+ 0x07,
+ AO_USB_DESC_ENDPOINT,
+ AO_USB_IN3_EP|0x80, /* bEndpointAddress */
+ 0x02, /* bmAttributes = bulk */
+ LE_WORD(AO_USB_IN_SIZE),/* wMaxPacketSize */
+ 0x00, /* bInterval */
+#endif
+
/* String descriptors */
0x04,
AO_USB_DESC_STRING,
diff --git a/src/kernel/ao_usb.h b/src/kernel/ao_usb.h
index 936d939b..40516de1 100644
--- a/src/kernel/ao_usb.h
+++ b/src/kernel/ao_usb.h
@@ -41,7 +41,23 @@ ao_usb_pollchar(void);
void
ao_usb_flush(void);
+#if AO_USB_HAS_IN2
+void
+ao_usb_flush2(void);
+
+void
+ao_usb_putchar2(char c);
+#endif
+
+#if AO_USB_HAS_IN3
+void
+ao_usb_flush3(void);
+
+void
+ao_usb_putchar3(char c);
+#endif
/* Enable the USB controller */
+
void
ao_usb_enable(void);
@@ -107,6 +123,7 @@ extern __code __at (0x00aa) uint8_t ao_usb_descriptors [];
#define AO_USB_OUT_EP 4
#define AO_USB_IN_EP 5
#define AO_USB_IN2_EP 6
+#define AO_USB_IN3_EP 7
#endif
#ifndef AO_USB_HAS_OUT
@@ -125,6 +142,10 @@ extern __code __at (0x00aa) uint8_t ao_usb_descriptors [];
#define AO_USB_HAS_IN2 0
#endif
+#ifndef AO_USB_HAS_IN3
+#define AO_USB_HAS_IN3 0
+#endif
+
/*
* USB bulk packets can only come in 8, 16, 32 and 64
* byte sizes, so we'll use 64 for everything
diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c
index 483d2419..c4860d8e 100644
--- a/src/stmf0/ao_usb_stm.c
+++ b/src/stmf0/ao_usb_stm.c
@@ -113,6 +113,12 @@ static uint8_t ao_usb_in_tx2_which;
static uint8_t ao_usb_tx2_count;
#endif
+#if AO_USB_HAS_IN3
+static uint16_t ao_usb_in_tx3_offset;
+static uint8_t ao_usb_in_tx3_which;
+static uint8_t ao_usb_tx3_count;
+#endif
+
/*
* End point register indices
*/
@@ -122,6 +128,7 @@ static uint8_t ao_usb_tx2_count;
#define AO_USB_OUT_EPR 2
#define AO_USB_IN_EPR 3
#define AO_USB_IN2_EPR 4
+#define AO_USB_IN3_EPR 5
/* Marks when we don't need to send an IN packet.
* This happens only when the last IN packet is not full,
@@ -146,6 +153,16 @@ static uint16_t in2_count;
static uint8_t ao_usb_in2_flushed;
#endif
+#if AO_USB_HAS_IN3
+/* Marks when we have delivered an IN packet to the hardware
+ * and it has not been received yet. ao_sleep on this address
+ * to wait for it to be delivered.
+ */
+static uint8_t ao_usb_in3_pending;
+static uint16_t in3_count;
+static uint8_t ao_usb_in3_flushed;
+#endif
+
/* Marks when an OUT packet has been received by the hardware
* but not pulled to the shadow buffer.
*/
@@ -423,6 +440,11 @@ ao_usb_alloc_buffers(void)
ao_usb_in_tx2_offset = sram_addr;
sram_addr += AO_USB_IN_SIZE * 2;
#endif
+#if AO_USB_HAS_IN3
+ sram_addr += (sram_addr & 1);
+ ao_usb_in_tx3_offset = sram_addr;
+ sram_addr += AO_USB_IN_SIZE * 2;
+#endif
}
static void
@@ -558,6 +580,25 @@ ao_usb_set_configuration(void)
ao_usb_in_tx2_which = 0;
#endif
+#if AO_USB_HAS_IN3
+ /* Set up the IN3 end point */
+ stm_usb_bdt[AO_USB_IN3_EPR].double_tx[0].addr = ao_usb_in_tx3_offset;
+ stm_usb_bdt[AO_USB_IN3_EPR].double_tx[0].count = 0;
+ stm_usb_bdt[AO_USB_IN3_EPR].double_tx[1].addr = ao_usb_in_tx3_offset + AO_USB_IN_SIZE;
+ stm_usb_bdt[AO_USB_IN3_EPR].double_tx[1].count = 0;
+
+ ao_usb_init_ep(AO_USB_IN3_EPR,
+ AO_USB_IN3_EP,
+ STM_USB_EPR_EP_TYPE_BULK,
+ STM_USB_EPR_STAT_RX_DISABLED,
+ STM_USB_EPR_STAT_TX_NAK,
+ STM_USB_EPR_EP_KIND_DBL_BUF,
+ 0, 1);
+
+ /* First transmit data goes to buffer 0 */
+ ao_usb_in_tx3_which = 0;
+#endif
+
ao_usb_in_flushed = 0;
ao_usb_in_pending = 0;
ao_wakeup(&ao_usb_in_pending);
@@ -567,6 +608,12 @@ ao_usb_set_configuration(void)
ao_wakeup(&ao_usb_in2_pending);
#endif
+#if AO_USB_HAS_IN3
+ ao_usb_in3_flushed = 0;
+ ao_usb_in3_pending = 0;
+ ao_wakeup(&ao_usb_in3_pending);
+#endif
+
ao_usb_out_avail = 0;
ao_usb_configuration = 0;
@@ -996,6 +1043,16 @@ stm_usb_isr(void)
}
break;
#endif
+#if AO_USB_HAS_IN3
+ case AO_USB_IN3_EPR:
+ ++in3_count;
+ _tx_dbg1("TX3 ISR", epr);
+ if (ao_usb_epr_ctr_tx(epr)) {
+ ao_usb_in3_pending = 0;
+ ao_wakeup(&ao_usb_in3_pending);
+ }
+ break;
+#endif
case AO_USB_INT_EPR:
#if USB_STATUS
++int_count;
@@ -1132,6 +1189,9 @@ _ao_usb_in2_send(void)
/* Toggle our usage */
ao_usb_in_tx2_which = 1 - ao_usb_in_tx2_which;
+ /* Toggle the SW_BUF flag */
+ _ao_usb_toggle_dtog(AO_USB_IN2_EPR, 1, 0);
+
/* Mark the outgoing buffer as valid */
_ao_usb_set_stat_tx(AO_USB_IN2_EPR, STM_USB_EPR_STAT_TX_VALID);
@@ -1199,6 +1259,94 @@ ao_usb_putchar2(char c)
}
#endif
+#if AO_USB_HAS_IN3
+/* Queue the current IN buffer for transmission */
+static void
+_ao_usb_in3_send(void)
+{
+ _tx_dbg0("in3_send start");
+ debug ("send3 %d\n", ao_usb_tx3_count);
+ while (ao_usb_in3_pending)
+ ao_sleep(&ao_usb_in3_pending);
+ ao_usb_in3_pending = 1;
+ if (ao_usb_tx3_count != AO_USB_IN_SIZE)
+ ao_usb_in3_flushed = 1;
+ stm_usb_bdt[AO_USB_IN3_EPR].double_tx[ao_usb_in_tx3_which].count = ao_usb_tx3_count;
+ ao_usb_tx3_count = 0;
+
+ /* Toggle our usage */
+ ao_usb_in_tx3_which = 1 - ao_usb_in_tx3_which;
+
+ /* Toggle the SW_BUF flag */
+ _ao_usb_toggle_dtog(AO_USB_IN3_EPR, 1, 0);
+
+ /* Mark the outgoing buffer as valid */
+ _ao_usb_set_stat_tx(AO_USB_IN3_EPR, STM_USB_EPR_STAT_TX_VALID);
+
+ _tx_dbg0("in3_send end");
+}
+
+/* Wait for a free IN buffer. Interrupts are blocked */
+static void
+_ao_usb_in3_wait(void)
+{
+ for (;;) {
+ /* Check if the current buffer is writable */
+ if (ao_usb_tx3_count < AO_USB_IN_SIZE)
+ break;
+
+ _tx_dbg0("in3_wait top");
+ /* Wait for an IN buffer to be ready */
+ while (ao_usb_in3_pending)
+ ao_sleep(&ao_usb_in3_pending);
+ _tx_dbg0("in_wait bottom");
+ }
+}
+
+void
+ao_usb_flush3(void)
+{
+ if (!ao_usb_running)
+ return;
+
+ /* Anytime we've sent a character since
+ * the last time we flushed, we'll need
+ * to send a packet -- the only other time
+ * we would send a packet is when that
+ * packet was full, in which case we now
+ * want to send an empty packet
+ */
+ ao_arch_block_interrupts();
+ while (!ao_usb_in3_flushed) {
+ _tx_dbg0("flush3 top");
+ _ao_usb_in3_send();
+ _tx_dbg0("flush3 end");
+ }
+ ao_arch_release_interrupts();
+}
+
+void
+ao_usb_putchar3(char c)
+{
+ if (!ao_usb_running)
+ return;
+
+ ao_arch_block_interrupts();
+ _ao_usb_in3_wait();
+
+ ao_usb_in3_flushed = 0;
+ ao_usb_tx_byte(ao_usb_in_tx3_offset + AO_USB_IN_SIZE * ao_usb_in_tx3_which + ao_usb_tx3_count++, c);
+
+ /* Send the packet when full */
+ if (ao_usb_tx3_count == AO_USB_IN_SIZE) {
+ _tx_dbg0("putchar3 full");
+ _ao_usb_in3_send();
+ _tx_dbg0("putchar3 flushed");
+ }
+ ao_arch_release_interrupts();
+}
+#endif
+
#if AO_USB_HAS_OUT
static void
_ao_usb_out_recv(void)
@@ -1541,9 +1689,9 @@ struct ao_usb_dbg {
#endif
};
-#define NUM_USB_DBG 128
+#define NUM_USB_DBG 16
-struct ao_usb_dbg dbg[128];
+struct ao_usb_dbg dbg[NUM_USB_DBG];
int dbg_i;
static void _dbg(int line, char *msg, uint32_t value)
@@ -1555,11 +1703,11 @@ static void _dbg(int line, char *msg, uint32_t value)
asm("mrs %0,primask" : "=&r" (primask));
dbg[dbg_i].primask = primask;
#if TX_DBG
- dbg[dbg_i].in_count = in_count;
- dbg[dbg_i].in_epr = stm_usb.epr[AO_USB_IN_EPR];
- dbg[dbg_i].in_pending = ao_usb_in_pending;
- dbg[dbg_i].tx_count = ao_usb_tx_count;
- dbg[dbg_i].in_flushed = ao_usb_in_flushed;
+ dbg[dbg_i].in_count = in3_count;
+ dbg[dbg_i].in_epr = stm_usb.epr[AO_USB_IN3_EPR].r;
+ dbg[dbg_i].in_pending = ao_usb_in3_pending;
+ dbg[dbg_i].tx_count = ao_usb_tx3_count;
+ dbg[dbg_i].in_flushed = ao_usb_in3_flushed;
#endif
#if RX_DBG
dbg[dbg_i].rx_count = ao_usb_rx_count;
diff --git a/src/test/ao_flight_test.c b/src/test/ao_flight_test.c
index 2d862f82..8fe3b5df 100644
--- a/src/test/ao_flight_test.c
+++ b/src/test/ao_flight_test.c
@@ -504,7 +504,7 @@ ao_insert(void)
ao_data_ring[ao_data_head] = ao_data_static;
if (ao_flight_state != ao_flight_startup) {
#if HAS_ACCEL
- double accel = ((ao_flight_ground_accel - ao_data_accel_cook(&ao_data_static)) * GRAVITY * 2.0) /
+ double accel = ((ao_flight_ground_accel - ao_data_accel(&ao_data_static)) * GRAVITY * 2.0) /
(ao_config.accel_minus_g - ao_config.accel_plus_g);
#else
double accel = 0.0;
@@ -515,7 +515,12 @@ ao_insert(void)
tick_offset = -ao_data_static.tick;
if ((prev_tick - ao_data_static.tick) > 0x400)
tick_offset += 65536;
- simple_speed += accel * (ao_data_static.tick - prev_tick) / 100.0;
+ if (prev_tick) {
+ int ticks = ao_data_static.tick - prev_tick;
+ if (ticks < 0)
+ ticks += 65536;
+ simple_speed += accel * ticks / 100.0;
+ }
prev_tick = ao_data_static.tick;
time = (double) (ao_data_static.tick + tick_offset) / 100;
@@ -653,7 +658,7 @@ ao_insert(void)
#if 1
printf("%7.2f height %8.2f accel %8.3f accel_speed %8.3f "
- "state %-8.8s k_height %8.2f k_speed %8.3f k_accel %8.3f avg_height %5d drogue %4d main %4d error %5d"
+ "state %d k_height %8.2f k_speed %8.3f k_accel %8.3f avg_height %5d drogue %4d main %4d error %5d"
#if TELEMEGA
" angle %5d "
"accel_x %8.3f accel_y %8.3f accel_z %8.3f gyro_x %8.3f gyro_y %8.3f gyro_z %8.3f mag_x %8d mag_y %8d, mag_z %8d mag_angle %4d "
@@ -663,7 +668,7 @@ ao_insert(void)
height,
accel,
simple_speed > -100.0 ? simple_speed : -100.0,
- ao_state_names[ao_flight_state],
+ ao_flight_state * 10,
ao_k_height / 65536.0,
ao_k_speed / 65536.0 / 16.0,
ao_k_accel / 65536.0 / 16.0,
diff --git a/src/test/plottest b/src/test/plottest
index 95337f10..e427604a 100755
--- a/src/test/plottest
+++ b/src/test/plottest
@@ -1,4 +1,5 @@
gnuplot -persist << EOF
+set title "$1"
set ylabel "altitude (m)"
set y2label "velocity (m/s), acceleration(m/s²)"
set xlabel "time (s)"
@@ -13,5 +14,6 @@ plot "$1" using 1:3 with lines axes x1y1 title "raw height",\
"$1" using 1:15 with lines axes x1y2 title "accel",\
"$1" using 1:19 with lines axes x1y1 title "drogue",\
"$1" using 1:21 with lines axes x1y1 title "main",\
-"$1" using 1:23 with lines axes x1y1 title "error"
+"$1" using 1:23 with lines axes x1y1 title "error",\
+"$1" using 1:9 with lines axes x1y2 title "state"
EOF