forked from len0rd/rockbox
iPod Classic: Fix remaining PCM issues and add DMA information to the HW debug screen
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28991 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
67a85912c8
commit
46945eff06
3 changed files with 93 additions and 37 deletions
|
|
@ -29,6 +29,7 @@
|
|||
#include "storage.h"
|
||||
#include "power.h"
|
||||
#include "pmu-target.h"
|
||||
#include "pcm-target.h"
|
||||
|
||||
/* Skeleton for adding target specific debug info to the debug menu
|
||||
*/
|
||||
|
|
@ -40,7 +41,7 @@ bool __dbg_hw_info(void)
|
|||
int line;
|
||||
int i;
|
||||
unsigned int state = 0;
|
||||
const unsigned int max_states=2;
|
||||
const unsigned int max_states=3;
|
||||
|
||||
lcd_clear_display();
|
||||
lcd_setfont(FONT_SYSFIXED);
|
||||
|
|
@ -81,6 +82,16 @@ bool __dbg_hw_info(void)
|
|||
_DEBUG_PRINTF("backlight: %s", pmu_read(0x29) ? "on" : "off");
|
||||
_DEBUG_PRINTF("brightness value: %d", pmu_read(0x28));
|
||||
}
|
||||
else if(state==2)
|
||||
{
|
||||
_DEBUG_PRINTF("Audio DMA:");
|
||||
_DEBUG_PRINTF(">%08X %08X %08X %08X %08X", DMAC0C0CONFIG, DMAC0C0SRCADDR,
|
||||
DMAC0C0DESTADDR, DMAC0C0NEXTLLI, DMAC0C0CONTROL);
|
||||
for(i = 0; i < PCM_LLICOUNT; i++)
|
||||
_DEBUG_PRINTF("%08X: %08X %08X %08X %08X", &pcm_lli[i], pcm_lli[i].srcaddr,
|
||||
pcm_lli[i].dstaddr, pcm_lli[i].nextlli, pcm_lli[i].control);
|
||||
_DEBUG_PRINTF("chunk: %08X %08X", pcm_chunksize, pcm_remaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
state=0;
|
||||
|
|
|
|||
|
|
@ -29,21 +29,17 @@
|
|||
#include "pcm.h"
|
||||
#include "pcm_sampr.h"
|
||||
#include "mmu-arm.h"
|
||||
|
||||
/* S5L8702 PCM driver tunables: */
|
||||
#define LLIMAX (2047) /* Maximum number of samples per LLI */
|
||||
#define CHUNKSIZE (8700) /* Maximum number of samples to handle with one IRQ */
|
||||
/* (bigger chunks will be segmented internally) */
|
||||
#define WATERMARK (512) /* Number of remaining samples to schedule IRQ at */
|
||||
#include "pcm-target.h"
|
||||
|
||||
static volatile int locked = 0;
|
||||
static const int zerosample = 0;
|
||||
static unsigned char dblbuf[WATERMARK * 4] IBSS_ATTR;
|
||||
struct dma_lli lli[(CHUNKSIZE - WATERMARK + LLIMAX - 1) / LLIMAX + 1]
|
||||
__attribute__((aligned(16)));
|
||||
struct dma_lli* lastlli;
|
||||
static unsigned char dblbuf[2][PCM_WATERMARK * 4];
|
||||
static int active_dblbuf;
|
||||
struct dma_lli pcm_lli[PCM_LLICOUNT] __attribute__((aligned(16)));
|
||||
static struct dma_lli* lastlli;
|
||||
static const unsigned char* dataptr;
|
||||
static size_t remaining;
|
||||
size_t pcm_remaining;
|
||||
size_t pcm_chunksize;
|
||||
|
||||
/* Mask the DMA interrupt */
|
||||
void pcm_play_lock(void)
|
||||
|
|
@ -66,54 +62,63 @@ void INT_DMAC0C0(void) ICODE_ATTR;
|
|||
void INT_DMAC0C0(void)
|
||||
{
|
||||
DMAC0INTTCCLR = 1;
|
||||
if (!remaining) pcm_play_get_more_callback((void**)&dataptr, &remaining);
|
||||
if (!remaining)
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
lli->nextlli = NULL;
|
||||
lli->control = 0x75249000;
|
||||
pcm_play_get_more_callback((void**)&dataptr, &pcm_remaining);
|
||||
pcm_chunksize = pcm_remaining;
|
||||
}
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
pcm_lli->nextlli = NULL;
|
||||
pcm_lli->control = 0x75249000;
|
||||
clean_dcache();
|
||||
return;
|
||||
}
|
||||
uint32_t lastsize = MIN(WATERMARK * 4, remaining);
|
||||
remaining -= lastsize;
|
||||
if (remaining) lastlli = &lli[ARRAYLEN(lli) - 1];
|
||||
else lastlli = lli;
|
||||
uint32_t chunksize = MIN(CHUNKSIZE * 4 - lastsize, remaining);
|
||||
if (remaining > chunksize && chunksize > remaining - WATERMARK * 4)
|
||||
chunksize = remaining - WATERMARK * 4;
|
||||
remaining -= chunksize;
|
||||
uint32_t lastsize = MIN(PCM_WATERMARK * 4, pcm_remaining / 2 + 1) & ~1;
|
||||
pcm_remaining -= lastsize;
|
||||
if (pcm_remaining) lastlli = &pcm_lli[ARRAYLEN(pcm_lli) - 1];
|
||||
else lastlli = pcm_lli;
|
||||
uint32_t chunksize = MIN(PCM_CHUNKSIZE * 4 - lastsize, pcm_remaining);
|
||||
if (pcm_remaining > chunksize && chunksize > pcm_remaining - PCM_WATERMARK * 8)
|
||||
chunksize = pcm_remaining - PCM_WATERMARK * 8;
|
||||
pcm_remaining -= chunksize;
|
||||
bool last = !chunksize;
|
||||
int i = 0;
|
||||
while (chunksize)
|
||||
{
|
||||
uint32_t thislli = MIN(LLIMAX * 4, chunksize);
|
||||
uint32_t thislli = MIN(PCM_LLIMAX * 4, chunksize);
|
||||
chunksize -= thislli;
|
||||
lli[i].srcaddr = (void*)dataptr;
|
||||
lli[i].dstaddr = (void*)((int)&I2STXDB0);
|
||||
lli[i].nextlli = chunksize ? &lli[i + 1] : lastlli;
|
||||
lli[i].control = (chunksize ? 0x75249000 : 0xf5249000) | (thislli / 2);
|
||||
pcm_lli[i].srcaddr = (void*)dataptr;
|
||||
pcm_lli[i].dstaddr = (void*)((int)&I2STXDB0);
|
||||
pcm_lli[i].nextlli = chunksize ? &pcm_lli[i + 1] : lastlli;
|
||||
pcm_lli[i].control = (chunksize ? 0x75249000 : 0xf5249000) | (thislli / 2);
|
||||
dataptr += thislli;
|
||||
i++;
|
||||
}
|
||||
if (!remaining) memcpy(dblbuf, dataptr, lastsize);
|
||||
lastlli->srcaddr = remaining ? dataptr : dblbuf;
|
||||
if (!pcm_remaining)
|
||||
{
|
||||
memcpy(dblbuf[active_dblbuf], dataptr, lastsize);
|
||||
lastlli->srcaddr = dblbuf[active_dblbuf];
|
||||
active_dblbuf ^= 1;
|
||||
}
|
||||
else lastlli->srcaddr = dataptr;
|
||||
lastlli->dstaddr = (void*)((int)&I2STXDB0);
|
||||
lastlli->nextlli = last ? NULL : lli;
|
||||
lastlli->nextlli = last ? NULL : pcm_lli;
|
||||
lastlli->control = (last ? 0xf5249000 : 0x75249000) | (lastsize / 2);
|
||||
dataptr += lastsize;
|
||||
clean_dcache();
|
||||
if (!(DMAC0C0CONFIG & 1) && (lli[0].control & 0xfff))
|
||||
if (!(DMAC0C0CONFIG & 1) && (pcm_lli[0].control & 0xfff))
|
||||
{
|
||||
DMAC0C0LLI = lli[0];
|
||||
DMAC0C0LLI = pcm_lli[0];
|
||||
DMAC0C0CONFIG = 0x8a81;
|
||||
}
|
||||
else DMAC0C0NEXTLLI = lli;
|
||||
else DMAC0C0NEXTLLI = pcm_lli;
|
||||
}
|
||||
|
||||
void pcm_play_dma_start(const void* addr, size_t size)
|
||||
{
|
||||
dataptr = (const unsigned char*)addr;
|
||||
remaining = size;
|
||||
pcm_remaining = size;
|
||||
I2STXCOM = 0xe;
|
||||
DMAC0CONFIG |= 4;
|
||||
INT_DMAC0C0();
|
||||
|
|
@ -155,7 +160,7 @@ void pcm_dma_apply_settings(void)
|
|||
|
||||
size_t pcm_get_bytes_waiting(void)
|
||||
{
|
||||
int bytes = remaining;
|
||||
int bytes = pcm_remaining;
|
||||
const struct dma_lli* lli = (const struct dma_lli*)((int)&DMAC0C0LLI);
|
||||
while (lli)
|
||||
{
|
||||
|
|
|
|||
40
firmware/target/arm/s5l8702/pcm-target.h
Normal file
40
firmware/target/arm/s5l8702/pcm-target.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: system-target.h 28791 2010-12-11 09:39:33Z Buschel $
|
||||
*
|
||||
* Copyright (C) 2010 by Michael Sparmann
|
||||
*
|
||||
* This program 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef __PCM_TARGET_H__
|
||||
#define __PCM_TARGET_H__
|
||||
|
||||
|
||||
/* S5L8702 PCM driver tunables: */
|
||||
#define PCM_LLIMAX (2047) /* Maximum number of samples per LLI */
|
||||
#define PCM_CHUNKSIZE (10747) /* Maximum number of samples to handle with one IRQ */
|
||||
/* (bigger chunks will be segmented internally) */
|
||||
#define PCM_WATERMARK (512) /* Number of remaining samples to schedule IRQ at */
|
||||
|
||||
|
||||
#define PCM_LLICOUNT ((PCM_CHUNKSIZE - PCM_WATERMARK + PCM_LLIMAX - 1) / PCM_LLIMAX + 1)
|
||||
|
||||
|
||||
extern struct dma_lli pcm_lli[PCM_LLICOUNT];
|
||||
extern size_t pcm_remaining;
|
||||
extern size_t pcm_chunksize;
|
||||
|
||||
|
||||
#endif /* __PCM_TARGET_H__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue