Merge branch 'branch-1.6' into debian
authorBdale Garbee <bdale@gag.com>
Mon, 4 Jul 2016 21:48:32 +0000 (23:48 +0200)
committerBdale Garbee <bdale@gag.com>
Mon, 4 Jul 2016 21:48:32 +0000 (23:48 +0200)
24 files changed:
ChangeLog
altosdroid/Makefile.am
altosui/altos-windows.nsi.in
ao-tools/ao-chaosread/ao-chaosread.1
configure.ac
debian/control
doc/Makefile
doc/altusmetrum-docinfo.xml
doc/install-html [new file with mode: 0755]
doc/release-notes-1.6.5.inc [new file with mode: 0644]
doc/release-notes.inc
src/cc1111/ao_pins.h
src/drivers/ao_cc1120.c
src/drivers/ao_cc1200.c
src/kernel/ao.h
src/kernel/ao_flight.c
src/kernel/ao_task.c
src/stm/ao_arch_funcs.h
src/stm/ao_dma_stm.c
src/stm/ao_exti_stm.c
src/stm/ao_spi_stm.c
src/stm/stm32l.h
src/telemega-v1.0/ao_pins.h
src/telemini-v2.0/ao_pins.h

index dd00283b0f306491b582653df84f50c418fd484a..fffb7d533f6fd8cac3729caee2830e7f565197d0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,341 @@
+commit 2e26d1ab42163988dc26b06b016c3b05efe17659
+Merge: 639e461 65ed2f5
+Author: Bdale Garbee <bdale@gag.com>
+Date:   Mon Jul 4 23:47:24 2016 +0200
+
+    Merge branch 'master' into branch-1.6
+
+commit 65ed2f588ca596fe9aa559bebd590a2a11b9859b
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sun Jul 3 12:00:10 2016 +0200
+
+    doc: Build 1.6.5 release notes
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit d60133c65b4592f0f8c832135664a8e0c922b4f0
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 2 22:52:38 2016 +0200
+
+    Credit Chuck Haskin for helping fix the SPI bug.
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 14e73d89d7dbb44e9ffab2820aefb693b6e8ef24
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 2 22:08:58 2016 +0200
+
+    Bump to 1.6.5. Add preliminary release notes
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 8a6a95bb24517af00717fd377bad82ddb2289cf0
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit d2e286f66d2b15df128ffe9b40a201242fc4a10a
+Author: Keith Packard <keithp@keithp.com>
+Date:   Wed Jun 29 14:22:32 2016 -0700
+
+    Bump to testing version 1.6.4.2
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit a04830a636a71808ea8ef5ac5dfa59d6978d9f3b
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit caf3fc2628c13ff38ffbaabda8aa8d146cda748e
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit c6c250711355ae8060e956e786702be250ef4527
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit a35424cd48205af89ba023db979959dc75b06706
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 6c022e094f6f3c551355742a6f9c3deb6e554fe1
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 349a63aeed6cdeb89bf18c7b2e2c40782c79cc00
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 3b3a24f5f39a1b72cc8947c33b609f454b46aff8
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 658d8be170f9aea683fe62b68368736a177411a5
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 30eb5d2fa77e036690170e7057fa9df669375ae5
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 61ad8e5bf428246ac89cad7cb9a1edf2ef735fd5
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 5866d191cee56949ccab4c154a14604e83163d42
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 5ab4a8b911e254dc829b61cb0abc9fd0b46b84b3
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 69791ef235161fef404f682fd6955e7eed8dc125
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit f418584d4d225827e08f56de86055eb3f074f8d1
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 2e60cd22f6789c94343e6432822cedab028dc1ba
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 21a29c7452398e0cca0fb90f99fa42a2a0684668
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 785d2697376ebd20531d22441a60c41bd927b42a
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 0dec7d0885970a7d73468dd77220bae78e161b40
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 974aaf73cbb720f1b1183cc239001528b6c7a5b9
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit a7e0bb5eb661cfde31c383d605cb9cb8ca568bc7
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 40abb0d1e2f43a60ffa34b055ebb913ee3e20faf
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 5b7e81628437389014fdd39e323a6f0176e02ba6
+Author: Keith Packard <keithp@keithp.com>
+Date:   Mon Jun 27 23:28:28 2016 -0700
+
+    Mark testing version 1.6.4.1
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit 6d15cf1580563aea90e9c47f5b268c9c7bb9ba26
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 3374a9069618658a33af54472d8670e3086af1e0
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jun 24 12:06:32 2016 -0700
+
+    ao-tools/ao-chaosread: Document length (-l) option
+    
+    Signed-off-by: Keith Packard <keithp@keithp.com>
+
+commit ca59786b5022f592f6516a3ac54708789db14c94
+Author: Keith Packard <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 10fa950cb9fee0ba28adfc5ead108657655bb289
+Author: Bdale Garbee <bdale@gag.com>
+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 <keithp@keithp.com>
+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 <keithp@keithp.com>
+
+commit 639e461ded29a48c155afea12171cbfc191ccfd7
+Author: Bdale Garbee <bdale@gag.com>
+Date:   Fri Jun 17 10:01:17 2016 -0600
+
+    releasing 1.6.4
+
 commit 31cf047113ec72a78f4b500223a2c6be23bc86fd
 Merge: 2f0c977 afe74c0
 Author: Bdale Garbee <bdale@gag.com>
index 295abbc57347ca611fafe3b5890020b03fe2392e..686aeabfc5c6f39dae60a7ca5b33af2d13ccc365 100644 (file)
@@ -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
index c88b9e349fd1da5392a5c0eca876ceb4a914e6ee..c85e2ac8bd3aef607e42066d0dc18870729eccac 100644 (file)
@@ -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"
 
index d8ed6cb345890f6b9249eac9e818d247f20457dc..ead8afb2c2d0b767226089a4b610f4a0ad6fc8f6 100644 (file)
@@ -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.
index 6745b0123722a4427e8c551057fa1c345dc16f43..001449a75e6c7dd5ef6d552aca3b0ab216ac40b4 100644 (file)
@@ -18,8 +18,8 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([altos], 1.6.4)
-ANDROID_VERSION=12
+AC_INIT([altos], 1.6.5)
+ANDROID_VERSION=13
 AC_CONFIG_SRCDIR([src/kernel/ao.h])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 AM_MAINTAINER_MODE
index 426fb777f0a55affc0c33fcc0082983ab66a159b..e20a54a2352f477121f09a81dd19228051401704 100644 (file)
@@ -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,
index 31bc08d820a25bd709eeba9ff479ef9fc22f3c15..707a4428ad527c578dd66d956b7c457cb44f30d0 100644 (file)
@@ -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 \
index 1b8ff68d1a0fdf948597049a0d44850ac07badc4..fbd14c5a5a22cea0ff62740206a92c54971973c6 100644 (file)
 </legalnotice>
 <revhistory>
   <?dbhtml filename="altusmetrum-revhistory.html"?>
+  <revision>
+    <revnumber>1.6.5</revnumber>
+    <date>8 Jul 2016</date>
+    <revremark>
+      Minor release fixing TeleMega and TeleMetrum v2.0 bug which
+      would often result in loss of data logging and telemetry in
+      flight. Thanks to Chuck Haskin for help characterizing the bug
+      and testing this release.
+    </revremark>
+  </revision>
   <revision>
     <revnumber>1.6.4</revnumber>
     <date>10 May 2016</date>
diff --git a/doc/install-html b/doc/install-html
new file mode 100755 (executable)
index 0000000..71c7933
--- /dev/null
@@ -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/<!DOCTYPE [^>]*>//' "$file" > "$destination/$base"
+                           ;;
+                   esac
+                   ;;
+           esac
+           ;;
+       destination)
+           destination=$file
+           state=arg
+           ;;
+    esac
+done
diff --git a/doc/release-notes-1.6.5.inc b/doc/release-notes-1.6.5.inc
new file mode 100644 (file)
index 0000000..9f3ae28
--- /dev/null
@@ -0,0 +1,24 @@
+= 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. Found and characterized by Chuck Haskin, who also
+          tested the new firmware before release.
+
+       == AltosUI, TeleGPS and AltosDroid Applications
+
+       AltosUI fixes:
+
+       * Deliver firmward for TeleMega v2.0 and TeleBT v3.0 with
+          Windows package.
index 6ac90cfd6a4feeac70f493f0a06d2438063baa4f..b8b34e7bcf711bb713348ea2bd9f8bf347ab54b4 100644 (file)
@@ -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[]
 
index e12f813f8b0b7f8a48fef078252f093de42bb615..9cbb0a7b51aed07894959821dd9d68b27fff16af 100644 (file)
@@ -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)
index 5b814667fccf8f18e67d9e7aec557489bfae915a..6b8005852c9bea9ca49ba02b994b0a5717066cf9 100644 (file)
@@ -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();
 }
 
@@ -206,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
@@ -264,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);
 }
@@ -424,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[] = {
@@ -534,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)),
 };
 
 /*
@@ -739,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();
@@ -846,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];
@@ -869,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);
 
@@ -880,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);
@@ -900,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) {
@@ -937,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();
 }
 
@@ -1029,8 +1017,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 +1086,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 +1136,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;
                }
        }
index 6bccb18863f9439ac0f4ed46f76dc7bd90adabcd..cd85f208aa3dd8f6c6a03d7a57cc65ac57d608c9 100644 (file)
@@ -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();
 }
 
index 6ed0299e2d707baa607a515394ab4f4eccb7988b..27a16606010ff8f629c30755ed1e9ec39aeea1c3 100644 (file)
@@ -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 */
index 9ba02bb8b24e8cc9b872e3e84a205daf1bba96db..9031a54ae070e97e42a6d182e0d4b802e9897918 100644 (file)
@@ -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
                                 */
index e430edc6c02f3e5854b5163ebd18afc26d6c0e0e..cf0b58ed8eaa0bf939e0e77bc80635b69f6f52db 100644 (file)
@@ -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);
 }
@@ -165,13 +176,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
@@ -459,11 +471,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
@@ -492,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);
 }
 
@@ -523,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();
index 2c017c79f0191b5b5395f66f508a26748cb048db..a796891d53b24b9fe4b40179ecee94543029a0eb 100644 (file)
@@ -80,7 +80,13 @@ 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);
+
+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
@@ -249,9 +271,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);
 
@@ -343,6 +362,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)
index 8379a1a533ca0ec5e19321910b1a9975a952f744..0135de48e9e9131e619a8fc81b493ee23dfed4a8 100644 (file)
@@ -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(
@@ -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)
 {
@@ -120,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)
 {
@@ -131,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
 }
index 35958cf845632e37cb9c21781e7af057bd0bf173..925f9a222f50020cf9f82bad6ac0c34b9ba026da 100644 (file)
@@ -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
index 7eaa392418438ea56c9c7c4ae774ef6a52b0bed1..214092f6bb75922ca075bd404766416b650637e1 100644 (file)
@@ -41,12 +41,91 @@ 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
+
+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,
@@ -62,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
@@ -81,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,
@@ -118,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
@@ -137,27 +199,48 @@ 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));
+
+       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) |
-                       (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);
+                       (0 << STM_SPI_CR2_TXDMAEN) |
+                       (0 << STM_SPI_CR2_RXDMAEN));
+       validate_spi(stm_spi, 5, 0xffff);
 }
 
 void
-ao_spi_send_sync(void *block, uint16_t len, uint8_t spi_index)
+ao_spi_stop_bytes(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);
+       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)
+{
+       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) |
@@ -165,22 +248,28 @@ ao_spi_send_sync(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;
 
@@ -198,9 +287,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,
@@ -215,31 +301,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,
@@ -255,9 +326,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,
@@ -271,24 +339,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
@@ -296,44 +347,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;
        }
 }
@@ -341,39 +384,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;
        }
 }
@@ -383,20 +420,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
@@ -411,6 +435,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
@@ -428,6 +467,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);
 }
@@ -451,15 +491,62 @@ 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
+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
 }
index 0b6b27983d6a3633d891be36bfdd0f0ecb3063fe..352214ffdbc055c50c8fb44a3cde16dee23ea8d8 100644 (file)
@@ -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
 
index b81e59a9a340bb309c88a66a41f09a56d36a554f..58b4d61a3be9cce6f36d5874a4a0ea6244cadfbc 100644 (file)
@@ -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
index ed911798930537292a1177ff48db3478a60f18b5..e75adc072528fd25aa533b89ba2d25a4ba73e058 100644 (file)
@@ -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