ugfx/src/gaudin/gaudin.c

156 lines
3.2 KiB
C

/*
* This file is subject to the terms of the GFX License. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://ugfx.org/license.html
*/
/**
* @file src/gaudin/gaudin.c
* @brief GAUDIN sub-system code.
*
* @addtogroup GAUDIN
* @{
*/
#include "gfx.h"
#if GFX_USE_GAUDIN
/* Include the driver defines */
#include "gaudin/lld/gaudin_lld.h"
static gaudin_params aud;
static gfxSem *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 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)
gfxSemSignalI(paudSem);
#if GFX_USE_GEVENT
if (audFlags & AUDFLG_USE_EVENTS)
gtimerJabI(&AudGTimer);
#endif
}
void GAUDIN_ISR_ErrorI(void) {
/* Ignore any errors for now */
}
void _gaudinInit(void)
{
#if GFX_USE_GEVENT
gtimerInit(&AudGTimer);
#endif
}
void _gaudinDeinit(void)
{
/* ToDo */
}
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, 0, TRUE, TIME_INFINITE);
audFlags |= AUDFLG_USE_EVENTS;
return (GSourceHandle)&aud;
}
#endif
void gaudinSetBSem(gfxSem *pbsem, GEventAudioIn *pEvent) {
gfxSystemLock();
paudSem = pbsem;
paudEvent = pEvent;
gfxSystemUnlock();
}
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 */
/** @} */