aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Hannam <andrewh@inmarket.com.au>2013-03-01 09:04:52 +1000
committerAndrew Hannam <andrewh@inmarket.com.au>2013-03-01 09:04:52 +1000
commit6ee8b005ae3ee2bc48ea6ac972b0d3b2a2949608 (patch)
tree2ea08726aae7357443420ce45100c8118923dfdd /src
parent9bec5967b293d6c23c9d7e9338d8ece4873f6eac (diff)
downloaduGFX-6ee8b005ae3ee2bc48ea6ac972b0d3b2a2949608.tar.gz
uGFX-6ee8b005ae3ee2bc48ea6ac972b0d3b2a2949608.tar.bz2
uGFX-6ee8b005ae3ee2bc48ea6ac972b0d3b2a2949608.zip
GAUDIN implemented with GADC driver
Diffstat (limited to 'src')
-rw-r--r--src/gadc/gadc.c11
-rw-r--r--src/gaudin/gaudin.c196
2 files changed, 169 insertions, 38 deletions
diff --git a/src/gadc/gadc.c b/src/gadc/gadc.c
index 509557d3..8a3cfb8d 100644
--- a/src/gadc/gadc.c
+++ b/src/gadc/gadc.c
@@ -83,6 +83,7 @@ static struct hsdev {
size_t remaining;
BinarySemaphore *bsem;
GEventADC *pEvent;
+ GADCISRCallbackFunction isrfn;
} hs;
static struct lsdev {
@@ -181,6 +182,11 @@ void GADC_ISR_CompleteI(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
hs.pEvent->buffer = hs.lastbuffer;
hs.pEvent->flags = hs.lastflags;
}
+
+ /* Our three signalling mechanisms */
+ if (hs.isrfn)
+ hs.isrfn(buffer, n);
+
if (hs.bsem)
chBSemSignalI(hs.bsem);
@@ -344,6 +350,7 @@ void gadcHighSpeedInit(uint32_t physdev, uint32_t frequency, adcsample_t *buffer
hs.remaining = bufcount;
hs.bsem = 0;
hs.pEvent = 0;
+ hs.isrfn = 0;
}
#if GFX_USE_GEVENT
@@ -356,6 +363,10 @@ void gadcHighSpeedInit(uint32_t physdev, uint32_t frequency, adcsample_t *buffer
}
#endif
+void gadcHighSpeedSetISRCallback(GADCISRCallbackFunction isrfn) {
+ hs.isrfn = isrfn;
+}
+
void gadcHighSpeedSetBSem(BinarySemaphore *pbsem, GEventADC *pEvent) {
DoInit();
diff --git a/src/gaudin/gaudin.c b/src/gaudin/gaudin.c
index 120d7d81..4ce04132 100644
--- a/src/gaudin/gaudin.c
+++ b/src/gaudin/gaudin.c
@@ -1,38 +1,158 @@
-/*
- ChibiOS/GFX - Copyright (C) 2012
- Joel Bodenmann aka Tectu <joel@unormal.org>
-
- This file is part of ChibiOS/GFX.
-
- ChibiOS/GFX is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/GFX is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * @file src/gaudin/gaudin.c
- * @brief GAUDIN sub-system code.
- *
- * @addtogroup GAUDIN
- * @{
- */
-#include "ch.h"
-#include "hal.h"
-#include "gfx.h"
-
-#if GFX_USE_GAUDIN || defined(__DOXYGEN__)
-
- #error "GAUDIN: Not implemented yet"
-
-#endif /* GFX_USE_GAUDIN */
-/** @} */
-
+/*
+ ChibiOS/GFX - Copyright (C) 2012
+ Joel Bodenmann aka Tectu <joel@unormal.org>
+
+ This file is part of ChibiOS/GFX.
+
+ ChibiOS/GFX is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/GFX is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file src/gaudin/gaudin.c
+ * @brief GAUDIN sub-system code.
+ *
+ * @addtogroup GAUDIN
+ * @{
+ */
+#include "ch.h"
+#include "hal.h"
+#include "gfx.h"
+
+#if GFX_USE_GAUDIN
+
+/* Include the driver defines */
+#include "gaudin/lld/gaudin_lld.h"
+
+static gaudin_params aud;
+static BinarySemaphore *paudSem;
+static GEventAudioIn *paudEvent;
+static audin_sample_t *lastbuffer;
+static size_t lastcount;
+static uint16_t audFlags;
+ #define AUDFLG_RUNNING 0x0001
+ #define AUDFLG_USE_EVENTS 0x0002
+
+#if GFX_USE_GEVENT
+ static GTIMER_DECL(AudGTimer);
+
+ static void AudGTimerCallback(void *param) {
+ (void) param;
+ GSourceListener *psl;
+ GEventADC *pe;
+
+ psl = 0;
+ while ((psl = geventGetSourceListener((GSourceHandle)(&aud), psl))) {
+ if (!(pe = (GEventAudioIn *)geventGetEventBuffer(psl))) {
+ // This listener is missing - save this.
+ psl->srcflags |= GADC_AUDIO_IN_LOSTEVENT;
+ continue;
+ }
+
+ pe->type = GEVENT_AUDIO_IN;
+ pe->channel = aud.channel;
+ pe->count = lastcount;
+ pe->buffer = lastbuffer;
+ pe->flags = psl->srcflags;
+ psl->srcflags = 0;
+ geventSendEvent(psl);
+ }
+ }
+#endif
+
+void GAUDIN_ISR_CompleteI(audin_sample_t *buffer, size_t n) {
+ /* Save the details */
+ lastcount = n;
+ lastbuffer = buffer;
+
+ /* Signal the user with the data */
+ if (paudEvent) {
+ #if GFX_USE_GEVENT
+ paudEvent->type = GEVENT_AUDIO_IN;
+ #endif
+ paudEvent->channel = aud.channel;
+ paudEvent->count = lastcount;
+ paudEvent->buffer = lastbuffer;
+ paudEvent->flags = 0;
+ }
+
+ /* Our two signalling mechanisms */
+ if (paudSem)
+ chBSemSignalI(paudSem);
+
+ #if GFX_USE_GEVENT
+ if (audFlags & AUDFLG_USE_EVENTS)
+ gtimerJabI(&AudGTimer);
+ #endif
+}
+
+void GAUDIN_ISR_ErrorI(void) {
+ /* Ignore any errors for now */
+}
+
+bool_t gaudinInit(uint16_t channel, uint32_t frequency, audin_sample_t *buffer, size_t bufcount, size_t samplesPerEvent) {
+ /* Check the channel is valid */
+ if (channel >= GAUDIN_NUM_CHANNELS || frequency > GAUDIN_MAX_SAMPLE_FREQUENCY)
+ return FALSE;
+
+ /* Stop any existing transfers */
+ if ((audFlags & AUDFLG_RUNNING))
+ gadc_lld_stop();
+ audFlags = 0;
+
+ /* Initialise everything */
+ aud.channel = channel;
+ aud.frequency = frequency;
+ aud.buffer = buffer;
+ aud.bufcount = bufcount;
+ aud.samplesPerEvent = samplesPerEvent;
+ paudSem = 0;
+ paudEvent = 0;
+
+ /* Set up the low level driver */
+ gaudin_lld_init(&aud);
+ return TRUE;
+}
+
+#if GFX_USE_GEVENT
+ GSourceHandle gaudinGetSource(void) {
+ if (!gtimerIsActive(&AudGTimer))
+ gtimerStart(&AudGTimer, AudGTimerCallback, NULL, TRUE, TIME_INFINITE);
+ audFlags |= AUDFLG_USE_EVENTS;
+ return (GSourceHandle)&aud;
+ }
+#endif
+
+void gaudinSetBSem(BinarySemaphore *pbsem, GEventAudioIn *pEvent) {
+ chSysLock();
+ paudSem = pbsem;
+ paudEvent = pEvent;
+ chSysUnlock();
+}
+
+void gaudinStart(void) {
+ if (!(audFlags & AUDFLG_RUNNING)) {
+ audFlags |= AUDFLG_RUNNING;
+ gadc_lld_start();
+ }
+}
+
+void gaudinStop(void) {
+ if ((audFlags & AUDFLG_RUNNING)) {
+ gadc_lld_stop();
+ audFlags &= ~AUDFLG_RUNNING;
+ }
+}
+
+#endif /* GFX_USE_GAUDIN */
+/** @} */