From ed6eb010614b5b27757619fc629d7330fc8c4122 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 17 Jun 2016 10:18:20 -0700 Subject: doc: Add install-html script This script strips the XML-ish bits from html files so that ikiwiki can parse them correctly Signed-off-by: Keith Packard --- doc/install-html | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100755 doc/install-html diff --git a/doc/install-html b/doc/install-html new file mode 100755 index 00000000..71c7933c --- /dev/null +++ b/doc/install-html @@ -0,0 +1,32 @@ +#!/bin/sh +destination= +state=arg +for file in "$@"; do + case $state in + arg) + case $file in + -d) + state=destination + ;; + *) + base=`basename $file` + case "$destination" in + "") + echo "Need -d destination option before files" 1>&2 + exit 1 + ;; + *) + sed \ + -e 's/<[?]xml [^>]*>//' \ + -e 's/]*>//' "$file" > "$destination/$base" + ;; + esac + ;; + esac + ;; + destination) + destination=$file + state=arg + ;; + esac +done -- cgit v1.2.3 From 10fa950cb9fee0ba28adfc5ead108657655bb289 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Wed, 22 Jun 2016 15:01:09 -0600 Subject: switch libgtk-3-bin build-dep to gtk-update-icon-cache, closes: #825455 --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 426fb777..e20a54a2 100644 --- a/debian/control +++ b/debian/control @@ -20,7 +20,7 @@ Build-Depends: asciidoc, icoutils, libbluetooth-dev, libelf-dev, - libgtk-3-bin, + gtk-update-icon-cache, libjfreechart-java, libreadline-dev, librsvg2-bin, -- cgit v1.2.3 From ca59786b5022f592f6516a3ac54708789db14c94 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 20 Jun 2016 10:19:32 -0700 Subject: Bump android version to 13 Need to update the maps API key in the package Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6745b012..38ad58c4 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) AC_INIT([altos], 1.6.4) -ANDROID_VERSION=12 +ANDROID_VERSION=13 AC_CONFIG_SRCDIR([src/kernel/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- cgit v1.2.3 From 3374a9069618658a33af54472d8670e3086af1e0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 24 Jun 2016 12:06:32 -0700 Subject: ao-tools/ao-chaosread: Document length (-l) option Signed-off-by: Keith Packard --- ao-tools/ao-chaosread/ao-chaosread.1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ao-tools/ao-chaosread/ao-chaosread.1 b/ao-tools/ao-chaosread/ao-chaosread.1 index d8ed6cb3..ead8afb2 100644 --- a/ao-tools/ao-chaosread/ao-chaosread.1 +++ b/ao-tools/ao-chaosread/ao-chaosread.1 @@ -29,6 +29,10 @@ reads ADC values from the noise source on the attached ChaosKey device. \-s serial | --serial serial This selects a ChaosKey by serial number instead of using the first one found. +.TP +\-l length | --length length +Set the amount of data to read. Suffixes 'k', 'M' and 'G' are +supported. The default is 1k. .SH USAGE .I ao-chaosread reads noise data. -- cgit v1.2.3 From 6d15cf1580563aea90e9c47f5b268c9c7bb9ba26 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 24 Jun 2016 12:07:36 -0700 Subject: altosdroid: Deal with multiple installed android SDKs Use the latest SDK's zipalign Signed-off-by: Keith Packard --- altosdroid/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altosdroid/Makefile.am b/altosdroid/Makefile.am index 295abbc5..686aeabf 100644 --- a/altosdroid/Makefile.am +++ b/altosdroid/Makefile.am @@ -15,7 +15,7 @@ ADB=$(SDK)/platform-tools/adb AAPT=$(SDK)/platform-tools/aapt APKBUILDER=$(SDK)/tools/apkbuilder ZIPALIGN_A=$(SDK)/tools/zipalign -ZIPALIGN_B=$(SDK)/build-tools/*/zipalign +ZIPALIGN_B=$(shell ls $(SDK)/build-tools/*/zipalign | tail -1) JAVA_SRC_DIR=src/org/altusmetrum/AltosDroid EXT_LIBDIR=libs -- cgit v1.2.3 From 5b7e81628437389014fdd39e323a6f0176e02ba6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 27 Jun 2016 23:28:28 -0700 Subject: Mark testing version 1.6.4.1 Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 38ad58c4..aa6be1d0 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.6.4) +AC_INIT([altos], 1.6.4.1) ANDROID_VERSION=13 AC_CONFIG_SRCDIR([src/kernel/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) -- cgit v1.2.3 From 40abb0d1e2f43a60ffa34b055ebb913ee3e20faf Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 00:07:23 -0700 Subject: altosui: Deliver firmware for Tmega 2.0 and TBT 3.0 for Windows too 1.6.4 added Tmega 2.0 and TBT 3.0 firmware to linux and mac, but neglected windows. Signed-off-by: Keith Packard --- altosui/altos-windows.nsi.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/altosui/altos-windows.nsi.in b/altosui/altos-windows.nsi.in index c88b9e34..c85e2ac8 100644 --- a/altosui/altos-windows.nsi.in +++ b/altosui/altos-windows.nsi.in @@ -129,7 +129,9 @@ Section "Firmware" File "../src/teledongle-v0.2/teledongle-v0.2-${VERSION}.ihx" File "../src/teledongle-v3.0/teledongle-v3.0-${VERSION}.ihx" File "../src/telebt-v1.0/telebt-v1.0-${VERSION}.ihx" + File "../src/telebt-v3.0/telebt-v3.0-${VERSION}.ihx" File "../src/telemega-v1.0/telemega-v1.0-${VERSION}.ihx" + File "../src/telemega-v2.0/telemega-v2.0-${VERSION}.ihx" File "../src/easymini-v1.0/easymini-v1.0-${VERSION}.ihx" File "../src/easymega-v1.0/easymega-v1.0-${VERSION}.ihx" -- cgit v1.2.3 From a7e0bb5eb661cfde31c383d605cb9cb8ca568bc7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 17:04:59 -0700 Subject: altos: Block interrupts while waking tasks sleeping on timers. Interrupts may not be blocked in the timer ISR, but they need to be while walking the pending timer list and moving tasks back to the run queue. Signed-off-by: Keith Packard --- src/kernel/ao.h | 1 + src/kernel/ao_task.c | 15 ++++++++------- src/stm/ao_arch_funcs.h | 8 ++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/kernel/ao.h b/src/kernel/ao.h index 6ed0299e..27a16606 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -73,6 +73,7 @@ typedef AO_PORT_TYPE ao_port_t; #define AO_PANIC_EXTI 16 /* Mis-using exti API */ #define AO_PANIC_FAST_TIMER 17 /* Mis-using fast timer API */ #define AO_PANIC_ADC 18 /* Mis-using ADC interface */ +#define AO_PANIC_IRQ 19 /* interrupts not blocked */ #define AO_PANIC_SELF_TEST_CC1120 0x40 | 1 /* Self test failure */ #define AO_PANIC_SELF_TEST_HMC5883 0x40 | 2 /* Self test failure */ #define AO_PANIC_SELF_TEST_MPU6000 0x40 | 3 /* Self test failure */ diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index e430edc6..03d69caa 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -165,13 +165,14 @@ ao_task_check_alarm(uint16_t tick) { struct ao_task *alarm, *next; - ao_list_for_each_entry_safe(alarm, next, &alarm_queue, struct ao_task, alarm_queue) { - if ((int16_t) (tick - alarm->alarm) < 0) - break; - alarm->alarm = 0; - ao_task_from_alarm_queue(alarm); - ao_task_to_run_queue(alarm); - } + ao_arch_critical( + ao_list_for_each_entry_safe(alarm, next, &alarm_queue, struct ao_task, alarm_queue) { + if ((int16_t) (tick - alarm->alarm) < 0) + break; + alarm->alarm = 0; + ao_task_from_alarm_queue(alarm); + ao_task_to_run_queue(alarm); + }); } void diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 2c017c79..33359857 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -343,6 +343,14 @@ ao_arch_memory_barrier() { asm volatile("" ::: "memory"); } +static inline void +ao_arch_irq_check(void) { + uint32_t primask; + asm("mrs %0,primask" : "=&r" (primask)); + if ((primask & 1) == 0) + ao_panic(AO_PANIC_IRQ); +} + #if HAS_TASK static inline void ao_arch_init_stack(struct ao_task *task, void *start) -- cgit v1.2.3 From 974aaf73cbb720f1b1183cc239001528b6c7a5b9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 17:09:00 -0700 Subject: altos: Move comment in ao_sleep_for next to related code The comment got moved to the wrong place Signed-off-by: Keith Packard --- src/kernel/ao_task.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index 03d69caa..5b8f9356 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -460,11 +460,11 @@ ao_sleep_for(__xdata void *wchan, uint16_t timeout) if (timeout) { #if HAS_TASK_QUEUE uint32_t flags; + flags = ao_arch_irqsave(); +#endif /* 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() + timeout + 1)) ao_cur_task->alarm = 1; #if HAS_TASK_QUEUE -- cgit v1.2.3 From 0dec7d0885970a7d73468dd77220bae78e161b40 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 17:11:38 -0700 Subject: altos/stm: remove ao_dma_abort This function isn't used anywhere. Signed-off-by: Keith Packard --- src/stm/ao_arch_funcs.h | 3 --- src/stm/ao_dma_stm.c | 7 ------- 2 files changed, 10 deletions(-) diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 33359857..25b43587 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -249,9 +249,6 @@ ao_dma_start(uint8_t index); void ao_dma_done_transfer(uint8_t index); -void -ao_dma_abort(uint8_t index); - void ao_dma_alloc(uint8_t index); diff --git a/src/stm/ao_dma_stm.c b/src/stm/ao_dma_stm.c index 8379a1a5..298a15b5 100644 --- a/src/stm/ao_dma_stm.c +++ b/src/stm/ao_dma_stm.c @@ -105,13 +105,6 @@ ao_dma_done_transfer(uint8_t index) ao_mutex_put(&ao_dma_mutex[index]); } -void -ao_dma_abort(uint8_t index) -{ - stm_dma.channel[index].ccr &= ~(1 << STM_DMA_CCR_EN); - ao_wakeup(&ao_dma_done[index]); -} - void ao_dma_alloc(uint8_t index) { -- cgit v1.2.3 From 785d2697376ebd20531d22441a60c41bd927b42a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 17:12:48 -0700 Subject: altos/stm: use 0xff for dma mutex value for allocated mutexes DMA channels which are 'allocated' can't be shared. Instead of using the value '1' in the related 'mutex', use 0xff which won't match any task. Signed-off-by: Keith Packard --- src/stm/ao_dma_stm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stm/ao_dma_stm.c b/src/stm/ao_dma_stm.c index 298a15b5..93b7fb47 100644 --- a/src/stm/ao_dma_stm.c +++ b/src/stm/ao_dma_stm.c @@ -64,7 +64,7 @@ ao_dma_set_transfer(uint8_t index, if (ao_dma_allocated[index]) { if (ao_dma_mutex[index]) ao_panic(AO_PANIC_DMA); - ao_dma_mutex[index] = 1; + ao_dma_mutex[index] = 0xff; } else ao_mutex_get(&ao_dma_mutex[index]); ao_arch_critical( -- cgit v1.2.3 From 21a29c7452398e0cca0fb90f99fa42a2a0684668 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 17:15:27 -0700 Subject: altos/stm: Add more SPI status register bits These weren't the original version of the docs that we had. Signed-off-by: Keith Packard --- src/stm/stm32l.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 0b6b2798..352214ff 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -1359,10 +1359,13 @@ extern struct stm_spi stm_spi1, stm_spi2, stm_spi3; #define STM_SPI_CR2_TXDMAEN 1 #define STM_SPI_CR2_RXDMAEN 0 +#define STM_SPI_SR_FRE 8 #define STM_SPI_SR_BSY 7 #define STM_SPI_SR_OVR 6 #define STM_SPI_SR_MODF 5 #define STM_SPI_SR_CRCERR 4 +#define STM_SPI_SR_UDR 3 +#define STM_SPI_SR_CHSIDE 2 #define STM_SPI_SR_TXE 1 #define STM_SPI_SR_RXNE 0 -- cgit v1.2.3 From 2e60cd22f6789c94343e6432822cedab028dc1ba Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 18:25:44 -0700 Subject: altos/stm: Change ao_spi_send_sync definition to take const source Provides for a bit better error checking. Signed-off-by: Keith Packard --- src/stm/ao_arch_funcs.h | 2 +- src/stm/ao_spi_stm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 25b43587..8393898d 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -80,7 +80,7 @@ void ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index); void -ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index); +ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index); static inline void ao_spi_send_byte(uint8_t byte, uint8_t spi_index) diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 7eaa3924..8ed820eb 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -154,7 +154,7 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index) } void -ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index) +ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index) { uint8_t *b = block; struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; -- cgit v1.2.3 From f418584d4d225827e08f56de86055eb3f074f8d1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 27 Jun 2016 17:26:19 -0700 Subject: altos: Add STM DMA debugging This provides a command that shows current DMA operations when compiled with -DDEBUG=1. Without that, this patch has no effect. Signed-off-by: Keith Packard --- src/stm/ao_dma_stm.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/stm/ao_dma_stm.c b/src/stm/ao_dma_stm.c index 93b7fb47..0135de48 100644 --- a/src/stm/ao_dma_stm.c +++ b/src/stm/ao_dma_stm.c @@ -113,6 +113,40 @@ ao_dma_alloc(uint8_t index) ao_dma_allocated[index] = 1; } +#if DEBUG +void +ao_dma_dump_cmd(void) +{ + int i; + + ao_arch_critical( + if (ao_dma_active++ == 0) + stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_DMA1EN); + ); + printf ("isr %08x ifcr%08x\n", stm_dma.isr, stm_dma.ifcr); + for (i = 0; i < NUM_DMA; i++) + printf("%d: done %d allocated %d mutex %2d ccr %04x cndtr %04x cpar %08x cmar %08x isr %08x\n", + i, + ao_dma_done[i], + ao_dma_allocated[i], + ao_dma_mutex[i], + stm_dma.channel[i].ccr, + stm_dma.channel[i].cndtr, + stm_dma.channel[i].cpar, + stm_dma.channel[i].cmar, + ao_dma_config[i].isr); + ao_arch_critical( + if (--ao_dma_active == 0) + stm_rcc.ahbenr &= ~(1 << STM_RCC_AHBENR_DMA1EN); + ); +} + +static const struct ao_cmds ao_dma_cmds[] = { + { ao_dma_dump_cmd, "D\0Dump DMA status" }, + { 0, NULL } +}; +#endif + void ao_dma_init(void) { @@ -124,5 +158,7 @@ ao_dma_init(void) ao_dma_allocated[index] = 0; ao_dma_mutex[index] = 0; } - +#if DEBUG + ao_cmd_register(&ao_dma_cmds[0]); +#endif } -- cgit v1.2.3 From 69791ef235161fef404f682fd6955e7eed8dc125 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 27 Jun 2016 23:26:20 -0700 Subject: altos: Add STM SPI debugging This dumps out the SPI hardware state and history of SPI operations when compiled with -DDEBUG=1. Without that, this patch does nothing. Signed-off-by: Keith Packard --- src/stm/ao_spi_stm.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 8ed820eb..3b5773b6 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -41,6 +41,49 @@ static const struct ao_spi_stm_info ao_spi_stm_info[STM_NUM_SPI] = { static uint8_t spi_dev_null; +#if DEBUG +static struct { + uint8_t task; + uint8_t which; + AO_TICK_TYPE tick; + uint16_t len; +} spi_tasks[64]; +static uint8_t spi_task_index; + +static void +validate_spi(struct stm_spi *stm_spi, int which, uint16_t len) +{ + uint32_t sr = stm_spi->sr; + + if (stm_spi != &stm_spi2) + return; + spi_tasks[spi_task_index].task = ao_cur_task ? ao_cur_task->task_id : 0; + spi_tasks[spi_task_index].which = which; + spi_tasks[spi_task_index].tick = ao_time(); + spi_tasks[spi_task_index].len = len; + spi_task_index = (spi_task_index + 1) & (63); + if (sr & (1 << STM_SPI_SR_FRE)) + ao_panic(0x40 | 1); + if (sr & (1 << STM_SPI_SR_BSY)) + ao_panic(0x40 | 2); + if (sr & (1 << STM_SPI_SR_OVR)) + ao_panic(0x40 | 3); + if (sr & (1 << STM_SPI_SR_MODF)) + ao_panic(0x40 | 4); + if (sr & (1 << STM_SPI_SR_UDR)) + ao_panic(0x40 | 5); + if ((sr & (1 << STM_SPI_SR_TXE)) == 0) + ao_panic(0x40 | 6); + if (sr & (1 << STM_SPI_SR_RXNE)) + ao_panic(0x40 | 7); + if (which != 5 && which != 6 && which != 13) + if (ao_cur_task->task_id != ao_spi_mutex[1]) + ao_panic(0x40 | 8); +} +#else +#define validate_spi(stm_spi, which, len) do { (void) (which); (void) (len); } while (0) +#endif + void ao_spi_send(const void *block, uint16_t len, uint8_t spi_index) { @@ -460,6 +503,50 @@ ao_spi_channel_init(uint8_t spi_index) (0 << STM_SPI_CR2_RXDMAEN)); } +#if DEBUG +void +ao_spi_dump_cmd(void) +{ + int s; + + for (s = 0; s < 64; s++) { + int i = (spi_task_index + s) & 63; + if (spi_tasks[i].which) { + int t; + const char *name = "(none)"; + for (t = 0; t < ao_num_tasks; t++) + if (ao_tasks[t]->task_id == spi_tasks[i].task) { + name = ao_tasks[t]->name; + break; + } + printf("%2d: %5d task %2d which %2d len %5d %s\n", + s, + spi_tasks[i].tick, + spi_tasks[i].task, + spi_tasks[i].which, + spi_tasks[i].len, + name); + } + } + for (s = 0; s < STM_NUM_SPI; s++) { + struct stm_spi *spi = ao_spi_stm_info[s].stm_spi; + + printf("%1d: mutex %2d index %3d miso dma %3d mosi dma %3d", + s, ao_spi_mutex[s], ao_spi_index[s], + ao_spi_stm_info[s].miso_dma_index, + ao_spi_stm_info[s].mosi_dma_index); + printf(" cr1 %04x cr2 %02x sr %03x\n", + spi->cr1, spi->cr2, spi->sr); + } + +} + +static const struct ao_cmds ao_spi_cmds[] = { + { ao_spi_dump_cmd, "S\0Dump SPI status" }, + { 0, NULL } +}; +#endif + void ao_spi_init(void) { @@ -504,4 +591,7 @@ ao_spi_init(void) ao_spi_index[1] = AO_SPI_CONFIG_NONE; ao_spi_channel_init(1); #endif +#if DEBUG + ao_cmd_register(&ao_spi_cmds[0]); +#endif } -- cgit v1.2.3 From 5ab4a8b911e254dc829b61cb0abc9fd0b46b84b3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 27 Jun 2016 23:25:01 -0700 Subject: altos/stm: move spi execution to common ao_spi_run This regularizes SPI hardware use and ensures that the device is turned off after it has been used and that the status register is back to 'normal' the next time through. Signed-off-by: Keith Packard --- src/stm/ao_spi_stm.c | 198 +++++++++++++++++++++++---------------------------- 1 file changed, 90 insertions(+), 108 deletions(-) diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 3b5773b6..2b6834fd 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -84,12 +84,48 @@ validate_spi(struct stm_spi *stm_spi, int which, uint16_t len) #define validate_spi(stm_spi, which, len) do { (void) (which); (void) (len); } while (0) #endif +static void +ao_spi_run(uint8_t id, uint8_t which, uint16_t len) +{ + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + uint8_t mosi_dma_index = ao_spi_stm_info[id].mosi_dma_index; + uint8_t miso_dma_index = ao_spi_stm_info[id].miso_dma_index; + + validate_spi(stm_spi, which, len); + + stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (1 << STM_SPI_CR2_TXDMAEN) | + (1 << STM_SPI_CR2_RXDMAEN)); + + ao_dma_start(miso_dma_index); + ao_dma_start(mosi_dma_index); + + ao_arch_critical( + while (!ao_dma_done[miso_dma_index]) + ao_sleep(&ao_dma_done[miso_dma_index]); + ); + + while ((stm_spi->sr & (1 << STM_SPI_SR_TXE)) == 0); + while (stm_spi->sr & (1 << STM_SPI_SR_BSY)); + + validate_spi(stm_spi, which+1, len); + + stm_spi->cr2 = 0; + + ao_dma_done_transfer(mosi_dma_index); + ao_dma_done_transfer(miso_dma_index); +} + void ao_spi_send(const void *block, uint16_t len, uint8_t spi_index) { - struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; - uint8_t mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; - uint8_t miso_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].miso_dma_index; + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + uint8_t mosi_dma_index = ao_spi_stm_info[id].mosi_dma_index; + uint8_t miso_dma_index = ao_spi_stm_info[id].miso_dma_index; /* Set up the transmit DMA to deliver data */ ao_dma_set_transfer(mosi_dma_index, @@ -105,9 +141,6 @@ ao_spi_send(const void *block, uint16_t len, uint8_t spi_index) (0 << STM_DMA_CCR_CIRC) | (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); - /* Clear RXNE */ - (void) stm_spi->dr; - /* Set up the receive DMA -- when this is done, we know the SPI unit * is idle. Without this, we'd have to poll waiting for the BSY bit to * be cleared @@ -124,28 +157,17 @@ ao_spi_send(const void *block, uint16_t len, uint8_t spi_index) (0 << STM_DMA_CCR_PINC) | (0 << STM_DMA_CCR_CIRC) | (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); - stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | - (0 << STM_SPI_CR2_RXNEIE) | - (0 << STM_SPI_CR2_ERRIE) | - (0 << STM_SPI_CR2_SSOE) | - (1 << STM_SPI_CR2_TXDMAEN) | - (1 << STM_SPI_CR2_RXDMAEN)); - ao_dma_start(miso_dma_index); - ao_dma_start(mosi_dma_index); - ao_arch_critical( - while (!ao_dma_done[miso_dma_index]) - ao_sleep(&ao_dma_done[miso_dma_index]); - ); - ao_dma_done_transfer(mosi_dma_index); - ao_dma_done_transfer(miso_dma_index); + + ao_spi_run(id, 1, len); } void ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index) { - struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; - uint8_t mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; - uint8_t miso_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].miso_dma_index; + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + uint8_t mosi_dma_index = ao_spi_stm_info[id].mosi_dma_index; + uint8_t miso_dma_index = ao_spi_stm_info[id].miso_dma_index; /* Set up the transmit DMA to deliver data */ ao_dma_set_transfer(mosi_dma_index, @@ -161,9 +183,6 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index) (0 << STM_DMA_CCR_CIRC) | (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); - /* Clear RXNE */ - (void) stm_spi->dr; - /* Set up the receive DMA -- when this is done, we know the SPI unit * is idle. Without this, we'd have to poll waiting for the BSY bit to * be cleared @@ -180,27 +199,16 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index) (0 << STM_DMA_CCR_PINC) | (0 << STM_DMA_CCR_CIRC) | (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); - stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | - (0 << STM_SPI_CR2_RXNEIE) | - (0 << STM_SPI_CR2_ERRIE) | - (0 << STM_SPI_CR2_SSOE) | - (1 << STM_SPI_CR2_TXDMAEN) | - (1 << STM_SPI_CR2_RXDMAEN)); - ao_dma_start(miso_dma_index); - ao_dma_start(mosi_dma_index); - ao_arch_critical( - while (!ao_dma_done[miso_dma_index]) - ao_sleep(&ao_dma_done[miso_dma_index]); - ); - ao_dma_done_transfer(mosi_dma_index); - ao_dma_done_transfer(miso_dma_index); + + ao_spi_run(id, 3, len); } void ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index) { - uint8_t *b = block; - struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; + uint8_t id = AO_SPI_INDEX(spi_index); + const uint8_t *b = block; + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | (0 << STM_SPI_CR2_RXNEIE) | @@ -208,22 +216,28 @@ ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index) (0 << STM_SPI_CR2_SSOE) | (0 << STM_SPI_CR2_TXDMAEN) | (0 << STM_SPI_CR2_RXDMAEN)); - - /* Clear RXNE */ - (void) stm_spi->dr; - + validate_spi(stm_spi, 7, len); while (len--) { while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))); stm_spi->dr = *b++; } + while ((stm_spi->sr & (1 << STM_SPI_SR_TXE)) == 0) + ; + while (stm_spi->sr & (1 << STM_SPI_SR_BSY)) + ; + /* Clear the OVR flag */ + (void) stm_spi->dr; + (void) stm_spi->sr; + validate_spi(stm_spi, 8, len); } void ao_spi_recv(void *block, uint16_t len, uint8_t spi_index) { - struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; - uint8_t mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; - uint8_t miso_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].miso_dma_index; + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + uint8_t mosi_dma_index = ao_spi_stm_info[id].mosi_dma_index; + uint8_t miso_dma_index = ao_spi_stm_info[id].miso_dma_index; spi_dev_null = 0xff; @@ -241,9 +255,6 @@ ao_spi_recv(void *block, uint16_t len, uint8_t spi_index) (0 << STM_DMA_CCR_CIRC) | (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); - /* Clear RXNE */ - (void) stm_spi->dr; - /* Set up the receive DMA to capture data */ ao_dma_set_transfer(miso_dma_index, &stm_spi->dr, @@ -258,31 +269,16 @@ ao_spi_recv(void *block, uint16_t len, uint8_t spi_index) (0 << STM_DMA_CCR_CIRC) | (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); - stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | - (0 << STM_SPI_CR2_RXNEIE) | - (0 << STM_SPI_CR2_ERRIE) | - (0 << STM_SPI_CR2_SSOE) | - (1 << STM_SPI_CR2_TXDMAEN) | - (1 << STM_SPI_CR2_RXDMAEN)); - ao_dma_start(miso_dma_index); - ao_dma_start(mosi_dma_index); - - /* Wait until the SPI unit is done */ - ao_arch_critical( - while (!ao_dma_done[miso_dma_index]) - ao_sleep(&ao_dma_done[miso_dma_index]); - ); - - ao_dma_done_transfer(mosi_dma_index); - ao_dma_done_transfer(miso_dma_index); + ao_spi_run(id, 9, len); } void ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index) { - struct stm_spi *stm_spi = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].stm_spi; - uint8_t mosi_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].mosi_dma_index; - uint8_t miso_dma_index = ao_spi_stm_info[AO_SPI_INDEX(spi_index)].miso_dma_index; + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + uint8_t mosi_dma_index = ao_spi_stm_info[id].mosi_dma_index; + uint8_t miso_dma_index = ao_spi_stm_info[id].miso_dma_index; /* Set up transmit DMA to send data */ ao_dma_set_transfer(mosi_dma_index, @@ -298,9 +294,6 @@ ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index) (0 << STM_DMA_CCR_CIRC) | (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR)); - /* Clear RXNE */ - (void) stm_spi->dr; - /* Set up the receive DMA to capture data */ ao_dma_set_transfer(miso_dma_index, &stm_spi->dr, @@ -314,24 +307,7 @@ ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index) (0 << STM_DMA_CCR_PINC) | (0 << STM_DMA_CCR_CIRC) | (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR)); - - stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | - (0 << STM_SPI_CR2_RXNEIE) | - (0 << STM_SPI_CR2_ERRIE) | - (0 << STM_SPI_CR2_SSOE) | - (1 << STM_SPI_CR2_TXDMAEN) | - (1 << STM_SPI_CR2_RXDMAEN)); - ao_dma_start(miso_dma_index); - ao_dma_start(mosi_dma_index); - - /* Wait until the SPI unit is done */ - ao_arch_critical( - while (!ao_dma_done[miso_dma_index]) - ao_sleep(&ao_dma_done[miso_dma_index]); - ); - - ao_dma_done_transfer(mosi_dma_index); - ao_dma_done_transfer(miso_dma_index); + ao_spi_run(id, 11, len); } static void @@ -426,20 +402,7 @@ ao_spi_config(uint8_t spi_index, uint32_t speed) { uint8_t id = AO_SPI_INDEX(spi_index); struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; - stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) | /* Three wire mode */ - (0 << STM_SPI_CR1_BIDIOE) | - (0 << STM_SPI_CR1_CRCEN) | /* CRC disabled */ - (0 << STM_SPI_CR1_CRCNEXT) | - (0 << STM_SPI_CR1_DFF) | - (0 << STM_SPI_CR1_RXONLY) | - (1 << STM_SPI_CR1_SSM) | /* Software SS handling */ - (1 << STM_SPI_CR1_SSI) | /* ... */ - (0 << STM_SPI_CR1_LSBFIRST) | /* Big endian */ - (1 << STM_SPI_CR1_SPE) | /* Enable SPI unit */ - (speed << STM_SPI_CR1_BR) | /* baud rate to pclk/4 */ - (1 << STM_SPI_CR1_MSTR) | - (0 << STM_SPI_CR1_CPOL) | /* Format 0 */ - (0 << STM_SPI_CR1_CPHA)); + if (spi_index != ao_spi_index[id]) { /* Disable old config @@ -454,6 +417,21 @@ ao_spi_config(uint8_t spi_index, uint32_t speed) */ ao_spi_index[id] = spi_index; } + stm_spi->cr1 = ((0 << STM_SPI_CR1_BIDIMODE) | /* Three wire mode */ + (0 << STM_SPI_CR1_BIDIOE) | + (0 << STM_SPI_CR1_CRCEN) | /* CRC disabled */ + (0 << STM_SPI_CR1_CRCNEXT) | + (0 << STM_SPI_CR1_DFF) | + (0 << STM_SPI_CR1_RXONLY) | + (1 << STM_SPI_CR1_SSM) | /* Software SS handling */ + (1 << STM_SPI_CR1_SSI) | /* ... */ + (0 << STM_SPI_CR1_LSBFIRST) | /* Big endian */ + (1 << STM_SPI_CR1_SPE) | /* Enable SPI unit */ + (speed << STM_SPI_CR1_BR) | /* baud rate to pclk/4 */ + (1 << STM_SPI_CR1_MSTR) | + (0 << STM_SPI_CR1_CPOL) | /* Format 0 */ + (0 << STM_SPI_CR1_CPHA)); + validate_spi(stm_spi, 13, 0); } uint8_t @@ -471,6 +449,7 @@ void ao_spi_get(uint8_t spi_index, uint32_t speed) { uint8_t id = AO_SPI_INDEX(spi_index); + ao_mutex_get(&ao_spi_mutex[id]); ao_spi_config(spi_index, speed); } @@ -494,13 +473,16 @@ ao_spi_channel_init(uint8_t spi_index) ao_spi_disable_index(spi_index); stm_spi->cr1 = 0; - (void) stm_spi->sr; stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | (0 << STM_SPI_CR2_RXNEIE) | (0 << STM_SPI_CR2_ERRIE) | (0 << STM_SPI_CR2_SSOE) | (0 << STM_SPI_CR2_TXDMAEN) | (0 << STM_SPI_CR2_RXDMAEN)); + + /* Clear any pending data and error flags */ + (void) stm_spi->dr; + (void) stm_spi->sr; } #if DEBUG -- cgit v1.2.3 From 5866d191cee56949ccab4c154a14604e83163d42 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 18:37:49 -0700 Subject: altos/stm: Clean up spi_enable/disable_index functions These had an extra level of switch nesting for no good reason. Signed-off-by: Keith Packard --- src/stm/ao_spi_stm.c | 124 +++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 69 deletions(-) diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index 2b6834fd..e69c2d7b 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -315,44 +315,36 @@ ao_spi_disable_index(uint8_t spi_index) { /* Disable current config */ - switch (AO_SPI_INDEX(spi_index)) { - case STM_SPI_INDEX(1): - switch (spi_index) { - case AO_SPI_1_PA5_PA6_PA7: - stm_gpio_set(&stm_gpioa, 5, 1); - stm_moder_set(&stm_gpioa, 5, STM_MODER_OUTPUT); - stm_moder_set(&stm_gpioa, 6, STM_MODER_INPUT); - stm_moder_set(&stm_gpioa, 7, STM_MODER_OUTPUT); - break; - case AO_SPI_1_PB3_PB4_PB5: - stm_gpio_set(&stm_gpiob, 3, 1); - stm_moder_set(&stm_gpiob, 3, STM_MODER_OUTPUT); - stm_moder_set(&stm_gpiob, 4, STM_MODER_INPUT); - stm_moder_set(&stm_gpiob, 5, STM_MODER_OUTPUT); - break; - case AO_SPI_1_PE13_PE14_PE15: - stm_gpio_set(&stm_gpioe, 13, 1); - stm_moder_set(&stm_gpioe, 13, STM_MODER_OUTPUT); - stm_moder_set(&stm_gpioe, 14, STM_MODER_INPUT); - stm_moder_set(&stm_gpioe, 15, STM_MODER_OUTPUT); - break; - } + switch (spi_index) { + case AO_SPI_1_PA5_PA6_PA7: + stm_gpio_set(&stm_gpioa, 5, 1); + stm_moder_set(&stm_gpioa, 5, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpioa, 6, STM_MODER_INPUT); + stm_moder_set(&stm_gpioa, 7, STM_MODER_OUTPUT); break; - case STM_SPI_INDEX(2): - switch (spi_index) { - case AO_SPI_2_PB13_PB14_PB15: - stm_gpio_set(&stm_gpiob, 13, 1); - stm_moder_set(&stm_gpiob, 13, STM_MODER_OUTPUT); - stm_moder_set(&stm_gpiob, 14, STM_MODER_INPUT); - stm_moder_set(&stm_gpiob, 15, STM_MODER_OUTPUT); - break; - case AO_SPI_2_PD1_PD3_PD4: - stm_gpio_set(&stm_gpiod, 1, 1); - stm_moder_set(&stm_gpiod, 1, STM_MODER_OUTPUT); - stm_moder_set(&stm_gpiod, 3, STM_MODER_INPUT); - stm_moder_set(&stm_gpiod, 4, STM_MODER_OUTPUT); - break; - } + case AO_SPI_1_PB3_PB4_PB5: + stm_gpio_set(&stm_gpiob, 3, 1); + stm_moder_set(&stm_gpiob, 3, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpiob, 4, STM_MODER_INPUT); + stm_moder_set(&stm_gpiob, 5, STM_MODER_OUTPUT); + break; + case AO_SPI_1_PE13_PE14_PE15: + stm_gpio_set(&stm_gpioe, 13, 1); + stm_moder_set(&stm_gpioe, 13, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpioe, 14, STM_MODER_INPUT); + stm_moder_set(&stm_gpioe, 15, STM_MODER_OUTPUT); + break; + case AO_SPI_2_PB13_PB14_PB15: + stm_gpio_set(&stm_gpiob, 13, 1); + stm_moder_set(&stm_gpiob, 13, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpiob, 14, STM_MODER_INPUT); + stm_moder_set(&stm_gpiob, 15, STM_MODER_OUTPUT); + break; + case AO_SPI_2_PD1_PD3_PD4: + stm_gpio_set(&stm_gpiod, 1, 1); + stm_moder_set(&stm_gpiod, 1, STM_MODER_OUTPUT); + stm_moder_set(&stm_gpiod, 3, STM_MODER_INPUT); + stm_moder_set(&stm_gpiod, 4, STM_MODER_OUTPUT); break; } } @@ -360,39 +352,33 @@ ao_spi_disable_index(uint8_t spi_index) static void ao_spi_enable_index(uint8_t spi_index) { - switch (AO_SPI_INDEX(spi_index)) { - case STM_SPI_INDEX(1): - switch (spi_index) { - case AO_SPI_1_PA5_PA6_PA7: - stm_afr_set(&stm_gpioa, 5, STM_AFR_AF5); - stm_afr_set(&stm_gpioa, 6, STM_AFR_AF5); - stm_afr_set(&stm_gpioa, 7, STM_AFR_AF5); - break; - case AO_SPI_1_PB3_PB4_PB5: - stm_afr_set(&stm_gpiob, 3, STM_AFR_AF5); - stm_afr_set(&stm_gpiob, 4, STM_AFR_AF5); - stm_afr_set(&stm_gpiob, 5, STM_AFR_AF5); - break; - case AO_SPI_1_PE13_PE14_PE15: - stm_afr_set(&stm_gpioe, 13, STM_AFR_AF5); - stm_afr_set(&stm_gpioe, 14, STM_AFR_AF5); - stm_afr_set(&stm_gpioe, 15, STM_AFR_AF5); - break; - } + /* Enable new config + */ + switch (spi_index) { + case AO_SPI_1_PA5_PA6_PA7: + stm_afr_set(&stm_gpioa, 5, STM_AFR_AF5); + stm_afr_set(&stm_gpioa, 6, STM_AFR_AF5); + stm_afr_set(&stm_gpioa, 7, STM_AFR_AF5); break; - case STM_SPI_INDEX(2): - switch (spi_index) { - case AO_SPI_2_PB13_PB14_PB15: - stm_afr_set(&stm_gpiob, 13, STM_AFR_AF5); - stm_afr_set(&stm_gpiob, 14, STM_AFR_AF5); - stm_afr_set(&stm_gpiob, 15, STM_AFR_AF5); - break; - case AO_SPI_2_PD1_PD3_PD4: - stm_afr_set(&stm_gpiod, 1, STM_AFR_AF5); - stm_afr_set(&stm_gpiod, 3, STM_AFR_AF5); - stm_afr_set(&stm_gpiod, 4, STM_AFR_AF5); - break; - } + case AO_SPI_1_PB3_PB4_PB5: + stm_afr_set(&stm_gpiob, 3, STM_AFR_AF5); + stm_afr_set(&stm_gpiob, 4, STM_AFR_AF5); + stm_afr_set(&stm_gpiob, 5, STM_AFR_AF5); + break; + case AO_SPI_1_PE13_PE14_PE15: + stm_afr_set(&stm_gpioe, 13, STM_AFR_AF5); + stm_afr_set(&stm_gpioe, 14, STM_AFR_AF5); + stm_afr_set(&stm_gpioe, 15, STM_AFR_AF5); + break; + case AO_SPI_2_PB13_PB14_PB15: + stm_afr_set(&stm_gpiob, 13, STM_AFR_AF5); + stm_afr_set(&stm_gpiob, 14, STM_AFR_AF5); + stm_afr_set(&stm_gpiob, 15, STM_AFR_AF5); + break; + case AO_SPI_2_PD1_PD3_PD4: + stm_afr_set(&stm_gpiod, 1, STM_AFR_AF5); + stm_afr_set(&stm_gpiod, 3, STM_AFR_AF5); + stm_afr_set(&stm_gpiod, 4, STM_AFR_AF5); break; } } -- cgit v1.2.3 From 61ad8e5bf428246ac89cad7cb9a1edf2ef735fd5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 18:39:31 -0700 Subject: altos/stm: Add better byte-level SPI api This provides inline functions for sending and receiving individual bytes, and setup/finish functions to wrap them in. This make the byte sending respect the SPI hardware interface requirements. Signed-off-by: Keith Packard --- src/stm/ao_arch_funcs.h | 42 ++++++++++++++++++++++++++++++++---------- src/stm/ao_spi_stm.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 8393898d..a796891d 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -82,6 +82,12 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index); void ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index); +void +ao_spi_start_bytes(uint8_t spi_index); + +void +ao_spi_stop_bytes(uint8_t spi_index); + static inline void ao_spi_send_byte(uint8_t byte, uint8_t spi_index) { @@ -96,18 +102,34 @@ ao_spi_send_byte(uint8_t byte, uint8_t spi_index) break; } - stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | - (0 << STM_SPI_CR2_RXNEIE) | - (0 << STM_SPI_CR2_ERRIE) | - (0 << STM_SPI_CR2_SSOE) | - (0 << STM_SPI_CR2_TXDMAEN) | - (0 << STM_SPI_CR2_RXDMAEN)); - - /* Clear RXNE */ + while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))) + ; + stm_spi->dr = byte; + while (!(stm_spi->sr & (1 << STM_SPI_SR_RXNE))) + ; (void) stm_spi->dr; +} - while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))); - stm_spi->dr = byte; +static inline uint8_t +ao_spi_recv_byte(uint8_t spi_index) +{ + struct stm_spi *stm_spi; + + switch (AO_SPI_INDEX(spi_index)) { + case 0: + stm_spi = &stm_spi1; + break; + case 1: + stm_spi = &stm_spi2; + break; + } + + while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))) + ; + stm_spi->dr = 0xff; + while (!(stm_spi->sr & (1 << STM_SPI_SR_RXNE))) + ; + return stm_spi->dr; } void diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index e69c2d7b..214092f6 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -203,6 +203,38 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index) ao_spi_run(id, 3, len); } +void +ao_spi_start_bytes(uint8_t spi_index) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + + stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (0 << STM_SPI_CR2_TXDMAEN) | + (0 << STM_SPI_CR2_RXDMAEN)); + validate_spi(stm_spi, 5, 0xffff); +} + +void +ao_spi_stop_bytes(uint8_t spi_index) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + + while ((stm_spi->sr & (1 << STM_SPI_SR_TXE)) == 0) + ; + while (stm_spi->sr & (1 << STM_SPI_SR_BSY)) + ; + /* Clear the OVR flag */ + (void) stm_spi->dr; + (void) stm_spi->sr; + validate_spi(stm_spi, 6, 0xffff); + stm_spi->cr2 = 0; +} + void ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index) { -- cgit v1.2.3 From 30eb5d2fa77e036690170e7057fa9df669375ae5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 18:40:46 -0700 Subject: altos/drivers: Use more reliable byte interface for CC1120 reception This replaces direct register access with function calls to allow that code to respect the hardware requirements. Signed-off-by: Keith Packard --- src/drivers/ao_cc1120.c | 35 +++++++++++++++-------------------- src/telemega-v1.0/ao_pins.h | 1 - 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index 5b814667..eb7d872b 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -44,7 +44,10 @@ extern const uint32_t ao_radio_cal; #define ao_radio_try_select(task_id) ao_spi_try_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz, task_id) #define ao_radio_select() ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS,AO_SPI_SPEED_4MHz) #define ao_radio_deselect() ao_spi_put_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS) -#define ao_radio_spi_send_sync(d,l) ao_spi_send_sync((d), (l), AO_CC1120_SPI_BUS) +#define ao_radio_spi_start_bytes() ao_spi_start_bytes(AO_CC1120_SPI_BUS) +#define ao_radio_spi_stop_bytes() ao_spi_stop_bytes(AO_CC1120_SPI_BUS) +#define ao_radio_spi_send_byte(b) ao_spi_send_byte(b, AO_CC1120_SPI_BUS) +#define ao_radio_spi_recv_byte() ao_spi_recv_byte(AO_CC1120_SPI_BUS) #define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1120_SPI_BUS) #define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1120_SPI_BUS) #define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1120_SPI_BUS) @@ -111,28 +114,23 @@ ao_radio_reg_write(uint16_t addr, uint8_t value) static void _ao_radio_burst_read_start (uint16_t addr) { - uint8_t data[2]; - uint8_t d; + ao_radio_spi_start_bytes(); if (CC1120_IS_EXTENDED(addr)) { - data[0] = ((1 << CC1120_READ) | - (1 << CC1120_BURST) | - CC1120_EXTENDED); - data[1] = addr; - d = 2; + ao_radio_spi_send_byte((1 << CC1120_READ) | + (1 << CC1120_BURST) | + CC1120_EXTENDED); } else { - data[0] = ((1 << CC1120_READ) | - (1 << CC1120_BURST) | - addr); - d = 1; + addr |= ((1 << CC1120_READ) | + (1 << CC1120_BURST)); } - - ao_radio_spi_send_sync(data, d); + ao_radio_spi_send_byte(addr); } static void ao_radio_burst_read_stop (void) { + ao_radio_spi_stop_bytes(); ao_radio_deselect(); } @@ -1029,8 +1027,7 @@ ao_radio_rx_isr(void) rx_starting = 0; ao_wakeup(&ao_radio_wake); } - d = AO_CC1120_SPI.dr; - AO_CC1120_SPI.dr = 0; + d = ao_radio_spi_recv_byte(); if (rx_ignore == 0) { if (rx_data_cur < rx_data_count) rx_data[rx_data_cur++] = d; @@ -1099,7 +1096,7 @@ ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) rx_data_count = len * 8; /* bytes to bits */ rx_data_cur = 0; rx_data_consumed = 0; - rx_ignore = 2; + rx_ignore = 1; /* Must be set before changing the frequency; any abort * after the frequency is set needs to terminate the read @@ -1149,9 +1146,7 @@ ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) ao_radio_select(); _ao_radio_burst_read_start(CC1120_SOFT_RX_DATA_OUT); if (rx_ignore) { - uint8_t ignore = AO_CC1120_SPI.dr; - (void) ignore; - AO_CC1120_SPI.dr = 0; + (void) ao_radio_spi_recv_byte(); --rx_ignore; } } diff --git a/src/telemega-v1.0/ao_pins.h b/src/telemega-v1.0/ao_pins.h index b81e59a9..58b4d61a 100644 --- a/src/telemega-v1.0/ao_pins.h +++ b/src/telemega-v1.0/ao_pins.h @@ -307,7 +307,6 @@ struct ao_adc { #define AO_CC1120_SPI_CS_PORT (&stm_gpioc) #define AO_CC1120_SPI_CS_PIN 5 #define AO_CC1120_SPI_BUS AO_SPI_2_PB13_PB14_PB15 -#define AO_CC1120_SPI stm_spi2 #define AO_CC1120_INT_PORT (&stm_gpioe) #define AO_CC1120_INT_PIN 1 -- cgit v1.2.3 From 658d8be170f9aea683fe62b68368736a177411a5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Jun 2016 17:03:34 -0700 Subject: altos: Add debug check for irq block when editing task queues List manipulation operations are not atomic, so interrupts need to be blocked while changing them. Signed-off-by: Keith Packard --- src/kernel/ao_task.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index 5b8f9356..47352fc1 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -54,6 +54,12 @@ static inline void ao_check_stack(void) { #define ao_check_stack() #endif +#if DEBUG +#define ao_task_irq_check() ao_arch_irq_check() +#else +#define ao_task_irq_check() +#endif + #if HAS_TASK_QUEUE #define SLEEP_HASH_SIZE 17 @@ -65,6 +71,7 @@ static struct ao_list sleep_queue[SLEEP_HASH_SIZE]; static void ao_task_to_run_queue(struct ao_task *task) { + ao_task_irq_check(); ao_list_del(&task->queue); ao_list_append(&task->queue, &run_queue); } @@ -78,6 +85,7 @@ ao_task_sleep_queue(void *wchan) static void ao_task_to_sleep_queue(struct ao_task *task, void *wchan) { + ao_task_irq_check(); ao_list_del(&task->queue); ao_list_append(&task->queue, ao_task_sleep_queue(wchan)); } @@ -122,6 +130,7 @@ static void ao_task_to_alarm_queue(struct ao_task *task) { struct ao_task *alarm; + ao_task_irq_check(); ao_list_for_each_entry(alarm, &alarm_queue, struct ao_task, alarm_queue) { if ((int16_t) (alarm->alarm - task->alarm) >= 0) { ao_list_insert(&task->alarm_queue, alarm->alarm_queue.prev); @@ -138,6 +147,7 @@ ao_task_to_alarm_queue(struct ao_task *task) static void ao_task_from_alarm_queue(struct ao_task *task) { + ao_task_irq_check(); ao_list_del(&task->alarm_queue); if (ao_list_is_empty(&alarm_queue)) ao_task_alarm_tick = 0; @@ -156,6 +166,7 @@ ao_task_init_queue(struct ao_task *task) static void ao_task_exit_queue(struct ao_task *task) { + ao_task_irq_check(); ao_list_del(&task->queue); ao_list_del(&task->alarm_queue); } -- cgit v1.2.3 From 3b3a24f5f39a1b72cc8947c33b609f454b46aff8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 Jun 2016 12:49:16 -0700 Subject: altos: cc1200: use FIFO threshold pin output for APRS buffering Instead of polling the device for fifo space, just use the available pin configuration to figure out if there is enough space for a single APRS buffer. Then set the APRS buffer size to match the fifo threshold setting in the chip so that we know we can write the whole APRS buffer once the pin says there's space. Signed-off-by: Keith Packard --- src/drivers/ao_cc1200.c | 105 ++++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 74 deletions(-) diff --git a/src/drivers/ao_cc1200.c b/src/drivers/ao_cc1200.c index 6bccb188..cd85f208 100644 --- a/src/drivers/ao_cc1200.c +++ b/src/drivers/ao_cc1200.c @@ -185,9 +185,9 @@ ao_radio_fifo_write_fixed(uint8_t data, uint8_t len) } static uint8_t -ao_radio_tx_fifo_space(void) +ao_radio_int_pin(void) { - return CC1200_FIFO_SIZE - ao_radio_reg_read(CC1200_NUM_TXBYTES); + return ao_gpio_get(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN, AO_CC1200_INT); } static uint8_t @@ -482,6 +482,7 @@ static const uint16_t rdf_setup[] = { */ #define APRS_SYMBOL_RATE_E 6 #define APRS_SYMBOL_RATE_M 1013008 +#define APRS_BUFFER_SIZE 64 static const uint16_t aprs_setup[] = { CC1200_DEVIATION_M, APRS_DEV_M, @@ -516,6 +517,9 @@ static const uint16_t aprs_setup[] = { (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_FIFO_CFG, + ((0 << CC1200_FIFO_CFG_CRC_AUTOFLUSH) | + (APRS_BUFFER_SIZE << CC1200_FIFO_CFG_FIFO_THR)), }; /* @@ -861,105 +865,58 @@ ao_radio_send(const void *d, uint8_t size) ao_radio_run(); } - -#define AO_RADIO_LOTS 64 - void ao_radio_send_aprs(ao_radio_fill_func fill) { - uint8_t buf[AO_RADIO_LOTS], *b; + uint8_t buf[APRS_BUFFER_SIZE]; int cnt; int total = 0; uint8_t done = 0; uint8_t started = 0; - uint8_t fifo_space; ao_radio_abort = 0; ao_radio_get(0xff); - fifo_space = CC1200_FIFO_SIZE; - while (!done) { + ao_radio_wake = 0; + while (!done && !ao_radio_abort) { cnt = (*fill)(buf, sizeof(buf)); if (cnt < 0) { done = 1; cnt = -cnt; } -#if CC1200_APRS_TRACE - printf("APRS fill %d bytes done %d\n", cnt, done); -#endif total += cnt; /* At the last buffer, set the total length */ if (done) ao_radio_set_len(total & 0xff); - b = buf; - while (cnt) { - uint8_t this_len = cnt; - - /* Wait for some space in the fifo */ - while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) { -#if CC1200_APRS_TRACE - printf("APRS space %d cnt %d\n", fifo_space, cnt); flush(); -#endif - ao_radio_wake = 0; - ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); - } - if (ao_radio_abort) - break; - if (this_len > fifo_space) - this_len = fifo_space; - - cnt -= this_len; - - if (done) { - if (cnt) - ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF); - else - ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH); - } else - ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF); - + /* Wait for some space in the fifo */ + while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) { + ao_radio_wake = 0; ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); - - ao_radio_fifo_write(b, this_len); - b += this_len; -#if CC1200_APRS_TRACE - printf("APRS write fifo %d space now %d\n", this_len, ao_radio_tx_fifo_space()); -#endif - if (!started) { -#if CC1200_APRS_TRACE - printf("APRS start\n"); -#endif - ao_radio_strobe(CC1200_STX); -#if CC1200_APRS_TRACE - { int t; - for (t = 0; t < 20; t++) { - uint8_t status = ao_radio_status(); - uint8_t space = ao_radio_tx_fifo_space(); - printf ("status: %02x fifo %d\n", status, space); - if ((status >> 4) == 2) - break; - ao_delay(AO_MS_TO_TICKS(0)); - } - } -#endif - started = 1; - } + ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); } - if (ao_radio_abort) { - ao_radio_idle(); + if (ao_radio_abort) break; + + if (done) + ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH); + else + ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF); + + ao_radio_fifo_write(buf, cnt); + if (!started) { + ao_radio_strobe(CC1200_STX); + started = 1; } } /* Wait for the transmitter to go idle */ - ao_radio_wake = 0; -#if CC1200_APRS_TRACE - printf("APRS wait idle\n"); flush(); -#endif - ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); -#if CC1200_APRS_TRACE - printf("APRS abort %d\n", ao_radio_abort); -#endif + while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) { + ao_radio_wake = 0; + ao_exti_enable(AO_CC1200_INT_PORT, AO_CC1200_INT_PIN); + ao_radio_wait_isr(AO_MS_TO_TICKS(1000)); + } + if (ao_radio_abort) + ao_radio_idle(); ao_radio_put(); } -- cgit v1.2.3 From 349a63aeed6cdeb89bf18c7b2e2c40782c79cc00 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 Jun 2016 12:52:37 -0700 Subject: altos: Make ao_delay(0) not wait forever ao_delay() is implemented on top of ao_sleep_for, and ao_sleep_for uses the timeout value of 0 to indicate an infinite timeout. Calls to ao_delay for 0 ticks would unintentionally hit this case and end up waiting forever.x Signed-off-by: Keith Packard --- src/kernel/ao_task.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index 47352fc1..0a790ccd 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -504,6 +504,8 @@ static __xdata uint8_t ao_forever; void ao_delay(uint16_t ticks) { + if (!ticks) + ticks = 1; ao_sleep_for(&ao_forever, ticks); } -- cgit v1.2.3 From 6c022e094f6f3c551355742a6f9c3deb6e554fe1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 Jun 2016 16:07:22 -0700 Subject: altos/telemini-v2.0: Remove show tasks command There's not enough memory for this command, and it isn't necessary. Signed-off-by: Keith Packard --- src/telemini-v2.0/ao_pins.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/telemini-v2.0/ao_pins.h b/src/telemini-v2.0/ao_pins.h index ed911798..e75adc07 100644 --- a/src/telemini-v2.0/ao_pins.h +++ b/src/telemini-v2.0/ao_pins.h @@ -44,6 +44,7 @@ #define PACKET_HAS_SLAVE 1 #define HAS_RADIO_RATE 1 #define HAS_TELEMETRY 1 +#define HAS_TASK_INFO 0 #define AO_LED_RED 2 #define LEDS_AVAILABLE AO_LED_RED -- cgit v1.2.3 From a35424cd48205af89ba023db979959dc75b06706 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 Jun 2016 12:54:31 -0700 Subject: altos: Make task list output more useful Add the timeout value and task id Signed-off-by: Keith Packard --- src/kernel/ao_task.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/kernel/ao_task.c b/src/kernel/ao_task.c index 0a790ccd..cf0b58ed 100644 --- a/src/kernel/ao_task.c +++ b/src/kernel/ao_task.c @@ -537,12 +537,15 @@ ao_task_info(void) { uint8_t i; __xdata struct ao_task *task; + uint16_t now = ao_time(); for (i = 0; i < ao_num_tasks; i++) { task = ao_tasks[i]; - printf("%12s: wchan %04x\n", - task->name, - (int) task->wchan); + printf("%2d: wchan %08x alarm %5d %s\n", + task->task_id, + (int) task->wchan, + task->alarm ? (int16_t) (task->alarm - now) : 9999, + task->name); } #if HAS_TASK_QUEUE && DEBUG ao_task_validate(); -- cgit v1.2.3 From c6c250711355ae8060e956e786702be250ef4527 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 Jun 2016 12:55:30 -0700 Subject: altos/stm: clean up ao_exti_enable Was computing (1 << pin) twice for no good reason. Signed-off-by: Keith Packard --- src/stm/ao_exti_stm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stm/ao_exti_stm.c b/src/stm/ao_exti_stm.c index 35958cf8..925f9a22 100644 --- a/src/stm/ao_exti_stm.c +++ b/src/stm/ao_exti_stm.c @@ -144,7 +144,7 @@ ao_exti_enable(struct stm_gpio *gpio, uint8_t pin) { uint32_t mask = (1 << pin); (void) gpio; stm_exti.pr = mask; - stm_exti.imr |= (1 << pin); + stm_exti.imr |= mask; } void -- cgit v1.2.3 From caf3fc2628c13ff38ffbaabda8aa8d146cda748e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 Jun 2016 18:33:56 -0700 Subject: altos: Leave USB enabled in flight with -DDEBUG=1 This leaves the command line available for diagnostics when debugging. Signed-off-by: Keith Packard --- src/kernel/ao_flight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/ao_flight.c b/src/kernel/ao_flight.c index 9ba02bb8..9031a54a 100644 --- a/src/kernel/ao_flight.c +++ b/src/kernel/ao_flight.c @@ -130,7 +130,7 @@ ao_flight(void) { /* Set pad mode - we can fly! */ ao_flight_state = ao_flight_pad; -#if HAS_USB && !HAS_FLIGHT_DEBUG && !HAS_SAMPLE_PROFILE +#if HAS_USB && !HAS_FLIGHT_DEBUG && !HAS_SAMPLE_PROFILE && !DEBUG /* Disable the USB controller in flight mode * to save power */ -- cgit v1.2.3 From a04830a636a71808ea8ef5ac5dfa59d6978d9f3b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 Jun 2016 18:41:24 -0700 Subject: altos: Use FIFO_THR pin for cc1120 transmit buffering Instead of reading NUM_TXBYTES, set the FIFO_THR pin to indicate when 64 bytes are available in the buffer. Signed-off-by: Keith Packard --- src/drivers/ao_cc1120.c | 138 ++++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 74 deletions(-) diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c index eb7d872b..6b800585 100644 --- a/src/drivers/ao_cc1120.c +++ b/src/drivers/ao_cc1120.c @@ -204,9 +204,9 @@ ao_radio_fifo_write_fixed(uint8_t data, uint8_t len) } static uint8_t -ao_radio_tx_fifo_space(void) +ao_radio_int_pin(void) { - return CC1120_FIFO_SIZE - ao_radio_reg_read(CC1120_NUM_TXBYTES); + return ao_gpio_get(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, AO_CC1120_INT); } #if CC1120_DEBUG @@ -262,11 +262,16 @@ ao_radio_isr(void) } static void -ao_radio_start_tx(void) +ao_radio_enable_isr(void) { - ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_isr); ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN); ao_exti_enable(AO_CC1120_MCU_WAKEUP_PORT, AO_CC1120_MCU_WAKEUP_PIN); +} + +static void +ao_radio_start_tx(void) +{ + ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_isr); ao_radio_tx_finished = 0; ao_radio_strobe(CC1120_STX); } @@ -422,10 +427,13 @@ static const uint16_t packet_setup_24[] = { CC1120_PA_CFG0, 0x7e, }; +#define AO_CC1120_TX_BUFFER 64 + static const uint16_t packet_tx_setup[] = { CC1120_PKT_CFG2, ((CC1120_PKT_CFG2_CCA_MODE_ALWAYS_CLEAR << CC1120_PKT_CFG2_CCA_MODE) | (CC1120_PKT_CFG2_PKT_FORMAT_NORMAL << CC1120_PKT_CFG2_PKT_FORMAT)), - AO_CC1120_INT_GPIO_IOCFG, CC1120_IOCFG_GPIO_CFG_RX0TX1_CFG, + CC1120_FIFO_CFG, ((0 << CC1120_FIFO_CFG_CRC_AUTOFLUSH) | + (AO_CC1120_TX_BUFFER << CC1120_FIFO_CFG_FIFO_THR)), }; static const uint16_t packet_rx_setup[] = { @@ -532,6 +540,8 @@ static const uint16_t aprs_setup[] = { CC1120_PREAMBLE_CFG1, ((CC1120_PREAMBLE_CFG1_NUM_PREAMBLE_NONE << CC1120_PREAMBLE_CFG1_NUM_PREAMBLE) | (CC1120_PREAMBLE_CFG1_PREAMBLE_WORD_AA << CC1120_PREAMBLE_CFG1_PREAMBLE_WORD)), CC1120_PA_CFG0, 0x7d, + CC1120_FIFO_CFG, ((0 << CC1120_FIFO_CFG_CRC_AUTOFLUSH) | + (AO_CC1120_TX_BUFFER << CC1120_FIFO_CFG_FIFO_THR)), }; /* @@ -737,8 +747,10 @@ ao_rdf_run(void) ao_radio_start_tx(); ao_arch_block_interrupts(); - while (!ao_radio_wake && !ao_radio_abort && !ao_radio_mcu_wake) + while (!ao_radio_wake && !ao_radio_abort && !ao_radio_mcu_wake) { + ao_radio_enable_isr(); ao_sleep(&ao_radio_wake); + } ao_arch_release_interrupts(); if (ao_radio_mcu_wake) ao_radio_check_marc_status(); @@ -844,18 +856,14 @@ ao_radio_wait_isr(uint16_t timeout) ao_radio_check_marc_status(); } -static uint8_t -ao_radio_wait_tx(uint8_t wait_fifo) +static void +ao_radio_wait_fifo(void) { - uint8_t fifo_space = 0; - - do { + while (ao_radio_int_pin() != 0 && !ao_radio_abort) { + ao_radio_wake = 0; + ao_radio_enable_isr(); ao_radio_wait_isr(0); - if (!wait_fifo) - return 0; - fifo_space = ao_radio_tx_fifo_space(); - } while (!fifo_space && !ao_radio_abort); - return fifo_space; + } } static uint8_t tx_data[(AO_RADIO_MAX_SEND + 4) * 2]; @@ -867,7 +875,6 @@ ao_radio_send(const void *d, uint8_t size) uint8_t encode_len; uint8_t this_len; uint8_t started = 0; - uint8_t fifo_space; encode_len = ao_fec_encode(d, size, tx_data); @@ -878,14 +885,17 @@ ao_radio_send(const void *d, uint8_t size) /* Flush any pending TX bytes */ ao_radio_strobe(CC1120_SFTX); - started = 0; - fifo_space = CC1120_FIFO_SIZE; while (encode_len) { this_len = encode_len; - ao_radio_wake = 0; - if (this_len > fifo_space) { - this_len = fifo_space; + if (started) { + ao_radio_wait_fifo(); + if (ao_radio_abort) + break; + } + + if (this_len > AO_CC1120_TX_BUFFER) { + this_len = AO_CC1120_TX_BUFFER; ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX_BUF); } else { ao_radio_set_mode(AO_RADIO_MODE_PACKET_TX_FINISH); @@ -898,35 +908,32 @@ ao_radio_send(const void *d, uint8_t size) if (!started) { ao_radio_start_tx(); started = 1; - } else { - ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN); - } - - fifo_space = ao_radio_wait_tx(encode_len != 0); - if (ao_radio_abort) { - ao_radio_idle(); - break; } } - while (started && !ao_radio_abort && !ao_radio_tx_finished) + while (started && !ao_radio_abort && !ao_radio_tx_finished) { + ao_radio_wake = 0; + ao_radio_enable_isr(); ao_radio_wait_isr(0); + } + if (ao_radio_abort) + ao_radio_idle(); ao_radio_put(); } -#define AO_RADIO_LOTS 64 - void ao_radio_send_aprs(ao_radio_fill_func fill) { - uint8_t buf[AO_RADIO_LOTS], *b; + uint8_t buf[AO_CC1120_TX_BUFFER]; int cnt; int total = 0; uint8_t done = 0; uint8_t started = 0; - uint8_t fifo_space; ao_radio_get(0xff); - fifo_space = CC1120_FIFO_SIZE; + + ao_radio_abort = 0; + + ao_exti_set_callback(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, ao_radio_isr); while (!done) { cnt = (*fill)(buf, sizeof(buf)); if (cnt < 0) { @@ -935,51 +942,34 @@ ao_radio_send_aprs(ao_radio_fill_func fill) } total += cnt; - /* At the last buffer, set the total length */ - if (done) - ao_radio_set_len(total & 0xff); - - b = buf; - while (cnt) { - uint8_t this_len = cnt; - - /* Wait for some space in the fifo */ - while (!ao_radio_abort && (fifo_space = ao_radio_tx_fifo_space()) == 0) { - ao_radio_wake = 0; - ao_radio_wait_isr(0); - } + /* Wait for some space in the fifo */ + if (started) { + ao_radio_wait_fifo(); if (ao_radio_abort) break; - if (this_len > fifo_space) - this_len = fifo_space; - - cnt -= this_len; - - if (done) { - if (cnt) - ao_radio_set_mode(AO_RADIO_MODE_APRS_LAST_BUF); - else - ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH); - } else - ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF); - - ao_radio_fifo_write(b, this_len); - b += this_len; - - if (!started) { - ao_radio_start_tx(); - started = 1; - } else - ao_exti_enable(AO_CC1120_INT_PORT, AO_CC1120_INT_PIN); } - if (ao_radio_abort) { - ao_radio_idle(); - break; + + if (done) { + ao_radio_set_len(total & 0xff); + ao_radio_set_mode(AO_RADIO_MODE_APRS_FINISH); + } else + ao_radio_set_mode(AO_RADIO_MODE_APRS_BUF); + + ao_radio_fifo_write(buf, cnt); + + if (!started) { + ao_radio_start_tx(); + started = 1; } - /* Wait for the transmitter to go idle */ + } + /* Wait for the transmitter to go idle */ + while (started && ao_radio_int_pin() != 0 && !ao_radio_abort) { ao_radio_wake = 0; + ao_radio_enable_isr(); ao_radio_wait_isr(0); } + if (ao_radio_abort) + ao_radio_idle(); ao_radio_put(); } -- cgit v1.2.3 From d2e286f66d2b15df128ffe9b40a201242fc4a10a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 29 Jun 2016 14:22:32 -0700 Subject: Bump to testing version 1.6.4.2 Signed-off-by: Keith Packard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index aa6be1d0..325b1870 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.6.4.1) +AC_INIT([altos], 1.6.4.2) ANDROID_VERSION=13 AC_CONFIG_SRCDIR([src/kernel/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) -- cgit v1.2.3 From 8a6a95bb24517af00717fd377bad82ddb2289cf0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 30 Jun 2016 20:43:03 -0700 Subject: altos/cc1111: Remove 'show tasks' command This saves space on cc1111 parts. Signed-off-by: Keith Packard --- src/cc1111/ao_pins.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc1111/ao_pins.h b/src/cc1111/ao_pins.h index e12f813f..9cbb0a7b 100644 --- a/src/cc1111/ao_pins.h +++ b/src/cc1111/ao_pins.h @@ -61,6 +61,7 @@ #define HAS_TELEMETRY 1 #define HAS_RADIO_RATE 0 /* not enough space for this */ #define HAS_MUTEX_TRY 0 + #define HAS_TASK_INFO 0 /* not enough space for this either */ #endif #if defined(TELEMETRUM_V_1_1) -- cgit v1.2.3 From 14e73d89d7dbb44e9ffab2820aefb693b6e8ef24 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 2 Jul 2016 22:08:58 +0200 Subject: Bump to 1.6.5. Add preliminary release notes Signed-off-by: Keith Packard --- configure.ac | 2 +- doc/altusmetrum-docinfo.xml | 9 +++++++++ doc/release-notes-1.6.5.inc | 23 +++++++++++++++++++++++ doc/release-notes.inc | 5 ++++- 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 doc/release-notes-1.6.5.inc diff --git a/configure.ac b/configure.ac index 325b1870..001449a7 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([altos], 1.6.4.2) +AC_INIT([altos], 1.6.5) ANDROID_VERSION=13 AC_CONFIG_SRCDIR([src/kernel/ao.h]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) diff --git a/doc/altusmetrum-docinfo.xml b/doc/altusmetrum-docinfo.xml index 1b8ff68d..b64f3843 100644 --- a/doc/altusmetrum-docinfo.xml +++ b/doc/altusmetrum-docinfo.xml @@ -46,6 +46,15 @@ + + 1.6.5 + 8 Jul 2016 + + Minor release fixing TeleMega and TeleMetrum v2.0 bug which + would often result in loss of data logging and telemetry in + flight. + + 1.6.4 10 May 2016 diff --git a/doc/release-notes-1.6.5.inc b/doc/release-notes-1.6.5.inc new file mode 100644 index 00000000..c77f466f --- /dev/null +++ b/doc/release-notes-1.6.5.inc @@ -0,0 +1,23 @@ += Release Notes for Version 1.6.5 +:toc!: +:doctype: article + + Version 1.6.5 fixes a TeleMega and TeleMetrum v2.0 bug where + the device would often stop logging data and transmitting + telemetry in flight. All TeleMega v1.0, v2.0 and TeleMetrum + v2.0 users should update their flight firmware. + + == AltOS + + AltOS fixes: + + * Fix STM32L SPI driver to prevent lock-up in the logging or + radio code, either of which could stop data logging and + telemetry. + + == AltosUI, TeleGPS and AltosDroid Applications + + AltosUI fixes: + + * Deliver firmward for TeleMega v2.0 and TeleBT v3.0 with + Windows package. diff --git a/doc/release-notes.inc b/doc/release-notes.inc index 6ac90cfd..b8b34e7b 100644 --- a/doc/release-notes.inc +++ b/doc/release-notes.inc @@ -2,10 +2,13 @@ == Release Notes :leveloffset: 2 - include::release-notes-1.6.4.raw[] + include::release-notes-1.6.5.raw[] <<<< + :leveloffset: 2 + include::release-notes-1.6.4.raw[] + <<<< :leveloffset: 2 include::release-notes-1.6.3.raw[] -- cgit v1.2.3 From d60133c65b4592f0f8c832135664a8e0c922b4f0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 2 Jul 2016 22:52:38 +0200 Subject: Credit Chuck Haskin for helping fix the SPI bug. Signed-off-by: Keith Packard --- doc/altusmetrum-docinfo.xml | 3 ++- doc/release-notes-1.6.5.inc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/altusmetrum-docinfo.xml b/doc/altusmetrum-docinfo.xml index b64f3843..fbd14c5a 100644 --- a/doc/altusmetrum-docinfo.xml +++ b/doc/altusmetrum-docinfo.xml @@ -52,7 +52,8 @@ Minor release fixing TeleMega and TeleMetrum v2.0 bug which would often result in loss of data logging and telemetry in - flight. + flight. Thanks to Chuck Haskin for help characterizing the bug + and testing this release. diff --git a/doc/release-notes-1.6.5.inc b/doc/release-notes-1.6.5.inc index c77f466f..9f3ae281 100644 --- a/doc/release-notes-1.6.5.inc +++ b/doc/release-notes-1.6.5.inc @@ -13,7 +13,8 @@ * Fix STM32L SPI driver to prevent lock-up in the logging or radio code, either of which could stop data logging and - telemetry. + telemetry. Found and characterized by Chuck Haskin, who also + tested the new firmware before release. == AltosUI, TeleGPS and AltosDroid Applications -- cgit v1.2.3 From 65ed2f588ca596fe9aa559bebd590a2a11b9859b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 3 Jul 2016 12:00:10 +0200 Subject: doc: Build 1.6.5 release notes Signed-off-by: Keith Packard --- doc/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/Makefile b/doc/Makefile index 31bc08d8..707a4428 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -3,6 +3,7 @@ # RELNOTES_INC=\ + release-notes-1.6.5.inc \ release-notes-1.6.4.inc \ release-notes-1.6.3.inc \ release-notes-1.6.2.inc \ -- cgit v1.2.3 From ea1ff225f1f450ee3fc377807d1bb7b982bf792d Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Mon, 4 Jul 2016 23:47:56 +0200 Subject: updating ChangeLog for 1.6.5 release --- ChangeLog | 338 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) diff --git a/ChangeLog b/ChangeLog index dd00283b..fffb7d53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,341 @@ +commit 2e26d1ab42163988dc26b06b016c3b05efe17659 +Merge: 639e461 65ed2f5 +Author: Bdale Garbee +Date: Mon Jul 4 23:47:24 2016 +0200 + + Merge branch 'master' into branch-1.6 + +commit 65ed2f588ca596fe9aa559bebd590a2a11b9859b +Author: Keith Packard +Date: Sun Jul 3 12:00:10 2016 +0200 + + doc: Build 1.6.5 release notes + + Signed-off-by: Keith Packard + +commit d60133c65b4592f0f8c832135664a8e0c922b4f0 +Author: Keith Packard +Date: Sat Jul 2 22:52:38 2016 +0200 + + Credit Chuck Haskin for helping fix the SPI bug. + + Signed-off-by: Keith Packard + +commit 14e73d89d7dbb44e9ffab2820aefb693b6e8ef24 +Author: Keith Packard +Date: Sat Jul 2 22:08:58 2016 +0200 + + Bump to 1.6.5. Add preliminary release notes + + Signed-off-by: Keith Packard + +commit 8a6a95bb24517af00717fd377bad82ddb2289cf0 +Author: Keith Packard +Date: Thu Jun 30 20:43:03 2016 -0700 + + altos/cc1111: Remove 'show tasks' command + + This saves space on cc1111 parts. + + Signed-off-by: Keith Packard + +commit d2e286f66d2b15df128ffe9b40a201242fc4a10a +Author: Keith Packard +Date: Wed Jun 29 14:22:32 2016 -0700 + + Bump to testing version 1.6.4.2 + + Signed-off-by: Keith Packard + +commit a04830a636a71808ea8ef5ac5dfa59d6978d9f3b +Author: Keith Packard +Date: Wed Jun 29 18:41:24 2016 -0700 + + altos: Use FIFO_THR pin for cc1120 transmit buffering + + Instead of reading NUM_TXBYTES, set the FIFO_THR pin to indicate when + 64 bytes are available in the buffer. + + Signed-off-by: Keith Packard + +commit caf3fc2628c13ff38ffbaabda8aa8d146cda748e +Author: Keith Packard +Date: Wed Jun 29 18:33:56 2016 -0700 + + altos: Leave USB enabled in flight with -DDEBUG=1 + + This leaves the command line available for diagnostics when debugging. + + Signed-off-by: Keith Packard + +commit c6c250711355ae8060e956e786702be250ef4527 +Author: Keith Packard +Date: Wed Jun 29 12:55:30 2016 -0700 + + altos/stm: clean up ao_exti_enable + + Was computing (1 << pin) twice for no good reason. + + Signed-off-by: Keith Packard + +commit a35424cd48205af89ba023db979959dc75b06706 +Author: Keith Packard +Date: Wed Jun 29 12:54:31 2016 -0700 + + altos: Make task list output more useful + + Add the timeout value and task id + + Signed-off-by: Keith Packard + +commit 6c022e094f6f3c551355742a6f9c3deb6e554fe1 +Author: Keith Packard +Date: Wed Jun 29 16:07:22 2016 -0700 + + altos/telemini-v2.0: Remove show tasks command + + There's not enough memory for this command, and it isn't necessary. + + Signed-off-by: Keith Packard + +commit 349a63aeed6cdeb89bf18c7b2e2c40782c79cc00 +Author: Keith Packard +Date: Wed Jun 29 12:52:37 2016 -0700 + + altos: Make ao_delay(0) not wait forever + + ao_delay() is implemented on top of ao_sleep_for, and ao_sleep_for + uses the timeout value of 0 to indicate an infinite timeout. Calls to + ao_delay for 0 ticks would unintentionally hit this case and end up + waiting forever.x + + Signed-off-by: Keith Packard + +commit 3b3a24f5f39a1b72cc8947c33b609f454b46aff8 +Author: Keith Packard +Date: Wed Jun 29 12:49:16 2016 -0700 + + altos: cc1200: use FIFO threshold pin output for APRS buffering + + Instead of polling the device for fifo space, just use the available + pin configuration to figure out if there is enough space for a single + APRS buffer. Then set the APRS buffer size to match the fifo threshold + setting in the chip so that we know we can write the whole APRS buffer + once the pin says there's space. + + Signed-off-by: Keith Packard + +commit 658d8be170f9aea683fe62b68368736a177411a5 +Author: Keith Packard +Date: Tue Jun 28 17:03:34 2016 -0700 + + altos: Add debug check for irq block when editing task queues + + List manipulation operations are not atomic, so interrupts need to be + blocked while changing them. + + Signed-off-by: Keith Packard + +commit 30eb5d2fa77e036690170e7057fa9df669375ae5 +Author: Keith Packard +Date: Tue Jun 28 18:40:46 2016 -0700 + + altos/drivers: Use more reliable byte interface for CC1120 reception + + This replaces direct register access with function calls to allow that + code to respect the hardware requirements. + + Signed-off-by: Keith Packard + +commit 61ad8e5bf428246ac89cad7cb9a1edf2ef735fd5 +Author: Keith Packard +Date: Tue Jun 28 18:39:31 2016 -0700 + + altos/stm: Add better byte-level SPI api + + This provides inline functions for sending and receiving individual + bytes, and setup/finish functions to wrap them in. This make the byte + sending respect the SPI hardware interface requirements. + + Signed-off-by: Keith Packard + +commit 5866d191cee56949ccab4c154a14604e83163d42 +Author: Keith Packard +Date: Tue Jun 28 18:37:49 2016 -0700 + + altos/stm: Clean up spi_enable/disable_index functions + + These had an extra level of switch nesting for no good reason. + + Signed-off-by: Keith Packard + +commit 5ab4a8b911e254dc829b61cb0abc9fd0b46b84b3 +Author: Keith Packard +Date: Mon Jun 27 23:25:01 2016 -0700 + + altos/stm: move spi execution to common ao_spi_run + + This regularizes SPI hardware use and ensures that the device is + turned off after it has been used and that the status register is back + to 'normal' the next time through. + + Signed-off-by: Keith Packard + +commit 69791ef235161fef404f682fd6955e7eed8dc125 +Author: Keith Packard +Date: Mon Jun 27 23:26:20 2016 -0700 + + altos: Add STM SPI debugging + + This dumps out the SPI hardware state and history of SPI operations + when compiled with -DDEBUG=1. Without that, this patch does nothing. + + Signed-off-by: Keith Packard + +commit f418584d4d225827e08f56de86055eb3f074f8d1 +Author: Keith Packard +Date: Mon Jun 27 17:26:19 2016 -0700 + + altos: Add STM DMA debugging + + This provides a command that shows current DMA operations when + compiled with -DDEBUG=1. Without that, this patch has no effect. + + Signed-off-by: Keith Packard + +commit 2e60cd22f6789c94343e6432822cedab028dc1ba +Author: Keith Packard +Date: Tue Jun 28 18:25:44 2016 -0700 + + altos/stm: Change ao_spi_send_sync definition to take const source + + Provides for a bit better error checking. + + Signed-off-by: Keith Packard + +commit 21a29c7452398e0cca0fb90f99fa42a2a0684668 +Author: Keith Packard +Date: Tue Jun 28 17:15:27 2016 -0700 + + altos/stm: Add more SPI status register bits + + These weren't the original version of the docs that we had. + + Signed-off-by: Keith Packard + +commit 785d2697376ebd20531d22441a60c41bd927b42a +Author: Keith Packard +Date: Tue Jun 28 17:12:48 2016 -0700 + + altos/stm: use 0xff for dma mutex value for allocated mutexes + + DMA channels which are 'allocated' can't be shared. Instead of using + the value '1' in the related 'mutex', use 0xff which won't match any task. + + Signed-off-by: Keith Packard + +commit 0dec7d0885970a7d73468dd77220bae78e161b40 +Author: Keith Packard +Date: Tue Jun 28 17:11:38 2016 -0700 + + altos/stm: remove ao_dma_abort + + This function isn't used anywhere. + + Signed-off-by: Keith Packard + +commit 974aaf73cbb720f1b1183cc239001528b6c7a5b9 +Author: Keith Packard +Date: Tue Jun 28 17:09:00 2016 -0700 + + altos: Move comment in ao_sleep_for next to related code + + The comment got moved to the wrong place + + Signed-off-by: Keith Packard + +commit a7e0bb5eb661cfde31c383d605cb9cb8ca568bc7 +Author: Keith Packard +Date: Tue Jun 28 17:04:59 2016 -0700 + + altos: Block interrupts while waking tasks sleeping on timers. + + Interrupts may not be blocked in the timer ISR, but they need to be + while walking the pending timer list and moving tasks back to the run + queue. + + Signed-off-by: Keith Packard + +commit 40abb0d1e2f43a60ffa34b055ebb913ee3e20faf +Author: Keith Packard +Date: Tue Jun 28 00:07:23 2016 -0700 + + altosui: Deliver firmware for Tmega 2.0 and TBT 3.0 for Windows too + + 1.6.4 added Tmega 2.0 and TBT 3.0 firmware to linux and mac, but + neglected windows. + + Signed-off-by: Keith Packard + +commit 5b7e81628437389014fdd39e323a6f0176e02ba6 +Author: Keith Packard +Date: Mon Jun 27 23:28:28 2016 -0700 + + Mark testing version 1.6.4.1 + + Signed-off-by: Keith Packard + +commit 6d15cf1580563aea90e9c47f5b268c9c7bb9ba26 +Author: Keith Packard +Date: Fri Jun 24 12:07:36 2016 -0700 + + altosdroid: Deal with multiple installed android SDKs + + Use the latest SDK's zipalign + + Signed-off-by: Keith Packard + +commit 3374a9069618658a33af54472d8670e3086af1e0 +Author: Keith Packard +Date: Fri Jun 24 12:06:32 2016 -0700 + + ao-tools/ao-chaosread: Document length (-l) option + + Signed-off-by: Keith Packard + +commit ca59786b5022f592f6516a3ac54708789db14c94 +Author: Keith Packard +Date: Mon Jun 20 10:19:32 2016 -0700 + + Bump android version to 13 + + Need to update the maps API key in the package + + Signed-off-by: Keith Packard + +commit 10fa950cb9fee0ba28adfc5ead108657655bb289 +Author: Bdale Garbee +Date: Wed Jun 22 15:01:09 2016 -0600 + + switch libgtk-3-bin build-dep to gtk-update-icon-cache, closes: #825455 + +commit ed6eb010614b5b27757619fc629d7330fc8c4122 +Author: Keith Packard +Date: Fri Jun 17 10:18:20 2016 -0700 + + doc: Add install-html script + + This script strips the XML-ish bits from html files so that ikiwiki + can parse them correctly + + Signed-off-by: Keith Packard + +commit 639e461ded29a48c155afea12171cbfc191ccfd7 +Author: Bdale Garbee +Date: Fri Jun 17 10:01:17 2016 -0600 + + releasing 1.6.4 + commit 31cf047113ec72a78f4b500223a2c6be23bc86fd Merge: 2f0c977 afe74c0 Author: Bdale Garbee -- cgit v1.2.3