Merge branch 'master' of https://bitbucket.org/Tectu/ugfx
This commit is contained in:
commit
a394e2c35d
@ -3,3 +3,4 @@ GFXSRC +=
|
||||
GFXDEFS += -DGFX_USE_OS_CHIBIOS=TRUE
|
||||
include $(GFXLIB)/drivers/gdisp/ILI9341/gdisp_lld.mk
|
||||
include $(GFXLIB)/drivers/ginput/touch/MCU/ginput_lld.mk
|
||||
include $(GFXLIB)/drivers/gaudio/vs1053/driver.mk
|
||||
|
97
boards/base/Mikromedia-STM32-M4-ILI9341/gaudio_play_board.h
Normal file
97
boards/base/Mikromedia-STM32-M4-ILI9341/gaudio_play_board.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef GAUDIO_PLAY_BOARD_H
|
||||
#define GAUDIO_PLAY_BOARD_H
|
||||
|
||||
#define SET_CS palSetPad(GPIOC, GPIOC_MP3_CS)
|
||||
#define CLR_CS palClearPad(GPIOC, GPIOC_MP3_CS)
|
||||
#define SET_RST palSetPad(GPIOC, GPIOC_MP3_RST)
|
||||
#define CLR_RST palClearPad(GPIOC, GPIOC_MP3_RST)
|
||||
#define SET_DCS palSetPad(GPIOC, GPIOC_MP3_DCS)
|
||||
#define CLR_DCS palClearPad(GPIOC, GPIOC_MP3_DCS)
|
||||
#define GET_DREQ palReadPad(GPIOC, GPIOC_MP3_DREQ)
|
||||
#define SPI_PORT &SPID3
|
||||
|
||||
static const SPIConfig spicfg_init = {
|
||||
0,
|
||||
GPIOC,
|
||||
GPIOC_MP3_CS,
|
||||
SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0,
|
||||
};
|
||||
|
||||
static const SPIConfig spicfg = {
|
||||
0,
|
||||
GPIOC,
|
||||
GPIOC_MP3_CS,
|
||||
0,
|
||||
};
|
||||
|
||||
// Initialise the board
|
||||
static inline void board_init(void) {
|
||||
palSetPadMode(GPIOC, GPIOC_MP3_CS, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(GPIOC, GPIOC_MP3_RST, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(GPIOC, GPIOC_MP3_DCS, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(GPIOC, GPIOC_MP3_DREQ, PAL_MODE_INPUT);
|
||||
SET_CS; SET_RST; SET_DCS;
|
||||
spiStart(SPI_PORT, &spicfg_init);
|
||||
}
|
||||
|
||||
// Chip is initialised enough so we can talk fast to it
|
||||
#define board_init_end() spiStart(SPI_PORT, &spicfg)
|
||||
|
||||
// Reset the board
|
||||
#define board_reset() { CLR_RST; gfxSleepMilliseconds(1); SET_RST; }
|
||||
|
||||
// Returns the state of the dreq pin
|
||||
#define board_dreq() GET_DREQ
|
||||
|
||||
// Start a command write
|
||||
static inline void board_startcmdwrite(void) {
|
||||
#if SPI_USE_MUTUAL_EXCLUSION
|
||||
spiAcquireBus(SPI_PORT);
|
||||
#endif
|
||||
CLR_CS;
|
||||
}
|
||||
|
||||
// End a command write
|
||||
static inline void board_endcmdwrite(void) {
|
||||
#if SPI_USE_MUTUAL_EXCLUSION
|
||||
spiReleaseBus(SPI_PORT);
|
||||
#endif
|
||||
SET_CS;
|
||||
}
|
||||
|
||||
// Start a command read
|
||||
#define board_startcmdread() board_startcmdwrite()
|
||||
|
||||
// End a command read
|
||||
#define board_endcmdread() board_endcmdwrite()
|
||||
|
||||
// Start a data write
|
||||
static inline void board_startdatawrite(void) {
|
||||
#if SPI_USE_MUTUAL_EXCLUSION
|
||||
spiAcquireBus(SPI_PORT);
|
||||
#endif
|
||||
CLR_DCS;
|
||||
}
|
||||
|
||||
// End a data write
|
||||
static inline void board_enddatawrite(void) {
|
||||
#if SPI_USE_MUTUAL_EXCLUSION
|
||||
spiReleaseBus(SPI_PORT);
|
||||
#endif
|
||||
SET_DCS;
|
||||
}
|
||||
|
||||
// Write data to the SPI port
|
||||
#define board_spiwrite(buf, len) spiSend(SPI_PORT, len, buf)
|
||||
|
||||
// Read data from the SPI port
|
||||
#define board_spiread(buf, len) spiReceive(SPI_PORT, len, buf)
|
||||
|
||||
#endif /* GAUDIO_PLAY_BOARD_H */
|
@ -3,7 +3,8 @@ running under ChibiOS with the ILI9341 display.
|
||||
|
||||
On this board uGFX currently supports:
|
||||
- GDISP via the ILI9341 display
|
||||
- GINPUT-touch via the MCU driver
|
||||
- GINPUT-touch via the MCU driver
|
||||
- GAUDIO (play only) via the vs1053 driver
|
||||
|
||||
Note there are two variants of this board - one with the ILI9341 display
|
||||
and an older one with a different display. This one is for the ILI9341 display.
|
||||
|
@ -10,7 +10,7 @@ FEATURE: Added gdispGDrawThickLine() by user jpa-
|
||||
DEPRECATE: TDISP module removed
|
||||
FIX: Console does not execute gwinPrintf() anymore if not visible
|
||||
FEATURE: Added gwinGetColor() and gwinGetBgColor()
|
||||
FEATURE: Console does now have an optional buffer (GWIN_CONSOLE_USE_HISTORY)
|
||||
FEATURE: Console now has an optional backing store buffer (GWIN_CONSOLE_USE_HISTORY)
|
||||
FEATURE: Added smooth scrolling to list widget
|
||||
FEATURE: Increased performance of gwinListAddItem()
|
||||
FEATURE: Added gfxDeinit()
|
||||
@ -20,11 +20,18 @@ FEATURE: Image file handling changed to use new GFILE module.
|
||||
DEPRECTATE: Old image opening functions deprecated.
|
||||
FEATURE: Restructure and simplify the include path for GFX
|
||||
FEATURE: Added LGDP4532 driver by user shilow
|
||||
FIX: Updated board files to support api changes in ChibiOS/RT 2.6.4
|
||||
FEATURE: Support for ChibiOS/RT 3.x
|
||||
FEATURE: Added gwinProgressbarStop() and gwinProgressbarReset()
|
||||
FEATURE: Added generic ILI93xx driver by xlh1460
|
||||
FEATURE: Added gwinListEnableRender()
|
||||
FEATURE: Added gwinLabelSetAttribute()
|
||||
FEATURE: Complete restructure of the GAUDIN and GAUDOUT into a common GAUDIO module
|
||||
FEATURE: Added a PWM audio play driver
|
||||
FEATURE: Update GADC audio recording driver to new GAUDIO format
|
||||
FEATURE: Added vs1053 audio play driver
|
||||
FEATURE: Added GAUDIO wave-play demo
|
||||
FEATURE: Added many GWIN simple demo's and updated the combined widget demo
|
||||
|
||||
|
||||
*** changes after 1.9 ***
|
||||
|
7
drivers/gaudio/vs1053/driver.mk
Normal file
7
drivers/gaudio/vs1053/driver.mk
Normal file
@ -0,0 +1,7 @@
|
||||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/gaudio/vs1053/gaudio_play_lld.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/gaudio/vs1053
|
||||
|
||||
GFXDEFS += -DGFX_USE_GTIMER=TRUE
|
71
drivers/gaudio/vs1053/gaudio_play_board_template.h
Normal file
71
drivers/gaudio/vs1053/gaudio_play_board_template.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef GAUDIO_PLAY_BOARD_H
|
||||
#define GAUDIO_PLAY_BOARD_H
|
||||
|
||||
// Initialise the board
|
||||
static void board_init(void) {
|
||||
|
||||
}
|
||||
|
||||
// Chip is initialised enough so we can talk fast to it
|
||||
static void board_init_end(void) {
|
||||
|
||||
}
|
||||
|
||||
// Reset the board
|
||||
static void board_reset(void) {
|
||||
|
||||
}
|
||||
|
||||
// Returns the state of the dreq pin
|
||||
static bool board_dreq(void) {
|
||||
|
||||
}
|
||||
|
||||
// Start a command write
|
||||
static void board_startcmdwrite(void) {
|
||||
|
||||
}
|
||||
|
||||
// End a command write
|
||||
static void board_endcmdwrite(void) {
|
||||
|
||||
}
|
||||
|
||||
// Start a command read
|
||||
static void board_startcmdread(void) {
|
||||
|
||||
}
|
||||
|
||||
// End a command read
|
||||
static void board_endcmdread(void) {
|
||||
|
||||
}
|
||||
|
||||
// Start a data write
|
||||
static void board_startdatawrite(void) {
|
||||
|
||||
}
|
||||
|
||||
// End a data write
|
||||
static void board_enddatawrite(void) {
|
||||
|
||||
}
|
||||
|
||||
// Write data to the SPI port
|
||||
static void board_spiwrite(const uint8_t *buf, unsigned len) {
|
||||
|
||||
}
|
||||
|
||||
// Read data from the SPI port
|
||||
static void board_spiread(uint8_t *buf, unsigned len) {
|
||||
|
||||
}
|
||||
|
||||
#endif /* GAUDIO_PLAY_BOARD_H */
|
29
drivers/gaudio/vs1053/gaudio_play_config.h
Normal file
29
drivers/gaudio/vs1053/gaudio_play_config.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef GAUDIO_PLAY_CONFIG_H
|
||||
#define GAUDIO_PLAY_CONFIG_H
|
||||
|
||||
#if GFX_USE_GAUDIO && GAUDIO_NEED_PLAY
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver hardware support. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define GAUDIO_PLAY_MAX_SAMPLE_FREQUENCY 48000
|
||||
#define GAUDIO_PLAY_NUM_FORMATS 2
|
||||
#define GAUDIO_PLAY_FORMAT1 ARRAY_DATA_16BITSIGNED
|
||||
#define GAUDIO_PLAY_FORMAT2 ARRAY_DATA_8BITUNSIGNED
|
||||
#define GAUDIO_PLAY_NUM_CHANNELS 2
|
||||
#define GAUDIO_PLAY_CHANNEL0_IS_STEREO FALSE
|
||||
#define GAUDIO_PLAY_CHANNEL1_IS_STEREO TRUE
|
||||
#define GAUDIO_PLAY_MONO 0
|
||||
#define GAUDIO_PLAY_STEREO 1
|
||||
|
||||
#endif /* GFX_USE_GAUDIO && GAUDIO_NEED_PLAY */
|
||||
|
||||
#endif /* GAUDIO_PLAY_CONFIG_H */
|
348
drivers/gaudio/vs1053/gaudio_play_lld.c
Normal file
348
drivers/gaudio/vs1053/gaudio_play_lld.c
Normal file
@ -0,0 +1,348 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
/* Include the vs1053 registers */
|
||||
#include "drivers/gaudio/vs1053/vs1053.h"
|
||||
|
||||
/* Include the board interface */
|
||||
#include "gaudio_play_board.h"
|
||||
|
||||
// Override-able parameters
|
||||
#ifndef VS1053_CLK
|
||||
#define VS1053_CLK 12288000
|
||||
#endif
|
||||
#ifndef VS1053_FIRMWARE_PATCH
|
||||
#define VS1053_FIRMWARE_PATCH FALSE
|
||||
#endif
|
||||
|
||||
// Load the patch file if desired. New format patches only.
|
||||
#if VS1053_FIRMWARE_PATCH
|
||||
#define SKIP_PLUGIN_VARNAME
|
||||
static const uint16_t plugin[] = { /* Compressed plugin */
|
||||
#include "vs1053_patch.plg"
|
||||
};
|
||||
#endif
|
||||
|
||||
// Set various stuff based on the clock
|
||||
#if VS1053_CLK >= 16192000
|
||||
#define SCI_MODE_STARTUP (SCI_MODE_DEFAULTS|SM_CLK_RANGE)
|
||||
#define VS1053_CLKI (VS1053_CLK/2)
|
||||
#else
|
||||
#define SCI_MODE_STARTUP (SCI_MODE_DEFAULTS)
|
||||
#define VS1053_CLKI (VS1053_CLK)
|
||||
#endif
|
||||
#if VS1053_CLKI > 13000000 || VS1053_CLKI < 12000000
|
||||
#error "GAUDIO(vs1053): VS1053_CLK is out of range"
|
||||
#endif
|
||||
#if VS1053_CLKI == 12288000
|
||||
#define SC_FREQ_ADJUST 0x0000
|
||||
#else
|
||||
#define SC_FREQ_ADJUST ((VS1053_CLKI-8000000)/4000)
|
||||
#endif
|
||||
#define VS1053_MAX_SAMPLE_RATE (VS1053_CLKI/256)
|
||||
#if VS1053_CLKI > 1228800
|
||||
#define SC_CLOCK_MODE (SC_MULT_3|SC_ADD_1|SC_FREQ_ADJUST)
|
||||
#else
|
||||
#define SC_CLOCK_MODE (SC_MULT_3_5|SC_ADD_1|SC_FREQ_ADJUST)
|
||||
#endif
|
||||
|
||||
// Our static variables
|
||||
static bool_t vs1053_isinit;
|
||||
static GTimer playTimer;
|
||||
|
||||
// Some common macro's
|
||||
#define waitforready() while(!board_dreq()) gfxSleepMilliseconds(5)
|
||||
|
||||
static void cmd_write(uint16_t addr, uint16_t data) {
|
||||
char buf[4];
|
||||
buf[0] = 2;
|
||||
buf[1] = (char)addr;
|
||||
buf[2] = (char)(data >> 8);
|
||||
buf[3] = (char)data;
|
||||
|
||||
waitforready();
|
||||
board_startcmdwrite();
|
||||
board_spiwrite(buf, 4);
|
||||
board_endcmdwrite();
|
||||
}
|
||||
|
||||
#if VS1053_CLK > 12288000
|
||||
static inline void cmd_writenodreq(uint16_t addr, uint16_t data) {
|
||||
uint8_t buf[4];
|
||||
|
||||
// This is the same as cmd_write() except for it doesn't wait for dreq first
|
||||
buf[0] = 2;
|
||||
buf[1] = (uint8_t)addr;
|
||||
buf[2] = (uint8_t)(data >> 8);
|
||||
buf[3] = (uint8_t)data;
|
||||
|
||||
board_startcmdwrite();
|
||||
board_spiwrite(buf, 4);
|
||||
board_endcmdwrite();
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint16_t cmd_read(uint16_t addr) {
|
||||
uint8_t buf[2];
|
||||
|
||||
buf[0] = 3;
|
||||
buf[1] = (char)addr;
|
||||
|
||||
board_startcmdread();
|
||||
board_spiwrite(buf, 2);
|
||||
board_spiread(buf, 2);
|
||||
board_endcmdread();
|
||||
return (((uint16_t)buf[0])<<8)|buf[1];
|
||||
}
|
||||
|
||||
static void data_write(const uint8_t *data, unsigned len) {
|
||||
board_startdatawrite();
|
||||
board_spiwrite(data, len);
|
||||
board_enddatawrite();
|
||||
}
|
||||
|
||||
#if VS1053_FIRMWARE_PATCH
|
||||
static void LoadUserCode(void) {
|
||||
int i;
|
||||
uint16_t addr, n, val;
|
||||
|
||||
for(i=0; i<sizeof(plugin)/sizeof(plugin[0]);) {
|
||||
addr = plugin[i++];
|
||||
n = plugin[i++];
|
||||
if (n & 0x8000U) { /* RLE run, replicate n samples */
|
||||
n &= 0x7FFF;
|
||||
val = plugin[i++];
|
||||
while (n--)
|
||||
cmd_write(addr, val);
|
||||
} else { /* Copy run, copy n samples */
|
||||
while (n--)
|
||||
cmd_write(addr, plugin[i++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void vs1053_hard_reset(void) {
|
||||
gtimerInit(&playTimer);
|
||||
|
||||
board_init();
|
||||
board_reset();
|
||||
|
||||
#if VS1053_CLK > 12288000
|
||||
cmd_writenodreq(SCI_MODE, SCI_MODE_STARTUP); // Set super-clock before dreq
|
||||
#endif
|
||||
|
||||
// Set up registers
|
||||
cmd_write(SCI_MODE, SCI_MODE_STARTUP); // Set mode
|
||||
cmd_write(SCI_CLOCKF, SC_CLOCK_MODE); // Set clocks
|
||||
board_init_end(); // Clocks are now set up
|
||||
cmd_write(SCI_BASS, 0x0000); // No treble or bass boost
|
||||
cmd_write(SCI_VOL, VOL_MAX); // Maximum volume
|
||||
|
||||
// Load any firmware
|
||||
#if VS1053_FIRMWARE_PATCH
|
||||
LoadUserCode();
|
||||
|
||||
// Reset mode just in case
|
||||
cmd_write(SCI_MODE, SCI_MODE_STARTUP);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vs1053_soft_reset(void) {
|
||||
cmd_write(SCI_MODE, cmd_read(SCI_MODE)|SM_RESET);
|
||||
gfxSleepMilliseconds(1); // Wait for at least 2uS
|
||||
waitforready();
|
||||
|
||||
// Reload any firmware
|
||||
#if VS1053_FIRMWARE_PATCH
|
||||
LoadUserCode();
|
||||
|
||||
// Reset mode just in case
|
||||
cmd_write(SCI_MODE, SCI_MODE_STARTUP);
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint16_t vs1053_getendbyte(void) {
|
||||
cmd_write(SCI_WRAMADDR, WRAMADDR_EXTRAPARAMS+4);
|
||||
return cmd_read(SCI_WRAM);
|
||||
}
|
||||
|
||||
static GTimer playTimer;
|
||||
static GDataBuffer *pplay;
|
||||
static size_t playlen;
|
||||
static uint8_t *pdata;
|
||||
|
||||
static void FeedData(void *param) {
|
||||
unsigned len;
|
||||
(void) param;
|
||||
|
||||
// While there is data space
|
||||
while (!board_dreq()) {
|
||||
|
||||
// Send up to 32 bytes
|
||||
len = playlen;
|
||||
if (len > 32) len = 32;
|
||||
data_write(pdata, len);
|
||||
pdata += len;
|
||||
playlen -= len;
|
||||
|
||||
// Have we finished the buffer
|
||||
while (!playlen) {
|
||||
gfxSystemLock();
|
||||
gaudioPlayReleaseDataBlockI(pplay);
|
||||
|
||||
// Get a new data buffer
|
||||
if (!(pplay = gaudioPlayGetDataBlockI())) {
|
||||
// We should really only do the play-done when the audio
|
||||
// has really finished playing. Unfortunately there seems
|
||||
// to be no documented way of determining this.
|
||||
gaudioPlayDoneI();
|
||||
gfxSystemUnlock();
|
||||
gtimerStop(&playTimer);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up ready for the new buffer
|
||||
playlen = pplay->len;
|
||||
pdata = (uint8_t *)(pplay+1);
|
||||
gfxSystemUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
bool_t gaudio_play_lld_init(uint16_t channel, uint32_t frequency, ArrayDataFormat format) {
|
||||
uint32_t brate;
|
||||
uint32_t bps;
|
||||
uint8_t buf[4];
|
||||
static const uint8_t hdr1[] = {
|
||||
'R', 'I', 'F', 'F',
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
'W', 'A', 'V', 'E',
|
||||
'f', 'm', 't', ' ',
|
||||
16, 0, 0, 0,
|
||||
0x01, 0x00,
|
||||
};
|
||||
static const uint8_t hdr2[] = {
|
||||
'd', 'a', 't', 'a',
|
||||
0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
|
||||
if (format != ARRAY_DATA_8BITUNSIGNED && format != ARRAY_DATA_16BITSIGNED)
|
||||
return FALSE;
|
||||
if (frequency > VS1053_MAX_SAMPLE_RATE)
|
||||
return FALSE;
|
||||
|
||||
// Reset the chip if needed
|
||||
if (!vs1053_isinit) {
|
||||
vs1053_hard_reset();
|
||||
vs1053_isinit = TRUE;
|
||||
}
|
||||
|
||||
// Setup
|
||||
bps = (gfxSampleFormatBits(format)+7)/8;
|
||||
if (channel == GAUDIO_PLAY_STEREO)
|
||||
bps *= 2;
|
||||
brate = frequency * bps;
|
||||
|
||||
// Write the RIFF header
|
||||
waitforready();
|
||||
data_write(hdr1, sizeof(hdr1));
|
||||
buf[0] = channel == GAUDIO_PLAY_STEREO ? 2 : 1; buf[1] = 0; data_write(buf, 2);
|
||||
buf[0] = frequency; buf[1] = frequency>>8; buf[2] = frequency>>16; buf[3] = frequency>>24; data_write(buf, 4);
|
||||
buf[0] = brate; buf[1] = brate>>8; buf[2] = brate>>16; buf[3] = brate>>24; data_write(buf, 4);
|
||||
waitforready(); // 32 bytes max before checking
|
||||
buf[0] = bps; buf[1] = 0; data_write(buf, 2);
|
||||
buf[0] = gfxSampleFormatBits(format); buf[1] = 0; data_write(buf, 2);
|
||||
data_write(hdr2, sizeof(hdr2));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t gaudio_play_lld_set_volume(uint8_t vol) {
|
||||
// Volume is 0xFE -> 0x00. Adjust vol to match
|
||||
vol = ~vol;
|
||||
if (vol == 0xFF) vol = 0xFE;
|
||||
|
||||
cmd_write(SCI_VOL, ((uint16_t)vol) << 8 | vol);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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;
|
||||
pdata = (uint8_t *)(pplay+1);
|
||||
gfxSystemUnlock();
|
||||
|
||||
// Start the playing by starting the timer and executing FeedData immediately just to get things started
|
||||
// We really should set the timer to be equivalent to half the available data but that is just too hard to calculate.
|
||||
gtimerStart(&playTimer, FeedData, 0, TRUE, 5);
|
||||
FeedData(0);
|
||||
}
|
||||
|
||||
void gaudio_play_lld_stop(void) {
|
||||
uint8_t ch;
|
||||
unsigned i;
|
||||
|
||||
// Stop the timer interrupt
|
||||
gtimerStop(&playTimer);
|
||||
|
||||
// We may need to clean up the remaining buffer.
|
||||
gfxSystemLock();
|
||||
if (pplay) {
|
||||
gaudioPlayReleaseDataBlockI(pplay);
|
||||
pplay = 0;
|
||||
gaudioPlayDoneI();
|
||||
}
|
||||
gfxSystemUnlock();
|
||||
|
||||
// Set CANCEL
|
||||
cmd_write(SCI_MODE, cmd_read(SCI_MODE)|SM_CANCEL);
|
||||
|
||||
// Write up to 2048 bytes of data
|
||||
ch = 0;
|
||||
for(i = 0; i < 2048; i++) {
|
||||
if (!(i & 0x1F)) {
|
||||
waitforready();
|
||||
if (!(cmd_read(SCI_MODE) & SM_CANCEL))
|
||||
break;
|
||||
}
|
||||
data_write(&ch, 1);
|
||||
}
|
||||
|
||||
// Make sure the cancel worked
|
||||
waitforready();
|
||||
if ((cmd_read(SCI_MODE) & SM_CANCEL))
|
||||
vs1053_soft_reset();
|
||||
|
||||
// Send the terminating data
|
||||
ch = vs1053_getendbyte();
|
||||
for(i = 0; i < 2052; i++) {
|
||||
if (!(i & 0x1F))
|
||||
waitforready();
|
||||
data_write(&ch, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GAUDIO && GAUDIO_NEED_PLAY */
|
4
drivers/gaudio/vs1053/readme.txt
Normal file
4
drivers/gaudio/vs1053/readme.txt
Normal file
@ -0,0 +1,4 @@
|
||||
This chip supports playing in many formats including MP3 etc.
|
||||
For this driver however we only support PCM in 8 bit unisgned and 16 bit signed formats.
|
||||
|
||||
Requires GFX_USE_GTIMER
|
101
drivers/gaudio/vs1053/vs1053.h
Normal file
101
drivers/gaudio/vs1053/vs1053.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _VS1053_H
|
||||
#define _VS1053_H
|
||||
|
||||
// Registers
|
||||
#define SCI_MODE 0x00
|
||||
#define SM_DIFF 0x0001
|
||||
#define SM_LAYER12 0x0002
|
||||
#define SM_RESET 0x0004
|
||||
#define SM_CANCEL 0x0008
|
||||
#define SM_EARSPEAKER_LO 0x0010
|
||||
#define SM_TESTS 0x0020
|
||||
#define SM_STREAM 0x0040
|
||||
#define SM_EARSPEAKER_HI 0x0080
|
||||
#define SM_DACT 0x0100
|
||||
#define SM_SDIORD 0x0200
|
||||
#define SM_SDISHARE 0x0400
|
||||
#define SM_SDINEW 0x0800
|
||||
#define SM_ADPCM 0x1000
|
||||
#define SM_LINE1 0x4000
|
||||
#define SM_CLK_RANGE 0x8000
|
||||
#define SCI_MODE_DEFAULTS (SM_LINE1|SM_SDINEW)
|
||||
#define SCI_STATUS 0x01
|
||||
#define SS_DO_NOT_JUMP 0x8000
|
||||
#define SS_SWING_MASK 0x7000
|
||||
#define SS_SWING_SHIFT 12
|
||||
#define SS_VCM_OVERLOAD 0x0800
|
||||
#define SS_VCM_DISABLE 0x0400
|
||||
#define SS_VER_MASK 0x00F0
|
||||
#define SS_VER_SHIFT 4
|
||||
#define SS_APDOWN2 0x0008
|
||||
#define SS_APDOWN1 0x0004
|
||||
#define SS_SS_AD_CLOCK 0x0002
|
||||
#define SS_REFERENCE_SEL 0x0001
|
||||
#define SCI_BASS 0x02
|
||||
#define ST_AMPLITUDE_MASK 0xF000
|
||||
#define ST_AMPLITUDE_SHIFT 12
|
||||
#define ST_FREQLIMIT_MASK 0x0F00
|
||||
#define ST_FREQLIMIT_SHIFT 8
|
||||
#define SB_AMPLITUDE_MASK 0x00F0
|
||||
#define SB_AMPLITUDE_SHIFT 4
|
||||
#define SB_FREQLIMIT_MASK 0x000F
|
||||
#define SB_FREQLIMIT_SHIFT 0
|
||||
#define SCI_CLOCKF 0x03
|
||||
#define SC_MULT_1 0x0000
|
||||
#define SC_MULT_2 0x2000
|
||||
#define SC_MULT_2_5 0x4000
|
||||
#define SC_MULT_3 0x6000
|
||||
#define SC_MULT_3_5 0x8000
|
||||
#define SC_MULT_4 0xa000
|
||||
#define SC_MULT_4_5 0xc000
|
||||
#define SC_MULT_5 0xe000
|
||||
#define SC_ADD_NONE 0x0000
|
||||
#define SC_ADD_1 0x0800
|
||||
#define SC_ADD_1_5 0x1000
|
||||
#define SC_ADD_2 0x1800
|
||||
#define SC_FREQ_MASK 0x07FF
|
||||
#define SCI_DECODE_TIME 0x04
|
||||
#define SCI_AUDATA 0x05
|
||||
#define SR_RATE_MASK 0xFFFE
|
||||
#define SR_IS_STEREO 0x0001
|
||||
#define SCI_WRAM 0x06
|
||||
#define SCI_WRAMADDR 0x07
|
||||
#define WRAMADDR_XDATA 0x1800
|
||||
#define WRAMADDR_YDATA 0x5800
|
||||
#define WRAMADDR_INSTR 0x8040
|
||||
#define WRAMADDR_IO 0xC000
|
||||
#define WRAMADDR_EXTRAPARAMS 0x1E02
|
||||
#define SCI_HDAT0 0x08
|
||||
#define SCI_HDAT1 0x09
|
||||
#define HD_FMT_NONE 0x0000
|
||||
#define HD_FMT_WAV 0x7665
|
||||
#define HD_FMT_AAC_ADTS 0x4154
|
||||
#define HD_FMT_AAC_ADIF 0x4144
|
||||
#define HD_FMT_AAC_M4A 0x4D34
|
||||
#define HD_FMT_WMA 0x574D
|
||||
#define HD_FMT_MIDI 0x4D54
|
||||
#define HD_FMT_OGG 0x4F67
|
||||
#define HD_FMT_MP3_MIN 0xFFE0
|
||||
#define HD_FMT_MP3_MAX 0xFFFF
|
||||
#define SCI_AIADDR 0x0A
|
||||
#define SCI_VOL 0x0B
|
||||
#define VOL_LEFT_MASK 0xFF00
|
||||
#define VOL_LEFT_SHIFT 8
|
||||
#define VOL_RIGHT_MASK 0x00FF
|
||||
#define VOL_RIGHT_SHIFT 0
|
||||
#define VOL_POWERDOWN 0xFFFF
|
||||
#define VOL_MAX 0x0000
|
||||
#define VOL_MIN 0xFEFE
|
||||
#define SCI_AICTRL0 0x0C
|
||||
#define SCI_AICTRL1 0x0D
|
||||
#define SCI_AICTRL2 0x0E
|
||||
#define SCI_AICTRL3 0x0F
|
||||
|
||||
#endif /* _VS1053_H */
|
Loading…
Reference in New Issue
Block a user