diff options
author | inmarket <andrewh@inmarket.com.au> | 2014-03-30 19:10:31 +1000 |
---|---|---|
committer | inmarket <andrewh@inmarket.com.au> | 2014-03-30 19:10:31 +1000 |
commit | 04f03ea71da1337c501b598c6038afaf0216fed8 (patch) | |
tree | 7d31e7b75256f42bc6b98bce7e625431d4f7722a /drivers/gaudio/pwm/gaudio_play_lld.c | |
parent | c16cb15ce9b5e4cc1a913def9614f8a587bc0868 (diff) | |
download | uGFX-04f03ea71da1337c501b598c6038afaf0216fed8.tar.gz uGFX-04f03ea71da1337c501b598c6038afaf0216fed8.tar.bz2 uGFX-04f03ea71da1337c501b598c6038afaf0216fed8.zip |
New PWM audio driver for audio output using a digital pin on a CPU
Diffstat (limited to 'drivers/gaudio/pwm/gaudio_play_lld.c')
-rw-r--r-- | drivers/gaudio/pwm/gaudio_play_lld.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/drivers/gaudio/pwm/gaudio_play_lld.c b/drivers/gaudio/pwm/gaudio_play_lld.c new file mode 100644 index 00000000..07fd14b2 --- /dev/null +++ b/drivers/gaudio/pwm/gaudio_play_lld.c @@ -0,0 +1,117 @@ +/* + * 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 + */ + +#include "gfx.h" + +#if GFX_USE_GAUDIO && GAUDIO_NEED_PLAY + +/* Include the driver defines */ +#include "src/gaudio/driver_play.h" + +/* Forward definition */ +static void gaudio_play_pwm_timer_callbackI(void); + +/* Include the board interface */ +#include "gaudio_play_board.h" + +static GDataBuffer *pplay; +static ArrayDataFormat playfmt; +static size_t playlen; +static uint8_t *pdata; + +static void gaudio_play_pwm_timer_callbackI(void) { + if (pplay) { + + // Get the next value from the current data buffer + if (gfxSampleFormatBits(playfmt) > 8) { + gaudio_play_pwm_setI(*(uint16_t *)pdata); + pdata += 2; + } else { + gaudio_play_pwm_setI(*pdata); + pdata++; + } + + // Are we done yet + if (--playlen) + return; + gaudioPlayReleaseDataBlockI(pplay); + + // Get a new data buffer + if (!(pplay = gaudioPlayGetDataBlockI())) { + // All is done + gaudioPlayDoneI(); + return; + } + + } else { + // Get a new data buffer + if (!(pplay = gaudioPlayGetDataBlockI())) + return; + } + + // Set up ready for the new buffer + playlen = pplay->len; + if (gfxSampleFormatBits(playfmt) > 8) + playlen >>= 1; + pdata = (uint8_t *)(pplay+1); +} + + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +bool_t gaudio_play_lld_init(uint16_t channel, uint32_t frequency, ArrayDataFormat format) { + (void) channel; + + if (format != ARRAY_DATA_8BITUNSIGNED && format != ARRAY_DATA_10BITUNSIGNED) + return FALSE; + + playfmt = format; + return gaudio_play_pwm_setup(frequency, format); +} + +bool_t gaudio_play_lld_set_volume(uint8_t vol) { + (void) vol; + return FALSE; +} + +void gaudio_play_lld_start(void) { + + gfxSystemLock(); + // Get a new data buffer + if (pplay || !(pplay = gaudioPlayGetDataBlockI())) { + gfxSystemUnlock(); // Nothing to do + return; + } + + // Set up ready for the new buffer + playlen = pplay->len; + if (gfxSampleFormatBits(playfmt) > 8) + playlen >>= 1; + pdata = (uint8_t *)(pplay+1); + gfxSystemUnlock(); + + // Start the playing + gaudio_play_pwm_start(); +} + +void gaudio_play_lld_stop(void) { + // Stop everything + gaudio_play_pwm_stop(); + + // We may need to clean up the remaining buffer. + gfxSystemLock(); + if (pplay) { + gaudioPlayReleaseDataBlockI(pplay); + pplay = 0; + gaudioPlayDoneI(); + } + gfxSystemUnlock(); +} + +#endif /* GFX_USE_GAUDIO && GAUDIO_NEED_PLAY */ |