mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
Sound working with rockbox PCM interface on the M:Robe 500. Doom and Rockboy run with sound. There are stability problems that need to be looked into causing the player to reset when music playback is attempted.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20284 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
2d9caa9aa3
commit
3c7ada5941
10 changed files with 259 additions and 236 deletions
|
|
@ -26,20 +26,55 @@
|
|||
#include <stdbool.h>
|
||||
#include "button.h"
|
||||
#include "lcd.h"
|
||||
#include "debug.h"
|
||||
#include "sprintf.h"
|
||||
#include "font.h"
|
||||
#include "pcm.h"
|
||||
#include "debug-target.h"
|
||||
#include "lcd-target.h"
|
||||
#include "dsp-target.h"
|
||||
#include "dsp/ipc.h"
|
||||
|
||||
#ifndef CREATIVE_ZVx
|
||||
#include "tsc2100.h"
|
||||
#endif
|
||||
|
||||
#define ARM_BUFFER_SIZE (PCM_SIZE)
|
||||
|
||||
static signed short *the_rover = (signed short *)0x1900000;
|
||||
static unsigned int index_rover = 0;
|
||||
|
||||
void pcmtest_get_more(unsigned char** start, size_t* size)
|
||||
{
|
||||
unsigned long sdem_addr;
|
||||
sdem_addr = (unsigned long)the_rover + index_rover;
|
||||
|
||||
*start = (unsigned char*)(sdem_addr);
|
||||
*size = ARM_BUFFER_SIZE;
|
||||
|
||||
index_rover += ARM_BUFFER_SIZE;
|
||||
if (index_rover >= 4*1024*1024)
|
||||
{
|
||||
index_rover = 0;
|
||||
}
|
||||
|
||||
DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
|
||||
(unsigned long)the_rover, (unsigned long)sdem_addr);
|
||||
}
|
||||
|
||||
bool __dbg_ports(void)
|
||||
{
|
||||
dsp_init();
|
||||
dsp_wake();
|
||||
int fd;
|
||||
int bytes;
|
||||
|
||||
fd = open("/test.raw", O_RDONLY);
|
||||
bytes = read(fd, the_rover, 4*1024*1024);
|
||||
close(fd);
|
||||
|
||||
DEBUGF("read %d rover bytes", bytes);
|
||||
|
||||
pcm_play_data(&pcmtest_get_more,(unsigned char*)the_rover, ARM_BUFFER_SIZE);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,18 +27,6 @@
|
|||
#include "dsp-target.h"
|
||||
#include "dsp/ipc.h"
|
||||
|
||||
/* A "DSP image" is an array of these, terminated by raw_data_size_half = 0. */
|
||||
struct dsp_section {
|
||||
const unsigned short *raw_data;
|
||||
unsigned short physical_addr;
|
||||
unsigned short raw_data_size_half;
|
||||
};
|
||||
|
||||
/* Must define struct dsp_section before including the image. */
|
||||
#include "dsp/dsp-image.h"
|
||||
|
||||
#define dsp_message (*(volatile struct ipc_message *)&DSP_(_status))
|
||||
|
||||
#ifdef DEBUG
|
||||
static void dsp_status(void)
|
||||
{
|
||||
|
|
@ -74,7 +62,7 @@ static void dsp_status(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void dsp_reset(void)
|
||||
void dsp_reset(void)
|
||||
{
|
||||
DSP_(0x7fff) = 0xdead;
|
||||
|
||||
|
|
@ -102,7 +90,7 @@ void dsp_wake(void)
|
|||
restore_irq(old_level);
|
||||
}
|
||||
|
||||
static void dsp_load(const struct dsp_section *im)
|
||||
void dsp_load(const struct dsp_section *im)
|
||||
{
|
||||
while (im->raw_data_size_half) {
|
||||
volatile unsigned short *data_ptr = &DSP_(im->physical_addr);
|
||||
|
|
@ -131,110 +119,3 @@ static void dsp_load(const struct dsp_section *im)
|
|||
}
|
||||
}
|
||||
|
||||
static signed short *the_rover = (signed short *)0x1900000;
|
||||
static unsigned int index_rover = 0;
|
||||
#define ARM_BUFFER_SIZE (PCM_SIZE)
|
||||
|
||||
void dsp_init(void)
|
||||
{
|
||||
unsigned long sdem_addr;
|
||||
int fd;
|
||||
int bytes;
|
||||
|
||||
IO_INTC_IRQ0 = 1 << 11;
|
||||
IO_INTC_EINT0 |= 1 << 11;
|
||||
|
||||
IO_DSPC_HPIB_CONTROL = 1 << 10 | 1 << 9 | 1 << 8 | 1 << 7 | 1 << 3 | 1 << 0;
|
||||
|
||||
dsp_reset();
|
||||
dsp_load(dsp_image);
|
||||
|
||||
/* Initialize codec. */
|
||||
sdem_addr = (unsigned long)the_rover - CONFIG_SDRAM_START;
|
||||
DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
|
||||
(unsigned long)the_rover, (unsigned long)sdem_addr);
|
||||
DSP_(_sdem_addrl) = sdem_addr & 0xffff;
|
||||
DSP_(_sdem_addrh) = sdem_addr >> 16;
|
||||
DSP_(_sdem_dsp_size) = ARM_BUFFER_SIZE;
|
||||
|
||||
fd = open("/test.raw", O_RDONLY);
|
||||
bytes = read(fd, the_rover, 4*1024*1024);
|
||||
close(fd);
|
||||
|
||||
DEBUGF("read %d rover bytes", bytes);
|
||||
|
||||
#ifdef IPC_SIZES
|
||||
DEBUGF("dsp_message at 0x%08x", &dsp_message);
|
||||
DEBUGF("sizeof(ipc_message)=%uB offset(ipc_message.payload)=%uB",
|
||||
sizeof(struct ipc_message), (int)&((struct ipc_message*)0)->payload);
|
||||
#endif
|
||||
|
||||
#if 0//def INIT_MSG
|
||||
/* Prepare init message. */
|
||||
|
||||
/* DSP accesses MUST be done a word at a time. */
|
||||
dsp_message.msg = MSG_INIT;
|
||||
|
||||
sdem_addr = (unsigned long)pcm_sdram - CONFIG_SDRAM_START;
|
||||
DEBUGF("pcm_sdram at 0x%08x, sdem_addr 0x%08x", pcm_sdram, sdem_addr);
|
||||
dsp_message.payload.init.sdem_addrl = sdem_addr & 0xffff;
|
||||
dsp_message.payload.init.sdem_addrh = sdem_addr >> 16;
|
||||
|
||||
DEBUGF("dsp_message: %04x %04x %04x %04x",
|
||||
((unsigned short *)&dsp_message)[0],
|
||||
((unsigned short *)&dsp_message)[1],
|
||||
((unsigned short *)&dsp_message)[2],
|
||||
((unsigned short *)&dsp_message)[3]);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void DSPHINT(void)
|
||||
{
|
||||
unsigned long sdem_addr;
|
||||
unsigned int i;
|
||||
char buffer[80];
|
||||
|
||||
IO_INTC_IRQ0 = 1 << 11;
|
||||
|
||||
switch (dsp_message.msg)
|
||||
{
|
||||
case MSG_DEBUGF:
|
||||
/* DSP stores one character per word. */
|
||||
for (i = 0; i < sizeof(buffer); i++)
|
||||
{
|
||||
buffer[i] = dsp_message.payload.debugf.buffer[i];
|
||||
}
|
||||
|
||||
/* Release shared area to DSP. */
|
||||
dsp_wake();
|
||||
|
||||
DEBUGF("DSP: %s", buffer);
|
||||
break;
|
||||
case MSG_REFILL:
|
||||
sdem_addr = (unsigned long)the_rover + index_rover - CONFIG_SDRAM_START;
|
||||
|
||||
DSP_(_sdem_addrl) = sdem_addr & 0xffff;
|
||||
DSP_(_sdem_addrh) = sdem_addr >> 16;
|
||||
DSP_(_sdem_dsp_size) = ARM_BUFFER_SIZE;
|
||||
|
||||
index_rover += ARM_BUFFER_SIZE;
|
||||
if (index_rover >= 4*1024*1024)
|
||||
{
|
||||
index_rover = 0;
|
||||
}
|
||||
|
||||
DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
|
||||
(unsigned long)the_rover, (unsigned long)sdem_addr);
|
||||
|
||||
break;
|
||||
default:
|
||||
DEBUGF("DSP: unknown msg 0x%04x", dsp_message.msg);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Release shared area to DSP. */
|
||||
dsp_wake();
|
||||
|
||||
DEBUGF("DSP: %s", buffer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,25 @@
|
|||
*
|
||||
*/
|
||||
#ifndef DSP_H
|
||||
#define DSP_H
|
||||
#define DSP_H
|
||||
|
||||
/* DSP memory is mapped into ARM space via HPIB. */
|
||||
#define DSP_(addr) (*(volatile unsigned short *)(0x40000 + ((addr) << 1)))
|
||||
|
||||
/* A "DSP image" is an array of these, terminated by raw_data_size_half = 0. */
|
||||
struct dsp_section {
|
||||
const unsigned short *raw_data;
|
||||
unsigned short physical_addr;
|
||||
unsigned short raw_data_size_half;
|
||||
};
|
||||
|
||||
#define dsp_message (*(volatile struct ipc_message *)&DSP_(_status))
|
||||
|
||||
/* Must define struct dsp_section before including the image. */
|
||||
#include "dsp/dsp-image.h"
|
||||
|
||||
void dsp_init(void);
|
||||
void dsp_wake(void);
|
||||
void dsp_wake(void);
|
||||
void dsp_load(const struct dsp_section *im);
|
||||
void dsp_reset(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,18 +27,26 @@
|
|||
|
||||
volatile struct ipc_message status;
|
||||
|
||||
extern int waiting;
|
||||
volatile int acked;
|
||||
interrupt void handle_int0(void) {
|
||||
IFR = 1;
|
||||
acked = 1;
|
||||
waiting = 0;
|
||||
rebuffer();
|
||||
}
|
||||
|
||||
void waitforack(void)
|
||||
void startack(void)
|
||||
{
|
||||
/* Wait until ARM has picked up data. */
|
||||
acked = 0;
|
||||
int_arm();
|
||||
while (!acked) {
|
||||
}
|
||||
|
||||
void waitack(void)
|
||||
{
|
||||
/* Wait until ARM has picked up data. */
|
||||
while (!acked)
|
||||
{
|
||||
/* IDLE alone never seems to wake up :( */
|
||||
asm(" IDLE 1");
|
||||
asm(" NOP");
|
||||
|
|
@ -52,7 +60,8 @@ void debugf(const char *fmt, ...) {
|
|||
vsnprintf((char *)status.payload.debugf.buffer, sizeof(status), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
waitforack();
|
||||
startack();
|
||||
waitack();
|
||||
|
||||
acked = 2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@
|
|||
#include "registers.h"
|
||||
|
||||
extern volatile struct ipc_message status;
|
||||
void waitforack(void);
|
||||
|
||||
void startack(void);
|
||||
void waitack(void);
|
||||
|
||||
void debugf(const char *fmt, ...);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ unsigned short last_size;
|
|||
/* This tells us which half of the DSP buffer (data) is free */
|
||||
unsigned short dma0_unlocked;
|
||||
|
||||
int waiting=0;
|
||||
/* rebuffer sets up the next SDRAM to SARAM transfer and tells the ARM when it
|
||||
* is done with a buffer.
|
||||
*/
|
||||
|
|
@ -76,45 +77,49 @@ void rebuffer(void)
|
|||
sdem_level=0;
|
||||
|
||||
/* Get a new buffer (location and size) from ARM */
|
||||
status.msg = MSG_REFILL;
|
||||
int_arm();
|
||||
status.msg = MSG_REFILL;
|
||||
waiting=1;
|
||||
startack();
|
||||
}
|
||||
|
||||
/* Size is in bytes (but forced 32 bit transfers */
|
||||
if( (dsp_level + (sdem_dsp_size - sdem_level) ) > DSP_BUFFER_SIZE)
|
||||
|
||||
if(!waiting)
|
||||
{
|
||||
last_size = DSP_BUFFER_SIZE-dsp_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_size = sdem_dsp_size-sdem_level;
|
||||
}
|
||||
/* Size is in bytes (but forced 32 bit transfers */
|
||||
if( (dsp_level + (sdem_dsp_size - sdem_level) ) > DSP_BUFFER_SIZE)
|
||||
{
|
||||
last_size = DSP_BUFFER_SIZE-dsp_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
last_size = sdem_dsp_size-sdem_level;
|
||||
}
|
||||
|
||||
/* DSP addresses are 16 bit (word) */
|
||||
DSP_ADDRL = (unsigned short)data + (dma0_unlocked >> 1) + (dsp_level>>1);
|
||||
DSP_ADDRH = 0;
|
||||
/* DSP addresses are 16 bit (word) */
|
||||
DSP_ADDRL = (unsigned short)data + (dma0_unlocked >> 1) + (dsp_level>>1);
|
||||
DSP_ADDRH = 0;
|
||||
|
||||
/* SDRAM addresses are 8 bit (byte)
|
||||
* Warning: These addresses are forced to 32 bit alignment!
|
||||
*/
|
||||
sdem_addr = ((unsigned long)sdem_addrh << 16 | sdem_addrl) + sdem_level;
|
||||
SDEM_ADDRL = sdem_addr & 0xffff;
|
||||
SDEM_ADDRH = sdem_addr >> 16;
|
||||
/* SDRAM addresses are 8 bit (byte)
|
||||
* Warning: These addresses are forced to 32 bit alignment!
|
||||
*/
|
||||
sdem_addr = ((unsigned long)sdem_addrh << 16 | sdem_addrl) + sdem_level;
|
||||
SDEM_ADDRL = sdem_addr & 0xffff;
|
||||
SDEM_ADDRH = sdem_addr >> 16;
|
||||
|
||||
/* Set the size of the SDRAM to SARAM transfer (demac transfer) */
|
||||
DMA_SIZE = last_size;
|
||||
/* Set the size of the SDRAM to SARAM transfer (demac transfer) */
|
||||
DMA_SIZE = last_size;
|
||||
|
||||
DMA_CTRL = 0;
|
||||
DMA_CTRL = 0;
|
||||
|
||||
/* These are just debug signals that are not used/needed right now */
|
||||
status.payload.refill._DMA_TRG = DMA_TRG;
|
||||
status.payload.refill._SDEM_ADDRH = SDEM_ADDRH;
|
||||
status.payload.refill._SDEM_ADDRL = SDEM_ADDRL;
|
||||
status.payload.refill._DSP_ADDRH = DSP_ADDRH;
|
||||
status.payload.refill._DSP_ADDRL = DSP_ADDRL;
|
||||
/* These are just debug signals that are not used/needed right now */
|
||||
status.payload.refill._DMA_TRG = DMA_TRG;
|
||||
status.payload.refill._SDEM_ADDRH = SDEM_ADDRH;
|
||||
status.payload.refill._SDEM_ADDRL = SDEM_ADDRL;
|
||||
status.payload.refill._DSP_ADDRH = DSP_ADDRH;
|
||||
status.payload.refill._DSP_ADDRL = DSP_ADDRL;
|
||||
|
||||
/* Start the demac transfer */
|
||||
DMA_TRG = 1;
|
||||
/* Start the demac transfer */
|
||||
DMA_TRG = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* This interupt handler is for the SARAM (on DSP) to McBSP IIS DMA transfer.
|
||||
|
|
@ -146,8 +151,7 @@ interrupt void handle_dma0(void)
|
|||
* (dsp_level), the SDRAM buffer level (sdem_level) and to rebuffer if the dsp
|
||||
* buffer is not full.
|
||||
*/
|
||||
interrupt void handle_dmac(void) {
|
||||
unsigned long sdem_addr;
|
||||
interrupt void handle_dmac(void) {
|
||||
IFR = 1 << 11;
|
||||
|
||||
dsp_level+=last_size;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -7,7 +7,7 @@
|
|||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Karl Kurbjun
|
||||
* Copyright (C) 2007 and 2009 by Karl Kurbjun
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -18,16 +18,20 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "logf.h"
|
||||
#include "audio.h"
|
||||
#include "sound.h"
|
||||
#include "file.h"
|
||||
#include "dsp-target.h"
|
||||
#include "dsp/ipc.h"
|
||||
#include "mmu-arm.h"
|
||||
|
||||
void pcm_postinit(void)
|
||||
{
|
||||
|
||||
audiohw_postinit();
|
||||
}
|
||||
|
||||
const void * pcm_play_dma_get_peak_buffer(int *count)
|
||||
|
|
@ -38,17 +42,28 @@ const void * pcm_play_dma_get_peak_buffer(int *count)
|
|||
|
||||
void pcm_play_dma_init(void)
|
||||
{
|
||||
|
||||
IO_INTC_IRQ0 = 1 << 11;
|
||||
IO_INTC_EINT0 |= 1 << 11;
|
||||
|
||||
IO_DSPC_HPIB_CONTROL = 1 << 10 | 1 << 9 | 1 << 8 | 1 << 7 | 1 << 3 | 1 << 0;
|
||||
|
||||
dsp_reset();
|
||||
dsp_load(dsp_image);
|
||||
}
|
||||
|
||||
void pcm_dma_apply_settings(void)
|
||||
{
|
||||
audiohw_set_frequency(pcm_fsel);
|
||||
}
|
||||
|
||||
void pcm_play_dma_start(const void *addr, size_t size)
|
||||
{
|
||||
(void) addr;
|
||||
(void) size;
|
||||
unsigned long sdem_addr=(unsigned long)addr - CONFIG_SDRAM_START;
|
||||
/* Initialize codec. */
|
||||
DSP_(_sdem_addrl) = sdem_addr & 0xffff;
|
||||
DSP_(_sdem_addrh) = sdem_addr >> 16;
|
||||
DSP_(_sdem_dsp_size) = size;
|
||||
dsp_wake();
|
||||
}
|
||||
|
||||
void pcm_play_dma_stop(void)
|
||||
|
|
@ -73,5 +88,69 @@ void pcm_play_dma_pause(bool pause)
|
|||
|
||||
size_t pcm_get_bytes_waiting(void)
|
||||
{
|
||||
return 0;
|
||||
return DSP_(_sdem_dsp_size)-DSP_(_sdem_level);
|
||||
}
|
||||
|
||||
void DSPHINT(void)
|
||||
{
|
||||
static unsigned char *start;
|
||||
static size_t size;
|
||||
register pcm_more_callback_type get_more; /* No stack for this */
|
||||
|
||||
unsigned int i;
|
||||
char buffer[80];
|
||||
|
||||
IO_INTC_IRQ0 = 1 << 11;
|
||||
|
||||
switch (dsp_message.msg)
|
||||
{
|
||||
case MSG_DEBUGF:
|
||||
/* DSP stores one character per word. */
|
||||
for (i = 0; i < sizeof(buffer); i++)
|
||||
{
|
||||
buffer[i] = dsp_message.payload.debugf.buffer[i];
|
||||
}
|
||||
|
||||
/* Release shared area to DSP. */
|
||||
dsp_wake();
|
||||
|
||||
DEBUGF("DSP: %s", buffer);
|
||||
break;
|
||||
|
||||
case MSG_REFILL:
|
||||
/* Buffer empty. Try to get more. */
|
||||
get_more = pcm_callback_for_more;
|
||||
size = 0;
|
||||
|
||||
if (get_more == NULL || (get_more(&start, &size), size == 0))
|
||||
{
|
||||
/* Callback missing or no more DMA to do */
|
||||
pcm_play_dma_stop();
|
||||
pcm_play_dma_stopped_callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START;
|
||||
/* Flush any pending cache writes */
|
||||
clean_dcache_range(start, size);
|
||||
|
||||
/* set the new DMA values */
|
||||
DSP_(_sdem_addrl) = sdem_addr & 0xffff;
|
||||
DSP_(_sdem_addrh) = sdem_addr >> 16;
|
||||
DSP_(_sdem_dsp_size) = size;
|
||||
|
||||
DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
|
||||
(unsigned long)start, (unsigned long)sdem_addr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEBUGF("DSP: unknown msg 0x%04x", dsp_message.msg);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Re-Activate the channel */
|
||||
dsp_wake();
|
||||
|
||||
DEBUGF("DSP: %s", buffer);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue